ActivityManagerService.java revision 91097de49b0f683b00e26a75dbc0ac6082344137
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.Manifest; 32import android.app.AppOpsManager; 33import android.app.IActivityContainer; 34import android.app.IActivityContainerCallback; 35import android.appwidget.AppWidgetManager; 36import android.graphics.Rect; 37import android.os.BatteryStats; 38import android.service.voice.IVoiceInteractionSession; 39import android.util.ArrayMap; 40 41import com.android.internal.R; 42import com.android.internal.annotations.GuardedBy; 43import com.android.internal.app.IAppOpsService; 44import com.android.internal.app.IVoiceInteractor; 45import com.android.internal.app.ProcessMap; 46import com.android.internal.app.ProcessStats; 47import com.android.internal.os.BackgroundThread; 48import com.android.internal.os.BatteryStatsImpl; 49import com.android.internal.os.ProcessCpuTracker; 50import com.android.internal.os.TransferPipe; 51import com.android.internal.os.Zygote; 52import com.android.internal.util.FastPrintWriter; 53import com.android.internal.util.FastXmlSerializer; 54import com.android.internal.util.MemInfoReader; 55import com.android.internal.util.Preconditions; 56import com.android.server.AppOpsService; 57import com.android.server.AttributeCache; 58import com.android.server.IntentResolver; 59import com.android.server.LocalServices; 60import com.android.server.ServiceThread; 61import com.android.server.SystemService; 62import com.android.server.SystemServiceManager; 63import com.android.server.Watchdog; 64import com.android.server.am.ActivityStack.ActivityState; 65import com.android.server.firewall.IntentFirewall; 66import com.android.server.pm.UserManagerService; 67import com.android.server.wm.AppTransition; 68import com.android.server.wm.WindowManagerService; 69import com.google.android.collect.Lists; 70import com.google.android.collect.Maps; 71 72import libcore.io.IoUtils; 73 74import org.xmlpull.v1.XmlPullParser; 75import org.xmlpull.v1.XmlPullParserException; 76import org.xmlpull.v1.XmlSerializer; 77 78import android.app.Activity; 79import android.app.ActivityManager; 80import android.app.ActivityManager.RunningTaskInfo; 81import android.app.ActivityManager.StackInfo; 82import android.app.ActivityManagerInternal; 83import android.app.ActivityManagerNative; 84import android.app.ActivityOptions; 85import android.app.ActivityThread; 86import android.app.AlertDialog; 87import android.app.AppGlobals; 88import android.app.ApplicationErrorReport; 89import android.app.Dialog; 90import android.app.IActivityController; 91import android.app.IApplicationThread; 92import android.app.IInstrumentationWatcher; 93import android.app.INotificationManager; 94import android.app.IProcessObserver; 95import android.app.IServiceConnection; 96import android.app.IStopUserCallback; 97import android.app.IThumbnailReceiver; 98import android.app.IUiAutomationConnection; 99import android.app.IUserSwitchObserver; 100import android.app.Instrumentation; 101import android.app.Notification; 102import android.app.NotificationManager; 103import android.app.PendingIntent; 104import android.app.backup.IBackupManager; 105import android.content.ActivityNotFoundException; 106import android.content.BroadcastReceiver; 107import android.content.ClipData; 108import android.content.ComponentCallbacks2; 109import android.content.ComponentName; 110import android.content.ContentProvider; 111import android.content.ContentResolver; 112import android.content.Context; 113import android.content.DialogInterface; 114import android.content.IContentProvider; 115import android.content.IIntentReceiver; 116import android.content.IIntentSender; 117import android.content.Intent; 118import android.content.IntentFilter; 119import android.content.IntentSender; 120import android.content.pm.ActivityInfo; 121import android.content.pm.ApplicationInfo; 122import android.content.pm.ConfigurationInfo; 123import android.content.pm.IPackageDataObserver; 124import android.content.pm.IPackageManager; 125import android.content.pm.InstrumentationInfo; 126import android.content.pm.PackageInfo; 127import android.content.pm.PackageManager; 128import android.content.pm.ParceledListSlice; 129import android.content.pm.UserInfo; 130import android.content.pm.PackageManager.NameNotFoundException; 131import android.content.pm.PathPermission; 132import android.content.pm.ProviderInfo; 133import android.content.pm.ResolveInfo; 134import android.content.pm.ServiceInfo; 135import android.content.res.CompatibilityInfo; 136import android.content.res.Configuration; 137import android.graphics.Bitmap; 138import android.net.Proxy; 139import android.net.ProxyProperties; 140import android.net.Uri; 141import android.os.Binder; 142import android.os.Build; 143import android.os.Bundle; 144import android.os.Debug; 145import android.os.DropBoxManager; 146import android.os.Environment; 147import android.os.FactoryTest; 148import android.os.FileObserver; 149import android.os.FileUtils; 150import android.os.Handler; 151import android.os.IBinder; 152import android.os.IPermissionController; 153import android.os.IRemoteCallback; 154import android.os.IUserManager; 155import android.os.Looper; 156import android.os.Message; 157import android.os.Parcel; 158import android.os.ParcelFileDescriptor; 159import android.os.Process; 160import android.os.RemoteCallbackList; 161import android.os.RemoteException; 162import android.os.SELinux; 163import android.os.ServiceManager; 164import android.os.StrictMode; 165import android.os.SystemClock; 166import android.os.SystemProperties; 167import android.os.UpdateLock; 168import android.os.UserHandle; 169import android.provider.Settings; 170import android.text.format.DateUtils; 171import android.text.format.Time; 172import android.util.AtomicFile; 173import android.util.EventLog; 174import android.util.Log; 175import android.util.Pair; 176import android.util.PrintWriterPrinter; 177import android.util.Slog; 178import android.util.SparseArray; 179import android.util.TimeUtils; 180import android.util.Xml; 181import android.view.Gravity; 182import android.view.LayoutInflater; 183import android.view.View; 184import android.view.WindowManager; 185 186import java.io.BufferedInputStream; 187import java.io.BufferedOutputStream; 188import java.io.DataInputStream; 189import java.io.DataOutputStream; 190import java.io.File; 191import java.io.FileDescriptor; 192import java.io.FileInputStream; 193import java.io.FileNotFoundException; 194import java.io.FileOutputStream; 195import java.io.IOException; 196import java.io.InputStreamReader; 197import java.io.PrintWriter; 198import java.io.StringWriter; 199import java.lang.ref.WeakReference; 200import java.util.ArrayList; 201import java.util.Arrays; 202import java.util.Collections; 203import java.util.Comparator; 204import java.util.HashMap; 205import java.util.HashSet; 206import java.util.Iterator; 207import java.util.List; 208import java.util.Locale; 209import java.util.Map; 210import java.util.Set; 211import java.util.concurrent.atomic.AtomicBoolean; 212import java.util.concurrent.atomic.AtomicLong; 213 214public final class ActivityManagerService extends ActivityManagerNative 215 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 216 private static final String USER_DATA_DIR = "/data/user/"; 217 static final String TAG = "ActivityManager"; 218 static final String TAG_MU = "ActivityManagerServiceMU"; 219 static final boolean DEBUG = false; 220 static final boolean localLOGV = DEBUG; 221 static final boolean DEBUG_BACKUP = localLOGV || false; 222 static final boolean DEBUG_BROADCAST = localLOGV || false; 223 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 224 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 225 static final boolean DEBUG_CLEANUP = localLOGV || false; 226 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 227 static final boolean DEBUG_FOCUS = false; 228 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 229 static final boolean DEBUG_MU = localLOGV || false; 230 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 231 static final boolean DEBUG_LRU = localLOGV || false; 232 static final boolean DEBUG_PAUSE = localLOGV || false; 233 static final boolean DEBUG_POWER = localLOGV || false; 234 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 235 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 236 static final boolean DEBUG_PROCESSES = localLOGV || false; 237 static final boolean DEBUG_PROVIDER = localLOGV || false; 238 static final boolean DEBUG_RESULTS = localLOGV || false; 239 static final boolean DEBUG_SERVICE = localLOGV || false; 240 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 241 static final boolean DEBUG_STACK = localLOGV || false; 242 static final boolean DEBUG_SWITCH = localLOGV || false; 243 static final boolean DEBUG_TASKS = localLOGV || false; 244 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 245 static final boolean DEBUG_TRANSITION = localLOGV || false; 246 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 247 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 248 static final boolean DEBUG_VISBILITY = localLOGV || false; 249 static final boolean DEBUG_PSS = localLOGV || false; 250 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 251 static final boolean VALIDATE_TOKENS = false; 252 static final boolean SHOW_ACTIVITY_START_TIME = true; 253 254 // Control over CPU and battery monitoring. 255 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 256 static final boolean MONITOR_CPU_USAGE = true; 257 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 258 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 259 static final boolean MONITOR_THREAD_CPU_USAGE = false; 260 261 // The flags that are set for all calls we make to the package manager. 262 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 263 264 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 265 266 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 267 268 // Maximum number of recent tasks that we can remember. 269 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 270 271 // Amount of time after a call to stopAppSwitches() during which we will 272 // prevent further untrusted switches from happening. 273 static final long APP_SWITCH_DELAY_TIME = 5*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. 277 static final int PROC_START_TIMEOUT = 10*1000; 278 279 // How long we wait for a launched process to attach to the activity manager 280 // before we decide it's never going to come up for real, when the process was 281 // started with a wrapper for instrumentation (such as Valgrind) because it 282 // could take much longer than usual. 283 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 284 285 // How long to wait after going idle before forcing apps to GC. 286 static final int GC_TIMEOUT = 5*1000; 287 288 // The minimum amount of time between successive GC requests for a process. 289 static final int GC_MIN_INTERVAL = 60*1000; 290 291 // The minimum amount of time between successive PSS requests for a process. 292 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 293 294 // The minimum amount of time between successive PSS requests for a process 295 // when the request is due to the memory state being lowered. 296 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 297 298 // The rate at which we check for apps using excessive power -- 15 mins. 299 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 300 301 // The minimum sample duration we will allow before deciding we have 302 // enough data on wake locks to start killing things. 303 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 304 305 // The minimum sample duration we will allow before deciding we have 306 // enough data on CPU usage to start killing things. 307 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 308 309 // How long we allow a receiver to run before giving up on it. 310 static final int BROADCAST_FG_TIMEOUT = 10*1000; 311 static final int BROADCAST_BG_TIMEOUT = 60*1000; 312 313 // How long we wait until we timeout on key dispatching. 314 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 315 316 // How long we wait until we timeout on key dispatching during instrumentation. 317 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 318 319 // Amount of time we wait for observers to handle a user switch before 320 // giving up on them and unfreezing the screen. 321 static final int USER_SWITCH_TIMEOUT = 2*1000; 322 323 // Maximum number of users we allow to be running at a time. 324 static final int MAX_RUNNING_USERS = 3; 325 326 // How long to wait in getAssistContextExtras for the activity and foreground services 327 // to respond with the result. 328 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 329 330 // Maximum number of persisted Uri grants a package is allowed 331 static final int MAX_PERSISTED_URI_GRANTS = 128; 332 333 static final int MY_PID = Process.myPid(); 334 335 static final String[] EMPTY_STRING_ARRAY = new String[0]; 336 337 // How many bytes to write into the dropbox log before truncating 338 static final int DROPBOX_MAX_SIZE = 256 * 1024; 339 340 /** All system services */ 341 SystemServiceManager mSystemServiceManager; 342 343 /** Run all ActivityStacks through this */ 344 ActivityStackSupervisor mStackSupervisor; 345 346 public IntentFirewall mIntentFirewall; 347 348 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 349 // default actuion automatically. Important for devices without direct input 350 // devices. 351 private boolean mShowDialogs = true; 352 353 /** 354 * Description of a request to start a new activity, which has been held 355 * due to app switches being disabled. 356 */ 357 static class PendingActivityLaunch { 358 final ActivityRecord r; 359 final ActivityRecord sourceRecord; 360 final int startFlags; 361 final ActivityStack stack; 362 363 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 364 int _startFlags, ActivityStack _stack) { 365 r = _r; 366 sourceRecord = _sourceRecord; 367 startFlags = _startFlags; 368 stack = _stack; 369 } 370 } 371 372 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 373 = new ArrayList<PendingActivityLaunch>(); 374 375 BroadcastQueue mFgBroadcastQueue; 376 BroadcastQueue mBgBroadcastQueue; 377 // Convenient for easy iteration over the queues. Foreground is first 378 // so that dispatch of foreground broadcasts gets precedence. 379 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 380 381 BroadcastQueue broadcastQueueForIntent(Intent intent) { 382 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 383 if (DEBUG_BACKGROUND_BROADCAST) { 384 Slog.i(TAG, "Broadcast intent " + intent + " on " 385 + (isFg ? "foreground" : "background") 386 + " queue"); 387 } 388 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 389 } 390 391 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 392 for (BroadcastQueue queue : mBroadcastQueues) { 393 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 394 if (r != null) { 395 return r; 396 } 397 } 398 return null; 399 } 400 401 /** 402 * Activity we have told the window manager to have key focus. 403 */ 404 ActivityRecord mFocusedActivity = null; 405 406 /** 407 * List of intents that were used to start the most recent tasks. 408 */ 409 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 410 411 public class PendingAssistExtras extends Binder implements Runnable { 412 public final ActivityRecord activity; 413 public boolean haveResult = false; 414 public Bundle result = null; 415 public PendingAssistExtras(ActivityRecord _activity) { 416 activity = _activity; 417 } 418 @Override 419 public void run() { 420 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 421 synchronized (this) { 422 haveResult = true; 423 notifyAll(); 424 } 425 } 426 } 427 428 final ArrayList<PendingAssistExtras> mPendingAssistExtras 429 = new ArrayList<PendingAssistExtras>(); 430 431 /** 432 * Process management. 433 */ 434 final ProcessList mProcessList = new ProcessList(); 435 436 /** 437 * All of the applications we currently have running organized by name. 438 * The keys are strings of the application package name (as 439 * returned by the package manager), and the keys are ApplicationRecord 440 * objects. 441 */ 442 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 443 444 /** 445 * Tracking long-term execution of processes to look for abuse and other 446 * bad app behavior. 447 */ 448 final ProcessStatsService mProcessStats; 449 450 /** 451 * The currently running isolated processes. 452 */ 453 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 454 455 /** 456 * Counter for assigning isolated process uids, to avoid frequently reusing the 457 * same ones. 458 */ 459 int mNextIsolatedProcessUid = 0; 460 461 /** 462 * The currently running heavy-weight process, if any. 463 */ 464 ProcessRecord mHeavyWeightProcess = null; 465 466 /** 467 * The last time that various processes have crashed. 468 */ 469 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 470 471 /** 472 * Information about a process that is currently marked as bad. 473 */ 474 static final class BadProcessInfo { 475 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 476 this.time = time; 477 this.shortMsg = shortMsg; 478 this.longMsg = longMsg; 479 this.stack = stack; 480 } 481 482 final long time; 483 final String shortMsg; 484 final String longMsg; 485 final String stack; 486 } 487 488 /** 489 * Set of applications that we consider to be bad, and will reject 490 * incoming broadcasts from (which the user has no control over). 491 * Processes are added to this set when they have crashed twice within 492 * a minimum amount of time; they are removed from it when they are 493 * later restarted (hopefully due to some user action). The value is the 494 * time it was added to the list. 495 */ 496 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 497 498 /** 499 * All of the processes we currently have running organized by pid. 500 * The keys are the pid running the application. 501 * 502 * <p>NOTE: This object is protected by its own lock, NOT the global 503 * activity manager lock! 504 */ 505 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 506 507 /** 508 * All of the processes that have been forced to be foreground. The key 509 * is the pid of the caller who requested it (we hold a death 510 * link on it). 511 */ 512 abstract class ForegroundToken implements IBinder.DeathRecipient { 513 int pid; 514 IBinder token; 515 } 516 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 517 518 /** 519 * List of records for processes that someone had tried to start before the 520 * system was ready. We don't start them at that point, but ensure they 521 * are started by the time booting is complete. 522 */ 523 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 524 525 /** 526 * List of persistent applications that are in the process 527 * of being started. 528 */ 529 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 530 531 /** 532 * Processes that are being forcibly torn down. 533 */ 534 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 535 536 /** 537 * List of running applications, sorted by recent usage. 538 * The first entry in the list is the least recently used. 539 */ 540 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 541 542 /** 543 * Where in mLruProcesses that the processes hosting activities start. 544 */ 545 int mLruProcessActivityStart = 0; 546 547 /** 548 * Where in mLruProcesses that the processes hosting services start. 549 * This is after (lower index) than mLruProcessesActivityStart. 550 */ 551 int mLruProcessServiceStart = 0; 552 553 /** 554 * List of processes that should gc as soon as things are idle. 555 */ 556 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 557 558 /** 559 * Processes we want to collect PSS data from. 560 */ 561 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 562 563 /** 564 * Last time we requested PSS data of all processes. 565 */ 566 long mLastFullPssTime = SystemClock.uptimeMillis(); 567 568 /** 569 * This is the process holding what we currently consider to be 570 * the "home" activity. 571 */ 572 ProcessRecord mHomeProcess; 573 574 /** 575 * This is the process holding the activity the user last visited that 576 * is in a different process from the one they are currently in. 577 */ 578 ProcessRecord mPreviousProcess; 579 580 /** 581 * The time at which the previous process was last visible. 582 */ 583 long mPreviousProcessVisibleTime; 584 585 /** 586 * Which uses have been started, so are allowed to run code. 587 */ 588 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 589 590 /** 591 * LRU list of history of current users. Most recently current is at the end. 592 */ 593 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 594 595 /** 596 * Constant array of the users that are currently started. 597 */ 598 int[] mStartedUserArray = new int[] { 0 }; 599 600 /** 601 * Registered observers of the user switching mechanics. 602 */ 603 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 604 = new RemoteCallbackList<IUserSwitchObserver>(); 605 606 /** 607 * Currently active user switch. 608 */ 609 Object mCurUserSwitchCallback; 610 611 /** 612 * Packages that the user has asked to have run in screen size 613 * compatibility mode instead of filling the screen. 614 */ 615 final CompatModePackages mCompatModePackages; 616 617 /** 618 * Set of IntentSenderRecord objects that are currently active. 619 */ 620 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 621 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 622 623 /** 624 * Fingerprints (hashCode()) of stack traces that we've 625 * already logged DropBox entries for. Guarded by itself. If 626 * something (rogue user app) forces this over 627 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 628 */ 629 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 630 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 631 632 /** 633 * Strict Mode background batched logging state. 634 * 635 * The string buffer is guarded by itself, and its lock is also 636 * used to determine if another batched write is already 637 * in-flight. 638 */ 639 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 640 641 /** 642 * Keeps track of all IIntentReceivers that have been registered for 643 * broadcasts. Hash keys are the receiver IBinder, hash value is 644 * a ReceiverList. 645 */ 646 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 647 new HashMap<IBinder, ReceiverList>(); 648 649 /** 650 * Resolver for broadcast intents to registered receivers. 651 * Holds BroadcastFilter (subclass of IntentFilter). 652 */ 653 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 654 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 655 @Override 656 protected boolean allowFilterResult( 657 BroadcastFilter filter, List<BroadcastFilter> dest) { 658 IBinder target = filter.receiverList.receiver.asBinder(); 659 for (int i=dest.size()-1; i>=0; i--) { 660 if (dest.get(i).receiverList.receiver.asBinder() == target) { 661 return false; 662 } 663 } 664 return true; 665 } 666 667 @Override 668 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 669 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 670 || userId == filter.owningUserId) { 671 return super.newResult(filter, match, userId); 672 } 673 return null; 674 } 675 676 @Override 677 protected BroadcastFilter[] newArray(int size) { 678 return new BroadcastFilter[size]; 679 } 680 681 @Override 682 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 683 return packageName.equals(filter.packageName); 684 } 685 }; 686 687 /** 688 * State of all active sticky broadcasts per user. Keys are the action of the 689 * sticky Intent, values are an ArrayList of all broadcasted intents with 690 * that action (which should usually be one). The SparseArray is keyed 691 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 692 * for stickies that are sent to all users. 693 */ 694 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 695 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 696 697 final ActiveServices mServices; 698 699 /** 700 * Backup/restore process management 701 */ 702 String mBackupAppName = null; 703 BackupRecord mBackupTarget = null; 704 705 /** 706 * List of PendingThumbnailsRecord objects of clients who are still 707 * waiting to receive all of the thumbnails for a task. 708 */ 709 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 710 new ArrayList<PendingThumbnailsRecord>(); 711 712 final ProviderMap mProviderMap; 713 714 /** 715 * List of content providers who have clients waiting for them. The 716 * application is currently being launched and the provider will be 717 * removed from this list once it is published. 718 */ 719 final ArrayList<ContentProviderRecord> mLaunchingProviders 720 = new ArrayList<ContentProviderRecord>(); 721 722 /** 723 * File storing persisted {@link #mGrantedUriPermissions}. 724 */ 725 private final AtomicFile mGrantFile; 726 727 /** XML constants used in {@link #mGrantFile} */ 728 private static final String TAG_URI_GRANTS = "uri-grants"; 729 private static final String TAG_URI_GRANT = "uri-grant"; 730 private static final String ATTR_USER_HANDLE = "userHandle"; 731 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 732 private static final String ATTR_TARGET_PKG = "targetPkg"; 733 private static final String ATTR_URI = "uri"; 734 private static final String ATTR_MODE_FLAGS = "modeFlags"; 735 private static final String ATTR_CREATED_TIME = "createdTime"; 736 private static final String ATTR_PREFIX = "prefix"; 737 738 /** 739 * Global set of specific {@link Uri} permissions that have been granted. 740 * This optimized lookup structure maps from {@link UriPermission#targetUid} 741 * to {@link UriPermission#uri} to {@link UriPermission}. 742 */ 743 @GuardedBy("this") 744 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 745 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 746 747 public static class GrantUri { 748 public final Uri uri; 749 public final boolean prefix; 750 751 public GrantUri(Uri uri, boolean prefix) { 752 this.uri = uri; 753 this.prefix = prefix; 754 } 755 756 @Override 757 public int hashCode() { 758 return toString().hashCode(); 759 } 760 761 @Override 762 public boolean equals(Object o) { 763 if (o instanceof GrantUri) { 764 GrantUri other = (GrantUri) o; 765 return uri.equals(other.uri) && prefix == other.prefix; 766 } 767 return false; 768 } 769 770 @Override 771 public String toString() { 772 if (prefix) { 773 return uri.toString() + " [prefix]"; 774 } else { 775 return uri.toString(); 776 } 777 } 778 } 779 780 CoreSettingsObserver mCoreSettingsObserver; 781 782 /** 783 * Thread-local storage used to carry caller permissions over through 784 * indirect content-provider access. 785 */ 786 private class Identity { 787 public int pid; 788 public int uid; 789 790 Identity(int _pid, int _uid) { 791 pid = _pid; 792 uid = _uid; 793 } 794 } 795 796 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 797 798 /** 799 * All information we have collected about the runtime performance of 800 * any user id that can impact battery performance. 801 */ 802 final BatteryStatsService mBatteryStatsService; 803 804 /** 805 * Information about component usage 806 */ 807 final UsageStatsService mUsageStatsService; 808 809 /** 810 * Information about and control over application operations 811 */ 812 final AppOpsService mAppOpsService; 813 814 /** 815 * Current configuration information. HistoryRecord objects are given 816 * a reference to this object to indicate which configuration they are 817 * currently running in, so this object must be kept immutable. 818 */ 819 Configuration mConfiguration = new Configuration(); 820 821 /** 822 * Current sequencing integer of the configuration, for skipping old 823 * configurations. 824 */ 825 int mConfigurationSeq = 0; 826 827 /** 828 * Hardware-reported OpenGLES version. 829 */ 830 final int GL_ES_VERSION; 831 832 /** 833 * List of initialization arguments to pass to all processes when binding applications to them. 834 * For example, references to the commonly used services. 835 */ 836 HashMap<String, IBinder> mAppBindArgs; 837 838 /** 839 * Temporary to avoid allocations. Protected by main lock. 840 */ 841 final StringBuilder mStringBuilder = new StringBuilder(256); 842 843 /** 844 * Used to control how we initialize the service. 845 */ 846 ComponentName mTopComponent; 847 String mTopAction = Intent.ACTION_MAIN; 848 String mTopData; 849 boolean mProcessesReady = false; 850 boolean mSystemReady = false; 851 boolean mBooting = false; 852 boolean mWaitingUpdate = false; 853 boolean mDidUpdate = false; 854 boolean mOnBattery = false; 855 boolean mLaunchWarningShown = false; 856 857 Context mContext; 858 859 int mFactoryTest; 860 861 boolean mCheckedForSetup; 862 863 /** 864 * The time at which we will allow normal application switches again, 865 * after a call to {@link #stopAppSwitches()}. 866 */ 867 long mAppSwitchesAllowedTime; 868 869 /** 870 * This is set to true after the first switch after mAppSwitchesAllowedTime 871 * is set; any switches after that will clear the time. 872 */ 873 boolean mDidAppSwitch; 874 875 /** 876 * Last time (in realtime) at which we checked for power usage. 877 */ 878 long mLastPowerCheckRealtime; 879 880 /** 881 * Last time (in uptime) at which we checked for power usage. 882 */ 883 long mLastPowerCheckUptime; 884 885 /** 886 * Set while we are wanting to sleep, to prevent any 887 * activities from being started/resumed. 888 */ 889 private boolean mSleeping = false; 890 891 /** 892 * Set while we are running a voice interaction. This overrides 893 * sleeping while it is active. 894 */ 895 private boolean mRunningVoice = false; 896 897 /** 898 * State of external calls telling us if the device is asleep. 899 */ 900 private boolean mWentToSleep = false; 901 902 /** 903 * State of external call telling us if the lock screen is shown. 904 */ 905 private boolean mLockScreenShown = false; 906 907 /** 908 * Set if we are shutting down the system, similar to sleeping. 909 */ 910 boolean mShuttingDown = false; 911 912 /** 913 * Current sequence id for oom_adj computation traversal. 914 */ 915 int mAdjSeq = 0; 916 917 /** 918 * Current sequence id for process LRU updating. 919 */ 920 int mLruSeq = 0; 921 922 /** 923 * Keep track of the non-cached/empty process we last found, to help 924 * determine how to distribute cached/empty processes next time. 925 */ 926 int mNumNonCachedProcs = 0; 927 928 /** 929 * Keep track of the number of cached hidden procs, to balance oom adj 930 * distribution between those and empty procs. 931 */ 932 int mNumCachedHiddenProcs = 0; 933 934 /** 935 * Keep track of the number of service processes we last found, to 936 * determine on the next iteration which should be B services. 937 */ 938 int mNumServiceProcs = 0; 939 int mNewNumAServiceProcs = 0; 940 int mNewNumServiceProcs = 0; 941 942 /** 943 * Allow the current computed overall memory level of the system to go down? 944 * This is set to false when we are killing processes for reasons other than 945 * memory management, so that the now smaller process list will not be taken as 946 * an indication that memory is tighter. 947 */ 948 boolean mAllowLowerMemLevel = false; 949 950 /** 951 * The last computed memory level, for holding when we are in a state that 952 * processes are going away for other reasons. 953 */ 954 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 955 956 /** 957 * The last total number of process we have, to determine if changes actually look 958 * like a shrinking number of process due to lower RAM. 959 */ 960 int mLastNumProcesses; 961 962 /** 963 * The uptime of the last time we performed idle maintenance. 964 */ 965 long mLastIdleTime = SystemClock.uptimeMillis(); 966 967 /** 968 * Total time spent with RAM that has been added in the past since the last idle time. 969 */ 970 long mLowRamTimeSinceLastIdle = 0; 971 972 /** 973 * If RAM is currently low, when that horrible situation started. 974 */ 975 long mLowRamStartTime = 0; 976 977 /** 978 * For reporting to battery stats the current top application. 979 */ 980 private String mCurResumedPackage = null; 981 private int mCurResumedUid = -1; 982 983 /** 984 * For reporting to battery stats the apps currently running foreground 985 * service. The ProcessMap is package/uid tuples; each of these contain 986 * an array of the currently foreground processes. 987 */ 988 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 989 = new ProcessMap<ArrayList<ProcessRecord>>(); 990 991 /** 992 * This is set if we had to do a delayed dexopt of an app before launching 993 * it, to increasing the ANR timeouts in that case. 994 */ 995 boolean mDidDexOpt; 996 997 /** 998 * Set if the systemServer made a call to enterSafeMode. 999 */ 1000 boolean mSafeMode; 1001 1002 String mDebugApp = null; 1003 boolean mWaitForDebugger = false; 1004 boolean mDebugTransient = false; 1005 String mOrigDebugApp = null; 1006 boolean mOrigWaitForDebugger = false; 1007 boolean mAlwaysFinishActivities = false; 1008 IActivityController mController = null; 1009 String mProfileApp = null; 1010 ProcessRecord mProfileProc = null; 1011 String mProfileFile; 1012 ParcelFileDescriptor mProfileFd; 1013 int mProfileType = 0; 1014 boolean mAutoStopProfiler = false; 1015 String mOpenGlTraceApp = null; 1016 1017 static class ProcessChangeItem { 1018 static final int CHANGE_ACTIVITIES = 1<<0; 1019 static final int CHANGE_IMPORTANCE= 1<<1; 1020 int changes; 1021 int uid; 1022 int pid; 1023 int importance; 1024 boolean foregroundActivities; 1025 } 1026 1027 final RemoteCallbackList<IProcessObserver> mProcessObservers 1028 = new RemoteCallbackList<IProcessObserver>(); 1029 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1030 1031 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1032 = new ArrayList<ProcessChangeItem>(); 1033 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1034 = new ArrayList<ProcessChangeItem>(); 1035 1036 /** 1037 * Runtime CPU use collection thread. This object's lock is used to 1038 * protect all related state. 1039 */ 1040 final Thread mProcessCpuThread; 1041 1042 /** 1043 * Used to collect process stats when showing not responding dialog. 1044 * Protected by mProcessCpuThread. 1045 */ 1046 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1047 MONITOR_THREAD_CPU_USAGE); 1048 final AtomicLong mLastCpuTime = new AtomicLong(0); 1049 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1050 1051 long mLastWriteTime = 0; 1052 1053 /** 1054 * Used to retain an update lock when the foreground activity is in 1055 * immersive mode. 1056 */ 1057 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1058 1059 /** 1060 * Set to true after the system has finished booting. 1061 */ 1062 boolean mBooted = false; 1063 1064 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1065 int mProcessLimitOverride = -1; 1066 1067 WindowManagerService mWindowManager; 1068 1069 final ActivityThread mSystemThread; 1070 1071 int mCurrentUserId = 0; 1072 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1073 private UserManagerService mUserManager; 1074 1075 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1076 final ProcessRecord mApp; 1077 final int mPid; 1078 final IApplicationThread mAppThread; 1079 1080 AppDeathRecipient(ProcessRecord app, int pid, 1081 IApplicationThread thread) { 1082 if (localLOGV) Slog.v( 1083 TAG, "New death recipient " + this 1084 + " for thread " + thread.asBinder()); 1085 mApp = app; 1086 mPid = pid; 1087 mAppThread = thread; 1088 } 1089 1090 @Override 1091 public void binderDied() { 1092 if (localLOGV) Slog.v( 1093 TAG, "Death received in " + this 1094 + " for thread " + mAppThread.asBinder()); 1095 synchronized(ActivityManagerService.this) { 1096 appDiedLocked(mApp, mPid, mAppThread); 1097 } 1098 } 1099 } 1100 1101 static final int SHOW_ERROR_MSG = 1; 1102 static final int SHOW_NOT_RESPONDING_MSG = 2; 1103 static final int SHOW_FACTORY_ERROR_MSG = 3; 1104 static final int UPDATE_CONFIGURATION_MSG = 4; 1105 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1106 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1107 static final int SERVICE_TIMEOUT_MSG = 12; 1108 static final int UPDATE_TIME_ZONE = 13; 1109 static final int SHOW_UID_ERROR_MSG = 14; 1110 static final int IM_FEELING_LUCKY_MSG = 15; 1111 static final int PROC_START_TIMEOUT_MSG = 20; 1112 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1113 static final int KILL_APPLICATION_MSG = 22; 1114 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1115 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1116 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1117 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1118 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1119 static final int CLEAR_DNS_CACHE_MSG = 28; 1120 static final int UPDATE_HTTP_PROXY_MSG = 29; 1121 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1122 static final int DISPATCH_PROCESSES_CHANGED = 31; 1123 static final int DISPATCH_PROCESS_DIED = 32; 1124 static final int REPORT_MEM_USAGE_MSG = 33; 1125 static final int REPORT_USER_SWITCH_MSG = 34; 1126 static final int CONTINUE_USER_SWITCH_MSG = 35; 1127 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1128 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1129 static final int PERSIST_URI_GRANTS_MSG = 38; 1130 static final int REQUEST_ALL_PSS_MSG = 39; 1131 static final int START_PROFILES_MSG = 40; 1132 static final int UPDATE_TIME = 41; 1133 static final int SYSTEM_USER_START_MSG = 42; 1134 static final int SYSTEM_USER_CURRENT_MSG = 43; 1135 1136 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1137 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1138 static final int FIRST_COMPAT_MODE_MSG = 300; 1139 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1140 1141 AlertDialog mUidAlert; 1142 CompatModeDialog mCompatModeDialog; 1143 long mLastMemUsageReportTime = 0; 1144 1145 /** 1146 * Flag whether the current user is a "monkey", i.e. whether 1147 * the UI is driven by a UI automation tool. 1148 */ 1149 private boolean mUserIsMonkey; 1150 1151 final ServiceThread mHandlerThread; 1152 final MainHandler mHandler; 1153 1154 final class MainHandler extends Handler { 1155 public MainHandler(Looper looper) { 1156 super(looper, null, true); 1157 } 1158 1159 @Override 1160 public void handleMessage(Message msg) { 1161 switch (msg.what) { 1162 case SHOW_ERROR_MSG: { 1163 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1164 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1165 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1166 synchronized (ActivityManagerService.this) { 1167 ProcessRecord proc = (ProcessRecord)data.get("app"); 1168 AppErrorResult res = (AppErrorResult) data.get("result"); 1169 if (proc != null && proc.crashDialog != null) { 1170 Slog.e(TAG, "App already has crash dialog: " + proc); 1171 if (res != null) { 1172 res.set(0); 1173 } 1174 return; 1175 } 1176 if (!showBackground && UserHandle.getAppId(proc.uid) 1177 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1178 && proc.pid != MY_PID) { 1179 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1180 if (res != null) { 1181 res.set(0); 1182 } 1183 return; 1184 } 1185 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1186 Dialog d = new AppErrorDialog(mContext, 1187 ActivityManagerService.this, res, proc); 1188 d.show(); 1189 proc.crashDialog = d; 1190 } else { 1191 // The device is asleep, so just pretend that the user 1192 // saw a crash dialog and hit "force quit". 1193 if (res != null) { 1194 res.set(0); 1195 } 1196 } 1197 } 1198 1199 ensureBootCompleted(); 1200 } break; 1201 case SHOW_NOT_RESPONDING_MSG: { 1202 synchronized (ActivityManagerService.this) { 1203 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1204 ProcessRecord proc = (ProcessRecord)data.get("app"); 1205 if (proc != null && proc.anrDialog != null) { 1206 Slog.e(TAG, "App already has anr dialog: " + proc); 1207 return; 1208 } 1209 1210 Intent intent = new Intent("android.intent.action.ANR"); 1211 if (!mProcessesReady) { 1212 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1213 | Intent.FLAG_RECEIVER_FOREGROUND); 1214 } 1215 broadcastIntentLocked(null, null, intent, 1216 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1217 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1218 1219 if (mShowDialogs) { 1220 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1221 mContext, proc, (ActivityRecord)data.get("activity"), 1222 msg.arg1 != 0); 1223 d.show(); 1224 proc.anrDialog = d; 1225 } else { 1226 // Just kill the app if there is no dialog to be shown. 1227 killAppAtUsersRequest(proc, null); 1228 } 1229 } 1230 1231 ensureBootCompleted(); 1232 } break; 1233 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1234 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1235 synchronized (ActivityManagerService.this) { 1236 ProcessRecord proc = (ProcessRecord) data.get("app"); 1237 if (proc == null) { 1238 Slog.e(TAG, "App not found when showing strict mode dialog."); 1239 break; 1240 } 1241 if (proc.crashDialog != null) { 1242 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1243 return; 1244 } 1245 AppErrorResult res = (AppErrorResult) data.get("result"); 1246 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1247 Dialog d = new StrictModeViolationDialog(mContext, 1248 ActivityManagerService.this, res, proc); 1249 d.show(); 1250 proc.crashDialog = d; 1251 } else { 1252 // The device is asleep, so just pretend that the user 1253 // saw a crash dialog and hit "force quit". 1254 res.set(0); 1255 } 1256 } 1257 ensureBootCompleted(); 1258 } break; 1259 case SHOW_FACTORY_ERROR_MSG: { 1260 Dialog d = new FactoryErrorDialog( 1261 mContext, msg.getData().getCharSequence("msg")); 1262 d.show(); 1263 ensureBootCompleted(); 1264 } break; 1265 case UPDATE_CONFIGURATION_MSG: { 1266 final ContentResolver resolver = mContext.getContentResolver(); 1267 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1268 } break; 1269 case GC_BACKGROUND_PROCESSES_MSG: { 1270 synchronized (ActivityManagerService.this) { 1271 performAppGcsIfAppropriateLocked(); 1272 } 1273 } break; 1274 case WAIT_FOR_DEBUGGER_MSG: { 1275 synchronized (ActivityManagerService.this) { 1276 ProcessRecord app = (ProcessRecord)msg.obj; 1277 if (msg.arg1 != 0) { 1278 if (!app.waitedForDebugger) { 1279 Dialog d = new AppWaitingForDebuggerDialog( 1280 ActivityManagerService.this, 1281 mContext, app); 1282 app.waitDialog = d; 1283 app.waitedForDebugger = true; 1284 d.show(); 1285 } 1286 } else { 1287 if (app.waitDialog != null) { 1288 app.waitDialog.dismiss(); 1289 app.waitDialog = null; 1290 } 1291 } 1292 } 1293 } break; 1294 case SERVICE_TIMEOUT_MSG: { 1295 if (mDidDexOpt) { 1296 mDidDexOpt = false; 1297 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1298 nmsg.obj = msg.obj; 1299 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1300 return; 1301 } 1302 mServices.serviceTimeout((ProcessRecord)msg.obj); 1303 } break; 1304 case UPDATE_TIME_ZONE: { 1305 synchronized (ActivityManagerService.this) { 1306 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1307 ProcessRecord r = mLruProcesses.get(i); 1308 if (r.thread != null) { 1309 try { 1310 r.thread.updateTimeZone(); 1311 } catch (RemoteException ex) { 1312 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1313 } 1314 } 1315 } 1316 } 1317 } break; 1318 case CLEAR_DNS_CACHE_MSG: { 1319 synchronized (ActivityManagerService.this) { 1320 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1321 ProcessRecord r = mLruProcesses.get(i); 1322 if (r.thread != null) { 1323 try { 1324 r.thread.clearDnsCache(); 1325 } catch (RemoteException ex) { 1326 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1327 } 1328 } 1329 } 1330 } 1331 } break; 1332 case UPDATE_HTTP_PROXY_MSG: { 1333 ProxyProperties proxy = (ProxyProperties)msg.obj; 1334 String host = ""; 1335 String port = ""; 1336 String exclList = ""; 1337 String pacFileUrl = null; 1338 if (proxy != null) { 1339 host = proxy.getHost(); 1340 port = Integer.toString(proxy.getPort()); 1341 exclList = proxy.getExclusionList(); 1342 pacFileUrl = proxy.getPacFileUrl(); 1343 } 1344 synchronized (ActivityManagerService.this) { 1345 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1346 ProcessRecord r = mLruProcesses.get(i); 1347 if (r.thread != null) { 1348 try { 1349 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1350 } catch (RemoteException ex) { 1351 Slog.w(TAG, "Failed to update http proxy for: " + 1352 r.info.processName); 1353 } 1354 } 1355 } 1356 } 1357 } break; 1358 case SHOW_UID_ERROR_MSG: { 1359 String title = "System UIDs Inconsistent"; 1360 String text = "UIDs on the system are inconsistent, you need to wipe your" 1361 + " data partition or your device will be unstable."; 1362 Log.e(TAG, title + ": " + text); 1363 if (mShowDialogs) { 1364 // XXX This is a temporary dialog, no need to localize. 1365 AlertDialog d = new BaseErrorDialog(mContext); 1366 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1367 d.setCancelable(false); 1368 d.setTitle(title); 1369 d.setMessage(text); 1370 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1371 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1372 mUidAlert = d; 1373 d.show(); 1374 } 1375 } break; 1376 case IM_FEELING_LUCKY_MSG: { 1377 if (mUidAlert != null) { 1378 mUidAlert.dismiss(); 1379 mUidAlert = null; 1380 } 1381 } break; 1382 case PROC_START_TIMEOUT_MSG: { 1383 if (mDidDexOpt) { 1384 mDidDexOpt = false; 1385 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1386 nmsg.obj = msg.obj; 1387 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1388 return; 1389 } 1390 ProcessRecord app = (ProcessRecord)msg.obj; 1391 synchronized (ActivityManagerService.this) { 1392 processStartTimedOutLocked(app); 1393 } 1394 } break; 1395 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1396 synchronized (ActivityManagerService.this) { 1397 doPendingActivityLaunchesLocked(true); 1398 } 1399 } break; 1400 case KILL_APPLICATION_MSG: { 1401 synchronized (ActivityManagerService.this) { 1402 int appid = msg.arg1; 1403 boolean restart = (msg.arg2 == 1); 1404 Bundle bundle = (Bundle)msg.obj; 1405 String pkg = bundle.getString("pkg"); 1406 String reason = bundle.getString("reason"); 1407 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1408 false, UserHandle.USER_ALL, reason); 1409 } 1410 } break; 1411 case FINALIZE_PENDING_INTENT_MSG: { 1412 ((PendingIntentRecord)msg.obj).completeFinalize(); 1413 } break; 1414 case POST_HEAVY_NOTIFICATION_MSG: { 1415 INotificationManager inm = NotificationManager.getService(); 1416 if (inm == null) { 1417 return; 1418 } 1419 1420 ActivityRecord root = (ActivityRecord)msg.obj; 1421 ProcessRecord process = root.app; 1422 if (process == null) { 1423 return; 1424 } 1425 1426 try { 1427 Context context = mContext.createPackageContext(process.info.packageName, 0); 1428 String text = mContext.getString(R.string.heavy_weight_notification, 1429 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1430 Notification notification = new Notification(); 1431 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1432 notification.when = 0; 1433 notification.flags = Notification.FLAG_ONGOING_EVENT; 1434 notification.tickerText = text; 1435 notification.defaults = 0; // please be quiet 1436 notification.sound = null; 1437 notification.vibrate = null; 1438 notification.setLatestEventInfo(context, text, 1439 mContext.getText(R.string.heavy_weight_notification_detail), 1440 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1441 PendingIntent.FLAG_CANCEL_CURRENT, null, 1442 new UserHandle(root.userId))); 1443 1444 try { 1445 int[] outId = new int[1]; 1446 inm.enqueueNotificationWithTag("android", "android", null, 1447 R.string.heavy_weight_notification, 1448 notification, outId, root.userId); 1449 } catch (RuntimeException e) { 1450 Slog.w(ActivityManagerService.TAG, 1451 "Error showing notification for heavy-weight app", e); 1452 } catch (RemoteException e) { 1453 } 1454 } catch (NameNotFoundException e) { 1455 Slog.w(TAG, "Unable to create context for heavy notification", e); 1456 } 1457 } break; 1458 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1459 INotificationManager inm = NotificationManager.getService(); 1460 if (inm == null) { 1461 return; 1462 } 1463 try { 1464 inm.cancelNotificationWithTag("android", null, 1465 R.string.heavy_weight_notification, msg.arg1); 1466 } catch (RuntimeException e) { 1467 Slog.w(ActivityManagerService.TAG, 1468 "Error canceling notification for service", e); 1469 } catch (RemoteException e) { 1470 } 1471 } break; 1472 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1473 synchronized (ActivityManagerService.this) { 1474 checkExcessivePowerUsageLocked(true); 1475 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1476 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1477 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1478 } 1479 } break; 1480 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1481 synchronized (ActivityManagerService.this) { 1482 ActivityRecord ar = (ActivityRecord)msg.obj; 1483 if (mCompatModeDialog != null) { 1484 if (mCompatModeDialog.mAppInfo.packageName.equals( 1485 ar.info.applicationInfo.packageName)) { 1486 return; 1487 } 1488 mCompatModeDialog.dismiss(); 1489 mCompatModeDialog = null; 1490 } 1491 if (ar != null && false) { 1492 if (mCompatModePackages.getPackageAskCompatModeLocked( 1493 ar.packageName)) { 1494 int mode = mCompatModePackages.computeCompatModeLocked( 1495 ar.info.applicationInfo); 1496 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1497 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1498 mCompatModeDialog = new CompatModeDialog( 1499 ActivityManagerService.this, mContext, 1500 ar.info.applicationInfo); 1501 mCompatModeDialog.show(); 1502 } 1503 } 1504 } 1505 } 1506 break; 1507 } 1508 case DISPATCH_PROCESSES_CHANGED: { 1509 dispatchProcessesChanged(); 1510 break; 1511 } 1512 case DISPATCH_PROCESS_DIED: { 1513 final int pid = msg.arg1; 1514 final int uid = msg.arg2; 1515 dispatchProcessDied(pid, uid); 1516 break; 1517 } 1518 case REPORT_MEM_USAGE_MSG: { 1519 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1520 Thread thread = new Thread() { 1521 @Override public void run() { 1522 final SparseArray<ProcessMemInfo> infoMap 1523 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1524 for (int i=0, N=memInfos.size(); i<N; i++) { 1525 ProcessMemInfo mi = memInfos.get(i); 1526 infoMap.put(mi.pid, mi); 1527 } 1528 updateCpuStatsNow(); 1529 synchronized (mProcessCpuThread) { 1530 final int N = mProcessCpuTracker.countStats(); 1531 for (int i=0; i<N; i++) { 1532 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1533 if (st.vsize > 0) { 1534 long pss = Debug.getPss(st.pid, null); 1535 if (pss > 0) { 1536 if (infoMap.indexOfKey(st.pid) < 0) { 1537 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1538 ProcessList.NATIVE_ADJ, -1, "native", null); 1539 mi.pss = pss; 1540 memInfos.add(mi); 1541 } 1542 } 1543 } 1544 } 1545 } 1546 1547 long totalPss = 0; 1548 for (int i=0, N=memInfos.size(); i<N; i++) { 1549 ProcessMemInfo mi = memInfos.get(i); 1550 if (mi.pss == 0) { 1551 mi.pss = Debug.getPss(mi.pid, null); 1552 } 1553 totalPss += mi.pss; 1554 } 1555 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1556 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1557 if (lhs.oomAdj != rhs.oomAdj) { 1558 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1559 } 1560 if (lhs.pss != rhs.pss) { 1561 return lhs.pss < rhs.pss ? 1 : -1; 1562 } 1563 return 0; 1564 } 1565 }); 1566 1567 StringBuilder tag = new StringBuilder(128); 1568 StringBuilder stack = new StringBuilder(128); 1569 tag.append("Low on memory -- "); 1570 appendMemBucket(tag, totalPss, "total", false); 1571 appendMemBucket(stack, totalPss, "total", true); 1572 1573 StringBuilder logBuilder = new StringBuilder(1024); 1574 logBuilder.append("Low on memory:\n"); 1575 1576 boolean firstLine = true; 1577 int lastOomAdj = Integer.MIN_VALUE; 1578 for (int i=0, N=memInfos.size(); i<N; i++) { 1579 ProcessMemInfo mi = memInfos.get(i); 1580 1581 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1582 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1583 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1584 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1585 if (lastOomAdj != mi.oomAdj) { 1586 lastOomAdj = mi.oomAdj; 1587 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1588 tag.append(" / "); 1589 } 1590 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1591 if (firstLine) { 1592 stack.append(":"); 1593 firstLine = false; 1594 } 1595 stack.append("\n\t at "); 1596 } else { 1597 stack.append("$"); 1598 } 1599 } else { 1600 tag.append(" "); 1601 stack.append("$"); 1602 } 1603 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1604 appendMemBucket(tag, mi.pss, mi.name, false); 1605 } 1606 appendMemBucket(stack, mi.pss, mi.name, true); 1607 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1608 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1609 stack.append("("); 1610 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1611 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1612 stack.append(DUMP_MEM_OOM_LABEL[k]); 1613 stack.append(":"); 1614 stack.append(DUMP_MEM_OOM_ADJ[k]); 1615 } 1616 } 1617 stack.append(")"); 1618 } 1619 } 1620 1621 logBuilder.append(" "); 1622 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1623 logBuilder.append(' '); 1624 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1625 logBuilder.append(' '); 1626 ProcessList.appendRamKb(logBuilder, mi.pss); 1627 logBuilder.append(" kB: "); 1628 logBuilder.append(mi.name); 1629 logBuilder.append(" ("); 1630 logBuilder.append(mi.pid); 1631 logBuilder.append(") "); 1632 logBuilder.append(mi.adjType); 1633 logBuilder.append('\n'); 1634 if (mi.adjReason != null) { 1635 logBuilder.append(" "); 1636 logBuilder.append(mi.adjReason); 1637 logBuilder.append('\n'); 1638 } 1639 } 1640 1641 logBuilder.append(" "); 1642 ProcessList.appendRamKb(logBuilder, totalPss); 1643 logBuilder.append(" kB: TOTAL\n"); 1644 1645 long[] infos = new long[Debug.MEMINFO_COUNT]; 1646 Debug.getMemInfo(infos); 1647 logBuilder.append(" MemInfo: "); 1648 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1649 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1650 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1651 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1652 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1653 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1654 logBuilder.append(" ZRAM: "); 1655 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1656 logBuilder.append(" kB RAM, "); 1657 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1658 logBuilder.append(" kB swap total, "); 1659 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1660 logBuilder.append(" kB swap free\n"); 1661 } 1662 Slog.i(TAG, logBuilder.toString()); 1663 1664 StringBuilder dropBuilder = new StringBuilder(1024); 1665 /* 1666 StringWriter oomSw = new StringWriter(); 1667 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1668 StringWriter catSw = new StringWriter(); 1669 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1670 String[] emptyArgs = new String[] { }; 1671 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1672 oomPw.flush(); 1673 String oomString = oomSw.toString(); 1674 */ 1675 dropBuilder.append(stack); 1676 dropBuilder.append('\n'); 1677 dropBuilder.append('\n'); 1678 dropBuilder.append(logBuilder); 1679 dropBuilder.append('\n'); 1680 /* 1681 dropBuilder.append(oomString); 1682 dropBuilder.append('\n'); 1683 */ 1684 StringWriter catSw = new StringWriter(); 1685 synchronized (ActivityManagerService.this) { 1686 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1687 String[] emptyArgs = new String[] { }; 1688 catPw.println(); 1689 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1690 catPw.println(); 1691 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1692 false, false, null); 1693 catPw.println(); 1694 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1695 catPw.flush(); 1696 } 1697 dropBuilder.append(catSw.toString()); 1698 addErrorToDropBox("lowmem", null, "system_server", null, 1699 null, tag.toString(), dropBuilder.toString(), null, null); 1700 //Slog.i(TAG, "Sent to dropbox:"); 1701 //Slog.i(TAG, dropBuilder.toString()); 1702 synchronized (ActivityManagerService.this) { 1703 long now = SystemClock.uptimeMillis(); 1704 if (mLastMemUsageReportTime < now) { 1705 mLastMemUsageReportTime = now; 1706 } 1707 } 1708 } 1709 }; 1710 thread.start(); 1711 break; 1712 } 1713 case REPORT_USER_SWITCH_MSG: { 1714 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1715 break; 1716 } 1717 case CONTINUE_USER_SWITCH_MSG: { 1718 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1719 break; 1720 } 1721 case USER_SWITCH_TIMEOUT_MSG: { 1722 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1723 break; 1724 } 1725 case IMMERSIVE_MODE_LOCK_MSG: { 1726 final boolean nextState = (msg.arg1 != 0); 1727 if (mUpdateLock.isHeld() != nextState) { 1728 if (DEBUG_IMMERSIVE) { 1729 final ActivityRecord r = (ActivityRecord) msg.obj; 1730 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1731 } 1732 if (nextState) { 1733 mUpdateLock.acquire(); 1734 } else { 1735 mUpdateLock.release(); 1736 } 1737 } 1738 break; 1739 } 1740 case PERSIST_URI_GRANTS_MSG: { 1741 writeGrantedUriPermissions(); 1742 break; 1743 } 1744 case REQUEST_ALL_PSS_MSG: { 1745 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1746 break; 1747 } 1748 case START_PROFILES_MSG: { 1749 synchronized (ActivityManagerService.this) { 1750 startProfilesLocked(); 1751 } 1752 break; 1753 } 1754 case UPDATE_TIME: { 1755 synchronized (ActivityManagerService.this) { 1756 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1757 ProcessRecord r = mLruProcesses.get(i); 1758 if (r.thread != null) { 1759 try { 1760 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1761 } catch (RemoteException ex) { 1762 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1763 } 1764 } 1765 } 1766 } 1767 break; 1768 } 1769 case SYSTEM_USER_START_MSG: { 1770 mSystemServiceManager.startUser(msg.arg1); 1771 break; 1772 } 1773 case SYSTEM_USER_CURRENT_MSG: { 1774 mSystemServiceManager.switchUser(msg.arg1); 1775 break; 1776 } 1777 } 1778 } 1779 }; 1780 1781 static final int COLLECT_PSS_BG_MSG = 1; 1782 1783 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1784 @Override 1785 public void handleMessage(Message msg) { 1786 switch (msg.what) { 1787 case COLLECT_PSS_BG_MSG: { 1788 int i=0, num=0; 1789 long start = SystemClock.uptimeMillis(); 1790 long[] tmp = new long[1]; 1791 do { 1792 ProcessRecord proc; 1793 int procState; 1794 int pid; 1795 synchronized (ActivityManagerService.this) { 1796 if (i >= mPendingPssProcesses.size()) { 1797 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1798 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1799 mPendingPssProcesses.clear(); 1800 return; 1801 } 1802 proc = mPendingPssProcesses.get(i); 1803 procState = proc.pssProcState; 1804 if (proc.thread != null && procState == proc.setProcState) { 1805 pid = proc.pid; 1806 } else { 1807 proc = null; 1808 pid = 0; 1809 } 1810 i++; 1811 } 1812 if (proc != null) { 1813 long pss = Debug.getPss(pid, tmp); 1814 synchronized (ActivityManagerService.this) { 1815 if (proc.thread != null && proc.setProcState == procState 1816 && proc.pid == pid) { 1817 num++; 1818 proc.lastPssTime = SystemClock.uptimeMillis(); 1819 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1820 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1821 + ": " + pss + " lastPss=" + proc.lastPss 1822 + " state=" + ProcessList.makeProcStateString(procState)); 1823 if (proc.initialIdlePss == 0) { 1824 proc.initialIdlePss = pss; 1825 } 1826 proc.lastPss = pss; 1827 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1828 proc.lastCachedPss = pss; 1829 } 1830 } 1831 } 1832 } 1833 } while (true); 1834 } 1835 } 1836 } 1837 }; 1838 1839 public void setSystemProcess() { 1840 try { 1841 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1842 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1843 ServiceManager.addService("meminfo", new MemBinder(this)); 1844 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1845 ServiceManager.addService("dbinfo", new DbBinder(this)); 1846 if (MONITOR_CPU_USAGE) { 1847 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1848 } 1849 ServiceManager.addService("permission", new PermissionController(this)); 1850 1851 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1852 "android", STOCK_PM_FLAGS); 1853 mSystemThread.installSystemApplicationInfo(info); 1854 1855 synchronized (this) { 1856 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1857 app.persistent = true; 1858 app.pid = MY_PID; 1859 app.maxAdj = ProcessList.SYSTEM_ADJ; 1860 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1861 mProcessNames.put(app.processName, app.uid, app); 1862 synchronized (mPidsSelfLocked) { 1863 mPidsSelfLocked.put(app.pid, app); 1864 } 1865 updateLruProcessLocked(app, false, null); 1866 updateOomAdjLocked(); 1867 } 1868 } catch (PackageManager.NameNotFoundException e) { 1869 throw new RuntimeException( 1870 "Unable to find android system package", e); 1871 } 1872 } 1873 1874 public void setWindowManager(WindowManagerService wm) { 1875 mWindowManager = wm; 1876 mStackSupervisor.setWindowManager(wm); 1877 } 1878 1879 public void startObservingNativeCrashes() { 1880 final NativeCrashListener ncl = new NativeCrashListener(this); 1881 ncl.start(); 1882 } 1883 1884 public IAppOpsService getAppOpsService() { 1885 return mAppOpsService; 1886 } 1887 1888 static class MemBinder extends Binder { 1889 ActivityManagerService mActivityManagerService; 1890 MemBinder(ActivityManagerService activityManagerService) { 1891 mActivityManagerService = activityManagerService; 1892 } 1893 1894 @Override 1895 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1896 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1897 != PackageManager.PERMISSION_GRANTED) { 1898 pw.println("Permission Denial: can't dump meminfo from from pid=" 1899 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1900 + " without permission " + android.Manifest.permission.DUMP); 1901 return; 1902 } 1903 1904 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1905 } 1906 } 1907 1908 static class GraphicsBinder extends Binder { 1909 ActivityManagerService mActivityManagerService; 1910 GraphicsBinder(ActivityManagerService activityManagerService) { 1911 mActivityManagerService = activityManagerService; 1912 } 1913 1914 @Override 1915 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1916 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1917 != PackageManager.PERMISSION_GRANTED) { 1918 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1919 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1920 + " without permission " + android.Manifest.permission.DUMP); 1921 return; 1922 } 1923 1924 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1925 } 1926 } 1927 1928 static class DbBinder extends Binder { 1929 ActivityManagerService mActivityManagerService; 1930 DbBinder(ActivityManagerService activityManagerService) { 1931 mActivityManagerService = activityManagerService; 1932 } 1933 1934 @Override 1935 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1936 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1937 != PackageManager.PERMISSION_GRANTED) { 1938 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1939 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1940 + " without permission " + android.Manifest.permission.DUMP); 1941 return; 1942 } 1943 1944 mActivityManagerService.dumpDbInfo(fd, pw, args); 1945 } 1946 } 1947 1948 static class CpuBinder extends Binder { 1949 ActivityManagerService mActivityManagerService; 1950 CpuBinder(ActivityManagerService activityManagerService) { 1951 mActivityManagerService = activityManagerService; 1952 } 1953 1954 @Override 1955 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1956 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1957 != PackageManager.PERMISSION_GRANTED) { 1958 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1959 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1960 + " without permission " + android.Manifest.permission.DUMP); 1961 return; 1962 } 1963 1964 synchronized (mActivityManagerService.mProcessCpuThread) { 1965 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1966 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1967 SystemClock.uptimeMillis())); 1968 } 1969 } 1970 } 1971 1972 public static final class Lifecycle extends SystemService { 1973 private final ActivityManagerService mService; 1974 1975 public Lifecycle(Context context) { 1976 super(context); 1977 mService = new ActivityManagerService(context); 1978 } 1979 1980 @Override 1981 public void onStart() { 1982 mService.start(); 1983 } 1984 1985 public ActivityManagerService getService() { 1986 return mService; 1987 } 1988 } 1989 1990 // Note: This method is invoked on the main thread but may need to attach various 1991 // handlers to other threads. So take care to be explicit about the looper. 1992 public ActivityManagerService(Context systemContext) { 1993 mContext = systemContext; 1994 mFactoryTest = FactoryTest.getMode(); 1995 mSystemThread = ActivityThread.currentActivityThread(); 1996 1997 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1998 1999 mHandlerThread = new ServiceThread(TAG, 2000 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2001 mHandlerThread.start(); 2002 mHandler = new MainHandler(mHandlerThread.getLooper()); 2003 2004 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2005 "foreground", BROADCAST_FG_TIMEOUT, false); 2006 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2007 "background", BROADCAST_BG_TIMEOUT, true); 2008 mBroadcastQueues[0] = mFgBroadcastQueue; 2009 mBroadcastQueues[1] = mBgBroadcastQueue; 2010 2011 mServices = new ActiveServices(this); 2012 mProviderMap = new ProviderMap(this); 2013 2014 // TODO: Move creation of battery stats service outside of activity manager service. 2015 File dataDir = Environment.getDataDirectory(); 2016 File systemDir = new File(dataDir, "system"); 2017 systemDir.mkdirs(); 2018 mBatteryStatsService = new BatteryStatsService(new File( 2019 systemDir, "batterystats.bin").toString(), mHandler); 2020 mBatteryStatsService.getActiveStatistics().readLocked(); 2021 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2022 mOnBattery = DEBUG_POWER ? true 2023 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2024 mBatteryStatsService.getActiveStatistics().setCallback(this); 2025 2026 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2027 2028 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2029 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2030 2031 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2032 2033 // User 0 is the first and only user that runs at boot. 2034 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2035 mUserLru.add(Integer.valueOf(0)); 2036 updateStartedUserArrayLocked(); 2037 2038 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2039 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2040 2041 mConfiguration.setToDefaults(); 2042 mConfiguration.setLocale(Locale.getDefault()); 2043 2044 mConfigurationSeq = mConfiguration.seq = 1; 2045 mProcessCpuTracker.init(); 2046 2047 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2048 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2049 mStackSupervisor = new ActivityStackSupervisor(this); 2050 2051 mProcessCpuThread = new Thread("CpuTracker") { 2052 @Override 2053 public void run() { 2054 while (true) { 2055 try { 2056 try { 2057 synchronized(this) { 2058 final long now = SystemClock.uptimeMillis(); 2059 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2060 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2061 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2062 // + ", write delay=" + nextWriteDelay); 2063 if (nextWriteDelay < nextCpuDelay) { 2064 nextCpuDelay = nextWriteDelay; 2065 } 2066 if (nextCpuDelay > 0) { 2067 mProcessCpuMutexFree.set(true); 2068 this.wait(nextCpuDelay); 2069 } 2070 } 2071 } catch (InterruptedException e) { 2072 } 2073 updateCpuStatsNow(); 2074 } catch (Exception e) { 2075 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2076 } 2077 } 2078 } 2079 }; 2080 2081 Watchdog.getInstance().addMonitor(this); 2082 Watchdog.getInstance().addThread(mHandler); 2083 } 2084 2085 public void setSystemServiceManager(SystemServiceManager mgr) { 2086 mSystemServiceManager = mgr; 2087 } 2088 2089 private void start() { 2090 mProcessCpuThread.start(); 2091 2092 mBatteryStatsService.publish(mContext); 2093 mUsageStatsService.publish(mContext); 2094 mAppOpsService.publish(mContext); 2095 2096 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2097 } 2098 2099 @Override 2100 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2101 throws RemoteException { 2102 if (code == SYSPROPS_TRANSACTION) { 2103 // We need to tell all apps about the system property change. 2104 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2105 synchronized(this) { 2106 final int NP = mProcessNames.getMap().size(); 2107 for (int ip=0; ip<NP; ip++) { 2108 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2109 final int NA = apps.size(); 2110 for (int ia=0; ia<NA; ia++) { 2111 ProcessRecord app = apps.valueAt(ia); 2112 if (app.thread != null) { 2113 procs.add(app.thread.asBinder()); 2114 } 2115 } 2116 } 2117 } 2118 2119 int N = procs.size(); 2120 for (int i=0; i<N; i++) { 2121 Parcel data2 = Parcel.obtain(); 2122 try { 2123 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2124 } catch (RemoteException e) { 2125 } 2126 data2.recycle(); 2127 } 2128 } 2129 try { 2130 return super.onTransact(code, data, reply, flags); 2131 } catch (RuntimeException e) { 2132 // The activity manager only throws security exceptions, so let's 2133 // log all others. 2134 if (!(e instanceof SecurityException)) { 2135 Slog.wtf(TAG, "Activity Manager Crash", e); 2136 } 2137 throw e; 2138 } 2139 } 2140 2141 void updateCpuStats() { 2142 final long now = SystemClock.uptimeMillis(); 2143 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2144 return; 2145 } 2146 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2147 synchronized (mProcessCpuThread) { 2148 mProcessCpuThread.notify(); 2149 } 2150 } 2151 } 2152 2153 void updateCpuStatsNow() { 2154 synchronized (mProcessCpuThread) { 2155 mProcessCpuMutexFree.set(false); 2156 final long now = SystemClock.uptimeMillis(); 2157 boolean haveNewCpuStats = false; 2158 2159 if (MONITOR_CPU_USAGE && 2160 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2161 mLastCpuTime.set(now); 2162 haveNewCpuStats = true; 2163 mProcessCpuTracker.update(); 2164 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2165 //Slog.i(TAG, "Total CPU usage: " 2166 // + mProcessCpu.getTotalCpuPercent() + "%"); 2167 2168 // Slog the cpu usage if the property is set. 2169 if ("true".equals(SystemProperties.get("events.cpu"))) { 2170 int user = mProcessCpuTracker.getLastUserTime(); 2171 int system = mProcessCpuTracker.getLastSystemTime(); 2172 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2173 int irq = mProcessCpuTracker.getLastIrqTime(); 2174 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2175 int idle = mProcessCpuTracker.getLastIdleTime(); 2176 2177 int total = user + system + iowait + irq + softIrq + idle; 2178 if (total == 0) total = 1; 2179 2180 EventLog.writeEvent(EventLogTags.CPU, 2181 ((user+system+iowait+irq+softIrq) * 100) / total, 2182 (user * 100) / total, 2183 (system * 100) / total, 2184 (iowait * 100) / total, 2185 (irq * 100) / total, 2186 (softIrq * 100) / total); 2187 } 2188 } 2189 2190 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2191 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2192 synchronized(bstats) { 2193 synchronized(mPidsSelfLocked) { 2194 if (haveNewCpuStats) { 2195 if (mOnBattery) { 2196 int perc = bstats.startAddingCpuLocked(); 2197 int totalUTime = 0; 2198 int totalSTime = 0; 2199 final int N = mProcessCpuTracker.countStats(); 2200 for (int i=0; i<N; i++) { 2201 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2202 if (!st.working) { 2203 continue; 2204 } 2205 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2206 int otherUTime = (st.rel_utime*perc)/100; 2207 int otherSTime = (st.rel_stime*perc)/100; 2208 totalUTime += otherUTime; 2209 totalSTime += otherSTime; 2210 if (pr != null) { 2211 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2212 if (ps == null || !ps.isActive()) { 2213 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2214 pr.info.uid, pr.processName); 2215 } 2216 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2217 st.rel_stime-otherSTime); 2218 ps.addSpeedStepTimes(cpuSpeedTimes); 2219 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2220 } else { 2221 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2222 if (ps == null || !ps.isActive()) { 2223 st.batteryStats = ps = bstats.getProcessStatsLocked( 2224 bstats.mapUid(st.uid), st.name); 2225 } 2226 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2227 st.rel_stime-otherSTime); 2228 ps.addSpeedStepTimes(cpuSpeedTimes); 2229 } 2230 } 2231 bstats.finishAddingCpuLocked(perc, totalUTime, 2232 totalSTime, cpuSpeedTimes); 2233 } 2234 } 2235 } 2236 2237 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2238 mLastWriteTime = now; 2239 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2240 } 2241 } 2242 } 2243 } 2244 2245 @Override 2246 public void batteryNeedsCpuUpdate() { 2247 updateCpuStatsNow(); 2248 } 2249 2250 @Override 2251 public void batteryPowerChanged(boolean onBattery) { 2252 // When plugging in, update the CPU stats first before changing 2253 // the plug state. 2254 updateCpuStatsNow(); 2255 synchronized (this) { 2256 synchronized(mPidsSelfLocked) { 2257 mOnBattery = DEBUG_POWER ? true : onBattery; 2258 } 2259 } 2260 } 2261 2262 /** 2263 * Initialize the application bind args. These are passed to each 2264 * process when the bindApplication() IPC is sent to the process. They're 2265 * lazily setup to make sure the services are running when they're asked for. 2266 */ 2267 private HashMap<String, IBinder> getCommonServicesLocked() { 2268 if (mAppBindArgs == null) { 2269 mAppBindArgs = new HashMap<String, IBinder>(); 2270 2271 // Setup the application init args 2272 mAppBindArgs.put("package", ServiceManager.getService("package")); 2273 mAppBindArgs.put("window", ServiceManager.getService("window")); 2274 mAppBindArgs.put(Context.ALARM_SERVICE, 2275 ServiceManager.getService(Context.ALARM_SERVICE)); 2276 } 2277 return mAppBindArgs; 2278 } 2279 2280 final void setFocusedActivityLocked(ActivityRecord r) { 2281 if (mFocusedActivity != r) { 2282 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2283 mFocusedActivity = r; 2284 if (r.task != null && r.task.voiceInteractor != null) { 2285 startRunningVoiceLocked(); 2286 } else { 2287 finishRunningVoiceLocked(); 2288 } 2289 mStackSupervisor.setFocusedStack(r); 2290 if (r != null) { 2291 mWindowManager.setFocusedApp(r.appToken, true); 2292 } 2293 applyUpdateLockStateLocked(r); 2294 } 2295 } 2296 2297 final void clearFocusedActivity(ActivityRecord r) { 2298 if (mFocusedActivity == r) { 2299 mFocusedActivity = null; 2300 } 2301 } 2302 2303 @Override 2304 public void setFocusedStack(int stackId) { 2305 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2306 synchronized (ActivityManagerService.this) { 2307 ActivityStack stack = mStackSupervisor.getStack(stackId); 2308 if (stack != null) { 2309 ActivityRecord r = stack.topRunningActivityLocked(null); 2310 if (r != null) { 2311 setFocusedActivityLocked(r); 2312 } 2313 } 2314 } 2315 } 2316 2317 @Override 2318 public void notifyActivityDrawn(IBinder token) { 2319 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2320 synchronized (this) { 2321 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2322 if (r != null) { 2323 r.task.stack.notifyActivityDrawnLocked(r); 2324 } 2325 } 2326 } 2327 2328 final void applyUpdateLockStateLocked(ActivityRecord r) { 2329 // Modifications to the UpdateLock state are done on our handler, outside 2330 // the activity manager's locks. The new state is determined based on the 2331 // state *now* of the relevant activity record. The object is passed to 2332 // the handler solely for logging detail, not to be consulted/modified. 2333 final boolean nextState = r != null && r.immersive; 2334 mHandler.sendMessage( 2335 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2336 } 2337 2338 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2339 Message msg = Message.obtain(); 2340 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2341 msg.obj = r.task.askedCompatMode ? null : r; 2342 mHandler.sendMessage(msg); 2343 } 2344 2345 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2346 String what, Object obj, ProcessRecord srcApp) { 2347 app.lastActivityTime = now; 2348 2349 if (app.activities.size() > 0) { 2350 // Don't want to touch dependent processes that are hosting activities. 2351 return index; 2352 } 2353 2354 int lrui = mLruProcesses.lastIndexOf(app); 2355 if (lrui < 0) { 2356 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2357 + what + " " + obj + " from " + srcApp); 2358 return index; 2359 } 2360 2361 if (lrui >= index) { 2362 // Don't want to cause this to move dependent processes *back* in the 2363 // list as if they were less frequently used. 2364 return index; 2365 } 2366 2367 if (lrui >= mLruProcessActivityStart) { 2368 // Don't want to touch dependent processes that are hosting activities. 2369 return index; 2370 } 2371 2372 mLruProcesses.remove(lrui); 2373 if (index > 0) { 2374 index--; 2375 } 2376 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2377 + " in LRU list: " + app); 2378 mLruProcesses.add(index, app); 2379 return index; 2380 } 2381 2382 final void removeLruProcessLocked(ProcessRecord app) { 2383 int lrui = mLruProcesses.lastIndexOf(app); 2384 if (lrui >= 0) { 2385 if (lrui <= mLruProcessActivityStart) { 2386 mLruProcessActivityStart--; 2387 } 2388 if (lrui <= mLruProcessServiceStart) { 2389 mLruProcessServiceStart--; 2390 } 2391 mLruProcesses.remove(lrui); 2392 } 2393 } 2394 2395 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2396 ProcessRecord client) { 2397 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2398 || app.treatLikeActivity; 2399 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2400 if (!activityChange && hasActivity) { 2401 // The process has activities, so we are only allowing activity-based adjustments 2402 // to move it. It should be kept in the front of the list with other 2403 // processes that have activities, and we don't want those to change their 2404 // order except due to activity operations. 2405 return; 2406 } 2407 2408 mLruSeq++; 2409 final long now = SystemClock.uptimeMillis(); 2410 app.lastActivityTime = now; 2411 2412 // First a quick reject: if the app is already at the position we will 2413 // put it, then there is nothing to do. 2414 if (hasActivity) { 2415 final int N = mLruProcesses.size(); 2416 if (N > 0 && mLruProcesses.get(N-1) == app) { 2417 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2418 return; 2419 } 2420 } else { 2421 if (mLruProcessServiceStart > 0 2422 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2423 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2424 return; 2425 } 2426 } 2427 2428 int lrui = mLruProcesses.lastIndexOf(app); 2429 2430 if (app.persistent && lrui >= 0) { 2431 // We don't care about the position of persistent processes, as long as 2432 // they are in the list. 2433 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2434 return; 2435 } 2436 2437 /* In progress: compute new position first, so we can avoid doing work 2438 if the process is not actually going to move. Not yet working. 2439 int addIndex; 2440 int nextIndex; 2441 boolean inActivity = false, inService = false; 2442 if (hasActivity) { 2443 // Process has activities, put it at the very tipsy-top. 2444 addIndex = mLruProcesses.size(); 2445 nextIndex = mLruProcessServiceStart; 2446 inActivity = true; 2447 } else if (hasService) { 2448 // Process has services, put it at the top of the service list. 2449 addIndex = mLruProcessActivityStart; 2450 nextIndex = mLruProcessServiceStart; 2451 inActivity = true; 2452 inService = true; 2453 } else { 2454 // Process not otherwise of interest, it goes to the top of the non-service area. 2455 addIndex = mLruProcessServiceStart; 2456 if (client != null) { 2457 int clientIndex = mLruProcesses.lastIndexOf(client); 2458 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2459 + app); 2460 if (clientIndex >= 0 && addIndex > clientIndex) { 2461 addIndex = clientIndex; 2462 } 2463 } 2464 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2465 } 2466 2467 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2468 + mLruProcessActivityStart + "): " + app); 2469 */ 2470 2471 if (lrui >= 0) { 2472 if (lrui < mLruProcessActivityStart) { 2473 mLruProcessActivityStart--; 2474 } 2475 if (lrui < mLruProcessServiceStart) { 2476 mLruProcessServiceStart--; 2477 } 2478 /* 2479 if (addIndex > lrui) { 2480 addIndex--; 2481 } 2482 if (nextIndex > lrui) { 2483 nextIndex--; 2484 } 2485 */ 2486 mLruProcesses.remove(lrui); 2487 } 2488 2489 /* 2490 mLruProcesses.add(addIndex, app); 2491 if (inActivity) { 2492 mLruProcessActivityStart++; 2493 } 2494 if (inService) { 2495 mLruProcessActivityStart++; 2496 } 2497 */ 2498 2499 int nextIndex; 2500 if (hasActivity) { 2501 final int N = mLruProcesses.size(); 2502 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2503 // Process doesn't have activities, but has clients with 2504 // activities... move it up, but one below the top (the top 2505 // should always have a real activity). 2506 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2507 mLruProcesses.add(N-1, app); 2508 // To keep it from spamming the LRU list (by making a bunch of clients), 2509 // we will push down any other entries owned by the app. 2510 final int uid = app.info.uid; 2511 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2512 ProcessRecord subProc = mLruProcesses.get(i); 2513 if (subProc.info.uid == uid) { 2514 // We want to push this one down the list. If the process after 2515 // it is for the same uid, however, don't do so, because we don't 2516 // want them internally to be re-ordered. 2517 if (mLruProcesses.get(i-1).info.uid != uid) { 2518 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2519 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2520 ProcessRecord tmp = mLruProcesses.get(i); 2521 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2522 mLruProcesses.set(i-1, tmp); 2523 i--; 2524 } 2525 } else { 2526 // A gap, we can stop here. 2527 break; 2528 } 2529 } 2530 } else { 2531 // Process has activities, put it at the very tipsy-top. 2532 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2533 mLruProcesses.add(app); 2534 } 2535 nextIndex = mLruProcessServiceStart; 2536 } else if (hasService) { 2537 // Process has services, put it at the top of the service list. 2538 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2539 mLruProcesses.add(mLruProcessActivityStart, app); 2540 nextIndex = mLruProcessServiceStart; 2541 mLruProcessActivityStart++; 2542 } else { 2543 // Process not otherwise of interest, it goes to the top of the non-service area. 2544 int index = mLruProcessServiceStart; 2545 if (client != null) { 2546 // If there is a client, don't allow the process to be moved up higher 2547 // in the list than that client. 2548 int clientIndex = mLruProcesses.lastIndexOf(client); 2549 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2550 + " when updating " + app); 2551 if (clientIndex <= lrui) { 2552 // Don't allow the client index restriction to push it down farther in the 2553 // list than it already is. 2554 clientIndex = lrui; 2555 } 2556 if (clientIndex >= 0 && index > clientIndex) { 2557 index = clientIndex; 2558 } 2559 } 2560 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2561 mLruProcesses.add(index, app); 2562 nextIndex = index-1; 2563 mLruProcessActivityStart++; 2564 mLruProcessServiceStart++; 2565 } 2566 2567 // If the app is currently using a content provider or service, 2568 // bump those processes as well. 2569 for (int j=app.connections.size()-1; j>=0; j--) { 2570 ConnectionRecord cr = app.connections.valueAt(j); 2571 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2572 && cr.binding.service.app != null 2573 && cr.binding.service.app.lruSeq != mLruSeq 2574 && !cr.binding.service.app.persistent) { 2575 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2576 "service connection", cr, app); 2577 } 2578 } 2579 for (int j=app.conProviders.size()-1; j>=0; j--) { 2580 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2581 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2582 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2583 "provider reference", cpr, app); 2584 } 2585 } 2586 } 2587 2588 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2589 if (uid == Process.SYSTEM_UID) { 2590 // The system gets to run in any process. If there are multiple 2591 // processes with the same uid, just pick the first (this 2592 // should never happen). 2593 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2594 if (procs == null) return null; 2595 final int N = procs.size(); 2596 for (int i = 0; i < N; i++) { 2597 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2598 } 2599 } 2600 ProcessRecord proc = mProcessNames.get(processName, uid); 2601 if (false && proc != null && !keepIfLarge 2602 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2603 && proc.lastCachedPss >= 4000) { 2604 // Turn this condition on to cause killing to happen regularly, for testing. 2605 if (proc.baseProcessTracker != null) { 2606 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2607 } 2608 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2609 + "k from cached"); 2610 } else if (proc != null && !keepIfLarge 2611 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2612 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2613 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2614 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2615 if (proc.baseProcessTracker != null) { 2616 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2617 } 2618 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2619 + "k from cached"); 2620 } 2621 } 2622 return proc; 2623 } 2624 2625 void ensurePackageDexOpt(String packageName) { 2626 IPackageManager pm = AppGlobals.getPackageManager(); 2627 try { 2628 if (pm.performDexOpt(packageName)) { 2629 mDidDexOpt = true; 2630 } 2631 } catch (RemoteException e) { 2632 } 2633 } 2634 2635 boolean isNextTransitionForward() { 2636 int transit = mWindowManager.getPendingAppTransition(); 2637 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2638 || transit == AppTransition.TRANSIT_TASK_OPEN 2639 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2640 } 2641 2642 final ProcessRecord startProcessLocked(String processName, 2643 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2644 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2645 boolean isolated, boolean keepIfLarge) { 2646 ProcessRecord app; 2647 if (!isolated) { 2648 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2649 } else { 2650 // If this is an isolated process, it can't re-use an existing process. 2651 app = null; 2652 } 2653 // We don't have to do anything more if: 2654 // (1) There is an existing application record; and 2655 // (2) The caller doesn't think it is dead, OR there is no thread 2656 // object attached to it so we know it couldn't have crashed; and 2657 // (3) There is a pid assigned to it, so it is either starting or 2658 // already running. 2659 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2660 + " app=" + app + " knownToBeDead=" + knownToBeDead 2661 + " thread=" + (app != null ? app.thread : null) 2662 + " pid=" + (app != null ? app.pid : -1)); 2663 if (app != null && app.pid > 0) { 2664 if (!knownToBeDead || app.thread == null) { 2665 // We already have the app running, or are waiting for it to 2666 // come up (we have a pid but not yet its thread), so keep it. 2667 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2668 // If this is a new package in the process, add the package to the list 2669 app.addPackage(info.packageName, mProcessStats); 2670 return app; 2671 } 2672 2673 // An application record is attached to a previous process, 2674 // clean it up now. 2675 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2676 handleAppDiedLocked(app, true, true); 2677 } 2678 2679 String hostingNameStr = hostingName != null 2680 ? hostingName.flattenToShortString() : null; 2681 2682 if (!isolated) { 2683 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2684 // If we are in the background, then check to see if this process 2685 // is bad. If so, we will just silently fail. 2686 if (mBadProcesses.get(info.processName, info.uid) != null) { 2687 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2688 + "/" + info.processName); 2689 return null; 2690 } 2691 } else { 2692 // When the user is explicitly starting a process, then clear its 2693 // crash count so that we won't make it bad until they see at 2694 // least one crash dialog again, and make the process good again 2695 // if it had been bad. 2696 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2697 + "/" + info.processName); 2698 mProcessCrashTimes.remove(info.processName, info.uid); 2699 if (mBadProcesses.get(info.processName, info.uid) != null) { 2700 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2701 UserHandle.getUserId(info.uid), info.uid, 2702 info.processName); 2703 mBadProcesses.remove(info.processName, info.uid); 2704 if (app != null) { 2705 app.bad = false; 2706 } 2707 } 2708 } 2709 } 2710 2711 if (app == null) { 2712 app = newProcessRecordLocked(info, processName, isolated); 2713 if (app == null) { 2714 Slog.w(TAG, "Failed making new process record for " 2715 + processName + "/" + info.uid + " isolated=" + isolated); 2716 return null; 2717 } 2718 mProcessNames.put(processName, app.uid, app); 2719 if (isolated) { 2720 mIsolatedProcesses.put(app.uid, app); 2721 } 2722 } else { 2723 // If this is a new package in the process, add the package to the list 2724 app.addPackage(info.packageName, mProcessStats); 2725 } 2726 2727 // If the system is not ready yet, then hold off on starting this 2728 // process until it is. 2729 if (!mProcessesReady 2730 && !isAllowedWhileBooting(info) 2731 && !allowWhileBooting) { 2732 if (!mProcessesOnHold.contains(app)) { 2733 mProcessesOnHold.add(app); 2734 } 2735 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2736 return app; 2737 } 2738 2739 startProcessLocked(app, hostingType, hostingNameStr); 2740 return (app.pid != 0) ? app : null; 2741 } 2742 2743 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2744 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2745 } 2746 2747 private final void startProcessLocked(ProcessRecord app, 2748 String hostingType, String hostingNameStr) { 2749 if (app.pid > 0 && app.pid != MY_PID) { 2750 synchronized (mPidsSelfLocked) { 2751 mPidsSelfLocked.remove(app.pid); 2752 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2753 } 2754 app.setPid(0); 2755 } 2756 2757 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2758 "startProcessLocked removing on hold: " + app); 2759 mProcessesOnHold.remove(app); 2760 2761 updateCpuStats(); 2762 2763 try { 2764 int uid = app.uid; 2765 2766 int[] gids = null; 2767 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2768 if (!app.isolated) { 2769 int[] permGids = null; 2770 try { 2771 final PackageManager pm = mContext.getPackageManager(); 2772 permGids = pm.getPackageGids(app.info.packageName); 2773 2774 if (Environment.isExternalStorageEmulated()) { 2775 if (pm.checkPermission( 2776 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2777 app.info.packageName) == PERMISSION_GRANTED) { 2778 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2779 } else { 2780 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2781 } 2782 } 2783 } catch (PackageManager.NameNotFoundException e) { 2784 Slog.w(TAG, "Unable to retrieve gids", e); 2785 } 2786 2787 /* 2788 * Add shared application GID so applications can share some 2789 * resources like shared libraries 2790 */ 2791 if (permGids == null) { 2792 gids = new int[1]; 2793 } else { 2794 gids = new int[permGids.length + 1]; 2795 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2796 } 2797 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2798 } 2799 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2800 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2801 && mTopComponent != null 2802 && app.processName.equals(mTopComponent.getPackageName())) { 2803 uid = 0; 2804 } 2805 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2806 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2807 uid = 0; 2808 } 2809 } 2810 int debugFlags = 0; 2811 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2812 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2813 // Also turn on CheckJNI for debuggable apps. It's quite 2814 // awkward to turn on otherwise. 2815 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2816 } 2817 // Run the app in safe mode if its manifest requests so or the 2818 // system is booted in safe mode. 2819 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2820 mSafeMode == true) { 2821 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2822 } 2823 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2824 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2825 } 2826 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2827 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2828 } 2829 if ("1".equals(SystemProperties.get("debug.assert"))) { 2830 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2831 } 2832 2833 String requiredAbi = app.info.requiredCpuAbi; 2834 if (requiredAbi == null) { 2835 requiredAbi = Build.SUPPORTED_ABIS[0]; 2836 } 2837 2838 // Start the process. It will either succeed and return a result containing 2839 // the PID of the new process, or else throw a RuntimeException. 2840 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2841 app.processName, uid, uid, gids, debugFlags, mountExternal, 2842 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2843 2844 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2845 synchronized (bs) { 2846 if (bs.isOnBattery()) { 2847 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2848 } 2849 } 2850 2851 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2852 UserHandle.getUserId(uid), startResult.pid, uid, 2853 app.processName, hostingType, 2854 hostingNameStr != null ? hostingNameStr : ""); 2855 2856 if (app.persistent) { 2857 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2858 } 2859 2860 StringBuilder buf = mStringBuilder; 2861 buf.setLength(0); 2862 buf.append("Start proc "); 2863 buf.append(app.processName); 2864 buf.append(" for "); 2865 buf.append(hostingType); 2866 if (hostingNameStr != null) { 2867 buf.append(" "); 2868 buf.append(hostingNameStr); 2869 } 2870 buf.append(": pid="); 2871 buf.append(startResult.pid); 2872 buf.append(" uid="); 2873 buf.append(uid); 2874 buf.append(" gids={"); 2875 if (gids != null) { 2876 for (int gi=0; gi<gids.length; gi++) { 2877 if (gi != 0) buf.append(", "); 2878 buf.append(gids[gi]); 2879 2880 } 2881 } 2882 buf.append("}"); 2883 Slog.i(TAG, buf.toString()); 2884 app.setPid(startResult.pid); 2885 app.usingWrapper = startResult.usingWrapper; 2886 app.removed = false; 2887 synchronized (mPidsSelfLocked) { 2888 this.mPidsSelfLocked.put(startResult.pid, app); 2889 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2890 msg.obj = app; 2891 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2892 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2893 } 2894 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2895 app.processName, app.info.uid); 2896 if (app.isolated) { 2897 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2898 } 2899 } catch (RuntimeException e) { 2900 // XXX do better error recovery. 2901 app.setPid(0); 2902 Slog.e(TAG, "Failure starting process " + app.processName, e); 2903 } 2904 } 2905 2906 void updateUsageStats(ActivityRecord component, boolean resumed) { 2907 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2908 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2909 if (resumed) { 2910 mUsageStatsService.noteResumeComponent(component.realActivity); 2911 synchronized (stats) { 2912 stats.noteActivityResumedLocked(component.app.uid); 2913 } 2914 } else { 2915 mUsageStatsService.notePauseComponent(component.realActivity); 2916 synchronized (stats) { 2917 stats.noteActivityPausedLocked(component.app.uid); 2918 } 2919 } 2920 } 2921 2922 Intent getHomeIntent() { 2923 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2924 intent.setComponent(mTopComponent); 2925 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2926 intent.addCategory(Intent.CATEGORY_HOME); 2927 } 2928 return intent; 2929 } 2930 2931 boolean startHomeActivityLocked(int userId) { 2932 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2933 && mTopAction == null) { 2934 // We are running in factory test mode, but unable to find 2935 // the factory test app, so just sit around displaying the 2936 // error message and don't try to start anything. 2937 return false; 2938 } 2939 Intent intent = getHomeIntent(); 2940 ActivityInfo aInfo = 2941 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2942 if (aInfo != null) { 2943 intent.setComponent(new ComponentName( 2944 aInfo.applicationInfo.packageName, aInfo.name)); 2945 // Don't do this if the home app is currently being 2946 // instrumented. 2947 aInfo = new ActivityInfo(aInfo); 2948 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2949 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2950 aInfo.applicationInfo.uid, true); 2951 if (app == null || app.instrumentationClass == null) { 2952 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2953 mStackSupervisor.startHomeActivity(intent, aInfo); 2954 } 2955 } 2956 2957 return true; 2958 } 2959 2960 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2961 ActivityInfo ai = null; 2962 ComponentName comp = intent.getComponent(); 2963 try { 2964 if (comp != null) { 2965 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2966 } else { 2967 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2968 intent, 2969 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2970 flags, userId); 2971 2972 if (info != null) { 2973 ai = info.activityInfo; 2974 } 2975 } 2976 } catch (RemoteException e) { 2977 // ignore 2978 } 2979 2980 return ai; 2981 } 2982 2983 /** 2984 * Starts the "new version setup screen" if appropriate. 2985 */ 2986 void startSetupActivityLocked() { 2987 // Only do this once per boot. 2988 if (mCheckedForSetup) { 2989 return; 2990 } 2991 2992 // We will show this screen if the current one is a different 2993 // version than the last one shown, and we are not running in 2994 // low-level factory test mode. 2995 final ContentResolver resolver = mContext.getContentResolver(); 2996 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2997 Settings.Global.getInt(resolver, 2998 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2999 mCheckedForSetup = true; 3000 3001 // See if we should be showing the platform update setup UI. 3002 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3003 List<ResolveInfo> ris = mContext.getPackageManager() 3004 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3005 3006 // We don't allow third party apps to replace this. 3007 ResolveInfo ri = null; 3008 for (int i=0; ris != null && i<ris.size(); i++) { 3009 if ((ris.get(i).activityInfo.applicationInfo.flags 3010 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3011 ri = ris.get(i); 3012 break; 3013 } 3014 } 3015 3016 if (ri != null) { 3017 String vers = ri.activityInfo.metaData != null 3018 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3019 : null; 3020 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3021 vers = ri.activityInfo.applicationInfo.metaData.getString( 3022 Intent.METADATA_SETUP_VERSION); 3023 } 3024 String lastVers = Settings.Secure.getString( 3025 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3026 if (vers != null && !vers.equals(lastVers)) { 3027 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3028 intent.setComponent(new ComponentName( 3029 ri.activityInfo.packageName, ri.activityInfo.name)); 3030 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3031 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3032 } 3033 } 3034 } 3035 } 3036 3037 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3038 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3039 } 3040 3041 void enforceNotIsolatedCaller(String caller) { 3042 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3043 throw new SecurityException("Isolated process not allowed to call " + caller); 3044 } 3045 } 3046 3047 @Override 3048 public int getFrontActivityScreenCompatMode() { 3049 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3050 synchronized (this) { 3051 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3052 } 3053 } 3054 3055 @Override 3056 public void setFrontActivityScreenCompatMode(int mode) { 3057 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3058 "setFrontActivityScreenCompatMode"); 3059 synchronized (this) { 3060 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3061 } 3062 } 3063 3064 @Override 3065 public int getPackageScreenCompatMode(String packageName) { 3066 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3067 synchronized (this) { 3068 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3069 } 3070 } 3071 3072 @Override 3073 public void setPackageScreenCompatMode(String packageName, int mode) { 3074 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3075 "setPackageScreenCompatMode"); 3076 synchronized (this) { 3077 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3078 } 3079 } 3080 3081 @Override 3082 public boolean getPackageAskScreenCompat(String packageName) { 3083 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3084 synchronized (this) { 3085 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3086 } 3087 } 3088 3089 @Override 3090 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3091 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3092 "setPackageAskScreenCompat"); 3093 synchronized (this) { 3094 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3095 } 3096 } 3097 3098 private void dispatchProcessesChanged() { 3099 int N; 3100 synchronized (this) { 3101 N = mPendingProcessChanges.size(); 3102 if (mActiveProcessChanges.length < N) { 3103 mActiveProcessChanges = new ProcessChangeItem[N]; 3104 } 3105 mPendingProcessChanges.toArray(mActiveProcessChanges); 3106 mAvailProcessChanges.addAll(mPendingProcessChanges); 3107 mPendingProcessChanges.clear(); 3108 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3109 } 3110 3111 int i = mProcessObservers.beginBroadcast(); 3112 while (i > 0) { 3113 i--; 3114 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3115 if (observer != null) { 3116 try { 3117 for (int j=0; j<N; j++) { 3118 ProcessChangeItem item = mActiveProcessChanges[j]; 3119 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3120 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3121 + item.pid + " uid=" + item.uid + ": " 3122 + item.foregroundActivities); 3123 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3124 item.foregroundActivities); 3125 } 3126 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3127 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3128 + item.pid + " uid=" + item.uid + ": " + item.importance); 3129 observer.onImportanceChanged(item.pid, item.uid, 3130 item.importance); 3131 } 3132 } 3133 } catch (RemoteException e) { 3134 } 3135 } 3136 } 3137 mProcessObservers.finishBroadcast(); 3138 } 3139 3140 private void dispatchProcessDied(int pid, int uid) { 3141 int i = mProcessObservers.beginBroadcast(); 3142 while (i > 0) { 3143 i--; 3144 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3145 if (observer != null) { 3146 try { 3147 observer.onProcessDied(pid, uid); 3148 } catch (RemoteException e) { 3149 } 3150 } 3151 } 3152 mProcessObservers.finishBroadcast(); 3153 } 3154 3155 final void doPendingActivityLaunchesLocked(boolean doResume) { 3156 final int N = mPendingActivityLaunches.size(); 3157 if (N <= 0) { 3158 return; 3159 } 3160 for (int i=0; i<N; i++) { 3161 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3162 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3163 doResume && i == (N-1), null); 3164 } 3165 mPendingActivityLaunches.clear(); 3166 } 3167 3168 @Override 3169 public final int startActivity(IApplicationThread caller, String callingPackage, 3170 Intent intent, String resolvedType, IBinder resultTo, 3171 String resultWho, int requestCode, int startFlags, 3172 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3173 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3174 resultWho, requestCode, 3175 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3176 } 3177 3178 @Override 3179 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3180 Intent intent, String resolvedType, IBinder resultTo, 3181 String resultWho, int requestCode, int startFlags, 3182 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3183 enforceNotIsolatedCaller("startActivity"); 3184 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3185 false, true, "startActivity", null); 3186 // TODO: Switch to user app stacks here. 3187 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3188 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3189 null, null, options, userId, null); 3190 } 3191 3192 @Override 3193 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3194 Intent intent, String resolvedType, IBinder resultTo, 3195 String resultWho, int requestCode, int startFlags, String profileFile, 3196 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3197 enforceNotIsolatedCaller("startActivityAndWait"); 3198 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3199 false, true, "startActivityAndWait", null); 3200 WaitResult res = new WaitResult(); 3201 // TODO: Switch to user app stacks here. 3202 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3203 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3204 res, null, options, UserHandle.getCallingUserId(), null); 3205 return res; 3206 } 3207 3208 @Override 3209 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3210 Intent intent, String resolvedType, IBinder resultTo, 3211 String resultWho, int requestCode, int startFlags, Configuration config, 3212 Bundle options, int userId) { 3213 enforceNotIsolatedCaller("startActivityWithConfig"); 3214 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3215 false, true, "startActivityWithConfig", null); 3216 // TODO: Switch to user app stacks here. 3217 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3218 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3219 null, null, null, config, options, userId, null); 3220 return ret; 3221 } 3222 3223 @Override 3224 public int startActivityIntentSender(IApplicationThread caller, 3225 IntentSender intent, Intent fillInIntent, String resolvedType, 3226 IBinder resultTo, String resultWho, int requestCode, 3227 int flagsMask, int flagsValues, Bundle options) { 3228 enforceNotIsolatedCaller("startActivityIntentSender"); 3229 // Refuse possible leaked file descriptors 3230 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3231 throw new IllegalArgumentException("File descriptors passed in Intent"); 3232 } 3233 3234 IIntentSender sender = intent.getTarget(); 3235 if (!(sender instanceof PendingIntentRecord)) { 3236 throw new IllegalArgumentException("Bad PendingIntent object"); 3237 } 3238 3239 PendingIntentRecord pir = (PendingIntentRecord)sender; 3240 3241 synchronized (this) { 3242 // If this is coming from the currently resumed activity, it is 3243 // effectively saying that app switches are allowed at this point. 3244 final ActivityStack stack = getFocusedStack(); 3245 if (stack.mResumedActivity != null && 3246 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3247 mAppSwitchesAllowedTime = 0; 3248 } 3249 } 3250 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3251 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3252 return ret; 3253 } 3254 3255 @Override 3256 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3257 Intent intent, String resolvedType, IVoiceInteractionSession session, 3258 IVoiceInteractor interactor, int startFlags, String profileFile, 3259 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3260 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3261 != PackageManager.PERMISSION_GRANTED) { 3262 String msg = "Permission Denial: startVoiceActivity() from pid=" 3263 + Binder.getCallingPid() 3264 + ", uid=" + Binder.getCallingUid() 3265 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3266 Slog.w(TAG, msg); 3267 throw new SecurityException(msg); 3268 } 3269 if (session == null || interactor == null) { 3270 throw new NullPointerException("null session or interactor"); 3271 } 3272 userId = handleIncomingUser(callingPid, callingUid, userId, 3273 false, true, "startVoiceActivity", null); 3274 // TODO: Switch to user app stacks here. 3275 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3276 resolvedType, session, interactor, null, null, 0, startFlags, 3277 profileFile, profileFd, null, null, options, userId, null); 3278 } 3279 3280 @Override 3281 public boolean startNextMatchingActivity(IBinder callingActivity, 3282 Intent intent, Bundle options) { 3283 // Refuse possible leaked file descriptors 3284 if (intent != null && intent.hasFileDescriptors() == true) { 3285 throw new IllegalArgumentException("File descriptors passed in Intent"); 3286 } 3287 3288 synchronized (this) { 3289 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3290 if (r == null) { 3291 ActivityOptions.abort(options); 3292 return false; 3293 } 3294 if (r.app == null || r.app.thread == null) { 3295 // The caller is not running... d'oh! 3296 ActivityOptions.abort(options); 3297 return false; 3298 } 3299 intent = new Intent(intent); 3300 // The caller is not allowed to change the data. 3301 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3302 // And we are resetting to find the next component... 3303 intent.setComponent(null); 3304 3305 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3306 3307 ActivityInfo aInfo = null; 3308 try { 3309 List<ResolveInfo> resolves = 3310 AppGlobals.getPackageManager().queryIntentActivities( 3311 intent, r.resolvedType, 3312 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3313 UserHandle.getCallingUserId()); 3314 3315 // Look for the original activity in the list... 3316 final int N = resolves != null ? resolves.size() : 0; 3317 for (int i=0; i<N; i++) { 3318 ResolveInfo rInfo = resolves.get(i); 3319 if (rInfo.activityInfo.packageName.equals(r.packageName) 3320 && rInfo.activityInfo.name.equals(r.info.name)) { 3321 // We found the current one... the next matching is 3322 // after it. 3323 i++; 3324 if (i<N) { 3325 aInfo = resolves.get(i).activityInfo; 3326 } 3327 if (debug) { 3328 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3329 + "/" + r.info.name); 3330 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3331 + "/" + aInfo.name); 3332 } 3333 break; 3334 } 3335 } 3336 } catch (RemoteException e) { 3337 } 3338 3339 if (aInfo == null) { 3340 // Nobody who is next! 3341 ActivityOptions.abort(options); 3342 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3343 return false; 3344 } 3345 3346 intent.setComponent(new ComponentName( 3347 aInfo.applicationInfo.packageName, aInfo.name)); 3348 intent.setFlags(intent.getFlags()&~( 3349 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3350 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3351 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3352 Intent.FLAG_ACTIVITY_NEW_TASK)); 3353 3354 // Okay now we need to start the new activity, replacing the 3355 // currently running activity. This is a little tricky because 3356 // we want to start the new one as if the current one is finished, 3357 // but not finish the current one first so that there is no flicker. 3358 // And thus... 3359 final boolean wasFinishing = r.finishing; 3360 r.finishing = true; 3361 3362 // Propagate reply information over to the new activity. 3363 final ActivityRecord resultTo = r.resultTo; 3364 final String resultWho = r.resultWho; 3365 final int requestCode = r.requestCode; 3366 r.resultTo = null; 3367 if (resultTo != null) { 3368 resultTo.removeResultsLocked(r, resultWho, requestCode); 3369 } 3370 3371 final long origId = Binder.clearCallingIdentity(); 3372 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3373 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3374 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3375 options, false, null, null); 3376 Binder.restoreCallingIdentity(origId); 3377 3378 r.finishing = wasFinishing; 3379 if (res != ActivityManager.START_SUCCESS) { 3380 return false; 3381 } 3382 return true; 3383 } 3384 } 3385 3386 final int startActivityInPackage(int uid, String callingPackage, 3387 Intent intent, String resolvedType, IBinder resultTo, 3388 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3389 IActivityContainer container) { 3390 3391 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3392 false, true, "startActivityInPackage", null); 3393 3394 // TODO: Switch to user app stacks here. 3395 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3396 null, null, resultTo, resultWho, requestCode, startFlags, 3397 null, null, null, null, options, userId, container); 3398 return ret; 3399 } 3400 3401 @Override 3402 public final int startActivities(IApplicationThread caller, String callingPackage, 3403 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3404 int userId) { 3405 enforceNotIsolatedCaller("startActivities"); 3406 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3407 false, true, "startActivity", null); 3408 // TODO: Switch to user app stacks here. 3409 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3410 resolvedTypes, resultTo, options, userId); 3411 return ret; 3412 } 3413 3414 final int startActivitiesInPackage(int uid, String callingPackage, 3415 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3416 Bundle options, int userId) { 3417 3418 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3419 false, true, "startActivityInPackage", null); 3420 // TODO: Switch to user app stacks here. 3421 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3422 resultTo, options, userId); 3423 return ret; 3424 } 3425 3426 final void addRecentTaskLocked(TaskRecord task) { 3427 int N = mRecentTasks.size(); 3428 // Quick case: check if the top-most recent task is the same. 3429 if (N > 0 && mRecentTasks.get(0) == task) { 3430 return; 3431 } 3432 // Another quick case: never add voice sessions. 3433 if (task.voiceSession != null) { 3434 return; 3435 } 3436 // Remove any existing entries that are the same kind of task. 3437 final Intent intent = task.intent; 3438 final boolean document = intent != null && intent.isDocument(); 3439 for (int i=0; i<N; i++) { 3440 TaskRecord tr = mRecentTasks.get(i); 3441 if (task != tr) { 3442 if (task.userId != tr.userId) { 3443 continue; 3444 } 3445 final Intent trIntent = tr.intent; 3446 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3447 (intent == null || !intent.filterEquals(trIntent))) { 3448 continue; 3449 } 3450 if (document || trIntent != null && trIntent.isDocument()) { 3451 // Document tasks do not match other tasks. 3452 continue; 3453 } 3454 } 3455 3456 // Either task and tr are the same or, their affinities match or their intents match 3457 // and neither of them is a document. 3458 tr.disposeThumbnail(); 3459 mRecentTasks.remove(i); 3460 i--; 3461 N--; 3462 if (task.intent == null) { 3463 // If the new recent task we are adding is not fully 3464 // specified, then replace it with the existing recent task. 3465 task = tr; 3466 } 3467 } 3468 if (N >= MAX_RECENT_TASKS) { 3469 mRecentTasks.remove(N-1).disposeThumbnail(); 3470 } 3471 mRecentTasks.add(0, task); 3472 } 3473 3474 @Override 3475 public void reportActivityFullyDrawn(IBinder token) { 3476 synchronized (this) { 3477 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3478 if (r == null) { 3479 return; 3480 } 3481 r.reportFullyDrawnLocked(); 3482 } 3483 } 3484 3485 @Override 3486 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3487 synchronized (this) { 3488 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3489 if (r == null) { 3490 return; 3491 } 3492 final long origId = Binder.clearCallingIdentity(); 3493 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3494 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3495 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3496 if (config != null) { 3497 r.frozenBeforeDestroy = true; 3498 if (!updateConfigurationLocked(config, r, false, false)) { 3499 mStackSupervisor.resumeTopActivitiesLocked(); 3500 } 3501 } 3502 Binder.restoreCallingIdentity(origId); 3503 } 3504 } 3505 3506 @Override 3507 public int getRequestedOrientation(IBinder token) { 3508 synchronized (this) { 3509 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3510 if (r == null) { 3511 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3512 } 3513 return mWindowManager.getAppOrientation(r.appToken); 3514 } 3515 } 3516 3517 /** 3518 * This is the internal entry point for handling Activity.finish(). 3519 * 3520 * @param token The Binder token referencing the Activity we want to finish. 3521 * @param resultCode Result code, if any, from this Activity. 3522 * @param resultData Result data (Intent), if any, from this Activity. 3523 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3524 * the root Activity in the task. 3525 * 3526 * @return Returns true if the activity successfully finished, or false if it is still running. 3527 */ 3528 @Override 3529 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3530 boolean finishTask) { 3531 // Refuse possible leaked file descriptors 3532 if (resultData != null && resultData.hasFileDescriptors() == true) { 3533 throw new IllegalArgumentException("File descriptors passed in Intent"); 3534 } 3535 3536 synchronized(this) { 3537 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3538 if (r == null) { 3539 return true; 3540 } 3541 // Keep track of the root activity of the task before we finish it 3542 TaskRecord tr = r.task; 3543 ActivityRecord rootR = tr.getRootActivity(); 3544 if (mController != null) { 3545 // Find the first activity that is not finishing. 3546 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3547 if (next != null) { 3548 // ask watcher if this is allowed 3549 boolean resumeOK = true; 3550 try { 3551 resumeOK = mController.activityResuming(next.packageName); 3552 } catch (RemoteException e) { 3553 mController = null; 3554 Watchdog.getInstance().setActivityController(null); 3555 } 3556 3557 if (!resumeOK) { 3558 return false; 3559 } 3560 } 3561 } 3562 final long origId = Binder.clearCallingIdentity(); 3563 try { 3564 boolean res; 3565 if (finishTask && r == rootR) { 3566 // If requested, remove the task that is associated to this activity only if it 3567 // was the root activity in the task. The result code and data is ignored because 3568 // we don't support returning them across task boundaries. 3569 res = removeTaskByIdLocked(tr.taskId, 0); 3570 } else { 3571 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3572 resultData, "app-request", true); 3573 } 3574 return res; 3575 } finally { 3576 Binder.restoreCallingIdentity(origId); 3577 } 3578 } 3579 } 3580 3581 @Override 3582 public final void finishHeavyWeightApp() { 3583 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3584 != PackageManager.PERMISSION_GRANTED) { 3585 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3586 + Binder.getCallingPid() 3587 + ", uid=" + Binder.getCallingUid() 3588 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3589 Slog.w(TAG, msg); 3590 throw new SecurityException(msg); 3591 } 3592 3593 synchronized(this) { 3594 if (mHeavyWeightProcess == null) { 3595 return; 3596 } 3597 3598 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3599 mHeavyWeightProcess.activities); 3600 for (int i=0; i<activities.size(); i++) { 3601 ActivityRecord r = activities.get(i); 3602 if (!r.finishing) { 3603 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3604 null, "finish-heavy", true); 3605 } 3606 } 3607 3608 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3609 mHeavyWeightProcess.userId, 0)); 3610 mHeavyWeightProcess = null; 3611 } 3612 } 3613 3614 @Override 3615 public void crashApplication(int uid, int initialPid, String packageName, 3616 String message) { 3617 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3618 != PackageManager.PERMISSION_GRANTED) { 3619 String msg = "Permission Denial: crashApplication() from pid=" 3620 + Binder.getCallingPid() 3621 + ", uid=" + Binder.getCallingUid() 3622 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3623 Slog.w(TAG, msg); 3624 throw new SecurityException(msg); 3625 } 3626 3627 synchronized(this) { 3628 ProcessRecord proc = null; 3629 3630 // Figure out which process to kill. We don't trust that initialPid 3631 // still has any relation to current pids, so must scan through the 3632 // list. 3633 synchronized (mPidsSelfLocked) { 3634 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3635 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3636 if (p.uid != uid) { 3637 continue; 3638 } 3639 if (p.pid == initialPid) { 3640 proc = p; 3641 break; 3642 } 3643 if (p.pkgList.containsKey(packageName)) { 3644 proc = p; 3645 } 3646 } 3647 } 3648 3649 if (proc == null) { 3650 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3651 + " initialPid=" + initialPid 3652 + " packageName=" + packageName); 3653 return; 3654 } 3655 3656 if (proc.thread != null) { 3657 if (proc.pid == Process.myPid()) { 3658 Log.w(TAG, "crashApplication: trying to crash self!"); 3659 return; 3660 } 3661 long ident = Binder.clearCallingIdentity(); 3662 try { 3663 proc.thread.scheduleCrash(message); 3664 } catch (RemoteException e) { 3665 } 3666 Binder.restoreCallingIdentity(ident); 3667 } 3668 } 3669 } 3670 3671 @Override 3672 public final void finishSubActivity(IBinder token, String resultWho, 3673 int requestCode) { 3674 synchronized(this) { 3675 final long origId = Binder.clearCallingIdentity(); 3676 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3677 if (r != null) { 3678 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3679 } 3680 Binder.restoreCallingIdentity(origId); 3681 } 3682 } 3683 3684 @Override 3685 public boolean finishActivityAffinity(IBinder token) { 3686 synchronized(this) { 3687 final long origId = Binder.clearCallingIdentity(); 3688 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3689 boolean res = false; 3690 if (r != null) { 3691 res = r.task.stack.finishActivityAffinityLocked(r); 3692 } 3693 Binder.restoreCallingIdentity(origId); 3694 return res; 3695 } 3696 } 3697 3698 @Override 3699 public boolean willActivityBeVisible(IBinder token) { 3700 synchronized(this) { 3701 ActivityStack stack = ActivityRecord.getStackLocked(token); 3702 if (stack != null) { 3703 return stack.willActivityBeVisibleLocked(token); 3704 } 3705 return false; 3706 } 3707 } 3708 3709 @Override 3710 public void overridePendingTransition(IBinder token, String packageName, 3711 int enterAnim, int exitAnim) { 3712 synchronized(this) { 3713 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3714 if (self == null) { 3715 return; 3716 } 3717 3718 final long origId = Binder.clearCallingIdentity(); 3719 3720 if (self.state == ActivityState.RESUMED 3721 || self.state == ActivityState.PAUSING) { 3722 mWindowManager.overridePendingAppTransition(packageName, 3723 enterAnim, exitAnim, null); 3724 } 3725 3726 Binder.restoreCallingIdentity(origId); 3727 } 3728 } 3729 3730 /** 3731 * Main function for removing an existing process from the activity manager 3732 * as a result of that process going away. Clears out all connections 3733 * to the process. 3734 */ 3735 private final void handleAppDiedLocked(ProcessRecord app, 3736 boolean restarting, boolean allowRestart) { 3737 int pid = app.pid; 3738 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3739 if (!restarting) { 3740 removeLruProcessLocked(app); 3741 if (pid > 0) { 3742 ProcessList.remove(pid); 3743 } 3744 } 3745 3746 if (mProfileProc == app) { 3747 clearProfilerLocked(); 3748 } 3749 3750 // Remove this application's activities from active lists. 3751 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3752 3753 app.activities.clear(); 3754 3755 if (app.instrumentationClass != null) { 3756 Slog.w(TAG, "Crash of app " + app.processName 3757 + " running instrumentation " + app.instrumentationClass); 3758 Bundle info = new Bundle(); 3759 info.putString("shortMsg", "Process crashed."); 3760 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3761 } 3762 3763 if (!restarting) { 3764 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3765 // If there was nothing to resume, and we are not already 3766 // restarting this process, but there is a visible activity that 3767 // is hosted by the process... then make sure all visible 3768 // activities are running, taking care of restarting this 3769 // process. 3770 if (hasVisibleActivities) { 3771 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3772 } 3773 } 3774 } 3775 } 3776 3777 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3778 IBinder threadBinder = thread.asBinder(); 3779 // Find the application record. 3780 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3781 ProcessRecord rec = mLruProcesses.get(i); 3782 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3783 return i; 3784 } 3785 } 3786 return -1; 3787 } 3788 3789 final ProcessRecord getRecordForAppLocked( 3790 IApplicationThread thread) { 3791 if (thread == null) { 3792 return null; 3793 } 3794 3795 int appIndex = getLRURecordIndexForAppLocked(thread); 3796 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3797 } 3798 3799 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3800 // If there are no longer any background processes running, 3801 // and the app that died was not running instrumentation, 3802 // then tell everyone we are now low on memory. 3803 boolean haveBg = false; 3804 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3805 ProcessRecord rec = mLruProcesses.get(i); 3806 if (rec.thread != null 3807 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3808 haveBg = true; 3809 break; 3810 } 3811 } 3812 3813 if (!haveBg) { 3814 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3815 if (doReport) { 3816 long now = SystemClock.uptimeMillis(); 3817 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3818 doReport = false; 3819 } else { 3820 mLastMemUsageReportTime = now; 3821 } 3822 } 3823 final ArrayList<ProcessMemInfo> memInfos 3824 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3825 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3826 long now = SystemClock.uptimeMillis(); 3827 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3828 ProcessRecord rec = mLruProcesses.get(i); 3829 if (rec == dyingProc || rec.thread == null) { 3830 continue; 3831 } 3832 if (doReport) { 3833 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3834 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3835 } 3836 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3837 // The low memory report is overriding any current 3838 // state for a GC request. Make sure to do 3839 // heavy/important/visible/foreground processes first. 3840 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3841 rec.lastRequestedGc = 0; 3842 } else { 3843 rec.lastRequestedGc = rec.lastLowMemory; 3844 } 3845 rec.reportLowMemory = true; 3846 rec.lastLowMemory = now; 3847 mProcessesToGc.remove(rec); 3848 addProcessToGcListLocked(rec); 3849 } 3850 } 3851 if (doReport) { 3852 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3853 mHandler.sendMessage(msg); 3854 } 3855 scheduleAppGcsLocked(); 3856 } 3857 } 3858 3859 final void appDiedLocked(ProcessRecord app, int pid, 3860 IApplicationThread thread) { 3861 3862 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3863 synchronized (stats) { 3864 stats.noteProcessDiedLocked(app.info.uid, pid); 3865 } 3866 3867 // Clean up already done if the process has been re-started. 3868 if (app.pid == pid && app.thread != null && 3869 app.thread.asBinder() == thread.asBinder()) { 3870 boolean doLowMem = app.instrumentationClass == null; 3871 boolean doOomAdj = doLowMem; 3872 if (!app.killedByAm) { 3873 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3874 + ") has died."); 3875 mAllowLowerMemLevel = true; 3876 } else { 3877 // Note that we always want to do oom adj to update our state with the 3878 // new number of procs. 3879 mAllowLowerMemLevel = false; 3880 doLowMem = false; 3881 } 3882 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3883 if (DEBUG_CLEANUP) Slog.v( 3884 TAG, "Dying app: " + app + ", pid: " + pid 3885 + ", thread: " + thread.asBinder()); 3886 handleAppDiedLocked(app, false, true); 3887 3888 if (doOomAdj) { 3889 updateOomAdjLocked(); 3890 } 3891 if (doLowMem) { 3892 doLowMemReportIfNeededLocked(app); 3893 } 3894 } else if (app.pid != pid) { 3895 // A new process has already been started. 3896 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3897 + ") has died and restarted (pid " + app.pid + ")."); 3898 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3899 } else if (DEBUG_PROCESSES) { 3900 Slog.d(TAG, "Received spurious death notification for thread " 3901 + thread.asBinder()); 3902 } 3903 } 3904 3905 /** 3906 * If a stack trace dump file is configured, dump process stack traces. 3907 * @param clearTraces causes the dump file to be erased prior to the new 3908 * traces being written, if true; when false, the new traces will be 3909 * appended to any existing file content. 3910 * @param firstPids of dalvik VM processes to dump stack traces for first 3911 * @param lastPids of dalvik VM processes to dump stack traces for last 3912 * @param nativeProcs optional list of native process names to dump stack crawls 3913 * @return file containing stack traces, or null if no dump file is configured 3914 */ 3915 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3916 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3917 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3918 if (tracesPath == null || tracesPath.length() == 0) { 3919 return null; 3920 } 3921 3922 File tracesFile = new File(tracesPath); 3923 try { 3924 File tracesDir = tracesFile.getParentFile(); 3925 if (!tracesDir.exists()) { 3926 tracesFile.mkdirs(); 3927 if (!SELinux.restorecon(tracesDir)) { 3928 return null; 3929 } 3930 } 3931 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3932 3933 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3934 tracesFile.createNewFile(); 3935 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3936 } catch (IOException e) { 3937 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3938 return null; 3939 } 3940 3941 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3942 return tracesFile; 3943 } 3944 3945 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3946 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3947 // Use a FileObserver to detect when traces finish writing. 3948 // The order of traces is considered important to maintain for legibility. 3949 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3950 @Override 3951 public synchronized void onEvent(int event, String path) { notify(); } 3952 }; 3953 3954 try { 3955 observer.startWatching(); 3956 3957 // First collect all of the stacks of the most important pids. 3958 if (firstPids != null) { 3959 try { 3960 int num = firstPids.size(); 3961 for (int i = 0; i < num; i++) { 3962 synchronized (observer) { 3963 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3964 observer.wait(200); // Wait for write-close, give up after 200msec 3965 } 3966 } 3967 } catch (InterruptedException e) { 3968 Log.wtf(TAG, e); 3969 } 3970 } 3971 3972 // Next collect the stacks of the native pids 3973 if (nativeProcs != null) { 3974 int[] pids = Process.getPidsForCommands(nativeProcs); 3975 if (pids != null) { 3976 for (int pid : pids) { 3977 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3978 } 3979 } 3980 } 3981 3982 // Lastly, measure CPU usage. 3983 if (processCpuTracker != null) { 3984 processCpuTracker.init(); 3985 System.gc(); 3986 processCpuTracker.update(); 3987 try { 3988 synchronized (processCpuTracker) { 3989 processCpuTracker.wait(500); // measure over 1/2 second. 3990 } 3991 } catch (InterruptedException e) { 3992 } 3993 processCpuTracker.update(); 3994 3995 // We'll take the stack crawls of just the top apps using CPU. 3996 final int N = processCpuTracker.countWorkingStats(); 3997 int numProcs = 0; 3998 for (int i=0; i<N && numProcs<5; i++) { 3999 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4000 if (lastPids.indexOfKey(stats.pid) >= 0) { 4001 numProcs++; 4002 try { 4003 synchronized (observer) { 4004 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4005 observer.wait(200); // Wait for write-close, give up after 200msec 4006 } 4007 } catch (InterruptedException e) { 4008 Log.wtf(TAG, e); 4009 } 4010 4011 } 4012 } 4013 } 4014 } finally { 4015 observer.stopWatching(); 4016 } 4017 } 4018 4019 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4020 if (true || IS_USER_BUILD) { 4021 return; 4022 } 4023 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4024 if (tracesPath == null || tracesPath.length() == 0) { 4025 return; 4026 } 4027 4028 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4029 StrictMode.allowThreadDiskWrites(); 4030 try { 4031 final File tracesFile = new File(tracesPath); 4032 final File tracesDir = tracesFile.getParentFile(); 4033 final File tracesTmp = new File(tracesDir, "__tmp__"); 4034 try { 4035 if (!tracesDir.exists()) { 4036 tracesFile.mkdirs(); 4037 if (!SELinux.restorecon(tracesDir.getPath())) { 4038 return; 4039 } 4040 } 4041 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4042 4043 if (tracesFile.exists()) { 4044 tracesTmp.delete(); 4045 tracesFile.renameTo(tracesTmp); 4046 } 4047 StringBuilder sb = new StringBuilder(); 4048 Time tobj = new Time(); 4049 tobj.set(System.currentTimeMillis()); 4050 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4051 sb.append(": "); 4052 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4053 sb.append(" since "); 4054 sb.append(msg); 4055 FileOutputStream fos = new FileOutputStream(tracesFile); 4056 fos.write(sb.toString().getBytes()); 4057 if (app == null) { 4058 fos.write("\n*** No application process!".getBytes()); 4059 } 4060 fos.close(); 4061 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4062 } catch (IOException e) { 4063 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4064 return; 4065 } 4066 4067 if (app != null) { 4068 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4069 firstPids.add(app.pid); 4070 dumpStackTraces(tracesPath, firstPids, null, null, null); 4071 } 4072 4073 File lastTracesFile = null; 4074 File curTracesFile = null; 4075 for (int i=9; i>=0; i--) { 4076 String name = String.format(Locale.US, "slow%02d.txt", i); 4077 curTracesFile = new File(tracesDir, name); 4078 if (curTracesFile.exists()) { 4079 if (lastTracesFile != null) { 4080 curTracesFile.renameTo(lastTracesFile); 4081 } else { 4082 curTracesFile.delete(); 4083 } 4084 } 4085 lastTracesFile = curTracesFile; 4086 } 4087 tracesFile.renameTo(curTracesFile); 4088 if (tracesTmp.exists()) { 4089 tracesTmp.renameTo(tracesFile); 4090 } 4091 } finally { 4092 StrictMode.setThreadPolicy(oldPolicy); 4093 } 4094 } 4095 4096 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4097 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4098 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4099 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4100 4101 if (mController != null) { 4102 try { 4103 // 0 == continue, -1 = kill process immediately 4104 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4105 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4106 } catch (RemoteException e) { 4107 mController = null; 4108 Watchdog.getInstance().setActivityController(null); 4109 } 4110 } 4111 4112 long anrTime = SystemClock.uptimeMillis(); 4113 if (MONITOR_CPU_USAGE) { 4114 updateCpuStatsNow(); 4115 } 4116 4117 synchronized (this) { 4118 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4119 if (mShuttingDown) { 4120 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4121 return; 4122 } else if (app.notResponding) { 4123 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4124 return; 4125 } else if (app.crashing) { 4126 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4127 return; 4128 } 4129 4130 // In case we come through here for the same app before completing 4131 // this one, mark as anring now so we will bail out. 4132 app.notResponding = true; 4133 4134 // Log the ANR to the event log. 4135 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4136 app.processName, app.info.flags, annotation); 4137 4138 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4139 firstPids.add(app.pid); 4140 4141 int parentPid = app.pid; 4142 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4143 if (parentPid != app.pid) firstPids.add(parentPid); 4144 4145 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4146 4147 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4148 ProcessRecord r = mLruProcesses.get(i); 4149 if (r != null && r.thread != null) { 4150 int pid = r.pid; 4151 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4152 if (r.persistent) { 4153 firstPids.add(pid); 4154 } else { 4155 lastPids.put(pid, Boolean.TRUE); 4156 } 4157 } 4158 } 4159 } 4160 } 4161 4162 // Log the ANR to the main log. 4163 StringBuilder info = new StringBuilder(); 4164 info.setLength(0); 4165 info.append("ANR in ").append(app.processName); 4166 if (activity != null && activity.shortComponentName != null) { 4167 info.append(" (").append(activity.shortComponentName).append(")"); 4168 } 4169 info.append("\n"); 4170 info.append("PID: ").append(app.pid).append("\n"); 4171 if (annotation != null) { 4172 info.append("Reason: ").append(annotation).append("\n"); 4173 } 4174 if (parent != null && parent != activity) { 4175 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4176 } 4177 4178 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4179 4180 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4181 NATIVE_STACKS_OF_INTEREST); 4182 4183 String cpuInfo = null; 4184 if (MONITOR_CPU_USAGE) { 4185 updateCpuStatsNow(); 4186 synchronized (mProcessCpuThread) { 4187 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4188 } 4189 info.append(processCpuTracker.printCurrentLoad()); 4190 info.append(cpuInfo); 4191 } 4192 4193 info.append(processCpuTracker.printCurrentState(anrTime)); 4194 4195 Slog.e(TAG, info.toString()); 4196 if (tracesFile == null) { 4197 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4198 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4199 } 4200 4201 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4202 cpuInfo, tracesFile, null); 4203 4204 if (mController != null) { 4205 try { 4206 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4207 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4208 if (res != 0) { 4209 if (res < 0 && app.pid != MY_PID) { 4210 Process.killProcess(app.pid); 4211 } else { 4212 synchronized (this) { 4213 mServices.scheduleServiceTimeoutLocked(app); 4214 } 4215 } 4216 return; 4217 } 4218 } catch (RemoteException e) { 4219 mController = null; 4220 Watchdog.getInstance().setActivityController(null); 4221 } 4222 } 4223 4224 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4225 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4226 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4227 4228 synchronized (this) { 4229 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4230 killUnneededProcessLocked(app, "background ANR"); 4231 return; 4232 } 4233 4234 // Set the app's notResponding state, and look up the errorReportReceiver 4235 makeAppNotRespondingLocked(app, 4236 activity != null ? activity.shortComponentName : null, 4237 annotation != null ? "ANR " + annotation : "ANR", 4238 info.toString()); 4239 4240 // Bring up the infamous App Not Responding dialog 4241 Message msg = Message.obtain(); 4242 HashMap<String, Object> map = new HashMap<String, Object>(); 4243 msg.what = SHOW_NOT_RESPONDING_MSG; 4244 msg.obj = map; 4245 msg.arg1 = aboveSystem ? 1 : 0; 4246 map.put("app", app); 4247 if (activity != null) { 4248 map.put("activity", activity); 4249 } 4250 4251 mHandler.sendMessage(msg); 4252 } 4253 } 4254 4255 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4256 if (!mLaunchWarningShown) { 4257 mLaunchWarningShown = true; 4258 mHandler.post(new Runnable() { 4259 @Override 4260 public void run() { 4261 synchronized (ActivityManagerService.this) { 4262 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4263 d.show(); 4264 mHandler.postDelayed(new Runnable() { 4265 @Override 4266 public void run() { 4267 synchronized (ActivityManagerService.this) { 4268 d.dismiss(); 4269 mLaunchWarningShown = false; 4270 } 4271 } 4272 }, 4000); 4273 } 4274 } 4275 }); 4276 } 4277 } 4278 4279 @Override 4280 public boolean clearApplicationUserData(final String packageName, 4281 final IPackageDataObserver observer, int userId) { 4282 enforceNotIsolatedCaller("clearApplicationUserData"); 4283 int uid = Binder.getCallingUid(); 4284 int pid = Binder.getCallingPid(); 4285 userId = handleIncomingUser(pid, uid, 4286 userId, false, true, "clearApplicationUserData", null); 4287 long callingId = Binder.clearCallingIdentity(); 4288 try { 4289 IPackageManager pm = AppGlobals.getPackageManager(); 4290 int pkgUid = -1; 4291 synchronized(this) { 4292 try { 4293 pkgUid = pm.getPackageUid(packageName, userId); 4294 } catch (RemoteException e) { 4295 } 4296 if (pkgUid == -1) { 4297 Slog.w(TAG, "Invalid packageName: " + packageName); 4298 if (observer != null) { 4299 try { 4300 observer.onRemoveCompleted(packageName, false); 4301 } catch (RemoteException e) { 4302 Slog.i(TAG, "Observer no longer exists."); 4303 } 4304 } 4305 return false; 4306 } 4307 if (uid == pkgUid || checkComponentPermission( 4308 android.Manifest.permission.CLEAR_APP_USER_DATA, 4309 pid, uid, -1, true) 4310 == PackageManager.PERMISSION_GRANTED) { 4311 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4312 } else { 4313 throw new SecurityException("PID " + pid + " does not have permission " 4314 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4315 + " of package " + packageName); 4316 } 4317 } 4318 4319 try { 4320 // Clear application user data 4321 pm.clearApplicationUserData(packageName, observer, userId); 4322 4323 // Remove all permissions granted from/to this package 4324 removeUriPermissionsForPackageLocked(packageName, userId, true); 4325 4326 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4327 Uri.fromParts("package", packageName, null)); 4328 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4329 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4330 null, null, 0, null, null, null, false, false, userId); 4331 } catch (RemoteException e) { 4332 } 4333 } finally { 4334 Binder.restoreCallingIdentity(callingId); 4335 } 4336 return true; 4337 } 4338 4339 @Override 4340 public void killBackgroundProcesses(final String packageName, int userId) { 4341 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4342 != PackageManager.PERMISSION_GRANTED && 4343 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4344 != PackageManager.PERMISSION_GRANTED) { 4345 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4346 + Binder.getCallingPid() 4347 + ", uid=" + Binder.getCallingUid() 4348 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4349 Slog.w(TAG, msg); 4350 throw new SecurityException(msg); 4351 } 4352 4353 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4354 userId, true, true, "killBackgroundProcesses", null); 4355 long callingId = Binder.clearCallingIdentity(); 4356 try { 4357 IPackageManager pm = AppGlobals.getPackageManager(); 4358 synchronized(this) { 4359 int appId = -1; 4360 try { 4361 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4362 } catch (RemoteException e) { 4363 } 4364 if (appId == -1) { 4365 Slog.w(TAG, "Invalid packageName: " + packageName); 4366 return; 4367 } 4368 killPackageProcessesLocked(packageName, appId, userId, 4369 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4370 } 4371 } finally { 4372 Binder.restoreCallingIdentity(callingId); 4373 } 4374 } 4375 4376 @Override 4377 public void killAllBackgroundProcesses() { 4378 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4379 != PackageManager.PERMISSION_GRANTED) { 4380 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4381 + Binder.getCallingPid() 4382 + ", uid=" + Binder.getCallingUid() 4383 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4384 Slog.w(TAG, msg); 4385 throw new SecurityException(msg); 4386 } 4387 4388 long callingId = Binder.clearCallingIdentity(); 4389 try { 4390 synchronized(this) { 4391 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4392 final int NP = mProcessNames.getMap().size(); 4393 for (int ip=0; ip<NP; ip++) { 4394 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4395 final int NA = apps.size(); 4396 for (int ia=0; ia<NA; ia++) { 4397 ProcessRecord app = apps.valueAt(ia); 4398 if (app.persistent) { 4399 // we don't kill persistent processes 4400 continue; 4401 } 4402 if (app.removed) { 4403 procs.add(app); 4404 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4405 app.removed = true; 4406 procs.add(app); 4407 } 4408 } 4409 } 4410 4411 int N = procs.size(); 4412 for (int i=0; i<N; i++) { 4413 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4414 } 4415 mAllowLowerMemLevel = true; 4416 updateOomAdjLocked(); 4417 doLowMemReportIfNeededLocked(null); 4418 } 4419 } finally { 4420 Binder.restoreCallingIdentity(callingId); 4421 } 4422 } 4423 4424 @Override 4425 public void forceStopPackage(final String packageName, int userId) { 4426 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4427 != PackageManager.PERMISSION_GRANTED) { 4428 String msg = "Permission Denial: forceStopPackage() from pid=" 4429 + Binder.getCallingPid() 4430 + ", uid=" + Binder.getCallingUid() 4431 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4432 Slog.w(TAG, msg); 4433 throw new SecurityException(msg); 4434 } 4435 final int callingPid = Binder.getCallingPid(); 4436 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4437 userId, true, true, "forceStopPackage", null); 4438 long callingId = Binder.clearCallingIdentity(); 4439 try { 4440 IPackageManager pm = AppGlobals.getPackageManager(); 4441 synchronized(this) { 4442 int[] users = userId == UserHandle.USER_ALL 4443 ? getUsersLocked() : new int[] { userId }; 4444 for (int user : users) { 4445 int pkgUid = -1; 4446 try { 4447 pkgUid = pm.getPackageUid(packageName, user); 4448 } catch (RemoteException e) { 4449 } 4450 if (pkgUid == -1) { 4451 Slog.w(TAG, "Invalid packageName: " + packageName); 4452 continue; 4453 } 4454 try { 4455 pm.setPackageStoppedState(packageName, true, user); 4456 } catch (RemoteException e) { 4457 } catch (IllegalArgumentException e) { 4458 Slog.w(TAG, "Failed trying to unstop package " 4459 + packageName + ": " + e); 4460 } 4461 if (isUserRunningLocked(user, false)) { 4462 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4463 } 4464 } 4465 } 4466 } finally { 4467 Binder.restoreCallingIdentity(callingId); 4468 } 4469 } 4470 4471 /* 4472 * The pkg name and app id have to be specified. 4473 */ 4474 @Override 4475 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4476 if (pkg == null) { 4477 return; 4478 } 4479 // Make sure the uid is valid. 4480 if (appid < 0) { 4481 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4482 return; 4483 } 4484 int callerUid = Binder.getCallingUid(); 4485 // Only the system server can kill an application 4486 if (callerUid == Process.SYSTEM_UID) { 4487 // Post an aysnc message to kill the application 4488 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4489 msg.arg1 = appid; 4490 msg.arg2 = 0; 4491 Bundle bundle = new Bundle(); 4492 bundle.putString("pkg", pkg); 4493 bundle.putString("reason", reason); 4494 msg.obj = bundle; 4495 mHandler.sendMessage(msg); 4496 } else { 4497 throw new SecurityException(callerUid + " cannot kill pkg: " + 4498 pkg); 4499 } 4500 } 4501 4502 @Override 4503 public void closeSystemDialogs(String reason) { 4504 enforceNotIsolatedCaller("closeSystemDialogs"); 4505 4506 final int pid = Binder.getCallingPid(); 4507 final int uid = Binder.getCallingUid(); 4508 final long origId = Binder.clearCallingIdentity(); 4509 try { 4510 synchronized (this) { 4511 // Only allow this from foreground processes, so that background 4512 // applications can't abuse it to prevent system UI from being shown. 4513 if (uid >= Process.FIRST_APPLICATION_UID) { 4514 ProcessRecord proc; 4515 synchronized (mPidsSelfLocked) { 4516 proc = mPidsSelfLocked.get(pid); 4517 } 4518 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4519 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4520 + " from background process " + proc); 4521 return; 4522 } 4523 } 4524 closeSystemDialogsLocked(reason); 4525 } 4526 } finally { 4527 Binder.restoreCallingIdentity(origId); 4528 } 4529 } 4530 4531 void closeSystemDialogsLocked(String reason) { 4532 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4533 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4534 | Intent.FLAG_RECEIVER_FOREGROUND); 4535 if (reason != null) { 4536 intent.putExtra("reason", reason); 4537 } 4538 mWindowManager.closeSystemDialogs(reason); 4539 4540 mStackSupervisor.closeSystemDialogsLocked(); 4541 4542 broadcastIntentLocked(null, null, intent, null, 4543 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4544 Process.SYSTEM_UID, UserHandle.USER_ALL); 4545 } 4546 4547 @Override 4548 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4549 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4550 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4551 for (int i=pids.length-1; i>=0; i--) { 4552 ProcessRecord proc; 4553 int oomAdj; 4554 synchronized (this) { 4555 synchronized (mPidsSelfLocked) { 4556 proc = mPidsSelfLocked.get(pids[i]); 4557 oomAdj = proc != null ? proc.setAdj : 0; 4558 } 4559 } 4560 infos[i] = new Debug.MemoryInfo(); 4561 Debug.getMemoryInfo(pids[i], infos[i]); 4562 if (proc != null) { 4563 synchronized (this) { 4564 if (proc.thread != null && proc.setAdj == oomAdj) { 4565 // Record this for posterity if the process has been stable. 4566 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4567 infos[i].getTotalUss(), false, proc.pkgList); 4568 } 4569 } 4570 } 4571 } 4572 return infos; 4573 } 4574 4575 @Override 4576 public long[] getProcessPss(int[] pids) { 4577 enforceNotIsolatedCaller("getProcessPss"); 4578 long[] pss = new long[pids.length]; 4579 for (int i=pids.length-1; i>=0; i--) { 4580 ProcessRecord proc; 4581 int oomAdj; 4582 synchronized (this) { 4583 synchronized (mPidsSelfLocked) { 4584 proc = mPidsSelfLocked.get(pids[i]); 4585 oomAdj = proc != null ? proc.setAdj : 0; 4586 } 4587 } 4588 long[] tmpUss = new long[1]; 4589 pss[i] = Debug.getPss(pids[i], tmpUss); 4590 if (proc != null) { 4591 synchronized (this) { 4592 if (proc.thread != null && proc.setAdj == oomAdj) { 4593 // Record this for posterity if the process has been stable. 4594 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4595 } 4596 } 4597 } 4598 } 4599 return pss; 4600 } 4601 4602 @Override 4603 public void killApplicationProcess(String processName, int uid) { 4604 if (processName == null) { 4605 return; 4606 } 4607 4608 int callerUid = Binder.getCallingUid(); 4609 // Only the system server can kill an application 4610 if (callerUid == Process.SYSTEM_UID) { 4611 synchronized (this) { 4612 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4613 if (app != null && app.thread != null) { 4614 try { 4615 app.thread.scheduleSuicide(); 4616 } catch (RemoteException e) { 4617 // If the other end already died, then our work here is done. 4618 } 4619 } else { 4620 Slog.w(TAG, "Process/uid not found attempting kill of " 4621 + processName + " / " + uid); 4622 } 4623 } 4624 } else { 4625 throw new SecurityException(callerUid + " cannot kill app process: " + 4626 processName); 4627 } 4628 } 4629 4630 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4631 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4632 false, true, false, false, UserHandle.getUserId(uid), reason); 4633 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4634 Uri.fromParts("package", packageName, null)); 4635 if (!mProcessesReady) { 4636 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4637 | Intent.FLAG_RECEIVER_FOREGROUND); 4638 } 4639 intent.putExtra(Intent.EXTRA_UID, uid); 4640 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4641 broadcastIntentLocked(null, null, intent, 4642 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4643 false, false, 4644 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4645 } 4646 4647 private void forceStopUserLocked(int userId, String reason) { 4648 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4649 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4650 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4651 | Intent.FLAG_RECEIVER_FOREGROUND); 4652 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4653 broadcastIntentLocked(null, null, intent, 4654 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4655 false, false, 4656 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4657 } 4658 4659 private final boolean killPackageProcessesLocked(String packageName, int appId, 4660 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4661 boolean doit, boolean evenPersistent, String reason) { 4662 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4663 4664 // Remove all processes this package may have touched: all with the 4665 // same UID (except for the system or root user), and all whose name 4666 // matches the package name. 4667 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4668 final int NP = mProcessNames.getMap().size(); 4669 for (int ip=0; ip<NP; ip++) { 4670 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4671 final int NA = apps.size(); 4672 for (int ia=0; ia<NA; ia++) { 4673 ProcessRecord app = apps.valueAt(ia); 4674 if (app.persistent && !evenPersistent) { 4675 // we don't kill persistent processes 4676 continue; 4677 } 4678 if (app.removed) { 4679 if (doit) { 4680 procs.add(app); 4681 } 4682 continue; 4683 } 4684 4685 // Skip process if it doesn't meet our oom adj requirement. 4686 if (app.setAdj < minOomAdj) { 4687 continue; 4688 } 4689 4690 // If no package is specified, we call all processes under the 4691 // give user id. 4692 if (packageName == null) { 4693 if (app.userId != userId) { 4694 continue; 4695 } 4696 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4697 continue; 4698 } 4699 // Package has been specified, we want to hit all processes 4700 // that match it. We need to qualify this by the processes 4701 // that are running under the specified app and user ID. 4702 } else { 4703 if (UserHandle.getAppId(app.uid) != appId) { 4704 continue; 4705 } 4706 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4707 continue; 4708 } 4709 if (!app.pkgList.containsKey(packageName)) { 4710 continue; 4711 } 4712 } 4713 4714 // Process has passed all conditions, kill it! 4715 if (!doit) { 4716 return true; 4717 } 4718 app.removed = true; 4719 procs.add(app); 4720 } 4721 } 4722 4723 int N = procs.size(); 4724 for (int i=0; i<N; i++) { 4725 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4726 } 4727 updateOomAdjLocked(); 4728 return N > 0; 4729 } 4730 4731 private final boolean forceStopPackageLocked(String name, int appId, 4732 boolean callerWillRestart, boolean purgeCache, boolean doit, 4733 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4734 int i; 4735 int N; 4736 4737 if (userId == UserHandle.USER_ALL && name == null) { 4738 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4739 } 4740 4741 if (appId < 0 && name != null) { 4742 try { 4743 appId = UserHandle.getAppId( 4744 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4745 } catch (RemoteException e) { 4746 } 4747 } 4748 4749 if (doit) { 4750 if (name != null) { 4751 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4752 + " user=" + userId + ": " + reason); 4753 } else { 4754 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4755 } 4756 4757 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4758 for (int ip=pmap.size()-1; ip>=0; ip--) { 4759 SparseArray<Long> ba = pmap.valueAt(ip); 4760 for (i=ba.size()-1; i>=0; i--) { 4761 boolean remove = false; 4762 final int entUid = ba.keyAt(i); 4763 if (name != null) { 4764 if (userId == UserHandle.USER_ALL) { 4765 if (UserHandle.getAppId(entUid) == appId) { 4766 remove = true; 4767 } 4768 } else { 4769 if (entUid == UserHandle.getUid(userId, appId)) { 4770 remove = true; 4771 } 4772 } 4773 } else if (UserHandle.getUserId(entUid) == userId) { 4774 remove = true; 4775 } 4776 if (remove) { 4777 ba.removeAt(i); 4778 } 4779 } 4780 if (ba.size() == 0) { 4781 pmap.removeAt(ip); 4782 } 4783 } 4784 } 4785 4786 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4787 -100, callerWillRestart, true, doit, evenPersistent, 4788 name == null ? ("stop user " + userId) : ("stop " + name)); 4789 4790 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4791 if (!doit) { 4792 return true; 4793 } 4794 didSomething = true; 4795 } 4796 4797 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4798 if (!doit) { 4799 return true; 4800 } 4801 didSomething = true; 4802 } 4803 4804 if (name == null) { 4805 // Remove all sticky broadcasts from this user. 4806 mStickyBroadcasts.remove(userId); 4807 } 4808 4809 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4810 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4811 userId, providers)) { 4812 if (!doit) { 4813 return true; 4814 } 4815 didSomething = true; 4816 } 4817 N = providers.size(); 4818 for (i=0; i<N; i++) { 4819 removeDyingProviderLocked(null, providers.get(i), true); 4820 } 4821 4822 // Remove transient permissions granted from/to this package/user 4823 removeUriPermissionsForPackageLocked(name, userId, false); 4824 4825 if (name == null || uninstalling) { 4826 // Remove pending intents. For now we only do this when force 4827 // stopping users, because we have some problems when doing this 4828 // for packages -- app widgets are not currently cleaned up for 4829 // such packages, so they can be left with bad pending intents. 4830 if (mIntentSenderRecords.size() > 0) { 4831 Iterator<WeakReference<PendingIntentRecord>> it 4832 = mIntentSenderRecords.values().iterator(); 4833 while (it.hasNext()) { 4834 WeakReference<PendingIntentRecord> wpir = it.next(); 4835 if (wpir == null) { 4836 it.remove(); 4837 continue; 4838 } 4839 PendingIntentRecord pir = wpir.get(); 4840 if (pir == null) { 4841 it.remove(); 4842 continue; 4843 } 4844 if (name == null) { 4845 // Stopping user, remove all objects for the user. 4846 if (pir.key.userId != userId) { 4847 // Not the same user, skip it. 4848 continue; 4849 } 4850 } else { 4851 if (UserHandle.getAppId(pir.uid) != appId) { 4852 // Different app id, skip it. 4853 continue; 4854 } 4855 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4856 // Different user, skip it. 4857 continue; 4858 } 4859 if (!pir.key.packageName.equals(name)) { 4860 // Different package, skip it. 4861 continue; 4862 } 4863 } 4864 if (!doit) { 4865 return true; 4866 } 4867 didSomething = true; 4868 it.remove(); 4869 pir.canceled = true; 4870 if (pir.key.activity != null) { 4871 pir.key.activity.pendingResults.remove(pir.ref); 4872 } 4873 } 4874 } 4875 } 4876 4877 if (doit) { 4878 if (purgeCache && name != null) { 4879 AttributeCache ac = AttributeCache.instance(); 4880 if (ac != null) { 4881 ac.removePackage(name); 4882 } 4883 } 4884 if (mBooted) { 4885 mStackSupervisor.resumeTopActivitiesLocked(); 4886 mStackSupervisor.scheduleIdleLocked(); 4887 } 4888 } 4889 4890 return didSomething; 4891 } 4892 4893 private final boolean removeProcessLocked(ProcessRecord app, 4894 boolean callerWillRestart, boolean allowRestart, String reason) { 4895 final String name = app.processName; 4896 final int uid = app.uid; 4897 if (DEBUG_PROCESSES) Slog.d( 4898 TAG, "Force removing proc " + app.toShortString() + " (" + name 4899 + "/" + uid + ")"); 4900 4901 mProcessNames.remove(name, uid); 4902 mIsolatedProcesses.remove(app.uid); 4903 if (mHeavyWeightProcess == app) { 4904 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4905 mHeavyWeightProcess.userId, 0)); 4906 mHeavyWeightProcess = null; 4907 } 4908 boolean needRestart = false; 4909 if (app.pid > 0 && app.pid != MY_PID) { 4910 int pid = app.pid; 4911 synchronized (mPidsSelfLocked) { 4912 mPidsSelfLocked.remove(pid); 4913 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4914 } 4915 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4916 app.processName, app.info.uid); 4917 if (app.isolated) { 4918 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4919 } 4920 killUnneededProcessLocked(app, reason); 4921 handleAppDiedLocked(app, true, allowRestart); 4922 removeLruProcessLocked(app); 4923 4924 if (app.persistent && !app.isolated) { 4925 if (!callerWillRestart) { 4926 addAppLocked(app.info, false); 4927 } else { 4928 needRestart = true; 4929 } 4930 } 4931 } else { 4932 mRemovedProcesses.add(app); 4933 } 4934 4935 return needRestart; 4936 } 4937 4938 private final void processStartTimedOutLocked(ProcessRecord app) { 4939 final int pid = app.pid; 4940 boolean gone = false; 4941 synchronized (mPidsSelfLocked) { 4942 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4943 if (knownApp != null && knownApp.thread == null) { 4944 mPidsSelfLocked.remove(pid); 4945 gone = true; 4946 } 4947 } 4948 4949 if (gone) { 4950 Slog.w(TAG, "Process " + app + " failed to attach"); 4951 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4952 pid, app.uid, app.processName); 4953 mProcessNames.remove(app.processName, app.uid); 4954 mIsolatedProcesses.remove(app.uid); 4955 if (mHeavyWeightProcess == app) { 4956 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4957 mHeavyWeightProcess.userId, 0)); 4958 mHeavyWeightProcess = null; 4959 } 4960 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4961 app.processName, app.info.uid); 4962 if (app.isolated) { 4963 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4964 } 4965 // Take care of any launching providers waiting for this process. 4966 checkAppInLaunchingProvidersLocked(app, true); 4967 // Take care of any services that are waiting for the process. 4968 mServices.processStartTimedOutLocked(app); 4969 killUnneededProcessLocked(app, "start timeout"); 4970 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4971 Slog.w(TAG, "Unattached app died before backup, skipping"); 4972 try { 4973 IBackupManager bm = IBackupManager.Stub.asInterface( 4974 ServiceManager.getService(Context.BACKUP_SERVICE)); 4975 bm.agentDisconnected(app.info.packageName); 4976 } catch (RemoteException e) { 4977 // Can't happen; the backup manager is local 4978 } 4979 } 4980 if (isPendingBroadcastProcessLocked(pid)) { 4981 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4982 skipPendingBroadcastLocked(pid); 4983 } 4984 } else { 4985 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4986 } 4987 } 4988 4989 private final boolean attachApplicationLocked(IApplicationThread thread, 4990 int pid) { 4991 4992 // Find the application record that is being attached... either via 4993 // the pid if we are running in multiple processes, or just pull the 4994 // next app record if we are emulating process with anonymous threads. 4995 ProcessRecord app; 4996 if (pid != MY_PID && pid >= 0) { 4997 synchronized (mPidsSelfLocked) { 4998 app = mPidsSelfLocked.get(pid); 4999 } 5000 } else { 5001 app = null; 5002 } 5003 5004 if (app == null) { 5005 Slog.w(TAG, "No pending application record for pid " + pid 5006 + " (IApplicationThread " + thread + "); dropping process"); 5007 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5008 if (pid > 0 && pid != MY_PID) { 5009 Process.killProcessQuiet(pid); 5010 } else { 5011 try { 5012 thread.scheduleExit(); 5013 } catch (Exception e) { 5014 // Ignore exceptions. 5015 } 5016 } 5017 return false; 5018 } 5019 5020 // If this application record is still attached to a previous 5021 // process, clean it up now. 5022 if (app.thread != null) { 5023 handleAppDiedLocked(app, true, true); 5024 } 5025 5026 // Tell the process all about itself. 5027 5028 if (localLOGV) Slog.v( 5029 TAG, "Binding process pid " + pid + " to record " + app); 5030 5031 final String processName = app.processName; 5032 try { 5033 AppDeathRecipient adr = new AppDeathRecipient( 5034 app, pid, thread); 5035 thread.asBinder().linkToDeath(adr, 0); 5036 app.deathRecipient = adr; 5037 } catch (RemoteException e) { 5038 app.resetPackageList(mProcessStats); 5039 startProcessLocked(app, "link fail", processName); 5040 return false; 5041 } 5042 5043 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5044 5045 app.makeActive(thread, mProcessStats); 5046 app.curAdj = app.setAdj = -100; 5047 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5048 app.forcingToForeground = null; 5049 updateProcessForegroundLocked(app, false, false); 5050 app.hasShownUi = false; 5051 app.debugging = false; 5052 app.cached = false; 5053 5054 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5055 5056 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5057 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5058 5059 if (!normalMode) { 5060 Slog.i(TAG, "Launching preboot mode app: " + app); 5061 } 5062 5063 if (localLOGV) Slog.v( 5064 TAG, "New app record " + app 5065 + " thread=" + thread.asBinder() + " pid=" + pid); 5066 try { 5067 int testMode = IApplicationThread.DEBUG_OFF; 5068 if (mDebugApp != null && mDebugApp.equals(processName)) { 5069 testMode = mWaitForDebugger 5070 ? IApplicationThread.DEBUG_WAIT 5071 : IApplicationThread.DEBUG_ON; 5072 app.debugging = true; 5073 if (mDebugTransient) { 5074 mDebugApp = mOrigDebugApp; 5075 mWaitForDebugger = mOrigWaitForDebugger; 5076 } 5077 } 5078 String profileFile = app.instrumentationProfileFile; 5079 ParcelFileDescriptor profileFd = null; 5080 boolean profileAutoStop = false; 5081 if (mProfileApp != null && mProfileApp.equals(processName)) { 5082 mProfileProc = app; 5083 profileFile = mProfileFile; 5084 profileFd = mProfileFd; 5085 profileAutoStop = mAutoStopProfiler; 5086 } 5087 boolean enableOpenGlTrace = false; 5088 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5089 enableOpenGlTrace = true; 5090 mOpenGlTraceApp = null; 5091 } 5092 5093 // If the app is being launched for restore or full backup, set it up specially 5094 boolean isRestrictedBackupMode = false; 5095 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5096 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5097 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5098 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5099 } 5100 5101 ensurePackageDexOpt(app.instrumentationInfo != null 5102 ? app.instrumentationInfo.packageName 5103 : app.info.packageName); 5104 if (app.instrumentationClass != null) { 5105 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5106 } 5107 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5108 + processName + " with config " + mConfiguration); 5109 ApplicationInfo appInfo = app.instrumentationInfo != null 5110 ? app.instrumentationInfo : app.info; 5111 app.compat = compatibilityInfoForPackageLocked(appInfo); 5112 if (profileFd != null) { 5113 profileFd = profileFd.dup(); 5114 } 5115 thread.bindApplication(processName, appInfo, providers, 5116 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5117 app.instrumentationArguments, app.instrumentationWatcher, 5118 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5119 isRestrictedBackupMode || !normalMode, app.persistent, 5120 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5121 mCoreSettingsObserver.getCoreSettingsLocked()); 5122 updateLruProcessLocked(app, false, null); 5123 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5124 } catch (Exception e) { 5125 // todo: Yikes! What should we do? For now we will try to 5126 // start another process, but that could easily get us in 5127 // an infinite loop of restarting processes... 5128 Slog.w(TAG, "Exception thrown during bind!", e); 5129 5130 app.resetPackageList(mProcessStats); 5131 app.unlinkDeathRecipient(); 5132 startProcessLocked(app, "bind fail", processName); 5133 return false; 5134 } 5135 5136 // Remove this record from the list of starting applications. 5137 mPersistentStartingProcesses.remove(app); 5138 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5139 "Attach application locked removing on hold: " + app); 5140 mProcessesOnHold.remove(app); 5141 5142 boolean badApp = false; 5143 boolean didSomething = false; 5144 5145 // See if the top visible activity is waiting to run in this process... 5146 if (normalMode) { 5147 try { 5148 if (mStackSupervisor.attachApplicationLocked(app)) { 5149 didSomething = true; 5150 } 5151 } catch (Exception e) { 5152 badApp = true; 5153 } 5154 } 5155 5156 // Find any services that should be running in this process... 5157 if (!badApp) { 5158 try { 5159 didSomething |= mServices.attachApplicationLocked(app, processName); 5160 } catch (Exception e) { 5161 badApp = true; 5162 } 5163 } 5164 5165 // Check if a next-broadcast receiver is in this process... 5166 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5167 try { 5168 didSomething |= sendPendingBroadcastsLocked(app); 5169 } catch (Exception e) { 5170 // If the app died trying to launch the receiver we declare it 'bad' 5171 badApp = true; 5172 } 5173 } 5174 5175 // Check whether the next backup agent is in this process... 5176 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5177 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5178 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5179 try { 5180 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5181 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5182 mBackupTarget.backupMode); 5183 } catch (Exception e) { 5184 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5185 e.printStackTrace(); 5186 } 5187 } 5188 5189 if (badApp) { 5190 // todo: Also need to kill application to deal with all 5191 // kinds of exceptions. 5192 handleAppDiedLocked(app, false, true); 5193 return false; 5194 } 5195 5196 if (!didSomething) { 5197 updateOomAdjLocked(); 5198 } 5199 5200 return true; 5201 } 5202 5203 @Override 5204 public final void attachApplication(IApplicationThread thread) { 5205 synchronized (this) { 5206 int callingPid = Binder.getCallingPid(); 5207 final long origId = Binder.clearCallingIdentity(); 5208 attachApplicationLocked(thread, callingPid); 5209 Binder.restoreCallingIdentity(origId); 5210 } 5211 } 5212 5213 @Override 5214 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5215 final long origId = Binder.clearCallingIdentity(); 5216 synchronized (this) { 5217 ActivityStack stack = ActivityRecord.getStackLocked(token); 5218 if (stack != null) { 5219 ActivityRecord r = 5220 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5221 if (stopProfiling) { 5222 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5223 try { 5224 mProfileFd.close(); 5225 } catch (IOException e) { 5226 } 5227 clearProfilerLocked(); 5228 } 5229 } 5230 } 5231 } 5232 Binder.restoreCallingIdentity(origId); 5233 } 5234 5235 void enableScreenAfterBoot() { 5236 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5237 SystemClock.uptimeMillis()); 5238 mWindowManager.enableScreenAfterBoot(); 5239 5240 synchronized (this) { 5241 updateEventDispatchingLocked(); 5242 } 5243 } 5244 5245 @Override 5246 public void showBootMessage(final CharSequence msg, final boolean always) { 5247 enforceNotIsolatedCaller("showBootMessage"); 5248 mWindowManager.showBootMessage(msg, always); 5249 } 5250 5251 @Override 5252 public void dismissKeyguardOnNextActivity() { 5253 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5254 final long token = Binder.clearCallingIdentity(); 5255 try { 5256 synchronized (this) { 5257 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5258 if (mLockScreenShown) { 5259 mLockScreenShown = false; 5260 comeOutOfSleepIfNeededLocked(); 5261 } 5262 mStackSupervisor.setDismissKeyguard(true); 5263 } 5264 } finally { 5265 Binder.restoreCallingIdentity(token); 5266 } 5267 } 5268 5269 final void finishBooting() { 5270 IntentFilter pkgFilter = new IntentFilter(); 5271 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5272 pkgFilter.addDataScheme("package"); 5273 mContext.registerReceiver(new BroadcastReceiver() { 5274 @Override 5275 public void onReceive(Context context, Intent intent) { 5276 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5277 if (pkgs != null) { 5278 for (String pkg : pkgs) { 5279 synchronized (ActivityManagerService.this) { 5280 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5281 "finished booting")) { 5282 setResultCode(Activity.RESULT_OK); 5283 return; 5284 } 5285 } 5286 } 5287 } 5288 } 5289 }, pkgFilter); 5290 5291 synchronized (this) { 5292 // Ensure that any processes we had put on hold are now started 5293 // up. 5294 final int NP = mProcessesOnHold.size(); 5295 if (NP > 0) { 5296 ArrayList<ProcessRecord> procs = 5297 new ArrayList<ProcessRecord>(mProcessesOnHold); 5298 for (int ip=0; ip<NP; ip++) { 5299 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5300 + procs.get(ip)); 5301 startProcessLocked(procs.get(ip), "on-hold", null); 5302 } 5303 } 5304 5305 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5306 // Start looking for apps that are abusing wake locks. 5307 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5308 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5309 // Tell anyone interested that we are done booting! 5310 SystemProperties.set("sys.boot_completed", "1"); 5311 SystemProperties.set("dev.bootcomplete", "1"); 5312 for (int i=0; i<mStartedUsers.size(); i++) { 5313 UserStartedState uss = mStartedUsers.valueAt(i); 5314 if (uss.mState == UserStartedState.STATE_BOOTING) { 5315 uss.mState = UserStartedState.STATE_RUNNING; 5316 final int userId = mStartedUsers.keyAt(i); 5317 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5318 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5319 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5320 broadcastIntentLocked(null, null, intent, null, 5321 new IIntentReceiver.Stub() { 5322 @Override 5323 public void performReceive(Intent intent, int resultCode, 5324 String data, Bundle extras, boolean ordered, 5325 boolean sticky, int sendingUser) { 5326 synchronized (ActivityManagerService.this) { 5327 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5328 true, false); 5329 } 5330 } 5331 }, 5332 0, null, null, 5333 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5334 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5335 userId); 5336 } 5337 } 5338 scheduleStartProfilesLocked(); 5339 } 5340 } 5341 } 5342 5343 final void ensureBootCompleted() { 5344 boolean booting; 5345 boolean enableScreen; 5346 synchronized (this) { 5347 booting = mBooting; 5348 mBooting = false; 5349 enableScreen = !mBooted; 5350 mBooted = true; 5351 } 5352 5353 if (booting) { 5354 finishBooting(); 5355 } 5356 5357 if (enableScreen) { 5358 enableScreenAfterBoot(); 5359 } 5360 } 5361 5362 @Override 5363 public final void activityResumed(IBinder token) { 5364 final long origId = Binder.clearCallingIdentity(); 5365 synchronized(this) { 5366 ActivityStack stack = ActivityRecord.getStackLocked(token); 5367 if (stack != null) { 5368 ActivityRecord.activityResumedLocked(token); 5369 } 5370 } 5371 Binder.restoreCallingIdentity(origId); 5372 } 5373 5374 @Override 5375 public final void activityPaused(IBinder token) { 5376 final long origId = Binder.clearCallingIdentity(); 5377 synchronized(this) { 5378 ActivityStack stack = ActivityRecord.getStackLocked(token); 5379 if (stack != null) { 5380 stack.activityPausedLocked(token, false); 5381 } 5382 } 5383 Binder.restoreCallingIdentity(origId); 5384 } 5385 5386 @Override 5387 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5388 CharSequence description) { 5389 if (localLOGV) Slog.v( 5390 TAG, "Activity stopped: token=" + token); 5391 5392 // Refuse possible leaked file descriptors 5393 if (icicle != null && icicle.hasFileDescriptors()) { 5394 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5395 } 5396 5397 ActivityRecord r = null; 5398 5399 final long origId = Binder.clearCallingIdentity(); 5400 5401 synchronized (this) { 5402 r = ActivityRecord.isInStackLocked(token); 5403 if (r != null) { 5404 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5405 } 5406 } 5407 5408 if (r != null) { 5409 sendPendingThumbnail(r, null, null, null, false); 5410 } 5411 5412 trimApplications(); 5413 5414 Binder.restoreCallingIdentity(origId); 5415 } 5416 5417 @Override 5418 public final void activityDestroyed(IBinder token) { 5419 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5420 synchronized (this) { 5421 ActivityStack stack = ActivityRecord.getStackLocked(token); 5422 if (stack != null) { 5423 stack.activityDestroyedLocked(token); 5424 } 5425 } 5426 } 5427 5428 @Override 5429 public String getCallingPackage(IBinder token) { 5430 synchronized (this) { 5431 ActivityRecord r = getCallingRecordLocked(token); 5432 return r != null ? r.info.packageName : null; 5433 } 5434 } 5435 5436 @Override 5437 public ComponentName getCallingActivity(IBinder token) { 5438 synchronized (this) { 5439 ActivityRecord r = getCallingRecordLocked(token); 5440 return r != null ? r.intent.getComponent() : null; 5441 } 5442 } 5443 5444 private ActivityRecord getCallingRecordLocked(IBinder token) { 5445 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5446 if (r == null) { 5447 return null; 5448 } 5449 return r.resultTo; 5450 } 5451 5452 @Override 5453 public ComponentName getActivityClassForToken(IBinder token) { 5454 synchronized(this) { 5455 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5456 if (r == null) { 5457 return null; 5458 } 5459 return r.intent.getComponent(); 5460 } 5461 } 5462 5463 @Override 5464 public String getPackageForToken(IBinder token) { 5465 synchronized(this) { 5466 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5467 if (r == null) { 5468 return null; 5469 } 5470 return r.packageName; 5471 } 5472 } 5473 5474 @Override 5475 public IIntentSender getIntentSender(int type, 5476 String packageName, IBinder token, String resultWho, 5477 int requestCode, Intent[] intents, String[] resolvedTypes, 5478 int flags, Bundle options, int userId) { 5479 enforceNotIsolatedCaller("getIntentSender"); 5480 // Refuse possible leaked file descriptors 5481 if (intents != null) { 5482 if (intents.length < 1) { 5483 throw new IllegalArgumentException("Intents array length must be >= 1"); 5484 } 5485 for (int i=0; i<intents.length; i++) { 5486 Intent intent = intents[i]; 5487 if (intent != null) { 5488 if (intent.hasFileDescriptors()) { 5489 throw new IllegalArgumentException("File descriptors passed in Intent"); 5490 } 5491 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5492 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5493 throw new IllegalArgumentException( 5494 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5495 } 5496 intents[i] = new Intent(intent); 5497 } 5498 } 5499 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5500 throw new IllegalArgumentException( 5501 "Intent array length does not match resolvedTypes length"); 5502 } 5503 } 5504 if (options != null) { 5505 if (options.hasFileDescriptors()) { 5506 throw new IllegalArgumentException("File descriptors passed in options"); 5507 } 5508 } 5509 5510 synchronized(this) { 5511 int callingUid = Binder.getCallingUid(); 5512 int origUserId = userId; 5513 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5514 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5515 "getIntentSender", null); 5516 if (origUserId == UserHandle.USER_CURRENT) { 5517 // We don't want to evaluate this until the pending intent is 5518 // actually executed. However, we do want to always do the 5519 // security checking for it above. 5520 userId = UserHandle.USER_CURRENT; 5521 } 5522 try { 5523 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5524 int uid = AppGlobals.getPackageManager() 5525 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5526 if (!UserHandle.isSameApp(callingUid, uid)) { 5527 String msg = "Permission Denial: getIntentSender() from pid=" 5528 + Binder.getCallingPid() 5529 + ", uid=" + Binder.getCallingUid() 5530 + ", (need uid=" + uid + ")" 5531 + " is not allowed to send as package " + packageName; 5532 Slog.w(TAG, msg); 5533 throw new SecurityException(msg); 5534 } 5535 } 5536 5537 return getIntentSenderLocked(type, packageName, callingUid, userId, 5538 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5539 5540 } catch (RemoteException e) { 5541 throw new SecurityException(e); 5542 } 5543 } 5544 } 5545 5546 IIntentSender getIntentSenderLocked(int type, String packageName, 5547 int callingUid, int userId, IBinder token, String resultWho, 5548 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5549 Bundle options) { 5550 if (DEBUG_MU) 5551 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5552 ActivityRecord activity = null; 5553 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5554 activity = ActivityRecord.isInStackLocked(token); 5555 if (activity == null) { 5556 return null; 5557 } 5558 if (activity.finishing) { 5559 return null; 5560 } 5561 } 5562 5563 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5564 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5565 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5566 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5567 |PendingIntent.FLAG_UPDATE_CURRENT); 5568 5569 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5570 type, packageName, activity, resultWho, 5571 requestCode, intents, resolvedTypes, flags, options, userId); 5572 WeakReference<PendingIntentRecord> ref; 5573 ref = mIntentSenderRecords.get(key); 5574 PendingIntentRecord rec = ref != null ? ref.get() : null; 5575 if (rec != null) { 5576 if (!cancelCurrent) { 5577 if (updateCurrent) { 5578 if (rec.key.requestIntent != null) { 5579 rec.key.requestIntent.replaceExtras(intents != null ? 5580 intents[intents.length - 1] : null); 5581 } 5582 if (intents != null) { 5583 intents[intents.length-1] = rec.key.requestIntent; 5584 rec.key.allIntents = intents; 5585 rec.key.allResolvedTypes = resolvedTypes; 5586 } else { 5587 rec.key.allIntents = null; 5588 rec.key.allResolvedTypes = null; 5589 } 5590 } 5591 return rec; 5592 } 5593 rec.canceled = true; 5594 mIntentSenderRecords.remove(key); 5595 } 5596 if (noCreate) { 5597 return rec; 5598 } 5599 rec = new PendingIntentRecord(this, key, callingUid); 5600 mIntentSenderRecords.put(key, rec.ref); 5601 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5602 if (activity.pendingResults == null) { 5603 activity.pendingResults 5604 = new HashSet<WeakReference<PendingIntentRecord>>(); 5605 } 5606 activity.pendingResults.add(rec.ref); 5607 } 5608 return rec; 5609 } 5610 5611 @Override 5612 public void cancelIntentSender(IIntentSender sender) { 5613 if (!(sender instanceof PendingIntentRecord)) { 5614 return; 5615 } 5616 synchronized(this) { 5617 PendingIntentRecord rec = (PendingIntentRecord)sender; 5618 try { 5619 int uid = AppGlobals.getPackageManager() 5620 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5621 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5622 String msg = "Permission Denial: cancelIntentSender() from pid=" 5623 + Binder.getCallingPid() 5624 + ", uid=" + Binder.getCallingUid() 5625 + " is not allowed to cancel packges " 5626 + rec.key.packageName; 5627 Slog.w(TAG, msg); 5628 throw new SecurityException(msg); 5629 } 5630 } catch (RemoteException e) { 5631 throw new SecurityException(e); 5632 } 5633 cancelIntentSenderLocked(rec, true); 5634 } 5635 } 5636 5637 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5638 rec.canceled = true; 5639 mIntentSenderRecords.remove(rec.key); 5640 if (cleanActivity && rec.key.activity != null) { 5641 rec.key.activity.pendingResults.remove(rec.ref); 5642 } 5643 } 5644 5645 @Override 5646 public String getPackageForIntentSender(IIntentSender pendingResult) { 5647 if (!(pendingResult instanceof PendingIntentRecord)) { 5648 return null; 5649 } 5650 try { 5651 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5652 return res.key.packageName; 5653 } catch (ClassCastException e) { 5654 } 5655 return null; 5656 } 5657 5658 @Override 5659 public int getUidForIntentSender(IIntentSender sender) { 5660 if (sender instanceof PendingIntentRecord) { 5661 try { 5662 PendingIntentRecord res = (PendingIntentRecord)sender; 5663 return res.uid; 5664 } catch (ClassCastException e) { 5665 } 5666 } 5667 return -1; 5668 } 5669 5670 @Override 5671 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5672 if (!(pendingResult instanceof PendingIntentRecord)) { 5673 return false; 5674 } 5675 try { 5676 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5677 if (res.key.allIntents == null) { 5678 return false; 5679 } 5680 for (int i=0; i<res.key.allIntents.length; i++) { 5681 Intent intent = res.key.allIntents[i]; 5682 if (intent.getPackage() != null && intent.getComponent() != null) { 5683 return false; 5684 } 5685 } 5686 return true; 5687 } catch (ClassCastException e) { 5688 } 5689 return false; 5690 } 5691 5692 @Override 5693 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5694 if (!(pendingResult instanceof PendingIntentRecord)) { 5695 return false; 5696 } 5697 try { 5698 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5699 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5700 return true; 5701 } 5702 return false; 5703 } catch (ClassCastException e) { 5704 } 5705 return false; 5706 } 5707 5708 @Override 5709 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5710 if (!(pendingResult instanceof PendingIntentRecord)) { 5711 return null; 5712 } 5713 try { 5714 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5715 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5716 } catch (ClassCastException e) { 5717 } 5718 return null; 5719 } 5720 5721 @Override 5722 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5723 if (!(pendingResult instanceof PendingIntentRecord)) { 5724 return null; 5725 } 5726 try { 5727 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5728 Intent intent = res.key.requestIntent; 5729 if (intent != null) { 5730 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5731 || res.lastTagPrefix.equals(prefix))) { 5732 return res.lastTag; 5733 } 5734 res.lastTagPrefix = prefix; 5735 StringBuilder sb = new StringBuilder(128); 5736 if (prefix != null) { 5737 sb.append(prefix); 5738 } 5739 if (intent.getAction() != null) { 5740 sb.append(intent.getAction()); 5741 } else if (intent.getComponent() != null) { 5742 intent.getComponent().appendShortString(sb); 5743 } else { 5744 sb.append("?"); 5745 } 5746 return res.lastTag = sb.toString(); 5747 } 5748 } catch (ClassCastException e) { 5749 } 5750 return null; 5751 } 5752 5753 @Override 5754 public void setProcessLimit(int max) { 5755 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5756 "setProcessLimit()"); 5757 synchronized (this) { 5758 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5759 mProcessLimitOverride = max; 5760 } 5761 trimApplications(); 5762 } 5763 5764 @Override 5765 public int getProcessLimit() { 5766 synchronized (this) { 5767 return mProcessLimitOverride; 5768 } 5769 } 5770 5771 void foregroundTokenDied(ForegroundToken token) { 5772 synchronized (ActivityManagerService.this) { 5773 synchronized (mPidsSelfLocked) { 5774 ForegroundToken cur 5775 = mForegroundProcesses.get(token.pid); 5776 if (cur != token) { 5777 return; 5778 } 5779 mForegroundProcesses.remove(token.pid); 5780 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5781 if (pr == null) { 5782 return; 5783 } 5784 pr.forcingToForeground = null; 5785 updateProcessForegroundLocked(pr, false, false); 5786 } 5787 updateOomAdjLocked(); 5788 } 5789 } 5790 5791 @Override 5792 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5793 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5794 "setProcessForeground()"); 5795 synchronized(this) { 5796 boolean changed = false; 5797 5798 synchronized (mPidsSelfLocked) { 5799 ProcessRecord pr = mPidsSelfLocked.get(pid); 5800 if (pr == null && isForeground) { 5801 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5802 return; 5803 } 5804 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5805 if (oldToken != null) { 5806 oldToken.token.unlinkToDeath(oldToken, 0); 5807 mForegroundProcesses.remove(pid); 5808 if (pr != null) { 5809 pr.forcingToForeground = null; 5810 } 5811 changed = true; 5812 } 5813 if (isForeground && token != null) { 5814 ForegroundToken newToken = new ForegroundToken() { 5815 @Override 5816 public void binderDied() { 5817 foregroundTokenDied(this); 5818 } 5819 }; 5820 newToken.pid = pid; 5821 newToken.token = token; 5822 try { 5823 token.linkToDeath(newToken, 0); 5824 mForegroundProcesses.put(pid, newToken); 5825 pr.forcingToForeground = token; 5826 changed = true; 5827 } catch (RemoteException e) { 5828 // If the process died while doing this, we will later 5829 // do the cleanup with the process death link. 5830 } 5831 } 5832 } 5833 5834 if (changed) { 5835 updateOomAdjLocked(); 5836 } 5837 } 5838 } 5839 5840 // ========================================================= 5841 // PERMISSIONS 5842 // ========================================================= 5843 5844 static class PermissionController extends IPermissionController.Stub { 5845 ActivityManagerService mActivityManagerService; 5846 PermissionController(ActivityManagerService activityManagerService) { 5847 mActivityManagerService = activityManagerService; 5848 } 5849 5850 @Override 5851 public boolean checkPermission(String permission, int pid, int uid) { 5852 return mActivityManagerService.checkPermission(permission, pid, 5853 uid) == PackageManager.PERMISSION_GRANTED; 5854 } 5855 } 5856 5857 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5858 @Override 5859 public int checkComponentPermission(String permission, int pid, int uid, 5860 int owningUid, boolean exported) { 5861 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5862 owningUid, exported); 5863 } 5864 5865 @Override 5866 public Object getAMSLock() { 5867 return ActivityManagerService.this; 5868 } 5869 } 5870 5871 /** 5872 * This can be called with or without the global lock held. 5873 */ 5874 int checkComponentPermission(String permission, int pid, int uid, 5875 int owningUid, boolean exported) { 5876 // We might be performing an operation on behalf of an indirect binder 5877 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5878 // client identity accordingly before proceeding. 5879 Identity tlsIdentity = sCallerIdentity.get(); 5880 if (tlsIdentity != null) { 5881 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5882 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5883 uid = tlsIdentity.uid; 5884 pid = tlsIdentity.pid; 5885 } 5886 5887 if (pid == MY_PID) { 5888 return PackageManager.PERMISSION_GRANTED; 5889 } 5890 5891 return ActivityManager.checkComponentPermission(permission, uid, 5892 owningUid, exported); 5893 } 5894 5895 /** 5896 * As the only public entry point for permissions checking, this method 5897 * can enforce the semantic that requesting a check on a null global 5898 * permission is automatically denied. (Internally a null permission 5899 * string is used when calling {@link #checkComponentPermission} in cases 5900 * when only uid-based security is needed.) 5901 * 5902 * This can be called with or without the global lock held. 5903 */ 5904 @Override 5905 public int checkPermission(String permission, int pid, int uid) { 5906 if (permission == null) { 5907 return PackageManager.PERMISSION_DENIED; 5908 } 5909 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5910 } 5911 5912 /** 5913 * Binder IPC calls go through the public entry point. 5914 * This can be called with or without the global lock held. 5915 */ 5916 int checkCallingPermission(String permission) { 5917 return checkPermission(permission, 5918 Binder.getCallingPid(), 5919 UserHandle.getAppId(Binder.getCallingUid())); 5920 } 5921 5922 /** 5923 * This can be called with or without the global lock held. 5924 */ 5925 void enforceCallingPermission(String permission, String func) { 5926 if (checkCallingPermission(permission) 5927 == PackageManager.PERMISSION_GRANTED) { 5928 return; 5929 } 5930 5931 String msg = "Permission Denial: " + func + " from pid=" 5932 + Binder.getCallingPid() 5933 + ", uid=" + Binder.getCallingUid() 5934 + " requires " + permission; 5935 Slog.w(TAG, msg); 5936 throw new SecurityException(msg); 5937 } 5938 5939 /** 5940 * Determine if UID is holding permissions required to access {@link Uri} in 5941 * the given {@link ProviderInfo}. Final permission checking is always done 5942 * in {@link ContentProvider}. 5943 */ 5944 private final boolean checkHoldingPermissionsLocked( 5945 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 5946 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5947 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5948 5949 if (pi.applicationInfo.uid == uid) { 5950 return true; 5951 } else if (!pi.exported) { 5952 return false; 5953 } 5954 5955 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5956 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5957 try { 5958 // check if target holds top-level <provider> permissions 5959 if (!readMet && pi.readPermission != null 5960 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5961 readMet = true; 5962 } 5963 if (!writeMet && pi.writePermission != null 5964 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5965 writeMet = true; 5966 } 5967 5968 // track if unprotected read/write is allowed; any denied 5969 // <path-permission> below removes this ability 5970 boolean allowDefaultRead = pi.readPermission == null; 5971 boolean allowDefaultWrite = pi.writePermission == null; 5972 5973 // check if target holds any <path-permission> that match uri 5974 final PathPermission[] pps = pi.pathPermissions; 5975 if (pps != null) { 5976 final String path = uri.getPath(); 5977 int i = pps.length; 5978 while (i > 0 && (!readMet || !writeMet)) { 5979 i--; 5980 PathPermission pp = pps[i]; 5981 if (pp.match(path)) { 5982 if (!readMet) { 5983 final String pprperm = pp.getReadPermission(); 5984 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5985 + pprperm + " for " + pp.getPath() 5986 + ": match=" + pp.match(path) 5987 + " check=" + pm.checkUidPermission(pprperm, uid)); 5988 if (pprperm != null) { 5989 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5990 readMet = true; 5991 } else { 5992 allowDefaultRead = false; 5993 } 5994 } 5995 } 5996 if (!writeMet) { 5997 final String ppwperm = pp.getWritePermission(); 5998 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5999 + ppwperm + " for " + pp.getPath() 6000 + ": match=" + pp.match(path) 6001 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6002 if (ppwperm != null) { 6003 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6004 writeMet = true; 6005 } else { 6006 allowDefaultWrite = false; 6007 } 6008 } 6009 } 6010 } 6011 } 6012 } 6013 6014 // grant unprotected <provider> read/write, if not blocked by 6015 // <path-permission> above 6016 if (allowDefaultRead) readMet = true; 6017 if (allowDefaultWrite) writeMet = true; 6018 6019 } catch (RemoteException e) { 6020 return false; 6021 } 6022 6023 return readMet && writeMet; 6024 } 6025 6026 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6027 ProviderInfo pi = null; 6028 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6029 if (cpr != null) { 6030 pi = cpr.info; 6031 } else { 6032 try { 6033 pi = AppGlobals.getPackageManager().resolveContentProvider( 6034 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6035 } catch (RemoteException ex) { 6036 } 6037 } 6038 return pi; 6039 } 6040 6041 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 6042 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6043 if (targetUris != null) { 6044 return targetUris.get(uri); 6045 } 6046 return null; 6047 } 6048 6049 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6050 String targetPkg, int targetUid, GrantUri uri) { 6051 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6052 if (targetUris == null) { 6053 targetUris = Maps.newArrayMap(); 6054 mGrantedUriPermissions.put(targetUid, targetUris); 6055 } 6056 6057 UriPermission perm = targetUris.get(uri); 6058 if (perm == null) { 6059 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 6060 targetUris.put(uri, perm); 6061 } 6062 6063 return perm; 6064 } 6065 6066 private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) { 6067 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6068 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6069 : UriPermission.STRENGTH_OWNED; 6070 6071 // Root gets to do everything. 6072 if (uid == 0) { 6073 return true; 6074 } 6075 6076 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6077 if (perms == null) return false; 6078 6079 // First look for exact match 6080 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 6081 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6082 return true; 6083 } 6084 6085 // No exact match, look for prefixes 6086 final int N = perms.size(); 6087 for (int i = 0; i < N; i++) { 6088 final UriPermission perm = perms.valueAt(i); 6089 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6090 && perm.getStrength(modeFlags) >= minStrength) { 6091 return true; 6092 } 6093 } 6094 6095 return false; 6096 } 6097 6098 @Override 6099 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6100 enforceNotIsolatedCaller("checkUriPermission"); 6101 6102 // Another redirected-binder-call permissions check as in 6103 // {@link checkComponentPermission}. 6104 Identity tlsIdentity = sCallerIdentity.get(); 6105 if (tlsIdentity != null) { 6106 uid = tlsIdentity.uid; 6107 pid = tlsIdentity.pid; 6108 } 6109 6110 // Our own process gets to do everything. 6111 if (pid == MY_PID) { 6112 return PackageManager.PERMISSION_GRANTED; 6113 } 6114 synchronized (this) { 6115 return checkUriPermissionLocked(uri, uid, modeFlags) 6116 ? PackageManager.PERMISSION_GRANTED 6117 : PackageManager.PERMISSION_DENIED; 6118 } 6119 } 6120 6121 /** 6122 * Check if the targetPkg can be granted permission to access uri by 6123 * the callingUid using the given modeFlags. Throws a security exception 6124 * if callingUid is not allowed to do this. Returns the uid of the target 6125 * if the URI permission grant should be performed; returns -1 if it is not 6126 * needed (for example targetPkg already has permission to access the URI). 6127 * If you already know the uid of the target, you can supply it in 6128 * lastTargetUid else set that to -1. 6129 */ 6130 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6131 Uri uri, final int modeFlags, int lastTargetUid) { 6132 if (!Intent.isAccessUriMode(modeFlags)) { 6133 return -1; 6134 } 6135 6136 if (targetPkg != null) { 6137 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6138 "Checking grant " + targetPkg + " permission to " + uri); 6139 } 6140 6141 final IPackageManager pm = AppGlobals.getPackageManager(); 6142 6143 // If this is not a content: uri, we can't do anything with it. 6144 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6145 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6146 "Can't grant URI permission for non-content URI: " + uri); 6147 return -1; 6148 } 6149 6150 final String authority = uri.getAuthority(); 6151 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6152 if (pi == null) { 6153 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6154 return -1; 6155 } 6156 6157 int targetUid = lastTargetUid; 6158 if (targetUid < 0 && targetPkg != null) { 6159 try { 6160 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6161 if (targetUid < 0) { 6162 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6163 "Can't grant URI permission no uid for: " + targetPkg); 6164 return -1; 6165 } 6166 } catch (RemoteException ex) { 6167 return -1; 6168 } 6169 } 6170 6171 if (targetUid >= 0) { 6172 // First... does the target actually need this permission? 6173 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6174 // No need to grant the target this permission. 6175 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6176 "Target " + targetPkg + " already has full permission to " + uri); 6177 return -1; 6178 } 6179 } else { 6180 // First... there is no target package, so can anyone access it? 6181 boolean allowed = pi.exported; 6182 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6183 if (pi.readPermission != null) { 6184 allowed = false; 6185 } 6186 } 6187 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6188 if (pi.writePermission != null) { 6189 allowed = false; 6190 } 6191 } 6192 if (allowed) { 6193 return -1; 6194 } 6195 } 6196 6197 // Second... is the provider allowing granting of URI permissions? 6198 if (!pi.grantUriPermissions) { 6199 throw new SecurityException("Provider " + pi.packageName 6200 + "/" + pi.name 6201 + " does not allow granting of Uri permissions (uri " 6202 + uri + ")"); 6203 } 6204 if (pi.uriPermissionPatterns != null) { 6205 final int N = pi.uriPermissionPatterns.length; 6206 boolean allowed = false; 6207 for (int i=0; i<N; i++) { 6208 if (pi.uriPermissionPatterns[i] != null 6209 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6210 allowed = true; 6211 break; 6212 } 6213 } 6214 if (!allowed) { 6215 throw new SecurityException("Provider " + pi.packageName 6216 + "/" + pi.name 6217 + " does not allow granting of permission to path of Uri " 6218 + uri); 6219 } 6220 } 6221 6222 // Third... does the caller itself have permission to access 6223 // this uri? 6224 if (callingUid != Process.myUid()) { 6225 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6226 // Require they hold a strong enough Uri permission 6227 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6228 throw new SecurityException("Uid " + callingUid 6229 + " does not have permission to uri " + uri); 6230 } 6231 } 6232 } 6233 6234 return targetUid; 6235 } 6236 6237 @Override 6238 public int checkGrantUriPermission(int callingUid, String targetPkg, 6239 Uri uri, final int modeFlags) { 6240 enforceNotIsolatedCaller("checkGrantUriPermission"); 6241 synchronized(this) { 6242 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6243 } 6244 } 6245 6246 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6247 final int modeFlags, UriPermissionOwner owner) { 6248 if (!Intent.isAccessUriMode(modeFlags)) { 6249 return; 6250 } 6251 6252 // So here we are: the caller has the assumed permission 6253 // to the uri, and the target doesn't. Let's now give this to 6254 // the target. 6255 6256 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6257 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6258 6259 final String authority = uri.getAuthority(); 6260 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6261 if (pi == null) { 6262 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6263 return; 6264 } 6265 6266 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6267 final UriPermission perm = findOrCreateUriPermissionLocked( 6268 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6269 perm.grantModes(modeFlags, owner); 6270 } 6271 6272 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6273 final int modeFlags, UriPermissionOwner owner) { 6274 if (targetPkg == null) { 6275 throw new NullPointerException("targetPkg"); 6276 } 6277 6278 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6279 if (targetUid < 0) { 6280 return; 6281 } 6282 6283 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6284 } 6285 6286 static class NeededUriGrants extends ArrayList<Uri> { 6287 final String targetPkg; 6288 final int targetUid; 6289 final int flags; 6290 6291 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6292 this.targetPkg = targetPkg; 6293 this.targetUid = targetUid; 6294 this.flags = flags; 6295 } 6296 } 6297 6298 /** 6299 * Like checkGrantUriPermissionLocked, but takes an Intent. 6300 */ 6301 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6302 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6303 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6304 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6305 + " clip=" + (intent != null ? intent.getClipData() : null) 6306 + " from " + intent + "; flags=0x" 6307 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6308 6309 if (targetPkg == null) { 6310 throw new NullPointerException("targetPkg"); 6311 } 6312 6313 if (intent == null) { 6314 return null; 6315 } 6316 Uri data = intent.getData(); 6317 ClipData clip = intent.getClipData(); 6318 if (data == null && clip == null) { 6319 return null; 6320 } 6321 6322 if (data != null) { 6323 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6324 mode, needed != null ? needed.targetUid : -1); 6325 if (targetUid > 0) { 6326 if (needed == null) { 6327 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6328 } 6329 needed.add(data); 6330 } 6331 } 6332 if (clip != null) { 6333 for (int i=0; i<clip.getItemCount(); i++) { 6334 Uri uri = clip.getItemAt(i).getUri(); 6335 if (uri != null) { 6336 int targetUid = -1; 6337 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6338 mode, needed != null ? needed.targetUid : -1); 6339 if (targetUid > 0) { 6340 if (needed == null) { 6341 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6342 } 6343 needed.add(uri); 6344 } 6345 } else { 6346 Intent clipIntent = clip.getItemAt(i).getIntent(); 6347 if (clipIntent != null) { 6348 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6349 callingUid, targetPkg, clipIntent, mode, needed); 6350 if (newNeeded != null) { 6351 needed = newNeeded; 6352 } 6353 } 6354 } 6355 } 6356 } 6357 6358 return needed; 6359 } 6360 6361 /** 6362 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6363 */ 6364 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6365 UriPermissionOwner owner) { 6366 if (needed != null) { 6367 for (int i=0; i<needed.size(); i++) { 6368 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6369 needed.get(i), needed.flags, owner); 6370 } 6371 } 6372 } 6373 6374 void grantUriPermissionFromIntentLocked(int callingUid, 6375 String targetPkg, Intent intent, UriPermissionOwner owner) { 6376 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6377 intent, intent != null ? intent.getFlags() : 0, null); 6378 if (needed == null) { 6379 return; 6380 } 6381 6382 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6383 } 6384 6385 @Override 6386 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6387 Uri uri, final int modeFlags) { 6388 enforceNotIsolatedCaller("grantUriPermission"); 6389 synchronized(this) { 6390 final ProcessRecord r = getRecordForAppLocked(caller); 6391 if (r == null) { 6392 throw new SecurityException("Unable to find app for caller " 6393 + caller 6394 + " when granting permission to uri " + uri); 6395 } 6396 if (targetPkg == null) { 6397 throw new IllegalArgumentException("null target"); 6398 } 6399 if (uri == null) { 6400 throw new IllegalArgumentException("null uri"); 6401 } 6402 6403 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6404 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6405 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6406 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6407 6408 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6409 } 6410 } 6411 6412 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6413 if (perm.modeFlags == 0) { 6414 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6415 perm.targetUid); 6416 if (perms != null) { 6417 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6418 "Removing " + perm.targetUid + " permission to " + perm.uri); 6419 6420 perms.remove(perm.uri); 6421 if (perms.isEmpty()) { 6422 mGrantedUriPermissions.remove(perm.targetUid); 6423 } 6424 } 6425 } 6426 } 6427 6428 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6429 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6430 6431 final IPackageManager pm = AppGlobals.getPackageManager(); 6432 final String authority = uri.getAuthority(); 6433 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6434 if (pi == null) { 6435 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6436 return; 6437 } 6438 6439 // Does the caller have this permission on the URI? 6440 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6441 // Right now, if you are not the original owner of the permission, 6442 // you are not allowed to revoke it. 6443 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6444 throw new SecurityException("Uid " + callingUid 6445 + " does not have permission to uri " + uri); 6446 //} 6447 } 6448 6449 boolean persistChanged = false; 6450 6451 // Go through all of the permissions and remove any that match. 6452 int N = mGrantedUriPermissions.size(); 6453 for (int i = 0; i < N; i++) { 6454 final int targetUid = mGrantedUriPermissions.keyAt(i); 6455 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6456 6457 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6458 final UriPermission perm = it.next(); 6459 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6460 if (DEBUG_URI_PERMISSION) 6461 Slog.v(TAG, 6462 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6463 persistChanged |= perm.revokeModes( 6464 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6465 if (perm.modeFlags == 0) { 6466 it.remove(); 6467 } 6468 } 6469 } 6470 6471 if (perms.isEmpty()) { 6472 mGrantedUriPermissions.remove(targetUid); 6473 N--; 6474 i--; 6475 } 6476 } 6477 6478 if (persistChanged) { 6479 schedulePersistUriGrants(); 6480 } 6481 } 6482 6483 @Override 6484 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6485 final int modeFlags) { 6486 enforceNotIsolatedCaller("revokeUriPermission"); 6487 synchronized(this) { 6488 final ProcessRecord r = getRecordForAppLocked(caller); 6489 if (r == null) { 6490 throw new SecurityException("Unable to find app for caller " 6491 + caller 6492 + " when revoking permission to uri " + uri); 6493 } 6494 if (uri == null) { 6495 Slog.w(TAG, "revokeUriPermission: null uri"); 6496 return; 6497 } 6498 6499 if (!Intent.isAccessUriMode(modeFlags)) { 6500 return; 6501 } 6502 6503 final IPackageManager pm = AppGlobals.getPackageManager(); 6504 final String authority = uri.getAuthority(); 6505 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6506 if (pi == null) { 6507 Slog.w(TAG, "No content provider found for permission revoke: " 6508 + uri.toSafeString()); 6509 return; 6510 } 6511 6512 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6513 } 6514 } 6515 6516 /** 6517 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6518 * given package. 6519 * 6520 * @param packageName Package name to match, or {@code null} to apply to all 6521 * packages. 6522 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6523 * to all users. 6524 * @param persistable If persistable grants should be removed. 6525 */ 6526 private void removeUriPermissionsForPackageLocked( 6527 String packageName, int userHandle, boolean persistable) { 6528 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6529 throw new IllegalArgumentException("Must narrow by either package or user"); 6530 } 6531 6532 boolean persistChanged = false; 6533 6534 int N = mGrantedUriPermissions.size(); 6535 for (int i = 0; i < N; i++) { 6536 final int targetUid = mGrantedUriPermissions.keyAt(i); 6537 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6538 6539 // Only inspect grants matching user 6540 if (userHandle == UserHandle.USER_ALL 6541 || userHandle == UserHandle.getUserId(targetUid)) { 6542 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6543 final UriPermission perm = it.next(); 6544 6545 // Only inspect grants matching package 6546 if (packageName == null || perm.sourcePkg.equals(packageName) 6547 || perm.targetPkg.equals(packageName)) { 6548 persistChanged |= perm.revokeModes( 6549 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6550 6551 // Only remove when no modes remain; any persisted grants 6552 // will keep this alive. 6553 if (perm.modeFlags == 0) { 6554 it.remove(); 6555 } 6556 } 6557 } 6558 6559 if (perms.isEmpty()) { 6560 mGrantedUriPermissions.remove(targetUid); 6561 N--; 6562 i--; 6563 } 6564 } 6565 } 6566 6567 if (persistChanged) { 6568 schedulePersistUriGrants(); 6569 } 6570 } 6571 6572 @Override 6573 public IBinder newUriPermissionOwner(String name) { 6574 enforceNotIsolatedCaller("newUriPermissionOwner"); 6575 synchronized(this) { 6576 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6577 return owner.getExternalTokenLocked(); 6578 } 6579 } 6580 6581 @Override 6582 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6583 Uri uri, final int modeFlags) { 6584 synchronized(this) { 6585 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6586 if (owner == null) { 6587 throw new IllegalArgumentException("Unknown owner: " + token); 6588 } 6589 if (fromUid != Binder.getCallingUid()) { 6590 if (Binder.getCallingUid() != Process.myUid()) { 6591 // Only system code can grant URI permissions on behalf 6592 // of other users. 6593 throw new SecurityException("nice try"); 6594 } 6595 } 6596 if (targetPkg == null) { 6597 throw new IllegalArgumentException("null target"); 6598 } 6599 if (uri == null) { 6600 throw new IllegalArgumentException("null uri"); 6601 } 6602 6603 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6604 } 6605 } 6606 6607 @Override 6608 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6609 synchronized(this) { 6610 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6611 if (owner == null) { 6612 throw new IllegalArgumentException("Unknown owner: " + token); 6613 } 6614 6615 if (uri == null) { 6616 owner.removeUriPermissionsLocked(mode); 6617 } else { 6618 owner.removeUriPermissionLocked(uri, mode); 6619 } 6620 } 6621 } 6622 6623 private void schedulePersistUriGrants() { 6624 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6625 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6626 10 * DateUtils.SECOND_IN_MILLIS); 6627 } 6628 } 6629 6630 private void writeGrantedUriPermissions() { 6631 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6632 6633 // Snapshot permissions so we can persist without lock 6634 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6635 synchronized (this) { 6636 final int size = mGrantedUriPermissions.size(); 6637 for (int i = 0; i < size; i++) { 6638 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6639 for (UriPermission perm : perms.values()) { 6640 if (perm.persistedModeFlags != 0) { 6641 persist.add(perm.snapshot()); 6642 } 6643 } 6644 } 6645 } 6646 6647 FileOutputStream fos = null; 6648 try { 6649 fos = mGrantFile.startWrite(); 6650 6651 XmlSerializer out = new FastXmlSerializer(); 6652 out.setOutput(fos, "utf-8"); 6653 out.startDocument(null, true); 6654 out.startTag(null, TAG_URI_GRANTS); 6655 for (UriPermission.Snapshot perm : persist) { 6656 out.startTag(null, TAG_URI_GRANT); 6657 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6658 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6659 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6660 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6661 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6662 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6663 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6664 out.endTag(null, TAG_URI_GRANT); 6665 } 6666 out.endTag(null, TAG_URI_GRANTS); 6667 out.endDocument(); 6668 6669 mGrantFile.finishWrite(fos); 6670 } catch (IOException e) { 6671 if (fos != null) { 6672 mGrantFile.failWrite(fos); 6673 } 6674 } 6675 } 6676 6677 private void readGrantedUriPermissionsLocked() { 6678 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6679 6680 final long now = System.currentTimeMillis(); 6681 6682 FileInputStream fis = null; 6683 try { 6684 fis = mGrantFile.openRead(); 6685 final XmlPullParser in = Xml.newPullParser(); 6686 in.setInput(fis, null); 6687 6688 int type; 6689 while ((type = in.next()) != END_DOCUMENT) { 6690 final String tag = in.getName(); 6691 if (type == START_TAG) { 6692 if (TAG_URI_GRANT.equals(tag)) { 6693 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6694 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6695 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6696 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6697 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6698 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6699 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6700 6701 // Sanity check that provider still belongs to source package 6702 final ProviderInfo pi = getProviderInfoLocked( 6703 uri.getAuthority(), userHandle); 6704 if (pi != null && sourcePkg.equals(pi.packageName)) { 6705 int targetUid = -1; 6706 try { 6707 targetUid = AppGlobals.getPackageManager() 6708 .getPackageUid(targetPkg, userHandle); 6709 } catch (RemoteException e) { 6710 } 6711 if (targetUid != -1) { 6712 final UriPermission perm = findOrCreateUriPermissionLocked( 6713 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6714 perm.initPersistedModes(modeFlags, createdTime); 6715 } 6716 } else { 6717 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6718 + " but instead found " + pi); 6719 } 6720 } 6721 } 6722 } 6723 } catch (FileNotFoundException e) { 6724 // Missing grants is okay 6725 } catch (IOException e) { 6726 Log.wtf(TAG, "Failed reading Uri grants", e); 6727 } catch (XmlPullParserException e) { 6728 Log.wtf(TAG, "Failed reading Uri grants", e); 6729 } finally { 6730 IoUtils.closeQuietly(fis); 6731 } 6732 } 6733 6734 @Override 6735 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6736 enforceNotIsolatedCaller("takePersistableUriPermission"); 6737 6738 Preconditions.checkFlagsArgument(modeFlags, 6739 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6740 6741 synchronized (this) { 6742 final int callingUid = Binder.getCallingUid(); 6743 boolean persistChanged = false; 6744 6745 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6746 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6747 6748 final boolean exactValid = (exactPerm != null) 6749 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6750 final boolean prefixValid = (prefixPerm != null) 6751 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6752 6753 if (!(exactValid || prefixValid)) { 6754 throw new SecurityException("No persistable permission grants found for UID " 6755 + callingUid + " and Uri " + uri.toSafeString()); 6756 } 6757 6758 if (exactValid) { 6759 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6760 } 6761 if (prefixValid) { 6762 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6763 } 6764 6765 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6766 6767 if (persistChanged) { 6768 schedulePersistUriGrants(); 6769 } 6770 } 6771 } 6772 6773 @Override 6774 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6775 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6776 6777 Preconditions.checkFlagsArgument(modeFlags, 6778 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6779 6780 synchronized (this) { 6781 final int callingUid = Binder.getCallingUid(); 6782 boolean persistChanged = false; 6783 6784 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6785 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6786 if (exactPerm == null && prefixPerm == null) { 6787 throw new SecurityException("No permission grants found for UID " + callingUid 6788 + " and Uri " + uri.toSafeString()); 6789 } 6790 6791 if (exactPerm != null) { 6792 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6793 removeUriPermissionIfNeededLocked(exactPerm); 6794 } 6795 if (prefixPerm != null) { 6796 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6797 removeUriPermissionIfNeededLocked(prefixPerm); 6798 } 6799 6800 if (persistChanged) { 6801 schedulePersistUriGrants(); 6802 } 6803 } 6804 } 6805 6806 /** 6807 * Prune any older {@link UriPermission} for the given UID until outstanding 6808 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6809 * 6810 * @return if any mutations occured that require persisting. 6811 */ 6812 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6813 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6814 if (perms == null) return false; 6815 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6816 6817 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6818 for (UriPermission perm : perms.values()) { 6819 if (perm.persistedModeFlags != 0) { 6820 persisted.add(perm); 6821 } 6822 } 6823 6824 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6825 if (trimCount <= 0) return false; 6826 6827 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6828 for (int i = 0; i < trimCount; i++) { 6829 final UriPermission perm = persisted.get(i); 6830 6831 if (DEBUG_URI_PERMISSION) { 6832 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6833 } 6834 6835 perm.releasePersistableModes(~0); 6836 removeUriPermissionIfNeededLocked(perm); 6837 } 6838 6839 return true; 6840 } 6841 6842 @Override 6843 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6844 String packageName, boolean incoming) { 6845 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6846 Preconditions.checkNotNull(packageName, "packageName"); 6847 6848 final int callingUid = Binder.getCallingUid(); 6849 final IPackageManager pm = AppGlobals.getPackageManager(); 6850 try { 6851 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6852 if (packageUid != callingUid) { 6853 throw new SecurityException( 6854 "Package " + packageName + " does not belong to calling UID " + callingUid); 6855 } 6856 } catch (RemoteException e) { 6857 throw new SecurityException("Failed to verify package name ownership"); 6858 } 6859 6860 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6861 synchronized (this) { 6862 if (incoming) { 6863 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6864 callingUid); 6865 if (perms == null) { 6866 Slog.w(TAG, "No permission grants found for " + packageName); 6867 } else { 6868 for (UriPermission perm : perms.values()) { 6869 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6870 result.add(perm.buildPersistedPublicApiObject()); 6871 } 6872 } 6873 } 6874 } else { 6875 final int size = mGrantedUriPermissions.size(); 6876 for (int i = 0; i < size; i++) { 6877 final ArrayMap<GrantUri, UriPermission> perms = 6878 mGrantedUriPermissions.valueAt(i); 6879 for (UriPermission perm : perms.values()) { 6880 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6881 result.add(perm.buildPersistedPublicApiObject()); 6882 } 6883 } 6884 } 6885 } 6886 } 6887 return new ParceledListSlice<android.content.UriPermission>(result); 6888 } 6889 6890 @Override 6891 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6892 synchronized (this) { 6893 ProcessRecord app = 6894 who != null ? getRecordForAppLocked(who) : null; 6895 if (app == null) return; 6896 6897 Message msg = Message.obtain(); 6898 msg.what = WAIT_FOR_DEBUGGER_MSG; 6899 msg.obj = app; 6900 msg.arg1 = waiting ? 1 : 0; 6901 mHandler.sendMessage(msg); 6902 } 6903 } 6904 6905 @Override 6906 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6907 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6908 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6909 outInfo.availMem = Process.getFreeMemory(); 6910 outInfo.totalMem = Process.getTotalMemory(); 6911 outInfo.threshold = homeAppMem; 6912 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6913 outInfo.hiddenAppThreshold = cachedAppMem; 6914 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6915 ProcessList.SERVICE_ADJ); 6916 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6917 ProcessList.VISIBLE_APP_ADJ); 6918 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6919 ProcessList.FOREGROUND_APP_ADJ); 6920 } 6921 6922 // ========================================================= 6923 // TASK MANAGEMENT 6924 // ========================================================= 6925 6926 @Override 6927 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6928 IThumbnailReceiver receiver) { 6929 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6930 6931 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6932 ActivityRecord topRecord = null; 6933 6934 synchronized(this) { 6935 if (localLOGV) Slog.v( 6936 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6937 + ", receiver=" + receiver); 6938 6939 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6940 != PackageManager.PERMISSION_GRANTED) { 6941 if (receiver != null) { 6942 // If the caller wants to wait for pending thumbnails, 6943 // it ain't gonna get them. 6944 try { 6945 receiver.finished(); 6946 } catch (RemoteException ex) { 6947 } 6948 } 6949 String msg = "Permission Denial: getTasks() from pid=" 6950 + Binder.getCallingPid() 6951 + ", uid=" + Binder.getCallingUid() 6952 + " requires " + android.Manifest.permission.GET_TASKS; 6953 Slog.w(TAG, msg); 6954 throw new SecurityException(msg); 6955 } 6956 6957 // TODO: Improve with MRU list from all ActivityStacks. 6958 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6959 6960 if (!pending.pendingRecords.isEmpty()) { 6961 mPendingThumbnails.add(pending); 6962 } 6963 } 6964 6965 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6966 6967 if (topRecord != null) { 6968 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6969 try { 6970 IApplicationThread topThumbnail = topRecord.app.thread; 6971 topThumbnail.requestThumbnail(topRecord.appToken); 6972 } catch (Exception e) { 6973 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6974 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6975 } 6976 } 6977 6978 if (pending.pendingRecords.isEmpty() && receiver != null) { 6979 // In this case all thumbnails were available and the client 6980 // is being asked to be told when the remaining ones come in... 6981 // which is unusually, since the top-most currently running 6982 // activity should never have a canned thumbnail! Oh well. 6983 try { 6984 receiver.finished(); 6985 } catch (RemoteException ex) { 6986 } 6987 } 6988 6989 return list; 6990 } 6991 6992 TaskRecord getMostRecentTask() { 6993 return mRecentTasks.get(0); 6994 } 6995 6996 @Override 6997 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6998 int flags, int userId) { 6999 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7000 false, true, "getRecentTasks", null); 7001 7002 synchronized (this) { 7003 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 7004 "getRecentTasks()"); 7005 final boolean detailed = checkCallingPermission( 7006 android.Manifest.permission.GET_DETAILED_TASKS) 7007 == PackageManager.PERMISSION_GRANTED; 7008 7009 IPackageManager pm = AppGlobals.getPackageManager(); 7010 7011 final int N = mRecentTasks.size(); 7012 ArrayList<ActivityManager.RecentTaskInfo> res 7013 = new ArrayList<ActivityManager.RecentTaskInfo>( 7014 maxNum < N ? maxNum : N); 7015 7016 final Set<Integer> includedUsers; 7017 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7018 includedUsers = getProfileIdsLocked(userId); 7019 } else { 7020 includedUsers = new HashSet<Integer>(); 7021 } 7022 includedUsers.add(Integer.valueOf(userId)); 7023 for (int i=0; i<N && maxNum > 0; i++) { 7024 TaskRecord tr = mRecentTasks.get(i); 7025 // Only add calling user or related users recent tasks 7026 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7027 7028 // Return the entry if desired by the caller. We always return 7029 // the first entry, because callers always expect this to be the 7030 // foreground app. We may filter others if the caller has 7031 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7032 // we should exclude the entry. 7033 7034 if (i == 0 7035 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7036 || (tr.intent == null) 7037 || ((tr.intent.getFlags() 7038 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7039 ActivityManager.RecentTaskInfo rti 7040 = new ActivityManager.RecentTaskInfo(); 7041 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7042 rti.persistentId = tr.taskId; 7043 rti.baseIntent = new Intent( 7044 tr.intent != null ? tr.intent : tr.affinityIntent); 7045 if (!detailed) { 7046 rti.baseIntent.replaceExtras((Bundle)null); 7047 } 7048 rti.origActivity = tr.origActivity; 7049 rti.description = tr.lastDescription; 7050 rti.stackId = tr.stack.mStackId; 7051 rti.userId = tr.userId; 7052 7053 // Traverse upwards looking for any break between main task activities and 7054 // utility activities. 7055 final ArrayList<ActivityRecord> activities = tr.mActivities; 7056 int activityNdx; 7057 final int numActivities = activities.size(); 7058 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7059 ++activityNdx) { 7060 final ActivityRecord r = activities.get(activityNdx); 7061 if (r.intent != null && 7062 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7063 != 0) { 7064 break; 7065 } 7066 } 7067 // Traverse downwards starting below break looking for set label and icon. 7068 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7069 final ActivityRecord r = activities.get(activityNdx); 7070 if (r.activityLabel != null || r.activityIcon != null) { 7071 rti.activityLabel = r.activityLabel; 7072 rti.activityIcon = r.activityIcon; 7073 break; 7074 } 7075 } 7076 7077 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7078 // Check whether this activity is currently available. 7079 try { 7080 if (rti.origActivity != null) { 7081 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7082 == null) { 7083 continue; 7084 } 7085 } else if (rti.baseIntent != null) { 7086 if (pm.queryIntentActivities(rti.baseIntent, 7087 null, 0, userId) == null) { 7088 continue; 7089 } 7090 } 7091 } catch (RemoteException e) { 7092 // Will never happen. 7093 } 7094 } 7095 7096 res.add(rti); 7097 maxNum--; 7098 } 7099 } 7100 return res; 7101 } 7102 } 7103 7104 private TaskRecord recentTaskForIdLocked(int id) { 7105 final int N = mRecentTasks.size(); 7106 for (int i=0; i<N; i++) { 7107 TaskRecord tr = mRecentTasks.get(i); 7108 if (tr.taskId == id) { 7109 return tr; 7110 } 7111 } 7112 return null; 7113 } 7114 7115 @Override 7116 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7117 synchronized (this) { 7118 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7119 "getTaskThumbnails()"); 7120 TaskRecord tr = recentTaskForIdLocked(id); 7121 if (tr != null) { 7122 return tr.getTaskThumbnailsLocked(); 7123 } 7124 } 7125 return null; 7126 } 7127 7128 @Override 7129 public Bitmap getTaskTopThumbnail(int id) { 7130 synchronized (this) { 7131 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7132 "getTaskTopThumbnail()"); 7133 TaskRecord tr = recentTaskForIdLocked(id); 7134 if (tr != null) { 7135 return tr.getTaskTopThumbnailLocked(); 7136 } 7137 } 7138 return null; 7139 } 7140 7141 @Override 7142 public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel, 7143 Bitmap activityIcon) { 7144 synchronized (this) { 7145 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7146 if (r != null) { 7147 r.activityLabel = activityLabel.toString(); 7148 r.activityIcon = activityIcon; 7149 } 7150 } 7151 } 7152 7153 @Override 7154 public boolean removeSubTask(int taskId, int subTaskIndex) { 7155 synchronized (this) { 7156 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7157 "removeSubTask()"); 7158 long ident = Binder.clearCallingIdentity(); 7159 try { 7160 TaskRecord tr = recentTaskForIdLocked(taskId); 7161 if (tr != null) { 7162 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7163 } 7164 return false; 7165 } finally { 7166 Binder.restoreCallingIdentity(ident); 7167 } 7168 } 7169 } 7170 7171 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7172 if (!pr.killedByAm) { 7173 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7174 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7175 pr.processName, pr.setAdj, reason); 7176 pr.killedByAm = true; 7177 Process.killProcessQuiet(pr.pid); 7178 } 7179 } 7180 7181 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7182 tr.disposeThumbnail(); 7183 mRecentTasks.remove(tr); 7184 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7185 Intent baseIntent = new Intent( 7186 tr.intent != null ? tr.intent : tr.affinityIntent); 7187 ComponentName component = baseIntent.getComponent(); 7188 if (component == null) { 7189 Slog.w(TAG, "Now component for base intent of task: " + tr); 7190 return; 7191 } 7192 7193 // Find any running services associated with this app. 7194 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7195 7196 if (killProcesses) { 7197 // Find any running processes associated with this app. 7198 final String pkg = component.getPackageName(); 7199 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7200 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7201 for (int i=0; i<pmap.size(); i++) { 7202 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7203 for (int j=0; j<uids.size(); j++) { 7204 ProcessRecord proc = uids.valueAt(j); 7205 if (proc.userId != tr.userId) { 7206 continue; 7207 } 7208 if (!proc.pkgList.containsKey(pkg)) { 7209 continue; 7210 } 7211 procs.add(proc); 7212 } 7213 } 7214 7215 // Kill the running processes. 7216 for (int i=0; i<procs.size(); i++) { 7217 ProcessRecord pr = procs.get(i); 7218 if (pr == mHomeProcess) { 7219 // Don't kill the home process along with tasks from the same package. 7220 continue; 7221 } 7222 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7223 killUnneededProcessLocked(pr, "remove task"); 7224 } else { 7225 pr.waitingToKill = "remove task"; 7226 } 7227 } 7228 } 7229 } 7230 7231 /** 7232 * Removes the task with the specified task id. 7233 * 7234 * @param taskId Identifier of the task to be removed. 7235 * @param flags Additional operational flags. May be 0 or 7236 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7237 * @return Returns true if the given task was found and removed. 7238 */ 7239 private boolean removeTaskByIdLocked(int taskId, int flags) { 7240 TaskRecord tr = recentTaskForIdLocked(taskId); 7241 if (tr != null) { 7242 tr.removeTaskActivitiesLocked(-1, false); 7243 cleanUpRemovedTaskLocked(tr, flags); 7244 return true; 7245 } 7246 return false; 7247 } 7248 7249 @Override 7250 public boolean removeTask(int taskId, int flags) { 7251 synchronized (this) { 7252 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7253 "removeTask()"); 7254 long ident = Binder.clearCallingIdentity(); 7255 try { 7256 return removeTaskByIdLocked(taskId, flags); 7257 } finally { 7258 Binder.restoreCallingIdentity(ident); 7259 } 7260 } 7261 } 7262 7263 /** 7264 * TODO: Add mController hook 7265 */ 7266 @Override 7267 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7268 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7269 "moveTaskToFront()"); 7270 7271 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7272 synchronized(this) { 7273 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7274 Binder.getCallingUid(), "Task to front")) { 7275 ActivityOptions.abort(options); 7276 return; 7277 } 7278 final long origId = Binder.clearCallingIdentity(); 7279 try { 7280 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7281 if (task == null) { 7282 return; 7283 } 7284 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7285 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7286 return; 7287 } 7288 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7289 } finally { 7290 Binder.restoreCallingIdentity(origId); 7291 } 7292 ActivityOptions.abort(options); 7293 } 7294 } 7295 7296 @Override 7297 public void moveTaskToBack(int taskId) { 7298 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7299 "moveTaskToBack()"); 7300 7301 synchronized(this) { 7302 TaskRecord tr = recentTaskForIdLocked(taskId); 7303 if (tr != null) { 7304 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7305 ActivityStack stack = tr.stack; 7306 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7307 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7308 Binder.getCallingUid(), "Task to back")) { 7309 return; 7310 } 7311 } 7312 final long origId = Binder.clearCallingIdentity(); 7313 try { 7314 stack.moveTaskToBackLocked(taskId, null); 7315 } finally { 7316 Binder.restoreCallingIdentity(origId); 7317 } 7318 } 7319 } 7320 } 7321 7322 /** 7323 * Moves an activity, and all of the other activities within the same task, to the bottom 7324 * of the history stack. The activity's order within the task is unchanged. 7325 * 7326 * @param token A reference to the activity we wish to move 7327 * @param nonRoot If false then this only works if the activity is the root 7328 * of a task; if true it will work for any activity in a task. 7329 * @return Returns true if the move completed, false if not. 7330 */ 7331 @Override 7332 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7333 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7334 synchronized(this) { 7335 final long origId = Binder.clearCallingIdentity(); 7336 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7337 if (taskId >= 0) { 7338 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7339 } 7340 Binder.restoreCallingIdentity(origId); 7341 } 7342 return false; 7343 } 7344 7345 @Override 7346 public void moveTaskBackwards(int task) { 7347 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7348 "moveTaskBackwards()"); 7349 7350 synchronized(this) { 7351 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7352 Binder.getCallingUid(), "Task backwards")) { 7353 return; 7354 } 7355 final long origId = Binder.clearCallingIdentity(); 7356 moveTaskBackwardsLocked(task); 7357 Binder.restoreCallingIdentity(origId); 7358 } 7359 } 7360 7361 private final void moveTaskBackwardsLocked(int task) { 7362 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7363 } 7364 7365 @Override 7366 public IBinder getHomeActivityToken() throws RemoteException { 7367 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7368 "getHomeActivityToken()"); 7369 synchronized (this) { 7370 return mStackSupervisor.getHomeActivityToken(); 7371 } 7372 } 7373 7374 @Override 7375 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7376 IActivityContainerCallback callback) throws RemoteException { 7377 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7378 "createActivityContainer()"); 7379 synchronized (this) { 7380 if (parentActivityToken == null) { 7381 throw new IllegalArgumentException("parent token must not be null"); 7382 } 7383 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7384 if (r == null) { 7385 return null; 7386 } 7387 if (callback == null) { 7388 throw new IllegalArgumentException("callback must not be null"); 7389 } 7390 return mStackSupervisor.createActivityContainer(r, callback); 7391 } 7392 } 7393 7394 @Override 7395 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7396 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7397 "deleteActivityContainer()"); 7398 synchronized (this) { 7399 mStackSupervisor.deleteActivityContainer(container); 7400 } 7401 } 7402 7403 @Override 7404 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7405 throws RemoteException { 7406 synchronized (this) { 7407 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7408 if (stack != null) { 7409 return stack.mActivityContainer; 7410 } 7411 return null; 7412 } 7413 } 7414 7415 @Override 7416 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7417 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7418 "moveTaskToStack()"); 7419 if (stackId == HOME_STACK_ID) { 7420 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7421 new RuntimeException("here").fillInStackTrace()); 7422 } 7423 synchronized (this) { 7424 long ident = Binder.clearCallingIdentity(); 7425 try { 7426 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7427 + stackId + " toTop=" + toTop); 7428 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7429 } finally { 7430 Binder.restoreCallingIdentity(ident); 7431 } 7432 } 7433 } 7434 7435 @Override 7436 public void resizeStack(int stackBoxId, Rect bounds) { 7437 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7438 "resizeStackBox()"); 7439 long ident = Binder.clearCallingIdentity(); 7440 try { 7441 mWindowManager.resizeStack(stackBoxId, bounds); 7442 } finally { 7443 Binder.restoreCallingIdentity(ident); 7444 } 7445 } 7446 7447 @Override 7448 public List<StackInfo> getAllStackInfos() { 7449 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7450 "getAllStackInfos()"); 7451 long ident = Binder.clearCallingIdentity(); 7452 try { 7453 synchronized (this) { 7454 return mStackSupervisor.getAllStackInfosLocked(); 7455 } 7456 } finally { 7457 Binder.restoreCallingIdentity(ident); 7458 } 7459 } 7460 7461 @Override 7462 public StackInfo getStackInfo(int stackId) { 7463 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7464 "getStackInfo()"); 7465 long ident = Binder.clearCallingIdentity(); 7466 try { 7467 synchronized (this) { 7468 return mStackSupervisor.getStackInfoLocked(stackId); 7469 } 7470 } finally { 7471 Binder.restoreCallingIdentity(ident); 7472 } 7473 } 7474 7475 @Override 7476 public boolean isInHomeStack(int taskId) { 7477 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7478 "getStackInfo()"); 7479 long ident = Binder.clearCallingIdentity(); 7480 try { 7481 synchronized (this) { 7482 TaskRecord tr = recentTaskForIdLocked(taskId); 7483 if (tr != null) { 7484 return tr.stack.isHomeStack(); 7485 } 7486 } 7487 } finally { 7488 Binder.restoreCallingIdentity(ident); 7489 } 7490 return false; 7491 } 7492 7493 @Override 7494 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7495 synchronized(this) { 7496 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7497 } 7498 } 7499 7500 private boolean isLockTaskAuthorized(ComponentName name) { 7501// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7502// "startLockTaskMode()"); 7503// DevicePolicyManager dpm = (DevicePolicyManager) 7504// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7505// return dpm != null && dpm.isLockTaskPermitted(name); 7506 return true; 7507 } 7508 7509 private void startLockTaskMode(TaskRecord task) { 7510 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7511 return; 7512 } 7513 long ident = Binder.clearCallingIdentity(); 7514 try { 7515 synchronized (this) { 7516 // Since we lost lock on task, make sure it is still there. 7517 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7518 if (task != null) { 7519 mStackSupervisor.setLockTaskModeLocked(task); 7520 } 7521 } 7522 } finally { 7523 Binder.restoreCallingIdentity(ident); 7524 } 7525 } 7526 7527 @Override 7528 public void startLockTaskMode(int taskId) { 7529 long ident = Binder.clearCallingIdentity(); 7530 try { 7531 final TaskRecord task; 7532 synchronized (this) { 7533 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7534 } 7535 if (task != null) { 7536 startLockTaskMode(task); 7537 } 7538 } finally { 7539 Binder.restoreCallingIdentity(ident); 7540 } 7541 } 7542 7543 @Override 7544 public void startLockTaskMode(IBinder token) { 7545 long ident = Binder.clearCallingIdentity(); 7546 try { 7547 final TaskRecord task; 7548 synchronized (this) { 7549 final ActivityRecord r = ActivityRecord.forToken(token); 7550 if (r == null) { 7551 return; 7552 } 7553 task = r.task; 7554 } 7555 if (task != null) { 7556 startLockTaskMode(task); 7557 } 7558 } finally { 7559 Binder.restoreCallingIdentity(ident); 7560 } 7561 } 7562 7563 @Override 7564 public void stopLockTaskMode() { 7565// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7566// "stopLockTaskMode()"); 7567 synchronized (this) { 7568 mStackSupervisor.setLockTaskModeLocked(null); 7569 } 7570 } 7571 7572 @Override 7573 public boolean isInLockTaskMode() { 7574 synchronized (this) { 7575 return mStackSupervisor.isInLockTaskMode(); 7576 } 7577 } 7578 7579 // ========================================================= 7580 // THUMBNAILS 7581 // ========================================================= 7582 7583 public void reportThumbnail(IBinder token, 7584 Bitmap thumbnail, CharSequence description) { 7585 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7586 final long origId = Binder.clearCallingIdentity(); 7587 sendPendingThumbnail(null, token, thumbnail, description, true); 7588 Binder.restoreCallingIdentity(origId); 7589 } 7590 7591 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7592 Bitmap thumbnail, CharSequence description, boolean always) { 7593 TaskRecord task; 7594 ArrayList<PendingThumbnailsRecord> receivers = null; 7595 7596 //System.out.println("Send pending thumbnail: " + r); 7597 7598 synchronized(this) { 7599 if (r == null) { 7600 r = ActivityRecord.isInStackLocked(token); 7601 if (r == null) { 7602 return; 7603 } 7604 } 7605 if (thumbnail == null && r.thumbHolder != null) { 7606 thumbnail = r.thumbHolder.lastThumbnail; 7607 description = r.thumbHolder.lastDescription; 7608 } 7609 if (thumbnail == null && !always) { 7610 // If there is no thumbnail, and this entry is not actually 7611 // going away, then abort for now and pick up the next 7612 // thumbnail we get. 7613 return; 7614 } 7615 task = r.task; 7616 7617 int N = mPendingThumbnails.size(); 7618 int i=0; 7619 while (i<N) { 7620 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7621 //System.out.println("Looking in " + pr.pendingRecords); 7622 if (pr.pendingRecords.remove(r)) { 7623 if (receivers == null) { 7624 receivers = new ArrayList<PendingThumbnailsRecord>(); 7625 } 7626 receivers.add(pr); 7627 if (pr.pendingRecords.size() == 0) { 7628 pr.finished = true; 7629 mPendingThumbnails.remove(i); 7630 N--; 7631 continue; 7632 } 7633 } 7634 i++; 7635 } 7636 } 7637 7638 if (receivers != null) { 7639 final int N = receivers.size(); 7640 for (int i=0; i<N; i++) { 7641 try { 7642 PendingThumbnailsRecord pr = receivers.get(i); 7643 pr.receiver.newThumbnail( 7644 task != null ? task.taskId : -1, thumbnail, description); 7645 if (pr.finished) { 7646 pr.receiver.finished(); 7647 } 7648 } catch (Exception e) { 7649 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7650 } 7651 } 7652 } 7653 } 7654 7655 // ========================================================= 7656 // CONTENT PROVIDERS 7657 // ========================================================= 7658 7659 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7660 List<ProviderInfo> providers = null; 7661 try { 7662 providers = AppGlobals.getPackageManager(). 7663 queryContentProviders(app.processName, app.uid, 7664 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7665 } catch (RemoteException ex) { 7666 } 7667 if (DEBUG_MU) 7668 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7669 int userId = app.userId; 7670 if (providers != null) { 7671 int N = providers.size(); 7672 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7673 for (int i=0; i<N; i++) { 7674 ProviderInfo cpi = 7675 (ProviderInfo)providers.get(i); 7676 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7677 cpi.name, cpi.flags); 7678 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7679 // This is a singleton provider, but a user besides the 7680 // default user is asking to initialize a process it runs 7681 // in... well, no, it doesn't actually run in this process, 7682 // it runs in the process of the default user. Get rid of it. 7683 providers.remove(i); 7684 N--; 7685 i--; 7686 continue; 7687 } 7688 7689 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7690 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7691 if (cpr == null) { 7692 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7693 mProviderMap.putProviderByClass(comp, cpr); 7694 } 7695 if (DEBUG_MU) 7696 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7697 app.pubProviders.put(cpi.name, cpr); 7698 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7699 // Don't add this if it is a platform component that is marked 7700 // to run in multiple processes, because this is actually 7701 // part of the framework so doesn't make sense to track as a 7702 // separate apk in the process. 7703 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7704 } 7705 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7706 } 7707 } 7708 return providers; 7709 } 7710 7711 /** 7712 * Check if {@link ProcessRecord} has a possible chance at accessing the 7713 * given {@link ProviderInfo}. Final permission checking is always done 7714 * in {@link ContentProvider}. 7715 */ 7716 private final String checkContentProviderPermissionLocked( 7717 ProviderInfo cpi, ProcessRecord r) { 7718 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7719 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7720 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7721 cpi.applicationInfo.uid, cpi.exported) 7722 == PackageManager.PERMISSION_GRANTED) { 7723 return null; 7724 } 7725 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7726 cpi.applicationInfo.uid, cpi.exported) 7727 == PackageManager.PERMISSION_GRANTED) { 7728 return null; 7729 } 7730 7731 PathPermission[] pps = cpi.pathPermissions; 7732 if (pps != null) { 7733 int i = pps.length; 7734 while (i > 0) { 7735 i--; 7736 PathPermission pp = pps[i]; 7737 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7738 cpi.applicationInfo.uid, cpi.exported) 7739 == PackageManager.PERMISSION_GRANTED) { 7740 return null; 7741 } 7742 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7743 cpi.applicationInfo.uid, cpi.exported) 7744 == PackageManager.PERMISSION_GRANTED) { 7745 return null; 7746 } 7747 } 7748 } 7749 7750 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7751 if (perms != null) { 7752 for (GrantUri uri : perms.keySet()) { 7753 if (uri.uri.getAuthority().equals(cpi.authority)) { 7754 return null; 7755 } 7756 } 7757 } 7758 7759 String msg; 7760 if (!cpi.exported) { 7761 msg = "Permission Denial: opening provider " + cpi.name 7762 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7763 + ", uid=" + callingUid + ") that is not exported from uid " 7764 + cpi.applicationInfo.uid; 7765 } else { 7766 msg = "Permission Denial: opening provider " + cpi.name 7767 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7768 + ", uid=" + callingUid + ") requires " 7769 + cpi.readPermission + " or " + cpi.writePermission; 7770 } 7771 Slog.w(TAG, msg); 7772 return msg; 7773 } 7774 7775 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7776 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7777 if (r != null) { 7778 for (int i=0; i<r.conProviders.size(); i++) { 7779 ContentProviderConnection conn = r.conProviders.get(i); 7780 if (conn.provider == cpr) { 7781 if (DEBUG_PROVIDER) Slog.v(TAG, 7782 "Adding provider requested by " 7783 + r.processName + " from process " 7784 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7785 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7786 if (stable) { 7787 conn.stableCount++; 7788 conn.numStableIncs++; 7789 } else { 7790 conn.unstableCount++; 7791 conn.numUnstableIncs++; 7792 } 7793 return conn; 7794 } 7795 } 7796 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7797 if (stable) { 7798 conn.stableCount = 1; 7799 conn.numStableIncs = 1; 7800 } else { 7801 conn.unstableCount = 1; 7802 conn.numUnstableIncs = 1; 7803 } 7804 cpr.connections.add(conn); 7805 r.conProviders.add(conn); 7806 return conn; 7807 } 7808 cpr.addExternalProcessHandleLocked(externalProcessToken); 7809 return null; 7810 } 7811 7812 boolean decProviderCountLocked(ContentProviderConnection conn, 7813 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7814 if (conn != null) { 7815 cpr = conn.provider; 7816 if (DEBUG_PROVIDER) Slog.v(TAG, 7817 "Removing provider requested by " 7818 + conn.client.processName + " from process " 7819 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7820 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7821 if (stable) { 7822 conn.stableCount--; 7823 } else { 7824 conn.unstableCount--; 7825 } 7826 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7827 cpr.connections.remove(conn); 7828 conn.client.conProviders.remove(conn); 7829 return true; 7830 } 7831 return false; 7832 } 7833 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7834 return false; 7835 } 7836 7837 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7838 String name, IBinder token, boolean stable, int userId) { 7839 ContentProviderRecord cpr; 7840 ContentProviderConnection conn = null; 7841 ProviderInfo cpi = null; 7842 7843 synchronized(this) { 7844 ProcessRecord r = null; 7845 if (caller != null) { 7846 r = getRecordForAppLocked(caller); 7847 if (r == null) { 7848 throw new SecurityException( 7849 "Unable to find app for caller " + caller 7850 + " (pid=" + Binder.getCallingPid() 7851 + ") when getting content provider " + name); 7852 } 7853 } 7854 7855 // First check if this content provider has been published... 7856 cpr = mProviderMap.getProviderByName(name, userId); 7857 boolean providerRunning = cpr != null; 7858 if (providerRunning) { 7859 cpi = cpr.info; 7860 String msg; 7861 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7862 throw new SecurityException(msg); 7863 } 7864 7865 if (r != null && cpr.canRunHere(r)) { 7866 // This provider has been published or is in the process 7867 // of being published... but it is also allowed to run 7868 // in the caller's process, so don't make a connection 7869 // and just let the caller instantiate its own instance. 7870 ContentProviderHolder holder = cpr.newHolder(null); 7871 // don't give caller the provider object, it needs 7872 // to make its own. 7873 holder.provider = null; 7874 return holder; 7875 } 7876 7877 final long origId = Binder.clearCallingIdentity(); 7878 7879 // In this case the provider instance already exists, so we can 7880 // return it right away. 7881 conn = incProviderCountLocked(r, cpr, token, stable); 7882 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7883 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7884 // If this is a perceptible app accessing the provider, 7885 // make sure to count it as being accessed and thus 7886 // back up on the LRU list. This is good because 7887 // content providers are often expensive to start. 7888 updateLruProcessLocked(cpr.proc, false, null); 7889 } 7890 } 7891 7892 if (cpr.proc != null) { 7893 if (false) { 7894 if (cpr.name.flattenToShortString().equals( 7895 "com.android.providers.calendar/.CalendarProvider2")) { 7896 Slog.v(TAG, "****************** KILLING " 7897 + cpr.name.flattenToShortString()); 7898 Process.killProcess(cpr.proc.pid); 7899 } 7900 } 7901 boolean success = updateOomAdjLocked(cpr.proc); 7902 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7903 // NOTE: there is still a race here where a signal could be 7904 // pending on the process even though we managed to update its 7905 // adj level. Not sure what to do about this, but at least 7906 // the race is now smaller. 7907 if (!success) { 7908 // Uh oh... it looks like the provider's process 7909 // has been killed on us. We need to wait for a new 7910 // process to be started, and make sure its death 7911 // doesn't kill our process. 7912 Slog.i(TAG, 7913 "Existing provider " + cpr.name.flattenToShortString() 7914 + " is crashing; detaching " + r); 7915 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7916 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7917 if (!lastRef) { 7918 // This wasn't the last ref our process had on 7919 // the provider... we have now been killed, bail. 7920 return null; 7921 } 7922 providerRunning = false; 7923 conn = null; 7924 } 7925 } 7926 7927 Binder.restoreCallingIdentity(origId); 7928 } 7929 7930 boolean singleton; 7931 if (!providerRunning) { 7932 try { 7933 cpi = AppGlobals.getPackageManager(). 7934 resolveContentProvider(name, 7935 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7936 } catch (RemoteException ex) { 7937 } 7938 if (cpi == null) { 7939 return null; 7940 } 7941 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7942 cpi.name, cpi.flags); 7943 if (singleton) { 7944 userId = 0; 7945 } 7946 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7947 7948 String msg; 7949 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7950 throw new SecurityException(msg); 7951 } 7952 7953 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7954 && !cpi.processName.equals("system")) { 7955 // If this content provider does not run in the system 7956 // process, and the system is not yet ready to run other 7957 // processes, then fail fast instead of hanging. 7958 throw new IllegalArgumentException( 7959 "Attempt to launch content provider before system ready"); 7960 } 7961 7962 // Make sure that the user who owns this provider is started. If not, 7963 // we don't want to allow it to run. 7964 if (mStartedUsers.get(userId) == null) { 7965 Slog.w(TAG, "Unable to launch app " 7966 + cpi.applicationInfo.packageName + "/" 7967 + cpi.applicationInfo.uid + " for provider " 7968 + name + ": user " + userId + " is stopped"); 7969 return null; 7970 } 7971 7972 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7973 cpr = mProviderMap.getProviderByClass(comp, userId); 7974 final boolean firstClass = cpr == null; 7975 if (firstClass) { 7976 try { 7977 ApplicationInfo ai = 7978 AppGlobals.getPackageManager(). 7979 getApplicationInfo( 7980 cpi.applicationInfo.packageName, 7981 STOCK_PM_FLAGS, userId); 7982 if (ai == null) { 7983 Slog.w(TAG, "No package info for content provider " 7984 + cpi.name); 7985 return null; 7986 } 7987 ai = getAppInfoForUser(ai, userId); 7988 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7989 } catch (RemoteException ex) { 7990 // pm is in same process, this will never happen. 7991 } 7992 } 7993 7994 if (r != null && cpr.canRunHere(r)) { 7995 // If this is a multiprocess provider, then just return its 7996 // info and allow the caller to instantiate it. Only do 7997 // this if the provider is the same user as the caller's 7998 // process, or can run as root (so can be in any process). 7999 return cpr.newHolder(null); 8000 } 8001 8002 if (DEBUG_PROVIDER) { 8003 RuntimeException e = new RuntimeException("here"); 8004 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8005 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8006 } 8007 8008 // This is single process, and our app is now connecting to it. 8009 // See if we are already in the process of launching this 8010 // provider. 8011 final int N = mLaunchingProviders.size(); 8012 int i; 8013 for (i=0; i<N; i++) { 8014 if (mLaunchingProviders.get(i) == cpr) { 8015 break; 8016 } 8017 } 8018 8019 // If the provider is not already being launched, then get it 8020 // started. 8021 if (i >= N) { 8022 final long origId = Binder.clearCallingIdentity(); 8023 8024 try { 8025 // Content provider is now in use, its package can't be stopped. 8026 try { 8027 AppGlobals.getPackageManager().setPackageStoppedState( 8028 cpr.appInfo.packageName, false, userId); 8029 } catch (RemoteException e) { 8030 } catch (IllegalArgumentException e) { 8031 Slog.w(TAG, "Failed trying to unstop package " 8032 + cpr.appInfo.packageName + ": " + e); 8033 } 8034 8035 // Use existing process if already started 8036 ProcessRecord proc = getProcessRecordLocked( 8037 cpi.processName, cpr.appInfo.uid, false); 8038 if (proc != null && proc.thread != null) { 8039 if (DEBUG_PROVIDER) { 8040 Slog.d(TAG, "Installing in existing process " + proc); 8041 } 8042 proc.pubProviders.put(cpi.name, cpr); 8043 try { 8044 proc.thread.scheduleInstallProvider(cpi); 8045 } catch (RemoteException e) { 8046 } 8047 } else { 8048 proc = startProcessLocked(cpi.processName, 8049 cpr.appInfo, false, 0, "content provider", 8050 new ComponentName(cpi.applicationInfo.packageName, 8051 cpi.name), false, false, false); 8052 if (proc == null) { 8053 Slog.w(TAG, "Unable to launch app " 8054 + cpi.applicationInfo.packageName + "/" 8055 + cpi.applicationInfo.uid + " for provider " 8056 + name + ": process is bad"); 8057 return null; 8058 } 8059 } 8060 cpr.launchingApp = proc; 8061 mLaunchingProviders.add(cpr); 8062 } finally { 8063 Binder.restoreCallingIdentity(origId); 8064 } 8065 } 8066 8067 // Make sure the provider is published (the same provider class 8068 // may be published under multiple names). 8069 if (firstClass) { 8070 mProviderMap.putProviderByClass(comp, cpr); 8071 } 8072 8073 mProviderMap.putProviderByName(name, cpr); 8074 conn = incProviderCountLocked(r, cpr, token, stable); 8075 if (conn != null) { 8076 conn.waiting = true; 8077 } 8078 } 8079 } 8080 8081 // Wait for the provider to be published... 8082 synchronized (cpr) { 8083 while (cpr.provider == null) { 8084 if (cpr.launchingApp == null) { 8085 Slog.w(TAG, "Unable to launch app " 8086 + cpi.applicationInfo.packageName + "/" 8087 + cpi.applicationInfo.uid + " for provider " 8088 + name + ": launching app became null"); 8089 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8090 UserHandle.getUserId(cpi.applicationInfo.uid), 8091 cpi.applicationInfo.packageName, 8092 cpi.applicationInfo.uid, name); 8093 return null; 8094 } 8095 try { 8096 if (DEBUG_MU) { 8097 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8098 + cpr.launchingApp); 8099 } 8100 if (conn != null) { 8101 conn.waiting = true; 8102 } 8103 cpr.wait(); 8104 } catch (InterruptedException ex) { 8105 } finally { 8106 if (conn != null) { 8107 conn.waiting = false; 8108 } 8109 } 8110 } 8111 } 8112 return cpr != null ? cpr.newHolder(conn) : null; 8113 } 8114 8115 public final ContentProviderHolder getContentProvider( 8116 IApplicationThread caller, String name, int userId, boolean stable) { 8117 enforceNotIsolatedCaller("getContentProvider"); 8118 if (caller == null) { 8119 String msg = "null IApplicationThread when getting content provider " 8120 + name; 8121 Slog.w(TAG, msg); 8122 throw new SecurityException(msg); 8123 } 8124 8125 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8126 false, true, "getContentProvider", null); 8127 return getContentProviderImpl(caller, name, null, stable, userId); 8128 } 8129 8130 public ContentProviderHolder getContentProviderExternal( 8131 String name, int userId, IBinder token) { 8132 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8133 "Do not have permission in call getContentProviderExternal()"); 8134 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8135 false, true, "getContentProvider", null); 8136 return getContentProviderExternalUnchecked(name, token, userId); 8137 } 8138 8139 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8140 IBinder token, int userId) { 8141 return getContentProviderImpl(null, name, token, true, userId); 8142 } 8143 8144 /** 8145 * Drop a content provider from a ProcessRecord's bookkeeping 8146 */ 8147 public void removeContentProvider(IBinder connection, boolean stable) { 8148 enforceNotIsolatedCaller("removeContentProvider"); 8149 long ident = Binder.clearCallingIdentity(); 8150 try { 8151 synchronized (this) { 8152 ContentProviderConnection conn; 8153 try { 8154 conn = (ContentProviderConnection)connection; 8155 } catch (ClassCastException e) { 8156 String msg ="removeContentProvider: " + connection 8157 + " not a ContentProviderConnection"; 8158 Slog.w(TAG, msg); 8159 throw new IllegalArgumentException(msg); 8160 } 8161 if (conn == null) { 8162 throw new NullPointerException("connection is null"); 8163 } 8164 if (decProviderCountLocked(conn, null, null, stable)) { 8165 updateOomAdjLocked(); 8166 } 8167 } 8168 } finally { 8169 Binder.restoreCallingIdentity(ident); 8170 } 8171 } 8172 8173 public void removeContentProviderExternal(String name, IBinder token) { 8174 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8175 "Do not have permission in call removeContentProviderExternal()"); 8176 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8177 } 8178 8179 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8180 synchronized (this) { 8181 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8182 if(cpr == null) { 8183 //remove from mProvidersByClass 8184 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8185 return; 8186 } 8187 8188 //update content provider record entry info 8189 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8190 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8191 if (localCpr.hasExternalProcessHandles()) { 8192 if (localCpr.removeExternalProcessHandleLocked(token)) { 8193 updateOomAdjLocked(); 8194 } else { 8195 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8196 + " with no external reference for token: " 8197 + token + "."); 8198 } 8199 } else { 8200 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8201 + " with no external references."); 8202 } 8203 } 8204 } 8205 8206 public final void publishContentProviders(IApplicationThread caller, 8207 List<ContentProviderHolder> providers) { 8208 if (providers == null) { 8209 return; 8210 } 8211 8212 enforceNotIsolatedCaller("publishContentProviders"); 8213 synchronized (this) { 8214 final ProcessRecord r = getRecordForAppLocked(caller); 8215 if (DEBUG_MU) 8216 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8217 if (r == null) { 8218 throw new SecurityException( 8219 "Unable to find app for caller " + caller 8220 + " (pid=" + Binder.getCallingPid() 8221 + ") when publishing content providers"); 8222 } 8223 8224 final long origId = Binder.clearCallingIdentity(); 8225 8226 final int N = providers.size(); 8227 for (int i=0; i<N; i++) { 8228 ContentProviderHolder src = providers.get(i); 8229 if (src == null || src.info == null || src.provider == null) { 8230 continue; 8231 } 8232 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8233 if (DEBUG_MU) 8234 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8235 if (dst != null) { 8236 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8237 mProviderMap.putProviderByClass(comp, dst); 8238 String names[] = dst.info.authority.split(";"); 8239 for (int j = 0; j < names.length; j++) { 8240 mProviderMap.putProviderByName(names[j], dst); 8241 } 8242 8243 int NL = mLaunchingProviders.size(); 8244 int j; 8245 for (j=0; j<NL; j++) { 8246 if (mLaunchingProviders.get(j) == dst) { 8247 mLaunchingProviders.remove(j); 8248 j--; 8249 NL--; 8250 } 8251 } 8252 synchronized (dst) { 8253 dst.provider = src.provider; 8254 dst.proc = r; 8255 dst.notifyAll(); 8256 } 8257 updateOomAdjLocked(r); 8258 } 8259 } 8260 8261 Binder.restoreCallingIdentity(origId); 8262 } 8263 } 8264 8265 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8266 ContentProviderConnection conn; 8267 try { 8268 conn = (ContentProviderConnection)connection; 8269 } catch (ClassCastException e) { 8270 String msg ="refContentProvider: " + connection 8271 + " not a ContentProviderConnection"; 8272 Slog.w(TAG, msg); 8273 throw new IllegalArgumentException(msg); 8274 } 8275 if (conn == null) { 8276 throw new NullPointerException("connection is null"); 8277 } 8278 8279 synchronized (this) { 8280 if (stable > 0) { 8281 conn.numStableIncs += stable; 8282 } 8283 stable = conn.stableCount + stable; 8284 if (stable < 0) { 8285 throw new IllegalStateException("stableCount < 0: " + stable); 8286 } 8287 8288 if (unstable > 0) { 8289 conn.numUnstableIncs += unstable; 8290 } 8291 unstable = conn.unstableCount + unstable; 8292 if (unstable < 0) { 8293 throw new IllegalStateException("unstableCount < 0: " + unstable); 8294 } 8295 8296 if ((stable+unstable) <= 0) { 8297 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8298 + stable + " unstable=" + unstable); 8299 } 8300 conn.stableCount = stable; 8301 conn.unstableCount = unstable; 8302 return !conn.dead; 8303 } 8304 } 8305 8306 public void unstableProviderDied(IBinder connection) { 8307 ContentProviderConnection conn; 8308 try { 8309 conn = (ContentProviderConnection)connection; 8310 } catch (ClassCastException e) { 8311 String msg ="refContentProvider: " + connection 8312 + " not a ContentProviderConnection"; 8313 Slog.w(TAG, msg); 8314 throw new IllegalArgumentException(msg); 8315 } 8316 if (conn == null) { 8317 throw new NullPointerException("connection is null"); 8318 } 8319 8320 // Safely retrieve the content provider associated with the connection. 8321 IContentProvider provider; 8322 synchronized (this) { 8323 provider = conn.provider.provider; 8324 } 8325 8326 if (provider == null) { 8327 // Um, yeah, we're way ahead of you. 8328 return; 8329 } 8330 8331 // Make sure the caller is being honest with us. 8332 if (provider.asBinder().pingBinder()) { 8333 // Er, no, still looks good to us. 8334 synchronized (this) { 8335 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8336 + " says " + conn + " died, but we don't agree"); 8337 return; 8338 } 8339 } 8340 8341 // Well look at that! It's dead! 8342 synchronized (this) { 8343 if (conn.provider.provider != provider) { 8344 // But something changed... good enough. 8345 return; 8346 } 8347 8348 ProcessRecord proc = conn.provider.proc; 8349 if (proc == null || proc.thread == null) { 8350 // Seems like the process is already cleaned up. 8351 return; 8352 } 8353 8354 // As far as we're concerned, this is just like receiving a 8355 // death notification... just a bit prematurely. 8356 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8357 + ") early provider death"); 8358 final long ident = Binder.clearCallingIdentity(); 8359 try { 8360 appDiedLocked(proc, proc.pid, proc.thread); 8361 } finally { 8362 Binder.restoreCallingIdentity(ident); 8363 } 8364 } 8365 } 8366 8367 @Override 8368 public void appNotRespondingViaProvider(IBinder connection) { 8369 enforceCallingPermission( 8370 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8371 8372 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8373 if (conn == null) { 8374 Slog.w(TAG, "ContentProviderConnection is null"); 8375 return; 8376 } 8377 8378 final ProcessRecord host = conn.provider.proc; 8379 if (host == null) { 8380 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8381 return; 8382 } 8383 8384 final long token = Binder.clearCallingIdentity(); 8385 try { 8386 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8387 } finally { 8388 Binder.restoreCallingIdentity(token); 8389 } 8390 } 8391 8392 public final void installSystemProviders() { 8393 List<ProviderInfo> providers; 8394 synchronized (this) { 8395 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8396 providers = generateApplicationProvidersLocked(app); 8397 if (providers != null) { 8398 for (int i=providers.size()-1; i>=0; i--) { 8399 ProviderInfo pi = (ProviderInfo)providers.get(i); 8400 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8401 Slog.w(TAG, "Not installing system proc provider " + pi.name 8402 + ": not system .apk"); 8403 providers.remove(i); 8404 } 8405 } 8406 } 8407 } 8408 if (providers != null) { 8409 mSystemThread.installSystemProviders(providers); 8410 } 8411 8412 mCoreSettingsObserver = new CoreSettingsObserver(this); 8413 8414 mUsageStatsService.monitorPackages(); 8415 } 8416 8417 /** 8418 * Allows app to retrieve the MIME type of a URI without having permission 8419 * to access its content provider. 8420 * 8421 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8422 * 8423 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8424 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8425 */ 8426 public String getProviderMimeType(Uri uri, int userId) { 8427 enforceNotIsolatedCaller("getProviderMimeType"); 8428 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8429 userId, false, true, "getProviderMimeType", null); 8430 final String name = uri.getAuthority(); 8431 final long ident = Binder.clearCallingIdentity(); 8432 ContentProviderHolder holder = null; 8433 8434 try { 8435 holder = getContentProviderExternalUnchecked(name, null, userId); 8436 if (holder != null) { 8437 return holder.provider.getType(uri); 8438 } 8439 } catch (RemoteException e) { 8440 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8441 return null; 8442 } finally { 8443 if (holder != null) { 8444 removeContentProviderExternalUnchecked(name, null, userId); 8445 } 8446 Binder.restoreCallingIdentity(ident); 8447 } 8448 8449 return null; 8450 } 8451 8452 // ========================================================= 8453 // GLOBAL MANAGEMENT 8454 // ========================================================= 8455 8456 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8457 boolean isolated) { 8458 String proc = customProcess != null ? customProcess : info.processName; 8459 BatteryStatsImpl.Uid.Proc ps = null; 8460 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8461 int uid = info.uid; 8462 if (isolated) { 8463 int userId = UserHandle.getUserId(uid); 8464 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8465 while (true) { 8466 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8467 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8468 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8469 } 8470 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8471 mNextIsolatedProcessUid++; 8472 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8473 // No process for this uid, use it. 8474 break; 8475 } 8476 stepsLeft--; 8477 if (stepsLeft <= 0) { 8478 return null; 8479 } 8480 } 8481 } 8482 return new ProcessRecord(stats, info, proc, uid); 8483 } 8484 8485 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8486 ProcessRecord app; 8487 if (!isolated) { 8488 app = getProcessRecordLocked(info.processName, info.uid, true); 8489 } else { 8490 app = null; 8491 } 8492 8493 if (app == null) { 8494 app = newProcessRecordLocked(info, null, isolated); 8495 mProcessNames.put(info.processName, app.uid, app); 8496 if (isolated) { 8497 mIsolatedProcesses.put(app.uid, app); 8498 } 8499 updateLruProcessLocked(app, false, null); 8500 updateOomAdjLocked(); 8501 } 8502 8503 // This package really, really can not be stopped. 8504 try { 8505 AppGlobals.getPackageManager().setPackageStoppedState( 8506 info.packageName, false, UserHandle.getUserId(app.uid)); 8507 } catch (RemoteException e) { 8508 } catch (IllegalArgumentException e) { 8509 Slog.w(TAG, "Failed trying to unstop package " 8510 + info.packageName + ": " + e); 8511 } 8512 8513 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8514 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8515 app.persistent = true; 8516 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8517 } 8518 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8519 mPersistentStartingProcesses.add(app); 8520 startProcessLocked(app, "added application", app.processName); 8521 } 8522 8523 return app; 8524 } 8525 8526 public void unhandledBack() { 8527 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8528 "unhandledBack()"); 8529 8530 synchronized(this) { 8531 final long origId = Binder.clearCallingIdentity(); 8532 try { 8533 getFocusedStack().unhandledBackLocked(); 8534 } finally { 8535 Binder.restoreCallingIdentity(origId); 8536 } 8537 } 8538 } 8539 8540 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8541 enforceNotIsolatedCaller("openContentUri"); 8542 final int userId = UserHandle.getCallingUserId(); 8543 String name = uri.getAuthority(); 8544 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8545 ParcelFileDescriptor pfd = null; 8546 if (cph != null) { 8547 // We record the binder invoker's uid in thread-local storage before 8548 // going to the content provider to open the file. Later, in the code 8549 // that handles all permissions checks, we look for this uid and use 8550 // that rather than the Activity Manager's own uid. The effect is that 8551 // we do the check against the caller's permissions even though it looks 8552 // to the content provider like the Activity Manager itself is making 8553 // the request. 8554 sCallerIdentity.set(new Identity( 8555 Binder.getCallingPid(), Binder.getCallingUid())); 8556 try { 8557 pfd = cph.provider.openFile(null, uri, "r", null); 8558 } catch (FileNotFoundException e) { 8559 // do nothing; pfd will be returned null 8560 } finally { 8561 // Ensure that whatever happens, we clean up the identity state 8562 sCallerIdentity.remove(); 8563 } 8564 8565 // We've got the fd now, so we're done with the provider. 8566 removeContentProviderExternalUnchecked(name, null, userId); 8567 } else { 8568 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8569 } 8570 return pfd; 8571 } 8572 8573 // Actually is sleeping or shutting down or whatever else in the future 8574 // is an inactive state. 8575 public boolean isSleepingOrShuttingDown() { 8576 return mSleeping || mShuttingDown; 8577 } 8578 8579 public boolean isSleeping() { 8580 return mSleeping; 8581 } 8582 8583 void goingToSleep() { 8584 synchronized(this) { 8585 mWentToSleep = true; 8586 updateEventDispatchingLocked(); 8587 goToSleepIfNeededLocked(); 8588 } 8589 } 8590 8591 void finishRunningVoiceLocked() { 8592 if (mRunningVoice) { 8593 mRunningVoice = false; 8594 goToSleepIfNeededLocked(); 8595 } 8596 } 8597 8598 void goToSleepIfNeededLocked() { 8599 if (mWentToSleep && !mRunningVoice) { 8600 if (!mSleeping) { 8601 mSleeping = true; 8602 mStackSupervisor.goingToSleepLocked(); 8603 8604 // Initialize the wake times of all processes. 8605 checkExcessivePowerUsageLocked(false); 8606 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8607 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8608 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8609 } 8610 } 8611 } 8612 8613 @Override 8614 public boolean shutdown(int timeout) { 8615 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8616 != PackageManager.PERMISSION_GRANTED) { 8617 throw new SecurityException("Requires permission " 8618 + android.Manifest.permission.SHUTDOWN); 8619 } 8620 8621 boolean timedout = false; 8622 8623 synchronized(this) { 8624 mShuttingDown = true; 8625 updateEventDispatchingLocked(); 8626 timedout = mStackSupervisor.shutdownLocked(timeout); 8627 } 8628 8629 mAppOpsService.shutdown(); 8630 mUsageStatsService.shutdown(); 8631 mBatteryStatsService.shutdown(); 8632 synchronized (this) { 8633 mProcessStats.shutdownLocked(); 8634 } 8635 8636 return timedout; 8637 } 8638 8639 public final void activitySlept(IBinder token) { 8640 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8641 8642 final long origId = Binder.clearCallingIdentity(); 8643 8644 synchronized (this) { 8645 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8646 if (r != null) { 8647 mStackSupervisor.activitySleptLocked(r); 8648 } 8649 } 8650 8651 Binder.restoreCallingIdentity(origId); 8652 } 8653 8654 void logLockScreen(String msg) { 8655 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8656 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8657 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8658 mStackSupervisor.mDismissKeyguardOnNextActivity); 8659 } 8660 8661 private void comeOutOfSleepIfNeededLocked() { 8662 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8663 if (mSleeping) { 8664 mSleeping = false; 8665 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8666 } 8667 } 8668 } 8669 8670 void wakingUp() { 8671 synchronized(this) { 8672 mWentToSleep = false; 8673 updateEventDispatchingLocked(); 8674 comeOutOfSleepIfNeededLocked(); 8675 } 8676 } 8677 8678 void startRunningVoiceLocked() { 8679 if (!mRunningVoice) { 8680 mRunningVoice = true; 8681 comeOutOfSleepIfNeededLocked(); 8682 } 8683 } 8684 8685 private void updateEventDispatchingLocked() { 8686 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8687 } 8688 8689 public void setLockScreenShown(boolean shown) { 8690 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8691 != PackageManager.PERMISSION_GRANTED) { 8692 throw new SecurityException("Requires permission " 8693 + android.Manifest.permission.DEVICE_POWER); 8694 } 8695 8696 synchronized(this) { 8697 long ident = Binder.clearCallingIdentity(); 8698 try { 8699 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8700 mLockScreenShown = shown; 8701 comeOutOfSleepIfNeededLocked(); 8702 } finally { 8703 Binder.restoreCallingIdentity(ident); 8704 } 8705 } 8706 } 8707 8708 public void stopAppSwitches() { 8709 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8710 != PackageManager.PERMISSION_GRANTED) { 8711 throw new SecurityException("Requires permission " 8712 + android.Manifest.permission.STOP_APP_SWITCHES); 8713 } 8714 8715 synchronized(this) { 8716 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8717 + APP_SWITCH_DELAY_TIME; 8718 mDidAppSwitch = false; 8719 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8720 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8721 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8722 } 8723 } 8724 8725 public void resumeAppSwitches() { 8726 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8727 != PackageManager.PERMISSION_GRANTED) { 8728 throw new SecurityException("Requires permission " 8729 + android.Manifest.permission.STOP_APP_SWITCHES); 8730 } 8731 8732 synchronized(this) { 8733 // Note that we don't execute any pending app switches... we will 8734 // let those wait until either the timeout, or the next start 8735 // activity request. 8736 mAppSwitchesAllowedTime = 0; 8737 } 8738 } 8739 8740 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8741 String name) { 8742 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8743 return true; 8744 } 8745 8746 final int perm = checkComponentPermission( 8747 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8748 callingUid, -1, true); 8749 if (perm == PackageManager.PERMISSION_GRANTED) { 8750 return true; 8751 } 8752 8753 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8754 return false; 8755 } 8756 8757 public void setDebugApp(String packageName, boolean waitForDebugger, 8758 boolean persistent) { 8759 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8760 "setDebugApp()"); 8761 8762 long ident = Binder.clearCallingIdentity(); 8763 try { 8764 // Note that this is not really thread safe if there are multiple 8765 // callers into it at the same time, but that's not a situation we 8766 // care about. 8767 if (persistent) { 8768 final ContentResolver resolver = mContext.getContentResolver(); 8769 Settings.Global.putString( 8770 resolver, Settings.Global.DEBUG_APP, 8771 packageName); 8772 Settings.Global.putInt( 8773 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8774 waitForDebugger ? 1 : 0); 8775 } 8776 8777 synchronized (this) { 8778 if (!persistent) { 8779 mOrigDebugApp = mDebugApp; 8780 mOrigWaitForDebugger = mWaitForDebugger; 8781 } 8782 mDebugApp = packageName; 8783 mWaitForDebugger = waitForDebugger; 8784 mDebugTransient = !persistent; 8785 if (packageName != null) { 8786 forceStopPackageLocked(packageName, -1, false, false, true, true, 8787 false, UserHandle.USER_ALL, "set debug app"); 8788 } 8789 } 8790 } finally { 8791 Binder.restoreCallingIdentity(ident); 8792 } 8793 } 8794 8795 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8796 synchronized (this) { 8797 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8798 if (!isDebuggable) { 8799 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8800 throw new SecurityException("Process not debuggable: " + app.packageName); 8801 } 8802 } 8803 8804 mOpenGlTraceApp = processName; 8805 } 8806 } 8807 8808 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8809 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8810 synchronized (this) { 8811 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8812 if (!isDebuggable) { 8813 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8814 throw new SecurityException("Process not debuggable: " + app.packageName); 8815 } 8816 } 8817 mProfileApp = processName; 8818 mProfileFile = profileFile; 8819 if (mProfileFd != null) { 8820 try { 8821 mProfileFd.close(); 8822 } catch (IOException e) { 8823 } 8824 mProfileFd = null; 8825 } 8826 mProfileFd = profileFd; 8827 mProfileType = 0; 8828 mAutoStopProfiler = autoStopProfiler; 8829 } 8830 } 8831 8832 @Override 8833 public void setAlwaysFinish(boolean enabled) { 8834 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8835 "setAlwaysFinish()"); 8836 8837 Settings.Global.putInt( 8838 mContext.getContentResolver(), 8839 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8840 8841 synchronized (this) { 8842 mAlwaysFinishActivities = enabled; 8843 } 8844 } 8845 8846 @Override 8847 public void setActivityController(IActivityController controller) { 8848 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8849 "setActivityController()"); 8850 synchronized (this) { 8851 mController = controller; 8852 Watchdog.getInstance().setActivityController(controller); 8853 } 8854 } 8855 8856 @Override 8857 public void setUserIsMonkey(boolean userIsMonkey) { 8858 synchronized (this) { 8859 synchronized (mPidsSelfLocked) { 8860 final int callingPid = Binder.getCallingPid(); 8861 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8862 if (precessRecord == null) { 8863 throw new SecurityException("Unknown process: " + callingPid); 8864 } 8865 if (precessRecord.instrumentationUiAutomationConnection == null) { 8866 throw new SecurityException("Only an instrumentation process " 8867 + "with a UiAutomation can call setUserIsMonkey"); 8868 } 8869 } 8870 mUserIsMonkey = userIsMonkey; 8871 } 8872 } 8873 8874 @Override 8875 public boolean isUserAMonkey() { 8876 synchronized (this) { 8877 // If there is a controller also implies the user is a monkey. 8878 return (mUserIsMonkey || mController != null); 8879 } 8880 } 8881 8882 public void requestBugReport() { 8883 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8884 SystemProperties.set("ctl.start", "bugreport"); 8885 } 8886 8887 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8888 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8889 } 8890 8891 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8892 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8893 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8894 } 8895 return KEY_DISPATCHING_TIMEOUT; 8896 } 8897 8898 @Override 8899 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8900 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8901 != PackageManager.PERMISSION_GRANTED) { 8902 throw new SecurityException("Requires permission " 8903 + android.Manifest.permission.FILTER_EVENTS); 8904 } 8905 ProcessRecord proc; 8906 long timeout; 8907 synchronized (this) { 8908 synchronized (mPidsSelfLocked) { 8909 proc = mPidsSelfLocked.get(pid); 8910 } 8911 timeout = getInputDispatchingTimeoutLocked(proc); 8912 } 8913 8914 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8915 return -1; 8916 } 8917 8918 return timeout; 8919 } 8920 8921 /** 8922 * Handle input dispatching timeouts. 8923 * Returns whether input dispatching should be aborted or not. 8924 */ 8925 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8926 final ActivityRecord activity, final ActivityRecord parent, 8927 final boolean aboveSystem, String reason) { 8928 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8929 != PackageManager.PERMISSION_GRANTED) { 8930 throw new SecurityException("Requires permission " 8931 + android.Manifest.permission.FILTER_EVENTS); 8932 } 8933 8934 final String annotation; 8935 if (reason == null) { 8936 annotation = "Input dispatching timed out"; 8937 } else { 8938 annotation = "Input dispatching timed out (" + reason + ")"; 8939 } 8940 8941 if (proc != null) { 8942 synchronized (this) { 8943 if (proc.debugging) { 8944 return false; 8945 } 8946 8947 if (mDidDexOpt) { 8948 // Give more time since we were dexopting. 8949 mDidDexOpt = false; 8950 return false; 8951 } 8952 8953 if (proc.instrumentationClass != null) { 8954 Bundle info = new Bundle(); 8955 info.putString("shortMsg", "keyDispatchingTimedOut"); 8956 info.putString("longMsg", annotation); 8957 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8958 return true; 8959 } 8960 } 8961 mHandler.post(new Runnable() { 8962 @Override 8963 public void run() { 8964 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8965 } 8966 }); 8967 } 8968 8969 return true; 8970 } 8971 8972 public Bundle getAssistContextExtras(int requestType) { 8973 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8974 "getAssistContextExtras()"); 8975 PendingAssistExtras pae; 8976 Bundle extras = new Bundle(); 8977 synchronized (this) { 8978 ActivityRecord activity = getFocusedStack().mResumedActivity; 8979 if (activity == null) { 8980 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8981 return null; 8982 } 8983 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8984 if (activity.app == null || activity.app.thread == null) { 8985 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8986 return extras; 8987 } 8988 if (activity.app.pid == Binder.getCallingPid()) { 8989 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8990 return extras; 8991 } 8992 pae = new PendingAssistExtras(activity); 8993 try { 8994 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8995 requestType); 8996 mPendingAssistExtras.add(pae); 8997 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8998 } catch (RemoteException e) { 8999 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9000 return extras; 9001 } 9002 } 9003 synchronized (pae) { 9004 while (!pae.haveResult) { 9005 try { 9006 pae.wait(); 9007 } catch (InterruptedException e) { 9008 } 9009 } 9010 if (pae.result != null) { 9011 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9012 } 9013 } 9014 synchronized (this) { 9015 mPendingAssistExtras.remove(pae); 9016 mHandler.removeCallbacks(pae); 9017 } 9018 return extras; 9019 } 9020 9021 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9022 PendingAssistExtras pae = (PendingAssistExtras)token; 9023 synchronized (pae) { 9024 pae.result = extras; 9025 pae.haveResult = true; 9026 pae.notifyAll(); 9027 } 9028 } 9029 9030 public void registerProcessObserver(IProcessObserver observer) { 9031 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9032 "registerProcessObserver()"); 9033 synchronized (this) { 9034 mProcessObservers.register(observer); 9035 } 9036 } 9037 9038 @Override 9039 public void unregisterProcessObserver(IProcessObserver observer) { 9040 synchronized (this) { 9041 mProcessObservers.unregister(observer); 9042 } 9043 } 9044 9045 @Override 9046 public boolean convertFromTranslucent(IBinder token) { 9047 final long origId = Binder.clearCallingIdentity(); 9048 try { 9049 synchronized (this) { 9050 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9051 if (r == null) { 9052 return false; 9053 } 9054 if (r.changeWindowTranslucency(true)) { 9055 mWindowManager.setAppFullscreen(token, true); 9056 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9057 return true; 9058 } 9059 return false; 9060 } 9061 } finally { 9062 Binder.restoreCallingIdentity(origId); 9063 } 9064 } 9065 9066 @Override 9067 public boolean convertToTranslucent(IBinder token) { 9068 final long origId = Binder.clearCallingIdentity(); 9069 try { 9070 synchronized (this) { 9071 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9072 if (r == null) { 9073 return false; 9074 } 9075 if (r.changeWindowTranslucency(false)) { 9076 r.task.stack.convertToTranslucent(r); 9077 mWindowManager.setAppFullscreen(token, false); 9078 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9079 return true; 9080 } 9081 return false; 9082 } 9083 } finally { 9084 Binder.restoreCallingIdentity(origId); 9085 } 9086 } 9087 9088 @Override 9089 public void setImmersive(IBinder token, boolean immersive) { 9090 synchronized(this) { 9091 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9092 if (r == null) { 9093 throw new IllegalArgumentException(); 9094 } 9095 r.immersive = immersive; 9096 9097 // update associated state if we're frontmost 9098 if (r == mFocusedActivity) { 9099 if (DEBUG_IMMERSIVE) { 9100 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9101 } 9102 applyUpdateLockStateLocked(r); 9103 } 9104 } 9105 } 9106 9107 @Override 9108 public boolean isImmersive(IBinder token) { 9109 synchronized (this) { 9110 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9111 if (r == null) { 9112 throw new IllegalArgumentException(); 9113 } 9114 return r.immersive; 9115 } 9116 } 9117 9118 public boolean isTopActivityImmersive() { 9119 enforceNotIsolatedCaller("startActivity"); 9120 synchronized (this) { 9121 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9122 return (r != null) ? r.immersive : false; 9123 } 9124 } 9125 9126 public final void enterSafeMode() { 9127 synchronized(this) { 9128 // It only makes sense to do this before the system is ready 9129 // and started launching other packages. 9130 if (!mSystemReady) { 9131 try { 9132 AppGlobals.getPackageManager().enterSafeMode(); 9133 } catch (RemoteException e) { 9134 } 9135 } 9136 9137 mSafeMode = true; 9138 } 9139 } 9140 9141 public final void showSafeModeOverlay() { 9142 View v = LayoutInflater.from(mContext).inflate( 9143 com.android.internal.R.layout.safe_mode, null); 9144 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9145 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9146 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9147 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9148 lp.gravity = Gravity.BOTTOM | Gravity.START; 9149 lp.format = v.getBackground().getOpacity(); 9150 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9151 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9152 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9153 ((WindowManager)mContext.getSystemService( 9154 Context.WINDOW_SERVICE)).addView(v, lp); 9155 } 9156 9157 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9158 if (!(sender instanceof PendingIntentRecord)) { 9159 return; 9160 } 9161 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9162 synchronized (stats) { 9163 if (mBatteryStatsService.isOnBattery()) { 9164 mBatteryStatsService.enforceCallingPermission(); 9165 PendingIntentRecord rec = (PendingIntentRecord)sender; 9166 int MY_UID = Binder.getCallingUid(); 9167 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9168 BatteryStatsImpl.Uid.Pkg pkg = 9169 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9170 sourcePkg != null ? sourcePkg : rec.key.packageName); 9171 pkg.incWakeupsLocked(); 9172 } 9173 } 9174 } 9175 9176 public boolean killPids(int[] pids, String pReason, boolean secure) { 9177 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9178 throw new SecurityException("killPids only available to the system"); 9179 } 9180 String reason = (pReason == null) ? "Unknown" : pReason; 9181 // XXX Note: don't acquire main activity lock here, because the window 9182 // manager calls in with its locks held. 9183 9184 boolean killed = false; 9185 synchronized (mPidsSelfLocked) { 9186 int[] types = new int[pids.length]; 9187 int worstType = 0; 9188 for (int i=0; i<pids.length; i++) { 9189 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9190 if (proc != null) { 9191 int type = proc.setAdj; 9192 types[i] = type; 9193 if (type > worstType) { 9194 worstType = type; 9195 } 9196 } 9197 } 9198 9199 // If the worst oom_adj is somewhere in the cached proc LRU range, 9200 // then constrain it so we will kill all cached procs. 9201 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9202 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9203 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9204 } 9205 9206 // If this is not a secure call, don't let it kill processes that 9207 // are important. 9208 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9209 worstType = ProcessList.SERVICE_ADJ; 9210 } 9211 9212 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9213 for (int i=0; i<pids.length; i++) { 9214 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9215 if (proc == null) { 9216 continue; 9217 } 9218 int adj = proc.setAdj; 9219 if (adj >= worstType && !proc.killedByAm) { 9220 killUnneededProcessLocked(proc, reason); 9221 killed = true; 9222 } 9223 } 9224 } 9225 return killed; 9226 } 9227 9228 @Override 9229 public void killUid(int uid, String reason) { 9230 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9231 throw new SecurityException("killUid only available to the system"); 9232 } 9233 synchronized (this) { 9234 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9235 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9236 reason != null ? reason : "kill uid"); 9237 } 9238 } 9239 9240 @Override 9241 public boolean killProcessesBelowForeground(String reason) { 9242 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9243 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9244 } 9245 9246 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9247 } 9248 9249 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9250 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9251 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9252 } 9253 9254 boolean killed = false; 9255 synchronized (mPidsSelfLocked) { 9256 final int size = mPidsSelfLocked.size(); 9257 for (int i = 0; i < size; i++) { 9258 final int pid = mPidsSelfLocked.keyAt(i); 9259 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9260 if (proc == null) continue; 9261 9262 final int adj = proc.setAdj; 9263 if (adj > belowAdj && !proc.killedByAm) { 9264 killUnneededProcessLocked(proc, reason); 9265 killed = true; 9266 } 9267 } 9268 } 9269 return killed; 9270 } 9271 9272 @Override 9273 public void hang(final IBinder who, boolean allowRestart) { 9274 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9275 != PackageManager.PERMISSION_GRANTED) { 9276 throw new SecurityException("Requires permission " 9277 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9278 } 9279 9280 final IBinder.DeathRecipient death = new DeathRecipient() { 9281 @Override 9282 public void binderDied() { 9283 synchronized (this) { 9284 notifyAll(); 9285 } 9286 } 9287 }; 9288 9289 try { 9290 who.linkToDeath(death, 0); 9291 } catch (RemoteException e) { 9292 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9293 return; 9294 } 9295 9296 synchronized (this) { 9297 Watchdog.getInstance().setAllowRestart(allowRestart); 9298 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9299 synchronized (death) { 9300 while (who.isBinderAlive()) { 9301 try { 9302 death.wait(); 9303 } catch (InterruptedException e) { 9304 } 9305 } 9306 } 9307 Watchdog.getInstance().setAllowRestart(true); 9308 } 9309 } 9310 9311 @Override 9312 public void restart() { 9313 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9314 != PackageManager.PERMISSION_GRANTED) { 9315 throw new SecurityException("Requires permission " 9316 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9317 } 9318 9319 Log.i(TAG, "Sending shutdown broadcast..."); 9320 9321 BroadcastReceiver br = new BroadcastReceiver() { 9322 @Override public void onReceive(Context context, Intent intent) { 9323 // Now the broadcast is done, finish up the low-level shutdown. 9324 Log.i(TAG, "Shutting down activity manager..."); 9325 shutdown(10000); 9326 Log.i(TAG, "Shutdown complete, restarting!"); 9327 Process.killProcess(Process.myPid()); 9328 System.exit(10); 9329 } 9330 }; 9331 9332 // First send the high-level shut down broadcast. 9333 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9334 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9335 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9336 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9337 mContext.sendOrderedBroadcastAsUser(intent, 9338 UserHandle.ALL, null, br, mHandler, 0, null, null); 9339 */ 9340 br.onReceive(mContext, intent); 9341 } 9342 9343 private long getLowRamTimeSinceIdle(long now) { 9344 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9345 } 9346 9347 @Override 9348 public void performIdleMaintenance() { 9349 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9350 != PackageManager.PERMISSION_GRANTED) { 9351 throw new SecurityException("Requires permission " 9352 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9353 } 9354 9355 synchronized (this) { 9356 final long now = SystemClock.uptimeMillis(); 9357 final long timeSinceLastIdle = now - mLastIdleTime; 9358 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9359 mLastIdleTime = now; 9360 mLowRamTimeSinceLastIdle = 0; 9361 if (mLowRamStartTime != 0) { 9362 mLowRamStartTime = now; 9363 } 9364 9365 StringBuilder sb = new StringBuilder(128); 9366 sb.append("Idle maintenance over "); 9367 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9368 sb.append(" low RAM for "); 9369 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9370 Slog.i(TAG, sb.toString()); 9371 9372 // If at least 1/3 of our time since the last idle period has been spent 9373 // with RAM low, then we want to kill processes. 9374 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9375 9376 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9377 ProcessRecord proc = mLruProcesses.get(i); 9378 if (proc.notCachedSinceIdle) { 9379 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9380 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9381 if (doKilling && proc.initialIdlePss != 0 9382 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9383 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9384 + " from " + proc.initialIdlePss + ")"); 9385 } 9386 } 9387 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9388 proc.notCachedSinceIdle = true; 9389 proc.initialIdlePss = 0; 9390 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9391 isSleeping(), now); 9392 } 9393 } 9394 9395 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9396 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9397 } 9398 } 9399 9400 private void retrieveSettings() { 9401 final ContentResolver resolver = mContext.getContentResolver(); 9402 String debugApp = Settings.Global.getString( 9403 resolver, Settings.Global.DEBUG_APP); 9404 boolean waitForDebugger = Settings.Global.getInt( 9405 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9406 boolean alwaysFinishActivities = Settings.Global.getInt( 9407 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9408 boolean forceRtl = Settings.Global.getInt( 9409 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9410 // Transfer any global setting for forcing RTL layout, into a System Property 9411 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9412 9413 Configuration configuration = new Configuration(); 9414 Settings.System.getConfiguration(resolver, configuration); 9415 if (forceRtl) { 9416 // This will take care of setting the correct layout direction flags 9417 configuration.setLayoutDirection(configuration.locale); 9418 } 9419 9420 synchronized (this) { 9421 mDebugApp = mOrigDebugApp = debugApp; 9422 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9423 mAlwaysFinishActivities = alwaysFinishActivities; 9424 // This happens before any activities are started, so we can 9425 // change mConfiguration in-place. 9426 updateConfigurationLocked(configuration, null, false, true); 9427 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9428 } 9429 } 9430 9431 public boolean testIsSystemReady() { 9432 // no need to synchronize(this) just to read & return the value 9433 return mSystemReady; 9434 } 9435 9436 private static File getCalledPreBootReceiversFile() { 9437 File dataDir = Environment.getDataDirectory(); 9438 File systemDir = new File(dataDir, "system"); 9439 File fname = new File(systemDir, "called_pre_boots.dat"); 9440 return fname; 9441 } 9442 9443 static final int LAST_DONE_VERSION = 10000; 9444 9445 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9446 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9447 File file = getCalledPreBootReceiversFile(); 9448 FileInputStream fis = null; 9449 try { 9450 fis = new FileInputStream(file); 9451 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9452 int fvers = dis.readInt(); 9453 if (fvers == LAST_DONE_VERSION) { 9454 String vers = dis.readUTF(); 9455 String codename = dis.readUTF(); 9456 String build = dis.readUTF(); 9457 if (android.os.Build.VERSION.RELEASE.equals(vers) 9458 && android.os.Build.VERSION.CODENAME.equals(codename) 9459 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9460 int num = dis.readInt(); 9461 while (num > 0) { 9462 num--; 9463 String pkg = dis.readUTF(); 9464 String cls = dis.readUTF(); 9465 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9466 } 9467 } 9468 } 9469 } catch (FileNotFoundException e) { 9470 } catch (IOException e) { 9471 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9472 } finally { 9473 if (fis != null) { 9474 try { 9475 fis.close(); 9476 } catch (IOException e) { 9477 } 9478 } 9479 } 9480 return lastDoneReceivers; 9481 } 9482 9483 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9484 File file = getCalledPreBootReceiversFile(); 9485 FileOutputStream fos = null; 9486 DataOutputStream dos = null; 9487 try { 9488 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9489 fos = new FileOutputStream(file); 9490 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9491 dos.writeInt(LAST_DONE_VERSION); 9492 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9493 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9494 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9495 dos.writeInt(list.size()); 9496 for (int i=0; i<list.size(); i++) { 9497 dos.writeUTF(list.get(i).getPackageName()); 9498 dos.writeUTF(list.get(i).getClassName()); 9499 } 9500 } catch (IOException e) { 9501 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9502 file.delete(); 9503 } finally { 9504 FileUtils.sync(fos); 9505 if (dos != null) { 9506 try { 9507 dos.close(); 9508 } catch (IOException e) { 9509 // TODO Auto-generated catch block 9510 e.printStackTrace(); 9511 } 9512 } 9513 } 9514 } 9515 9516 public void systemReady(final Runnable goingCallback) { 9517 synchronized(this) { 9518 if (mSystemReady) { 9519 if (goingCallback != null) goingCallback.run(); 9520 return; 9521 } 9522 9523 // Check to see if there are any update receivers to run. 9524 if (!mDidUpdate) { 9525 if (mWaitingUpdate) { 9526 return; 9527 } 9528 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9529 List<ResolveInfo> ris = null; 9530 try { 9531 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9532 intent, null, 0, 0); 9533 } catch (RemoteException e) { 9534 } 9535 if (ris != null) { 9536 for (int i=ris.size()-1; i>=0; i--) { 9537 if ((ris.get(i).activityInfo.applicationInfo.flags 9538 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9539 ris.remove(i); 9540 } 9541 } 9542 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9543 9544 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9545 9546 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9547 for (int i=0; i<ris.size(); i++) { 9548 ActivityInfo ai = ris.get(i).activityInfo; 9549 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9550 if (lastDoneReceivers.contains(comp)) { 9551 // We already did the pre boot receiver for this app with the current 9552 // platform version, so don't do it again... 9553 ris.remove(i); 9554 i--; 9555 // ...however, do keep it as one that has been done, so we don't 9556 // forget about it when rewriting the file of last done receivers. 9557 doneReceivers.add(comp); 9558 } 9559 } 9560 9561 final int[] users = getUsersLocked(); 9562 for (int i=0; i<ris.size(); i++) { 9563 ActivityInfo ai = ris.get(i).activityInfo; 9564 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9565 doneReceivers.add(comp); 9566 intent.setComponent(comp); 9567 for (int j=0; j<users.length; j++) { 9568 IIntentReceiver finisher = null; 9569 if (i == ris.size()-1 && j == users.length-1) { 9570 finisher = new IIntentReceiver.Stub() { 9571 public void performReceive(Intent intent, int resultCode, 9572 String data, Bundle extras, boolean ordered, 9573 boolean sticky, int sendingUser) { 9574 // The raw IIntentReceiver interface is called 9575 // with the AM lock held, so redispatch to 9576 // execute our code without the lock. 9577 mHandler.post(new Runnable() { 9578 public void run() { 9579 synchronized (ActivityManagerService.this) { 9580 mDidUpdate = true; 9581 } 9582 writeLastDonePreBootReceivers(doneReceivers); 9583 showBootMessage(mContext.getText( 9584 R.string.android_upgrading_complete), 9585 false); 9586 systemReady(goingCallback); 9587 } 9588 }); 9589 } 9590 }; 9591 } 9592 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9593 + " for user " + users[j]); 9594 broadcastIntentLocked(null, null, intent, null, finisher, 9595 0, null, null, null, AppOpsManager.OP_NONE, 9596 true, false, MY_PID, Process.SYSTEM_UID, 9597 users[j]); 9598 if (finisher != null) { 9599 mWaitingUpdate = true; 9600 } 9601 } 9602 } 9603 } 9604 if (mWaitingUpdate) { 9605 return; 9606 } 9607 mDidUpdate = true; 9608 } 9609 9610 mAppOpsService.systemReady(); 9611 mSystemReady = true; 9612 } 9613 9614 ArrayList<ProcessRecord> procsToKill = null; 9615 synchronized(mPidsSelfLocked) { 9616 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9617 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9618 if (!isAllowedWhileBooting(proc.info)){ 9619 if (procsToKill == null) { 9620 procsToKill = new ArrayList<ProcessRecord>(); 9621 } 9622 procsToKill.add(proc); 9623 } 9624 } 9625 } 9626 9627 synchronized(this) { 9628 if (procsToKill != null) { 9629 for (int i=procsToKill.size()-1; i>=0; i--) { 9630 ProcessRecord proc = procsToKill.get(i); 9631 Slog.i(TAG, "Removing system update proc: " + proc); 9632 removeProcessLocked(proc, true, false, "system update done"); 9633 } 9634 } 9635 9636 // Now that we have cleaned up any update processes, we 9637 // are ready to start launching real processes and know that 9638 // we won't trample on them any more. 9639 mProcessesReady = true; 9640 } 9641 9642 Slog.i(TAG, "System now ready"); 9643 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9644 SystemClock.uptimeMillis()); 9645 9646 synchronized(this) { 9647 // Make sure we have no pre-ready processes sitting around. 9648 9649 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9650 ResolveInfo ri = mContext.getPackageManager() 9651 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9652 STOCK_PM_FLAGS); 9653 CharSequence errorMsg = null; 9654 if (ri != null) { 9655 ActivityInfo ai = ri.activityInfo; 9656 ApplicationInfo app = ai.applicationInfo; 9657 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9658 mTopAction = Intent.ACTION_FACTORY_TEST; 9659 mTopData = null; 9660 mTopComponent = new ComponentName(app.packageName, 9661 ai.name); 9662 } else { 9663 errorMsg = mContext.getResources().getText( 9664 com.android.internal.R.string.factorytest_not_system); 9665 } 9666 } else { 9667 errorMsg = mContext.getResources().getText( 9668 com.android.internal.R.string.factorytest_no_action); 9669 } 9670 if (errorMsg != null) { 9671 mTopAction = null; 9672 mTopData = null; 9673 mTopComponent = null; 9674 Message msg = Message.obtain(); 9675 msg.what = SHOW_FACTORY_ERROR_MSG; 9676 msg.getData().putCharSequence("msg", errorMsg); 9677 mHandler.sendMessage(msg); 9678 } 9679 } 9680 } 9681 9682 retrieveSettings(); 9683 9684 synchronized (this) { 9685 readGrantedUriPermissionsLocked(); 9686 } 9687 9688 if (goingCallback != null) goingCallback.run(); 9689 9690 mSystemServiceManager.startUser(mCurrentUserId); 9691 9692 synchronized (this) { 9693 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9694 try { 9695 List apps = AppGlobals.getPackageManager(). 9696 getPersistentApplications(STOCK_PM_FLAGS); 9697 if (apps != null) { 9698 int N = apps.size(); 9699 int i; 9700 for (i=0; i<N; i++) { 9701 ApplicationInfo info 9702 = (ApplicationInfo)apps.get(i); 9703 if (info != null && 9704 !info.packageName.equals("android")) { 9705 addAppLocked(info, false); 9706 } 9707 } 9708 } 9709 } catch (RemoteException ex) { 9710 // pm is in same process, this will never happen. 9711 } 9712 } 9713 9714 // Start up initial activity. 9715 mBooting = true; 9716 9717 try { 9718 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9719 Message msg = Message.obtain(); 9720 msg.what = SHOW_UID_ERROR_MSG; 9721 mHandler.sendMessage(msg); 9722 } 9723 } catch (RemoteException e) { 9724 } 9725 9726 long ident = Binder.clearCallingIdentity(); 9727 try { 9728 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9729 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9730 | Intent.FLAG_RECEIVER_FOREGROUND); 9731 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9732 broadcastIntentLocked(null, null, intent, 9733 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9734 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9735 intent = new Intent(Intent.ACTION_USER_STARTING); 9736 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9737 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9738 broadcastIntentLocked(null, null, intent, 9739 null, new IIntentReceiver.Stub() { 9740 @Override 9741 public void performReceive(Intent intent, int resultCode, String data, 9742 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9743 throws RemoteException { 9744 } 9745 }, 0, null, null, 9746 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9747 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9748 } catch (Throwable t) { 9749 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9750 } finally { 9751 Binder.restoreCallingIdentity(ident); 9752 } 9753 mStackSupervisor.resumeTopActivitiesLocked(); 9754 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9755 } 9756 } 9757 9758 private boolean makeAppCrashingLocked(ProcessRecord app, 9759 String shortMsg, String longMsg, String stackTrace) { 9760 app.crashing = true; 9761 app.crashingReport = generateProcessError(app, 9762 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9763 startAppProblemLocked(app); 9764 app.stopFreezingAllLocked(); 9765 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9766 } 9767 9768 private void makeAppNotRespondingLocked(ProcessRecord app, 9769 String activity, String shortMsg, String longMsg) { 9770 app.notResponding = true; 9771 app.notRespondingReport = generateProcessError(app, 9772 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9773 activity, shortMsg, longMsg, null); 9774 startAppProblemLocked(app); 9775 app.stopFreezingAllLocked(); 9776 } 9777 9778 /** 9779 * Generate a process error record, suitable for attachment to a ProcessRecord. 9780 * 9781 * @param app The ProcessRecord in which the error occurred. 9782 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9783 * ActivityManager.AppErrorStateInfo 9784 * @param activity The activity associated with the crash, if known. 9785 * @param shortMsg Short message describing the crash. 9786 * @param longMsg Long message describing the crash. 9787 * @param stackTrace Full crash stack trace, may be null. 9788 * 9789 * @return Returns a fully-formed AppErrorStateInfo record. 9790 */ 9791 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9792 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9793 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9794 9795 report.condition = condition; 9796 report.processName = app.processName; 9797 report.pid = app.pid; 9798 report.uid = app.info.uid; 9799 report.tag = activity; 9800 report.shortMsg = shortMsg; 9801 report.longMsg = longMsg; 9802 report.stackTrace = stackTrace; 9803 9804 return report; 9805 } 9806 9807 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9808 synchronized (this) { 9809 app.crashing = false; 9810 app.crashingReport = null; 9811 app.notResponding = false; 9812 app.notRespondingReport = null; 9813 if (app.anrDialog == fromDialog) { 9814 app.anrDialog = null; 9815 } 9816 if (app.waitDialog == fromDialog) { 9817 app.waitDialog = null; 9818 } 9819 if (app.pid > 0 && app.pid != MY_PID) { 9820 handleAppCrashLocked(app, null, null, null); 9821 killUnneededProcessLocked(app, "user request after error"); 9822 } 9823 } 9824 } 9825 9826 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9827 String stackTrace) { 9828 long now = SystemClock.uptimeMillis(); 9829 9830 Long crashTime; 9831 if (!app.isolated) { 9832 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9833 } else { 9834 crashTime = null; 9835 } 9836 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9837 // This process loses! 9838 Slog.w(TAG, "Process " + app.info.processName 9839 + " has crashed too many times: killing!"); 9840 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9841 app.userId, app.info.processName, app.uid); 9842 mStackSupervisor.handleAppCrashLocked(app); 9843 if (!app.persistent) { 9844 // We don't want to start this process again until the user 9845 // explicitly does so... but for persistent process, we really 9846 // need to keep it running. If a persistent process is actually 9847 // repeatedly crashing, then badness for everyone. 9848 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9849 app.info.processName); 9850 if (!app.isolated) { 9851 // XXX We don't have a way to mark isolated processes 9852 // as bad, since they don't have a peristent identity. 9853 mBadProcesses.put(app.info.processName, app.uid, 9854 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9855 mProcessCrashTimes.remove(app.info.processName, app.uid); 9856 } 9857 app.bad = true; 9858 app.removed = true; 9859 // Don't let services in this process be restarted and potentially 9860 // annoy the user repeatedly. Unless it is persistent, since those 9861 // processes run critical code. 9862 removeProcessLocked(app, false, false, "crash"); 9863 mStackSupervisor.resumeTopActivitiesLocked(); 9864 return false; 9865 } 9866 mStackSupervisor.resumeTopActivitiesLocked(); 9867 } else { 9868 mStackSupervisor.finishTopRunningActivityLocked(app); 9869 } 9870 9871 // Bump up the crash count of any services currently running in the proc. 9872 for (int i=app.services.size()-1; i>=0; i--) { 9873 // Any services running in the application need to be placed 9874 // back in the pending list. 9875 ServiceRecord sr = app.services.valueAt(i); 9876 sr.crashCount++; 9877 } 9878 9879 // If the crashing process is what we consider to be the "home process" and it has been 9880 // replaced by a third-party app, clear the package preferred activities from packages 9881 // with a home activity running in the process to prevent a repeatedly crashing app 9882 // from blocking the user to manually clear the list. 9883 final ArrayList<ActivityRecord> activities = app.activities; 9884 if (app == mHomeProcess && activities.size() > 0 9885 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9886 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9887 final ActivityRecord r = activities.get(activityNdx); 9888 if (r.isHomeActivity()) { 9889 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9890 try { 9891 ActivityThread.getPackageManager() 9892 .clearPackagePreferredActivities(r.packageName); 9893 } catch (RemoteException c) { 9894 // pm is in same process, this will never happen. 9895 } 9896 } 9897 } 9898 } 9899 9900 if (!app.isolated) { 9901 // XXX Can't keep track of crash times for isolated processes, 9902 // because they don't have a perisistent identity. 9903 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9904 } 9905 9906 return true; 9907 } 9908 9909 void startAppProblemLocked(ProcessRecord app) { 9910 if (app.userId == mCurrentUserId) { 9911 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9912 mContext, app.info.packageName, app.info.flags); 9913 } else { 9914 // If this app is not running under the current user, then we 9915 // can't give it a report button because that would require 9916 // launching the report UI under a different user. 9917 app.errorReportReceiver = null; 9918 } 9919 skipCurrentReceiverLocked(app); 9920 } 9921 9922 void skipCurrentReceiverLocked(ProcessRecord app) { 9923 for (BroadcastQueue queue : mBroadcastQueues) { 9924 queue.skipCurrentReceiverLocked(app); 9925 } 9926 } 9927 9928 /** 9929 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9930 * The application process will exit immediately after this call returns. 9931 * @param app object of the crashing app, null for the system server 9932 * @param crashInfo describing the exception 9933 */ 9934 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9935 ProcessRecord r = findAppProcess(app, "Crash"); 9936 final String processName = app == null ? "system_server" 9937 : (r == null ? "unknown" : r.processName); 9938 9939 handleApplicationCrashInner("crash", r, processName, crashInfo); 9940 } 9941 9942 /* Native crash reporting uses this inner version because it needs to be somewhat 9943 * decoupled from the AM-managed cleanup lifecycle 9944 */ 9945 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9946 ApplicationErrorReport.CrashInfo crashInfo) { 9947 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9948 UserHandle.getUserId(Binder.getCallingUid()), processName, 9949 r == null ? -1 : r.info.flags, 9950 crashInfo.exceptionClassName, 9951 crashInfo.exceptionMessage, 9952 crashInfo.throwFileName, 9953 crashInfo.throwLineNumber); 9954 9955 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9956 9957 crashApplication(r, crashInfo); 9958 } 9959 9960 public void handleApplicationStrictModeViolation( 9961 IBinder app, 9962 int violationMask, 9963 StrictMode.ViolationInfo info) { 9964 ProcessRecord r = findAppProcess(app, "StrictMode"); 9965 if (r == null) { 9966 return; 9967 } 9968 9969 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9970 Integer stackFingerprint = info.hashCode(); 9971 boolean logIt = true; 9972 synchronized (mAlreadyLoggedViolatedStacks) { 9973 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9974 logIt = false; 9975 // TODO: sub-sample into EventLog for these, with 9976 // the info.durationMillis? Then we'd get 9977 // the relative pain numbers, without logging all 9978 // the stack traces repeatedly. We'd want to do 9979 // likewise in the client code, which also does 9980 // dup suppression, before the Binder call. 9981 } else { 9982 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9983 mAlreadyLoggedViolatedStacks.clear(); 9984 } 9985 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9986 } 9987 } 9988 if (logIt) { 9989 logStrictModeViolationToDropBox(r, info); 9990 } 9991 } 9992 9993 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9994 AppErrorResult result = new AppErrorResult(); 9995 synchronized (this) { 9996 final long origId = Binder.clearCallingIdentity(); 9997 9998 Message msg = Message.obtain(); 9999 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10000 HashMap<String, Object> data = new HashMap<String, Object>(); 10001 data.put("result", result); 10002 data.put("app", r); 10003 data.put("violationMask", violationMask); 10004 data.put("info", info); 10005 msg.obj = data; 10006 mHandler.sendMessage(msg); 10007 10008 Binder.restoreCallingIdentity(origId); 10009 } 10010 int res = result.get(); 10011 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10012 } 10013 } 10014 10015 // Depending on the policy in effect, there could be a bunch of 10016 // these in quick succession so we try to batch these together to 10017 // minimize disk writes, number of dropbox entries, and maximize 10018 // compression, by having more fewer, larger records. 10019 private void logStrictModeViolationToDropBox( 10020 ProcessRecord process, 10021 StrictMode.ViolationInfo info) { 10022 if (info == null) { 10023 return; 10024 } 10025 final boolean isSystemApp = process == null || 10026 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10027 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10028 final String processName = process == null ? "unknown" : process.processName; 10029 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10030 final DropBoxManager dbox = (DropBoxManager) 10031 mContext.getSystemService(Context.DROPBOX_SERVICE); 10032 10033 // Exit early if the dropbox isn't configured to accept this report type. 10034 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10035 10036 boolean bufferWasEmpty; 10037 boolean needsFlush; 10038 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10039 synchronized (sb) { 10040 bufferWasEmpty = sb.length() == 0; 10041 appendDropBoxProcessHeaders(process, processName, sb); 10042 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10043 sb.append("System-App: ").append(isSystemApp).append("\n"); 10044 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10045 if (info.violationNumThisLoop != 0) { 10046 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10047 } 10048 if (info.numAnimationsRunning != 0) { 10049 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10050 } 10051 if (info.broadcastIntentAction != null) { 10052 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10053 } 10054 if (info.durationMillis != -1) { 10055 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10056 } 10057 if (info.numInstances != -1) { 10058 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10059 } 10060 if (info.tags != null) { 10061 for (String tag : info.tags) { 10062 sb.append("Span-Tag: ").append(tag).append("\n"); 10063 } 10064 } 10065 sb.append("\n"); 10066 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10067 sb.append(info.crashInfo.stackTrace); 10068 } 10069 sb.append("\n"); 10070 10071 // Only buffer up to ~64k. Various logging bits truncate 10072 // things at 128k. 10073 needsFlush = (sb.length() > 64 * 1024); 10074 } 10075 10076 // Flush immediately if the buffer's grown too large, or this 10077 // is a non-system app. Non-system apps are isolated with a 10078 // different tag & policy and not batched. 10079 // 10080 // Batching is useful during internal testing with 10081 // StrictMode settings turned up high. Without batching, 10082 // thousands of separate files could be created on boot. 10083 if (!isSystemApp || needsFlush) { 10084 new Thread("Error dump: " + dropboxTag) { 10085 @Override 10086 public void run() { 10087 String report; 10088 synchronized (sb) { 10089 report = sb.toString(); 10090 sb.delete(0, sb.length()); 10091 sb.trimToSize(); 10092 } 10093 if (report.length() != 0) { 10094 dbox.addText(dropboxTag, report); 10095 } 10096 } 10097 }.start(); 10098 return; 10099 } 10100 10101 // System app batching: 10102 if (!bufferWasEmpty) { 10103 // An existing dropbox-writing thread is outstanding, so 10104 // we don't need to start it up. The existing thread will 10105 // catch the buffer appends we just did. 10106 return; 10107 } 10108 10109 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10110 // (After this point, we shouldn't access AMS internal data structures.) 10111 new Thread("Error dump: " + dropboxTag) { 10112 @Override 10113 public void run() { 10114 // 5 second sleep to let stacks arrive and be batched together 10115 try { 10116 Thread.sleep(5000); // 5 seconds 10117 } catch (InterruptedException e) {} 10118 10119 String errorReport; 10120 synchronized (mStrictModeBuffer) { 10121 errorReport = mStrictModeBuffer.toString(); 10122 if (errorReport.length() == 0) { 10123 return; 10124 } 10125 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10126 mStrictModeBuffer.trimToSize(); 10127 } 10128 dbox.addText(dropboxTag, errorReport); 10129 } 10130 }.start(); 10131 } 10132 10133 /** 10134 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10135 * @param app object of the crashing app, null for the system server 10136 * @param tag reported by the caller 10137 * @param crashInfo describing the context of the error 10138 * @return true if the process should exit immediately (WTF is fatal) 10139 */ 10140 public boolean handleApplicationWtf(IBinder app, String tag, 10141 ApplicationErrorReport.CrashInfo crashInfo) { 10142 ProcessRecord r = findAppProcess(app, "WTF"); 10143 final String processName = app == null ? "system_server" 10144 : (r == null ? "unknown" : r.processName); 10145 10146 EventLog.writeEvent(EventLogTags.AM_WTF, 10147 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10148 processName, 10149 r == null ? -1 : r.info.flags, 10150 tag, crashInfo.exceptionMessage); 10151 10152 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10153 10154 if (r != null && r.pid != Process.myPid() && 10155 Settings.Global.getInt(mContext.getContentResolver(), 10156 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10157 crashApplication(r, crashInfo); 10158 return true; 10159 } else { 10160 return false; 10161 } 10162 } 10163 10164 /** 10165 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10166 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10167 */ 10168 private ProcessRecord findAppProcess(IBinder app, String reason) { 10169 if (app == null) { 10170 return null; 10171 } 10172 10173 synchronized (this) { 10174 final int NP = mProcessNames.getMap().size(); 10175 for (int ip=0; ip<NP; ip++) { 10176 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10177 final int NA = apps.size(); 10178 for (int ia=0; ia<NA; ia++) { 10179 ProcessRecord p = apps.valueAt(ia); 10180 if (p.thread != null && p.thread.asBinder() == app) { 10181 return p; 10182 } 10183 } 10184 } 10185 10186 Slog.w(TAG, "Can't find mystery application for " + reason 10187 + " from pid=" + Binder.getCallingPid() 10188 + " uid=" + Binder.getCallingUid() + ": " + app); 10189 return null; 10190 } 10191 } 10192 10193 /** 10194 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10195 * to append various headers to the dropbox log text. 10196 */ 10197 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10198 StringBuilder sb) { 10199 // Watchdog thread ends up invoking this function (with 10200 // a null ProcessRecord) to add the stack file to dropbox. 10201 // Do not acquire a lock on this (am) in such cases, as it 10202 // could cause a potential deadlock, if and when watchdog 10203 // is invoked due to unavailability of lock on am and it 10204 // would prevent watchdog from killing system_server. 10205 if (process == null) { 10206 sb.append("Process: ").append(processName).append("\n"); 10207 return; 10208 } 10209 // Note: ProcessRecord 'process' is guarded by the service 10210 // instance. (notably process.pkgList, which could otherwise change 10211 // concurrently during execution of this method) 10212 synchronized (this) { 10213 sb.append("Process: ").append(processName).append("\n"); 10214 int flags = process.info.flags; 10215 IPackageManager pm = AppGlobals.getPackageManager(); 10216 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10217 for (int ip=0; ip<process.pkgList.size(); ip++) { 10218 String pkg = process.pkgList.keyAt(ip); 10219 sb.append("Package: ").append(pkg); 10220 try { 10221 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10222 if (pi != null) { 10223 sb.append(" v").append(pi.versionCode); 10224 if (pi.versionName != null) { 10225 sb.append(" (").append(pi.versionName).append(")"); 10226 } 10227 } 10228 } catch (RemoteException e) { 10229 Slog.e(TAG, "Error getting package info: " + pkg, e); 10230 } 10231 sb.append("\n"); 10232 } 10233 } 10234 } 10235 10236 private static String processClass(ProcessRecord process) { 10237 if (process == null || process.pid == MY_PID) { 10238 return "system_server"; 10239 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10240 return "system_app"; 10241 } else { 10242 return "data_app"; 10243 } 10244 } 10245 10246 /** 10247 * Write a description of an error (crash, WTF, ANR) to the drop box. 10248 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10249 * @param process which caused the error, null means the system server 10250 * @param activity which triggered the error, null if unknown 10251 * @param parent activity related to the error, null if unknown 10252 * @param subject line related to the error, null if absent 10253 * @param report in long form describing the error, null if absent 10254 * @param logFile to include in the report, null if none 10255 * @param crashInfo giving an application stack trace, null if absent 10256 */ 10257 public void addErrorToDropBox(String eventType, 10258 ProcessRecord process, String processName, ActivityRecord activity, 10259 ActivityRecord parent, String subject, 10260 final String report, final File logFile, 10261 final ApplicationErrorReport.CrashInfo crashInfo) { 10262 // NOTE -- this must never acquire the ActivityManagerService lock, 10263 // otherwise the watchdog may be prevented from resetting the system. 10264 10265 final String dropboxTag = processClass(process) + "_" + eventType; 10266 final DropBoxManager dbox = (DropBoxManager) 10267 mContext.getSystemService(Context.DROPBOX_SERVICE); 10268 10269 // Exit early if the dropbox isn't configured to accept this report type. 10270 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10271 10272 final StringBuilder sb = new StringBuilder(1024); 10273 appendDropBoxProcessHeaders(process, processName, sb); 10274 if (activity != null) { 10275 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10276 } 10277 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10278 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10279 } 10280 if (parent != null && parent != activity) { 10281 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10282 } 10283 if (subject != null) { 10284 sb.append("Subject: ").append(subject).append("\n"); 10285 } 10286 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10287 if (Debug.isDebuggerConnected()) { 10288 sb.append("Debugger: Connected\n"); 10289 } 10290 sb.append("\n"); 10291 10292 // Do the rest in a worker thread to avoid blocking the caller on I/O 10293 // (After this point, we shouldn't access AMS internal data structures.) 10294 Thread worker = new Thread("Error dump: " + dropboxTag) { 10295 @Override 10296 public void run() { 10297 if (report != null) { 10298 sb.append(report); 10299 } 10300 if (logFile != null) { 10301 try { 10302 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10303 "\n\n[[TRUNCATED]]")); 10304 } catch (IOException e) { 10305 Slog.e(TAG, "Error reading " + logFile, e); 10306 } 10307 } 10308 if (crashInfo != null && crashInfo.stackTrace != null) { 10309 sb.append(crashInfo.stackTrace); 10310 } 10311 10312 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10313 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10314 if (lines > 0) { 10315 sb.append("\n"); 10316 10317 // Merge several logcat streams, and take the last N lines 10318 InputStreamReader input = null; 10319 try { 10320 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10321 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10322 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10323 10324 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10325 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10326 input = new InputStreamReader(logcat.getInputStream()); 10327 10328 int num; 10329 char[] buf = new char[8192]; 10330 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10331 } catch (IOException e) { 10332 Slog.e(TAG, "Error running logcat", e); 10333 } finally { 10334 if (input != null) try { input.close(); } catch (IOException e) {} 10335 } 10336 } 10337 10338 dbox.addText(dropboxTag, sb.toString()); 10339 } 10340 }; 10341 10342 if (process == null) { 10343 // If process is null, we are being called from some internal code 10344 // and may be about to die -- run this synchronously. 10345 worker.run(); 10346 } else { 10347 worker.start(); 10348 } 10349 } 10350 10351 /** 10352 * Bring up the "unexpected error" dialog box for a crashing app. 10353 * Deal with edge cases (intercepts from instrumented applications, 10354 * ActivityController, error intent receivers, that sort of thing). 10355 * @param r the application crashing 10356 * @param crashInfo describing the failure 10357 */ 10358 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10359 long timeMillis = System.currentTimeMillis(); 10360 String shortMsg = crashInfo.exceptionClassName; 10361 String longMsg = crashInfo.exceptionMessage; 10362 String stackTrace = crashInfo.stackTrace; 10363 if (shortMsg != null && longMsg != null) { 10364 longMsg = shortMsg + ": " + longMsg; 10365 } else if (shortMsg != null) { 10366 longMsg = shortMsg; 10367 } 10368 10369 AppErrorResult result = new AppErrorResult(); 10370 synchronized (this) { 10371 if (mController != null) { 10372 try { 10373 String name = r != null ? r.processName : null; 10374 int pid = r != null ? r.pid : Binder.getCallingPid(); 10375 if (!mController.appCrashed(name, pid, 10376 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10377 Slog.w(TAG, "Force-killing crashed app " + name 10378 + " at watcher's request"); 10379 Process.killProcess(pid); 10380 return; 10381 } 10382 } catch (RemoteException e) { 10383 mController = null; 10384 Watchdog.getInstance().setActivityController(null); 10385 } 10386 } 10387 10388 final long origId = Binder.clearCallingIdentity(); 10389 10390 // If this process is running instrumentation, finish it. 10391 if (r != null && r.instrumentationClass != null) { 10392 Slog.w(TAG, "Error in app " + r.processName 10393 + " running instrumentation " + r.instrumentationClass + ":"); 10394 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10395 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10396 Bundle info = new Bundle(); 10397 info.putString("shortMsg", shortMsg); 10398 info.putString("longMsg", longMsg); 10399 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10400 Binder.restoreCallingIdentity(origId); 10401 return; 10402 } 10403 10404 // If we can't identify the process or it's already exceeded its crash quota, 10405 // quit right away without showing a crash dialog. 10406 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10407 Binder.restoreCallingIdentity(origId); 10408 return; 10409 } 10410 10411 Message msg = Message.obtain(); 10412 msg.what = SHOW_ERROR_MSG; 10413 HashMap data = new HashMap(); 10414 data.put("result", result); 10415 data.put("app", r); 10416 msg.obj = data; 10417 mHandler.sendMessage(msg); 10418 10419 Binder.restoreCallingIdentity(origId); 10420 } 10421 10422 int res = result.get(); 10423 10424 Intent appErrorIntent = null; 10425 synchronized (this) { 10426 if (r != null && !r.isolated) { 10427 // XXX Can't keep track of crash time for isolated processes, 10428 // since they don't have a persistent identity. 10429 mProcessCrashTimes.put(r.info.processName, r.uid, 10430 SystemClock.uptimeMillis()); 10431 } 10432 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10433 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10434 } 10435 } 10436 10437 if (appErrorIntent != null) { 10438 try { 10439 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10440 } catch (ActivityNotFoundException e) { 10441 Slog.w(TAG, "bug report receiver dissappeared", e); 10442 } 10443 } 10444 } 10445 10446 Intent createAppErrorIntentLocked(ProcessRecord r, 10447 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10448 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10449 if (report == null) { 10450 return null; 10451 } 10452 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10453 result.setComponent(r.errorReportReceiver); 10454 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10455 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10456 return result; 10457 } 10458 10459 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10460 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10461 if (r.errorReportReceiver == null) { 10462 return null; 10463 } 10464 10465 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10466 return null; 10467 } 10468 10469 ApplicationErrorReport report = new ApplicationErrorReport(); 10470 report.packageName = r.info.packageName; 10471 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10472 report.processName = r.processName; 10473 report.time = timeMillis; 10474 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10475 10476 if (r.crashing || r.forceCrashReport) { 10477 report.type = ApplicationErrorReport.TYPE_CRASH; 10478 report.crashInfo = crashInfo; 10479 } else if (r.notResponding) { 10480 report.type = ApplicationErrorReport.TYPE_ANR; 10481 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10482 10483 report.anrInfo.activity = r.notRespondingReport.tag; 10484 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10485 report.anrInfo.info = r.notRespondingReport.longMsg; 10486 } 10487 10488 return report; 10489 } 10490 10491 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10492 enforceNotIsolatedCaller("getProcessesInErrorState"); 10493 // assume our apps are happy - lazy create the list 10494 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10495 10496 final boolean allUsers = ActivityManager.checkUidPermission( 10497 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10498 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10499 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10500 10501 synchronized (this) { 10502 10503 // iterate across all processes 10504 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10505 ProcessRecord app = mLruProcesses.get(i); 10506 if (!allUsers && app.userId != userId) { 10507 continue; 10508 } 10509 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10510 // This one's in trouble, so we'll generate a report for it 10511 // crashes are higher priority (in case there's a crash *and* an anr) 10512 ActivityManager.ProcessErrorStateInfo report = null; 10513 if (app.crashing) { 10514 report = app.crashingReport; 10515 } else if (app.notResponding) { 10516 report = app.notRespondingReport; 10517 } 10518 10519 if (report != null) { 10520 if (errList == null) { 10521 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10522 } 10523 errList.add(report); 10524 } else { 10525 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10526 " crashing = " + app.crashing + 10527 " notResponding = " + app.notResponding); 10528 } 10529 } 10530 } 10531 } 10532 10533 return errList; 10534 } 10535 10536 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10537 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10538 if (currApp != null) { 10539 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10540 } 10541 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10542 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10543 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10544 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10545 if (currApp != null) { 10546 currApp.lru = 0; 10547 } 10548 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10549 } else if (adj >= ProcessList.SERVICE_ADJ) { 10550 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10551 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10552 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10553 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10554 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10555 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10556 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10557 } else { 10558 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10559 } 10560 } 10561 10562 private void fillInProcMemInfo(ProcessRecord app, 10563 ActivityManager.RunningAppProcessInfo outInfo) { 10564 outInfo.pid = app.pid; 10565 outInfo.uid = app.info.uid; 10566 if (mHeavyWeightProcess == app) { 10567 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10568 } 10569 if (app.persistent) { 10570 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10571 } 10572 if (app.activities.size() > 0) { 10573 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10574 } 10575 outInfo.lastTrimLevel = app.trimMemoryLevel; 10576 int adj = app.curAdj; 10577 outInfo.importance = oomAdjToImportance(adj, outInfo); 10578 outInfo.importanceReasonCode = app.adjTypeCode; 10579 } 10580 10581 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10582 enforceNotIsolatedCaller("getRunningAppProcesses"); 10583 // Lazy instantiation of list 10584 List<ActivityManager.RunningAppProcessInfo> runList = null; 10585 final boolean allUsers = ActivityManager.checkUidPermission( 10586 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10587 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10588 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10589 synchronized (this) { 10590 // Iterate across all processes 10591 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10592 ProcessRecord app = mLruProcesses.get(i); 10593 if (!allUsers && app.userId != userId) { 10594 continue; 10595 } 10596 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10597 // Generate process state info for running application 10598 ActivityManager.RunningAppProcessInfo currApp = 10599 new ActivityManager.RunningAppProcessInfo(app.processName, 10600 app.pid, app.getPackageList()); 10601 fillInProcMemInfo(app, currApp); 10602 if (app.adjSource instanceof ProcessRecord) { 10603 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10604 currApp.importanceReasonImportance = oomAdjToImportance( 10605 app.adjSourceOom, null); 10606 } else if (app.adjSource instanceof ActivityRecord) { 10607 ActivityRecord r = (ActivityRecord)app.adjSource; 10608 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10609 } 10610 if (app.adjTarget instanceof ComponentName) { 10611 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10612 } 10613 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10614 // + " lru=" + currApp.lru); 10615 if (runList == null) { 10616 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10617 } 10618 runList.add(currApp); 10619 } 10620 } 10621 } 10622 return runList; 10623 } 10624 10625 public List<ApplicationInfo> getRunningExternalApplications() { 10626 enforceNotIsolatedCaller("getRunningExternalApplications"); 10627 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10628 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10629 if (runningApps != null && runningApps.size() > 0) { 10630 Set<String> extList = new HashSet<String>(); 10631 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10632 if (app.pkgList != null) { 10633 for (String pkg : app.pkgList) { 10634 extList.add(pkg); 10635 } 10636 } 10637 } 10638 IPackageManager pm = AppGlobals.getPackageManager(); 10639 for (String pkg : extList) { 10640 try { 10641 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10642 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10643 retList.add(info); 10644 } 10645 } catch (RemoteException e) { 10646 } 10647 } 10648 } 10649 return retList; 10650 } 10651 10652 @Override 10653 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10654 enforceNotIsolatedCaller("getMyMemoryState"); 10655 synchronized (this) { 10656 ProcessRecord proc; 10657 synchronized (mPidsSelfLocked) { 10658 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10659 } 10660 fillInProcMemInfo(proc, outInfo); 10661 } 10662 } 10663 10664 @Override 10665 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10666 if (checkCallingPermission(android.Manifest.permission.DUMP) 10667 != PackageManager.PERMISSION_GRANTED) { 10668 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10669 + Binder.getCallingPid() 10670 + ", uid=" + Binder.getCallingUid() 10671 + " without permission " 10672 + android.Manifest.permission.DUMP); 10673 return; 10674 } 10675 10676 boolean dumpAll = false; 10677 boolean dumpClient = false; 10678 String dumpPackage = null; 10679 10680 int opti = 0; 10681 while (opti < args.length) { 10682 String opt = args[opti]; 10683 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10684 break; 10685 } 10686 opti++; 10687 if ("-a".equals(opt)) { 10688 dumpAll = true; 10689 } else if ("-c".equals(opt)) { 10690 dumpClient = true; 10691 } else if ("-h".equals(opt)) { 10692 pw.println("Activity manager dump options:"); 10693 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10694 pw.println(" cmd may be one of:"); 10695 pw.println(" a[ctivities]: activity stack state"); 10696 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10697 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10698 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10699 pw.println(" o[om]: out of memory management"); 10700 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10701 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10702 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10703 pw.println(" service [COMP_SPEC]: service client-side state"); 10704 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10705 pw.println(" all: dump all activities"); 10706 pw.println(" top: dump the top activity"); 10707 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10708 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10709 pw.println(" a partial substring in a component name, a"); 10710 pw.println(" hex object identifier."); 10711 pw.println(" -a: include all available server state."); 10712 pw.println(" -c: include client state."); 10713 return; 10714 } else { 10715 pw.println("Unknown argument: " + opt + "; use -h for help"); 10716 } 10717 } 10718 10719 long origId = Binder.clearCallingIdentity(); 10720 boolean more = false; 10721 // Is the caller requesting to dump a particular piece of data? 10722 if (opti < args.length) { 10723 String cmd = args[opti]; 10724 opti++; 10725 if ("activities".equals(cmd) || "a".equals(cmd)) { 10726 synchronized (this) { 10727 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10728 } 10729 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10730 String[] newArgs; 10731 String name; 10732 if (opti >= args.length) { 10733 name = null; 10734 newArgs = EMPTY_STRING_ARRAY; 10735 } else { 10736 name = args[opti]; 10737 opti++; 10738 newArgs = new String[args.length - opti]; 10739 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10740 args.length - opti); 10741 } 10742 synchronized (this) { 10743 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10744 } 10745 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10746 String[] newArgs; 10747 String name; 10748 if (opti >= args.length) { 10749 name = null; 10750 newArgs = EMPTY_STRING_ARRAY; 10751 } else { 10752 name = args[opti]; 10753 opti++; 10754 newArgs = new String[args.length - opti]; 10755 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10756 args.length - opti); 10757 } 10758 synchronized (this) { 10759 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10760 } 10761 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10762 String[] newArgs; 10763 String name; 10764 if (opti >= args.length) { 10765 name = null; 10766 newArgs = EMPTY_STRING_ARRAY; 10767 } else { 10768 name = args[opti]; 10769 opti++; 10770 newArgs = new String[args.length - opti]; 10771 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10772 args.length - opti); 10773 } 10774 synchronized (this) { 10775 dumpProcessesLocked(fd, pw, args, opti, true, name); 10776 } 10777 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10778 synchronized (this) { 10779 dumpOomLocked(fd, pw, args, opti, true); 10780 } 10781 } else if ("provider".equals(cmd)) { 10782 String[] newArgs; 10783 String name; 10784 if (opti >= args.length) { 10785 name = null; 10786 newArgs = EMPTY_STRING_ARRAY; 10787 } else { 10788 name = args[opti]; 10789 opti++; 10790 newArgs = new String[args.length - opti]; 10791 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10792 } 10793 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10794 pw.println("No providers match: " + name); 10795 pw.println("Use -h for help."); 10796 } 10797 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10798 synchronized (this) { 10799 dumpProvidersLocked(fd, pw, args, opti, true, null); 10800 } 10801 } else if ("service".equals(cmd)) { 10802 String[] newArgs; 10803 String name; 10804 if (opti >= args.length) { 10805 name = null; 10806 newArgs = EMPTY_STRING_ARRAY; 10807 } else { 10808 name = args[opti]; 10809 opti++; 10810 newArgs = new String[args.length - opti]; 10811 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10812 args.length - opti); 10813 } 10814 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10815 pw.println("No services match: " + name); 10816 pw.println("Use -h for help."); 10817 } 10818 } else if ("package".equals(cmd)) { 10819 String[] newArgs; 10820 if (opti >= args.length) { 10821 pw.println("package: no package name specified"); 10822 pw.println("Use -h for help."); 10823 } else { 10824 dumpPackage = args[opti]; 10825 opti++; 10826 newArgs = new String[args.length - opti]; 10827 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10828 args.length - opti); 10829 args = newArgs; 10830 opti = 0; 10831 more = true; 10832 } 10833 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10834 synchronized (this) { 10835 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10836 } 10837 } else { 10838 // Dumping a single activity? 10839 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10840 pw.println("Bad activity command, or no activities match: " + cmd); 10841 pw.println("Use -h for help."); 10842 } 10843 } 10844 if (!more) { 10845 Binder.restoreCallingIdentity(origId); 10846 return; 10847 } 10848 } 10849 10850 // No piece of data specified, dump everything. 10851 synchronized (this) { 10852 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10853 pw.println(); 10854 if (dumpAll) { 10855 pw.println("-------------------------------------------------------------------------------"); 10856 } 10857 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10858 pw.println(); 10859 if (dumpAll) { 10860 pw.println("-------------------------------------------------------------------------------"); 10861 } 10862 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10863 pw.println(); 10864 if (dumpAll) { 10865 pw.println("-------------------------------------------------------------------------------"); 10866 } 10867 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10868 pw.println(); 10869 if (dumpAll) { 10870 pw.println("-------------------------------------------------------------------------------"); 10871 } 10872 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10873 pw.println(); 10874 if (dumpAll) { 10875 pw.println("-------------------------------------------------------------------------------"); 10876 } 10877 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10878 } 10879 Binder.restoreCallingIdentity(origId); 10880 } 10881 10882 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10883 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10884 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10885 10886 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10887 dumpPackage); 10888 boolean needSep = printedAnything; 10889 10890 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10891 dumpPackage, needSep, " mFocusedActivity: "); 10892 if (printed) { 10893 printedAnything = true; 10894 needSep = false; 10895 } 10896 10897 if (dumpPackage == null) { 10898 if (needSep) { 10899 pw.println(); 10900 } 10901 needSep = true; 10902 printedAnything = true; 10903 mStackSupervisor.dump(pw, " "); 10904 } 10905 10906 if (mRecentTasks.size() > 0) { 10907 boolean printedHeader = false; 10908 10909 final int N = mRecentTasks.size(); 10910 for (int i=0; i<N; i++) { 10911 TaskRecord tr = mRecentTasks.get(i); 10912 if (dumpPackage != null) { 10913 if (tr.realActivity == null || 10914 !dumpPackage.equals(tr.realActivity)) { 10915 continue; 10916 } 10917 } 10918 if (!printedHeader) { 10919 if (needSep) { 10920 pw.println(); 10921 } 10922 pw.println(" Recent tasks:"); 10923 printedHeader = true; 10924 printedAnything = true; 10925 } 10926 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10927 pw.println(tr); 10928 if (dumpAll) { 10929 mRecentTasks.get(i).dump(pw, " "); 10930 } 10931 } 10932 } 10933 10934 if (!printedAnything) { 10935 pw.println(" (nothing)"); 10936 } 10937 } 10938 10939 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10940 int opti, boolean dumpAll, String dumpPackage) { 10941 boolean needSep = false; 10942 boolean printedAnything = false; 10943 int numPers = 0; 10944 10945 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10946 10947 if (dumpAll) { 10948 final int NP = mProcessNames.getMap().size(); 10949 for (int ip=0; ip<NP; ip++) { 10950 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10951 final int NA = procs.size(); 10952 for (int ia=0; ia<NA; ia++) { 10953 ProcessRecord r = procs.valueAt(ia); 10954 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10955 continue; 10956 } 10957 if (!needSep) { 10958 pw.println(" All known processes:"); 10959 needSep = true; 10960 printedAnything = true; 10961 } 10962 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10963 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10964 pw.print(" "); pw.println(r); 10965 r.dump(pw, " "); 10966 if (r.persistent) { 10967 numPers++; 10968 } 10969 } 10970 } 10971 } 10972 10973 if (mIsolatedProcesses.size() > 0) { 10974 boolean printed = false; 10975 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10976 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10977 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10978 continue; 10979 } 10980 if (!printed) { 10981 if (needSep) { 10982 pw.println(); 10983 } 10984 pw.println(" Isolated process list (sorted by uid):"); 10985 printedAnything = true; 10986 printed = true; 10987 needSep = true; 10988 } 10989 pw.println(String.format("%sIsolated #%2d: %s", 10990 " ", i, r.toString())); 10991 } 10992 } 10993 10994 if (mLruProcesses.size() > 0) { 10995 if (needSep) { 10996 pw.println(); 10997 } 10998 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10999 pw.print(" total, non-act at "); 11000 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11001 pw.print(", non-svc at "); 11002 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11003 pw.println("):"); 11004 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11005 needSep = true; 11006 printedAnything = true; 11007 } 11008 11009 if (dumpAll || dumpPackage != null) { 11010 synchronized (mPidsSelfLocked) { 11011 boolean printed = false; 11012 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11013 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11014 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11015 continue; 11016 } 11017 if (!printed) { 11018 if (needSep) pw.println(); 11019 needSep = true; 11020 pw.println(" PID mappings:"); 11021 printed = true; 11022 printedAnything = true; 11023 } 11024 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11025 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11026 } 11027 } 11028 } 11029 11030 if (mForegroundProcesses.size() > 0) { 11031 synchronized (mPidsSelfLocked) { 11032 boolean printed = false; 11033 for (int i=0; i<mForegroundProcesses.size(); i++) { 11034 ProcessRecord r = mPidsSelfLocked.get( 11035 mForegroundProcesses.valueAt(i).pid); 11036 if (dumpPackage != null && (r == null 11037 || !r.pkgList.containsKey(dumpPackage))) { 11038 continue; 11039 } 11040 if (!printed) { 11041 if (needSep) pw.println(); 11042 needSep = true; 11043 pw.println(" Foreground Processes:"); 11044 printed = true; 11045 printedAnything = true; 11046 } 11047 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11048 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11049 } 11050 } 11051 } 11052 11053 if (mPersistentStartingProcesses.size() > 0) { 11054 if (needSep) pw.println(); 11055 needSep = true; 11056 printedAnything = true; 11057 pw.println(" Persisent processes that are starting:"); 11058 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11059 "Starting Norm", "Restarting PERS", dumpPackage); 11060 } 11061 11062 if (mRemovedProcesses.size() > 0) { 11063 if (needSep) pw.println(); 11064 needSep = true; 11065 printedAnything = true; 11066 pw.println(" Processes that are being removed:"); 11067 dumpProcessList(pw, this, mRemovedProcesses, " ", 11068 "Removed Norm", "Removed PERS", dumpPackage); 11069 } 11070 11071 if (mProcessesOnHold.size() > 0) { 11072 if (needSep) pw.println(); 11073 needSep = true; 11074 printedAnything = true; 11075 pw.println(" Processes that are on old until the system is ready:"); 11076 dumpProcessList(pw, this, mProcessesOnHold, " ", 11077 "OnHold Norm", "OnHold PERS", dumpPackage); 11078 } 11079 11080 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11081 11082 if (mProcessCrashTimes.getMap().size() > 0) { 11083 boolean printed = false; 11084 long now = SystemClock.uptimeMillis(); 11085 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11086 final int NP = pmap.size(); 11087 for (int ip=0; ip<NP; ip++) { 11088 String pname = pmap.keyAt(ip); 11089 SparseArray<Long> uids = pmap.valueAt(ip); 11090 final int N = uids.size(); 11091 for (int i=0; i<N; i++) { 11092 int puid = uids.keyAt(i); 11093 ProcessRecord r = mProcessNames.get(pname, puid); 11094 if (dumpPackage != null && (r == null 11095 || !r.pkgList.containsKey(dumpPackage))) { 11096 continue; 11097 } 11098 if (!printed) { 11099 if (needSep) pw.println(); 11100 needSep = true; 11101 pw.println(" Time since processes crashed:"); 11102 printed = true; 11103 printedAnything = true; 11104 } 11105 pw.print(" Process "); pw.print(pname); 11106 pw.print(" uid "); pw.print(puid); 11107 pw.print(": last crashed "); 11108 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11109 pw.println(" ago"); 11110 } 11111 } 11112 } 11113 11114 if (mBadProcesses.getMap().size() > 0) { 11115 boolean printed = false; 11116 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11117 final int NP = pmap.size(); 11118 for (int ip=0; ip<NP; ip++) { 11119 String pname = pmap.keyAt(ip); 11120 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11121 final int N = uids.size(); 11122 for (int i=0; i<N; i++) { 11123 int puid = uids.keyAt(i); 11124 ProcessRecord r = mProcessNames.get(pname, puid); 11125 if (dumpPackage != null && (r == null 11126 || !r.pkgList.containsKey(dumpPackage))) { 11127 continue; 11128 } 11129 if (!printed) { 11130 if (needSep) pw.println(); 11131 needSep = true; 11132 pw.println(" Bad processes:"); 11133 printedAnything = true; 11134 } 11135 BadProcessInfo info = uids.valueAt(i); 11136 pw.print(" Bad process "); pw.print(pname); 11137 pw.print(" uid "); pw.print(puid); 11138 pw.print(": crashed at time "); pw.println(info.time); 11139 if (info.shortMsg != null) { 11140 pw.print(" Short msg: "); pw.println(info.shortMsg); 11141 } 11142 if (info.longMsg != null) { 11143 pw.print(" Long msg: "); pw.println(info.longMsg); 11144 } 11145 if (info.stack != null) { 11146 pw.println(" Stack:"); 11147 int lastPos = 0; 11148 for (int pos=0; pos<info.stack.length(); pos++) { 11149 if (info.stack.charAt(pos) == '\n') { 11150 pw.print(" "); 11151 pw.write(info.stack, lastPos, pos-lastPos); 11152 pw.println(); 11153 lastPos = pos+1; 11154 } 11155 } 11156 if (lastPos < info.stack.length()) { 11157 pw.print(" "); 11158 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11159 pw.println(); 11160 } 11161 } 11162 } 11163 } 11164 } 11165 11166 if (dumpPackage == null) { 11167 pw.println(); 11168 needSep = false; 11169 pw.println(" mStartedUsers:"); 11170 for (int i=0; i<mStartedUsers.size(); i++) { 11171 UserStartedState uss = mStartedUsers.valueAt(i); 11172 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11173 pw.print(": "); uss.dump("", pw); 11174 } 11175 pw.print(" mStartedUserArray: ["); 11176 for (int i=0; i<mStartedUserArray.length; i++) { 11177 if (i > 0) pw.print(", "); 11178 pw.print(mStartedUserArray[i]); 11179 } 11180 pw.println("]"); 11181 pw.print(" mUserLru: ["); 11182 for (int i=0; i<mUserLru.size(); i++) { 11183 if (i > 0) pw.print(", "); 11184 pw.print(mUserLru.get(i)); 11185 } 11186 pw.println("]"); 11187 if (dumpAll) { 11188 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11189 } 11190 } 11191 if (mHomeProcess != null && (dumpPackage == null 11192 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11193 if (needSep) { 11194 pw.println(); 11195 needSep = false; 11196 } 11197 pw.println(" mHomeProcess: " + mHomeProcess); 11198 } 11199 if (mPreviousProcess != null && (dumpPackage == null 11200 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11201 if (needSep) { 11202 pw.println(); 11203 needSep = false; 11204 } 11205 pw.println(" mPreviousProcess: " + mPreviousProcess); 11206 } 11207 if (dumpAll) { 11208 StringBuilder sb = new StringBuilder(128); 11209 sb.append(" mPreviousProcessVisibleTime: "); 11210 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11211 pw.println(sb); 11212 } 11213 if (mHeavyWeightProcess != null && (dumpPackage == null 11214 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11215 if (needSep) { 11216 pw.println(); 11217 needSep = false; 11218 } 11219 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11220 } 11221 if (dumpPackage == null) { 11222 pw.println(" mConfiguration: " + mConfiguration); 11223 } 11224 if (dumpAll) { 11225 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11226 if (mCompatModePackages.getPackages().size() > 0) { 11227 boolean printed = false; 11228 for (Map.Entry<String, Integer> entry 11229 : mCompatModePackages.getPackages().entrySet()) { 11230 String pkg = entry.getKey(); 11231 int mode = entry.getValue(); 11232 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11233 continue; 11234 } 11235 if (!printed) { 11236 pw.println(" mScreenCompatPackages:"); 11237 printed = true; 11238 } 11239 pw.print(" "); pw.print(pkg); pw.print(": "); 11240 pw.print(mode); pw.println(); 11241 } 11242 } 11243 } 11244 if (dumpPackage == null) { 11245 if (mSleeping || mWentToSleep || mLockScreenShown) { 11246 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11247 + " mLockScreenShown " + mLockScreenShown); 11248 } 11249 if (mShuttingDown || mRunningVoice) { 11250 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11251 } 11252 } 11253 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11254 || mOrigWaitForDebugger) { 11255 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11256 || dumpPackage.equals(mOrigDebugApp)) { 11257 if (needSep) { 11258 pw.println(); 11259 needSep = false; 11260 } 11261 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11262 + " mDebugTransient=" + mDebugTransient 11263 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11264 } 11265 } 11266 if (mOpenGlTraceApp != null) { 11267 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11268 if (needSep) { 11269 pw.println(); 11270 needSep = false; 11271 } 11272 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11273 } 11274 } 11275 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11276 || mProfileFd != null) { 11277 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11278 if (needSep) { 11279 pw.println(); 11280 needSep = false; 11281 } 11282 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11283 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11284 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11285 + mAutoStopProfiler); 11286 } 11287 } 11288 if (dumpPackage == null) { 11289 if (mAlwaysFinishActivities || mController != null) { 11290 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11291 + " mController=" + mController); 11292 } 11293 if (dumpAll) { 11294 pw.println(" Total persistent processes: " + numPers); 11295 pw.println(" mProcessesReady=" + mProcessesReady 11296 + " mSystemReady=" + mSystemReady); 11297 pw.println(" mBooting=" + mBooting 11298 + " mBooted=" + mBooted 11299 + " mFactoryTest=" + mFactoryTest); 11300 pw.print(" mLastPowerCheckRealtime="); 11301 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11302 pw.println(""); 11303 pw.print(" mLastPowerCheckUptime="); 11304 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11305 pw.println(""); 11306 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11307 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11308 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11309 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11310 + " (" + mLruProcesses.size() + " total)" 11311 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11312 + " mNumServiceProcs=" + mNumServiceProcs 11313 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11314 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11315 + " mLastMemoryLevel" + mLastMemoryLevel 11316 + " mLastNumProcesses" + mLastNumProcesses); 11317 long now = SystemClock.uptimeMillis(); 11318 pw.print(" mLastIdleTime="); 11319 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11320 pw.print(" mLowRamSinceLastIdle="); 11321 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11322 pw.println(); 11323 } 11324 } 11325 11326 if (!printedAnything) { 11327 pw.println(" (nothing)"); 11328 } 11329 } 11330 11331 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11332 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11333 if (mProcessesToGc.size() > 0) { 11334 boolean printed = false; 11335 long now = SystemClock.uptimeMillis(); 11336 for (int i=0; i<mProcessesToGc.size(); i++) { 11337 ProcessRecord proc = mProcessesToGc.get(i); 11338 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11339 continue; 11340 } 11341 if (!printed) { 11342 if (needSep) pw.println(); 11343 needSep = true; 11344 pw.println(" Processes that are waiting to GC:"); 11345 printed = true; 11346 } 11347 pw.print(" Process "); pw.println(proc); 11348 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11349 pw.print(", last gced="); 11350 pw.print(now-proc.lastRequestedGc); 11351 pw.print(" ms ago, last lowMem="); 11352 pw.print(now-proc.lastLowMemory); 11353 pw.println(" ms ago"); 11354 11355 } 11356 } 11357 return needSep; 11358 } 11359 11360 void printOomLevel(PrintWriter pw, String name, int adj) { 11361 pw.print(" "); 11362 if (adj >= 0) { 11363 pw.print(' '); 11364 if (adj < 10) pw.print(' '); 11365 } else { 11366 if (adj > -10) pw.print(' '); 11367 } 11368 pw.print(adj); 11369 pw.print(": "); 11370 pw.print(name); 11371 pw.print(" ("); 11372 pw.print(mProcessList.getMemLevel(adj)/1024); 11373 pw.println(" kB)"); 11374 } 11375 11376 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11377 int opti, boolean dumpAll) { 11378 boolean needSep = false; 11379 11380 if (mLruProcesses.size() > 0) { 11381 if (needSep) pw.println(); 11382 needSep = true; 11383 pw.println(" OOM levels:"); 11384 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11385 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11386 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11387 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11388 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11389 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11390 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11391 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11392 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11393 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11394 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11395 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11396 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11397 11398 if (needSep) pw.println(); 11399 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11400 pw.print(" total, non-act at "); 11401 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11402 pw.print(", non-svc at "); 11403 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11404 pw.println("):"); 11405 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11406 needSep = true; 11407 } 11408 11409 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11410 11411 pw.println(); 11412 pw.println(" mHomeProcess: " + mHomeProcess); 11413 pw.println(" mPreviousProcess: " + mPreviousProcess); 11414 if (mHeavyWeightProcess != null) { 11415 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11416 } 11417 11418 return true; 11419 } 11420 11421 /** 11422 * There are three ways to call this: 11423 * - no provider specified: dump all the providers 11424 * - a flattened component name that matched an existing provider was specified as the 11425 * first arg: dump that one provider 11426 * - the first arg isn't the flattened component name of an existing provider: 11427 * dump all providers whose component contains the first arg as a substring 11428 */ 11429 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11430 int opti, boolean dumpAll) { 11431 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11432 } 11433 11434 static class ItemMatcher { 11435 ArrayList<ComponentName> components; 11436 ArrayList<String> strings; 11437 ArrayList<Integer> objects; 11438 boolean all; 11439 11440 ItemMatcher() { 11441 all = true; 11442 } 11443 11444 void build(String name) { 11445 ComponentName componentName = ComponentName.unflattenFromString(name); 11446 if (componentName != null) { 11447 if (components == null) { 11448 components = new ArrayList<ComponentName>(); 11449 } 11450 components.add(componentName); 11451 all = false; 11452 } else { 11453 int objectId = 0; 11454 // Not a '/' separated full component name; maybe an object ID? 11455 try { 11456 objectId = Integer.parseInt(name, 16); 11457 if (objects == null) { 11458 objects = new ArrayList<Integer>(); 11459 } 11460 objects.add(objectId); 11461 all = false; 11462 } catch (RuntimeException e) { 11463 // Not an integer; just do string match. 11464 if (strings == null) { 11465 strings = new ArrayList<String>(); 11466 } 11467 strings.add(name); 11468 all = false; 11469 } 11470 } 11471 } 11472 11473 int build(String[] args, int opti) { 11474 for (; opti<args.length; opti++) { 11475 String name = args[opti]; 11476 if ("--".equals(name)) { 11477 return opti+1; 11478 } 11479 build(name); 11480 } 11481 return opti; 11482 } 11483 11484 boolean match(Object object, ComponentName comp) { 11485 if (all) { 11486 return true; 11487 } 11488 if (components != null) { 11489 for (int i=0; i<components.size(); i++) { 11490 if (components.get(i).equals(comp)) { 11491 return true; 11492 } 11493 } 11494 } 11495 if (objects != null) { 11496 for (int i=0; i<objects.size(); i++) { 11497 if (System.identityHashCode(object) == objects.get(i)) { 11498 return true; 11499 } 11500 } 11501 } 11502 if (strings != null) { 11503 String flat = comp.flattenToString(); 11504 for (int i=0; i<strings.size(); i++) { 11505 if (flat.contains(strings.get(i))) { 11506 return true; 11507 } 11508 } 11509 } 11510 return false; 11511 } 11512 } 11513 11514 /** 11515 * There are three things that cmd can be: 11516 * - a flattened component name that matches an existing activity 11517 * - the cmd arg isn't the flattened component name of an existing activity: 11518 * dump all activity whose component contains the cmd as a substring 11519 * - A hex number of the ActivityRecord object instance. 11520 */ 11521 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11522 int opti, boolean dumpAll) { 11523 ArrayList<ActivityRecord> activities; 11524 11525 synchronized (this) { 11526 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11527 } 11528 11529 if (activities.size() <= 0) { 11530 return false; 11531 } 11532 11533 String[] newArgs = new String[args.length - opti]; 11534 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11535 11536 TaskRecord lastTask = null; 11537 boolean needSep = false; 11538 for (int i=activities.size()-1; i>=0; i--) { 11539 ActivityRecord r = activities.get(i); 11540 if (needSep) { 11541 pw.println(); 11542 } 11543 needSep = true; 11544 synchronized (this) { 11545 if (lastTask != r.task) { 11546 lastTask = r.task; 11547 pw.print("TASK "); pw.print(lastTask.affinity); 11548 pw.print(" id="); pw.println(lastTask.taskId); 11549 if (dumpAll) { 11550 lastTask.dump(pw, " "); 11551 } 11552 } 11553 } 11554 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11555 } 11556 return true; 11557 } 11558 11559 /** 11560 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11561 * there is a thread associated with the activity. 11562 */ 11563 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11564 final ActivityRecord r, String[] args, boolean dumpAll) { 11565 String innerPrefix = prefix + " "; 11566 synchronized (this) { 11567 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11568 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11569 pw.print(" pid="); 11570 if (r.app != null) pw.println(r.app.pid); 11571 else pw.println("(not running)"); 11572 if (dumpAll) { 11573 r.dump(pw, innerPrefix); 11574 } 11575 } 11576 if (r.app != null && r.app.thread != null) { 11577 // flush anything that is already in the PrintWriter since the thread is going 11578 // to write to the file descriptor directly 11579 pw.flush(); 11580 try { 11581 TransferPipe tp = new TransferPipe(); 11582 try { 11583 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11584 r.appToken, innerPrefix, args); 11585 tp.go(fd); 11586 } finally { 11587 tp.kill(); 11588 } 11589 } catch (IOException e) { 11590 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11591 } catch (RemoteException e) { 11592 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11593 } 11594 } 11595 } 11596 11597 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11598 int opti, boolean dumpAll, String dumpPackage) { 11599 boolean needSep = false; 11600 boolean onlyHistory = false; 11601 boolean printedAnything = false; 11602 11603 if ("history".equals(dumpPackage)) { 11604 if (opti < args.length && "-s".equals(args[opti])) { 11605 dumpAll = false; 11606 } 11607 onlyHistory = true; 11608 dumpPackage = null; 11609 } 11610 11611 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11612 if (!onlyHistory && dumpAll) { 11613 if (mRegisteredReceivers.size() > 0) { 11614 boolean printed = false; 11615 Iterator it = mRegisteredReceivers.values().iterator(); 11616 while (it.hasNext()) { 11617 ReceiverList r = (ReceiverList)it.next(); 11618 if (dumpPackage != null && (r.app == null || 11619 !dumpPackage.equals(r.app.info.packageName))) { 11620 continue; 11621 } 11622 if (!printed) { 11623 pw.println(" Registered Receivers:"); 11624 needSep = true; 11625 printed = true; 11626 printedAnything = true; 11627 } 11628 pw.print(" * "); pw.println(r); 11629 r.dump(pw, " "); 11630 } 11631 } 11632 11633 if (mReceiverResolver.dump(pw, needSep ? 11634 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11635 " ", dumpPackage, false)) { 11636 needSep = true; 11637 printedAnything = true; 11638 } 11639 } 11640 11641 for (BroadcastQueue q : mBroadcastQueues) { 11642 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11643 printedAnything |= needSep; 11644 } 11645 11646 needSep = true; 11647 11648 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11649 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11650 if (needSep) { 11651 pw.println(); 11652 } 11653 needSep = true; 11654 printedAnything = true; 11655 pw.print(" Sticky broadcasts for user "); 11656 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11657 StringBuilder sb = new StringBuilder(128); 11658 for (Map.Entry<String, ArrayList<Intent>> ent 11659 : mStickyBroadcasts.valueAt(user).entrySet()) { 11660 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11661 if (dumpAll) { 11662 pw.println(":"); 11663 ArrayList<Intent> intents = ent.getValue(); 11664 final int N = intents.size(); 11665 for (int i=0; i<N; i++) { 11666 sb.setLength(0); 11667 sb.append(" Intent: "); 11668 intents.get(i).toShortString(sb, false, true, false, false); 11669 pw.println(sb.toString()); 11670 Bundle bundle = intents.get(i).getExtras(); 11671 if (bundle != null) { 11672 pw.print(" "); 11673 pw.println(bundle.toString()); 11674 } 11675 } 11676 } else { 11677 pw.println(""); 11678 } 11679 } 11680 } 11681 } 11682 11683 if (!onlyHistory && dumpAll) { 11684 pw.println(); 11685 for (BroadcastQueue queue : mBroadcastQueues) { 11686 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11687 + queue.mBroadcastsScheduled); 11688 } 11689 pw.println(" mHandler:"); 11690 mHandler.dump(new PrintWriterPrinter(pw), " "); 11691 needSep = true; 11692 printedAnything = true; 11693 } 11694 11695 if (!printedAnything) { 11696 pw.println(" (nothing)"); 11697 } 11698 } 11699 11700 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11701 int opti, boolean dumpAll, String dumpPackage) { 11702 boolean needSep; 11703 boolean printedAnything = false; 11704 11705 ItemMatcher matcher = new ItemMatcher(); 11706 matcher.build(args, opti); 11707 11708 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11709 11710 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11711 printedAnything |= needSep; 11712 11713 if (mLaunchingProviders.size() > 0) { 11714 boolean printed = false; 11715 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11716 ContentProviderRecord r = mLaunchingProviders.get(i); 11717 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11718 continue; 11719 } 11720 if (!printed) { 11721 if (needSep) pw.println(); 11722 needSep = true; 11723 pw.println(" Launching content providers:"); 11724 printed = true; 11725 printedAnything = true; 11726 } 11727 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11728 pw.println(r); 11729 } 11730 } 11731 11732 if (mGrantedUriPermissions.size() > 0) { 11733 boolean printed = false; 11734 int dumpUid = -2; 11735 if (dumpPackage != null) { 11736 try { 11737 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11738 } catch (NameNotFoundException e) { 11739 dumpUid = -1; 11740 } 11741 } 11742 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11743 int uid = mGrantedUriPermissions.keyAt(i); 11744 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11745 continue; 11746 } 11747 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11748 if (!printed) { 11749 if (needSep) pw.println(); 11750 needSep = true; 11751 pw.println(" Granted Uri Permissions:"); 11752 printed = true; 11753 printedAnything = true; 11754 } 11755 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11756 for (UriPermission perm : perms.values()) { 11757 pw.print(" "); pw.println(perm); 11758 if (dumpAll) { 11759 perm.dump(pw, " "); 11760 } 11761 } 11762 } 11763 } 11764 11765 if (!printedAnything) { 11766 pw.println(" (nothing)"); 11767 } 11768 } 11769 11770 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11771 int opti, boolean dumpAll, String dumpPackage) { 11772 boolean printed = false; 11773 11774 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11775 11776 if (mIntentSenderRecords.size() > 0) { 11777 Iterator<WeakReference<PendingIntentRecord>> it 11778 = mIntentSenderRecords.values().iterator(); 11779 while (it.hasNext()) { 11780 WeakReference<PendingIntentRecord> ref = it.next(); 11781 PendingIntentRecord rec = ref != null ? ref.get(): null; 11782 if (dumpPackage != null && (rec == null 11783 || !dumpPackage.equals(rec.key.packageName))) { 11784 continue; 11785 } 11786 printed = true; 11787 if (rec != null) { 11788 pw.print(" * "); pw.println(rec); 11789 if (dumpAll) { 11790 rec.dump(pw, " "); 11791 } 11792 } else { 11793 pw.print(" * "); pw.println(ref); 11794 } 11795 } 11796 } 11797 11798 if (!printed) { 11799 pw.println(" (nothing)"); 11800 } 11801 } 11802 11803 private static final int dumpProcessList(PrintWriter pw, 11804 ActivityManagerService service, List list, 11805 String prefix, String normalLabel, String persistentLabel, 11806 String dumpPackage) { 11807 int numPers = 0; 11808 final int N = list.size()-1; 11809 for (int i=N; i>=0; i--) { 11810 ProcessRecord r = (ProcessRecord)list.get(i); 11811 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11812 continue; 11813 } 11814 pw.println(String.format("%s%s #%2d: %s", 11815 prefix, (r.persistent ? persistentLabel : normalLabel), 11816 i, r.toString())); 11817 if (r.persistent) { 11818 numPers++; 11819 } 11820 } 11821 return numPers; 11822 } 11823 11824 private static final boolean dumpProcessOomList(PrintWriter pw, 11825 ActivityManagerService service, List<ProcessRecord> origList, 11826 String prefix, String normalLabel, String persistentLabel, 11827 boolean inclDetails, String dumpPackage) { 11828 11829 ArrayList<Pair<ProcessRecord, Integer>> list 11830 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11831 for (int i=0; i<origList.size(); i++) { 11832 ProcessRecord r = origList.get(i); 11833 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11834 continue; 11835 } 11836 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11837 } 11838 11839 if (list.size() <= 0) { 11840 return false; 11841 } 11842 11843 Comparator<Pair<ProcessRecord, Integer>> comparator 11844 = new Comparator<Pair<ProcessRecord, Integer>>() { 11845 @Override 11846 public int compare(Pair<ProcessRecord, Integer> object1, 11847 Pair<ProcessRecord, Integer> object2) { 11848 if (object1.first.setAdj != object2.first.setAdj) { 11849 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11850 } 11851 if (object1.second.intValue() != object2.second.intValue()) { 11852 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11853 } 11854 return 0; 11855 } 11856 }; 11857 11858 Collections.sort(list, comparator); 11859 11860 final long curRealtime = SystemClock.elapsedRealtime(); 11861 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11862 final long curUptime = SystemClock.uptimeMillis(); 11863 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11864 11865 for (int i=list.size()-1; i>=0; i--) { 11866 ProcessRecord r = list.get(i).first; 11867 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11868 char schedGroup; 11869 switch (r.setSchedGroup) { 11870 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11871 schedGroup = 'B'; 11872 break; 11873 case Process.THREAD_GROUP_DEFAULT: 11874 schedGroup = 'F'; 11875 break; 11876 default: 11877 schedGroup = '?'; 11878 break; 11879 } 11880 char foreground; 11881 if (r.foregroundActivities) { 11882 foreground = 'A'; 11883 } else if (r.foregroundServices) { 11884 foreground = 'S'; 11885 } else { 11886 foreground = ' '; 11887 } 11888 String procState = ProcessList.makeProcStateString(r.curProcState); 11889 pw.print(prefix); 11890 pw.print(r.persistent ? persistentLabel : normalLabel); 11891 pw.print(" #"); 11892 int num = (origList.size()-1)-list.get(i).second; 11893 if (num < 10) pw.print(' '); 11894 pw.print(num); 11895 pw.print(": "); 11896 pw.print(oomAdj); 11897 pw.print(' '); 11898 pw.print(schedGroup); 11899 pw.print('/'); 11900 pw.print(foreground); 11901 pw.print('/'); 11902 pw.print(procState); 11903 pw.print(" trm:"); 11904 if (r.trimMemoryLevel < 10) pw.print(' '); 11905 pw.print(r.trimMemoryLevel); 11906 pw.print(' '); 11907 pw.print(r.toShortString()); 11908 pw.print(" ("); 11909 pw.print(r.adjType); 11910 pw.println(')'); 11911 if (r.adjSource != null || r.adjTarget != null) { 11912 pw.print(prefix); 11913 pw.print(" "); 11914 if (r.adjTarget instanceof ComponentName) { 11915 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11916 } else if (r.adjTarget != null) { 11917 pw.print(r.adjTarget.toString()); 11918 } else { 11919 pw.print("{null}"); 11920 } 11921 pw.print("<="); 11922 if (r.adjSource instanceof ProcessRecord) { 11923 pw.print("Proc{"); 11924 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11925 pw.println("}"); 11926 } else if (r.adjSource != null) { 11927 pw.println(r.adjSource.toString()); 11928 } else { 11929 pw.println("{null}"); 11930 } 11931 } 11932 if (inclDetails) { 11933 pw.print(prefix); 11934 pw.print(" "); 11935 pw.print("oom: max="); pw.print(r.maxAdj); 11936 pw.print(" curRaw="); pw.print(r.curRawAdj); 11937 pw.print(" setRaw="); pw.print(r.setRawAdj); 11938 pw.print(" cur="); pw.print(r.curAdj); 11939 pw.print(" set="); pw.println(r.setAdj); 11940 pw.print(prefix); 11941 pw.print(" "); 11942 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11943 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11944 pw.print(" lastPss="); pw.print(r.lastPss); 11945 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11946 pw.print(prefix); 11947 pw.print(" "); 11948 pw.print("keeping="); pw.print(r.keeping); 11949 pw.print(" cached="); pw.print(r.cached); 11950 pw.print(" empty="); pw.print(r.empty); 11951 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11952 11953 if (!r.keeping) { 11954 if (r.lastWakeTime != 0) { 11955 long wtime; 11956 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11957 synchronized (stats) { 11958 wtime = stats.getProcessWakeTime(r.info.uid, 11959 r.pid, curRealtime); 11960 } 11961 long timeUsed = wtime - r.lastWakeTime; 11962 pw.print(prefix); 11963 pw.print(" "); 11964 pw.print("keep awake over "); 11965 TimeUtils.formatDuration(realtimeSince, pw); 11966 pw.print(" used "); 11967 TimeUtils.formatDuration(timeUsed, pw); 11968 pw.print(" ("); 11969 pw.print((timeUsed*100)/realtimeSince); 11970 pw.println("%)"); 11971 } 11972 if (r.lastCpuTime != 0) { 11973 long timeUsed = r.curCpuTime - r.lastCpuTime; 11974 pw.print(prefix); 11975 pw.print(" "); 11976 pw.print("run cpu over "); 11977 TimeUtils.formatDuration(uptimeSince, pw); 11978 pw.print(" used "); 11979 TimeUtils.formatDuration(timeUsed, pw); 11980 pw.print(" ("); 11981 pw.print((timeUsed*100)/uptimeSince); 11982 pw.println("%)"); 11983 } 11984 } 11985 } 11986 } 11987 return true; 11988 } 11989 11990 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11991 ArrayList<ProcessRecord> procs; 11992 synchronized (this) { 11993 if (args != null && args.length > start 11994 && args[start].charAt(0) != '-') { 11995 procs = new ArrayList<ProcessRecord>(); 11996 int pid = -1; 11997 try { 11998 pid = Integer.parseInt(args[start]); 11999 } catch (NumberFormatException e) { 12000 } 12001 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12002 ProcessRecord proc = mLruProcesses.get(i); 12003 if (proc.pid == pid) { 12004 procs.add(proc); 12005 } else if (proc.processName.equals(args[start])) { 12006 procs.add(proc); 12007 } 12008 } 12009 if (procs.size() <= 0) { 12010 return null; 12011 } 12012 } else { 12013 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12014 } 12015 } 12016 return procs; 12017 } 12018 12019 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12020 PrintWriter pw, String[] args) { 12021 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12022 if (procs == null) { 12023 pw.println("No process found for: " + args[0]); 12024 return; 12025 } 12026 12027 long uptime = SystemClock.uptimeMillis(); 12028 long realtime = SystemClock.elapsedRealtime(); 12029 pw.println("Applications Graphics Acceleration Info:"); 12030 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12031 12032 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12033 ProcessRecord r = procs.get(i); 12034 if (r.thread != null) { 12035 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12036 pw.flush(); 12037 try { 12038 TransferPipe tp = new TransferPipe(); 12039 try { 12040 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12041 tp.go(fd); 12042 } finally { 12043 tp.kill(); 12044 } 12045 } catch (IOException e) { 12046 pw.println("Failure while dumping the app: " + r); 12047 pw.flush(); 12048 } catch (RemoteException e) { 12049 pw.println("Got a RemoteException while dumping the app " + r); 12050 pw.flush(); 12051 } 12052 } 12053 } 12054 } 12055 12056 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12057 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12058 if (procs == null) { 12059 pw.println("No process found for: " + args[0]); 12060 return; 12061 } 12062 12063 pw.println("Applications Database Info:"); 12064 12065 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12066 ProcessRecord r = procs.get(i); 12067 if (r.thread != null) { 12068 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12069 pw.flush(); 12070 try { 12071 TransferPipe tp = new TransferPipe(); 12072 try { 12073 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12074 tp.go(fd); 12075 } finally { 12076 tp.kill(); 12077 } 12078 } catch (IOException e) { 12079 pw.println("Failure while dumping the app: " + r); 12080 pw.flush(); 12081 } catch (RemoteException e) { 12082 pw.println("Got a RemoteException while dumping the app " + r); 12083 pw.flush(); 12084 } 12085 } 12086 } 12087 } 12088 12089 final static class MemItem { 12090 final boolean isProc; 12091 final String label; 12092 final String shortLabel; 12093 final long pss; 12094 final int id; 12095 final boolean hasActivities; 12096 ArrayList<MemItem> subitems; 12097 12098 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12099 boolean _hasActivities) { 12100 isProc = true; 12101 label = _label; 12102 shortLabel = _shortLabel; 12103 pss = _pss; 12104 id = _id; 12105 hasActivities = _hasActivities; 12106 } 12107 12108 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12109 isProc = false; 12110 label = _label; 12111 shortLabel = _shortLabel; 12112 pss = _pss; 12113 id = _id; 12114 hasActivities = false; 12115 } 12116 } 12117 12118 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12119 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12120 if (sort && !isCompact) { 12121 Collections.sort(items, new Comparator<MemItem>() { 12122 @Override 12123 public int compare(MemItem lhs, MemItem rhs) { 12124 if (lhs.pss < rhs.pss) { 12125 return 1; 12126 } else if (lhs.pss > rhs.pss) { 12127 return -1; 12128 } 12129 return 0; 12130 } 12131 }); 12132 } 12133 12134 for (int i=0; i<items.size(); i++) { 12135 MemItem mi = items.get(i); 12136 if (!isCompact) { 12137 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12138 } else if (mi.isProc) { 12139 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12140 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12141 pw.println(mi.hasActivities ? ",a" : ",e"); 12142 } else { 12143 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12144 pw.println(mi.pss); 12145 } 12146 if (mi.subitems != null) { 12147 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12148 true, isCompact); 12149 } 12150 } 12151 } 12152 12153 // These are in KB. 12154 static final long[] DUMP_MEM_BUCKETS = new long[] { 12155 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12156 120*1024, 160*1024, 200*1024, 12157 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12158 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12159 }; 12160 12161 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12162 boolean stackLike) { 12163 int start = label.lastIndexOf('.'); 12164 if (start >= 0) start++; 12165 else start = 0; 12166 int end = label.length(); 12167 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12168 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12169 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12170 out.append(bucket); 12171 out.append(stackLike ? "MB." : "MB "); 12172 out.append(label, start, end); 12173 return; 12174 } 12175 } 12176 out.append(memKB/1024); 12177 out.append(stackLike ? "MB." : "MB "); 12178 out.append(label, start, end); 12179 } 12180 12181 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12182 ProcessList.NATIVE_ADJ, 12183 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12184 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12185 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12186 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12187 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12188 }; 12189 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12190 "Native", 12191 "System", "Persistent", "Foreground", 12192 "Visible", "Perceptible", 12193 "Heavy Weight", "Backup", 12194 "A Services", "Home", 12195 "Previous", "B Services", "Cached" 12196 }; 12197 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12198 "native", 12199 "sys", "pers", "fore", 12200 "vis", "percept", 12201 "heavy", "backup", 12202 "servicea", "home", 12203 "prev", "serviceb", "cached" 12204 }; 12205 12206 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12207 long realtime, boolean isCheckinRequest, boolean isCompact) { 12208 if (isCheckinRequest || isCompact) { 12209 // short checkin version 12210 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12211 } else { 12212 pw.println("Applications Memory Usage (kB):"); 12213 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12214 } 12215 } 12216 12217 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12218 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12219 boolean dumpDetails = false; 12220 boolean dumpFullDetails = false; 12221 boolean dumpDalvik = false; 12222 boolean oomOnly = false; 12223 boolean isCompact = false; 12224 boolean localOnly = false; 12225 12226 int opti = 0; 12227 while (opti < args.length) { 12228 String opt = args[opti]; 12229 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12230 break; 12231 } 12232 opti++; 12233 if ("-a".equals(opt)) { 12234 dumpDetails = true; 12235 dumpFullDetails = true; 12236 dumpDalvik = true; 12237 } else if ("-d".equals(opt)) { 12238 dumpDalvik = true; 12239 } else if ("-c".equals(opt)) { 12240 isCompact = true; 12241 } else if ("--oom".equals(opt)) { 12242 oomOnly = true; 12243 } else if ("--local".equals(opt)) { 12244 localOnly = true; 12245 } else if ("-h".equals(opt)) { 12246 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12247 pw.println(" -a: include all available information for each process."); 12248 pw.println(" -d: include dalvik details when dumping process details."); 12249 pw.println(" -c: dump in a compact machine-parseable representation."); 12250 pw.println(" --oom: only show processes organized by oom adj."); 12251 pw.println(" --local: only collect details locally, don't call process."); 12252 pw.println("If [process] is specified it can be the name or "); 12253 pw.println("pid of a specific process to dump."); 12254 return; 12255 } else { 12256 pw.println("Unknown argument: " + opt + "; use -h for help"); 12257 } 12258 } 12259 12260 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12261 long uptime = SystemClock.uptimeMillis(); 12262 long realtime = SystemClock.elapsedRealtime(); 12263 final long[] tmpLong = new long[1]; 12264 12265 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12266 if (procs == null) { 12267 // No Java processes. Maybe they want to print a native process. 12268 if (args != null && args.length > opti 12269 && args[opti].charAt(0) != '-') { 12270 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12271 = new ArrayList<ProcessCpuTracker.Stats>(); 12272 updateCpuStatsNow(); 12273 int findPid = -1; 12274 try { 12275 findPid = Integer.parseInt(args[opti]); 12276 } catch (NumberFormatException e) { 12277 } 12278 synchronized (mProcessCpuThread) { 12279 final int N = mProcessCpuTracker.countStats(); 12280 for (int i=0; i<N; i++) { 12281 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12282 if (st.pid == findPid || (st.baseName != null 12283 && st.baseName.equals(args[opti]))) { 12284 nativeProcs.add(st); 12285 } 12286 } 12287 } 12288 if (nativeProcs.size() > 0) { 12289 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12290 isCompact); 12291 Debug.MemoryInfo mi = null; 12292 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12293 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12294 final int pid = r.pid; 12295 if (!isCheckinRequest && dumpDetails) { 12296 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12297 } 12298 if (mi == null) { 12299 mi = new Debug.MemoryInfo(); 12300 } 12301 if (dumpDetails || (!brief && !oomOnly)) { 12302 Debug.getMemoryInfo(pid, mi); 12303 } else { 12304 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12305 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12306 } 12307 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12308 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12309 if (isCheckinRequest) { 12310 pw.println(); 12311 } 12312 } 12313 return; 12314 } 12315 } 12316 pw.println("No process found for: " + args[opti]); 12317 return; 12318 } 12319 12320 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12321 dumpDetails = true; 12322 } 12323 12324 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12325 12326 String[] innerArgs = new String[args.length-opti]; 12327 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12328 12329 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12330 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12331 long nativePss=0, dalvikPss=0, otherPss=0; 12332 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12333 12334 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12335 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12336 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12337 12338 long totalPss = 0; 12339 long cachedPss = 0; 12340 12341 Debug.MemoryInfo mi = null; 12342 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12343 final ProcessRecord r = procs.get(i); 12344 final IApplicationThread thread; 12345 final int pid; 12346 final int oomAdj; 12347 final boolean hasActivities; 12348 synchronized (this) { 12349 thread = r.thread; 12350 pid = r.pid; 12351 oomAdj = r.getSetAdjWithServices(); 12352 hasActivities = r.activities.size() > 0; 12353 } 12354 if (thread != null) { 12355 if (!isCheckinRequest && dumpDetails) { 12356 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12357 } 12358 if (mi == null) { 12359 mi = new Debug.MemoryInfo(); 12360 } 12361 if (dumpDetails || (!brief && !oomOnly)) { 12362 Debug.getMemoryInfo(pid, mi); 12363 } else { 12364 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12365 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12366 } 12367 if (dumpDetails) { 12368 if (localOnly) { 12369 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12370 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12371 if (isCheckinRequest) { 12372 pw.println(); 12373 } 12374 } else { 12375 try { 12376 pw.flush(); 12377 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12378 dumpDalvik, innerArgs); 12379 } catch (RemoteException e) { 12380 if (!isCheckinRequest) { 12381 pw.println("Got RemoteException!"); 12382 pw.flush(); 12383 } 12384 } 12385 } 12386 } 12387 12388 final long myTotalPss = mi.getTotalPss(); 12389 final long myTotalUss = mi.getTotalUss(); 12390 12391 synchronized (this) { 12392 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12393 // Record this for posterity if the process has been stable. 12394 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12395 } 12396 } 12397 12398 if (!isCheckinRequest && mi != null) { 12399 totalPss += myTotalPss; 12400 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12401 (hasActivities ? " / activities)" : ")"), 12402 r.processName, myTotalPss, pid, hasActivities); 12403 procMems.add(pssItem); 12404 procMemsMap.put(pid, pssItem); 12405 12406 nativePss += mi.nativePss; 12407 dalvikPss += mi.dalvikPss; 12408 otherPss += mi.otherPss; 12409 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12410 long mem = mi.getOtherPss(j); 12411 miscPss[j] += mem; 12412 otherPss -= mem; 12413 } 12414 12415 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12416 cachedPss += myTotalPss; 12417 } 12418 12419 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12420 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12421 || oomIndex == (oomPss.length-1)) { 12422 oomPss[oomIndex] += myTotalPss; 12423 if (oomProcs[oomIndex] == null) { 12424 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12425 } 12426 oomProcs[oomIndex].add(pssItem); 12427 break; 12428 } 12429 } 12430 } 12431 } 12432 } 12433 12434 if (!isCheckinRequest && procs.size() > 1) { 12435 // If we are showing aggregations, also look for native processes to 12436 // include so that our aggregations are more accurate. 12437 updateCpuStatsNow(); 12438 synchronized (mProcessCpuThread) { 12439 final int N = mProcessCpuTracker.countStats(); 12440 for (int i=0; i<N; i++) { 12441 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12442 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12443 if (mi == null) { 12444 mi = new Debug.MemoryInfo(); 12445 } 12446 if (!brief && !oomOnly) { 12447 Debug.getMemoryInfo(st.pid, mi); 12448 } else { 12449 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12450 mi.nativePrivateDirty = (int)tmpLong[0]; 12451 } 12452 12453 final long myTotalPss = mi.getTotalPss(); 12454 totalPss += myTotalPss; 12455 12456 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12457 st.name, myTotalPss, st.pid, false); 12458 procMems.add(pssItem); 12459 12460 nativePss += mi.nativePss; 12461 dalvikPss += mi.dalvikPss; 12462 otherPss += mi.otherPss; 12463 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12464 long mem = mi.getOtherPss(j); 12465 miscPss[j] += mem; 12466 otherPss -= mem; 12467 } 12468 oomPss[0] += myTotalPss; 12469 if (oomProcs[0] == null) { 12470 oomProcs[0] = new ArrayList<MemItem>(); 12471 } 12472 oomProcs[0].add(pssItem); 12473 } 12474 } 12475 } 12476 12477 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12478 12479 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12480 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12481 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12482 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12483 String label = Debug.MemoryInfo.getOtherLabel(j); 12484 catMems.add(new MemItem(label, label, miscPss[j], j)); 12485 } 12486 12487 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12488 for (int j=0; j<oomPss.length; j++) { 12489 if (oomPss[j] != 0) { 12490 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12491 : DUMP_MEM_OOM_LABEL[j]; 12492 MemItem item = new MemItem(label, label, oomPss[j], 12493 DUMP_MEM_OOM_ADJ[j]); 12494 item.subitems = oomProcs[j]; 12495 oomMems.add(item); 12496 } 12497 } 12498 12499 if (!brief && !oomOnly && !isCompact) { 12500 pw.println(); 12501 pw.println("Total PSS by process:"); 12502 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12503 pw.println(); 12504 } 12505 if (!isCompact) { 12506 pw.println("Total PSS by OOM adjustment:"); 12507 } 12508 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12509 if (!brief && !oomOnly) { 12510 PrintWriter out = categoryPw != null ? categoryPw : pw; 12511 if (!isCompact) { 12512 out.println(); 12513 out.println("Total PSS by category:"); 12514 } 12515 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12516 } 12517 if (!isCompact) { 12518 pw.println(); 12519 } 12520 MemInfoReader memInfo = new MemInfoReader(); 12521 memInfo.readMemInfo(); 12522 if (!brief) { 12523 if (!isCompact) { 12524 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12525 pw.print(" kB (status "); 12526 switch (mLastMemoryLevel) { 12527 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12528 pw.println("normal)"); 12529 break; 12530 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12531 pw.println("moderate)"); 12532 break; 12533 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12534 pw.println("low)"); 12535 break; 12536 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12537 pw.println("critical)"); 12538 break; 12539 default: 12540 pw.print(mLastMemoryLevel); 12541 pw.println(")"); 12542 break; 12543 } 12544 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12545 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12546 pw.print(cachedPss); pw.print(" cached pss + "); 12547 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12548 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12549 } else { 12550 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12551 pw.print(cachedPss + memInfo.getCachedSizeKb() 12552 + memInfo.getFreeSizeKb()); pw.print(","); 12553 pw.println(totalPss - cachedPss); 12554 } 12555 } 12556 if (!isCompact) { 12557 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12558 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12559 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12560 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12561 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12562 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12563 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12564 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12565 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12566 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12567 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12568 } 12569 if (!brief) { 12570 if (memInfo.getZramTotalSizeKb() != 0) { 12571 if (!isCompact) { 12572 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12573 pw.print(" kB physical used for "); 12574 pw.print(memInfo.getSwapTotalSizeKb() 12575 - memInfo.getSwapFreeSizeKb()); 12576 pw.print(" kB in swap ("); 12577 pw.print(memInfo.getSwapTotalSizeKb()); 12578 pw.println(" kB total swap)"); 12579 } else { 12580 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12581 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12582 pw.println(memInfo.getSwapFreeSizeKb()); 12583 } 12584 } 12585 final int[] SINGLE_LONG_FORMAT = new int[] { 12586 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12587 }; 12588 long[] longOut = new long[1]; 12589 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12590 SINGLE_LONG_FORMAT, null, longOut, null); 12591 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12592 longOut[0] = 0; 12593 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12594 SINGLE_LONG_FORMAT, null, longOut, null); 12595 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12596 longOut[0] = 0; 12597 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12598 SINGLE_LONG_FORMAT, null, longOut, null); 12599 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12600 longOut[0] = 0; 12601 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12602 SINGLE_LONG_FORMAT, null, longOut, null); 12603 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12604 if (!isCompact) { 12605 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12606 pw.print(" KSM: "); pw.print(sharing); 12607 pw.print(" kB saved from shared "); 12608 pw.print(shared); pw.println(" kB"); 12609 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12610 pw.print(voltile); pw.println(" kB volatile"); 12611 } 12612 pw.print(" Tuning: "); 12613 pw.print(ActivityManager.staticGetMemoryClass()); 12614 pw.print(" (large "); 12615 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12616 pw.print("), oom "); 12617 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12618 pw.print(" kB"); 12619 pw.print(", restore limit "); 12620 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12621 pw.print(" kB"); 12622 if (ActivityManager.isLowRamDeviceStatic()) { 12623 pw.print(" (low-ram)"); 12624 } 12625 if (ActivityManager.isHighEndGfx()) { 12626 pw.print(" (high-end-gfx)"); 12627 } 12628 pw.println(); 12629 } else { 12630 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12631 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12632 pw.println(voltile); 12633 pw.print("tuning,"); 12634 pw.print(ActivityManager.staticGetMemoryClass()); 12635 pw.print(','); 12636 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12637 pw.print(','); 12638 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12639 if (ActivityManager.isLowRamDeviceStatic()) { 12640 pw.print(",low-ram"); 12641 } 12642 if (ActivityManager.isHighEndGfx()) { 12643 pw.print(",high-end-gfx"); 12644 } 12645 pw.println(); 12646 } 12647 } 12648 } 12649 } 12650 12651 /** 12652 * Searches array of arguments for the specified string 12653 * @param args array of argument strings 12654 * @param value value to search for 12655 * @return true if the value is contained in the array 12656 */ 12657 private static boolean scanArgs(String[] args, String value) { 12658 if (args != null) { 12659 for (String arg : args) { 12660 if (value.equals(arg)) { 12661 return true; 12662 } 12663 } 12664 } 12665 return false; 12666 } 12667 12668 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12669 ContentProviderRecord cpr, boolean always) { 12670 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12671 12672 if (!inLaunching || always) { 12673 synchronized (cpr) { 12674 cpr.launchingApp = null; 12675 cpr.notifyAll(); 12676 } 12677 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12678 String names[] = cpr.info.authority.split(";"); 12679 for (int j = 0; j < names.length; j++) { 12680 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12681 } 12682 } 12683 12684 for (int i=0; i<cpr.connections.size(); i++) { 12685 ContentProviderConnection conn = cpr.connections.get(i); 12686 if (conn.waiting) { 12687 // If this connection is waiting for the provider, then we don't 12688 // need to mess with its process unless we are always removing 12689 // or for some reason the provider is not currently launching. 12690 if (inLaunching && !always) { 12691 continue; 12692 } 12693 } 12694 ProcessRecord capp = conn.client; 12695 conn.dead = true; 12696 if (conn.stableCount > 0) { 12697 if (!capp.persistent && capp.thread != null 12698 && capp.pid != 0 12699 && capp.pid != MY_PID) { 12700 killUnneededProcessLocked(capp, "depends on provider " 12701 + cpr.name.flattenToShortString() 12702 + " in dying proc " + (proc != null ? proc.processName : "??")); 12703 } 12704 } else if (capp.thread != null && conn.provider.provider != null) { 12705 try { 12706 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12707 } catch (RemoteException e) { 12708 } 12709 // In the protocol here, we don't expect the client to correctly 12710 // clean up this connection, we'll just remove it. 12711 cpr.connections.remove(i); 12712 conn.client.conProviders.remove(conn); 12713 } 12714 } 12715 12716 if (inLaunching && always) { 12717 mLaunchingProviders.remove(cpr); 12718 } 12719 return inLaunching; 12720 } 12721 12722 /** 12723 * Main code for cleaning up a process when it has gone away. This is 12724 * called both as a result of the process dying, or directly when stopping 12725 * a process when running in single process mode. 12726 */ 12727 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12728 boolean restarting, boolean allowRestart, int index) { 12729 if (index >= 0) { 12730 removeLruProcessLocked(app); 12731 ProcessList.remove(app.pid); 12732 } 12733 12734 mProcessesToGc.remove(app); 12735 mPendingPssProcesses.remove(app); 12736 12737 // Dismiss any open dialogs. 12738 if (app.crashDialog != null && !app.forceCrashReport) { 12739 app.crashDialog.dismiss(); 12740 app.crashDialog = null; 12741 } 12742 if (app.anrDialog != null) { 12743 app.anrDialog.dismiss(); 12744 app.anrDialog = null; 12745 } 12746 if (app.waitDialog != null) { 12747 app.waitDialog.dismiss(); 12748 app.waitDialog = null; 12749 } 12750 12751 app.crashing = false; 12752 app.notResponding = false; 12753 12754 app.resetPackageList(mProcessStats); 12755 app.unlinkDeathRecipient(); 12756 app.makeInactive(mProcessStats); 12757 app.forcingToForeground = null; 12758 updateProcessForegroundLocked(app, false, false); 12759 app.foregroundActivities = false; 12760 app.hasShownUi = false; 12761 app.treatLikeActivity = false; 12762 app.hasAboveClient = false; 12763 app.hasClientActivities = false; 12764 12765 mServices.killServicesLocked(app, allowRestart); 12766 12767 boolean restart = false; 12768 12769 // Remove published content providers. 12770 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12771 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12772 final boolean always = app.bad || !allowRestart; 12773 if (removeDyingProviderLocked(app, cpr, always) || always) { 12774 // We left the provider in the launching list, need to 12775 // restart it. 12776 restart = true; 12777 } 12778 12779 cpr.provider = null; 12780 cpr.proc = null; 12781 } 12782 app.pubProviders.clear(); 12783 12784 // Take care of any launching providers waiting for this process. 12785 if (checkAppInLaunchingProvidersLocked(app, false)) { 12786 restart = true; 12787 } 12788 12789 // Unregister from connected content providers. 12790 if (!app.conProviders.isEmpty()) { 12791 for (int i=0; i<app.conProviders.size(); i++) { 12792 ContentProviderConnection conn = app.conProviders.get(i); 12793 conn.provider.connections.remove(conn); 12794 } 12795 app.conProviders.clear(); 12796 } 12797 12798 // At this point there may be remaining entries in mLaunchingProviders 12799 // where we were the only one waiting, so they are no longer of use. 12800 // Look for these and clean up if found. 12801 // XXX Commented out for now. Trying to figure out a way to reproduce 12802 // the actual situation to identify what is actually going on. 12803 if (false) { 12804 for (int i=0; i<mLaunchingProviders.size(); i++) { 12805 ContentProviderRecord cpr = (ContentProviderRecord) 12806 mLaunchingProviders.get(i); 12807 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12808 synchronized (cpr) { 12809 cpr.launchingApp = null; 12810 cpr.notifyAll(); 12811 } 12812 } 12813 } 12814 } 12815 12816 skipCurrentReceiverLocked(app); 12817 12818 // Unregister any receivers. 12819 for (int i=app.receivers.size()-1; i>=0; i--) { 12820 removeReceiverLocked(app.receivers.valueAt(i)); 12821 } 12822 app.receivers.clear(); 12823 12824 // If the app is undergoing backup, tell the backup manager about it 12825 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12826 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12827 + mBackupTarget.appInfo + " died during backup"); 12828 try { 12829 IBackupManager bm = IBackupManager.Stub.asInterface( 12830 ServiceManager.getService(Context.BACKUP_SERVICE)); 12831 bm.agentDisconnected(app.info.packageName); 12832 } catch (RemoteException e) { 12833 // can't happen; backup manager is local 12834 } 12835 } 12836 12837 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12838 ProcessChangeItem item = mPendingProcessChanges.get(i); 12839 if (item.pid == app.pid) { 12840 mPendingProcessChanges.remove(i); 12841 mAvailProcessChanges.add(item); 12842 } 12843 } 12844 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12845 12846 // If the caller is restarting this app, then leave it in its 12847 // current lists and let the caller take care of it. 12848 if (restarting) { 12849 return; 12850 } 12851 12852 if (!app.persistent || app.isolated) { 12853 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12854 "Removing non-persistent process during cleanup: " + app); 12855 mProcessNames.remove(app.processName, app.uid); 12856 mIsolatedProcesses.remove(app.uid); 12857 if (mHeavyWeightProcess == app) { 12858 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12859 mHeavyWeightProcess.userId, 0)); 12860 mHeavyWeightProcess = null; 12861 } 12862 } else if (!app.removed) { 12863 // This app is persistent, so we need to keep its record around. 12864 // If it is not already on the pending app list, add it there 12865 // and start a new process for it. 12866 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12867 mPersistentStartingProcesses.add(app); 12868 restart = true; 12869 } 12870 } 12871 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12872 "Clean-up removing on hold: " + app); 12873 mProcessesOnHold.remove(app); 12874 12875 if (app == mHomeProcess) { 12876 mHomeProcess = null; 12877 } 12878 if (app == mPreviousProcess) { 12879 mPreviousProcess = null; 12880 } 12881 12882 if (restart && !app.isolated) { 12883 // We have components that still need to be running in the 12884 // process, so re-launch it. 12885 mProcessNames.put(app.processName, app.uid, app); 12886 startProcessLocked(app, "restart", app.processName); 12887 } else if (app.pid > 0 && app.pid != MY_PID) { 12888 // Goodbye! 12889 boolean removed; 12890 synchronized (mPidsSelfLocked) { 12891 mPidsSelfLocked.remove(app.pid); 12892 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12893 } 12894 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12895 app.processName, app.info.uid); 12896 if (app.isolated) { 12897 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12898 } 12899 app.setPid(0); 12900 } 12901 } 12902 12903 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12904 // Look through the content providers we are waiting to have launched, 12905 // and if any run in this process then either schedule a restart of 12906 // the process or kill the client waiting for it if this process has 12907 // gone bad. 12908 int NL = mLaunchingProviders.size(); 12909 boolean restart = false; 12910 for (int i=0; i<NL; i++) { 12911 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12912 if (cpr.launchingApp == app) { 12913 if (!alwaysBad && !app.bad) { 12914 restart = true; 12915 } else { 12916 removeDyingProviderLocked(app, cpr, true); 12917 // cpr should have been removed from mLaunchingProviders 12918 NL = mLaunchingProviders.size(); 12919 i--; 12920 } 12921 } 12922 } 12923 return restart; 12924 } 12925 12926 // ========================================================= 12927 // SERVICES 12928 // ========================================================= 12929 12930 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12931 int flags) { 12932 enforceNotIsolatedCaller("getServices"); 12933 synchronized (this) { 12934 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12935 } 12936 } 12937 12938 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12939 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12940 synchronized (this) { 12941 return mServices.getRunningServiceControlPanelLocked(name); 12942 } 12943 } 12944 12945 public ComponentName startService(IApplicationThread caller, Intent service, 12946 String resolvedType, int userId) { 12947 enforceNotIsolatedCaller("startService"); 12948 // Refuse possible leaked file descriptors 12949 if (service != null && service.hasFileDescriptors() == true) { 12950 throw new IllegalArgumentException("File descriptors passed in Intent"); 12951 } 12952 12953 if (DEBUG_SERVICE) 12954 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12955 synchronized(this) { 12956 final int callingPid = Binder.getCallingPid(); 12957 final int callingUid = Binder.getCallingUid(); 12958 final long origId = Binder.clearCallingIdentity(); 12959 ComponentName res = mServices.startServiceLocked(caller, service, 12960 resolvedType, callingPid, callingUid, userId); 12961 Binder.restoreCallingIdentity(origId); 12962 return res; 12963 } 12964 } 12965 12966 ComponentName startServiceInPackage(int uid, 12967 Intent service, String resolvedType, int userId) { 12968 synchronized(this) { 12969 if (DEBUG_SERVICE) 12970 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12971 final long origId = Binder.clearCallingIdentity(); 12972 ComponentName res = mServices.startServiceLocked(null, service, 12973 resolvedType, -1, uid, userId); 12974 Binder.restoreCallingIdentity(origId); 12975 return res; 12976 } 12977 } 12978 12979 public int stopService(IApplicationThread caller, Intent service, 12980 String resolvedType, int userId) { 12981 enforceNotIsolatedCaller("stopService"); 12982 // Refuse possible leaked file descriptors 12983 if (service != null && service.hasFileDescriptors() == true) { 12984 throw new IllegalArgumentException("File descriptors passed in Intent"); 12985 } 12986 12987 synchronized(this) { 12988 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12989 } 12990 } 12991 12992 public IBinder peekService(Intent service, String resolvedType) { 12993 enforceNotIsolatedCaller("peekService"); 12994 // Refuse possible leaked file descriptors 12995 if (service != null && service.hasFileDescriptors() == true) { 12996 throw new IllegalArgumentException("File descriptors passed in Intent"); 12997 } 12998 synchronized(this) { 12999 return mServices.peekServiceLocked(service, resolvedType); 13000 } 13001 } 13002 13003 public boolean stopServiceToken(ComponentName className, IBinder token, 13004 int startId) { 13005 synchronized(this) { 13006 return mServices.stopServiceTokenLocked(className, token, startId); 13007 } 13008 } 13009 13010 public void setServiceForeground(ComponentName className, IBinder token, 13011 int id, Notification notification, boolean removeNotification) { 13012 synchronized(this) { 13013 mServices.setServiceForegroundLocked(className, token, id, notification, 13014 removeNotification); 13015 } 13016 } 13017 13018 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13019 boolean requireFull, String name, String callerPackage) { 13020 final int callingUserId = UserHandle.getUserId(callingUid); 13021 if (callingUserId != userId) { 13022 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13023 if ((requireFull || checkComponentPermission( 13024 android.Manifest.permission.INTERACT_ACROSS_USERS, 13025 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13026 && checkComponentPermission( 13027 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13028 callingPid, callingUid, -1, true) 13029 != PackageManager.PERMISSION_GRANTED) { 13030 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13031 // In this case, they would like to just execute as their 13032 // owner user instead of failing. 13033 userId = callingUserId; 13034 } else { 13035 StringBuilder builder = new StringBuilder(128); 13036 builder.append("Permission Denial: "); 13037 builder.append(name); 13038 if (callerPackage != null) { 13039 builder.append(" from "); 13040 builder.append(callerPackage); 13041 } 13042 builder.append(" asks to run as user "); 13043 builder.append(userId); 13044 builder.append(" but is calling from user "); 13045 builder.append(UserHandle.getUserId(callingUid)); 13046 builder.append("; this requires "); 13047 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13048 if (!requireFull) { 13049 builder.append(" or "); 13050 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13051 } 13052 String msg = builder.toString(); 13053 Slog.w(TAG, msg); 13054 throw new SecurityException(msg); 13055 } 13056 } 13057 } 13058 if (userId == UserHandle.USER_CURRENT 13059 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13060 // Note that we may be accessing this outside of a lock... 13061 // shouldn't be a big deal, if this is being called outside 13062 // of a locked context there is intrinsically a race with 13063 // the value the caller will receive and someone else changing it. 13064 userId = mCurrentUserId; 13065 } 13066 if (!allowAll && userId < 0) { 13067 throw new IllegalArgumentException( 13068 "Call does not support special user #" + userId); 13069 } 13070 } 13071 return userId; 13072 } 13073 13074 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13075 String className, int flags) { 13076 boolean result = false; 13077 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13078 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13079 if (ActivityManager.checkUidPermission( 13080 android.Manifest.permission.INTERACT_ACROSS_USERS, 13081 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13082 ComponentName comp = new ComponentName(aInfo.packageName, className); 13083 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13084 + " requests FLAG_SINGLE_USER, but app does not hold " 13085 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13086 Slog.w(TAG, msg); 13087 throw new SecurityException(msg); 13088 } 13089 result = true; 13090 } 13091 } else if (componentProcessName == aInfo.packageName) { 13092 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13093 } else if ("system".equals(componentProcessName)) { 13094 result = true; 13095 } 13096 if (DEBUG_MU) { 13097 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13098 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13099 } 13100 return result; 13101 } 13102 13103 public int bindService(IApplicationThread caller, IBinder token, 13104 Intent service, String resolvedType, 13105 IServiceConnection connection, int flags, int userId) { 13106 enforceNotIsolatedCaller("bindService"); 13107 // Refuse possible leaked file descriptors 13108 if (service != null && service.hasFileDescriptors() == true) { 13109 throw new IllegalArgumentException("File descriptors passed in Intent"); 13110 } 13111 13112 synchronized(this) { 13113 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13114 connection, flags, userId); 13115 } 13116 } 13117 13118 public boolean unbindService(IServiceConnection connection) { 13119 synchronized (this) { 13120 return mServices.unbindServiceLocked(connection); 13121 } 13122 } 13123 13124 public void publishService(IBinder token, Intent intent, IBinder service) { 13125 // Refuse possible leaked file descriptors 13126 if (intent != null && intent.hasFileDescriptors() == true) { 13127 throw new IllegalArgumentException("File descriptors passed in Intent"); 13128 } 13129 13130 synchronized(this) { 13131 if (!(token instanceof ServiceRecord)) { 13132 throw new IllegalArgumentException("Invalid service token"); 13133 } 13134 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13135 } 13136 } 13137 13138 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13139 // Refuse possible leaked file descriptors 13140 if (intent != null && intent.hasFileDescriptors() == true) { 13141 throw new IllegalArgumentException("File descriptors passed in Intent"); 13142 } 13143 13144 synchronized(this) { 13145 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13146 } 13147 } 13148 13149 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13150 synchronized(this) { 13151 if (!(token instanceof ServiceRecord)) { 13152 throw new IllegalArgumentException("Invalid service token"); 13153 } 13154 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13155 } 13156 } 13157 13158 // ========================================================= 13159 // BACKUP AND RESTORE 13160 // ========================================================= 13161 13162 // Cause the target app to be launched if necessary and its backup agent 13163 // instantiated. The backup agent will invoke backupAgentCreated() on the 13164 // activity manager to announce its creation. 13165 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13166 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13167 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13168 13169 synchronized(this) { 13170 // !!! TODO: currently no check here that we're already bound 13171 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13172 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13173 synchronized (stats) { 13174 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13175 } 13176 13177 // Backup agent is now in use, its package can't be stopped. 13178 try { 13179 AppGlobals.getPackageManager().setPackageStoppedState( 13180 app.packageName, false, UserHandle.getUserId(app.uid)); 13181 } catch (RemoteException e) { 13182 } catch (IllegalArgumentException e) { 13183 Slog.w(TAG, "Failed trying to unstop package " 13184 + app.packageName + ": " + e); 13185 } 13186 13187 BackupRecord r = new BackupRecord(ss, app, backupMode); 13188 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13189 ? new ComponentName(app.packageName, app.backupAgentName) 13190 : new ComponentName("android", "FullBackupAgent"); 13191 // startProcessLocked() returns existing proc's record if it's already running 13192 ProcessRecord proc = startProcessLocked(app.processName, app, 13193 false, 0, "backup", hostingName, false, false, false); 13194 if (proc == null) { 13195 Slog.e(TAG, "Unable to start backup agent process " + r); 13196 return false; 13197 } 13198 13199 r.app = proc; 13200 mBackupTarget = r; 13201 mBackupAppName = app.packageName; 13202 13203 // Try not to kill the process during backup 13204 updateOomAdjLocked(proc); 13205 13206 // If the process is already attached, schedule the creation of the backup agent now. 13207 // If it is not yet live, this will be done when it attaches to the framework. 13208 if (proc.thread != null) { 13209 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13210 try { 13211 proc.thread.scheduleCreateBackupAgent(app, 13212 compatibilityInfoForPackageLocked(app), backupMode); 13213 } catch (RemoteException e) { 13214 // Will time out on the backup manager side 13215 } 13216 } else { 13217 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13218 } 13219 // Invariants: at this point, the target app process exists and the application 13220 // is either already running or in the process of coming up. mBackupTarget and 13221 // mBackupAppName describe the app, so that when it binds back to the AM we 13222 // know that it's scheduled for a backup-agent operation. 13223 } 13224 13225 return true; 13226 } 13227 13228 @Override 13229 public void clearPendingBackup() { 13230 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13231 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13232 13233 synchronized (this) { 13234 mBackupTarget = null; 13235 mBackupAppName = null; 13236 } 13237 } 13238 13239 // A backup agent has just come up 13240 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13241 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13242 + " = " + agent); 13243 13244 synchronized(this) { 13245 if (!agentPackageName.equals(mBackupAppName)) { 13246 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13247 return; 13248 } 13249 } 13250 13251 long oldIdent = Binder.clearCallingIdentity(); 13252 try { 13253 IBackupManager bm = IBackupManager.Stub.asInterface( 13254 ServiceManager.getService(Context.BACKUP_SERVICE)); 13255 bm.agentConnected(agentPackageName, agent); 13256 } catch (RemoteException e) { 13257 // can't happen; the backup manager service is local 13258 } catch (Exception e) { 13259 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13260 e.printStackTrace(); 13261 } finally { 13262 Binder.restoreCallingIdentity(oldIdent); 13263 } 13264 } 13265 13266 // done with this agent 13267 public void unbindBackupAgent(ApplicationInfo appInfo) { 13268 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13269 if (appInfo == null) { 13270 Slog.w(TAG, "unbind backup agent for null app"); 13271 return; 13272 } 13273 13274 synchronized(this) { 13275 try { 13276 if (mBackupAppName == null) { 13277 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13278 return; 13279 } 13280 13281 if (!mBackupAppName.equals(appInfo.packageName)) { 13282 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13283 return; 13284 } 13285 13286 // Not backing this app up any more; reset its OOM adjustment 13287 final ProcessRecord proc = mBackupTarget.app; 13288 updateOomAdjLocked(proc); 13289 13290 // If the app crashed during backup, 'thread' will be null here 13291 if (proc.thread != null) { 13292 try { 13293 proc.thread.scheduleDestroyBackupAgent(appInfo, 13294 compatibilityInfoForPackageLocked(appInfo)); 13295 } catch (Exception e) { 13296 Slog.e(TAG, "Exception when unbinding backup agent:"); 13297 e.printStackTrace(); 13298 } 13299 } 13300 } finally { 13301 mBackupTarget = null; 13302 mBackupAppName = null; 13303 } 13304 } 13305 } 13306 // ========================================================= 13307 // BROADCASTS 13308 // ========================================================= 13309 13310 private final List getStickiesLocked(String action, IntentFilter filter, 13311 List cur, int userId) { 13312 final ContentResolver resolver = mContext.getContentResolver(); 13313 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13314 if (stickies == null) { 13315 return cur; 13316 } 13317 final ArrayList<Intent> list = stickies.get(action); 13318 if (list == null) { 13319 return cur; 13320 } 13321 int N = list.size(); 13322 for (int i=0; i<N; i++) { 13323 Intent intent = list.get(i); 13324 if (filter.match(resolver, intent, true, TAG) >= 0) { 13325 if (cur == null) { 13326 cur = new ArrayList<Intent>(); 13327 } 13328 cur.add(intent); 13329 } 13330 } 13331 return cur; 13332 } 13333 13334 boolean isPendingBroadcastProcessLocked(int pid) { 13335 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13336 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13337 } 13338 13339 void skipPendingBroadcastLocked(int pid) { 13340 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13341 for (BroadcastQueue queue : mBroadcastQueues) { 13342 queue.skipPendingBroadcastLocked(pid); 13343 } 13344 } 13345 13346 // The app just attached; send any pending broadcasts that it should receive 13347 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13348 boolean didSomething = false; 13349 for (BroadcastQueue queue : mBroadcastQueues) { 13350 didSomething |= queue.sendPendingBroadcastsLocked(app); 13351 } 13352 return didSomething; 13353 } 13354 13355 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13356 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13357 enforceNotIsolatedCaller("registerReceiver"); 13358 int callingUid; 13359 int callingPid; 13360 synchronized(this) { 13361 ProcessRecord callerApp = null; 13362 if (caller != null) { 13363 callerApp = getRecordForAppLocked(caller); 13364 if (callerApp == null) { 13365 throw new SecurityException( 13366 "Unable to find app for caller " + caller 13367 + " (pid=" + Binder.getCallingPid() 13368 + ") when registering receiver " + receiver); 13369 } 13370 if (callerApp.info.uid != Process.SYSTEM_UID && 13371 !callerApp.pkgList.containsKey(callerPackage) && 13372 !"android".equals(callerPackage)) { 13373 throw new SecurityException("Given caller package " + callerPackage 13374 + " is not running in process " + callerApp); 13375 } 13376 callingUid = callerApp.info.uid; 13377 callingPid = callerApp.pid; 13378 } else { 13379 callerPackage = null; 13380 callingUid = Binder.getCallingUid(); 13381 callingPid = Binder.getCallingPid(); 13382 } 13383 13384 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13385 true, true, "registerReceiver", callerPackage); 13386 13387 List allSticky = null; 13388 13389 // Look for any matching sticky broadcasts... 13390 Iterator actions = filter.actionsIterator(); 13391 if (actions != null) { 13392 while (actions.hasNext()) { 13393 String action = (String)actions.next(); 13394 allSticky = getStickiesLocked(action, filter, allSticky, 13395 UserHandle.USER_ALL); 13396 allSticky = getStickiesLocked(action, filter, allSticky, 13397 UserHandle.getUserId(callingUid)); 13398 } 13399 } else { 13400 allSticky = getStickiesLocked(null, filter, allSticky, 13401 UserHandle.USER_ALL); 13402 allSticky = getStickiesLocked(null, filter, allSticky, 13403 UserHandle.getUserId(callingUid)); 13404 } 13405 13406 // The first sticky in the list is returned directly back to 13407 // the client. 13408 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13409 13410 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13411 + ": " + sticky); 13412 13413 if (receiver == null) { 13414 return sticky; 13415 } 13416 13417 ReceiverList rl 13418 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13419 if (rl == null) { 13420 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13421 userId, receiver); 13422 if (rl.app != null) { 13423 rl.app.receivers.add(rl); 13424 } else { 13425 try { 13426 receiver.asBinder().linkToDeath(rl, 0); 13427 } catch (RemoteException e) { 13428 return sticky; 13429 } 13430 rl.linkedToDeath = true; 13431 } 13432 mRegisteredReceivers.put(receiver.asBinder(), rl); 13433 } else if (rl.uid != callingUid) { 13434 throw new IllegalArgumentException( 13435 "Receiver requested to register for uid " + callingUid 13436 + " was previously registered for uid " + rl.uid); 13437 } else if (rl.pid != callingPid) { 13438 throw new IllegalArgumentException( 13439 "Receiver requested to register for pid " + callingPid 13440 + " was previously registered for pid " + rl.pid); 13441 } else if (rl.userId != userId) { 13442 throw new IllegalArgumentException( 13443 "Receiver requested to register for user " + userId 13444 + " was previously registered for user " + rl.userId); 13445 } 13446 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13447 permission, callingUid, userId); 13448 rl.add(bf); 13449 if (!bf.debugCheck()) { 13450 Slog.w(TAG, "==> For Dynamic broadast"); 13451 } 13452 mReceiverResolver.addFilter(bf); 13453 13454 // Enqueue broadcasts for all existing stickies that match 13455 // this filter. 13456 if (allSticky != null) { 13457 ArrayList receivers = new ArrayList(); 13458 receivers.add(bf); 13459 13460 int N = allSticky.size(); 13461 for (int i=0; i<N; i++) { 13462 Intent intent = (Intent)allSticky.get(i); 13463 BroadcastQueue queue = broadcastQueueForIntent(intent); 13464 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13465 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13466 null, null, false, true, true, -1); 13467 queue.enqueueParallelBroadcastLocked(r); 13468 queue.scheduleBroadcastsLocked(); 13469 } 13470 } 13471 13472 return sticky; 13473 } 13474 } 13475 13476 public void unregisterReceiver(IIntentReceiver receiver) { 13477 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13478 13479 final long origId = Binder.clearCallingIdentity(); 13480 try { 13481 boolean doTrim = false; 13482 13483 synchronized(this) { 13484 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13485 if (rl != null) { 13486 if (rl.curBroadcast != null) { 13487 BroadcastRecord r = rl.curBroadcast; 13488 final boolean doNext = finishReceiverLocked( 13489 receiver.asBinder(), r.resultCode, r.resultData, 13490 r.resultExtras, r.resultAbort); 13491 if (doNext) { 13492 doTrim = true; 13493 r.queue.processNextBroadcast(false); 13494 } 13495 } 13496 13497 if (rl.app != null) { 13498 rl.app.receivers.remove(rl); 13499 } 13500 removeReceiverLocked(rl); 13501 if (rl.linkedToDeath) { 13502 rl.linkedToDeath = false; 13503 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13504 } 13505 } 13506 } 13507 13508 // If we actually concluded any broadcasts, we might now be able 13509 // to trim the recipients' apps from our working set 13510 if (doTrim) { 13511 trimApplications(); 13512 return; 13513 } 13514 13515 } finally { 13516 Binder.restoreCallingIdentity(origId); 13517 } 13518 } 13519 13520 void removeReceiverLocked(ReceiverList rl) { 13521 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13522 int N = rl.size(); 13523 for (int i=0; i<N; i++) { 13524 mReceiverResolver.removeFilter(rl.get(i)); 13525 } 13526 } 13527 13528 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13529 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13530 ProcessRecord r = mLruProcesses.get(i); 13531 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13532 try { 13533 r.thread.dispatchPackageBroadcast(cmd, packages); 13534 } catch (RemoteException ex) { 13535 } 13536 } 13537 } 13538 } 13539 13540 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13541 int[] users) { 13542 List<ResolveInfo> receivers = null; 13543 try { 13544 HashSet<ComponentName> singleUserReceivers = null; 13545 boolean scannedFirstReceivers = false; 13546 for (int user : users) { 13547 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13548 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13549 if (user != 0 && newReceivers != null) { 13550 // If this is not the primary user, we need to check for 13551 // any receivers that should be filtered out. 13552 for (int i=0; i<newReceivers.size(); i++) { 13553 ResolveInfo ri = newReceivers.get(i); 13554 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13555 newReceivers.remove(i); 13556 i--; 13557 } 13558 } 13559 } 13560 if (newReceivers != null && newReceivers.size() == 0) { 13561 newReceivers = null; 13562 } 13563 if (receivers == null) { 13564 receivers = newReceivers; 13565 } else if (newReceivers != null) { 13566 // We need to concatenate the additional receivers 13567 // found with what we have do far. This would be easy, 13568 // but we also need to de-dup any receivers that are 13569 // singleUser. 13570 if (!scannedFirstReceivers) { 13571 // Collect any single user receivers we had already retrieved. 13572 scannedFirstReceivers = true; 13573 for (int i=0; i<receivers.size(); i++) { 13574 ResolveInfo ri = receivers.get(i); 13575 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13576 ComponentName cn = new ComponentName( 13577 ri.activityInfo.packageName, ri.activityInfo.name); 13578 if (singleUserReceivers == null) { 13579 singleUserReceivers = new HashSet<ComponentName>(); 13580 } 13581 singleUserReceivers.add(cn); 13582 } 13583 } 13584 } 13585 // Add the new results to the existing results, tracking 13586 // and de-dupping single user receivers. 13587 for (int i=0; i<newReceivers.size(); i++) { 13588 ResolveInfo ri = newReceivers.get(i); 13589 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13590 ComponentName cn = new ComponentName( 13591 ri.activityInfo.packageName, ri.activityInfo.name); 13592 if (singleUserReceivers == null) { 13593 singleUserReceivers = new HashSet<ComponentName>(); 13594 } 13595 if (!singleUserReceivers.contains(cn)) { 13596 singleUserReceivers.add(cn); 13597 receivers.add(ri); 13598 } 13599 } else { 13600 receivers.add(ri); 13601 } 13602 } 13603 } 13604 } 13605 } catch (RemoteException ex) { 13606 // pm is in same process, this will never happen. 13607 } 13608 return receivers; 13609 } 13610 13611 private final int broadcastIntentLocked(ProcessRecord callerApp, 13612 String callerPackage, Intent intent, String resolvedType, 13613 IIntentReceiver resultTo, int resultCode, String resultData, 13614 Bundle map, String requiredPermission, int appOp, 13615 boolean ordered, boolean sticky, int callingPid, int callingUid, 13616 int userId) { 13617 intent = new Intent(intent); 13618 13619 // By default broadcasts do not go to stopped apps. 13620 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13621 13622 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13623 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13624 + " ordered=" + ordered + " userid=" + userId); 13625 if ((resultTo != null) && !ordered) { 13626 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13627 } 13628 13629 userId = handleIncomingUser(callingPid, callingUid, userId, 13630 true, false, "broadcast", callerPackage); 13631 13632 // Make sure that the user who is receiving this broadcast is started. 13633 // If not, we will just skip it. 13634 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13635 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13636 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13637 Slog.w(TAG, "Skipping broadcast of " + intent 13638 + ": user " + userId + " is stopped"); 13639 return ActivityManager.BROADCAST_SUCCESS; 13640 } 13641 } 13642 13643 /* 13644 * Prevent non-system code (defined here to be non-persistent 13645 * processes) from sending protected broadcasts. 13646 */ 13647 int callingAppId = UserHandle.getAppId(callingUid); 13648 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13649 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13650 callingUid == 0) { 13651 // Always okay. 13652 } else if (callerApp == null || !callerApp.persistent) { 13653 try { 13654 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13655 intent.getAction())) { 13656 String msg = "Permission Denial: not allowed to send broadcast " 13657 + intent.getAction() + " from pid=" 13658 + callingPid + ", uid=" + callingUid; 13659 Slog.w(TAG, msg); 13660 throw new SecurityException(msg); 13661 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13662 // Special case for compatibility: we don't want apps to send this, 13663 // but historically it has not been protected and apps may be using it 13664 // to poke their own app widget. So, instead of making it protected, 13665 // just limit it to the caller. 13666 if (callerApp == null) { 13667 String msg = "Permission Denial: not allowed to send broadcast " 13668 + intent.getAction() + " from unknown caller."; 13669 Slog.w(TAG, msg); 13670 throw new SecurityException(msg); 13671 } else if (intent.getComponent() != null) { 13672 // They are good enough to send to an explicit component... verify 13673 // it is being sent to the calling app. 13674 if (!intent.getComponent().getPackageName().equals( 13675 callerApp.info.packageName)) { 13676 String msg = "Permission Denial: not allowed to send broadcast " 13677 + intent.getAction() + " to " 13678 + intent.getComponent().getPackageName() + " from " 13679 + callerApp.info.packageName; 13680 Slog.w(TAG, msg); 13681 throw new SecurityException(msg); 13682 } 13683 } else { 13684 // Limit broadcast to their own package. 13685 intent.setPackage(callerApp.info.packageName); 13686 } 13687 } 13688 } catch (RemoteException e) { 13689 Slog.w(TAG, "Remote exception", e); 13690 return ActivityManager.BROADCAST_SUCCESS; 13691 } 13692 } 13693 13694 // Handle special intents: if this broadcast is from the package 13695 // manager about a package being removed, we need to remove all of 13696 // its activities from the history stack. 13697 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13698 intent.getAction()); 13699 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13700 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13701 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13702 || uidRemoved) { 13703 if (checkComponentPermission( 13704 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13705 callingPid, callingUid, -1, true) 13706 == PackageManager.PERMISSION_GRANTED) { 13707 if (uidRemoved) { 13708 final Bundle intentExtras = intent.getExtras(); 13709 final int uid = intentExtras != null 13710 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13711 if (uid >= 0) { 13712 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13713 synchronized (bs) { 13714 bs.removeUidStatsLocked(uid); 13715 } 13716 mAppOpsService.uidRemoved(uid); 13717 } 13718 } else { 13719 // If resources are unavailable just force stop all 13720 // those packages and flush the attribute cache as well. 13721 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13722 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13723 if (list != null && (list.length > 0)) { 13724 for (String pkg : list) { 13725 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13726 "storage unmount"); 13727 } 13728 sendPackageBroadcastLocked( 13729 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13730 } 13731 } else { 13732 Uri data = intent.getData(); 13733 String ssp; 13734 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13735 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13736 intent.getAction()); 13737 boolean fullUninstall = removed && 13738 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13739 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13740 forceStopPackageLocked(ssp, UserHandle.getAppId( 13741 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13742 false, fullUninstall, userId, 13743 removed ? "pkg removed" : "pkg changed"); 13744 } 13745 if (removed) { 13746 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13747 new String[] {ssp}, userId); 13748 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13749 mAppOpsService.packageRemoved( 13750 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13751 13752 // Remove all permissions granted from/to this package 13753 removeUriPermissionsForPackageLocked(ssp, userId, true); 13754 } 13755 } 13756 } 13757 } 13758 } 13759 } else { 13760 String msg = "Permission Denial: " + intent.getAction() 13761 + " broadcast from " + callerPackage + " (pid=" + callingPid 13762 + ", uid=" + callingUid + ")" 13763 + " requires " 13764 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13765 Slog.w(TAG, msg); 13766 throw new SecurityException(msg); 13767 } 13768 13769 // Special case for adding a package: by default turn on compatibility 13770 // mode. 13771 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13772 Uri data = intent.getData(); 13773 String ssp; 13774 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13775 mCompatModePackages.handlePackageAddedLocked(ssp, 13776 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13777 } 13778 } 13779 13780 /* 13781 * If this is the time zone changed action, queue up a message that will reset the timezone 13782 * of all currently running processes. This message will get queued up before the broadcast 13783 * happens. 13784 */ 13785 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13786 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13787 } 13788 13789 /* 13790 * If the user set the time, let all running processes know. 13791 */ 13792 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13793 final int is24Hour = intent.getBooleanExtra( 13794 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13795 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13796 } 13797 13798 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13799 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13800 } 13801 13802 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13803 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13804 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13805 } 13806 13807 // Add to the sticky list if requested. 13808 if (sticky) { 13809 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13810 callingPid, callingUid) 13811 != PackageManager.PERMISSION_GRANTED) { 13812 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13813 + callingPid + ", uid=" + callingUid 13814 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13815 Slog.w(TAG, msg); 13816 throw new SecurityException(msg); 13817 } 13818 if (requiredPermission != null) { 13819 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13820 + " and enforce permission " + requiredPermission); 13821 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13822 } 13823 if (intent.getComponent() != null) { 13824 throw new SecurityException( 13825 "Sticky broadcasts can't target a specific component"); 13826 } 13827 // We use userId directly here, since the "all" target is maintained 13828 // as a separate set of sticky broadcasts. 13829 if (userId != UserHandle.USER_ALL) { 13830 // But first, if this is not a broadcast to all users, then 13831 // make sure it doesn't conflict with an existing broadcast to 13832 // all users. 13833 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13834 UserHandle.USER_ALL); 13835 if (stickies != null) { 13836 ArrayList<Intent> list = stickies.get(intent.getAction()); 13837 if (list != null) { 13838 int N = list.size(); 13839 int i; 13840 for (i=0; i<N; i++) { 13841 if (intent.filterEquals(list.get(i))) { 13842 throw new IllegalArgumentException( 13843 "Sticky broadcast " + intent + " for user " 13844 + userId + " conflicts with existing global broadcast"); 13845 } 13846 } 13847 } 13848 } 13849 } 13850 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13851 if (stickies == null) { 13852 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13853 mStickyBroadcasts.put(userId, stickies); 13854 } 13855 ArrayList<Intent> list = stickies.get(intent.getAction()); 13856 if (list == null) { 13857 list = new ArrayList<Intent>(); 13858 stickies.put(intent.getAction(), list); 13859 } 13860 int N = list.size(); 13861 int i; 13862 for (i=0; i<N; i++) { 13863 if (intent.filterEquals(list.get(i))) { 13864 // This sticky already exists, replace it. 13865 list.set(i, new Intent(intent)); 13866 break; 13867 } 13868 } 13869 if (i >= N) { 13870 list.add(new Intent(intent)); 13871 } 13872 } 13873 13874 int[] users; 13875 if (userId == UserHandle.USER_ALL) { 13876 // Caller wants broadcast to go to all started users. 13877 users = mStartedUserArray; 13878 } else { 13879 // Caller wants broadcast to go to one specific user. 13880 users = new int[] {userId}; 13881 } 13882 13883 // Figure out who all will receive this broadcast. 13884 List receivers = null; 13885 List<BroadcastFilter> registeredReceivers = null; 13886 // Need to resolve the intent to interested receivers... 13887 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13888 == 0) { 13889 receivers = collectReceiverComponents(intent, resolvedType, users); 13890 } 13891 if (intent.getComponent() == null) { 13892 registeredReceivers = mReceiverResolver.queryIntent(intent, 13893 resolvedType, false, userId); 13894 } 13895 13896 final boolean replacePending = 13897 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13898 13899 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13900 + " replacePending=" + replacePending); 13901 13902 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13903 if (!ordered && NR > 0) { 13904 // If we are not serializing this broadcast, then send the 13905 // registered receivers separately so they don't wait for the 13906 // components to be launched. 13907 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13908 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13909 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13910 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13911 ordered, sticky, false, userId); 13912 if (DEBUG_BROADCAST) Slog.v( 13913 TAG, "Enqueueing parallel broadcast " + r); 13914 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13915 if (!replaced) { 13916 queue.enqueueParallelBroadcastLocked(r); 13917 queue.scheduleBroadcastsLocked(); 13918 } 13919 registeredReceivers = null; 13920 NR = 0; 13921 } 13922 13923 // Merge into one list. 13924 int ir = 0; 13925 if (receivers != null) { 13926 // A special case for PACKAGE_ADDED: do not allow the package 13927 // being added to see this broadcast. This prevents them from 13928 // using this as a back door to get run as soon as they are 13929 // installed. Maybe in the future we want to have a special install 13930 // broadcast or such for apps, but we'd like to deliberately make 13931 // this decision. 13932 String skipPackages[] = null; 13933 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13934 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13935 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13936 Uri data = intent.getData(); 13937 if (data != null) { 13938 String pkgName = data.getSchemeSpecificPart(); 13939 if (pkgName != null) { 13940 skipPackages = new String[] { pkgName }; 13941 } 13942 } 13943 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13944 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13945 } 13946 if (skipPackages != null && (skipPackages.length > 0)) { 13947 for (String skipPackage : skipPackages) { 13948 if (skipPackage != null) { 13949 int NT = receivers.size(); 13950 for (int it=0; it<NT; it++) { 13951 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13952 if (curt.activityInfo.packageName.equals(skipPackage)) { 13953 receivers.remove(it); 13954 it--; 13955 NT--; 13956 } 13957 } 13958 } 13959 } 13960 } 13961 13962 int NT = receivers != null ? receivers.size() : 0; 13963 int it = 0; 13964 ResolveInfo curt = null; 13965 BroadcastFilter curr = null; 13966 while (it < NT && ir < NR) { 13967 if (curt == null) { 13968 curt = (ResolveInfo)receivers.get(it); 13969 } 13970 if (curr == null) { 13971 curr = registeredReceivers.get(ir); 13972 } 13973 if (curr.getPriority() >= curt.priority) { 13974 // Insert this broadcast record into the final list. 13975 receivers.add(it, curr); 13976 ir++; 13977 curr = null; 13978 it++; 13979 NT++; 13980 } else { 13981 // Skip to the next ResolveInfo in the final list. 13982 it++; 13983 curt = null; 13984 } 13985 } 13986 } 13987 while (ir < NR) { 13988 if (receivers == null) { 13989 receivers = new ArrayList(); 13990 } 13991 receivers.add(registeredReceivers.get(ir)); 13992 ir++; 13993 } 13994 13995 if ((receivers != null && receivers.size() > 0) 13996 || resultTo != null) { 13997 BroadcastQueue queue = broadcastQueueForIntent(intent); 13998 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13999 callerPackage, callingPid, callingUid, resolvedType, 14000 requiredPermission, appOp, receivers, resultTo, resultCode, 14001 resultData, map, ordered, sticky, false, userId); 14002 if (DEBUG_BROADCAST) Slog.v( 14003 TAG, "Enqueueing ordered broadcast " + r 14004 + ": prev had " + queue.mOrderedBroadcasts.size()); 14005 if (DEBUG_BROADCAST) { 14006 int seq = r.intent.getIntExtra("seq", -1); 14007 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14008 } 14009 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14010 if (!replaced) { 14011 queue.enqueueOrderedBroadcastLocked(r); 14012 queue.scheduleBroadcastsLocked(); 14013 } 14014 } 14015 14016 return ActivityManager.BROADCAST_SUCCESS; 14017 } 14018 14019 final Intent verifyBroadcastLocked(Intent intent) { 14020 // Refuse possible leaked file descriptors 14021 if (intent != null && intent.hasFileDescriptors() == true) { 14022 throw new IllegalArgumentException("File descriptors passed in Intent"); 14023 } 14024 14025 int flags = intent.getFlags(); 14026 14027 if (!mProcessesReady) { 14028 // if the caller really truly claims to know what they're doing, go 14029 // ahead and allow the broadcast without launching any receivers 14030 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14031 intent = new Intent(intent); 14032 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14033 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14034 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14035 + " before boot completion"); 14036 throw new IllegalStateException("Cannot broadcast before boot completed"); 14037 } 14038 } 14039 14040 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14041 throw new IllegalArgumentException( 14042 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14043 } 14044 14045 return intent; 14046 } 14047 14048 public final int broadcastIntent(IApplicationThread caller, 14049 Intent intent, String resolvedType, IIntentReceiver resultTo, 14050 int resultCode, String resultData, Bundle map, 14051 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14052 enforceNotIsolatedCaller("broadcastIntent"); 14053 synchronized(this) { 14054 intent = verifyBroadcastLocked(intent); 14055 14056 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14057 final int callingPid = Binder.getCallingPid(); 14058 final int callingUid = Binder.getCallingUid(); 14059 final long origId = Binder.clearCallingIdentity(); 14060 int res = broadcastIntentLocked(callerApp, 14061 callerApp != null ? callerApp.info.packageName : null, 14062 intent, resolvedType, resultTo, 14063 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14064 callingPid, callingUid, userId); 14065 Binder.restoreCallingIdentity(origId); 14066 return res; 14067 } 14068 } 14069 14070 int broadcastIntentInPackage(String packageName, int uid, 14071 Intent intent, String resolvedType, IIntentReceiver resultTo, 14072 int resultCode, String resultData, Bundle map, 14073 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14074 synchronized(this) { 14075 intent = verifyBroadcastLocked(intent); 14076 14077 final long origId = Binder.clearCallingIdentity(); 14078 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14079 resultTo, resultCode, resultData, map, requiredPermission, 14080 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14081 Binder.restoreCallingIdentity(origId); 14082 return res; 14083 } 14084 } 14085 14086 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14087 // Refuse possible leaked file descriptors 14088 if (intent != null && intent.hasFileDescriptors() == true) { 14089 throw new IllegalArgumentException("File descriptors passed in Intent"); 14090 } 14091 14092 userId = handleIncomingUser(Binder.getCallingPid(), 14093 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14094 14095 synchronized(this) { 14096 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14097 != PackageManager.PERMISSION_GRANTED) { 14098 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14099 + Binder.getCallingPid() 14100 + ", uid=" + Binder.getCallingUid() 14101 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14102 Slog.w(TAG, msg); 14103 throw new SecurityException(msg); 14104 } 14105 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14106 if (stickies != null) { 14107 ArrayList<Intent> list = stickies.get(intent.getAction()); 14108 if (list != null) { 14109 int N = list.size(); 14110 int i; 14111 for (i=0; i<N; i++) { 14112 if (intent.filterEquals(list.get(i))) { 14113 list.remove(i); 14114 break; 14115 } 14116 } 14117 if (list.size() <= 0) { 14118 stickies.remove(intent.getAction()); 14119 } 14120 } 14121 if (stickies.size() <= 0) { 14122 mStickyBroadcasts.remove(userId); 14123 } 14124 } 14125 } 14126 } 14127 14128 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14129 String resultData, Bundle resultExtras, boolean resultAbort) { 14130 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14131 if (r == null) { 14132 Slog.w(TAG, "finishReceiver called but not found on queue"); 14133 return false; 14134 } 14135 14136 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14137 } 14138 14139 void backgroundServicesFinishedLocked(int userId) { 14140 for (BroadcastQueue queue : mBroadcastQueues) { 14141 queue.backgroundServicesFinishedLocked(userId); 14142 } 14143 } 14144 14145 public void finishReceiver(IBinder who, int resultCode, String resultData, 14146 Bundle resultExtras, boolean resultAbort) { 14147 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14148 14149 // Refuse possible leaked file descriptors 14150 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14151 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14152 } 14153 14154 final long origId = Binder.clearCallingIdentity(); 14155 try { 14156 boolean doNext = false; 14157 BroadcastRecord r; 14158 14159 synchronized(this) { 14160 r = broadcastRecordForReceiverLocked(who); 14161 if (r != null) { 14162 doNext = r.queue.finishReceiverLocked(r, resultCode, 14163 resultData, resultExtras, resultAbort, true); 14164 } 14165 } 14166 14167 if (doNext) { 14168 r.queue.processNextBroadcast(false); 14169 } 14170 trimApplications(); 14171 } finally { 14172 Binder.restoreCallingIdentity(origId); 14173 } 14174 } 14175 14176 // ========================================================= 14177 // INSTRUMENTATION 14178 // ========================================================= 14179 14180 public boolean startInstrumentation(ComponentName className, 14181 String profileFile, int flags, Bundle arguments, 14182 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14183 int userId) { 14184 enforceNotIsolatedCaller("startInstrumentation"); 14185 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14186 userId, false, true, "startInstrumentation", null); 14187 // Refuse possible leaked file descriptors 14188 if (arguments != null && arguments.hasFileDescriptors()) { 14189 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14190 } 14191 14192 synchronized(this) { 14193 InstrumentationInfo ii = null; 14194 ApplicationInfo ai = null; 14195 try { 14196 ii = mContext.getPackageManager().getInstrumentationInfo( 14197 className, STOCK_PM_FLAGS); 14198 ai = AppGlobals.getPackageManager().getApplicationInfo( 14199 ii.targetPackage, STOCK_PM_FLAGS, userId); 14200 } catch (PackageManager.NameNotFoundException e) { 14201 } catch (RemoteException e) { 14202 } 14203 if (ii == null) { 14204 reportStartInstrumentationFailure(watcher, className, 14205 "Unable to find instrumentation info for: " + className); 14206 return false; 14207 } 14208 if (ai == null) { 14209 reportStartInstrumentationFailure(watcher, className, 14210 "Unable to find instrumentation target package: " + ii.targetPackage); 14211 return false; 14212 } 14213 14214 int match = mContext.getPackageManager().checkSignatures( 14215 ii.targetPackage, ii.packageName); 14216 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14217 String msg = "Permission Denial: starting instrumentation " 14218 + className + " from pid=" 14219 + Binder.getCallingPid() 14220 + ", uid=" + Binder.getCallingPid() 14221 + " not allowed because package " + ii.packageName 14222 + " does not have a signature matching the target " 14223 + ii.targetPackage; 14224 reportStartInstrumentationFailure(watcher, className, msg); 14225 throw new SecurityException(msg); 14226 } 14227 14228 final long origId = Binder.clearCallingIdentity(); 14229 // Instrumentation can kill and relaunch even persistent processes 14230 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14231 "start instr"); 14232 ProcessRecord app = addAppLocked(ai, false); 14233 app.instrumentationClass = className; 14234 app.instrumentationInfo = ai; 14235 app.instrumentationProfileFile = profileFile; 14236 app.instrumentationArguments = arguments; 14237 app.instrumentationWatcher = watcher; 14238 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14239 app.instrumentationResultClass = className; 14240 Binder.restoreCallingIdentity(origId); 14241 } 14242 14243 return true; 14244 } 14245 14246 /** 14247 * Report errors that occur while attempting to start Instrumentation. Always writes the 14248 * error to the logs, but if somebody is watching, send the report there too. This enables 14249 * the "am" command to report errors with more information. 14250 * 14251 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14252 * @param cn The component name of the instrumentation. 14253 * @param report The error report. 14254 */ 14255 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14256 ComponentName cn, String report) { 14257 Slog.w(TAG, report); 14258 try { 14259 if (watcher != null) { 14260 Bundle results = new Bundle(); 14261 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14262 results.putString("Error", report); 14263 watcher.instrumentationStatus(cn, -1, results); 14264 } 14265 } catch (RemoteException e) { 14266 Slog.w(TAG, e); 14267 } 14268 } 14269 14270 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14271 if (app.instrumentationWatcher != null) { 14272 try { 14273 // NOTE: IInstrumentationWatcher *must* be oneway here 14274 app.instrumentationWatcher.instrumentationFinished( 14275 app.instrumentationClass, 14276 resultCode, 14277 results); 14278 } catch (RemoteException e) { 14279 } 14280 } 14281 if (app.instrumentationUiAutomationConnection != null) { 14282 try { 14283 app.instrumentationUiAutomationConnection.shutdown(); 14284 } catch (RemoteException re) { 14285 /* ignore */ 14286 } 14287 // Only a UiAutomation can set this flag and now that 14288 // it is finished we make sure it is reset to its default. 14289 mUserIsMonkey = false; 14290 } 14291 app.instrumentationWatcher = null; 14292 app.instrumentationUiAutomationConnection = null; 14293 app.instrumentationClass = null; 14294 app.instrumentationInfo = null; 14295 app.instrumentationProfileFile = null; 14296 app.instrumentationArguments = null; 14297 14298 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14299 "finished inst"); 14300 } 14301 14302 public void finishInstrumentation(IApplicationThread target, 14303 int resultCode, Bundle results) { 14304 int userId = UserHandle.getCallingUserId(); 14305 // Refuse possible leaked file descriptors 14306 if (results != null && results.hasFileDescriptors()) { 14307 throw new IllegalArgumentException("File descriptors passed in Intent"); 14308 } 14309 14310 synchronized(this) { 14311 ProcessRecord app = getRecordForAppLocked(target); 14312 if (app == null) { 14313 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14314 return; 14315 } 14316 final long origId = Binder.clearCallingIdentity(); 14317 finishInstrumentationLocked(app, resultCode, results); 14318 Binder.restoreCallingIdentity(origId); 14319 } 14320 } 14321 14322 // ========================================================= 14323 // CONFIGURATION 14324 // ========================================================= 14325 14326 public ConfigurationInfo getDeviceConfigurationInfo() { 14327 ConfigurationInfo config = new ConfigurationInfo(); 14328 synchronized (this) { 14329 config.reqTouchScreen = mConfiguration.touchscreen; 14330 config.reqKeyboardType = mConfiguration.keyboard; 14331 config.reqNavigation = mConfiguration.navigation; 14332 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14333 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14334 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14335 } 14336 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14337 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14338 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14339 } 14340 config.reqGlEsVersion = GL_ES_VERSION; 14341 } 14342 return config; 14343 } 14344 14345 ActivityStack getFocusedStack() { 14346 return mStackSupervisor.getFocusedStack(); 14347 } 14348 14349 public Configuration getConfiguration() { 14350 Configuration ci; 14351 synchronized(this) { 14352 ci = new Configuration(mConfiguration); 14353 } 14354 return ci; 14355 } 14356 14357 public void updatePersistentConfiguration(Configuration values) { 14358 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14359 "updateConfiguration()"); 14360 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14361 "updateConfiguration()"); 14362 if (values == null) { 14363 throw new NullPointerException("Configuration must not be null"); 14364 } 14365 14366 synchronized(this) { 14367 final long origId = Binder.clearCallingIdentity(); 14368 updateConfigurationLocked(values, null, true, false); 14369 Binder.restoreCallingIdentity(origId); 14370 } 14371 } 14372 14373 public void updateConfiguration(Configuration values) { 14374 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14375 "updateConfiguration()"); 14376 14377 synchronized(this) { 14378 if (values == null && mWindowManager != null) { 14379 // sentinel: fetch the current configuration from the window manager 14380 values = mWindowManager.computeNewConfiguration(); 14381 } 14382 14383 if (mWindowManager != null) { 14384 mProcessList.applyDisplaySize(mWindowManager); 14385 } 14386 14387 final long origId = Binder.clearCallingIdentity(); 14388 if (values != null) { 14389 Settings.System.clearConfiguration(values); 14390 } 14391 updateConfigurationLocked(values, null, false, false); 14392 Binder.restoreCallingIdentity(origId); 14393 } 14394 } 14395 14396 /** 14397 * Do either or both things: (1) change the current configuration, and (2) 14398 * make sure the given activity is running with the (now) current 14399 * configuration. Returns true if the activity has been left running, or 14400 * false if <var>starting</var> is being destroyed to match the new 14401 * configuration. 14402 * @param persistent TODO 14403 */ 14404 boolean updateConfigurationLocked(Configuration values, 14405 ActivityRecord starting, boolean persistent, boolean initLocale) { 14406 int changes = 0; 14407 14408 if (values != null) { 14409 Configuration newConfig = new Configuration(mConfiguration); 14410 changes = newConfig.updateFrom(values); 14411 if (changes != 0) { 14412 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14413 Slog.i(TAG, "Updating configuration to: " + values); 14414 } 14415 14416 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14417 14418 if (values.locale != null && !initLocale) { 14419 saveLocaleLocked(values.locale, 14420 !values.locale.equals(mConfiguration.locale), 14421 values.userSetLocale); 14422 } 14423 14424 mConfigurationSeq++; 14425 if (mConfigurationSeq <= 0) { 14426 mConfigurationSeq = 1; 14427 } 14428 newConfig.seq = mConfigurationSeq; 14429 mConfiguration = newConfig; 14430 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14431 14432 final Configuration configCopy = new Configuration(mConfiguration); 14433 14434 // TODO: If our config changes, should we auto dismiss any currently 14435 // showing dialogs? 14436 mShowDialogs = shouldShowDialogs(newConfig); 14437 14438 AttributeCache ac = AttributeCache.instance(); 14439 if (ac != null) { 14440 ac.updateConfiguration(configCopy); 14441 } 14442 14443 // Make sure all resources in our process are updated 14444 // right now, so that anyone who is going to retrieve 14445 // resource values after we return will be sure to get 14446 // the new ones. This is especially important during 14447 // boot, where the first config change needs to guarantee 14448 // all resources have that config before following boot 14449 // code is executed. 14450 mSystemThread.applyConfigurationToResources(configCopy); 14451 14452 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14453 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14454 msg.obj = new Configuration(configCopy); 14455 mHandler.sendMessage(msg); 14456 } 14457 14458 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14459 ProcessRecord app = mLruProcesses.get(i); 14460 try { 14461 if (app.thread != null) { 14462 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14463 + app.processName + " new config " + mConfiguration); 14464 app.thread.scheduleConfigurationChanged(configCopy); 14465 } 14466 } catch (Exception e) { 14467 } 14468 } 14469 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14470 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14471 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14472 | Intent.FLAG_RECEIVER_FOREGROUND); 14473 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14474 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14475 Process.SYSTEM_UID, UserHandle.USER_ALL); 14476 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14477 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14478 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14479 broadcastIntentLocked(null, null, intent, 14480 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14481 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14482 } 14483 } 14484 } 14485 14486 boolean kept = true; 14487 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14488 // mainStack is null during startup. 14489 if (mainStack != null) { 14490 if (changes != 0 && starting == null) { 14491 // If the configuration changed, and the caller is not already 14492 // in the process of starting an activity, then find the top 14493 // activity to check if its configuration needs to change. 14494 starting = mainStack.topRunningActivityLocked(null); 14495 } 14496 14497 if (starting != null) { 14498 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14499 // And we need to make sure at this point that all other activities 14500 // are made visible with the correct configuration. 14501 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14502 } 14503 } 14504 14505 if (values != null && mWindowManager != null) { 14506 mWindowManager.setNewConfiguration(mConfiguration); 14507 } 14508 14509 return kept; 14510 } 14511 14512 /** 14513 * Decide based on the configuration whether we should shouw the ANR, 14514 * crash, etc dialogs. The idea is that if there is no affordnace to 14515 * press the on-screen buttons, we shouldn't show the dialog. 14516 * 14517 * A thought: SystemUI might also want to get told about this, the Power 14518 * dialog / global actions also might want different behaviors. 14519 */ 14520 private static final boolean shouldShowDialogs(Configuration config) { 14521 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14522 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14523 } 14524 14525 /** 14526 * Save the locale. You must be inside a synchronized (this) block. 14527 */ 14528 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14529 if(isDiff) { 14530 SystemProperties.set("user.language", l.getLanguage()); 14531 SystemProperties.set("user.region", l.getCountry()); 14532 } 14533 14534 if(isPersist) { 14535 SystemProperties.set("persist.sys.language", l.getLanguage()); 14536 SystemProperties.set("persist.sys.country", l.getCountry()); 14537 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14538 } 14539 } 14540 14541 @Override 14542 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14543 ActivityRecord srec = ActivityRecord.forToken(token); 14544 return srec != null && srec.task.affinity != null && 14545 srec.task.affinity.equals(destAffinity); 14546 } 14547 14548 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14549 Intent resultData) { 14550 14551 synchronized (this) { 14552 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14553 if (stack != null) { 14554 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14555 } 14556 return false; 14557 } 14558 } 14559 14560 public int getLaunchedFromUid(IBinder activityToken) { 14561 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14562 if (srec == null) { 14563 return -1; 14564 } 14565 return srec.launchedFromUid; 14566 } 14567 14568 public String getLaunchedFromPackage(IBinder activityToken) { 14569 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14570 if (srec == null) { 14571 return null; 14572 } 14573 return srec.launchedFromPackage; 14574 } 14575 14576 // ========================================================= 14577 // LIFETIME MANAGEMENT 14578 // ========================================================= 14579 14580 // Returns which broadcast queue the app is the current [or imminent] receiver 14581 // on, or 'null' if the app is not an active broadcast recipient. 14582 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14583 BroadcastRecord r = app.curReceiver; 14584 if (r != null) { 14585 return r.queue; 14586 } 14587 14588 // It's not the current receiver, but it might be starting up to become one 14589 synchronized (this) { 14590 for (BroadcastQueue queue : mBroadcastQueues) { 14591 r = queue.mPendingBroadcast; 14592 if (r != null && r.curApp == app) { 14593 // found it; report which queue it's in 14594 return queue; 14595 } 14596 } 14597 } 14598 14599 return null; 14600 } 14601 14602 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14603 boolean doingAll, long now) { 14604 if (mAdjSeq == app.adjSeq) { 14605 // This adjustment has already been computed. 14606 return app.curRawAdj; 14607 } 14608 14609 if (app.thread == null) { 14610 app.adjSeq = mAdjSeq; 14611 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14612 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14613 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14614 } 14615 14616 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14617 app.adjSource = null; 14618 app.adjTarget = null; 14619 app.empty = false; 14620 app.cached = false; 14621 14622 final int activitiesSize = app.activities.size(); 14623 14624 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14625 // The max adjustment doesn't allow this app to be anything 14626 // below foreground, so it is not worth doing work for it. 14627 app.adjType = "fixed"; 14628 app.adjSeq = mAdjSeq; 14629 app.curRawAdj = app.maxAdj; 14630 app.foregroundActivities = false; 14631 app.keeping = true; 14632 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14633 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14634 // System process can do UI, and when they do we want to have 14635 // them trim their memory after the user leaves the UI. To 14636 // facilitate this, here we need to determine whether or not it 14637 // is currently showing UI. 14638 app.systemNoUi = true; 14639 if (app == TOP_APP) { 14640 app.systemNoUi = false; 14641 } else if (activitiesSize > 0) { 14642 for (int j = 0; j < activitiesSize; j++) { 14643 final ActivityRecord r = app.activities.get(j); 14644 if (r.visible) { 14645 app.systemNoUi = false; 14646 } 14647 } 14648 } 14649 if (!app.systemNoUi) { 14650 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14651 } 14652 return (app.curAdj=app.maxAdj); 14653 } 14654 14655 app.keeping = false; 14656 app.systemNoUi = false; 14657 14658 // Determine the importance of the process, starting with most 14659 // important to least, and assign an appropriate OOM adjustment. 14660 int adj; 14661 int schedGroup; 14662 int procState; 14663 boolean foregroundActivities = false; 14664 boolean interesting = false; 14665 BroadcastQueue queue; 14666 if (app == TOP_APP) { 14667 // The last app on the list is the foreground app. 14668 adj = ProcessList.FOREGROUND_APP_ADJ; 14669 schedGroup = Process.THREAD_GROUP_DEFAULT; 14670 app.adjType = "top-activity"; 14671 foregroundActivities = true; 14672 interesting = true; 14673 procState = ActivityManager.PROCESS_STATE_TOP; 14674 } else if (app.instrumentationClass != null) { 14675 // Don't want to kill running instrumentation. 14676 adj = ProcessList.FOREGROUND_APP_ADJ; 14677 schedGroup = Process.THREAD_GROUP_DEFAULT; 14678 app.adjType = "instrumentation"; 14679 interesting = true; 14680 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14681 } else if ((queue = isReceivingBroadcast(app)) != null) { 14682 // An app that is currently receiving a broadcast also 14683 // counts as being in the foreground for OOM killer purposes. 14684 // It's placed in a sched group based on the nature of the 14685 // broadcast as reflected by which queue it's active in. 14686 adj = ProcessList.FOREGROUND_APP_ADJ; 14687 schedGroup = (queue == mFgBroadcastQueue) 14688 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14689 app.adjType = "broadcast"; 14690 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14691 } else if (app.executingServices.size() > 0) { 14692 // An app that is currently executing a service callback also 14693 // counts as being in the foreground. 14694 adj = ProcessList.FOREGROUND_APP_ADJ; 14695 schedGroup = app.execServicesFg ? 14696 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14697 app.adjType = "exec-service"; 14698 procState = ActivityManager.PROCESS_STATE_SERVICE; 14699 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14700 } else { 14701 // As far as we know the process is empty. We may change our mind later. 14702 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14703 // At this point we don't actually know the adjustment. Use the cached adj 14704 // value that the caller wants us to. 14705 adj = cachedAdj; 14706 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14707 app.cached = true; 14708 app.empty = true; 14709 app.adjType = "cch-empty"; 14710 } 14711 14712 // Examine all activities if not already foreground. 14713 if (!foregroundActivities && activitiesSize > 0) { 14714 for (int j = 0; j < activitiesSize; j++) { 14715 final ActivityRecord r = app.activities.get(j); 14716 if (r.app != app) { 14717 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14718 + app + "?!?"); 14719 continue; 14720 } 14721 if (r.visible) { 14722 // App has a visible activity; only upgrade adjustment. 14723 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14724 adj = ProcessList.VISIBLE_APP_ADJ; 14725 app.adjType = "visible"; 14726 } 14727 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14728 procState = ActivityManager.PROCESS_STATE_TOP; 14729 } 14730 schedGroup = Process.THREAD_GROUP_DEFAULT; 14731 app.cached = false; 14732 app.empty = false; 14733 foregroundActivities = true; 14734 break; 14735 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14736 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14737 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14738 app.adjType = "pausing"; 14739 } 14740 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14741 procState = ActivityManager.PROCESS_STATE_TOP; 14742 } 14743 schedGroup = Process.THREAD_GROUP_DEFAULT; 14744 app.cached = false; 14745 app.empty = false; 14746 foregroundActivities = true; 14747 } else if (r.state == ActivityState.STOPPING) { 14748 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14749 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14750 app.adjType = "stopping"; 14751 } 14752 // For the process state, we will at this point consider the 14753 // process to be cached. It will be cached either as an activity 14754 // or empty depending on whether the activity is finishing. We do 14755 // this so that we can treat the process as cached for purposes of 14756 // memory trimming (determing current memory level, trim command to 14757 // send to process) since there can be an arbitrary number of stopping 14758 // processes and they should soon all go into the cached state. 14759 if (!r.finishing) { 14760 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14761 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14762 } 14763 } 14764 app.cached = false; 14765 app.empty = false; 14766 foregroundActivities = true; 14767 } else { 14768 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14769 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14770 app.adjType = "cch-act"; 14771 } 14772 } 14773 } 14774 } 14775 14776 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14777 if (app.foregroundServices) { 14778 // The user is aware of this app, so make it visible. 14779 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14780 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14781 app.cached = false; 14782 app.adjType = "fg-service"; 14783 schedGroup = Process.THREAD_GROUP_DEFAULT; 14784 } else if (app.forcingToForeground != null) { 14785 // The user is aware of this app, so make it visible. 14786 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14787 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14788 app.cached = false; 14789 app.adjType = "force-fg"; 14790 app.adjSource = app.forcingToForeground; 14791 schedGroup = Process.THREAD_GROUP_DEFAULT; 14792 } 14793 } 14794 14795 if (app.foregroundServices) { 14796 interesting = true; 14797 } 14798 14799 if (app == mHeavyWeightProcess) { 14800 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14801 // We don't want to kill the current heavy-weight process. 14802 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14803 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14804 app.cached = false; 14805 app.adjType = "heavy"; 14806 } 14807 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14808 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14809 } 14810 } 14811 14812 if (app == mHomeProcess) { 14813 if (adj > ProcessList.HOME_APP_ADJ) { 14814 // This process is hosting what we currently consider to be the 14815 // home app, so we don't want to let it go into the background. 14816 adj = ProcessList.HOME_APP_ADJ; 14817 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14818 app.cached = false; 14819 app.adjType = "home"; 14820 } 14821 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14822 procState = ActivityManager.PROCESS_STATE_HOME; 14823 } 14824 } 14825 14826 if (app == mPreviousProcess && app.activities.size() > 0) { 14827 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14828 // This was the previous process that showed UI to the user. 14829 // We want to try to keep it around more aggressively, to give 14830 // a good experience around switching between two apps. 14831 adj = ProcessList.PREVIOUS_APP_ADJ; 14832 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14833 app.cached = false; 14834 app.adjType = "previous"; 14835 } 14836 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14837 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14838 } 14839 } 14840 14841 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14842 + " reason=" + app.adjType); 14843 14844 // By default, we use the computed adjustment. It may be changed if 14845 // there are applications dependent on our services or providers, but 14846 // this gives us a baseline and makes sure we don't get into an 14847 // infinite recursion. 14848 app.adjSeq = mAdjSeq; 14849 app.curRawAdj = adj; 14850 app.hasStartedServices = false; 14851 14852 if (mBackupTarget != null && app == mBackupTarget.app) { 14853 // If possible we want to avoid killing apps while they're being backed up 14854 if (adj > ProcessList.BACKUP_APP_ADJ) { 14855 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14856 adj = ProcessList.BACKUP_APP_ADJ; 14857 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14858 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14859 } 14860 app.adjType = "backup"; 14861 app.cached = false; 14862 } 14863 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14864 procState = ActivityManager.PROCESS_STATE_BACKUP; 14865 } 14866 } 14867 14868 boolean mayBeTop = false; 14869 14870 for (int is = app.services.size()-1; 14871 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14872 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14873 || procState > ActivityManager.PROCESS_STATE_TOP); 14874 is--) { 14875 ServiceRecord s = app.services.valueAt(is); 14876 if (s.startRequested) { 14877 app.hasStartedServices = true; 14878 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14879 procState = ActivityManager.PROCESS_STATE_SERVICE; 14880 } 14881 if (app.hasShownUi && app != mHomeProcess) { 14882 // If this process has shown some UI, let it immediately 14883 // go to the LRU list because it may be pretty heavy with 14884 // UI stuff. We'll tag it with a label just to help 14885 // debug and understand what is going on. 14886 if (adj > ProcessList.SERVICE_ADJ) { 14887 app.adjType = "cch-started-ui-services"; 14888 } 14889 } else { 14890 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14891 // This service has seen some activity within 14892 // recent memory, so we will keep its process ahead 14893 // of the background processes. 14894 if (adj > ProcessList.SERVICE_ADJ) { 14895 adj = ProcessList.SERVICE_ADJ; 14896 app.adjType = "started-services"; 14897 app.cached = false; 14898 } 14899 } 14900 // If we have let the service slide into the background 14901 // state, still have some text describing what it is doing 14902 // even though the service no longer has an impact. 14903 if (adj > ProcessList.SERVICE_ADJ) { 14904 app.adjType = "cch-started-services"; 14905 } 14906 } 14907 // Don't kill this process because it is doing work; it 14908 // has said it is doing work. 14909 app.keeping = true; 14910 } 14911 for (int conni = s.connections.size()-1; 14912 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14913 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14914 || procState > ActivityManager.PROCESS_STATE_TOP); 14915 conni--) { 14916 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14917 for (int i = 0; 14918 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14919 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14920 || procState > ActivityManager.PROCESS_STATE_TOP); 14921 i++) { 14922 // XXX should compute this based on the max of 14923 // all connected clients. 14924 ConnectionRecord cr = clist.get(i); 14925 if (cr.binding.client == app) { 14926 // Binding to ourself is not interesting. 14927 continue; 14928 } 14929 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14930 ProcessRecord client = cr.binding.client; 14931 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14932 TOP_APP, doingAll, now); 14933 int clientProcState = client.curProcState; 14934 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14935 // If the other app is cached for any reason, for purposes here 14936 // we are going to consider it empty. The specific cached state 14937 // doesn't propagate except under certain conditions. 14938 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14939 } 14940 String adjType = null; 14941 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14942 // Not doing bind OOM management, so treat 14943 // this guy more like a started service. 14944 if (app.hasShownUi && app != mHomeProcess) { 14945 // If this process has shown some UI, let it immediately 14946 // go to the LRU list because it may be pretty heavy with 14947 // UI stuff. We'll tag it with a label just to help 14948 // debug and understand what is going on. 14949 if (adj > clientAdj) { 14950 adjType = "cch-bound-ui-services"; 14951 } 14952 app.cached = false; 14953 clientAdj = adj; 14954 clientProcState = procState; 14955 } else { 14956 if (now >= (s.lastActivity 14957 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14958 // This service has not seen activity within 14959 // recent memory, so allow it to drop to the 14960 // LRU list if there is no other reason to keep 14961 // it around. We'll also tag it with a label just 14962 // to help debug and undertand what is going on. 14963 if (adj > clientAdj) { 14964 adjType = "cch-bound-services"; 14965 } 14966 clientAdj = adj; 14967 } 14968 } 14969 } 14970 if (adj > clientAdj) { 14971 // If this process has recently shown UI, and 14972 // the process that is binding to it is less 14973 // important than being visible, then we don't 14974 // care about the binding as much as we care 14975 // about letting this process get into the LRU 14976 // list to be killed and restarted if needed for 14977 // memory. 14978 if (app.hasShownUi && app != mHomeProcess 14979 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14980 adjType = "cch-bound-ui-services"; 14981 } else { 14982 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14983 |Context.BIND_IMPORTANT)) != 0) { 14984 adj = clientAdj; 14985 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14986 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14987 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14988 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14989 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14990 adj = clientAdj; 14991 } else { 14992 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14993 adj = ProcessList.VISIBLE_APP_ADJ; 14994 } 14995 } 14996 if (!client.cached) { 14997 app.cached = false; 14998 } 14999 if (client.keeping) { 15000 app.keeping = true; 15001 } 15002 adjType = "service"; 15003 } 15004 } 15005 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15006 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15007 schedGroup = Process.THREAD_GROUP_DEFAULT; 15008 } 15009 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15010 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15011 // Special handling of clients who are in the top state. 15012 // We *may* want to consider this process to be in the 15013 // top state as well, but only if there is not another 15014 // reason for it to be running. Being on the top is a 15015 // special state, meaning you are specifically running 15016 // for the current top app. If the process is already 15017 // running in the background for some other reason, it 15018 // is more important to continue considering it to be 15019 // in the background state. 15020 mayBeTop = true; 15021 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15022 } else { 15023 // Special handling for above-top states (persistent 15024 // processes). These should not bring the current process 15025 // into the top state, since they are not on top. Instead 15026 // give them the best state after that. 15027 clientProcState = 15028 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15029 } 15030 } 15031 } else { 15032 if (clientProcState < 15033 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15034 clientProcState = 15035 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15036 } 15037 } 15038 if (procState > clientProcState) { 15039 procState = clientProcState; 15040 } 15041 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15042 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15043 app.pendingUiClean = true; 15044 } 15045 if (adjType != null) { 15046 app.adjType = adjType; 15047 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15048 .REASON_SERVICE_IN_USE; 15049 app.adjSource = cr.binding.client; 15050 app.adjSourceOom = clientAdj; 15051 app.adjTarget = s.name; 15052 } 15053 } 15054 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15055 app.treatLikeActivity = true; 15056 } 15057 final ActivityRecord a = cr.activity; 15058 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15059 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15060 (a.visible || a.state == ActivityState.RESUMED 15061 || a.state == ActivityState.PAUSING)) { 15062 adj = ProcessList.FOREGROUND_APP_ADJ; 15063 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15064 schedGroup = Process.THREAD_GROUP_DEFAULT; 15065 } 15066 app.cached = false; 15067 app.adjType = "service"; 15068 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15069 .REASON_SERVICE_IN_USE; 15070 app.adjSource = a; 15071 app.adjSourceOom = adj; 15072 app.adjTarget = s.name; 15073 } 15074 } 15075 } 15076 } 15077 } 15078 15079 for (int provi = app.pubProviders.size()-1; 15080 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15081 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15082 || procState > ActivityManager.PROCESS_STATE_TOP); 15083 provi--) { 15084 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15085 for (int i = cpr.connections.size()-1; 15086 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15087 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15088 || procState > ActivityManager.PROCESS_STATE_TOP); 15089 i--) { 15090 ContentProviderConnection conn = cpr.connections.get(i); 15091 ProcessRecord client = conn.client; 15092 if (client == app) { 15093 // Being our own client is not interesting. 15094 continue; 15095 } 15096 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15097 int clientProcState = client.curProcState; 15098 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15099 // If the other app is cached for any reason, for purposes here 15100 // we are going to consider it empty. 15101 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15102 } 15103 if (adj > clientAdj) { 15104 if (app.hasShownUi && app != mHomeProcess 15105 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15106 app.adjType = "cch-ui-provider"; 15107 } else { 15108 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15109 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15110 app.adjType = "provider"; 15111 } 15112 app.cached &= client.cached; 15113 app.keeping |= client.keeping; 15114 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15115 .REASON_PROVIDER_IN_USE; 15116 app.adjSource = client; 15117 app.adjSourceOom = clientAdj; 15118 app.adjTarget = cpr.name; 15119 } 15120 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15121 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15122 // Special handling of clients who are in the top state. 15123 // We *may* want to consider this process to be in the 15124 // top state as well, but only if there is not another 15125 // reason for it to be running. Being on the top is a 15126 // special state, meaning you are specifically running 15127 // for the current top app. If the process is already 15128 // running in the background for some other reason, it 15129 // is more important to continue considering it to be 15130 // in the background state. 15131 mayBeTop = true; 15132 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15133 } else { 15134 // Special handling for above-top states (persistent 15135 // processes). These should not bring the current process 15136 // into the top state, since they are not on top. Instead 15137 // give them the best state after that. 15138 clientProcState = 15139 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15140 } 15141 } 15142 if (procState > clientProcState) { 15143 procState = clientProcState; 15144 } 15145 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15146 schedGroup = Process.THREAD_GROUP_DEFAULT; 15147 } 15148 } 15149 // If the provider has external (non-framework) process 15150 // dependencies, ensure that its adjustment is at least 15151 // FOREGROUND_APP_ADJ. 15152 if (cpr.hasExternalProcessHandles()) { 15153 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15154 adj = ProcessList.FOREGROUND_APP_ADJ; 15155 schedGroup = Process.THREAD_GROUP_DEFAULT; 15156 app.cached = false; 15157 app.keeping = true; 15158 app.adjType = "provider"; 15159 app.adjTarget = cpr.name; 15160 } 15161 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15162 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15163 } 15164 } 15165 } 15166 15167 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15168 // A client of one of our services or providers is in the top state. We 15169 // *may* want to be in the top state, but not if we are already running in 15170 // the background for some other reason. For the decision here, we are going 15171 // to pick out a few specific states that we want to remain in when a client 15172 // is top (states that tend to be longer-term) and otherwise allow it to go 15173 // to the top state. 15174 switch (procState) { 15175 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15176 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15177 case ActivityManager.PROCESS_STATE_SERVICE: 15178 // These all are longer-term states, so pull them up to the top 15179 // of the background states, but not all the way to the top state. 15180 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15181 break; 15182 default: 15183 // Otherwise, top is a better choice, so take it. 15184 procState = ActivityManager.PROCESS_STATE_TOP; 15185 break; 15186 } 15187 } 15188 15189 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15190 if (app.hasClientActivities) { 15191 // This is a cached process, but with client activities. Mark it so. 15192 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15193 app.adjType = "cch-client-act"; 15194 } else if (app.treatLikeActivity) { 15195 // This is a cached process, but somebody wants us to treat it like it has 15196 // an activity, okay! 15197 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15198 app.adjType = "cch-as-act"; 15199 } 15200 } 15201 15202 if (adj == ProcessList.SERVICE_ADJ) { 15203 if (doingAll) { 15204 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15205 mNewNumServiceProcs++; 15206 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15207 if (!app.serviceb) { 15208 // This service isn't far enough down on the LRU list to 15209 // normally be a B service, but if we are low on RAM and it 15210 // is large we want to force it down since we would prefer to 15211 // keep launcher over it. 15212 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15213 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15214 app.serviceHighRam = true; 15215 app.serviceb = true; 15216 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15217 } else { 15218 mNewNumAServiceProcs++; 15219 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15220 } 15221 } else { 15222 app.serviceHighRam = false; 15223 } 15224 } 15225 if (app.serviceb) { 15226 adj = ProcessList.SERVICE_B_ADJ; 15227 } 15228 } 15229 15230 app.curRawAdj = adj; 15231 15232 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15233 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15234 if (adj > app.maxAdj) { 15235 adj = app.maxAdj; 15236 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15237 schedGroup = Process.THREAD_GROUP_DEFAULT; 15238 } 15239 } 15240 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15241 app.keeping = true; 15242 } 15243 15244 // Do final modification to adj. Everything we do between here and applying 15245 // the final setAdj must be done in this function, because we will also use 15246 // it when computing the final cached adj later. Note that we don't need to 15247 // worry about this for max adj above, since max adj will always be used to 15248 // keep it out of the cached vaues. 15249 adj = app.modifyRawOomAdj(adj); 15250 15251 app.curProcState = procState; 15252 15253 int importance = app.memImportance; 15254 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15255 app.curAdj = adj; 15256 app.curSchedGroup = schedGroup; 15257 if (!interesting) { 15258 // For this reporting, if there is not something explicitly 15259 // interesting in this process then we will push it to the 15260 // background importance. 15261 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15262 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15263 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15264 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15265 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15266 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15267 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15268 } else if (adj >= ProcessList.SERVICE_ADJ) { 15269 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15270 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15271 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15272 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15273 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15274 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15275 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15276 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15277 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15278 } else { 15279 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15280 } 15281 } 15282 15283 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15284 if (foregroundActivities != app.foregroundActivities) { 15285 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15286 } 15287 if (changes != 0) { 15288 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15289 app.memImportance = importance; 15290 app.foregroundActivities = foregroundActivities; 15291 int i = mPendingProcessChanges.size()-1; 15292 ProcessChangeItem item = null; 15293 while (i >= 0) { 15294 item = mPendingProcessChanges.get(i); 15295 if (item.pid == app.pid) { 15296 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15297 break; 15298 } 15299 i--; 15300 } 15301 if (i < 0) { 15302 // No existing item in pending changes; need a new one. 15303 final int NA = mAvailProcessChanges.size(); 15304 if (NA > 0) { 15305 item = mAvailProcessChanges.remove(NA-1); 15306 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15307 } else { 15308 item = new ProcessChangeItem(); 15309 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15310 } 15311 item.changes = 0; 15312 item.pid = app.pid; 15313 item.uid = app.info.uid; 15314 if (mPendingProcessChanges.size() == 0) { 15315 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15316 "*** Enqueueing dispatch processes changed!"); 15317 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15318 } 15319 mPendingProcessChanges.add(item); 15320 } 15321 item.changes |= changes; 15322 item.importance = importance; 15323 item.foregroundActivities = foregroundActivities; 15324 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15325 + Integer.toHexString(System.identityHashCode(item)) 15326 + " " + app.toShortString() + ": changes=" + item.changes 15327 + " importance=" + item.importance 15328 + " foreground=" + item.foregroundActivities 15329 + " type=" + app.adjType + " source=" + app.adjSource 15330 + " target=" + app.adjTarget); 15331 } 15332 15333 return app.curRawAdj; 15334 } 15335 15336 /** 15337 * Schedule PSS collection of a process. 15338 */ 15339 void requestPssLocked(ProcessRecord proc, int procState) { 15340 if (mPendingPssProcesses.contains(proc)) { 15341 return; 15342 } 15343 if (mPendingPssProcesses.size() == 0) { 15344 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15345 } 15346 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15347 proc.pssProcState = procState; 15348 mPendingPssProcesses.add(proc); 15349 } 15350 15351 /** 15352 * Schedule PSS collection of all processes. 15353 */ 15354 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15355 if (!always) { 15356 if (now < (mLastFullPssTime + 15357 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15358 return; 15359 } 15360 } 15361 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15362 mLastFullPssTime = now; 15363 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15364 mPendingPssProcesses.clear(); 15365 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15366 ProcessRecord app = mLruProcesses.get(i); 15367 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15368 app.pssProcState = app.setProcState; 15369 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15370 isSleeping(), now); 15371 mPendingPssProcesses.add(app); 15372 } 15373 } 15374 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15375 } 15376 15377 /** 15378 * Ask a given process to GC right now. 15379 */ 15380 final void performAppGcLocked(ProcessRecord app) { 15381 try { 15382 app.lastRequestedGc = SystemClock.uptimeMillis(); 15383 if (app.thread != null) { 15384 if (app.reportLowMemory) { 15385 app.reportLowMemory = false; 15386 app.thread.scheduleLowMemory(); 15387 } else { 15388 app.thread.processInBackground(); 15389 } 15390 } 15391 } catch (Exception e) { 15392 // whatever. 15393 } 15394 } 15395 15396 /** 15397 * Returns true if things are idle enough to perform GCs. 15398 */ 15399 private final boolean canGcNowLocked() { 15400 boolean processingBroadcasts = false; 15401 for (BroadcastQueue q : mBroadcastQueues) { 15402 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15403 processingBroadcasts = true; 15404 } 15405 } 15406 return !processingBroadcasts 15407 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15408 } 15409 15410 /** 15411 * Perform GCs on all processes that are waiting for it, but only 15412 * if things are idle. 15413 */ 15414 final void performAppGcsLocked() { 15415 final int N = mProcessesToGc.size(); 15416 if (N <= 0) { 15417 return; 15418 } 15419 if (canGcNowLocked()) { 15420 while (mProcessesToGc.size() > 0) { 15421 ProcessRecord proc = mProcessesToGc.remove(0); 15422 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15423 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15424 <= SystemClock.uptimeMillis()) { 15425 // To avoid spamming the system, we will GC processes one 15426 // at a time, waiting a few seconds between each. 15427 performAppGcLocked(proc); 15428 scheduleAppGcsLocked(); 15429 return; 15430 } else { 15431 // It hasn't been long enough since we last GCed this 15432 // process... put it in the list to wait for its time. 15433 addProcessToGcListLocked(proc); 15434 break; 15435 } 15436 } 15437 } 15438 15439 scheduleAppGcsLocked(); 15440 } 15441 } 15442 15443 /** 15444 * If all looks good, perform GCs on all processes waiting for them. 15445 */ 15446 final void performAppGcsIfAppropriateLocked() { 15447 if (canGcNowLocked()) { 15448 performAppGcsLocked(); 15449 return; 15450 } 15451 // Still not idle, wait some more. 15452 scheduleAppGcsLocked(); 15453 } 15454 15455 /** 15456 * Schedule the execution of all pending app GCs. 15457 */ 15458 final void scheduleAppGcsLocked() { 15459 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15460 15461 if (mProcessesToGc.size() > 0) { 15462 // Schedule a GC for the time to the next process. 15463 ProcessRecord proc = mProcessesToGc.get(0); 15464 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15465 15466 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15467 long now = SystemClock.uptimeMillis(); 15468 if (when < (now+GC_TIMEOUT)) { 15469 when = now + GC_TIMEOUT; 15470 } 15471 mHandler.sendMessageAtTime(msg, when); 15472 } 15473 } 15474 15475 /** 15476 * Add a process to the array of processes waiting to be GCed. Keeps the 15477 * list in sorted order by the last GC time. The process can't already be 15478 * on the list. 15479 */ 15480 final void addProcessToGcListLocked(ProcessRecord proc) { 15481 boolean added = false; 15482 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15483 if (mProcessesToGc.get(i).lastRequestedGc < 15484 proc.lastRequestedGc) { 15485 added = true; 15486 mProcessesToGc.add(i+1, proc); 15487 break; 15488 } 15489 } 15490 if (!added) { 15491 mProcessesToGc.add(0, proc); 15492 } 15493 } 15494 15495 /** 15496 * Set up to ask a process to GC itself. This will either do it 15497 * immediately, or put it on the list of processes to gc the next 15498 * time things are idle. 15499 */ 15500 final void scheduleAppGcLocked(ProcessRecord app) { 15501 long now = SystemClock.uptimeMillis(); 15502 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15503 return; 15504 } 15505 if (!mProcessesToGc.contains(app)) { 15506 addProcessToGcListLocked(app); 15507 scheduleAppGcsLocked(); 15508 } 15509 } 15510 15511 final void checkExcessivePowerUsageLocked(boolean doKills) { 15512 updateCpuStatsNow(); 15513 15514 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15515 boolean doWakeKills = doKills; 15516 boolean doCpuKills = doKills; 15517 if (mLastPowerCheckRealtime == 0) { 15518 doWakeKills = false; 15519 } 15520 if (mLastPowerCheckUptime == 0) { 15521 doCpuKills = false; 15522 } 15523 if (stats.isScreenOn()) { 15524 doWakeKills = false; 15525 } 15526 final long curRealtime = SystemClock.elapsedRealtime(); 15527 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15528 final long curUptime = SystemClock.uptimeMillis(); 15529 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15530 mLastPowerCheckRealtime = curRealtime; 15531 mLastPowerCheckUptime = curUptime; 15532 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15533 doWakeKills = false; 15534 } 15535 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15536 doCpuKills = false; 15537 } 15538 int i = mLruProcesses.size(); 15539 while (i > 0) { 15540 i--; 15541 ProcessRecord app = mLruProcesses.get(i); 15542 if (!app.keeping) { 15543 long wtime; 15544 synchronized (stats) { 15545 wtime = stats.getProcessWakeTime(app.info.uid, 15546 app.pid, curRealtime); 15547 } 15548 long wtimeUsed = wtime - app.lastWakeTime; 15549 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15550 if (DEBUG_POWER) { 15551 StringBuilder sb = new StringBuilder(128); 15552 sb.append("Wake for "); 15553 app.toShortString(sb); 15554 sb.append(": over "); 15555 TimeUtils.formatDuration(realtimeSince, sb); 15556 sb.append(" used "); 15557 TimeUtils.formatDuration(wtimeUsed, sb); 15558 sb.append(" ("); 15559 sb.append((wtimeUsed*100)/realtimeSince); 15560 sb.append("%)"); 15561 Slog.i(TAG, sb.toString()); 15562 sb.setLength(0); 15563 sb.append("CPU for "); 15564 app.toShortString(sb); 15565 sb.append(": over "); 15566 TimeUtils.formatDuration(uptimeSince, sb); 15567 sb.append(" used "); 15568 TimeUtils.formatDuration(cputimeUsed, sb); 15569 sb.append(" ("); 15570 sb.append((cputimeUsed*100)/uptimeSince); 15571 sb.append("%)"); 15572 Slog.i(TAG, sb.toString()); 15573 } 15574 // If a process has held a wake lock for more 15575 // than 50% of the time during this period, 15576 // that sounds bad. Kill! 15577 if (doWakeKills && realtimeSince > 0 15578 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15579 synchronized (stats) { 15580 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15581 realtimeSince, wtimeUsed); 15582 } 15583 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15584 + " during " + realtimeSince); 15585 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15586 } else if (doCpuKills && uptimeSince > 0 15587 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15588 synchronized (stats) { 15589 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15590 uptimeSince, cputimeUsed); 15591 } 15592 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15593 + " during " + uptimeSince); 15594 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15595 } else { 15596 app.lastWakeTime = wtime; 15597 app.lastCpuTime = app.curCpuTime; 15598 } 15599 } 15600 } 15601 } 15602 15603 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15604 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15605 boolean success = true; 15606 15607 if (app.curRawAdj != app.setRawAdj) { 15608 if (wasKeeping && !app.keeping) { 15609 // This app is no longer something we want to keep. Note 15610 // its current wake lock time to later know to kill it if 15611 // it is not behaving well. 15612 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15613 synchronized (stats) { 15614 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15615 app.pid, SystemClock.elapsedRealtime()); 15616 } 15617 app.lastCpuTime = app.curCpuTime; 15618 } 15619 15620 app.setRawAdj = app.curRawAdj; 15621 } 15622 15623 if (app.curAdj != app.setAdj) { 15624 ProcessList.setOomAdj(app.pid, app.curAdj); 15625 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15626 TAG, "Set " + app.pid + " " + app.processName + 15627 " adj " + app.curAdj + ": " + app.adjType); 15628 app.setAdj = app.curAdj; 15629 } 15630 15631 if (app.setSchedGroup != app.curSchedGroup) { 15632 app.setSchedGroup = app.curSchedGroup; 15633 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15634 "Setting process group of " + app.processName 15635 + " to " + app.curSchedGroup); 15636 if (app.waitingToKill != null && 15637 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15638 killUnneededProcessLocked(app, app.waitingToKill); 15639 success = false; 15640 } else { 15641 if (true) { 15642 long oldId = Binder.clearCallingIdentity(); 15643 try { 15644 Process.setProcessGroup(app.pid, app.curSchedGroup); 15645 } catch (Exception e) { 15646 Slog.w(TAG, "Failed setting process group of " + app.pid 15647 + " to " + app.curSchedGroup); 15648 e.printStackTrace(); 15649 } finally { 15650 Binder.restoreCallingIdentity(oldId); 15651 } 15652 } else { 15653 if (app.thread != null) { 15654 try { 15655 app.thread.setSchedulingGroup(app.curSchedGroup); 15656 } catch (RemoteException e) { 15657 } 15658 } 15659 } 15660 Process.setSwappiness(app.pid, 15661 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15662 } 15663 } 15664 if (app.repProcState != app.curProcState) { 15665 app.repProcState = app.curProcState; 15666 if (!reportingProcessState && app.thread != null) { 15667 try { 15668 if (false) { 15669 //RuntimeException h = new RuntimeException("here"); 15670 Slog.i(TAG, "Sending new process state " + app.repProcState 15671 + " to " + app /*, h*/); 15672 } 15673 app.thread.setProcessState(app.repProcState); 15674 } catch (RemoteException e) { 15675 } 15676 } 15677 } 15678 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15679 app.setProcState)) { 15680 app.lastStateTime = now; 15681 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15682 isSleeping(), now); 15683 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15684 + ProcessList.makeProcStateString(app.setProcState) + " to " 15685 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15686 + (app.nextPssTime-now) + ": " + app); 15687 } else { 15688 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15689 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15690 requestPssLocked(app, app.setProcState); 15691 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15692 isSleeping(), now); 15693 } else if (false && DEBUG_PSS) { 15694 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15695 } 15696 } 15697 if (app.setProcState != app.curProcState) { 15698 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15699 "Proc state change of " + app.processName 15700 + " to " + app.curProcState); 15701 app.setProcState = app.curProcState; 15702 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15703 app.notCachedSinceIdle = false; 15704 } 15705 if (!doingAll) { 15706 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15707 } else { 15708 app.procStateChanged = true; 15709 } 15710 } 15711 return success; 15712 } 15713 15714 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15715 if (proc.thread != null && proc.baseProcessTracker != null) { 15716 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15717 } 15718 } 15719 15720 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15721 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15722 if (app.thread == null) { 15723 return false; 15724 } 15725 15726 final boolean wasKeeping = app.keeping; 15727 15728 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15729 15730 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15731 reportingProcessState, now); 15732 } 15733 15734 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15735 boolean oomAdj) { 15736 if (isForeground != proc.foregroundServices) { 15737 proc.foregroundServices = isForeground; 15738 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15739 proc.info.uid); 15740 if (isForeground) { 15741 if (curProcs == null) { 15742 curProcs = new ArrayList<ProcessRecord>(); 15743 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15744 } 15745 if (!curProcs.contains(proc)) { 15746 curProcs.add(proc); 15747 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15748 proc.info.packageName, proc.info.uid); 15749 } 15750 } else { 15751 if (curProcs != null) { 15752 if (curProcs.remove(proc)) { 15753 mBatteryStatsService.noteEvent( 15754 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15755 proc.info.packageName, proc.info.uid); 15756 if (curProcs.size() <= 0) { 15757 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15758 } 15759 } 15760 } 15761 } 15762 if (oomAdj) { 15763 updateOomAdjLocked(); 15764 } 15765 } 15766 } 15767 15768 private final ActivityRecord resumedAppLocked() { 15769 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15770 String pkg; 15771 int uid; 15772 if (act != null && !act.sleeping) { 15773 pkg = act.packageName; 15774 uid = act.info.applicationInfo.uid; 15775 } else { 15776 pkg = null; 15777 uid = -1; 15778 } 15779 // Has the UID or resumed package name changed? 15780 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15781 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15782 if (mCurResumedPackage != null) { 15783 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15784 mCurResumedPackage, mCurResumedUid); 15785 } 15786 mCurResumedPackage = pkg; 15787 mCurResumedUid = uid; 15788 if (mCurResumedPackage != null) { 15789 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15790 mCurResumedPackage, mCurResumedUid); 15791 } 15792 } 15793 return act; 15794 } 15795 15796 final boolean updateOomAdjLocked(ProcessRecord app) { 15797 return updateOomAdjLocked(app, false); 15798 } 15799 15800 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15801 final ActivityRecord TOP_ACT = resumedAppLocked(); 15802 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15803 final boolean wasCached = app.cached; 15804 15805 mAdjSeq++; 15806 15807 // This is the desired cached adjusment we want to tell it to use. 15808 // If our app is currently cached, we know it, and that is it. Otherwise, 15809 // we don't know it yet, and it needs to now be cached we will then 15810 // need to do a complete oom adj. 15811 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15812 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15813 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15814 SystemClock.uptimeMillis()); 15815 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15816 // Changed to/from cached state, so apps after it in the LRU 15817 // list may also be changed. 15818 updateOomAdjLocked(); 15819 } 15820 return success; 15821 } 15822 15823 final void updateOomAdjLocked() { 15824 final ActivityRecord TOP_ACT = resumedAppLocked(); 15825 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15826 final long now = SystemClock.uptimeMillis(); 15827 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15828 final int N = mLruProcesses.size(); 15829 15830 if (false) { 15831 RuntimeException e = new RuntimeException(); 15832 e.fillInStackTrace(); 15833 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15834 } 15835 15836 mAdjSeq++; 15837 mNewNumServiceProcs = 0; 15838 mNewNumAServiceProcs = 0; 15839 15840 final int emptyProcessLimit; 15841 final int cachedProcessLimit; 15842 if (mProcessLimit <= 0) { 15843 emptyProcessLimit = cachedProcessLimit = 0; 15844 } else if (mProcessLimit == 1) { 15845 emptyProcessLimit = 1; 15846 cachedProcessLimit = 0; 15847 } else { 15848 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15849 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15850 } 15851 15852 // Let's determine how many processes we have running vs. 15853 // how many slots we have for background processes; we may want 15854 // to put multiple processes in a slot of there are enough of 15855 // them. 15856 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15857 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15858 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15859 if (numEmptyProcs > cachedProcessLimit) { 15860 // If there are more empty processes than our limit on cached 15861 // processes, then use the cached process limit for the factor. 15862 // This ensures that the really old empty processes get pushed 15863 // down to the bottom, so if we are running low on memory we will 15864 // have a better chance at keeping around more cached processes 15865 // instead of a gazillion empty processes. 15866 numEmptyProcs = cachedProcessLimit; 15867 } 15868 int emptyFactor = numEmptyProcs/numSlots; 15869 if (emptyFactor < 1) emptyFactor = 1; 15870 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15871 if (cachedFactor < 1) cachedFactor = 1; 15872 int stepCached = 0; 15873 int stepEmpty = 0; 15874 int numCached = 0; 15875 int numEmpty = 0; 15876 int numTrimming = 0; 15877 15878 mNumNonCachedProcs = 0; 15879 mNumCachedHiddenProcs = 0; 15880 15881 // First update the OOM adjustment for each of the 15882 // application processes based on their current state. 15883 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15884 int nextCachedAdj = curCachedAdj+1; 15885 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15886 int nextEmptyAdj = curEmptyAdj+2; 15887 for (int i=N-1; i>=0; i--) { 15888 ProcessRecord app = mLruProcesses.get(i); 15889 if (!app.killedByAm && app.thread != null) { 15890 app.procStateChanged = false; 15891 final boolean wasKeeping = app.keeping; 15892 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15893 15894 // If we haven't yet assigned the final cached adj 15895 // to the process, do that now. 15896 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15897 switch (app.curProcState) { 15898 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15899 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15900 // This process is a cached process holding activities... 15901 // assign it the next cached value for that type, and then 15902 // step that cached level. 15903 app.curRawAdj = curCachedAdj; 15904 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15905 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15906 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15907 + ")"); 15908 if (curCachedAdj != nextCachedAdj) { 15909 stepCached++; 15910 if (stepCached >= cachedFactor) { 15911 stepCached = 0; 15912 curCachedAdj = nextCachedAdj; 15913 nextCachedAdj += 2; 15914 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15915 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15916 } 15917 } 15918 } 15919 break; 15920 default: 15921 // For everything else, assign next empty cached process 15922 // level and bump that up. Note that this means that 15923 // long-running services that have dropped down to the 15924 // cached level will be treated as empty (since their process 15925 // state is still as a service), which is what we want. 15926 app.curRawAdj = curEmptyAdj; 15927 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15928 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15929 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15930 + ")"); 15931 if (curEmptyAdj != nextEmptyAdj) { 15932 stepEmpty++; 15933 if (stepEmpty >= emptyFactor) { 15934 stepEmpty = 0; 15935 curEmptyAdj = nextEmptyAdj; 15936 nextEmptyAdj += 2; 15937 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15938 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15939 } 15940 } 15941 } 15942 break; 15943 } 15944 } 15945 15946 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15947 15948 // Count the number of process types. 15949 switch (app.curProcState) { 15950 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15951 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15952 mNumCachedHiddenProcs++; 15953 numCached++; 15954 if (numCached > cachedProcessLimit) { 15955 killUnneededProcessLocked(app, "cached #" + numCached); 15956 } 15957 break; 15958 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15959 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15960 && app.lastActivityTime < oldTime) { 15961 killUnneededProcessLocked(app, "empty for " 15962 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15963 / 1000) + "s"); 15964 } else { 15965 numEmpty++; 15966 if (numEmpty > emptyProcessLimit) { 15967 killUnneededProcessLocked(app, "empty #" + numEmpty); 15968 } 15969 } 15970 break; 15971 default: 15972 mNumNonCachedProcs++; 15973 break; 15974 } 15975 15976 if (app.isolated && app.services.size() <= 0) { 15977 // If this is an isolated process, and there are no 15978 // services running in it, then the process is no longer 15979 // needed. We agressively kill these because we can by 15980 // definition not re-use the same process again, and it is 15981 // good to avoid having whatever code was running in them 15982 // left sitting around after no longer needed. 15983 killUnneededProcessLocked(app, "isolated not needed"); 15984 } 15985 15986 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15987 && !app.killedByAm) { 15988 numTrimming++; 15989 } 15990 } 15991 } 15992 15993 mNumServiceProcs = mNewNumServiceProcs; 15994 15995 // Now determine the memory trimming level of background processes. 15996 // Unfortunately we need to start at the back of the list to do this 15997 // properly. We only do this if the number of background apps we 15998 // are managing to keep around is less than half the maximum we desire; 15999 // if we are keeping a good number around, we'll let them use whatever 16000 // memory they want. 16001 final int numCachedAndEmpty = numCached + numEmpty; 16002 int memFactor; 16003 if (numCached <= ProcessList.TRIM_CACHED_APPS 16004 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16005 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16006 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16007 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16008 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16009 } else { 16010 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16011 } 16012 } else { 16013 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16014 } 16015 // We always allow the memory level to go up (better). We only allow it to go 16016 // down if we are in a state where that is allowed, *and* the total number of processes 16017 // has gone down since last time. 16018 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16019 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16020 + " last=" + mLastNumProcesses); 16021 if (memFactor > mLastMemoryLevel) { 16022 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16023 memFactor = mLastMemoryLevel; 16024 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16025 } 16026 } 16027 mLastMemoryLevel = memFactor; 16028 mLastNumProcesses = mLruProcesses.size(); 16029 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16030 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16031 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16032 if (mLowRamStartTime == 0) { 16033 mLowRamStartTime = now; 16034 } 16035 int step = 0; 16036 int fgTrimLevel; 16037 switch (memFactor) { 16038 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16039 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16040 break; 16041 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16042 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16043 break; 16044 default: 16045 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16046 break; 16047 } 16048 int factor = numTrimming/3; 16049 int minFactor = 2; 16050 if (mHomeProcess != null) minFactor++; 16051 if (mPreviousProcess != null) minFactor++; 16052 if (factor < minFactor) factor = minFactor; 16053 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16054 for (int i=N-1; i>=0; i--) { 16055 ProcessRecord app = mLruProcesses.get(i); 16056 if (allChanged || app.procStateChanged) { 16057 setProcessTrackerState(app, trackerMemFactor, now); 16058 app.procStateChanged = false; 16059 } 16060 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16061 && !app.killedByAm) { 16062 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16063 try { 16064 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16065 "Trimming memory of " + app.processName 16066 + " to " + curLevel); 16067 app.thread.scheduleTrimMemory(curLevel); 16068 } catch (RemoteException e) { 16069 } 16070 if (false) { 16071 // For now we won't do this; our memory trimming seems 16072 // to be good enough at this point that destroying 16073 // activities causes more harm than good. 16074 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16075 && app != mHomeProcess && app != mPreviousProcess) { 16076 // Need to do this on its own message because the stack may not 16077 // be in a consistent state at this point. 16078 // For these apps we will also finish their activities 16079 // to help them free memory. 16080 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16081 } 16082 } 16083 } 16084 app.trimMemoryLevel = curLevel; 16085 step++; 16086 if (step >= factor) { 16087 step = 0; 16088 switch (curLevel) { 16089 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16090 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16091 break; 16092 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16093 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16094 break; 16095 } 16096 } 16097 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16098 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16099 && app.thread != null) { 16100 try { 16101 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16102 "Trimming memory of heavy-weight " + app.processName 16103 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16104 app.thread.scheduleTrimMemory( 16105 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16106 } catch (RemoteException e) { 16107 } 16108 } 16109 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16110 } else { 16111 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16112 || app.systemNoUi) && app.pendingUiClean) { 16113 // If this application is now in the background and it 16114 // had done UI, then give it the special trim level to 16115 // have it free UI resources. 16116 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16117 if (app.trimMemoryLevel < level && app.thread != null) { 16118 try { 16119 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16120 "Trimming memory of bg-ui " + app.processName 16121 + " to " + level); 16122 app.thread.scheduleTrimMemory(level); 16123 } catch (RemoteException e) { 16124 } 16125 } 16126 app.pendingUiClean = false; 16127 } 16128 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16129 try { 16130 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16131 "Trimming memory of fg " + app.processName 16132 + " to " + fgTrimLevel); 16133 app.thread.scheduleTrimMemory(fgTrimLevel); 16134 } catch (RemoteException e) { 16135 } 16136 } 16137 app.trimMemoryLevel = fgTrimLevel; 16138 } 16139 } 16140 } else { 16141 if (mLowRamStartTime != 0) { 16142 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16143 mLowRamStartTime = 0; 16144 } 16145 for (int i=N-1; i>=0; i--) { 16146 ProcessRecord app = mLruProcesses.get(i); 16147 if (allChanged || app.procStateChanged) { 16148 setProcessTrackerState(app, trackerMemFactor, now); 16149 app.procStateChanged = false; 16150 } 16151 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16152 || app.systemNoUi) && app.pendingUiClean) { 16153 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16154 && app.thread != null) { 16155 try { 16156 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16157 "Trimming memory of ui hidden " + app.processName 16158 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16159 app.thread.scheduleTrimMemory( 16160 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16161 } catch (RemoteException e) { 16162 } 16163 } 16164 app.pendingUiClean = false; 16165 } 16166 app.trimMemoryLevel = 0; 16167 } 16168 } 16169 16170 if (mAlwaysFinishActivities) { 16171 // Need to do this on its own message because the stack may not 16172 // be in a consistent state at this point. 16173 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16174 } 16175 16176 if (allChanged) { 16177 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16178 } 16179 16180 if (mProcessStats.shouldWriteNowLocked(now)) { 16181 mHandler.post(new Runnable() { 16182 @Override public void run() { 16183 synchronized (ActivityManagerService.this) { 16184 mProcessStats.writeStateAsyncLocked(); 16185 } 16186 } 16187 }); 16188 } 16189 16190 if (DEBUG_OOM_ADJ) { 16191 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16192 } 16193 } 16194 16195 final void trimApplications() { 16196 synchronized (this) { 16197 int i; 16198 16199 // First remove any unused application processes whose package 16200 // has been removed. 16201 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16202 final ProcessRecord app = mRemovedProcesses.get(i); 16203 if (app.activities.size() == 0 16204 && app.curReceiver == null && app.services.size() == 0) { 16205 Slog.i( 16206 TAG, "Exiting empty application process " 16207 + app.processName + " (" 16208 + (app.thread != null ? app.thread.asBinder() : null) 16209 + ")\n"); 16210 if (app.pid > 0 && app.pid != MY_PID) { 16211 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16212 app.processName, app.setAdj, "empty"); 16213 app.killedByAm = true; 16214 Process.killProcessQuiet(app.pid); 16215 } else { 16216 try { 16217 app.thread.scheduleExit(); 16218 } catch (Exception e) { 16219 // Ignore exceptions. 16220 } 16221 } 16222 cleanUpApplicationRecordLocked(app, false, true, -1); 16223 mRemovedProcesses.remove(i); 16224 16225 if (app.persistent) { 16226 if (app.persistent) { 16227 addAppLocked(app.info, false); 16228 } 16229 } 16230 } 16231 } 16232 16233 // Now update the oom adj for all processes. 16234 updateOomAdjLocked(); 16235 } 16236 } 16237 16238 /** This method sends the specified signal to each of the persistent apps */ 16239 public void signalPersistentProcesses(int sig) throws RemoteException { 16240 if (sig != Process.SIGNAL_USR1) { 16241 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16242 } 16243 16244 synchronized (this) { 16245 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16246 != PackageManager.PERMISSION_GRANTED) { 16247 throw new SecurityException("Requires permission " 16248 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16249 } 16250 16251 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16252 ProcessRecord r = mLruProcesses.get(i); 16253 if (r.thread != null && r.persistent) { 16254 Process.sendSignal(r.pid, sig); 16255 } 16256 } 16257 } 16258 } 16259 16260 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16261 if (proc == null || proc == mProfileProc) { 16262 proc = mProfileProc; 16263 path = mProfileFile; 16264 profileType = mProfileType; 16265 clearProfilerLocked(); 16266 } 16267 if (proc == null) { 16268 return; 16269 } 16270 try { 16271 proc.thread.profilerControl(false, path, null, profileType); 16272 } catch (RemoteException e) { 16273 throw new IllegalStateException("Process disappeared"); 16274 } 16275 } 16276 16277 private void clearProfilerLocked() { 16278 if (mProfileFd != null) { 16279 try { 16280 mProfileFd.close(); 16281 } catch (IOException e) { 16282 } 16283 } 16284 mProfileApp = null; 16285 mProfileProc = null; 16286 mProfileFile = null; 16287 mProfileType = 0; 16288 mAutoStopProfiler = false; 16289 } 16290 16291 public boolean profileControl(String process, int userId, boolean start, 16292 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16293 16294 try { 16295 synchronized (this) { 16296 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16297 // its own permission. 16298 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16299 != PackageManager.PERMISSION_GRANTED) { 16300 throw new SecurityException("Requires permission " 16301 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16302 } 16303 16304 if (start && fd == null) { 16305 throw new IllegalArgumentException("null fd"); 16306 } 16307 16308 ProcessRecord proc = null; 16309 if (process != null) { 16310 proc = findProcessLocked(process, userId, "profileControl"); 16311 } 16312 16313 if (start && (proc == null || proc.thread == null)) { 16314 throw new IllegalArgumentException("Unknown process: " + process); 16315 } 16316 16317 if (start) { 16318 stopProfilerLocked(null, null, 0); 16319 setProfileApp(proc.info, proc.processName, path, fd, false); 16320 mProfileProc = proc; 16321 mProfileType = profileType; 16322 try { 16323 fd = fd.dup(); 16324 } catch (IOException e) { 16325 fd = null; 16326 } 16327 proc.thread.profilerControl(start, path, fd, profileType); 16328 fd = null; 16329 mProfileFd = null; 16330 } else { 16331 stopProfilerLocked(proc, path, profileType); 16332 if (fd != null) { 16333 try { 16334 fd.close(); 16335 } catch (IOException e) { 16336 } 16337 } 16338 } 16339 16340 return true; 16341 } 16342 } catch (RemoteException e) { 16343 throw new IllegalStateException("Process disappeared"); 16344 } finally { 16345 if (fd != null) { 16346 try { 16347 fd.close(); 16348 } catch (IOException e) { 16349 } 16350 } 16351 } 16352 } 16353 16354 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16355 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16356 userId, true, true, callName, null); 16357 ProcessRecord proc = null; 16358 try { 16359 int pid = Integer.parseInt(process); 16360 synchronized (mPidsSelfLocked) { 16361 proc = mPidsSelfLocked.get(pid); 16362 } 16363 } catch (NumberFormatException e) { 16364 } 16365 16366 if (proc == null) { 16367 ArrayMap<String, SparseArray<ProcessRecord>> all 16368 = mProcessNames.getMap(); 16369 SparseArray<ProcessRecord> procs = all.get(process); 16370 if (procs != null && procs.size() > 0) { 16371 proc = procs.valueAt(0); 16372 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16373 for (int i=1; i<procs.size(); i++) { 16374 ProcessRecord thisProc = procs.valueAt(i); 16375 if (thisProc.userId == userId) { 16376 proc = thisProc; 16377 break; 16378 } 16379 } 16380 } 16381 } 16382 } 16383 16384 return proc; 16385 } 16386 16387 public boolean dumpHeap(String process, int userId, boolean managed, 16388 String path, ParcelFileDescriptor fd) throws RemoteException { 16389 16390 try { 16391 synchronized (this) { 16392 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16393 // its own permission (same as profileControl). 16394 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16395 != PackageManager.PERMISSION_GRANTED) { 16396 throw new SecurityException("Requires permission " 16397 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16398 } 16399 16400 if (fd == null) { 16401 throw new IllegalArgumentException("null fd"); 16402 } 16403 16404 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16405 if (proc == null || proc.thread == null) { 16406 throw new IllegalArgumentException("Unknown process: " + process); 16407 } 16408 16409 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16410 if (!isDebuggable) { 16411 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16412 throw new SecurityException("Process not debuggable: " + proc); 16413 } 16414 } 16415 16416 proc.thread.dumpHeap(managed, path, fd); 16417 fd = null; 16418 return true; 16419 } 16420 } catch (RemoteException e) { 16421 throw new IllegalStateException("Process disappeared"); 16422 } finally { 16423 if (fd != null) { 16424 try { 16425 fd.close(); 16426 } catch (IOException e) { 16427 } 16428 } 16429 } 16430 } 16431 16432 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16433 public void monitor() { 16434 synchronized (this) { } 16435 } 16436 16437 void onCoreSettingsChange(Bundle settings) { 16438 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16439 ProcessRecord processRecord = mLruProcesses.get(i); 16440 try { 16441 if (processRecord.thread != null) { 16442 processRecord.thread.setCoreSettings(settings); 16443 } 16444 } catch (RemoteException re) { 16445 /* ignore */ 16446 } 16447 } 16448 } 16449 16450 // Multi-user methods 16451 16452 /** 16453 * Start user, if its not already running, but don't bring it to foreground. 16454 */ 16455 @Override 16456 public boolean startUserInBackground(final int userId) { 16457 return startUser(userId, /* foreground */ false); 16458 } 16459 16460 /** 16461 * Refreshes the list of users related to the current user when either a 16462 * user switch happens or when a new related user is started in the 16463 * background. 16464 */ 16465 private void updateCurrentProfileIdsLocked() { 16466 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16467 mCurrentUserId, false /* enabledOnly */); 16468 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16469 for (int i = 0; i < currentProfileIds.length; i++) { 16470 currentProfileIds[i] = profiles.get(i).id; 16471 } 16472 mCurrentProfileIds = currentProfileIds; 16473 } 16474 16475 private Set getProfileIdsLocked(int userId) { 16476 Set userIds = new HashSet<Integer>(); 16477 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16478 userId, false /* enabledOnly */); 16479 for (UserInfo user : profiles) { 16480 userIds.add(Integer.valueOf(user.id)); 16481 } 16482 return userIds; 16483 } 16484 16485 @Override 16486 public boolean switchUser(final int userId) { 16487 return startUser(userId, /* foregound */ true); 16488 } 16489 16490 private boolean startUser(final int userId, boolean foreground) { 16491 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16492 != PackageManager.PERMISSION_GRANTED) { 16493 String msg = "Permission Denial: switchUser() from pid=" 16494 + Binder.getCallingPid() 16495 + ", uid=" + Binder.getCallingUid() 16496 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16497 Slog.w(TAG, msg); 16498 throw new SecurityException(msg); 16499 } 16500 16501 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16502 16503 final long ident = Binder.clearCallingIdentity(); 16504 try { 16505 synchronized (this) { 16506 final int oldUserId = mCurrentUserId; 16507 if (oldUserId == userId) { 16508 return true; 16509 } 16510 16511 mStackSupervisor.setLockTaskModeLocked(null); 16512 16513 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16514 if (userInfo == null) { 16515 Slog.w(TAG, "No user info for user #" + userId); 16516 return false; 16517 } 16518 16519 if (foreground) { 16520 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16521 R.anim.screen_user_enter); 16522 } 16523 16524 boolean needStart = false; 16525 16526 // If the user we are switching to is not currently started, then 16527 // we need to start it now. 16528 if (mStartedUsers.get(userId) == null) { 16529 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16530 updateStartedUserArrayLocked(); 16531 needStart = true; 16532 } 16533 16534 final Integer userIdInt = Integer.valueOf(userId); 16535 mUserLru.remove(userIdInt); 16536 mUserLru.add(userIdInt); 16537 16538 if (foreground) { 16539 mCurrentUserId = userId; 16540 updateCurrentProfileIdsLocked(); 16541 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16542 // Once the internal notion of the active user has switched, we lock the device 16543 // with the option to show the user switcher on the keyguard. 16544 mWindowManager.lockNow(null); 16545 } else { 16546 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16547 updateCurrentProfileIdsLocked(); 16548 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16549 mUserLru.remove(currentUserIdInt); 16550 mUserLru.add(currentUserIdInt); 16551 } 16552 16553 final UserStartedState uss = mStartedUsers.get(userId); 16554 16555 // Make sure user is in the started state. If it is currently 16556 // stopping, we need to knock that off. 16557 if (uss.mState == UserStartedState.STATE_STOPPING) { 16558 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16559 // so we can just fairly silently bring the user back from 16560 // the almost-dead. 16561 uss.mState = UserStartedState.STATE_RUNNING; 16562 updateStartedUserArrayLocked(); 16563 needStart = true; 16564 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16565 // This means ACTION_SHUTDOWN has been sent, so we will 16566 // need to treat this as a new boot of the user. 16567 uss.mState = UserStartedState.STATE_BOOTING; 16568 updateStartedUserArrayLocked(); 16569 needStart = true; 16570 } 16571 16572 if (uss.mState == UserStartedState.STATE_BOOTING) { 16573 // Booting up a new user, need to tell system services about it. 16574 // Note that this is on the same handler as scheduling of broadcasts, 16575 // which is important because it needs to go first. 16576 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16577 } 16578 16579 if (foreground) { 16580 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16581 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16582 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16583 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16584 oldUserId, userId, uss)); 16585 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16586 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16587 } 16588 16589 if (needStart) { 16590 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16591 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16592 | Intent.FLAG_RECEIVER_FOREGROUND); 16593 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16594 broadcastIntentLocked(null, null, intent, 16595 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16596 false, false, MY_PID, Process.SYSTEM_UID, userId); 16597 } 16598 16599 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16600 if (userId != 0) { 16601 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16602 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16603 broadcastIntentLocked(null, null, intent, null, 16604 new IIntentReceiver.Stub() { 16605 public void performReceive(Intent intent, int resultCode, 16606 String data, Bundle extras, boolean ordered, 16607 boolean sticky, int sendingUser) { 16608 userInitialized(uss, userId); 16609 } 16610 }, 0, null, null, null, AppOpsManager.OP_NONE, 16611 true, false, MY_PID, Process.SYSTEM_UID, 16612 userId); 16613 uss.initializing = true; 16614 } else { 16615 getUserManagerLocked().makeInitialized(userInfo.id); 16616 } 16617 } 16618 16619 if (foreground) { 16620 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16621 if (homeInFront) { 16622 startHomeActivityLocked(userId); 16623 } else { 16624 mStackSupervisor.resumeTopActivitiesLocked(); 16625 } 16626 EventLogTags.writeAmSwitchUser(userId); 16627 getUserManagerLocked().userForeground(userId); 16628 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16629 } 16630 16631 if (needStart) { 16632 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16633 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16634 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16635 broadcastIntentLocked(null, null, intent, 16636 null, new IIntentReceiver.Stub() { 16637 @Override 16638 public void performReceive(Intent intent, int resultCode, String data, 16639 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16640 throws RemoteException { 16641 } 16642 }, 0, null, null, 16643 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16644 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16645 } 16646 } 16647 } finally { 16648 Binder.restoreCallingIdentity(ident); 16649 } 16650 16651 return true; 16652 } 16653 16654 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16655 long ident = Binder.clearCallingIdentity(); 16656 try { 16657 Intent intent; 16658 if (oldUserId >= 0) { 16659 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16660 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16661 | Intent.FLAG_RECEIVER_FOREGROUND); 16662 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16663 broadcastIntentLocked(null, null, intent, 16664 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16665 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16666 } 16667 if (newUserId >= 0) { 16668 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16669 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16670 | Intent.FLAG_RECEIVER_FOREGROUND); 16671 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16672 broadcastIntentLocked(null, null, intent, 16673 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16674 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16675 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16676 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16677 | Intent.FLAG_RECEIVER_FOREGROUND); 16678 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16679 broadcastIntentLocked(null, null, intent, 16680 null, null, 0, null, null, 16681 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16682 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16683 } 16684 } finally { 16685 Binder.restoreCallingIdentity(ident); 16686 } 16687 } 16688 16689 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16690 final int newUserId) { 16691 final int N = mUserSwitchObservers.beginBroadcast(); 16692 if (N > 0) { 16693 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16694 int mCount = 0; 16695 @Override 16696 public void sendResult(Bundle data) throws RemoteException { 16697 synchronized (ActivityManagerService.this) { 16698 if (mCurUserSwitchCallback == this) { 16699 mCount++; 16700 if (mCount == N) { 16701 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16702 } 16703 } 16704 } 16705 } 16706 }; 16707 synchronized (this) { 16708 uss.switching = true; 16709 mCurUserSwitchCallback = callback; 16710 } 16711 for (int i=0; i<N; i++) { 16712 try { 16713 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16714 newUserId, callback); 16715 } catch (RemoteException e) { 16716 } 16717 } 16718 } else { 16719 synchronized (this) { 16720 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16721 } 16722 } 16723 mUserSwitchObservers.finishBroadcast(); 16724 } 16725 16726 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16727 synchronized (this) { 16728 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16729 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16730 } 16731 } 16732 16733 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16734 mCurUserSwitchCallback = null; 16735 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16736 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16737 oldUserId, newUserId, uss)); 16738 } 16739 16740 void userInitialized(UserStartedState uss, int newUserId) { 16741 completeSwitchAndInitalize(uss, newUserId, true, false); 16742 } 16743 16744 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16745 completeSwitchAndInitalize(uss, newUserId, false, true); 16746 } 16747 16748 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16749 boolean clearInitializing, boolean clearSwitching) { 16750 boolean unfrozen = false; 16751 synchronized (this) { 16752 if (clearInitializing) { 16753 uss.initializing = false; 16754 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16755 } 16756 if (clearSwitching) { 16757 uss.switching = false; 16758 } 16759 if (!uss.switching && !uss.initializing) { 16760 mWindowManager.stopFreezingScreen(); 16761 unfrozen = true; 16762 } 16763 } 16764 if (unfrozen) { 16765 final int N = mUserSwitchObservers.beginBroadcast(); 16766 for (int i=0; i<N; i++) { 16767 try { 16768 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16769 } catch (RemoteException e) { 16770 } 16771 } 16772 mUserSwitchObservers.finishBroadcast(); 16773 } 16774 } 16775 16776 void scheduleStartProfilesLocked() { 16777 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16778 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16779 DateUtils.SECOND_IN_MILLIS); 16780 } 16781 } 16782 16783 void startProfilesLocked() { 16784 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16785 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16786 mCurrentUserId, false /* enabledOnly */); 16787 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16788 for (UserInfo user : profiles) { 16789 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16790 && user.id != mCurrentUserId) { 16791 toStart.add(user); 16792 } 16793 } 16794 final int n = toStart.size(); 16795 int i = 0; 16796 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16797 startUserInBackground(toStart.get(i).id); 16798 } 16799 if (i < n) { 16800 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16801 } 16802 } 16803 16804 void finishUserSwitch(UserStartedState uss) { 16805 synchronized (this) { 16806 if (uss.mState == UserStartedState.STATE_BOOTING 16807 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16808 uss.mState = UserStartedState.STATE_RUNNING; 16809 final int userId = uss.mHandle.getIdentifier(); 16810 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16811 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16812 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16813 broadcastIntentLocked(null, null, intent, 16814 null, null, 0, null, null, 16815 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16816 true, false, MY_PID, Process.SYSTEM_UID, userId); 16817 } 16818 16819 startProfilesLocked(); 16820 16821 int num = mUserLru.size(); 16822 int i = 0; 16823 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16824 Integer oldUserId = mUserLru.get(i); 16825 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16826 if (oldUss == null) { 16827 // Shouldn't happen, but be sane if it does. 16828 mUserLru.remove(i); 16829 num--; 16830 continue; 16831 } 16832 if (oldUss.mState == UserStartedState.STATE_STOPPING 16833 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16834 // This user is already stopping, doesn't count. 16835 num--; 16836 i++; 16837 continue; 16838 } 16839 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16840 // Owner and current can't be stopped, but count as running. 16841 i++; 16842 continue; 16843 } 16844 // This is a user to be stopped. 16845 stopUserLocked(oldUserId, null); 16846 num--; 16847 i++; 16848 } 16849 } 16850 } 16851 16852 @Override 16853 public int stopUser(final int userId, final IStopUserCallback callback) { 16854 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16855 != PackageManager.PERMISSION_GRANTED) { 16856 String msg = "Permission Denial: switchUser() from pid=" 16857 + Binder.getCallingPid() 16858 + ", uid=" + Binder.getCallingUid() 16859 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16860 Slog.w(TAG, msg); 16861 throw new SecurityException(msg); 16862 } 16863 if (userId <= 0) { 16864 throw new IllegalArgumentException("Can't stop primary user " + userId); 16865 } 16866 synchronized (this) { 16867 return stopUserLocked(userId, callback); 16868 } 16869 } 16870 16871 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16872 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16873 if (mCurrentUserId == userId) { 16874 return ActivityManager.USER_OP_IS_CURRENT; 16875 } 16876 16877 final UserStartedState uss = mStartedUsers.get(userId); 16878 if (uss == null) { 16879 // User is not started, nothing to do... but we do need to 16880 // callback if requested. 16881 if (callback != null) { 16882 mHandler.post(new Runnable() { 16883 @Override 16884 public void run() { 16885 try { 16886 callback.userStopped(userId); 16887 } catch (RemoteException e) { 16888 } 16889 } 16890 }); 16891 } 16892 return ActivityManager.USER_OP_SUCCESS; 16893 } 16894 16895 if (callback != null) { 16896 uss.mStopCallbacks.add(callback); 16897 } 16898 16899 if (uss.mState != UserStartedState.STATE_STOPPING 16900 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16901 uss.mState = UserStartedState.STATE_STOPPING; 16902 updateStartedUserArrayLocked(); 16903 16904 long ident = Binder.clearCallingIdentity(); 16905 try { 16906 // We are going to broadcast ACTION_USER_STOPPING and then 16907 // once that is done send a final ACTION_SHUTDOWN and then 16908 // stop the user. 16909 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16910 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16911 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16912 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16913 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16914 // This is the result receiver for the final shutdown broadcast. 16915 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16916 @Override 16917 public void performReceive(Intent intent, int resultCode, String data, 16918 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16919 finishUserStop(uss); 16920 } 16921 }; 16922 // This is the result receiver for the initial stopping broadcast. 16923 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16924 @Override 16925 public void performReceive(Intent intent, int resultCode, String data, 16926 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16927 // On to the next. 16928 synchronized (ActivityManagerService.this) { 16929 if (uss.mState != UserStartedState.STATE_STOPPING) { 16930 // Whoops, we are being started back up. Abort, abort! 16931 return; 16932 } 16933 uss.mState = UserStartedState.STATE_SHUTDOWN; 16934 } 16935 mSystemServiceManager.stopUser(userId); 16936 broadcastIntentLocked(null, null, shutdownIntent, 16937 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16938 true, false, MY_PID, Process.SYSTEM_UID, userId); 16939 } 16940 }; 16941 // Kick things off. 16942 broadcastIntentLocked(null, null, stoppingIntent, 16943 null, stoppingReceiver, 0, null, null, 16944 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16945 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16946 } finally { 16947 Binder.restoreCallingIdentity(ident); 16948 } 16949 } 16950 16951 return ActivityManager.USER_OP_SUCCESS; 16952 } 16953 16954 void finishUserStop(UserStartedState uss) { 16955 final int userId = uss.mHandle.getIdentifier(); 16956 boolean stopped; 16957 ArrayList<IStopUserCallback> callbacks; 16958 synchronized (this) { 16959 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16960 if (mStartedUsers.get(userId) != uss) { 16961 stopped = false; 16962 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16963 stopped = false; 16964 } else { 16965 stopped = true; 16966 // User can no longer run. 16967 mStartedUsers.remove(userId); 16968 mUserLru.remove(Integer.valueOf(userId)); 16969 updateStartedUserArrayLocked(); 16970 16971 // Clean up all state and processes associated with the user. 16972 // Kill all the processes for the user. 16973 forceStopUserLocked(userId, "finish user"); 16974 } 16975 } 16976 16977 for (int i=0; i<callbacks.size(); i++) { 16978 try { 16979 if (stopped) callbacks.get(i).userStopped(userId); 16980 else callbacks.get(i).userStopAborted(userId); 16981 } catch (RemoteException e) { 16982 } 16983 } 16984 16985 if (stopped) { 16986 mSystemServiceManager.cleanupUser(userId); 16987 synchronized (this) { 16988 mStackSupervisor.removeUserLocked(userId); 16989 } 16990 } 16991 } 16992 16993 @Override 16994 public UserInfo getCurrentUser() { 16995 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16996 != PackageManager.PERMISSION_GRANTED) && ( 16997 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16998 != PackageManager.PERMISSION_GRANTED)) { 16999 String msg = "Permission Denial: getCurrentUser() from pid=" 17000 + Binder.getCallingPid() 17001 + ", uid=" + Binder.getCallingUid() 17002 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17003 Slog.w(TAG, msg); 17004 throw new SecurityException(msg); 17005 } 17006 synchronized (this) { 17007 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17008 } 17009 } 17010 17011 int getCurrentUserIdLocked() { 17012 return mCurrentUserId; 17013 } 17014 17015 @Override 17016 public boolean isUserRunning(int userId, boolean orStopped) { 17017 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17018 != PackageManager.PERMISSION_GRANTED) { 17019 String msg = "Permission Denial: isUserRunning() from pid=" 17020 + Binder.getCallingPid() 17021 + ", uid=" + Binder.getCallingUid() 17022 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17023 Slog.w(TAG, msg); 17024 throw new SecurityException(msg); 17025 } 17026 synchronized (this) { 17027 return isUserRunningLocked(userId, orStopped); 17028 } 17029 } 17030 17031 boolean isUserRunningLocked(int userId, boolean orStopped) { 17032 UserStartedState state = mStartedUsers.get(userId); 17033 if (state == null) { 17034 return false; 17035 } 17036 if (orStopped) { 17037 return true; 17038 } 17039 return state.mState != UserStartedState.STATE_STOPPING 17040 && state.mState != UserStartedState.STATE_SHUTDOWN; 17041 } 17042 17043 @Override 17044 public int[] getRunningUserIds() { 17045 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17046 != PackageManager.PERMISSION_GRANTED) { 17047 String msg = "Permission Denial: isUserRunning() from pid=" 17048 + Binder.getCallingPid() 17049 + ", uid=" + Binder.getCallingUid() 17050 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17051 Slog.w(TAG, msg); 17052 throw new SecurityException(msg); 17053 } 17054 synchronized (this) { 17055 return mStartedUserArray; 17056 } 17057 } 17058 17059 private void updateStartedUserArrayLocked() { 17060 int num = 0; 17061 for (int i=0; i<mStartedUsers.size(); i++) { 17062 UserStartedState uss = mStartedUsers.valueAt(i); 17063 // This list does not include stopping users. 17064 if (uss.mState != UserStartedState.STATE_STOPPING 17065 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17066 num++; 17067 } 17068 } 17069 mStartedUserArray = new int[num]; 17070 num = 0; 17071 for (int i=0; i<mStartedUsers.size(); i++) { 17072 UserStartedState uss = mStartedUsers.valueAt(i); 17073 if (uss.mState != UserStartedState.STATE_STOPPING 17074 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17075 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17076 num++; 17077 } 17078 } 17079 } 17080 17081 @Override 17082 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17083 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17084 != PackageManager.PERMISSION_GRANTED) { 17085 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17086 + Binder.getCallingPid() 17087 + ", uid=" + Binder.getCallingUid() 17088 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17089 Slog.w(TAG, msg); 17090 throw new SecurityException(msg); 17091 } 17092 17093 mUserSwitchObservers.register(observer); 17094 } 17095 17096 @Override 17097 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17098 mUserSwitchObservers.unregister(observer); 17099 } 17100 17101 private boolean userExists(int userId) { 17102 if (userId == 0) { 17103 return true; 17104 } 17105 UserManagerService ums = getUserManagerLocked(); 17106 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17107 } 17108 17109 int[] getUsersLocked() { 17110 UserManagerService ums = getUserManagerLocked(); 17111 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17112 } 17113 17114 UserManagerService getUserManagerLocked() { 17115 if (mUserManager == null) { 17116 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17117 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17118 } 17119 return mUserManager; 17120 } 17121 17122 private int applyUserId(int uid, int userId) { 17123 return UserHandle.getUid(userId, uid); 17124 } 17125 17126 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17127 if (info == null) return null; 17128 ApplicationInfo newInfo = new ApplicationInfo(info); 17129 newInfo.uid = applyUserId(info.uid, userId); 17130 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17131 + info.packageName; 17132 return newInfo; 17133 } 17134 17135 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17136 if (aInfo == null 17137 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17138 return aInfo; 17139 } 17140 17141 ActivityInfo info = new ActivityInfo(aInfo); 17142 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17143 return info; 17144 } 17145 17146 private final class LocalService extends ActivityManagerInternal { 17147 @Override 17148 public void goingToSleep() { 17149 ActivityManagerService.this.goingToSleep(); 17150 } 17151 17152 @Override 17153 public void wakingUp() { 17154 ActivityManagerService.this.wakingUp(); 17155 } 17156 } 17157} 17158