ActivityManagerService.java revision 8faa342c8a544229b9fc05378a6b33d18d0f8d6b
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readBooleanAttribute; 21import static com.android.internal.util.XmlUtils.readIntAttribute; 22import static com.android.internal.util.XmlUtils.readLongAttribute; 23import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 24import static com.android.internal.util.XmlUtils.writeIntAttribute; 25import static com.android.internal.util.XmlUtils.writeLongAttribute; 26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 28import static org.xmlpull.v1.XmlPullParser.START_TAG; 29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 30 31import android.app.AppOpsManager; 32import android.app.IActivityContainer; 33import android.app.IActivityContainerCallback; 34import android.appwidget.AppWidgetManager; 35import android.graphics.Rect; 36import android.os.BatteryStats; 37import android.util.ArrayMap; 38 39import com.android.internal.R; 40import com.android.internal.annotations.GuardedBy; 41import com.android.internal.app.IAppOpsService; 42import com.android.internal.app.ProcessMap; 43import com.android.internal.app.ProcessStats; 44import com.android.internal.content.PackageMonitor; 45import com.android.internal.os.BackgroundThread; 46import com.android.internal.os.BatteryStatsImpl; 47import com.android.internal.os.ProcessCpuTracker; 48import com.android.internal.os.TransferPipe; 49import com.android.internal.os.Zygote; 50import com.android.internal.util.FastPrintWriter; 51import com.android.internal.util.FastXmlSerializer; 52import com.android.internal.util.MemInfoReader; 53import com.android.internal.util.Preconditions; 54import com.android.server.AppOpsService; 55import com.android.server.AttributeCache; 56import com.android.server.IntentResolver; 57import com.android.server.LocalServices; 58import com.android.server.ServiceThread; 59import com.android.server.SystemService; 60import com.android.server.Watchdog; 61import com.android.server.am.ActivityStack.ActivityState; 62import com.android.server.firewall.IntentFirewall; 63import com.android.server.pm.UserManagerService; 64import com.android.server.wm.AppTransition; 65import com.android.server.wm.WindowManagerService; 66import com.google.android.collect.Lists; 67import com.google.android.collect.Maps; 68 69import libcore.io.IoUtils; 70 71import org.xmlpull.v1.XmlPullParser; 72import org.xmlpull.v1.XmlPullParserException; 73import org.xmlpull.v1.XmlSerializer; 74 75import android.app.Activity; 76import android.app.ActivityManager; 77import android.app.ActivityManager.RunningTaskInfo; 78import android.app.ActivityManager.StackInfo; 79import android.app.ActivityManagerInternal; 80import android.app.ActivityManagerNative; 81import android.app.ActivityOptions; 82import android.app.ActivityThread; 83import android.app.AlertDialog; 84import android.app.AppGlobals; 85import android.app.ApplicationErrorReport; 86import android.app.Dialog; 87import android.app.IActivityController; 88import android.app.IApplicationThread; 89import android.app.IInstrumentationWatcher; 90import android.app.INotificationManager; 91import android.app.IProcessObserver; 92import android.app.IServiceConnection; 93import android.app.IStopUserCallback; 94import android.app.IThumbnailReceiver; 95import android.app.IUiAutomationConnection; 96import android.app.IUserSwitchObserver; 97import android.app.Instrumentation; 98import android.app.Notification; 99import android.app.NotificationManager; 100import android.app.PendingIntent; 101import android.app.backup.IBackupManager; 102import android.content.ActivityNotFoundException; 103import android.content.BroadcastReceiver; 104import android.content.ClipData; 105import android.content.ComponentCallbacks2; 106import android.content.ComponentName; 107import android.content.ContentProvider; 108import android.content.ContentResolver; 109import android.content.Context; 110import android.content.DialogInterface; 111import android.content.IContentProvider; 112import android.content.IIntentReceiver; 113import android.content.IIntentSender; 114import android.content.Intent; 115import android.content.IntentFilter; 116import android.content.IntentSender; 117import android.content.pm.ActivityInfo; 118import android.content.pm.ApplicationInfo; 119import android.content.pm.ConfigurationInfo; 120import android.content.pm.IPackageDataObserver; 121import android.content.pm.IPackageManager; 122import android.content.pm.InstrumentationInfo; 123import android.content.pm.PackageInfo; 124import android.content.pm.PackageManager; 125import android.content.pm.ParceledListSlice; 126import android.content.pm.UserInfo; 127import android.content.pm.PackageManager.NameNotFoundException; 128import android.content.pm.PathPermission; 129import android.content.pm.ProviderInfo; 130import android.content.pm.ResolveInfo; 131import android.content.pm.ServiceInfo; 132import android.content.res.CompatibilityInfo; 133import android.content.res.Configuration; 134import android.graphics.Bitmap; 135import android.net.Proxy; 136import android.net.ProxyProperties; 137import android.net.Uri; 138import android.os.Binder; 139import android.os.Build; 140import android.os.Bundle; 141import android.os.Debug; 142import android.os.DropBoxManager; 143import android.os.Environment; 144import android.os.FactoryTest; 145import android.os.FileObserver; 146import android.os.FileUtils; 147import android.os.Handler; 148import android.os.IBinder; 149import android.os.IPermissionController; 150import android.os.IRemoteCallback; 151import android.os.IUserManager; 152import android.os.Looper; 153import android.os.Message; 154import android.os.Parcel; 155import android.os.ParcelFileDescriptor; 156import android.os.Process; 157import android.os.RemoteCallbackList; 158import android.os.RemoteException; 159import android.os.SELinux; 160import android.os.ServiceManager; 161import android.os.StrictMode; 162import android.os.SystemClock; 163import android.os.SystemProperties; 164import android.os.UpdateLock; 165import android.os.UserHandle; 166import android.provider.Settings; 167import android.text.format.DateUtils; 168import android.text.format.Time; 169import android.util.AtomicFile; 170import android.util.EventLog; 171import android.util.Log; 172import android.util.Pair; 173import android.util.PrintWriterPrinter; 174import android.util.Slog; 175import android.util.SparseArray; 176import android.util.TimeUtils; 177import android.util.Xml; 178import android.view.Gravity; 179import android.view.LayoutInflater; 180import android.view.View; 181import android.view.WindowManager; 182 183import java.io.BufferedInputStream; 184import java.io.BufferedOutputStream; 185import java.io.DataInputStream; 186import java.io.DataOutputStream; 187import java.io.File; 188import java.io.FileDescriptor; 189import java.io.FileInputStream; 190import java.io.FileNotFoundException; 191import java.io.FileOutputStream; 192import java.io.IOException; 193import java.io.InputStreamReader; 194import java.io.PrintWriter; 195import java.io.StringWriter; 196import java.lang.ref.WeakReference; 197import java.util.ArrayList; 198import java.util.Arrays; 199import java.util.Collections; 200import java.util.Comparator; 201import java.util.HashMap; 202import java.util.HashSet; 203import java.util.Iterator; 204import java.util.List; 205import java.util.Locale; 206import java.util.Map; 207import java.util.Set; 208import java.util.concurrent.atomic.AtomicBoolean; 209import java.util.concurrent.atomic.AtomicLong; 210 211public final class ActivityManagerService extends ActivityManagerNative 212 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 213 private static final String USER_DATA_DIR = "/data/user/"; 214 static final String TAG = "ActivityManager"; 215 static final String TAG_MU = "ActivityManagerServiceMU"; 216 static final boolean DEBUG = false; 217 static final boolean localLOGV = DEBUG; 218 static final boolean DEBUG_BACKUP = localLOGV || false; 219 static final boolean DEBUG_BROADCAST = localLOGV || false; 220 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 221 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 222 static final boolean DEBUG_CLEANUP = localLOGV || false; 223 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 224 static final boolean DEBUG_FOCUS = false; 225 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 226 static final boolean DEBUG_MU = localLOGV || false; 227 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 228 static final boolean DEBUG_LRU = localLOGV || false; 229 static final boolean DEBUG_PAUSE = localLOGV || false; 230 static final boolean DEBUG_POWER = localLOGV || false; 231 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 232 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 233 static final boolean DEBUG_PROCESSES = localLOGV || false; 234 static final boolean DEBUG_PROVIDER = localLOGV || false; 235 static final boolean DEBUG_RESULTS = localLOGV || false; 236 static final boolean DEBUG_SERVICE = localLOGV || false; 237 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 238 static final boolean DEBUG_STACK = localLOGV || false; 239 static final boolean DEBUG_SWITCH = localLOGV || false; 240 static final boolean DEBUG_TASKS = localLOGV || false; 241 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 242 static final boolean DEBUG_TRANSITION = localLOGV || false; 243 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 244 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 245 static final boolean DEBUG_VISBILITY = localLOGV || false; 246 static final boolean DEBUG_PSS = localLOGV || false; 247 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 248 static final boolean VALIDATE_TOKENS = false; 249 static final boolean SHOW_ACTIVITY_START_TIME = true; 250 251 // Control over CPU and battery monitoring. 252 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 253 static final boolean MONITOR_CPU_USAGE = true; 254 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 255 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 256 static final boolean MONITOR_THREAD_CPU_USAGE = false; 257 258 // The flags that are set for all calls we make to the package manager. 259 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 260 261 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 262 263 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 264 265 // Maximum number of recent tasks that we can remember. 266 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 267 268 // Amount of time after a call to stopAppSwitches() during which we will 269 // prevent further untrusted switches from happening. 270 static final long APP_SWITCH_DELAY_TIME = 5*1000; 271 272 // How long we wait for a launched process to attach to the activity manager 273 // before we decide it's never going to come up for real. 274 static final int PROC_START_TIMEOUT = 10*1000; 275 276 // How long we wait for a launched process to attach to the activity manager 277 // before we decide it's never going to come up for real, when the process was 278 // started with a wrapper for instrumentation (such as Valgrind) because it 279 // could take much longer than usual. 280 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 281 282 // How long to wait after going idle before forcing apps to GC. 283 static final int GC_TIMEOUT = 5*1000; 284 285 // The minimum amount of time between successive GC requests for a process. 286 static final int GC_MIN_INTERVAL = 60*1000; 287 288 // The minimum amount of time between successive PSS requests for a process. 289 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 290 291 // The minimum amount of time between successive PSS requests for a process 292 // when the request is due to the memory state being lowered. 293 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 294 295 // The rate at which we check for apps using excessive power -- 15 mins. 296 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on wake locks to start killing things. 300 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // The minimum sample duration we will allow before deciding we have 303 // enough data on CPU usage to start killing things. 304 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 305 306 // How long we allow a receiver to run before giving up on it. 307 static final int BROADCAST_FG_TIMEOUT = 10*1000; 308 static final int BROADCAST_BG_TIMEOUT = 60*1000; 309 310 // How long we wait until we timeout on key dispatching. 311 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 312 313 // How long we wait until we timeout on key dispatching during instrumentation. 314 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 315 316 // Amount of time we wait for observers to handle a user switch before 317 // giving up on them and unfreezing the screen. 318 static final int USER_SWITCH_TIMEOUT = 2*1000; 319 320 // Maximum number of users we allow to be running at a time. 321 static final int MAX_RUNNING_USERS = 3; 322 323 // How long to wait in getAssistContextExtras for the activity and foreground services 324 // to respond with the result. 325 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 326 327 // Maximum number of persisted Uri grants a package is allowed 328 static final int MAX_PERSISTED_URI_GRANTS = 128; 329 330 static final int MY_PID = Process.myPid(); 331 332 static final String[] EMPTY_STRING_ARRAY = new String[0]; 333 334 // How many bytes to write into the dropbox log before truncating 335 static final int DROPBOX_MAX_SIZE = 256 * 1024; 336 337 /** Run all ActivityStacks through this */ 338 ActivityStackSupervisor mStackSupervisor; 339 340 public IntentFirewall mIntentFirewall; 341 342 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 343 // default actuion automatically. Important for devices without direct input 344 // devices. 345 private boolean mShowDialogs = true; 346 347 /** 348 * Description of a request to start a new activity, which has been held 349 * due to app switches being disabled. 350 */ 351 static class PendingActivityLaunch { 352 final ActivityRecord r; 353 final ActivityRecord sourceRecord; 354 final int startFlags; 355 final ActivityStack stack; 356 357 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 358 int _startFlags, ActivityStack _stack) { 359 r = _r; 360 sourceRecord = _sourceRecord; 361 startFlags = _startFlags; 362 stack = _stack; 363 } 364 } 365 366 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 367 = new ArrayList<PendingActivityLaunch>(); 368 369 BroadcastQueue mFgBroadcastQueue; 370 BroadcastQueue mBgBroadcastQueue; 371 // Convenient for easy iteration over the queues. Foreground is first 372 // so that dispatch of foreground broadcasts gets precedence. 373 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 374 375 BroadcastQueue broadcastQueueForIntent(Intent intent) { 376 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 377 if (DEBUG_BACKGROUND_BROADCAST) { 378 Slog.i(TAG, "Broadcast intent " + intent + " on " 379 + (isFg ? "foreground" : "background") 380 + " queue"); 381 } 382 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 383 } 384 385 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 386 for (BroadcastQueue queue : mBroadcastQueues) { 387 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 388 if (r != null) { 389 return r; 390 } 391 } 392 return null; 393 } 394 395 /** 396 * Activity we have told the window manager to have key focus. 397 */ 398 ActivityRecord mFocusedActivity = null; 399 400 /** 401 * List of intents that were used to start the most recent tasks. 402 */ 403 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 404 405 public class PendingAssistExtras extends Binder implements Runnable { 406 public final ActivityRecord activity; 407 public boolean haveResult = false; 408 public Bundle result = null; 409 public PendingAssistExtras(ActivityRecord _activity) { 410 activity = _activity; 411 } 412 @Override 413 public void run() { 414 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 415 synchronized (this) { 416 haveResult = true; 417 notifyAll(); 418 } 419 } 420 } 421 422 final ArrayList<PendingAssistExtras> mPendingAssistExtras 423 = new ArrayList<PendingAssistExtras>(); 424 425 /** 426 * Process management. 427 */ 428 final ProcessList mProcessList = new ProcessList(); 429 430 /** 431 * All of the applications we currently have running organized by name. 432 * The keys are strings of the application package name (as 433 * returned by the package manager), and the keys are ApplicationRecord 434 * objects. 435 */ 436 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 437 438 /** 439 * Tracking long-term execution of processes to look for abuse and other 440 * bad app behavior. 441 */ 442 final ProcessStatsService mProcessStats; 443 444 /** 445 * The currently running isolated processes. 446 */ 447 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 448 449 /** 450 * Counter for assigning isolated process uids, to avoid frequently reusing the 451 * same ones. 452 */ 453 int mNextIsolatedProcessUid = 0; 454 455 /** 456 * The currently running heavy-weight process, if any. 457 */ 458 ProcessRecord mHeavyWeightProcess = null; 459 460 /** 461 * The last time that various processes have crashed. 462 */ 463 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 464 465 /** 466 * Information about a process that is currently marked as bad. 467 */ 468 static final class BadProcessInfo { 469 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 470 this.time = time; 471 this.shortMsg = shortMsg; 472 this.longMsg = longMsg; 473 this.stack = stack; 474 } 475 476 final long time; 477 final String shortMsg; 478 final String longMsg; 479 final String stack; 480 } 481 482 /** 483 * Set of applications that we consider to be bad, and will reject 484 * incoming broadcasts from (which the user has no control over). 485 * Processes are added to this set when they have crashed twice within 486 * a minimum amount of time; they are removed from it when they are 487 * later restarted (hopefully due to some user action). The value is the 488 * time it was added to the list. 489 */ 490 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 491 492 /** 493 * All of the processes we currently have running organized by pid. 494 * The keys are the pid running the application. 495 * 496 * <p>NOTE: This object is protected by its own lock, NOT the global 497 * activity manager lock! 498 */ 499 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 500 501 /** 502 * All of the processes that have been forced to be foreground. The key 503 * is the pid of the caller who requested it (we hold a death 504 * link on it). 505 */ 506 abstract class ForegroundToken implements IBinder.DeathRecipient { 507 int pid; 508 IBinder token; 509 } 510 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 511 512 /** 513 * List of records for processes that someone had tried to start before the 514 * system was ready. We don't start them at that point, but ensure they 515 * are started by the time booting is complete. 516 */ 517 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 518 519 /** 520 * List of persistent applications that are in the process 521 * of being started. 522 */ 523 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 524 525 /** 526 * Processes that are being forcibly torn down. 527 */ 528 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 529 530 /** 531 * List of running applications, sorted by recent usage. 532 * The first entry in the list is the least recently used. 533 */ 534 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 535 536 /** 537 * Where in mLruProcesses that the processes hosting activities start. 538 */ 539 int mLruProcessActivityStart = 0; 540 541 /** 542 * Where in mLruProcesses that the processes hosting services start. 543 * This is after (lower index) than mLruProcessesActivityStart. 544 */ 545 int mLruProcessServiceStart = 0; 546 547 /** 548 * List of processes that should gc as soon as things are idle. 549 */ 550 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 551 552 /** 553 * Processes we want to collect PSS data from. 554 */ 555 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 556 557 /** 558 * Last time we requested PSS data of all processes. 559 */ 560 long mLastFullPssTime = SystemClock.uptimeMillis(); 561 562 /** 563 * This is the process holding what we currently consider to be 564 * the "home" activity. 565 */ 566 ProcessRecord mHomeProcess; 567 568 /** 569 * This is the process holding the activity the user last visited that 570 * is in a different process from the one they are currently in. 571 */ 572 ProcessRecord mPreviousProcess; 573 574 /** 575 * The time at which the previous process was last visible. 576 */ 577 long mPreviousProcessVisibleTime; 578 579 /** 580 * Which uses have been started, so are allowed to run code. 581 */ 582 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 583 584 /** 585 * LRU list of history of current users. Most recently current is at the end. 586 */ 587 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 588 589 /** 590 * Constant array of the users that are currently started. 591 */ 592 int[] mStartedUserArray = new int[] { 0 }; 593 594 /** 595 * Registered observers of the user switching mechanics. 596 */ 597 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 598 = new RemoteCallbackList<IUserSwitchObserver>(); 599 600 /** 601 * Currently active user switch. 602 */ 603 Object mCurUserSwitchCallback; 604 605 /** 606 * Packages that the user has asked to have run in screen size 607 * compatibility mode instead of filling the screen. 608 */ 609 final CompatModePackages mCompatModePackages; 610 611 /** 612 * Set of IntentSenderRecord objects that are currently active. 613 */ 614 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 615 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 616 617 /** 618 * Fingerprints (hashCode()) of stack traces that we've 619 * already logged DropBox entries for. Guarded by itself. If 620 * something (rogue user app) forces this over 621 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 622 */ 623 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 624 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 625 626 /** 627 * Strict Mode background batched logging state. 628 * 629 * The string buffer is guarded by itself, and its lock is also 630 * used to determine if another batched write is already 631 * in-flight. 632 */ 633 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 634 635 /** 636 * Keeps track of all IIntentReceivers that have been registered for 637 * broadcasts. Hash keys are the receiver IBinder, hash value is 638 * a ReceiverList. 639 */ 640 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 641 new HashMap<IBinder, ReceiverList>(); 642 643 /** 644 * Resolver for broadcast intents to registered receivers. 645 * Holds BroadcastFilter (subclass of IntentFilter). 646 */ 647 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 648 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 649 @Override 650 protected boolean allowFilterResult( 651 BroadcastFilter filter, List<BroadcastFilter> dest) { 652 IBinder target = filter.receiverList.receiver.asBinder(); 653 for (int i=dest.size()-1; i>=0; i--) { 654 if (dest.get(i).receiverList.receiver.asBinder() == target) { 655 return false; 656 } 657 } 658 return true; 659 } 660 661 @Override 662 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 663 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 664 || userId == filter.owningUserId) { 665 return super.newResult(filter, match, userId); 666 } 667 return null; 668 } 669 670 @Override 671 protected BroadcastFilter[] newArray(int size) { 672 return new BroadcastFilter[size]; 673 } 674 675 @Override 676 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 677 return packageName.equals(filter.packageName); 678 } 679 }; 680 681 /** 682 * State of all active sticky broadcasts per user. Keys are the action of the 683 * sticky Intent, values are an ArrayList of all broadcasted intents with 684 * that action (which should usually be one). The SparseArray is keyed 685 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 686 * for stickies that are sent to all users. 687 */ 688 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 689 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 690 691 final ActiveServices mServices; 692 693 /** 694 * Backup/restore process management 695 */ 696 String mBackupAppName = null; 697 BackupRecord mBackupTarget = null; 698 699 /** 700 * List of PendingThumbnailsRecord objects of clients who are still 701 * waiting to receive all of the thumbnails for a task. 702 */ 703 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 704 new ArrayList<PendingThumbnailsRecord>(); 705 706 final ProviderMap mProviderMap; 707 708 /** 709 * List of content providers who have clients waiting for them. The 710 * application is currently being launched and the provider will be 711 * removed from this list once it is published. 712 */ 713 final ArrayList<ContentProviderRecord> mLaunchingProviders 714 = new ArrayList<ContentProviderRecord>(); 715 716 /** 717 * File storing persisted {@link #mGrantedUriPermissions}. 718 */ 719 private final AtomicFile mGrantFile; 720 721 /** XML constants used in {@link #mGrantFile} */ 722 private static final String TAG_URI_GRANTS = "uri-grants"; 723 private static final String TAG_URI_GRANT = "uri-grant"; 724 private static final String ATTR_USER_HANDLE = "userHandle"; 725 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 726 private static final String ATTR_TARGET_PKG = "targetPkg"; 727 private static final String ATTR_URI = "uri"; 728 private static final String ATTR_MODE_FLAGS = "modeFlags"; 729 private static final String ATTR_CREATED_TIME = "createdTime"; 730 private static final String ATTR_PREFIX = "prefix"; 731 732 /** 733 * Global set of specific {@link Uri} permissions that have been granted. 734 * This optimized lookup structure maps from {@link UriPermission#targetUid} 735 * to {@link UriPermission#uri} to {@link UriPermission}. 736 */ 737 @GuardedBy("this") 738 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 739 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 740 741 public static class GrantUri { 742 public final Uri uri; 743 public final boolean prefix; 744 745 public GrantUri(Uri uri, boolean prefix) { 746 this.uri = uri; 747 this.prefix = prefix; 748 } 749 750 @Override 751 public int hashCode() { 752 return toString().hashCode(); 753 } 754 755 @Override 756 public boolean equals(Object o) { 757 if (o instanceof GrantUri) { 758 GrantUri other = (GrantUri) o; 759 return uri.equals(other.uri) && prefix == other.prefix; 760 } 761 return false; 762 } 763 764 @Override 765 public String toString() { 766 if (prefix) { 767 return uri.toString() + " [prefix]"; 768 } else { 769 return uri.toString(); 770 } 771 } 772 } 773 774 CoreSettingsObserver mCoreSettingsObserver; 775 776 /** 777 * Thread-local storage used to carry caller permissions over through 778 * indirect content-provider access. 779 */ 780 private class Identity { 781 public int pid; 782 public int uid; 783 784 Identity(int _pid, int _uid) { 785 pid = _pid; 786 uid = _uid; 787 } 788 } 789 790 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 791 792 /** 793 * All information we have collected about the runtime performance of 794 * any user id that can impact battery performance. 795 */ 796 final BatteryStatsService mBatteryStatsService; 797 798 /** 799 * Information about component usage 800 */ 801 final UsageStatsService mUsageStatsService; 802 803 /** 804 * Information about and control over application operations 805 */ 806 final AppOpsService mAppOpsService; 807 808 /** 809 * Current configuration information. HistoryRecord objects are given 810 * a reference to this object to indicate which configuration they are 811 * currently running in, so this object must be kept immutable. 812 */ 813 Configuration mConfiguration = new Configuration(); 814 815 /** 816 * Current sequencing integer of the configuration, for skipping old 817 * configurations. 818 */ 819 int mConfigurationSeq = 0; 820 821 /** 822 * Hardware-reported OpenGLES version. 823 */ 824 final int GL_ES_VERSION; 825 826 /** 827 * List of initialization arguments to pass to all processes when binding applications to them. 828 * For example, references to the commonly used services. 829 */ 830 HashMap<String, IBinder> mAppBindArgs; 831 832 /** 833 * Temporary to avoid allocations. Protected by main lock. 834 */ 835 final StringBuilder mStringBuilder = new StringBuilder(256); 836 837 /** 838 * Used to control how we initialize the service. 839 */ 840 ComponentName mTopComponent; 841 String mTopAction = Intent.ACTION_MAIN; 842 String mTopData; 843 boolean mProcessesReady = false; 844 boolean mSystemReady = false; 845 boolean mBooting = false; 846 boolean mWaitingUpdate = false; 847 boolean mDidUpdate = false; 848 boolean mOnBattery = false; 849 boolean mLaunchWarningShown = false; 850 851 Context mContext; 852 853 int mFactoryTest; 854 855 boolean mCheckedForSetup; 856 857 /** 858 * The time at which we will allow normal application switches again, 859 * after a call to {@link #stopAppSwitches()}. 860 */ 861 long mAppSwitchesAllowedTime; 862 863 /** 864 * This is set to true after the first switch after mAppSwitchesAllowedTime 865 * is set; any switches after that will clear the time. 866 */ 867 boolean mDidAppSwitch; 868 869 /** 870 * Last time (in realtime) at which we checked for power usage. 871 */ 872 long mLastPowerCheckRealtime; 873 874 /** 875 * Last time (in uptime) at which we checked for power usage. 876 */ 877 long mLastPowerCheckUptime; 878 879 /** 880 * Set while we are wanting to sleep, to prevent any 881 * activities from being started/resumed. 882 */ 883 boolean mSleeping = false; 884 885 /** 886 * State of external calls telling us if the device is asleep. 887 */ 888 boolean mWentToSleep = false; 889 890 /** 891 * State of external call telling us if the lock screen is shown. 892 */ 893 boolean mLockScreenShown = false; 894 895 /** 896 * Set if we are shutting down the system, similar to sleeping. 897 */ 898 boolean mShuttingDown = false; 899 900 /** 901 * Current sequence id for oom_adj computation traversal. 902 */ 903 int mAdjSeq = 0; 904 905 /** 906 * Current sequence id for process LRU updating. 907 */ 908 int mLruSeq = 0; 909 910 /** 911 * Keep track of the non-cached/empty process we last found, to help 912 * determine how to distribute cached/empty processes next time. 913 */ 914 int mNumNonCachedProcs = 0; 915 916 /** 917 * Keep track of the number of cached hidden procs, to balance oom adj 918 * distribution between those and empty procs. 919 */ 920 int mNumCachedHiddenProcs = 0; 921 922 /** 923 * Keep track of the number of service processes we last found, to 924 * determine on the next iteration which should be B services. 925 */ 926 int mNumServiceProcs = 0; 927 int mNewNumAServiceProcs = 0; 928 int mNewNumServiceProcs = 0; 929 930 /** 931 * Allow the current computed overall memory level of the system to go down? 932 * This is set to false when we are killing processes for reasons other than 933 * memory management, so that the now smaller process list will not be taken as 934 * an indication that memory is tighter. 935 */ 936 boolean mAllowLowerMemLevel = false; 937 938 /** 939 * The last computed memory level, for holding when we are in a state that 940 * processes are going away for other reasons. 941 */ 942 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 943 944 /** 945 * The last total number of process we have, to determine if changes actually look 946 * like a shrinking number of process due to lower RAM. 947 */ 948 int mLastNumProcesses; 949 950 /** 951 * The uptime of the last time we performed idle maintenance. 952 */ 953 long mLastIdleTime = SystemClock.uptimeMillis(); 954 955 /** 956 * Total time spent with RAM that has been added in the past since the last idle time. 957 */ 958 long mLowRamTimeSinceLastIdle = 0; 959 960 /** 961 * If RAM is currently low, when that horrible situation started. 962 */ 963 long mLowRamStartTime = 0; 964 965 /** 966 * For reporting to battery stats the current top application. 967 */ 968 private String mCurResumedPackage = null; 969 private int mCurResumedUid = -1; 970 971 /** 972 * For reporting to battery stats the apps currently running foreground 973 * service. The ProcessMap is package/uid tuples; each of these contain 974 * an array of the currently foreground processes. 975 */ 976 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 977 = new ProcessMap<ArrayList<ProcessRecord>>(); 978 979 /** 980 * This is set if we had to do a delayed dexopt of an app before launching 981 * it, to increasing the ANR timeouts in that case. 982 */ 983 boolean mDidDexOpt; 984 985 /** 986 * Set if the systemServer made a call to enterSafeMode. 987 */ 988 boolean mSafeMode; 989 990 String mDebugApp = null; 991 boolean mWaitForDebugger = false; 992 boolean mDebugTransient = false; 993 String mOrigDebugApp = null; 994 boolean mOrigWaitForDebugger = false; 995 boolean mAlwaysFinishActivities = false; 996 IActivityController mController = null; 997 String mProfileApp = null; 998 ProcessRecord mProfileProc = null; 999 String mProfileFile; 1000 ParcelFileDescriptor mProfileFd; 1001 int mProfileType = 0; 1002 boolean mAutoStopProfiler = false; 1003 String mOpenGlTraceApp = null; 1004 1005 static class ProcessChangeItem { 1006 static final int CHANGE_ACTIVITIES = 1<<0; 1007 static final int CHANGE_IMPORTANCE= 1<<1; 1008 int changes; 1009 int uid; 1010 int pid; 1011 int importance; 1012 boolean foregroundActivities; 1013 } 1014 1015 final RemoteCallbackList<IProcessObserver> mProcessObservers 1016 = new RemoteCallbackList<IProcessObserver>(); 1017 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1018 1019 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1020 = new ArrayList<ProcessChangeItem>(); 1021 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1022 = new ArrayList<ProcessChangeItem>(); 1023 1024 /** 1025 * Runtime CPU use collection thread. This object's lock is used to 1026 * protect all related state. 1027 */ 1028 final Thread mProcessCpuThread; 1029 1030 /** 1031 * Used to collect process stats when showing not responding dialog. 1032 * Protected by mProcessCpuThread. 1033 */ 1034 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1035 MONITOR_THREAD_CPU_USAGE); 1036 final AtomicLong mLastCpuTime = new AtomicLong(0); 1037 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1038 1039 long mLastWriteTime = 0; 1040 1041 /** 1042 * Used to retain an update lock when the foreground activity is in 1043 * immersive mode. 1044 */ 1045 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1046 1047 /** 1048 * Set to true after the system has finished booting. 1049 */ 1050 boolean mBooted = false; 1051 1052 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1053 int mProcessLimitOverride = -1; 1054 1055 WindowManagerService mWindowManager; 1056 1057 final ActivityThread mSystemThread; 1058 1059 int mCurrentUserId = 0; 1060 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1061 private UserManagerService mUserManager; 1062 1063 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1064 final ProcessRecord mApp; 1065 final int mPid; 1066 final IApplicationThread mAppThread; 1067 1068 AppDeathRecipient(ProcessRecord app, int pid, 1069 IApplicationThread thread) { 1070 if (localLOGV) Slog.v( 1071 TAG, "New death recipient " + this 1072 + " for thread " + thread.asBinder()); 1073 mApp = app; 1074 mPid = pid; 1075 mAppThread = thread; 1076 } 1077 1078 @Override 1079 public void binderDied() { 1080 if (localLOGV) Slog.v( 1081 TAG, "Death received in " + this 1082 + " for thread " + mAppThread.asBinder()); 1083 synchronized(ActivityManagerService.this) { 1084 appDiedLocked(mApp, mPid, mAppThread); 1085 } 1086 } 1087 } 1088 1089 static final int SHOW_ERROR_MSG = 1; 1090 static final int SHOW_NOT_RESPONDING_MSG = 2; 1091 static final int SHOW_FACTORY_ERROR_MSG = 3; 1092 static final int UPDATE_CONFIGURATION_MSG = 4; 1093 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1094 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1095 static final int SERVICE_TIMEOUT_MSG = 12; 1096 static final int UPDATE_TIME_ZONE = 13; 1097 static final int SHOW_UID_ERROR_MSG = 14; 1098 static final int IM_FEELING_LUCKY_MSG = 15; 1099 static final int PROC_START_TIMEOUT_MSG = 20; 1100 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1101 static final int KILL_APPLICATION_MSG = 22; 1102 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1103 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1104 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1105 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1106 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1107 static final int CLEAR_DNS_CACHE_MSG = 28; 1108 static final int UPDATE_HTTP_PROXY_MSG = 29; 1109 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1110 static final int DISPATCH_PROCESSES_CHANGED = 31; 1111 static final int DISPATCH_PROCESS_DIED = 32; 1112 static final int REPORT_MEM_USAGE_MSG = 33; 1113 static final int REPORT_USER_SWITCH_MSG = 34; 1114 static final int CONTINUE_USER_SWITCH_MSG = 35; 1115 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1116 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1117 static final int PERSIST_URI_GRANTS_MSG = 38; 1118 static final int REQUEST_ALL_PSS_MSG = 39; 1119 static final int START_PROFILES_MSG = 40; 1120 static final int UPDATE_TIME = 41; 1121 1122 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1123 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1124 static final int FIRST_COMPAT_MODE_MSG = 300; 1125 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1126 1127 AlertDialog mUidAlert; 1128 CompatModeDialog mCompatModeDialog; 1129 long mLastMemUsageReportTime = 0; 1130 1131 /** 1132 * Flag whether the current user is a "monkey", i.e. whether 1133 * the UI is driven by a UI automation tool. 1134 */ 1135 private boolean mUserIsMonkey; 1136 1137 final ServiceThread mHandlerThread; 1138 final MainHandler mHandler; 1139 1140 final class MainHandler extends Handler { 1141 public MainHandler(Looper looper) { 1142 super(looper, null, true); 1143 } 1144 1145 @Override 1146 public void handleMessage(Message msg) { 1147 switch (msg.what) { 1148 case SHOW_ERROR_MSG: { 1149 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1150 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1151 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1152 synchronized (ActivityManagerService.this) { 1153 ProcessRecord proc = (ProcessRecord)data.get("app"); 1154 AppErrorResult res = (AppErrorResult) data.get("result"); 1155 if (proc != null && proc.crashDialog != null) { 1156 Slog.e(TAG, "App already has crash dialog: " + proc); 1157 if (res != null) { 1158 res.set(0); 1159 } 1160 return; 1161 } 1162 if (!showBackground && UserHandle.getAppId(proc.uid) 1163 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1164 && proc.pid != MY_PID) { 1165 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1166 if (res != null) { 1167 res.set(0); 1168 } 1169 return; 1170 } 1171 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1172 Dialog d = new AppErrorDialog(mContext, 1173 ActivityManagerService.this, res, proc); 1174 d.show(); 1175 proc.crashDialog = d; 1176 } else { 1177 // The device is asleep, so just pretend that the user 1178 // saw a crash dialog and hit "force quit". 1179 if (res != null) { 1180 res.set(0); 1181 } 1182 } 1183 } 1184 1185 ensureBootCompleted(); 1186 } break; 1187 case SHOW_NOT_RESPONDING_MSG: { 1188 synchronized (ActivityManagerService.this) { 1189 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1190 ProcessRecord proc = (ProcessRecord)data.get("app"); 1191 if (proc != null && proc.anrDialog != null) { 1192 Slog.e(TAG, "App already has anr dialog: " + proc); 1193 return; 1194 } 1195 1196 Intent intent = new Intent("android.intent.action.ANR"); 1197 if (!mProcessesReady) { 1198 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1199 | Intent.FLAG_RECEIVER_FOREGROUND); 1200 } 1201 broadcastIntentLocked(null, null, intent, 1202 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1203 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1204 1205 if (mShowDialogs) { 1206 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1207 mContext, proc, (ActivityRecord)data.get("activity"), 1208 msg.arg1 != 0); 1209 d.show(); 1210 proc.anrDialog = d; 1211 } else { 1212 // Just kill the app if there is no dialog to be shown. 1213 killAppAtUsersRequest(proc, null); 1214 } 1215 } 1216 1217 ensureBootCompleted(); 1218 } break; 1219 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1220 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1221 synchronized (ActivityManagerService.this) { 1222 ProcessRecord proc = (ProcessRecord) data.get("app"); 1223 if (proc == null) { 1224 Slog.e(TAG, "App not found when showing strict mode dialog."); 1225 break; 1226 } 1227 if (proc.crashDialog != null) { 1228 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1229 return; 1230 } 1231 AppErrorResult res = (AppErrorResult) data.get("result"); 1232 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1233 Dialog d = new StrictModeViolationDialog(mContext, 1234 ActivityManagerService.this, res, proc); 1235 d.show(); 1236 proc.crashDialog = d; 1237 } else { 1238 // The device is asleep, so just pretend that the user 1239 // saw a crash dialog and hit "force quit". 1240 res.set(0); 1241 } 1242 } 1243 ensureBootCompleted(); 1244 } break; 1245 case SHOW_FACTORY_ERROR_MSG: { 1246 Dialog d = new FactoryErrorDialog( 1247 mContext, msg.getData().getCharSequence("msg")); 1248 d.show(); 1249 ensureBootCompleted(); 1250 } break; 1251 case UPDATE_CONFIGURATION_MSG: { 1252 final ContentResolver resolver = mContext.getContentResolver(); 1253 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1254 } break; 1255 case GC_BACKGROUND_PROCESSES_MSG: { 1256 synchronized (ActivityManagerService.this) { 1257 performAppGcsIfAppropriateLocked(); 1258 } 1259 } break; 1260 case WAIT_FOR_DEBUGGER_MSG: { 1261 synchronized (ActivityManagerService.this) { 1262 ProcessRecord app = (ProcessRecord)msg.obj; 1263 if (msg.arg1 != 0) { 1264 if (!app.waitedForDebugger) { 1265 Dialog d = new AppWaitingForDebuggerDialog( 1266 ActivityManagerService.this, 1267 mContext, app); 1268 app.waitDialog = d; 1269 app.waitedForDebugger = true; 1270 d.show(); 1271 } 1272 } else { 1273 if (app.waitDialog != null) { 1274 app.waitDialog.dismiss(); 1275 app.waitDialog = null; 1276 } 1277 } 1278 } 1279 } break; 1280 case SERVICE_TIMEOUT_MSG: { 1281 if (mDidDexOpt) { 1282 mDidDexOpt = false; 1283 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1284 nmsg.obj = msg.obj; 1285 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1286 return; 1287 } 1288 mServices.serviceTimeout((ProcessRecord)msg.obj); 1289 } break; 1290 case UPDATE_TIME_ZONE: { 1291 synchronized (ActivityManagerService.this) { 1292 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1293 ProcessRecord r = mLruProcesses.get(i); 1294 if (r.thread != null) { 1295 try { 1296 r.thread.updateTimeZone(); 1297 } catch (RemoteException ex) { 1298 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1299 } 1300 } 1301 } 1302 } 1303 } break; 1304 case CLEAR_DNS_CACHE_MSG: { 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.clearDnsCache(); 1311 } catch (RemoteException ex) { 1312 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1313 } 1314 } 1315 } 1316 } 1317 } break; 1318 case UPDATE_HTTP_PROXY_MSG: { 1319 ProxyProperties proxy = (ProxyProperties)msg.obj; 1320 String host = ""; 1321 String port = ""; 1322 String exclList = ""; 1323 String pacFileUrl = null; 1324 if (proxy != null) { 1325 host = proxy.getHost(); 1326 port = Integer.toString(proxy.getPort()); 1327 exclList = proxy.getExclusionList(); 1328 pacFileUrl = proxy.getPacFileUrl(); 1329 } 1330 synchronized (ActivityManagerService.this) { 1331 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1332 ProcessRecord r = mLruProcesses.get(i); 1333 if (r.thread != null) { 1334 try { 1335 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1336 } catch (RemoteException ex) { 1337 Slog.w(TAG, "Failed to update http proxy for: " + 1338 r.info.processName); 1339 } 1340 } 1341 } 1342 } 1343 } break; 1344 case SHOW_UID_ERROR_MSG: { 1345 String title = "System UIDs Inconsistent"; 1346 String text = "UIDs on the system are inconsistent, you need to wipe your" 1347 + " data partition or your device will be unstable."; 1348 Log.e(TAG, title + ": " + text); 1349 if (mShowDialogs) { 1350 // XXX This is a temporary dialog, no need to localize. 1351 AlertDialog d = new BaseErrorDialog(mContext); 1352 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1353 d.setCancelable(false); 1354 d.setTitle(title); 1355 d.setMessage(text); 1356 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1357 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1358 mUidAlert = d; 1359 d.show(); 1360 } 1361 } break; 1362 case IM_FEELING_LUCKY_MSG: { 1363 if (mUidAlert != null) { 1364 mUidAlert.dismiss(); 1365 mUidAlert = null; 1366 } 1367 } break; 1368 case PROC_START_TIMEOUT_MSG: { 1369 if (mDidDexOpt) { 1370 mDidDexOpt = false; 1371 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1372 nmsg.obj = msg.obj; 1373 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1374 return; 1375 } 1376 ProcessRecord app = (ProcessRecord)msg.obj; 1377 synchronized (ActivityManagerService.this) { 1378 processStartTimedOutLocked(app); 1379 } 1380 } break; 1381 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1382 synchronized (ActivityManagerService.this) { 1383 doPendingActivityLaunchesLocked(true); 1384 } 1385 } break; 1386 case KILL_APPLICATION_MSG: { 1387 synchronized (ActivityManagerService.this) { 1388 int appid = msg.arg1; 1389 boolean restart = (msg.arg2 == 1); 1390 Bundle bundle = (Bundle)msg.obj; 1391 String pkg = bundle.getString("pkg"); 1392 String reason = bundle.getString("reason"); 1393 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1394 false, UserHandle.USER_ALL, reason); 1395 } 1396 } break; 1397 case FINALIZE_PENDING_INTENT_MSG: { 1398 ((PendingIntentRecord)msg.obj).completeFinalize(); 1399 } break; 1400 case POST_HEAVY_NOTIFICATION_MSG: { 1401 INotificationManager inm = NotificationManager.getService(); 1402 if (inm == null) { 1403 return; 1404 } 1405 1406 ActivityRecord root = (ActivityRecord)msg.obj; 1407 ProcessRecord process = root.app; 1408 if (process == null) { 1409 return; 1410 } 1411 1412 try { 1413 Context context = mContext.createPackageContext(process.info.packageName, 0); 1414 String text = mContext.getString(R.string.heavy_weight_notification, 1415 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1416 Notification notification = new Notification(); 1417 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1418 notification.when = 0; 1419 notification.flags = Notification.FLAG_ONGOING_EVENT; 1420 notification.tickerText = text; 1421 notification.defaults = 0; // please be quiet 1422 notification.sound = null; 1423 notification.vibrate = null; 1424 notification.setLatestEventInfo(context, text, 1425 mContext.getText(R.string.heavy_weight_notification_detail), 1426 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1427 PendingIntent.FLAG_CANCEL_CURRENT, null, 1428 new UserHandle(root.userId))); 1429 1430 try { 1431 int[] outId = new int[1]; 1432 inm.enqueueNotificationWithTag("android", "android", null, 1433 R.string.heavy_weight_notification, 1434 notification, outId, root.userId); 1435 } catch (RuntimeException e) { 1436 Slog.w(ActivityManagerService.TAG, 1437 "Error showing notification for heavy-weight app", e); 1438 } catch (RemoteException e) { 1439 } 1440 } catch (NameNotFoundException e) { 1441 Slog.w(TAG, "Unable to create context for heavy notification", e); 1442 } 1443 } break; 1444 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1445 INotificationManager inm = NotificationManager.getService(); 1446 if (inm == null) { 1447 return; 1448 } 1449 try { 1450 inm.cancelNotificationWithTag("android", null, 1451 R.string.heavy_weight_notification, msg.arg1); 1452 } catch (RuntimeException e) { 1453 Slog.w(ActivityManagerService.TAG, 1454 "Error canceling notification for service", e); 1455 } catch (RemoteException e) { 1456 } 1457 } break; 1458 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1459 synchronized (ActivityManagerService.this) { 1460 checkExcessivePowerUsageLocked(true); 1461 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1462 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1463 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1464 } 1465 } break; 1466 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1467 synchronized (ActivityManagerService.this) { 1468 ActivityRecord ar = (ActivityRecord)msg.obj; 1469 if (mCompatModeDialog != null) { 1470 if (mCompatModeDialog.mAppInfo.packageName.equals( 1471 ar.info.applicationInfo.packageName)) { 1472 return; 1473 } 1474 mCompatModeDialog.dismiss(); 1475 mCompatModeDialog = null; 1476 } 1477 if (ar != null && false) { 1478 if (mCompatModePackages.getPackageAskCompatModeLocked( 1479 ar.packageName)) { 1480 int mode = mCompatModePackages.computeCompatModeLocked( 1481 ar.info.applicationInfo); 1482 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1483 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1484 mCompatModeDialog = new CompatModeDialog( 1485 ActivityManagerService.this, mContext, 1486 ar.info.applicationInfo); 1487 mCompatModeDialog.show(); 1488 } 1489 } 1490 } 1491 } 1492 break; 1493 } 1494 case DISPATCH_PROCESSES_CHANGED: { 1495 dispatchProcessesChanged(); 1496 break; 1497 } 1498 case DISPATCH_PROCESS_DIED: { 1499 final int pid = msg.arg1; 1500 final int uid = msg.arg2; 1501 dispatchProcessDied(pid, uid); 1502 break; 1503 } 1504 case REPORT_MEM_USAGE_MSG: { 1505 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1506 Thread thread = new Thread() { 1507 @Override public void run() { 1508 final SparseArray<ProcessMemInfo> infoMap 1509 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1510 for (int i=0, N=memInfos.size(); i<N; i++) { 1511 ProcessMemInfo mi = memInfos.get(i); 1512 infoMap.put(mi.pid, mi); 1513 } 1514 updateCpuStatsNow(); 1515 synchronized (mProcessCpuThread) { 1516 final int N = mProcessCpuTracker.countStats(); 1517 for (int i=0; i<N; i++) { 1518 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1519 if (st.vsize > 0) { 1520 long pss = Debug.getPss(st.pid, null); 1521 if (pss > 0) { 1522 if (infoMap.indexOfKey(st.pid) < 0) { 1523 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1524 ProcessList.NATIVE_ADJ, -1, "native", null); 1525 mi.pss = pss; 1526 memInfos.add(mi); 1527 } 1528 } 1529 } 1530 } 1531 } 1532 1533 long totalPss = 0; 1534 for (int i=0, N=memInfos.size(); i<N; i++) { 1535 ProcessMemInfo mi = memInfos.get(i); 1536 if (mi.pss == 0) { 1537 mi.pss = Debug.getPss(mi.pid, null); 1538 } 1539 totalPss += mi.pss; 1540 } 1541 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1542 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1543 if (lhs.oomAdj != rhs.oomAdj) { 1544 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1545 } 1546 if (lhs.pss != rhs.pss) { 1547 return lhs.pss < rhs.pss ? 1 : -1; 1548 } 1549 return 0; 1550 } 1551 }); 1552 1553 StringBuilder tag = new StringBuilder(128); 1554 StringBuilder stack = new StringBuilder(128); 1555 tag.append("Low on memory -- "); 1556 appendMemBucket(tag, totalPss, "total", false); 1557 appendMemBucket(stack, totalPss, "total", true); 1558 1559 StringBuilder logBuilder = new StringBuilder(1024); 1560 logBuilder.append("Low on memory:\n"); 1561 1562 boolean firstLine = true; 1563 int lastOomAdj = Integer.MIN_VALUE; 1564 for (int i=0, N=memInfos.size(); i<N; i++) { 1565 ProcessMemInfo mi = memInfos.get(i); 1566 1567 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1568 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1569 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1570 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1571 if (lastOomAdj != mi.oomAdj) { 1572 lastOomAdj = mi.oomAdj; 1573 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1574 tag.append(" / "); 1575 } 1576 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1577 if (firstLine) { 1578 stack.append(":"); 1579 firstLine = false; 1580 } 1581 stack.append("\n\t at "); 1582 } else { 1583 stack.append("$"); 1584 } 1585 } else { 1586 tag.append(" "); 1587 stack.append("$"); 1588 } 1589 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1590 appendMemBucket(tag, mi.pss, mi.name, false); 1591 } 1592 appendMemBucket(stack, mi.pss, mi.name, true); 1593 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1594 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1595 stack.append("("); 1596 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1597 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1598 stack.append(DUMP_MEM_OOM_LABEL[k]); 1599 stack.append(":"); 1600 stack.append(DUMP_MEM_OOM_ADJ[k]); 1601 } 1602 } 1603 stack.append(")"); 1604 } 1605 } 1606 1607 logBuilder.append(" "); 1608 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1609 logBuilder.append(' '); 1610 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1611 logBuilder.append(' '); 1612 ProcessList.appendRamKb(logBuilder, mi.pss); 1613 logBuilder.append(" kB: "); 1614 logBuilder.append(mi.name); 1615 logBuilder.append(" ("); 1616 logBuilder.append(mi.pid); 1617 logBuilder.append(") "); 1618 logBuilder.append(mi.adjType); 1619 logBuilder.append('\n'); 1620 if (mi.adjReason != null) { 1621 logBuilder.append(" "); 1622 logBuilder.append(mi.adjReason); 1623 logBuilder.append('\n'); 1624 } 1625 } 1626 1627 logBuilder.append(" "); 1628 ProcessList.appendRamKb(logBuilder, totalPss); 1629 logBuilder.append(" kB: TOTAL\n"); 1630 1631 long[] infos = new long[Debug.MEMINFO_COUNT]; 1632 Debug.getMemInfo(infos); 1633 logBuilder.append(" MemInfo: "); 1634 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1635 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1636 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1637 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1638 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1639 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1640 logBuilder.append(" ZRAM: "); 1641 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1642 logBuilder.append(" kB RAM, "); 1643 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1644 logBuilder.append(" kB swap total, "); 1645 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1646 logBuilder.append(" kB swap free\n"); 1647 } 1648 Slog.i(TAG, logBuilder.toString()); 1649 1650 StringBuilder dropBuilder = new StringBuilder(1024); 1651 /* 1652 StringWriter oomSw = new StringWriter(); 1653 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1654 StringWriter catSw = new StringWriter(); 1655 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1656 String[] emptyArgs = new String[] { }; 1657 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1658 oomPw.flush(); 1659 String oomString = oomSw.toString(); 1660 */ 1661 dropBuilder.append(stack); 1662 dropBuilder.append('\n'); 1663 dropBuilder.append('\n'); 1664 dropBuilder.append(logBuilder); 1665 dropBuilder.append('\n'); 1666 /* 1667 dropBuilder.append(oomString); 1668 dropBuilder.append('\n'); 1669 */ 1670 StringWriter catSw = new StringWriter(); 1671 synchronized (ActivityManagerService.this) { 1672 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1673 String[] emptyArgs = new String[] { }; 1674 catPw.println(); 1675 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1676 catPw.println(); 1677 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1678 false, false, null); 1679 catPw.println(); 1680 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1681 catPw.flush(); 1682 } 1683 dropBuilder.append(catSw.toString()); 1684 addErrorToDropBox("lowmem", null, "system_server", null, 1685 null, tag.toString(), dropBuilder.toString(), null, null); 1686 //Slog.i(TAG, "Sent to dropbox:"); 1687 //Slog.i(TAG, dropBuilder.toString()); 1688 synchronized (ActivityManagerService.this) { 1689 long now = SystemClock.uptimeMillis(); 1690 if (mLastMemUsageReportTime < now) { 1691 mLastMemUsageReportTime = now; 1692 } 1693 } 1694 } 1695 }; 1696 thread.start(); 1697 break; 1698 } 1699 case REPORT_USER_SWITCH_MSG: { 1700 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1701 break; 1702 } 1703 case CONTINUE_USER_SWITCH_MSG: { 1704 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1705 break; 1706 } 1707 case USER_SWITCH_TIMEOUT_MSG: { 1708 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1709 break; 1710 } 1711 case IMMERSIVE_MODE_LOCK_MSG: { 1712 final boolean nextState = (msg.arg1 != 0); 1713 if (mUpdateLock.isHeld() != nextState) { 1714 if (DEBUG_IMMERSIVE) { 1715 final ActivityRecord r = (ActivityRecord) msg.obj; 1716 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1717 } 1718 if (nextState) { 1719 mUpdateLock.acquire(); 1720 } else { 1721 mUpdateLock.release(); 1722 } 1723 } 1724 break; 1725 } 1726 case PERSIST_URI_GRANTS_MSG: { 1727 writeGrantedUriPermissions(); 1728 break; 1729 } 1730 case REQUEST_ALL_PSS_MSG: { 1731 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1732 break; 1733 } 1734 case START_PROFILES_MSG: { 1735 synchronized (ActivityManagerService.this) { 1736 startProfilesLocked(); 1737 } 1738 break; 1739 } 1740 case UPDATE_TIME: { 1741 synchronized (ActivityManagerService.this) { 1742 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1743 ProcessRecord r = mLruProcesses.get(i); 1744 if (r.thread != null) { 1745 try { 1746 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1747 } catch (RemoteException ex) { 1748 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1749 } 1750 } 1751 } 1752 } 1753 break; 1754 } 1755 } 1756 } 1757 }; 1758 1759 static final int COLLECT_PSS_BG_MSG = 1; 1760 1761 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1762 @Override 1763 public void handleMessage(Message msg) { 1764 switch (msg.what) { 1765 case COLLECT_PSS_BG_MSG: { 1766 int i=0, num=0; 1767 long start = SystemClock.uptimeMillis(); 1768 long[] tmp = new long[1]; 1769 do { 1770 ProcessRecord proc; 1771 int procState; 1772 int pid; 1773 synchronized (ActivityManagerService.this) { 1774 if (i >= mPendingPssProcesses.size()) { 1775 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1776 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1777 mPendingPssProcesses.clear(); 1778 return; 1779 } 1780 proc = mPendingPssProcesses.get(i); 1781 procState = proc.pssProcState; 1782 if (proc.thread != null && procState == proc.setProcState) { 1783 pid = proc.pid; 1784 } else { 1785 proc = null; 1786 pid = 0; 1787 } 1788 i++; 1789 } 1790 if (proc != null) { 1791 long pss = Debug.getPss(pid, tmp); 1792 synchronized (ActivityManagerService.this) { 1793 if (proc.thread != null && proc.setProcState == procState 1794 && proc.pid == pid) { 1795 num++; 1796 proc.lastPssTime = SystemClock.uptimeMillis(); 1797 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1798 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1799 + ": " + pss + " lastPss=" + proc.lastPss 1800 + " state=" + ProcessList.makeProcStateString(procState)); 1801 if (proc.initialIdlePss == 0) { 1802 proc.initialIdlePss = pss; 1803 } 1804 proc.lastPss = pss; 1805 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1806 proc.lastCachedPss = pss; 1807 } 1808 } 1809 } 1810 } 1811 } while (true); 1812 } 1813 } 1814 } 1815 }; 1816 1817 /** 1818 * Monitor for package changes and update our internal state. 1819 */ 1820 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1821 @Override 1822 public void onPackageRemoved(String packageName, int uid) { 1823 // Remove all tasks with activities in the specified package from the list of recent tasks 1824 synchronized (ActivityManagerService.this) { 1825 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1826 TaskRecord tr = mRecentTasks.get(i); 1827 ComponentName cn = tr.intent.getComponent(); 1828 if (cn != null && cn.getPackageName().equals(packageName)) { 1829 // If the package name matches, remove the task and kill the process 1830 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1831 } 1832 } 1833 } 1834 } 1835 1836 @Override 1837 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1838 final PackageManager pm = mContext.getPackageManager(); 1839 final ArrayList<TaskRecord> recentTasks = new ArrayList<TaskRecord>(); 1840 final ArrayList<TaskRecord> tasksToRemove = new ArrayList<TaskRecord>(); 1841 // Copy the list of recent tasks so that we don't hold onto the lock on 1842 // ActivityManagerService for long periods while checking if components exist. 1843 synchronized (ActivityManagerService.this) { 1844 recentTasks.addAll(mRecentTasks); 1845 } 1846 // Check the recent tasks and filter out all tasks with components that no longer exist. 1847 Intent tmpI = new Intent(); 1848 for (int i = recentTasks.size() - 1; i >= 0; i--) { 1849 TaskRecord tr = recentTasks.get(i); 1850 ComponentName cn = tr.intent.getComponent(); 1851 if (cn != null && cn.getPackageName().equals(packageName)) { 1852 try { 1853 // Add the task to the list to remove if the component no longer exists 1854 tmpI.setComponent(cn); 1855 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1856 tasksToRemove.add(tr); 1857 } 1858 } catch (Exception e) {} 1859 } 1860 } 1861 // Prune all the tasks with removed components from the list of recent tasks 1862 synchronized (ActivityManagerService.this) { 1863 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1864 TaskRecord tr = tasksToRemove.get(i); 1865 // Remove the task but don't kill the process 1866 removeTaskByIdLocked(tr.taskId, 0); 1867 } 1868 } 1869 return true; 1870 } 1871 1872 @Override 1873 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1874 // Force stop the specified packages 1875 if (packages != null) { 1876 for (String pkg : packages) { 1877 synchronized (ActivityManagerService.this) { 1878 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1879 "finished booting")) { 1880 return true; 1881 } 1882 } 1883 } 1884 } 1885 return false; 1886 } 1887 }; 1888 1889 public void setSystemProcess() { 1890 try { 1891 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1892 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1893 ServiceManager.addService("meminfo", new MemBinder(this)); 1894 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1895 ServiceManager.addService("dbinfo", new DbBinder(this)); 1896 if (MONITOR_CPU_USAGE) { 1897 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1898 } 1899 ServiceManager.addService("permission", new PermissionController(this)); 1900 1901 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1902 "android", STOCK_PM_FLAGS); 1903 mSystemThread.installSystemApplicationInfo(info); 1904 1905 synchronized (this) { 1906 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1907 app.persistent = true; 1908 app.pid = MY_PID; 1909 app.maxAdj = ProcessList.SYSTEM_ADJ; 1910 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1911 mProcessNames.put(app.processName, app.uid, app); 1912 synchronized (mPidsSelfLocked) { 1913 mPidsSelfLocked.put(app.pid, app); 1914 } 1915 updateLruProcessLocked(app, false, null); 1916 updateOomAdjLocked(); 1917 } 1918 } catch (PackageManager.NameNotFoundException e) { 1919 throw new RuntimeException( 1920 "Unable to find android system package", e); 1921 } 1922 } 1923 1924 public void setWindowManager(WindowManagerService wm) { 1925 mWindowManager = wm; 1926 mStackSupervisor.setWindowManager(wm); 1927 } 1928 1929 public void startObservingNativeCrashes() { 1930 final NativeCrashListener ncl = new NativeCrashListener(this); 1931 ncl.start(); 1932 } 1933 1934 public IAppOpsService getAppOpsService() { 1935 return mAppOpsService; 1936 } 1937 1938 static class MemBinder extends Binder { 1939 ActivityManagerService mActivityManagerService; 1940 MemBinder(ActivityManagerService activityManagerService) { 1941 mActivityManagerService = activityManagerService; 1942 } 1943 1944 @Override 1945 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1946 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1947 != PackageManager.PERMISSION_GRANTED) { 1948 pw.println("Permission Denial: can't dump meminfo from from pid=" 1949 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1950 + " without permission " + android.Manifest.permission.DUMP); 1951 return; 1952 } 1953 1954 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1955 } 1956 } 1957 1958 static class GraphicsBinder extends Binder { 1959 ActivityManagerService mActivityManagerService; 1960 GraphicsBinder(ActivityManagerService activityManagerService) { 1961 mActivityManagerService = activityManagerService; 1962 } 1963 1964 @Override 1965 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1966 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1967 != PackageManager.PERMISSION_GRANTED) { 1968 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1969 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1970 + " without permission " + android.Manifest.permission.DUMP); 1971 return; 1972 } 1973 1974 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1975 } 1976 } 1977 1978 static class DbBinder extends Binder { 1979 ActivityManagerService mActivityManagerService; 1980 DbBinder(ActivityManagerService activityManagerService) { 1981 mActivityManagerService = activityManagerService; 1982 } 1983 1984 @Override 1985 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1986 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1987 != PackageManager.PERMISSION_GRANTED) { 1988 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1989 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1990 + " without permission " + android.Manifest.permission.DUMP); 1991 return; 1992 } 1993 1994 mActivityManagerService.dumpDbInfo(fd, pw, args); 1995 } 1996 } 1997 1998 static class CpuBinder extends Binder { 1999 ActivityManagerService mActivityManagerService; 2000 CpuBinder(ActivityManagerService activityManagerService) { 2001 mActivityManagerService = activityManagerService; 2002 } 2003 2004 @Override 2005 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2006 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2007 != PackageManager.PERMISSION_GRANTED) { 2008 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2009 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2010 + " without permission " + android.Manifest.permission.DUMP); 2011 return; 2012 } 2013 2014 synchronized (mActivityManagerService.mProcessCpuThread) { 2015 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2016 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2017 SystemClock.uptimeMillis())); 2018 } 2019 } 2020 } 2021 2022 public static final class Lifecycle extends SystemService { 2023 private final ActivityManagerService mService; 2024 2025 public Lifecycle(Context context) { 2026 super(context); 2027 mService = new ActivityManagerService(context); 2028 } 2029 2030 @Override 2031 public void onStart() { 2032 mService.start(); 2033 } 2034 2035 public ActivityManagerService getService() { 2036 return mService; 2037 } 2038 } 2039 2040 // Note: This method is invoked on the main thread but may need to attach various 2041 // handlers to other threads. So take care to be explicit about the looper. 2042 public ActivityManagerService(Context systemContext) { 2043 mContext = systemContext; 2044 mFactoryTest = FactoryTest.getMode(); 2045 mSystemThread = ActivityThread.currentActivityThread(); 2046 2047 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2048 2049 mHandlerThread = new ServiceThread(TAG, 2050 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2051 mHandlerThread.start(); 2052 mHandler = new MainHandler(mHandlerThread.getLooper()); 2053 2054 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2055 "foreground", BROADCAST_FG_TIMEOUT, false); 2056 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2057 "background", BROADCAST_BG_TIMEOUT, true); 2058 mBroadcastQueues[0] = mFgBroadcastQueue; 2059 mBroadcastQueues[1] = mBgBroadcastQueue; 2060 2061 mServices = new ActiveServices(this); 2062 mProviderMap = new ProviderMap(this); 2063 2064 // TODO: Move creation of battery stats service outside of activity manager service. 2065 File dataDir = Environment.getDataDirectory(); 2066 File systemDir = new File(dataDir, "system"); 2067 systemDir.mkdirs(); 2068 mBatteryStatsService = new BatteryStatsService(new File( 2069 systemDir, "batterystats.bin").toString(), mHandler); 2070 mBatteryStatsService.getActiveStatistics().readLocked(); 2071 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2072 mOnBattery = DEBUG_POWER ? true 2073 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2074 mBatteryStatsService.getActiveStatistics().setCallback(this); 2075 2076 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2077 2078 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2079 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2080 2081 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2082 2083 // User 0 is the first and only user that runs at boot. 2084 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2085 mUserLru.add(Integer.valueOf(0)); 2086 updateStartedUserArrayLocked(); 2087 2088 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2089 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2090 2091 mConfiguration.setToDefaults(); 2092 mConfiguration.setLocale(Locale.getDefault()); 2093 2094 mConfigurationSeq = mConfiguration.seq = 1; 2095 mProcessCpuTracker.init(); 2096 2097 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2098 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2099 mStackSupervisor = new ActivityStackSupervisor(this); 2100 2101 mProcessCpuThread = new Thread("CpuTracker") { 2102 @Override 2103 public void run() { 2104 while (true) { 2105 try { 2106 try { 2107 synchronized(this) { 2108 final long now = SystemClock.uptimeMillis(); 2109 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2110 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2111 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2112 // + ", write delay=" + nextWriteDelay); 2113 if (nextWriteDelay < nextCpuDelay) { 2114 nextCpuDelay = nextWriteDelay; 2115 } 2116 if (nextCpuDelay > 0) { 2117 mProcessCpuMutexFree.set(true); 2118 this.wait(nextCpuDelay); 2119 } 2120 } 2121 } catch (InterruptedException e) { 2122 } 2123 updateCpuStatsNow(); 2124 } catch (Exception e) { 2125 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2126 } 2127 } 2128 } 2129 }; 2130 2131 Watchdog.getInstance().addMonitor(this); 2132 Watchdog.getInstance().addThread(mHandler); 2133 } 2134 2135 private void start() { 2136 mProcessCpuThread.start(); 2137 2138 mBatteryStatsService.publish(mContext); 2139 mUsageStatsService.publish(mContext); 2140 mAppOpsService.publish(mContext); 2141 2142 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2143 } 2144 2145 @Override 2146 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2147 throws RemoteException { 2148 if (code == SYSPROPS_TRANSACTION) { 2149 // We need to tell all apps about the system property change. 2150 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2151 synchronized(this) { 2152 final int NP = mProcessNames.getMap().size(); 2153 for (int ip=0; ip<NP; ip++) { 2154 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2155 final int NA = apps.size(); 2156 for (int ia=0; ia<NA; ia++) { 2157 ProcessRecord app = apps.valueAt(ia); 2158 if (app.thread != null) { 2159 procs.add(app.thread.asBinder()); 2160 } 2161 } 2162 } 2163 } 2164 2165 int N = procs.size(); 2166 for (int i=0; i<N; i++) { 2167 Parcel data2 = Parcel.obtain(); 2168 try { 2169 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2170 } catch (RemoteException e) { 2171 } 2172 data2.recycle(); 2173 } 2174 } 2175 try { 2176 return super.onTransact(code, data, reply, flags); 2177 } catch (RuntimeException e) { 2178 // The activity manager only throws security exceptions, so let's 2179 // log all others. 2180 if (!(e instanceof SecurityException)) { 2181 Slog.wtf(TAG, "Activity Manager Crash", e); 2182 } 2183 throw e; 2184 } 2185 } 2186 2187 void updateCpuStats() { 2188 final long now = SystemClock.uptimeMillis(); 2189 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2190 return; 2191 } 2192 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2193 synchronized (mProcessCpuThread) { 2194 mProcessCpuThread.notify(); 2195 } 2196 } 2197 } 2198 2199 void updateCpuStatsNow() { 2200 synchronized (mProcessCpuThread) { 2201 mProcessCpuMutexFree.set(false); 2202 final long now = SystemClock.uptimeMillis(); 2203 boolean haveNewCpuStats = false; 2204 2205 if (MONITOR_CPU_USAGE && 2206 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2207 mLastCpuTime.set(now); 2208 haveNewCpuStats = true; 2209 mProcessCpuTracker.update(); 2210 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2211 //Slog.i(TAG, "Total CPU usage: " 2212 // + mProcessCpu.getTotalCpuPercent() + "%"); 2213 2214 // Slog the cpu usage if the property is set. 2215 if ("true".equals(SystemProperties.get("events.cpu"))) { 2216 int user = mProcessCpuTracker.getLastUserTime(); 2217 int system = mProcessCpuTracker.getLastSystemTime(); 2218 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2219 int irq = mProcessCpuTracker.getLastIrqTime(); 2220 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2221 int idle = mProcessCpuTracker.getLastIdleTime(); 2222 2223 int total = user + system + iowait + irq + softIrq + idle; 2224 if (total == 0) total = 1; 2225 2226 EventLog.writeEvent(EventLogTags.CPU, 2227 ((user+system+iowait+irq+softIrq) * 100) / total, 2228 (user * 100) / total, 2229 (system * 100) / total, 2230 (iowait * 100) / total, 2231 (irq * 100) / total, 2232 (softIrq * 100) / total); 2233 } 2234 } 2235 2236 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2237 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2238 synchronized(bstats) { 2239 synchronized(mPidsSelfLocked) { 2240 if (haveNewCpuStats) { 2241 if (mOnBattery) { 2242 int perc = bstats.startAddingCpuLocked(); 2243 int totalUTime = 0; 2244 int totalSTime = 0; 2245 final int N = mProcessCpuTracker.countStats(); 2246 for (int i=0; i<N; i++) { 2247 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2248 if (!st.working) { 2249 continue; 2250 } 2251 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2252 int otherUTime = (st.rel_utime*perc)/100; 2253 int otherSTime = (st.rel_stime*perc)/100; 2254 totalUTime += otherUTime; 2255 totalSTime += otherSTime; 2256 if (pr != null) { 2257 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2258 if (ps == null || !ps.isActive()) { 2259 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2260 pr.info.uid, pr.processName); 2261 } 2262 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2263 st.rel_stime-otherSTime); 2264 ps.addSpeedStepTimes(cpuSpeedTimes); 2265 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2266 } else { 2267 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2268 if (ps == null || !ps.isActive()) { 2269 st.batteryStats = ps = bstats.getProcessStatsLocked( 2270 bstats.mapUid(st.uid), st.name); 2271 } 2272 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2273 st.rel_stime-otherSTime); 2274 ps.addSpeedStepTimes(cpuSpeedTimes); 2275 } 2276 } 2277 bstats.finishAddingCpuLocked(perc, totalUTime, 2278 totalSTime, cpuSpeedTimes); 2279 } 2280 } 2281 } 2282 2283 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2284 mLastWriteTime = now; 2285 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2286 } 2287 } 2288 } 2289 } 2290 2291 @Override 2292 public void batteryNeedsCpuUpdate() { 2293 updateCpuStatsNow(); 2294 } 2295 2296 @Override 2297 public void batteryPowerChanged(boolean onBattery) { 2298 // When plugging in, update the CPU stats first before changing 2299 // the plug state. 2300 updateCpuStatsNow(); 2301 synchronized (this) { 2302 synchronized(mPidsSelfLocked) { 2303 mOnBattery = DEBUG_POWER ? true : onBattery; 2304 } 2305 } 2306 } 2307 2308 /** 2309 * Initialize the application bind args. These are passed to each 2310 * process when the bindApplication() IPC is sent to the process. They're 2311 * lazily setup to make sure the services are running when they're asked for. 2312 */ 2313 private HashMap<String, IBinder> getCommonServicesLocked() { 2314 if (mAppBindArgs == null) { 2315 mAppBindArgs = new HashMap<String, IBinder>(); 2316 2317 // Setup the application init args 2318 mAppBindArgs.put("package", ServiceManager.getService("package")); 2319 mAppBindArgs.put("window", ServiceManager.getService("window")); 2320 mAppBindArgs.put(Context.ALARM_SERVICE, 2321 ServiceManager.getService(Context.ALARM_SERVICE)); 2322 } 2323 return mAppBindArgs; 2324 } 2325 2326 final void setFocusedActivityLocked(ActivityRecord r) { 2327 if (mFocusedActivity != r) { 2328 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2329 mFocusedActivity = r; 2330 mStackSupervisor.setFocusedStack(r); 2331 if (r != null) { 2332 mWindowManager.setFocusedApp(r.appToken, true); 2333 } 2334 applyUpdateLockStateLocked(r); 2335 } 2336 } 2337 2338 @Override 2339 public void setFocusedStack(int stackId) { 2340 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2341 synchronized (ActivityManagerService.this) { 2342 ActivityStack stack = mStackSupervisor.getStack(stackId); 2343 if (stack != null) { 2344 ActivityRecord r = stack.topRunningActivityLocked(null); 2345 if (r != null) { 2346 setFocusedActivityLocked(r); 2347 } 2348 } 2349 } 2350 } 2351 2352 @Override 2353 public void notifyActivityDrawn(IBinder token) { 2354 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2355 synchronized (this) { 2356 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2357 if (r != null) { 2358 r.task.stack.notifyActivityDrawnLocked(r); 2359 } 2360 } 2361 } 2362 2363 final void applyUpdateLockStateLocked(ActivityRecord r) { 2364 // Modifications to the UpdateLock state are done on our handler, outside 2365 // the activity manager's locks. The new state is determined based on the 2366 // state *now* of the relevant activity record. The object is passed to 2367 // the handler solely for logging detail, not to be consulted/modified. 2368 final boolean nextState = r != null && r.immersive; 2369 mHandler.sendMessage( 2370 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2371 } 2372 2373 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2374 Message msg = Message.obtain(); 2375 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2376 msg.obj = r.task.askedCompatMode ? null : r; 2377 mHandler.sendMessage(msg); 2378 } 2379 2380 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2381 String what, Object obj, ProcessRecord srcApp) { 2382 app.lastActivityTime = now; 2383 2384 if (app.activities.size() > 0) { 2385 // Don't want to touch dependent processes that are hosting activities. 2386 return index; 2387 } 2388 2389 int lrui = mLruProcesses.lastIndexOf(app); 2390 if (lrui < 0) { 2391 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2392 + what + " " + obj + " from " + srcApp); 2393 return index; 2394 } 2395 2396 if (lrui >= index) { 2397 // Don't want to cause this to move dependent processes *back* in the 2398 // list as if they were less frequently used. 2399 return index; 2400 } 2401 2402 if (lrui >= mLruProcessActivityStart) { 2403 // Don't want to touch dependent processes that are hosting activities. 2404 return index; 2405 } 2406 2407 mLruProcesses.remove(lrui); 2408 if (index > 0) { 2409 index--; 2410 } 2411 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2412 + " in LRU list: " + app); 2413 mLruProcesses.add(index, app); 2414 return index; 2415 } 2416 2417 final void removeLruProcessLocked(ProcessRecord app) { 2418 int lrui = mLruProcesses.lastIndexOf(app); 2419 if (lrui >= 0) { 2420 if (lrui <= mLruProcessActivityStart) { 2421 mLruProcessActivityStart--; 2422 } 2423 if (lrui <= mLruProcessServiceStart) { 2424 mLruProcessServiceStart--; 2425 } 2426 mLruProcesses.remove(lrui); 2427 } 2428 } 2429 2430 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2431 ProcessRecord client) { 2432 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2433 || app.treatLikeActivity; 2434 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2435 if (!activityChange && hasActivity) { 2436 // The process has activities, so we are only allowing activity-based adjustments 2437 // to move it. It should be kept in the front of the list with other 2438 // processes that have activities, and we don't want those to change their 2439 // order except due to activity operations. 2440 return; 2441 } 2442 2443 mLruSeq++; 2444 final long now = SystemClock.uptimeMillis(); 2445 app.lastActivityTime = now; 2446 2447 // First a quick reject: if the app is already at the position we will 2448 // put it, then there is nothing to do. 2449 if (hasActivity) { 2450 final int N = mLruProcesses.size(); 2451 if (N > 0 && mLruProcesses.get(N-1) == app) { 2452 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2453 return; 2454 } 2455 } else { 2456 if (mLruProcessServiceStart > 0 2457 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2458 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2459 return; 2460 } 2461 } 2462 2463 int lrui = mLruProcesses.lastIndexOf(app); 2464 2465 if (app.persistent && lrui >= 0) { 2466 // We don't care about the position of persistent processes, as long as 2467 // they are in the list. 2468 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2469 return; 2470 } 2471 2472 /* In progress: compute new position first, so we can avoid doing work 2473 if the process is not actually going to move. Not yet working. 2474 int addIndex; 2475 int nextIndex; 2476 boolean inActivity = false, inService = false; 2477 if (hasActivity) { 2478 // Process has activities, put it at the very tipsy-top. 2479 addIndex = mLruProcesses.size(); 2480 nextIndex = mLruProcessServiceStart; 2481 inActivity = true; 2482 } else if (hasService) { 2483 // Process has services, put it at the top of the service list. 2484 addIndex = mLruProcessActivityStart; 2485 nextIndex = mLruProcessServiceStart; 2486 inActivity = true; 2487 inService = true; 2488 } else { 2489 // Process not otherwise of interest, it goes to the top of the non-service area. 2490 addIndex = mLruProcessServiceStart; 2491 if (client != null) { 2492 int clientIndex = mLruProcesses.lastIndexOf(client); 2493 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2494 + app); 2495 if (clientIndex >= 0 && addIndex > clientIndex) { 2496 addIndex = clientIndex; 2497 } 2498 } 2499 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2500 } 2501 2502 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2503 + mLruProcessActivityStart + "): " + app); 2504 */ 2505 2506 if (lrui >= 0) { 2507 if (lrui < mLruProcessActivityStart) { 2508 mLruProcessActivityStart--; 2509 } 2510 if (lrui < mLruProcessServiceStart) { 2511 mLruProcessServiceStart--; 2512 } 2513 /* 2514 if (addIndex > lrui) { 2515 addIndex--; 2516 } 2517 if (nextIndex > lrui) { 2518 nextIndex--; 2519 } 2520 */ 2521 mLruProcesses.remove(lrui); 2522 } 2523 2524 /* 2525 mLruProcesses.add(addIndex, app); 2526 if (inActivity) { 2527 mLruProcessActivityStart++; 2528 } 2529 if (inService) { 2530 mLruProcessActivityStart++; 2531 } 2532 */ 2533 2534 int nextIndex; 2535 if (hasActivity) { 2536 final int N = mLruProcesses.size(); 2537 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2538 // Process doesn't have activities, but has clients with 2539 // activities... move it up, but one below the top (the top 2540 // should always have a real activity). 2541 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2542 mLruProcesses.add(N-1, app); 2543 // To keep it from spamming the LRU list (by making a bunch of clients), 2544 // we will push down any other entries owned by the app. 2545 final int uid = app.info.uid; 2546 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2547 ProcessRecord subProc = mLruProcesses.get(i); 2548 if (subProc.info.uid == uid) { 2549 // We want to push this one down the list. If the process after 2550 // it is for the same uid, however, don't do so, because we don't 2551 // want them internally to be re-ordered. 2552 if (mLruProcesses.get(i-1).info.uid != uid) { 2553 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2554 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2555 ProcessRecord tmp = mLruProcesses.get(i); 2556 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2557 mLruProcesses.set(i-1, tmp); 2558 i--; 2559 } 2560 } else { 2561 // A gap, we can stop here. 2562 break; 2563 } 2564 } 2565 } else { 2566 // Process has activities, put it at the very tipsy-top. 2567 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2568 mLruProcesses.add(app); 2569 } 2570 nextIndex = mLruProcessServiceStart; 2571 } else if (hasService) { 2572 // Process has services, put it at the top of the service list. 2573 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2574 mLruProcesses.add(mLruProcessActivityStart, app); 2575 nextIndex = mLruProcessServiceStart; 2576 mLruProcessActivityStart++; 2577 } else { 2578 // Process not otherwise of interest, it goes to the top of the non-service area. 2579 int index = mLruProcessServiceStart; 2580 if (client != null) { 2581 // If there is a client, don't allow the process to be moved up higher 2582 // in the list than that client. 2583 int clientIndex = mLruProcesses.lastIndexOf(client); 2584 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2585 + " when updating " + app); 2586 if (clientIndex <= lrui) { 2587 // Don't allow the client index restriction to push it down farther in the 2588 // list than it already is. 2589 clientIndex = lrui; 2590 } 2591 if (clientIndex >= 0 && index > clientIndex) { 2592 index = clientIndex; 2593 } 2594 } 2595 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2596 mLruProcesses.add(index, app); 2597 nextIndex = index-1; 2598 mLruProcessActivityStart++; 2599 mLruProcessServiceStart++; 2600 } 2601 2602 // If the app is currently using a content provider or service, 2603 // bump those processes as well. 2604 for (int j=app.connections.size()-1; j>=0; j--) { 2605 ConnectionRecord cr = app.connections.valueAt(j); 2606 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2607 && cr.binding.service.app != null 2608 && cr.binding.service.app.lruSeq != mLruSeq 2609 && !cr.binding.service.app.persistent) { 2610 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2611 "service connection", cr, app); 2612 } 2613 } 2614 for (int j=app.conProviders.size()-1; j>=0; j--) { 2615 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2616 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2617 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2618 "provider reference", cpr, app); 2619 } 2620 } 2621 } 2622 2623 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2624 if (uid == Process.SYSTEM_UID) { 2625 // The system gets to run in any process. If there are multiple 2626 // processes with the same uid, just pick the first (this 2627 // should never happen). 2628 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2629 if (procs == null) return null; 2630 final int N = procs.size(); 2631 for (int i = 0; i < N; i++) { 2632 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2633 } 2634 } 2635 ProcessRecord proc = mProcessNames.get(processName, uid); 2636 if (false && proc != null && !keepIfLarge 2637 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2638 && proc.lastCachedPss >= 4000) { 2639 // Turn this condition on to cause killing to happen regularly, for testing. 2640 if (proc.baseProcessTracker != null) { 2641 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2642 } 2643 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2644 + "k from cached"); 2645 } else if (proc != null && !keepIfLarge 2646 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2647 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2648 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2649 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2650 if (proc.baseProcessTracker != null) { 2651 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2652 } 2653 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2654 + "k from cached"); 2655 } 2656 } 2657 return proc; 2658 } 2659 2660 void ensurePackageDexOpt(String packageName) { 2661 IPackageManager pm = AppGlobals.getPackageManager(); 2662 try { 2663 if (pm.performDexOpt(packageName)) { 2664 mDidDexOpt = true; 2665 } 2666 } catch (RemoteException e) { 2667 } 2668 } 2669 2670 boolean isNextTransitionForward() { 2671 int transit = mWindowManager.getPendingAppTransition(); 2672 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2673 || transit == AppTransition.TRANSIT_TASK_OPEN 2674 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2675 } 2676 2677 final ProcessRecord startProcessLocked(String processName, 2678 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2679 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2680 boolean isolated, boolean keepIfLarge) { 2681 ProcessRecord app; 2682 if (!isolated) { 2683 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2684 } else { 2685 // If this is an isolated process, it can't re-use an existing process. 2686 app = null; 2687 } 2688 // We don't have to do anything more if: 2689 // (1) There is an existing application record; and 2690 // (2) The caller doesn't think it is dead, OR there is no thread 2691 // object attached to it so we know it couldn't have crashed; and 2692 // (3) There is a pid assigned to it, so it is either starting or 2693 // already running. 2694 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2695 + " app=" + app + " knownToBeDead=" + knownToBeDead 2696 + " thread=" + (app != null ? app.thread : null) 2697 + " pid=" + (app != null ? app.pid : -1)); 2698 if (app != null && app.pid > 0) { 2699 if (!knownToBeDead || app.thread == null) { 2700 // We already have the app running, or are waiting for it to 2701 // come up (we have a pid but not yet its thread), so keep it. 2702 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2703 // If this is a new package in the process, add the package to the list 2704 app.addPackage(info.packageName, mProcessStats); 2705 return app; 2706 } 2707 2708 // An application record is attached to a previous process, 2709 // clean it up now. 2710 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2711 handleAppDiedLocked(app, true, true); 2712 } 2713 2714 String hostingNameStr = hostingName != null 2715 ? hostingName.flattenToShortString() : null; 2716 2717 if (!isolated) { 2718 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2719 // If we are in the background, then check to see if this process 2720 // is bad. If so, we will just silently fail. 2721 if (mBadProcesses.get(info.processName, info.uid) != null) { 2722 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2723 + "/" + info.processName); 2724 return null; 2725 } 2726 } else { 2727 // When the user is explicitly starting a process, then clear its 2728 // crash count so that we won't make it bad until they see at 2729 // least one crash dialog again, and make the process good again 2730 // if it had been bad. 2731 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2732 + "/" + info.processName); 2733 mProcessCrashTimes.remove(info.processName, info.uid); 2734 if (mBadProcesses.get(info.processName, info.uid) != null) { 2735 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2736 UserHandle.getUserId(info.uid), info.uid, 2737 info.processName); 2738 mBadProcesses.remove(info.processName, info.uid); 2739 if (app != null) { 2740 app.bad = false; 2741 } 2742 } 2743 } 2744 } 2745 2746 if (app == null) { 2747 app = newProcessRecordLocked(info, processName, isolated); 2748 if (app == null) { 2749 Slog.w(TAG, "Failed making new process record for " 2750 + processName + "/" + info.uid + " isolated=" + isolated); 2751 return null; 2752 } 2753 mProcessNames.put(processName, app.uid, app); 2754 if (isolated) { 2755 mIsolatedProcesses.put(app.uid, app); 2756 } 2757 } else { 2758 // If this is a new package in the process, add the package to the list 2759 app.addPackage(info.packageName, mProcessStats); 2760 } 2761 2762 // If the system is not ready yet, then hold off on starting this 2763 // process until it is. 2764 if (!mProcessesReady 2765 && !isAllowedWhileBooting(info) 2766 && !allowWhileBooting) { 2767 if (!mProcessesOnHold.contains(app)) { 2768 mProcessesOnHold.add(app); 2769 } 2770 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2771 return app; 2772 } 2773 2774 startProcessLocked(app, hostingType, hostingNameStr); 2775 return (app.pid != 0) ? app : null; 2776 } 2777 2778 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2779 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2780 } 2781 2782 private final void startProcessLocked(ProcessRecord app, 2783 String hostingType, String hostingNameStr) { 2784 if (app.pid > 0 && app.pid != MY_PID) { 2785 synchronized (mPidsSelfLocked) { 2786 mPidsSelfLocked.remove(app.pid); 2787 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2788 } 2789 app.setPid(0); 2790 } 2791 2792 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2793 "startProcessLocked removing on hold: " + app); 2794 mProcessesOnHold.remove(app); 2795 2796 updateCpuStats(); 2797 2798 try { 2799 int uid = app.uid; 2800 2801 int[] gids = null; 2802 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2803 if (!app.isolated) { 2804 int[] permGids = null; 2805 try { 2806 final PackageManager pm = mContext.getPackageManager(); 2807 permGids = pm.getPackageGids(app.info.packageName); 2808 2809 if (Environment.isExternalStorageEmulated()) { 2810 if (pm.checkPermission( 2811 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2812 app.info.packageName) == PERMISSION_GRANTED) { 2813 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2814 } else { 2815 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2816 } 2817 } 2818 } catch (PackageManager.NameNotFoundException e) { 2819 Slog.w(TAG, "Unable to retrieve gids", e); 2820 } 2821 2822 /* 2823 * Add shared application GID so applications can share some 2824 * resources like shared libraries 2825 */ 2826 if (permGids == null) { 2827 gids = new int[1]; 2828 } else { 2829 gids = new int[permGids.length + 1]; 2830 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2831 } 2832 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2833 } 2834 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2835 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2836 && mTopComponent != null 2837 && app.processName.equals(mTopComponent.getPackageName())) { 2838 uid = 0; 2839 } 2840 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2841 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2842 uid = 0; 2843 } 2844 } 2845 int debugFlags = 0; 2846 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2847 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2848 // Also turn on CheckJNI for debuggable apps. It's quite 2849 // awkward to turn on otherwise. 2850 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2851 } 2852 // Run the app in safe mode if its manifest requests so or the 2853 // system is booted in safe mode. 2854 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2855 mSafeMode == true) { 2856 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2857 } 2858 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2859 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2860 } 2861 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2862 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2863 } 2864 if ("1".equals(SystemProperties.get("debug.assert"))) { 2865 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2866 } 2867 2868 String requiredAbi = app.info.requiredCpuAbi; 2869 if (requiredAbi == null) { 2870 requiredAbi = Build.SUPPORTED_ABIS[0]; 2871 } 2872 2873 // Start the process. It will either succeed and return a result containing 2874 // the PID of the new process, or else throw a RuntimeException. 2875 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2876 app.processName, uid, uid, gids, debugFlags, mountExternal, 2877 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2878 2879 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2880 synchronized (bs) { 2881 if (bs.isOnBattery()) { 2882 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2883 } 2884 } 2885 2886 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2887 UserHandle.getUserId(uid), startResult.pid, uid, 2888 app.processName, hostingType, 2889 hostingNameStr != null ? hostingNameStr : ""); 2890 2891 if (app.persistent) { 2892 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2893 } 2894 2895 StringBuilder buf = mStringBuilder; 2896 buf.setLength(0); 2897 buf.append("Start proc "); 2898 buf.append(app.processName); 2899 buf.append(" for "); 2900 buf.append(hostingType); 2901 if (hostingNameStr != null) { 2902 buf.append(" "); 2903 buf.append(hostingNameStr); 2904 } 2905 buf.append(": pid="); 2906 buf.append(startResult.pid); 2907 buf.append(" uid="); 2908 buf.append(uid); 2909 buf.append(" gids={"); 2910 if (gids != null) { 2911 for (int gi=0; gi<gids.length; gi++) { 2912 if (gi != 0) buf.append(", "); 2913 buf.append(gids[gi]); 2914 2915 } 2916 } 2917 buf.append("}"); 2918 Slog.i(TAG, buf.toString()); 2919 app.setPid(startResult.pid); 2920 app.usingWrapper = startResult.usingWrapper; 2921 app.removed = false; 2922 synchronized (mPidsSelfLocked) { 2923 this.mPidsSelfLocked.put(startResult.pid, app); 2924 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2925 msg.obj = app; 2926 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2927 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2928 } 2929 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2930 app.processName, app.info.uid); 2931 if (app.isolated) { 2932 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2933 } 2934 } catch (RuntimeException e) { 2935 // XXX do better error recovery. 2936 app.setPid(0); 2937 Slog.e(TAG, "Failure starting process " + app.processName, e); 2938 } 2939 } 2940 2941 void updateUsageStats(ActivityRecord component, boolean resumed) { 2942 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2943 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2944 if (resumed) { 2945 mUsageStatsService.noteResumeComponent(component.realActivity); 2946 synchronized (stats) { 2947 stats.noteActivityResumedLocked(component.app.uid); 2948 } 2949 } else { 2950 mUsageStatsService.notePauseComponent(component.realActivity); 2951 synchronized (stats) { 2952 stats.noteActivityPausedLocked(component.app.uid); 2953 } 2954 } 2955 } 2956 2957 Intent getHomeIntent() { 2958 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2959 intent.setComponent(mTopComponent); 2960 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2961 intent.addCategory(Intent.CATEGORY_HOME); 2962 } 2963 return intent; 2964 } 2965 2966 boolean startHomeActivityLocked(int userId) { 2967 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2968 && mTopAction == null) { 2969 // We are running in factory test mode, but unable to find 2970 // the factory test app, so just sit around displaying the 2971 // error message and don't try to start anything. 2972 return false; 2973 } 2974 Intent intent = getHomeIntent(); 2975 ActivityInfo aInfo = 2976 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2977 if (aInfo != null) { 2978 intent.setComponent(new ComponentName( 2979 aInfo.applicationInfo.packageName, aInfo.name)); 2980 // Don't do this if the home app is currently being 2981 // instrumented. 2982 aInfo = new ActivityInfo(aInfo); 2983 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2984 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2985 aInfo.applicationInfo.uid, true); 2986 if (app == null || app.instrumentationClass == null) { 2987 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2988 mStackSupervisor.startHomeActivity(intent, aInfo); 2989 } 2990 } 2991 2992 return true; 2993 } 2994 2995 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2996 ActivityInfo ai = null; 2997 ComponentName comp = intent.getComponent(); 2998 try { 2999 if (comp != null) { 3000 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3001 } else { 3002 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3003 intent, 3004 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3005 flags, userId); 3006 3007 if (info != null) { 3008 ai = info.activityInfo; 3009 } 3010 } 3011 } catch (RemoteException e) { 3012 // ignore 3013 } 3014 3015 return ai; 3016 } 3017 3018 /** 3019 * Starts the "new version setup screen" if appropriate. 3020 */ 3021 void startSetupActivityLocked() { 3022 // Only do this once per boot. 3023 if (mCheckedForSetup) { 3024 return; 3025 } 3026 3027 // We will show this screen if the current one is a different 3028 // version than the last one shown, and we are not running in 3029 // low-level factory test mode. 3030 final ContentResolver resolver = mContext.getContentResolver(); 3031 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3032 Settings.Global.getInt(resolver, 3033 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3034 mCheckedForSetup = true; 3035 3036 // See if we should be showing the platform update setup UI. 3037 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3038 List<ResolveInfo> ris = mContext.getPackageManager() 3039 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3040 3041 // We don't allow third party apps to replace this. 3042 ResolveInfo ri = null; 3043 for (int i=0; ris != null && i<ris.size(); i++) { 3044 if ((ris.get(i).activityInfo.applicationInfo.flags 3045 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3046 ri = ris.get(i); 3047 break; 3048 } 3049 } 3050 3051 if (ri != null) { 3052 String vers = ri.activityInfo.metaData != null 3053 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3054 : null; 3055 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3056 vers = ri.activityInfo.applicationInfo.metaData.getString( 3057 Intent.METADATA_SETUP_VERSION); 3058 } 3059 String lastVers = Settings.Secure.getString( 3060 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3061 if (vers != null && !vers.equals(lastVers)) { 3062 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3063 intent.setComponent(new ComponentName( 3064 ri.activityInfo.packageName, ri.activityInfo.name)); 3065 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3066 null, null, 0, 0, 0, null, 0, null, false, null, null); 3067 } 3068 } 3069 } 3070 } 3071 3072 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3073 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3074 } 3075 3076 void enforceNotIsolatedCaller(String caller) { 3077 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3078 throw new SecurityException("Isolated process not allowed to call " + caller); 3079 } 3080 } 3081 3082 @Override 3083 public int getFrontActivityScreenCompatMode() { 3084 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3085 synchronized (this) { 3086 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3087 } 3088 } 3089 3090 @Override 3091 public void setFrontActivityScreenCompatMode(int mode) { 3092 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3093 "setFrontActivityScreenCompatMode"); 3094 synchronized (this) { 3095 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3096 } 3097 } 3098 3099 @Override 3100 public int getPackageScreenCompatMode(String packageName) { 3101 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3102 synchronized (this) { 3103 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3104 } 3105 } 3106 3107 @Override 3108 public void setPackageScreenCompatMode(String packageName, int mode) { 3109 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3110 "setPackageScreenCompatMode"); 3111 synchronized (this) { 3112 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3113 } 3114 } 3115 3116 @Override 3117 public boolean getPackageAskScreenCompat(String packageName) { 3118 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3119 synchronized (this) { 3120 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3121 } 3122 } 3123 3124 @Override 3125 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3126 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3127 "setPackageAskScreenCompat"); 3128 synchronized (this) { 3129 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3130 } 3131 } 3132 3133 private void dispatchProcessesChanged() { 3134 int N; 3135 synchronized (this) { 3136 N = mPendingProcessChanges.size(); 3137 if (mActiveProcessChanges.length < N) { 3138 mActiveProcessChanges = new ProcessChangeItem[N]; 3139 } 3140 mPendingProcessChanges.toArray(mActiveProcessChanges); 3141 mAvailProcessChanges.addAll(mPendingProcessChanges); 3142 mPendingProcessChanges.clear(); 3143 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3144 } 3145 3146 int i = mProcessObservers.beginBroadcast(); 3147 while (i > 0) { 3148 i--; 3149 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3150 if (observer != null) { 3151 try { 3152 for (int j=0; j<N; j++) { 3153 ProcessChangeItem item = mActiveProcessChanges[j]; 3154 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3155 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3156 + item.pid + " uid=" + item.uid + ": " 3157 + item.foregroundActivities); 3158 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3159 item.foregroundActivities); 3160 } 3161 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3162 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3163 + item.pid + " uid=" + item.uid + ": " + item.importance); 3164 observer.onImportanceChanged(item.pid, item.uid, 3165 item.importance); 3166 } 3167 } 3168 } catch (RemoteException e) { 3169 } 3170 } 3171 } 3172 mProcessObservers.finishBroadcast(); 3173 } 3174 3175 private void dispatchProcessDied(int pid, int uid) { 3176 int i = mProcessObservers.beginBroadcast(); 3177 while (i > 0) { 3178 i--; 3179 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3180 if (observer != null) { 3181 try { 3182 observer.onProcessDied(pid, uid); 3183 } catch (RemoteException e) { 3184 } 3185 } 3186 } 3187 mProcessObservers.finishBroadcast(); 3188 } 3189 3190 final void doPendingActivityLaunchesLocked(boolean doResume) { 3191 final int N = mPendingActivityLaunches.size(); 3192 if (N <= 0) { 3193 return; 3194 } 3195 for (int i=0; i<N; i++) { 3196 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3197 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3198 doResume && i == (N-1), null); 3199 } 3200 mPendingActivityLaunches.clear(); 3201 } 3202 3203 @Override 3204 public final int startActivity(IApplicationThread caller, String callingPackage, 3205 Intent intent, String resolvedType, IBinder resultTo, 3206 String resultWho, int requestCode, int startFlags, 3207 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3208 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3209 resultWho, requestCode, 3210 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3211 } 3212 3213 @Override 3214 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3215 Intent intent, String resolvedType, IBinder resultTo, 3216 String resultWho, int requestCode, int startFlags, 3217 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3218 enforceNotIsolatedCaller("startActivity"); 3219 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3220 false, true, "startActivity", null); 3221 // TODO: Switch to user app stacks here. 3222 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3223 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3224 null, null, options, userId, null); 3225 } 3226 3227 @Override 3228 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3229 Intent intent, String resolvedType, IBinder resultTo, 3230 String resultWho, int requestCode, int startFlags, String profileFile, 3231 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3232 enforceNotIsolatedCaller("startActivityAndWait"); 3233 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3234 false, true, "startActivityAndWait", null); 3235 WaitResult res = new WaitResult(); 3236 // TODO: Switch to user app stacks here. 3237 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3238 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3239 res, null, options, UserHandle.getCallingUserId(), null); 3240 return res; 3241 } 3242 3243 @Override 3244 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3245 Intent intent, String resolvedType, IBinder resultTo, 3246 String resultWho, int requestCode, int startFlags, Configuration config, 3247 Bundle options, int userId) { 3248 enforceNotIsolatedCaller("startActivityWithConfig"); 3249 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3250 false, true, "startActivityWithConfig", null); 3251 // TODO: Switch to user app stacks here. 3252 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3253 resolvedType, resultTo, resultWho, requestCode, startFlags, 3254 null, null, null, config, options, userId, null); 3255 return ret; 3256 } 3257 3258 @Override 3259 public int startActivityIntentSender(IApplicationThread caller, 3260 IntentSender intent, Intent fillInIntent, String resolvedType, 3261 IBinder resultTo, String resultWho, int requestCode, 3262 int flagsMask, int flagsValues, Bundle options) { 3263 enforceNotIsolatedCaller("startActivityIntentSender"); 3264 // Refuse possible leaked file descriptors 3265 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3266 throw new IllegalArgumentException("File descriptors passed in Intent"); 3267 } 3268 3269 IIntentSender sender = intent.getTarget(); 3270 if (!(sender instanceof PendingIntentRecord)) { 3271 throw new IllegalArgumentException("Bad PendingIntent object"); 3272 } 3273 3274 PendingIntentRecord pir = (PendingIntentRecord)sender; 3275 3276 synchronized (this) { 3277 // If this is coming from the currently resumed activity, it is 3278 // effectively saying that app switches are allowed at this point. 3279 final ActivityStack stack = getFocusedStack(); 3280 if (stack.mResumedActivity != null && 3281 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3282 mAppSwitchesAllowedTime = 0; 3283 } 3284 } 3285 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3286 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3287 return ret; 3288 } 3289 3290 @Override 3291 public boolean startNextMatchingActivity(IBinder callingActivity, 3292 Intent intent, Bundle options) { 3293 // Refuse possible leaked file descriptors 3294 if (intent != null && intent.hasFileDescriptors() == true) { 3295 throw new IllegalArgumentException("File descriptors passed in Intent"); 3296 } 3297 3298 synchronized (this) { 3299 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3300 if (r == null) { 3301 ActivityOptions.abort(options); 3302 return false; 3303 } 3304 if (r.app == null || r.app.thread == null) { 3305 // The caller is not running... d'oh! 3306 ActivityOptions.abort(options); 3307 return false; 3308 } 3309 intent = new Intent(intent); 3310 // The caller is not allowed to change the data. 3311 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3312 // And we are resetting to find the next component... 3313 intent.setComponent(null); 3314 3315 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3316 3317 ActivityInfo aInfo = null; 3318 try { 3319 List<ResolveInfo> resolves = 3320 AppGlobals.getPackageManager().queryIntentActivities( 3321 intent, r.resolvedType, 3322 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3323 UserHandle.getCallingUserId()); 3324 3325 // Look for the original activity in the list... 3326 final int N = resolves != null ? resolves.size() : 0; 3327 for (int i=0; i<N; i++) { 3328 ResolveInfo rInfo = resolves.get(i); 3329 if (rInfo.activityInfo.packageName.equals(r.packageName) 3330 && rInfo.activityInfo.name.equals(r.info.name)) { 3331 // We found the current one... the next matching is 3332 // after it. 3333 i++; 3334 if (i<N) { 3335 aInfo = resolves.get(i).activityInfo; 3336 } 3337 if (debug) { 3338 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3339 + "/" + r.info.name); 3340 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3341 + "/" + aInfo.name); 3342 } 3343 break; 3344 } 3345 } 3346 } catch (RemoteException e) { 3347 } 3348 3349 if (aInfo == null) { 3350 // Nobody who is next! 3351 ActivityOptions.abort(options); 3352 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3353 return false; 3354 } 3355 3356 intent.setComponent(new ComponentName( 3357 aInfo.applicationInfo.packageName, aInfo.name)); 3358 intent.setFlags(intent.getFlags()&~( 3359 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3360 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3361 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3362 Intent.FLAG_ACTIVITY_NEW_TASK)); 3363 3364 // Okay now we need to start the new activity, replacing the 3365 // currently running activity. This is a little tricky because 3366 // we want to start the new one as if the current one is finished, 3367 // but not finish the current one first so that there is no flicker. 3368 // And thus... 3369 final boolean wasFinishing = r.finishing; 3370 r.finishing = true; 3371 3372 // Propagate reply information over to the new activity. 3373 final ActivityRecord resultTo = r.resultTo; 3374 final String resultWho = r.resultWho; 3375 final int requestCode = r.requestCode; 3376 r.resultTo = null; 3377 if (resultTo != null) { 3378 resultTo.removeResultsLocked(r, resultWho, requestCode); 3379 } 3380 3381 final long origId = Binder.clearCallingIdentity(); 3382 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3383 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3384 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3385 options, false, null, null); 3386 Binder.restoreCallingIdentity(origId); 3387 3388 r.finishing = wasFinishing; 3389 if (res != ActivityManager.START_SUCCESS) { 3390 return false; 3391 } 3392 return true; 3393 } 3394 } 3395 3396 final int startActivityInPackage(int uid, String callingPackage, 3397 Intent intent, String resolvedType, IBinder resultTo, 3398 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3399 IActivityContainer container) { 3400 3401 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3402 false, true, "startActivityInPackage", null); 3403 3404 // TODO: Switch to user app stacks here. 3405 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3406 resultTo, resultWho, requestCode, startFlags, 3407 null, null, null, null, options, userId, container); 3408 return ret; 3409 } 3410 3411 @Override 3412 public final int startActivities(IApplicationThread caller, String callingPackage, 3413 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3414 int userId) { 3415 enforceNotIsolatedCaller("startActivities"); 3416 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3417 false, true, "startActivity", null); 3418 // TODO: Switch to user app stacks here. 3419 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3420 resolvedTypes, resultTo, options, userId); 3421 return ret; 3422 } 3423 3424 final int startActivitiesInPackage(int uid, String callingPackage, 3425 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3426 Bundle options, int userId) { 3427 3428 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3429 false, true, "startActivityInPackage", null); 3430 // TODO: Switch to user app stacks here. 3431 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3432 resultTo, options, userId); 3433 return ret; 3434 } 3435 3436 final void addRecentTaskLocked(TaskRecord task) { 3437 int N = mRecentTasks.size(); 3438 // Quick case: check if the top-most recent task is the same. 3439 if (N > 0 && mRecentTasks.get(0) == task) { 3440 return; 3441 } 3442 // Remove any existing entries that are the same kind of task. 3443 final Intent intent = task.intent; 3444 final boolean document = intent != null && intent.isDocument(); 3445 for (int i=0; i<N; i++) { 3446 TaskRecord tr = mRecentTasks.get(i); 3447 if (task != tr) { 3448 if (task.userId != tr.userId) { 3449 continue; 3450 } 3451 final Intent trIntent = tr.intent; 3452 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3453 (intent == null || !intent.filterEquals(trIntent))) { 3454 continue; 3455 } 3456 if (document || trIntent != null && trIntent.isDocument()) { 3457 // Document tasks do not match other tasks. 3458 continue; 3459 } 3460 } 3461 3462 // Either task and tr are the same or, their affinities match or their intents match 3463 // and neither of them is a document. 3464 tr.disposeThumbnail(); 3465 mRecentTasks.remove(i); 3466 i--; 3467 N--; 3468 if (task.intent == null) { 3469 // If the new recent task we are adding is not fully 3470 // specified, then replace it with the existing recent task. 3471 task = tr; 3472 } 3473 } 3474 if (N >= MAX_RECENT_TASKS) { 3475 mRecentTasks.remove(N-1).disposeThumbnail(); 3476 } 3477 mRecentTasks.add(0, task); 3478 } 3479 3480 @Override 3481 public void reportActivityFullyDrawn(IBinder token) { 3482 synchronized (this) { 3483 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3484 if (r == null) { 3485 return; 3486 } 3487 r.reportFullyDrawnLocked(); 3488 } 3489 } 3490 3491 @Override 3492 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3493 synchronized (this) { 3494 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3495 if (r == null) { 3496 return; 3497 } 3498 final long origId = Binder.clearCallingIdentity(); 3499 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3500 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3501 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3502 if (config != null) { 3503 r.frozenBeforeDestroy = true; 3504 if (!updateConfigurationLocked(config, r, false, false)) { 3505 mStackSupervisor.resumeTopActivitiesLocked(); 3506 } 3507 } 3508 Binder.restoreCallingIdentity(origId); 3509 } 3510 } 3511 3512 @Override 3513 public int getRequestedOrientation(IBinder token) { 3514 synchronized (this) { 3515 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3516 if (r == null) { 3517 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3518 } 3519 return mWindowManager.getAppOrientation(r.appToken); 3520 } 3521 } 3522 3523 /** 3524 * This is the internal entry point for handling Activity.finish(). 3525 * 3526 * @param token The Binder token referencing the Activity we want to finish. 3527 * @param resultCode Result code, if any, from this Activity. 3528 * @param resultData Result data (Intent), if any, from this Activity. 3529 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3530 * the root Activity in the task. 3531 * 3532 * @return Returns true if the activity successfully finished, or false if it is still running. 3533 */ 3534 @Override 3535 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3536 boolean finishTask) { 3537 // Refuse possible leaked file descriptors 3538 if (resultData != null && resultData.hasFileDescriptors() == true) { 3539 throw new IllegalArgumentException("File descriptors passed in Intent"); 3540 } 3541 3542 synchronized(this) { 3543 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3544 if (r == null) { 3545 return true; 3546 } 3547 // Keep track of the root activity of the task before we finish it 3548 TaskRecord tr = r.task; 3549 ActivityRecord rootR = tr.getRootActivity(); 3550 if (mController != null) { 3551 // Find the first activity that is not finishing. 3552 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3553 if (next != null) { 3554 // ask watcher if this is allowed 3555 boolean resumeOK = true; 3556 try { 3557 resumeOK = mController.activityResuming(next.packageName); 3558 } catch (RemoteException e) { 3559 mController = null; 3560 Watchdog.getInstance().setActivityController(null); 3561 } 3562 3563 if (!resumeOK) { 3564 return false; 3565 } 3566 } 3567 } 3568 final long origId = Binder.clearCallingIdentity(); 3569 try { 3570 boolean res; 3571 if (finishTask && r == rootR) { 3572 // If requested, remove the task that is associated to this activity only if it 3573 // was the root activity in the task. The result code and data is ignored because 3574 // we don't support returning them across task boundaries. 3575 res = removeTaskByIdLocked(tr.taskId, 0); 3576 } else { 3577 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3578 resultData, "app-request", true); 3579 } 3580 return res; 3581 } finally { 3582 Binder.restoreCallingIdentity(origId); 3583 } 3584 } 3585 } 3586 3587 @Override 3588 public final void finishHeavyWeightApp() { 3589 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3590 != PackageManager.PERMISSION_GRANTED) { 3591 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3592 + Binder.getCallingPid() 3593 + ", uid=" + Binder.getCallingUid() 3594 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3595 Slog.w(TAG, msg); 3596 throw new SecurityException(msg); 3597 } 3598 3599 synchronized(this) { 3600 if (mHeavyWeightProcess == null) { 3601 return; 3602 } 3603 3604 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3605 mHeavyWeightProcess.activities); 3606 for (int i=0; i<activities.size(); i++) { 3607 ActivityRecord r = activities.get(i); 3608 if (!r.finishing) { 3609 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3610 null, "finish-heavy", true); 3611 } 3612 } 3613 3614 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3615 mHeavyWeightProcess.userId, 0)); 3616 mHeavyWeightProcess = null; 3617 } 3618 } 3619 3620 @Override 3621 public void crashApplication(int uid, int initialPid, String packageName, 3622 String message) { 3623 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3624 != PackageManager.PERMISSION_GRANTED) { 3625 String msg = "Permission Denial: crashApplication() from pid=" 3626 + Binder.getCallingPid() 3627 + ", uid=" + Binder.getCallingUid() 3628 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3629 Slog.w(TAG, msg); 3630 throw new SecurityException(msg); 3631 } 3632 3633 synchronized(this) { 3634 ProcessRecord proc = null; 3635 3636 // Figure out which process to kill. We don't trust that initialPid 3637 // still has any relation to current pids, so must scan through the 3638 // list. 3639 synchronized (mPidsSelfLocked) { 3640 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3641 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3642 if (p.uid != uid) { 3643 continue; 3644 } 3645 if (p.pid == initialPid) { 3646 proc = p; 3647 break; 3648 } 3649 if (p.pkgList.containsKey(packageName)) { 3650 proc = p; 3651 } 3652 } 3653 } 3654 3655 if (proc == null) { 3656 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3657 + " initialPid=" + initialPid 3658 + " packageName=" + packageName); 3659 return; 3660 } 3661 3662 if (proc.thread != null) { 3663 if (proc.pid == Process.myPid()) { 3664 Log.w(TAG, "crashApplication: trying to crash self!"); 3665 return; 3666 } 3667 long ident = Binder.clearCallingIdentity(); 3668 try { 3669 proc.thread.scheduleCrash(message); 3670 } catch (RemoteException e) { 3671 } 3672 Binder.restoreCallingIdentity(ident); 3673 } 3674 } 3675 } 3676 3677 @Override 3678 public final void finishSubActivity(IBinder token, String resultWho, 3679 int requestCode) { 3680 synchronized(this) { 3681 final long origId = Binder.clearCallingIdentity(); 3682 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3683 if (r != null) { 3684 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3685 } 3686 Binder.restoreCallingIdentity(origId); 3687 } 3688 } 3689 3690 @Override 3691 public boolean finishActivityAffinity(IBinder token) { 3692 synchronized(this) { 3693 final long origId = Binder.clearCallingIdentity(); 3694 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3695 boolean res = false; 3696 if (r != null) { 3697 res = r.task.stack.finishActivityAffinityLocked(r); 3698 } 3699 Binder.restoreCallingIdentity(origId); 3700 return res; 3701 } 3702 } 3703 3704 @Override 3705 public boolean willActivityBeVisible(IBinder token) { 3706 synchronized(this) { 3707 ActivityStack stack = ActivityRecord.getStackLocked(token); 3708 if (stack != null) { 3709 return stack.willActivityBeVisibleLocked(token); 3710 } 3711 return false; 3712 } 3713 } 3714 3715 @Override 3716 public void overridePendingTransition(IBinder token, String packageName, 3717 int enterAnim, int exitAnim) { 3718 synchronized(this) { 3719 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3720 if (self == null) { 3721 return; 3722 } 3723 3724 final long origId = Binder.clearCallingIdentity(); 3725 3726 if (self.state == ActivityState.RESUMED 3727 || self.state == ActivityState.PAUSING) { 3728 mWindowManager.overridePendingAppTransition(packageName, 3729 enterAnim, exitAnim, null); 3730 } 3731 3732 Binder.restoreCallingIdentity(origId); 3733 } 3734 } 3735 3736 /** 3737 * Main function for removing an existing process from the activity manager 3738 * as a result of that process going away. Clears out all connections 3739 * to the process. 3740 */ 3741 private final void handleAppDiedLocked(ProcessRecord app, 3742 boolean restarting, boolean allowRestart) { 3743 int pid = app.pid; 3744 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3745 if (!restarting) { 3746 removeLruProcessLocked(app); 3747 if (pid > 0) { 3748 ProcessList.remove(pid); 3749 } 3750 } 3751 3752 if (mProfileProc == app) { 3753 clearProfilerLocked(); 3754 } 3755 3756 // Remove this application's activities from active lists. 3757 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3758 3759 app.activities.clear(); 3760 3761 if (app.instrumentationClass != null) { 3762 Slog.w(TAG, "Crash of app " + app.processName 3763 + " running instrumentation " + app.instrumentationClass); 3764 Bundle info = new Bundle(); 3765 info.putString("shortMsg", "Process crashed."); 3766 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3767 } 3768 3769 if (!restarting) { 3770 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3771 // If there was nothing to resume, and we are not already 3772 // restarting this process, but there is a visible activity that 3773 // is hosted by the process... then make sure all visible 3774 // activities are running, taking care of restarting this 3775 // process. 3776 if (hasVisibleActivities) { 3777 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3778 } 3779 } 3780 } 3781 } 3782 3783 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3784 IBinder threadBinder = thread.asBinder(); 3785 // Find the application record. 3786 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3787 ProcessRecord rec = mLruProcesses.get(i); 3788 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3789 return i; 3790 } 3791 } 3792 return -1; 3793 } 3794 3795 final ProcessRecord getRecordForAppLocked( 3796 IApplicationThread thread) { 3797 if (thread == null) { 3798 return null; 3799 } 3800 3801 int appIndex = getLRURecordIndexForAppLocked(thread); 3802 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3803 } 3804 3805 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3806 // If there are no longer any background processes running, 3807 // and the app that died was not running instrumentation, 3808 // then tell everyone we are now low on memory. 3809 boolean haveBg = false; 3810 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3811 ProcessRecord rec = mLruProcesses.get(i); 3812 if (rec.thread != null 3813 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3814 haveBg = true; 3815 break; 3816 } 3817 } 3818 3819 if (!haveBg) { 3820 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3821 if (doReport) { 3822 long now = SystemClock.uptimeMillis(); 3823 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3824 doReport = false; 3825 } else { 3826 mLastMemUsageReportTime = now; 3827 } 3828 } 3829 final ArrayList<ProcessMemInfo> memInfos 3830 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3831 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3832 long now = SystemClock.uptimeMillis(); 3833 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3834 ProcessRecord rec = mLruProcesses.get(i); 3835 if (rec == dyingProc || rec.thread == null) { 3836 continue; 3837 } 3838 if (doReport) { 3839 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3840 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3841 } 3842 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3843 // The low memory report is overriding any current 3844 // state for a GC request. Make sure to do 3845 // heavy/important/visible/foreground processes first. 3846 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3847 rec.lastRequestedGc = 0; 3848 } else { 3849 rec.lastRequestedGc = rec.lastLowMemory; 3850 } 3851 rec.reportLowMemory = true; 3852 rec.lastLowMemory = now; 3853 mProcessesToGc.remove(rec); 3854 addProcessToGcListLocked(rec); 3855 } 3856 } 3857 if (doReport) { 3858 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3859 mHandler.sendMessage(msg); 3860 } 3861 scheduleAppGcsLocked(); 3862 } 3863 } 3864 3865 final void appDiedLocked(ProcessRecord app, int pid, 3866 IApplicationThread thread) { 3867 3868 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3869 synchronized (stats) { 3870 stats.noteProcessDiedLocked(app.info.uid, pid); 3871 } 3872 3873 // Clean up already done if the process has been re-started. 3874 if (app.pid == pid && app.thread != null && 3875 app.thread.asBinder() == thread.asBinder()) { 3876 boolean doLowMem = app.instrumentationClass == null; 3877 boolean doOomAdj = doLowMem; 3878 if (!app.killedByAm) { 3879 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3880 + ") has died."); 3881 mAllowLowerMemLevel = true; 3882 } else { 3883 // Note that we always want to do oom adj to update our state with the 3884 // new number of procs. 3885 mAllowLowerMemLevel = false; 3886 doLowMem = false; 3887 } 3888 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3889 if (DEBUG_CLEANUP) Slog.v( 3890 TAG, "Dying app: " + app + ", pid: " + pid 3891 + ", thread: " + thread.asBinder()); 3892 handleAppDiedLocked(app, false, true); 3893 3894 if (doOomAdj) { 3895 updateOomAdjLocked(); 3896 } 3897 if (doLowMem) { 3898 doLowMemReportIfNeededLocked(app); 3899 } 3900 } else if (app.pid != pid) { 3901 // A new process has already been started. 3902 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3903 + ") has died and restarted (pid " + app.pid + ")."); 3904 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3905 } else if (DEBUG_PROCESSES) { 3906 Slog.d(TAG, "Received spurious death notification for thread " 3907 + thread.asBinder()); 3908 } 3909 } 3910 3911 /** 3912 * If a stack trace dump file is configured, dump process stack traces. 3913 * @param clearTraces causes the dump file to be erased prior to the new 3914 * traces being written, if true; when false, the new traces will be 3915 * appended to any existing file content. 3916 * @param firstPids of dalvik VM processes to dump stack traces for first 3917 * @param lastPids of dalvik VM processes to dump stack traces for last 3918 * @param nativeProcs optional list of native process names to dump stack crawls 3919 * @return file containing stack traces, or null if no dump file is configured 3920 */ 3921 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3922 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3923 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3924 if (tracesPath == null || tracesPath.length() == 0) { 3925 return null; 3926 } 3927 3928 File tracesFile = new File(tracesPath); 3929 try { 3930 File tracesDir = tracesFile.getParentFile(); 3931 if (!tracesDir.exists()) { 3932 tracesFile.mkdirs(); 3933 if (!SELinux.restorecon(tracesDir)) { 3934 return null; 3935 } 3936 } 3937 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3938 3939 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3940 tracesFile.createNewFile(); 3941 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3942 } catch (IOException e) { 3943 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3944 return null; 3945 } 3946 3947 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3948 return tracesFile; 3949 } 3950 3951 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3952 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3953 // Use a FileObserver to detect when traces finish writing. 3954 // The order of traces is considered important to maintain for legibility. 3955 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3956 @Override 3957 public synchronized void onEvent(int event, String path) { notify(); } 3958 }; 3959 3960 try { 3961 observer.startWatching(); 3962 3963 // First collect all of the stacks of the most important pids. 3964 if (firstPids != null) { 3965 try { 3966 int num = firstPids.size(); 3967 for (int i = 0; i < num; i++) { 3968 synchronized (observer) { 3969 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3970 observer.wait(200); // Wait for write-close, give up after 200msec 3971 } 3972 } 3973 } catch (InterruptedException e) { 3974 Log.wtf(TAG, e); 3975 } 3976 } 3977 3978 // Next collect the stacks of the native pids 3979 if (nativeProcs != null) { 3980 int[] pids = Process.getPidsForCommands(nativeProcs); 3981 if (pids != null) { 3982 for (int pid : pids) { 3983 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3984 } 3985 } 3986 } 3987 3988 // Lastly, measure CPU usage. 3989 if (processCpuTracker != null) { 3990 processCpuTracker.init(); 3991 System.gc(); 3992 processCpuTracker.update(); 3993 try { 3994 synchronized (processCpuTracker) { 3995 processCpuTracker.wait(500); // measure over 1/2 second. 3996 } 3997 } catch (InterruptedException e) { 3998 } 3999 processCpuTracker.update(); 4000 4001 // We'll take the stack crawls of just the top apps using CPU. 4002 final int N = processCpuTracker.countWorkingStats(); 4003 int numProcs = 0; 4004 for (int i=0; i<N && numProcs<5; i++) { 4005 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4006 if (lastPids.indexOfKey(stats.pid) >= 0) { 4007 numProcs++; 4008 try { 4009 synchronized (observer) { 4010 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4011 observer.wait(200); // Wait for write-close, give up after 200msec 4012 } 4013 } catch (InterruptedException e) { 4014 Log.wtf(TAG, e); 4015 } 4016 4017 } 4018 } 4019 } 4020 } finally { 4021 observer.stopWatching(); 4022 } 4023 } 4024 4025 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4026 if (true || IS_USER_BUILD) { 4027 return; 4028 } 4029 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4030 if (tracesPath == null || tracesPath.length() == 0) { 4031 return; 4032 } 4033 4034 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4035 StrictMode.allowThreadDiskWrites(); 4036 try { 4037 final File tracesFile = new File(tracesPath); 4038 final File tracesDir = tracesFile.getParentFile(); 4039 final File tracesTmp = new File(tracesDir, "__tmp__"); 4040 try { 4041 if (!tracesDir.exists()) { 4042 tracesFile.mkdirs(); 4043 if (!SELinux.restorecon(tracesDir.getPath())) { 4044 return; 4045 } 4046 } 4047 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4048 4049 if (tracesFile.exists()) { 4050 tracesTmp.delete(); 4051 tracesFile.renameTo(tracesTmp); 4052 } 4053 StringBuilder sb = new StringBuilder(); 4054 Time tobj = new Time(); 4055 tobj.set(System.currentTimeMillis()); 4056 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4057 sb.append(": "); 4058 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4059 sb.append(" since "); 4060 sb.append(msg); 4061 FileOutputStream fos = new FileOutputStream(tracesFile); 4062 fos.write(sb.toString().getBytes()); 4063 if (app == null) { 4064 fos.write("\n*** No application process!".getBytes()); 4065 } 4066 fos.close(); 4067 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4068 } catch (IOException e) { 4069 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4070 return; 4071 } 4072 4073 if (app != null) { 4074 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4075 firstPids.add(app.pid); 4076 dumpStackTraces(tracesPath, firstPids, null, null, null); 4077 } 4078 4079 File lastTracesFile = null; 4080 File curTracesFile = null; 4081 for (int i=9; i>=0; i--) { 4082 String name = String.format(Locale.US, "slow%02d.txt", i); 4083 curTracesFile = new File(tracesDir, name); 4084 if (curTracesFile.exists()) { 4085 if (lastTracesFile != null) { 4086 curTracesFile.renameTo(lastTracesFile); 4087 } else { 4088 curTracesFile.delete(); 4089 } 4090 } 4091 lastTracesFile = curTracesFile; 4092 } 4093 tracesFile.renameTo(curTracesFile); 4094 if (tracesTmp.exists()) { 4095 tracesTmp.renameTo(tracesFile); 4096 } 4097 } finally { 4098 StrictMode.setThreadPolicy(oldPolicy); 4099 } 4100 } 4101 4102 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4103 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4104 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4105 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4106 4107 if (mController != null) { 4108 try { 4109 // 0 == continue, -1 = kill process immediately 4110 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4111 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4112 } catch (RemoteException e) { 4113 mController = null; 4114 Watchdog.getInstance().setActivityController(null); 4115 } 4116 } 4117 4118 long anrTime = SystemClock.uptimeMillis(); 4119 if (MONITOR_CPU_USAGE) { 4120 updateCpuStatsNow(); 4121 } 4122 4123 synchronized (this) { 4124 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4125 if (mShuttingDown) { 4126 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4127 return; 4128 } else if (app.notResponding) { 4129 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4130 return; 4131 } else if (app.crashing) { 4132 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4133 return; 4134 } 4135 4136 // In case we come through here for the same app before completing 4137 // this one, mark as anring now so we will bail out. 4138 app.notResponding = true; 4139 4140 // Log the ANR to the event log. 4141 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4142 app.processName, app.info.flags, annotation); 4143 4144 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4145 firstPids.add(app.pid); 4146 4147 int parentPid = app.pid; 4148 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4149 if (parentPid != app.pid) firstPids.add(parentPid); 4150 4151 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4152 4153 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4154 ProcessRecord r = mLruProcesses.get(i); 4155 if (r != null && r.thread != null) { 4156 int pid = r.pid; 4157 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4158 if (r.persistent) { 4159 firstPids.add(pid); 4160 } else { 4161 lastPids.put(pid, Boolean.TRUE); 4162 } 4163 } 4164 } 4165 } 4166 } 4167 4168 // Log the ANR to the main log. 4169 StringBuilder info = new StringBuilder(); 4170 info.setLength(0); 4171 info.append("ANR in ").append(app.processName); 4172 if (activity != null && activity.shortComponentName != null) { 4173 info.append(" (").append(activity.shortComponentName).append(")"); 4174 } 4175 info.append("\n"); 4176 info.append("PID: ").append(app.pid).append("\n"); 4177 if (annotation != null) { 4178 info.append("Reason: ").append(annotation).append("\n"); 4179 } 4180 if (parent != null && parent != activity) { 4181 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4182 } 4183 4184 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4185 4186 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4187 NATIVE_STACKS_OF_INTEREST); 4188 4189 String cpuInfo = null; 4190 if (MONITOR_CPU_USAGE) { 4191 updateCpuStatsNow(); 4192 synchronized (mProcessCpuThread) { 4193 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4194 } 4195 info.append(processCpuTracker.printCurrentLoad()); 4196 info.append(cpuInfo); 4197 } 4198 4199 info.append(processCpuTracker.printCurrentState(anrTime)); 4200 4201 Slog.e(TAG, info.toString()); 4202 if (tracesFile == null) { 4203 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4204 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4205 } 4206 4207 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4208 cpuInfo, tracesFile, null); 4209 4210 if (mController != null) { 4211 try { 4212 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4213 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4214 if (res != 0) { 4215 if (res < 0 && app.pid != MY_PID) { 4216 Process.killProcess(app.pid); 4217 } else { 4218 synchronized (this) { 4219 mServices.scheduleServiceTimeoutLocked(app); 4220 } 4221 } 4222 return; 4223 } 4224 } catch (RemoteException e) { 4225 mController = null; 4226 Watchdog.getInstance().setActivityController(null); 4227 } 4228 } 4229 4230 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4231 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4232 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4233 4234 synchronized (this) { 4235 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4236 killUnneededProcessLocked(app, "background ANR"); 4237 return; 4238 } 4239 4240 // Set the app's notResponding state, and look up the errorReportReceiver 4241 makeAppNotRespondingLocked(app, 4242 activity != null ? activity.shortComponentName : null, 4243 annotation != null ? "ANR " + annotation : "ANR", 4244 info.toString()); 4245 4246 // Bring up the infamous App Not Responding dialog 4247 Message msg = Message.obtain(); 4248 HashMap<String, Object> map = new HashMap<String, Object>(); 4249 msg.what = SHOW_NOT_RESPONDING_MSG; 4250 msg.obj = map; 4251 msg.arg1 = aboveSystem ? 1 : 0; 4252 map.put("app", app); 4253 if (activity != null) { 4254 map.put("activity", activity); 4255 } 4256 4257 mHandler.sendMessage(msg); 4258 } 4259 } 4260 4261 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4262 if (!mLaunchWarningShown) { 4263 mLaunchWarningShown = true; 4264 mHandler.post(new Runnable() { 4265 @Override 4266 public void run() { 4267 synchronized (ActivityManagerService.this) { 4268 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4269 d.show(); 4270 mHandler.postDelayed(new Runnable() { 4271 @Override 4272 public void run() { 4273 synchronized (ActivityManagerService.this) { 4274 d.dismiss(); 4275 mLaunchWarningShown = false; 4276 } 4277 } 4278 }, 4000); 4279 } 4280 } 4281 }); 4282 } 4283 } 4284 4285 @Override 4286 public boolean clearApplicationUserData(final String packageName, 4287 final IPackageDataObserver observer, int userId) { 4288 enforceNotIsolatedCaller("clearApplicationUserData"); 4289 int uid = Binder.getCallingUid(); 4290 int pid = Binder.getCallingPid(); 4291 userId = handleIncomingUser(pid, uid, 4292 userId, false, true, "clearApplicationUserData", null); 4293 long callingId = Binder.clearCallingIdentity(); 4294 try { 4295 IPackageManager pm = AppGlobals.getPackageManager(); 4296 int pkgUid = -1; 4297 synchronized(this) { 4298 try { 4299 pkgUid = pm.getPackageUid(packageName, userId); 4300 } catch (RemoteException e) { 4301 } 4302 if (pkgUid == -1) { 4303 Slog.w(TAG, "Invalid packageName: " + packageName); 4304 if (observer != null) { 4305 try { 4306 observer.onRemoveCompleted(packageName, false); 4307 } catch (RemoteException e) { 4308 Slog.i(TAG, "Observer no longer exists."); 4309 } 4310 } 4311 return false; 4312 } 4313 if (uid == pkgUid || checkComponentPermission( 4314 android.Manifest.permission.CLEAR_APP_USER_DATA, 4315 pid, uid, -1, true) 4316 == PackageManager.PERMISSION_GRANTED) { 4317 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4318 } else { 4319 throw new SecurityException("PID " + pid + " does not have permission " 4320 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4321 + " of package " + packageName); 4322 } 4323 } 4324 4325 try { 4326 // Clear application user data 4327 pm.clearApplicationUserData(packageName, observer, userId); 4328 4329 // Remove all permissions granted from/to this package 4330 removeUriPermissionsForPackageLocked(packageName, userId, true); 4331 4332 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4333 Uri.fromParts("package", packageName, null)); 4334 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4335 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4336 null, null, 0, null, null, null, false, false, userId); 4337 } catch (RemoteException e) { 4338 } 4339 } finally { 4340 Binder.restoreCallingIdentity(callingId); 4341 } 4342 return true; 4343 } 4344 4345 @Override 4346 public void killBackgroundProcesses(final String packageName, int userId) { 4347 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4348 != PackageManager.PERMISSION_GRANTED && 4349 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4350 != PackageManager.PERMISSION_GRANTED) { 4351 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4352 + Binder.getCallingPid() 4353 + ", uid=" + Binder.getCallingUid() 4354 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4355 Slog.w(TAG, msg); 4356 throw new SecurityException(msg); 4357 } 4358 4359 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4360 userId, true, true, "killBackgroundProcesses", null); 4361 long callingId = Binder.clearCallingIdentity(); 4362 try { 4363 IPackageManager pm = AppGlobals.getPackageManager(); 4364 synchronized(this) { 4365 int appId = -1; 4366 try { 4367 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4368 } catch (RemoteException e) { 4369 } 4370 if (appId == -1) { 4371 Slog.w(TAG, "Invalid packageName: " + packageName); 4372 return; 4373 } 4374 killPackageProcessesLocked(packageName, appId, userId, 4375 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4376 } 4377 } finally { 4378 Binder.restoreCallingIdentity(callingId); 4379 } 4380 } 4381 4382 @Override 4383 public void killAllBackgroundProcesses() { 4384 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4385 != PackageManager.PERMISSION_GRANTED) { 4386 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4387 + Binder.getCallingPid() 4388 + ", uid=" + Binder.getCallingUid() 4389 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4390 Slog.w(TAG, msg); 4391 throw new SecurityException(msg); 4392 } 4393 4394 long callingId = Binder.clearCallingIdentity(); 4395 try { 4396 synchronized(this) { 4397 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4398 final int NP = mProcessNames.getMap().size(); 4399 for (int ip=0; ip<NP; ip++) { 4400 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4401 final int NA = apps.size(); 4402 for (int ia=0; ia<NA; ia++) { 4403 ProcessRecord app = apps.valueAt(ia); 4404 if (app.persistent) { 4405 // we don't kill persistent processes 4406 continue; 4407 } 4408 if (app.removed) { 4409 procs.add(app); 4410 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4411 app.removed = true; 4412 procs.add(app); 4413 } 4414 } 4415 } 4416 4417 int N = procs.size(); 4418 for (int i=0; i<N; i++) { 4419 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4420 } 4421 mAllowLowerMemLevel = true; 4422 updateOomAdjLocked(); 4423 doLowMemReportIfNeededLocked(null); 4424 } 4425 } finally { 4426 Binder.restoreCallingIdentity(callingId); 4427 } 4428 } 4429 4430 @Override 4431 public void forceStopPackage(final String packageName, int userId) { 4432 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4433 != PackageManager.PERMISSION_GRANTED) { 4434 String msg = "Permission Denial: forceStopPackage() from pid=" 4435 + Binder.getCallingPid() 4436 + ", uid=" + Binder.getCallingUid() 4437 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4438 Slog.w(TAG, msg); 4439 throw new SecurityException(msg); 4440 } 4441 final int callingPid = Binder.getCallingPid(); 4442 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4443 userId, true, true, "forceStopPackage", null); 4444 long callingId = Binder.clearCallingIdentity(); 4445 try { 4446 IPackageManager pm = AppGlobals.getPackageManager(); 4447 synchronized(this) { 4448 int[] users = userId == UserHandle.USER_ALL 4449 ? getUsersLocked() : new int[] { userId }; 4450 for (int user : users) { 4451 int pkgUid = -1; 4452 try { 4453 pkgUid = pm.getPackageUid(packageName, user); 4454 } catch (RemoteException e) { 4455 } 4456 if (pkgUid == -1) { 4457 Slog.w(TAG, "Invalid packageName: " + packageName); 4458 continue; 4459 } 4460 try { 4461 pm.setPackageStoppedState(packageName, true, user); 4462 } catch (RemoteException e) { 4463 } catch (IllegalArgumentException e) { 4464 Slog.w(TAG, "Failed trying to unstop package " 4465 + packageName + ": " + e); 4466 } 4467 if (isUserRunningLocked(user, false)) { 4468 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4469 } 4470 } 4471 } 4472 } finally { 4473 Binder.restoreCallingIdentity(callingId); 4474 } 4475 } 4476 4477 /* 4478 * The pkg name and app id have to be specified. 4479 */ 4480 @Override 4481 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4482 if (pkg == null) { 4483 return; 4484 } 4485 // Make sure the uid is valid. 4486 if (appid < 0) { 4487 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4488 return; 4489 } 4490 int callerUid = Binder.getCallingUid(); 4491 // Only the system server can kill an application 4492 if (callerUid == Process.SYSTEM_UID) { 4493 // Post an aysnc message to kill the application 4494 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4495 msg.arg1 = appid; 4496 msg.arg2 = 0; 4497 Bundle bundle = new Bundle(); 4498 bundle.putString("pkg", pkg); 4499 bundle.putString("reason", reason); 4500 msg.obj = bundle; 4501 mHandler.sendMessage(msg); 4502 } else { 4503 throw new SecurityException(callerUid + " cannot kill pkg: " + 4504 pkg); 4505 } 4506 } 4507 4508 @Override 4509 public void closeSystemDialogs(String reason) { 4510 enforceNotIsolatedCaller("closeSystemDialogs"); 4511 4512 final int pid = Binder.getCallingPid(); 4513 final int uid = Binder.getCallingUid(); 4514 final long origId = Binder.clearCallingIdentity(); 4515 try { 4516 synchronized (this) { 4517 // Only allow this from foreground processes, so that background 4518 // applications can't abuse it to prevent system UI from being shown. 4519 if (uid >= Process.FIRST_APPLICATION_UID) { 4520 ProcessRecord proc; 4521 synchronized (mPidsSelfLocked) { 4522 proc = mPidsSelfLocked.get(pid); 4523 } 4524 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4525 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4526 + " from background process " + proc); 4527 return; 4528 } 4529 } 4530 closeSystemDialogsLocked(reason); 4531 } 4532 } finally { 4533 Binder.restoreCallingIdentity(origId); 4534 } 4535 } 4536 4537 void closeSystemDialogsLocked(String reason) { 4538 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4539 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4540 | Intent.FLAG_RECEIVER_FOREGROUND); 4541 if (reason != null) { 4542 intent.putExtra("reason", reason); 4543 } 4544 mWindowManager.closeSystemDialogs(reason); 4545 4546 mStackSupervisor.closeSystemDialogsLocked(); 4547 4548 broadcastIntentLocked(null, null, intent, null, 4549 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4550 Process.SYSTEM_UID, UserHandle.USER_ALL); 4551 } 4552 4553 @Override 4554 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4555 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4556 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4557 for (int i=pids.length-1; i>=0; i--) { 4558 ProcessRecord proc; 4559 int oomAdj; 4560 synchronized (this) { 4561 synchronized (mPidsSelfLocked) { 4562 proc = mPidsSelfLocked.get(pids[i]); 4563 oomAdj = proc != null ? proc.setAdj : 0; 4564 } 4565 } 4566 infos[i] = new Debug.MemoryInfo(); 4567 Debug.getMemoryInfo(pids[i], infos[i]); 4568 if (proc != null) { 4569 synchronized (this) { 4570 if (proc.thread != null && proc.setAdj == oomAdj) { 4571 // Record this for posterity if the process has been stable. 4572 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4573 infos[i].getTotalUss(), false, proc.pkgList); 4574 } 4575 } 4576 } 4577 } 4578 return infos; 4579 } 4580 4581 @Override 4582 public long[] getProcessPss(int[] pids) { 4583 enforceNotIsolatedCaller("getProcessPss"); 4584 long[] pss = new long[pids.length]; 4585 for (int i=pids.length-1; i>=0; i--) { 4586 ProcessRecord proc; 4587 int oomAdj; 4588 synchronized (this) { 4589 synchronized (mPidsSelfLocked) { 4590 proc = mPidsSelfLocked.get(pids[i]); 4591 oomAdj = proc != null ? proc.setAdj : 0; 4592 } 4593 } 4594 long[] tmpUss = new long[1]; 4595 pss[i] = Debug.getPss(pids[i], tmpUss); 4596 if (proc != null) { 4597 synchronized (this) { 4598 if (proc.thread != null && proc.setAdj == oomAdj) { 4599 // Record this for posterity if the process has been stable. 4600 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4601 } 4602 } 4603 } 4604 } 4605 return pss; 4606 } 4607 4608 @Override 4609 public void killApplicationProcess(String processName, int uid) { 4610 if (processName == null) { 4611 return; 4612 } 4613 4614 int callerUid = Binder.getCallingUid(); 4615 // Only the system server can kill an application 4616 if (callerUid == Process.SYSTEM_UID) { 4617 synchronized (this) { 4618 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4619 if (app != null && app.thread != null) { 4620 try { 4621 app.thread.scheduleSuicide(); 4622 } catch (RemoteException e) { 4623 // If the other end already died, then our work here is done. 4624 } 4625 } else { 4626 Slog.w(TAG, "Process/uid not found attempting kill of " 4627 + processName + " / " + uid); 4628 } 4629 } 4630 } else { 4631 throw new SecurityException(callerUid + " cannot kill app process: " + 4632 processName); 4633 } 4634 } 4635 4636 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4637 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4638 false, true, false, false, UserHandle.getUserId(uid), reason); 4639 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4640 Uri.fromParts("package", packageName, null)); 4641 if (!mProcessesReady) { 4642 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4643 | Intent.FLAG_RECEIVER_FOREGROUND); 4644 } 4645 intent.putExtra(Intent.EXTRA_UID, uid); 4646 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4647 broadcastIntentLocked(null, null, intent, 4648 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4649 false, false, 4650 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4651 } 4652 4653 private void forceStopUserLocked(int userId, String reason) { 4654 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4655 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4656 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4657 | Intent.FLAG_RECEIVER_FOREGROUND); 4658 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4659 broadcastIntentLocked(null, null, intent, 4660 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4661 false, false, 4662 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4663 } 4664 4665 private final boolean killPackageProcessesLocked(String packageName, int appId, 4666 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4667 boolean doit, boolean evenPersistent, String reason) { 4668 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4669 4670 // Remove all processes this package may have touched: all with the 4671 // same UID (except for the system or root user), and all whose name 4672 // matches the package name. 4673 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4674 final int NP = mProcessNames.getMap().size(); 4675 for (int ip=0; ip<NP; ip++) { 4676 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4677 final int NA = apps.size(); 4678 for (int ia=0; ia<NA; ia++) { 4679 ProcessRecord app = apps.valueAt(ia); 4680 if (app.persistent && !evenPersistent) { 4681 // we don't kill persistent processes 4682 continue; 4683 } 4684 if (app.removed) { 4685 if (doit) { 4686 procs.add(app); 4687 } 4688 continue; 4689 } 4690 4691 // Skip process if it doesn't meet our oom adj requirement. 4692 if (app.setAdj < minOomAdj) { 4693 continue; 4694 } 4695 4696 // If no package is specified, we call all processes under the 4697 // give user id. 4698 if (packageName == null) { 4699 if (app.userId != userId) { 4700 continue; 4701 } 4702 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4703 continue; 4704 } 4705 // Package has been specified, we want to hit all processes 4706 // that match it. We need to qualify this by the processes 4707 // that are running under the specified app and user ID. 4708 } else { 4709 if (UserHandle.getAppId(app.uid) != appId) { 4710 continue; 4711 } 4712 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4713 continue; 4714 } 4715 if (!app.pkgList.containsKey(packageName)) { 4716 continue; 4717 } 4718 } 4719 4720 // Process has passed all conditions, kill it! 4721 if (!doit) { 4722 return true; 4723 } 4724 app.removed = true; 4725 procs.add(app); 4726 } 4727 } 4728 4729 int N = procs.size(); 4730 for (int i=0; i<N; i++) { 4731 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4732 } 4733 updateOomAdjLocked(); 4734 return N > 0; 4735 } 4736 4737 private final boolean forceStopPackageLocked(String name, int appId, 4738 boolean callerWillRestart, boolean purgeCache, boolean doit, 4739 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4740 int i; 4741 int N; 4742 4743 if (userId == UserHandle.USER_ALL && name == null) { 4744 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4745 } 4746 4747 if (appId < 0 && name != null) { 4748 try { 4749 appId = UserHandle.getAppId( 4750 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4751 } catch (RemoteException e) { 4752 } 4753 } 4754 4755 if (doit) { 4756 if (name != null) { 4757 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4758 + " user=" + userId + ": " + reason); 4759 } else { 4760 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4761 } 4762 4763 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4764 for (int ip=pmap.size()-1; ip>=0; ip--) { 4765 SparseArray<Long> ba = pmap.valueAt(ip); 4766 for (i=ba.size()-1; i>=0; i--) { 4767 boolean remove = false; 4768 final int entUid = ba.keyAt(i); 4769 if (name != null) { 4770 if (userId == UserHandle.USER_ALL) { 4771 if (UserHandle.getAppId(entUid) == appId) { 4772 remove = true; 4773 } 4774 } else { 4775 if (entUid == UserHandle.getUid(userId, appId)) { 4776 remove = true; 4777 } 4778 } 4779 } else if (UserHandle.getUserId(entUid) == userId) { 4780 remove = true; 4781 } 4782 if (remove) { 4783 ba.removeAt(i); 4784 } 4785 } 4786 if (ba.size() == 0) { 4787 pmap.removeAt(ip); 4788 } 4789 } 4790 } 4791 4792 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4793 -100, callerWillRestart, true, doit, evenPersistent, 4794 name == null ? ("stop user " + userId) : ("stop " + name)); 4795 4796 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4797 if (!doit) { 4798 return true; 4799 } 4800 didSomething = true; 4801 } 4802 4803 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4804 if (!doit) { 4805 return true; 4806 } 4807 didSomething = true; 4808 } 4809 4810 if (name == null) { 4811 // Remove all sticky broadcasts from this user. 4812 mStickyBroadcasts.remove(userId); 4813 } 4814 4815 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4816 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4817 userId, providers)) { 4818 if (!doit) { 4819 return true; 4820 } 4821 didSomething = true; 4822 } 4823 N = providers.size(); 4824 for (i=0; i<N; i++) { 4825 removeDyingProviderLocked(null, providers.get(i), true); 4826 } 4827 4828 // Remove transient permissions granted from/to this package/user 4829 removeUriPermissionsForPackageLocked(name, userId, false); 4830 4831 if (name == null || uninstalling) { 4832 // Remove pending intents. For now we only do this when force 4833 // stopping users, because we have some problems when doing this 4834 // for packages -- app widgets are not currently cleaned up for 4835 // such packages, so they can be left with bad pending intents. 4836 if (mIntentSenderRecords.size() > 0) { 4837 Iterator<WeakReference<PendingIntentRecord>> it 4838 = mIntentSenderRecords.values().iterator(); 4839 while (it.hasNext()) { 4840 WeakReference<PendingIntentRecord> wpir = it.next(); 4841 if (wpir == null) { 4842 it.remove(); 4843 continue; 4844 } 4845 PendingIntentRecord pir = wpir.get(); 4846 if (pir == null) { 4847 it.remove(); 4848 continue; 4849 } 4850 if (name == null) { 4851 // Stopping user, remove all objects for the user. 4852 if (pir.key.userId != userId) { 4853 // Not the same user, skip it. 4854 continue; 4855 } 4856 } else { 4857 if (UserHandle.getAppId(pir.uid) != appId) { 4858 // Different app id, skip it. 4859 continue; 4860 } 4861 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4862 // Different user, skip it. 4863 continue; 4864 } 4865 if (!pir.key.packageName.equals(name)) { 4866 // Different package, skip it. 4867 continue; 4868 } 4869 } 4870 if (!doit) { 4871 return true; 4872 } 4873 didSomething = true; 4874 it.remove(); 4875 pir.canceled = true; 4876 if (pir.key.activity != null) { 4877 pir.key.activity.pendingResults.remove(pir.ref); 4878 } 4879 } 4880 } 4881 } 4882 4883 if (doit) { 4884 if (purgeCache && name != null) { 4885 AttributeCache ac = AttributeCache.instance(); 4886 if (ac != null) { 4887 ac.removePackage(name); 4888 } 4889 } 4890 if (mBooted) { 4891 mStackSupervisor.resumeTopActivitiesLocked(); 4892 mStackSupervisor.scheduleIdleLocked(); 4893 } 4894 } 4895 4896 return didSomething; 4897 } 4898 4899 private final boolean removeProcessLocked(ProcessRecord app, 4900 boolean callerWillRestart, boolean allowRestart, String reason) { 4901 final String name = app.processName; 4902 final int uid = app.uid; 4903 if (DEBUG_PROCESSES) Slog.d( 4904 TAG, "Force removing proc " + app.toShortString() + " (" + name 4905 + "/" + uid + ")"); 4906 4907 mProcessNames.remove(name, uid); 4908 mIsolatedProcesses.remove(app.uid); 4909 if (mHeavyWeightProcess == app) { 4910 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4911 mHeavyWeightProcess.userId, 0)); 4912 mHeavyWeightProcess = null; 4913 } 4914 boolean needRestart = false; 4915 if (app.pid > 0 && app.pid != MY_PID) { 4916 int pid = app.pid; 4917 synchronized (mPidsSelfLocked) { 4918 mPidsSelfLocked.remove(pid); 4919 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4920 } 4921 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4922 app.processName, app.info.uid); 4923 if (app.isolated) { 4924 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4925 } 4926 killUnneededProcessLocked(app, reason); 4927 handleAppDiedLocked(app, true, allowRestart); 4928 removeLruProcessLocked(app); 4929 4930 if (app.persistent && !app.isolated) { 4931 if (!callerWillRestart) { 4932 addAppLocked(app.info, false); 4933 } else { 4934 needRestart = true; 4935 } 4936 } 4937 } else { 4938 mRemovedProcesses.add(app); 4939 } 4940 4941 return needRestart; 4942 } 4943 4944 private final void processStartTimedOutLocked(ProcessRecord app) { 4945 final int pid = app.pid; 4946 boolean gone = false; 4947 synchronized (mPidsSelfLocked) { 4948 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4949 if (knownApp != null && knownApp.thread == null) { 4950 mPidsSelfLocked.remove(pid); 4951 gone = true; 4952 } 4953 } 4954 4955 if (gone) { 4956 Slog.w(TAG, "Process " + app + " failed to attach"); 4957 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4958 pid, app.uid, app.processName); 4959 mProcessNames.remove(app.processName, app.uid); 4960 mIsolatedProcesses.remove(app.uid); 4961 if (mHeavyWeightProcess == app) { 4962 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4963 mHeavyWeightProcess.userId, 0)); 4964 mHeavyWeightProcess = null; 4965 } 4966 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4967 app.processName, app.info.uid); 4968 if (app.isolated) { 4969 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4970 } 4971 // Take care of any launching providers waiting for this process. 4972 checkAppInLaunchingProvidersLocked(app, true); 4973 // Take care of any services that are waiting for the process. 4974 mServices.processStartTimedOutLocked(app); 4975 killUnneededProcessLocked(app, "start timeout"); 4976 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4977 Slog.w(TAG, "Unattached app died before backup, skipping"); 4978 try { 4979 IBackupManager bm = IBackupManager.Stub.asInterface( 4980 ServiceManager.getService(Context.BACKUP_SERVICE)); 4981 bm.agentDisconnected(app.info.packageName); 4982 } catch (RemoteException e) { 4983 // Can't happen; the backup manager is local 4984 } 4985 } 4986 if (isPendingBroadcastProcessLocked(pid)) { 4987 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4988 skipPendingBroadcastLocked(pid); 4989 } 4990 } else { 4991 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4992 } 4993 } 4994 4995 private final boolean attachApplicationLocked(IApplicationThread thread, 4996 int pid) { 4997 4998 // Find the application record that is being attached... either via 4999 // the pid if we are running in multiple processes, or just pull the 5000 // next app record if we are emulating process with anonymous threads. 5001 ProcessRecord app; 5002 if (pid != MY_PID && pid >= 0) { 5003 synchronized (mPidsSelfLocked) { 5004 app = mPidsSelfLocked.get(pid); 5005 } 5006 } else { 5007 app = null; 5008 } 5009 5010 if (app == null) { 5011 Slog.w(TAG, "No pending application record for pid " + pid 5012 + " (IApplicationThread " + thread + "); dropping process"); 5013 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5014 if (pid > 0 && pid != MY_PID) { 5015 Process.killProcessQuiet(pid); 5016 } else { 5017 try { 5018 thread.scheduleExit(); 5019 } catch (Exception e) { 5020 // Ignore exceptions. 5021 } 5022 } 5023 return false; 5024 } 5025 5026 // If this application record is still attached to a previous 5027 // process, clean it up now. 5028 if (app.thread != null) { 5029 handleAppDiedLocked(app, true, true); 5030 } 5031 5032 // Tell the process all about itself. 5033 5034 if (localLOGV) Slog.v( 5035 TAG, "Binding process pid " + pid + " to record " + app); 5036 5037 final String processName = app.processName; 5038 try { 5039 AppDeathRecipient adr = new AppDeathRecipient( 5040 app, pid, thread); 5041 thread.asBinder().linkToDeath(adr, 0); 5042 app.deathRecipient = adr; 5043 } catch (RemoteException e) { 5044 app.resetPackageList(mProcessStats); 5045 startProcessLocked(app, "link fail", processName); 5046 return false; 5047 } 5048 5049 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5050 5051 app.makeActive(thread, mProcessStats); 5052 app.curAdj = app.setAdj = -100; 5053 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5054 app.forcingToForeground = null; 5055 updateProcessForegroundLocked(app, false, false); 5056 app.hasShownUi = false; 5057 app.debugging = false; 5058 app.cached = false; 5059 5060 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5061 5062 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5063 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5064 5065 if (!normalMode) { 5066 Slog.i(TAG, "Launching preboot mode app: " + app); 5067 } 5068 5069 if (localLOGV) Slog.v( 5070 TAG, "New app record " + app 5071 + " thread=" + thread.asBinder() + " pid=" + pid); 5072 try { 5073 int testMode = IApplicationThread.DEBUG_OFF; 5074 if (mDebugApp != null && mDebugApp.equals(processName)) { 5075 testMode = mWaitForDebugger 5076 ? IApplicationThread.DEBUG_WAIT 5077 : IApplicationThread.DEBUG_ON; 5078 app.debugging = true; 5079 if (mDebugTransient) { 5080 mDebugApp = mOrigDebugApp; 5081 mWaitForDebugger = mOrigWaitForDebugger; 5082 } 5083 } 5084 String profileFile = app.instrumentationProfileFile; 5085 ParcelFileDescriptor profileFd = null; 5086 boolean profileAutoStop = false; 5087 if (mProfileApp != null && mProfileApp.equals(processName)) { 5088 mProfileProc = app; 5089 profileFile = mProfileFile; 5090 profileFd = mProfileFd; 5091 profileAutoStop = mAutoStopProfiler; 5092 } 5093 boolean enableOpenGlTrace = false; 5094 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5095 enableOpenGlTrace = true; 5096 mOpenGlTraceApp = null; 5097 } 5098 5099 // If the app is being launched for restore or full backup, set it up specially 5100 boolean isRestrictedBackupMode = false; 5101 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5102 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5103 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5104 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5105 } 5106 5107 ensurePackageDexOpt(app.instrumentationInfo != null 5108 ? app.instrumentationInfo.packageName 5109 : app.info.packageName); 5110 if (app.instrumentationClass != null) { 5111 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5112 } 5113 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5114 + processName + " with config " + mConfiguration); 5115 ApplicationInfo appInfo = app.instrumentationInfo != null 5116 ? app.instrumentationInfo : app.info; 5117 app.compat = compatibilityInfoForPackageLocked(appInfo); 5118 if (profileFd != null) { 5119 profileFd = profileFd.dup(); 5120 } 5121 thread.bindApplication(processName, appInfo, providers, 5122 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5123 app.instrumentationArguments, app.instrumentationWatcher, 5124 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5125 isRestrictedBackupMode || !normalMode, app.persistent, 5126 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5127 mCoreSettingsObserver.getCoreSettingsLocked()); 5128 updateLruProcessLocked(app, false, null); 5129 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5130 } catch (Exception e) { 5131 // todo: Yikes! What should we do? For now we will try to 5132 // start another process, but that could easily get us in 5133 // an infinite loop of restarting processes... 5134 Slog.w(TAG, "Exception thrown during bind!", e); 5135 5136 app.resetPackageList(mProcessStats); 5137 app.unlinkDeathRecipient(); 5138 startProcessLocked(app, "bind fail", processName); 5139 return false; 5140 } 5141 5142 // Remove this record from the list of starting applications. 5143 mPersistentStartingProcesses.remove(app); 5144 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5145 "Attach application locked removing on hold: " + app); 5146 mProcessesOnHold.remove(app); 5147 5148 boolean badApp = false; 5149 boolean didSomething = false; 5150 5151 // See if the top visible activity is waiting to run in this process... 5152 if (normalMode) { 5153 try { 5154 if (mStackSupervisor.attachApplicationLocked(app)) { 5155 didSomething = true; 5156 } 5157 } catch (Exception e) { 5158 badApp = true; 5159 } 5160 } 5161 5162 // Find any services that should be running in this process... 5163 if (!badApp) { 5164 try { 5165 didSomething |= mServices.attachApplicationLocked(app, processName); 5166 } catch (Exception e) { 5167 badApp = true; 5168 } 5169 } 5170 5171 // Check if a next-broadcast receiver is in this process... 5172 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5173 try { 5174 didSomething |= sendPendingBroadcastsLocked(app); 5175 } catch (Exception e) { 5176 // If the app died trying to launch the receiver we declare it 'bad' 5177 badApp = true; 5178 } 5179 } 5180 5181 // Check whether the next backup agent is in this process... 5182 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5183 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5184 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5185 try { 5186 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5187 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5188 mBackupTarget.backupMode); 5189 } catch (Exception e) { 5190 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5191 e.printStackTrace(); 5192 } 5193 } 5194 5195 if (badApp) { 5196 // todo: Also need to kill application to deal with all 5197 // kinds of exceptions. 5198 handleAppDiedLocked(app, false, true); 5199 return false; 5200 } 5201 5202 if (!didSomething) { 5203 updateOomAdjLocked(); 5204 } 5205 5206 return true; 5207 } 5208 5209 @Override 5210 public final void attachApplication(IApplicationThread thread) { 5211 synchronized (this) { 5212 int callingPid = Binder.getCallingPid(); 5213 final long origId = Binder.clearCallingIdentity(); 5214 attachApplicationLocked(thread, callingPid); 5215 Binder.restoreCallingIdentity(origId); 5216 } 5217 } 5218 5219 @Override 5220 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5221 final long origId = Binder.clearCallingIdentity(); 5222 synchronized (this) { 5223 ActivityStack stack = ActivityRecord.getStackLocked(token); 5224 if (stack != null) { 5225 ActivityRecord r = 5226 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5227 if (stopProfiling) { 5228 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5229 try { 5230 mProfileFd.close(); 5231 } catch (IOException e) { 5232 } 5233 clearProfilerLocked(); 5234 } 5235 } 5236 } 5237 } 5238 Binder.restoreCallingIdentity(origId); 5239 } 5240 5241 void enableScreenAfterBoot() { 5242 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5243 SystemClock.uptimeMillis()); 5244 mWindowManager.enableScreenAfterBoot(); 5245 5246 synchronized (this) { 5247 updateEventDispatchingLocked(); 5248 } 5249 } 5250 5251 @Override 5252 public void showBootMessage(final CharSequence msg, final boolean always) { 5253 enforceNotIsolatedCaller("showBootMessage"); 5254 mWindowManager.showBootMessage(msg, always); 5255 } 5256 5257 @Override 5258 public void dismissKeyguardOnNextActivity() { 5259 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5260 final long token = Binder.clearCallingIdentity(); 5261 try { 5262 synchronized (this) { 5263 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5264 if (mLockScreenShown) { 5265 mLockScreenShown = false; 5266 comeOutOfSleepIfNeededLocked(); 5267 } 5268 mStackSupervisor.setDismissKeyguard(true); 5269 } 5270 } finally { 5271 Binder.restoreCallingIdentity(token); 5272 } 5273 } 5274 5275 final void finishBooting() { 5276 // Register receivers to handle package update events 5277 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5278 5279 synchronized (this) { 5280 // Ensure that any processes we had put on hold are now started 5281 // up. 5282 final int NP = mProcessesOnHold.size(); 5283 if (NP > 0) { 5284 ArrayList<ProcessRecord> procs = 5285 new ArrayList<ProcessRecord>(mProcessesOnHold); 5286 for (int ip=0; ip<NP; ip++) { 5287 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5288 + procs.get(ip)); 5289 startProcessLocked(procs.get(ip), "on-hold", null); 5290 } 5291 } 5292 5293 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5294 // Start looking for apps that are abusing wake locks. 5295 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5296 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5297 // Tell anyone interested that we are done booting! 5298 SystemProperties.set("sys.boot_completed", "1"); 5299 SystemProperties.set("dev.bootcomplete", "1"); 5300 for (int i=0; i<mStartedUsers.size(); i++) { 5301 UserStartedState uss = mStartedUsers.valueAt(i); 5302 if (uss.mState == UserStartedState.STATE_BOOTING) { 5303 uss.mState = UserStartedState.STATE_RUNNING; 5304 final int userId = mStartedUsers.keyAt(i); 5305 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5306 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5307 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5308 broadcastIntentLocked(null, null, intent, null, 5309 new IIntentReceiver.Stub() { 5310 @Override 5311 public void performReceive(Intent intent, int resultCode, 5312 String data, Bundle extras, boolean ordered, 5313 boolean sticky, int sendingUser) { 5314 synchronized (ActivityManagerService.this) { 5315 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5316 true, false); 5317 } 5318 } 5319 }, 5320 0, null, null, 5321 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5322 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5323 userId); 5324 } 5325 } 5326 scheduleStartProfilesLocked(); 5327 } 5328 } 5329 } 5330 5331 final void ensureBootCompleted() { 5332 boolean booting; 5333 boolean enableScreen; 5334 synchronized (this) { 5335 booting = mBooting; 5336 mBooting = false; 5337 enableScreen = !mBooted; 5338 mBooted = true; 5339 } 5340 5341 if (booting) { 5342 finishBooting(); 5343 } 5344 5345 if (enableScreen) { 5346 enableScreenAfterBoot(); 5347 } 5348 } 5349 5350 @Override 5351 public final void activityResumed(IBinder token) { 5352 final long origId = Binder.clearCallingIdentity(); 5353 synchronized(this) { 5354 ActivityStack stack = ActivityRecord.getStackLocked(token); 5355 if (stack != null) { 5356 ActivityRecord.activityResumedLocked(token); 5357 } 5358 } 5359 Binder.restoreCallingIdentity(origId); 5360 } 5361 5362 @Override 5363 public final void activityPaused(IBinder token) { 5364 final long origId = Binder.clearCallingIdentity(); 5365 synchronized(this) { 5366 ActivityStack stack = ActivityRecord.getStackLocked(token); 5367 if (stack != null) { 5368 stack.activityPausedLocked(token, false); 5369 } 5370 } 5371 Binder.restoreCallingIdentity(origId); 5372 } 5373 5374 @Override 5375 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5376 CharSequence description) { 5377 if (localLOGV) Slog.v( 5378 TAG, "Activity stopped: token=" + token); 5379 5380 // Refuse possible leaked file descriptors 5381 if (icicle != null && icicle.hasFileDescriptors()) { 5382 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5383 } 5384 5385 ActivityRecord r = null; 5386 5387 final long origId = Binder.clearCallingIdentity(); 5388 5389 synchronized (this) { 5390 r = ActivityRecord.isInStackLocked(token); 5391 if (r != null) { 5392 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5393 } 5394 } 5395 5396 if (r != null) { 5397 sendPendingThumbnail(r, null, null, null, false); 5398 } 5399 5400 trimApplications(); 5401 5402 Binder.restoreCallingIdentity(origId); 5403 } 5404 5405 @Override 5406 public final void activityDestroyed(IBinder token) { 5407 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5408 synchronized (this) { 5409 ActivityStack stack = ActivityRecord.getStackLocked(token); 5410 if (stack != null) { 5411 stack.activityDestroyedLocked(token); 5412 } 5413 } 5414 } 5415 5416 @Override 5417 public String getCallingPackage(IBinder token) { 5418 synchronized (this) { 5419 ActivityRecord r = getCallingRecordLocked(token); 5420 return r != null ? r.info.packageName : null; 5421 } 5422 } 5423 5424 @Override 5425 public ComponentName getCallingActivity(IBinder token) { 5426 synchronized (this) { 5427 ActivityRecord r = getCallingRecordLocked(token); 5428 return r != null ? r.intent.getComponent() : null; 5429 } 5430 } 5431 5432 private ActivityRecord getCallingRecordLocked(IBinder token) { 5433 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5434 if (r == null) { 5435 return null; 5436 } 5437 return r.resultTo; 5438 } 5439 5440 @Override 5441 public ComponentName getActivityClassForToken(IBinder token) { 5442 synchronized(this) { 5443 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5444 if (r == null) { 5445 return null; 5446 } 5447 return r.intent.getComponent(); 5448 } 5449 } 5450 5451 @Override 5452 public String getPackageForToken(IBinder token) { 5453 synchronized(this) { 5454 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5455 if (r == null) { 5456 return null; 5457 } 5458 return r.packageName; 5459 } 5460 } 5461 5462 @Override 5463 public IIntentSender getIntentSender(int type, 5464 String packageName, IBinder token, String resultWho, 5465 int requestCode, Intent[] intents, String[] resolvedTypes, 5466 int flags, Bundle options, int userId) { 5467 enforceNotIsolatedCaller("getIntentSender"); 5468 // Refuse possible leaked file descriptors 5469 if (intents != null) { 5470 if (intents.length < 1) { 5471 throw new IllegalArgumentException("Intents array length must be >= 1"); 5472 } 5473 for (int i=0; i<intents.length; i++) { 5474 Intent intent = intents[i]; 5475 if (intent != null) { 5476 if (intent.hasFileDescriptors()) { 5477 throw new IllegalArgumentException("File descriptors passed in Intent"); 5478 } 5479 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5480 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5481 throw new IllegalArgumentException( 5482 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5483 } 5484 intents[i] = new Intent(intent); 5485 } 5486 } 5487 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5488 throw new IllegalArgumentException( 5489 "Intent array length does not match resolvedTypes length"); 5490 } 5491 } 5492 if (options != null) { 5493 if (options.hasFileDescriptors()) { 5494 throw new IllegalArgumentException("File descriptors passed in options"); 5495 } 5496 } 5497 5498 synchronized(this) { 5499 int callingUid = Binder.getCallingUid(); 5500 int origUserId = userId; 5501 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5502 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5503 "getIntentSender", null); 5504 if (origUserId == UserHandle.USER_CURRENT) { 5505 // We don't want to evaluate this until the pending intent is 5506 // actually executed. However, we do want to always do the 5507 // security checking for it above. 5508 userId = UserHandle.USER_CURRENT; 5509 } 5510 try { 5511 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5512 int uid = AppGlobals.getPackageManager() 5513 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5514 if (!UserHandle.isSameApp(callingUid, uid)) { 5515 String msg = "Permission Denial: getIntentSender() from pid=" 5516 + Binder.getCallingPid() 5517 + ", uid=" + Binder.getCallingUid() 5518 + ", (need uid=" + uid + ")" 5519 + " is not allowed to send as package " + packageName; 5520 Slog.w(TAG, msg); 5521 throw new SecurityException(msg); 5522 } 5523 } 5524 5525 return getIntentSenderLocked(type, packageName, callingUid, userId, 5526 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5527 5528 } catch (RemoteException e) { 5529 throw new SecurityException(e); 5530 } 5531 } 5532 } 5533 5534 IIntentSender getIntentSenderLocked(int type, String packageName, 5535 int callingUid, int userId, IBinder token, String resultWho, 5536 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5537 Bundle options) { 5538 if (DEBUG_MU) 5539 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5540 ActivityRecord activity = null; 5541 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5542 activity = ActivityRecord.isInStackLocked(token); 5543 if (activity == null) { 5544 return null; 5545 } 5546 if (activity.finishing) { 5547 return null; 5548 } 5549 } 5550 5551 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5552 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5553 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5554 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5555 |PendingIntent.FLAG_UPDATE_CURRENT); 5556 5557 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5558 type, packageName, activity, resultWho, 5559 requestCode, intents, resolvedTypes, flags, options, userId); 5560 WeakReference<PendingIntentRecord> ref; 5561 ref = mIntentSenderRecords.get(key); 5562 PendingIntentRecord rec = ref != null ? ref.get() : null; 5563 if (rec != null) { 5564 if (!cancelCurrent) { 5565 if (updateCurrent) { 5566 if (rec.key.requestIntent != null) { 5567 rec.key.requestIntent.replaceExtras(intents != null ? 5568 intents[intents.length - 1] : null); 5569 } 5570 if (intents != null) { 5571 intents[intents.length-1] = rec.key.requestIntent; 5572 rec.key.allIntents = intents; 5573 rec.key.allResolvedTypes = resolvedTypes; 5574 } else { 5575 rec.key.allIntents = null; 5576 rec.key.allResolvedTypes = null; 5577 } 5578 } 5579 return rec; 5580 } 5581 rec.canceled = true; 5582 mIntentSenderRecords.remove(key); 5583 } 5584 if (noCreate) { 5585 return rec; 5586 } 5587 rec = new PendingIntentRecord(this, key, callingUid); 5588 mIntentSenderRecords.put(key, rec.ref); 5589 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5590 if (activity.pendingResults == null) { 5591 activity.pendingResults 5592 = new HashSet<WeakReference<PendingIntentRecord>>(); 5593 } 5594 activity.pendingResults.add(rec.ref); 5595 } 5596 return rec; 5597 } 5598 5599 @Override 5600 public void cancelIntentSender(IIntentSender sender) { 5601 if (!(sender instanceof PendingIntentRecord)) { 5602 return; 5603 } 5604 synchronized(this) { 5605 PendingIntentRecord rec = (PendingIntentRecord)sender; 5606 try { 5607 int uid = AppGlobals.getPackageManager() 5608 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5609 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5610 String msg = "Permission Denial: cancelIntentSender() from pid=" 5611 + Binder.getCallingPid() 5612 + ", uid=" + Binder.getCallingUid() 5613 + " is not allowed to cancel packges " 5614 + rec.key.packageName; 5615 Slog.w(TAG, msg); 5616 throw new SecurityException(msg); 5617 } 5618 } catch (RemoteException e) { 5619 throw new SecurityException(e); 5620 } 5621 cancelIntentSenderLocked(rec, true); 5622 } 5623 } 5624 5625 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5626 rec.canceled = true; 5627 mIntentSenderRecords.remove(rec.key); 5628 if (cleanActivity && rec.key.activity != null) { 5629 rec.key.activity.pendingResults.remove(rec.ref); 5630 } 5631 } 5632 5633 @Override 5634 public String getPackageForIntentSender(IIntentSender pendingResult) { 5635 if (!(pendingResult instanceof PendingIntentRecord)) { 5636 return null; 5637 } 5638 try { 5639 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5640 return res.key.packageName; 5641 } catch (ClassCastException e) { 5642 } 5643 return null; 5644 } 5645 5646 @Override 5647 public int getUidForIntentSender(IIntentSender sender) { 5648 if (sender instanceof PendingIntentRecord) { 5649 try { 5650 PendingIntentRecord res = (PendingIntentRecord)sender; 5651 return res.uid; 5652 } catch (ClassCastException e) { 5653 } 5654 } 5655 return -1; 5656 } 5657 5658 @Override 5659 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5660 if (!(pendingResult instanceof PendingIntentRecord)) { 5661 return false; 5662 } 5663 try { 5664 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5665 if (res.key.allIntents == null) { 5666 return false; 5667 } 5668 for (int i=0; i<res.key.allIntents.length; i++) { 5669 Intent intent = res.key.allIntents[i]; 5670 if (intent.getPackage() != null && intent.getComponent() != null) { 5671 return false; 5672 } 5673 } 5674 return true; 5675 } catch (ClassCastException e) { 5676 } 5677 return false; 5678 } 5679 5680 @Override 5681 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5682 if (!(pendingResult instanceof PendingIntentRecord)) { 5683 return false; 5684 } 5685 try { 5686 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5687 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5688 return true; 5689 } 5690 return false; 5691 } catch (ClassCastException e) { 5692 } 5693 return false; 5694 } 5695 5696 @Override 5697 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5698 if (!(pendingResult instanceof PendingIntentRecord)) { 5699 return null; 5700 } 5701 try { 5702 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5703 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5704 } catch (ClassCastException e) { 5705 } 5706 return null; 5707 } 5708 5709 @Override 5710 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5711 if (!(pendingResult instanceof PendingIntentRecord)) { 5712 return null; 5713 } 5714 try { 5715 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5716 Intent intent = res.key.requestIntent; 5717 if (intent != null) { 5718 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5719 || res.lastTagPrefix.equals(prefix))) { 5720 return res.lastTag; 5721 } 5722 res.lastTagPrefix = prefix; 5723 StringBuilder sb = new StringBuilder(128); 5724 if (prefix != null) { 5725 sb.append(prefix); 5726 } 5727 if (intent.getAction() != null) { 5728 sb.append(intent.getAction()); 5729 } else if (intent.getComponent() != null) { 5730 intent.getComponent().appendShortString(sb); 5731 } else { 5732 sb.append("?"); 5733 } 5734 return res.lastTag = sb.toString(); 5735 } 5736 } catch (ClassCastException e) { 5737 } 5738 return null; 5739 } 5740 5741 @Override 5742 public void setProcessLimit(int max) { 5743 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5744 "setProcessLimit()"); 5745 synchronized (this) { 5746 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5747 mProcessLimitOverride = max; 5748 } 5749 trimApplications(); 5750 } 5751 5752 @Override 5753 public int getProcessLimit() { 5754 synchronized (this) { 5755 return mProcessLimitOverride; 5756 } 5757 } 5758 5759 void foregroundTokenDied(ForegroundToken token) { 5760 synchronized (ActivityManagerService.this) { 5761 synchronized (mPidsSelfLocked) { 5762 ForegroundToken cur 5763 = mForegroundProcesses.get(token.pid); 5764 if (cur != token) { 5765 return; 5766 } 5767 mForegroundProcesses.remove(token.pid); 5768 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5769 if (pr == null) { 5770 return; 5771 } 5772 pr.forcingToForeground = null; 5773 updateProcessForegroundLocked(pr, false, false); 5774 } 5775 updateOomAdjLocked(); 5776 } 5777 } 5778 5779 @Override 5780 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5781 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5782 "setProcessForeground()"); 5783 synchronized(this) { 5784 boolean changed = false; 5785 5786 synchronized (mPidsSelfLocked) { 5787 ProcessRecord pr = mPidsSelfLocked.get(pid); 5788 if (pr == null && isForeground) { 5789 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5790 return; 5791 } 5792 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5793 if (oldToken != null) { 5794 oldToken.token.unlinkToDeath(oldToken, 0); 5795 mForegroundProcesses.remove(pid); 5796 if (pr != null) { 5797 pr.forcingToForeground = null; 5798 } 5799 changed = true; 5800 } 5801 if (isForeground && token != null) { 5802 ForegroundToken newToken = new ForegroundToken() { 5803 @Override 5804 public void binderDied() { 5805 foregroundTokenDied(this); 5806 } 5807 }; 5808 newToken.pid = pid; 5809 newToken.token = token; 5810 try { 5811 token.linkToDeath(newToken, 0); 5812 mForegroundProcesses.put(pid, newToken); 5813 pr.forcingToForeground = token; 5814 changed = true; 5815 } catch (RemoteException e) { 5816 // If the process died while doing this, we will later 5817 // do the cleanup with the process death link. 5818 } 5819 } 5820 } 5821 5822 if (changed) { 5823 updateOomAdjLocked(); 5824 } 5825 } 5826 } 5827 5828 // ========================================================= 5829 // PERMISSIONS 5830 // ========================================================= 5831 5832 static class PermissionController extends IPermissionController.Stub { 5833 ActivityManagerService mActivityManagerService; 5834 PermissionController(ActivityManagerService activityManagerService) { 5835 mActivityManagerService = activityManagerService; 5836 } 5837 5838 @Override 5839 public boolean checkPermission(String permission, int pid, int uid) { 5840 return mActivityManagerService.checkPermission(permission, pid, 5841 uid) == PackageManager.PERMISSION_GRANTED; 5842 } 5843 } 5844 5845 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5846 @Override 5847 public int checkComponentPermission(String permission, int pid, int uid, 5848 int owningUid, boolean exported) { 5849 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5850 owningUid, exported); 5851 } 5852 5853 @Override 5854 public Object getAMSLock() { 5855 return ActivityManagerService.this; 5856 } 5857 } 5858 5859 /** 5860 * This can be called with or without the global lock held. 5861 */ 5862 int checkComponentPermission(String permission, int pid, int uid, 5863 int owningUid, boolean exported) { 5864 // We might be performing an operation on behalf of an indirect binder 5865 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5866 // client identity accordingly before proceeding. 5867 Identity tlsIdentity = sCallerIdentity.get(); 5868 if (tlsIdentity != null) { 5869 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5870 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5871 uid = tlsIdentity.uid; 5872 pid = tlsIdentity.pid; 5873 } 5874 5875 if (pid == MY_PID) { 5876 return PackageManager.PERMISSION_GRANTED; 5877 } 5878 5879 return ActivityManager.checkComponentPermission(permission, uid, 5880 owningUid, exported); 5881 } 5882 5883 /** 5884 * As the only public entry point for permissions checking, this method 5885 * can enforce the semantic that requesting a check on a null global 5886 * permission is automatically denied. (Internally a null permission 5887 * string is used when calling {@link #checkComponentPermission} in cases 5888 * when only uid-based security is needed.) 5889 * 5890 * This can be called with or without the global lock held. 5891 */ 5892 @Override 5893 public int checkPermission(String permission, int pid, int uid) { 5894 if (permission == null) { 5895 return PackageManager.PERMISSION_DENIED; 5896 } 5897 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5898 } 5899 5900 /** 5901 * Binder IPC calls go through the public entry point. 5902 * This can be called with or without the global lock held. 5903 */ 5904 int checkCallingPermission(String permission) { 5905 return checkPermission(permission, 5906 Binder.getCallingPid(), 5907 UserHandle.getAppId(Binder.getCallingUid())); 5908 } 5909 5910 /** 5911 * This can be called with or without the global lock held. 5912 */ 5913 void enforceCallingPermission(String permission, String func) { 5914 if (checkCallingPermission(permission) 5915 == PackageManager.PERMISSION_GRANTED) { 5916 return; 5917 } 5918 5919 String msg = "Permission Denial: " + func + " from pid=" 5920 + Binder.getCallingPid() 5921 + ", uid=" + Binder.getCallingUid() 5922 + " requires " + permission; 5923 Slog.w(TAG, msg); 5924 throw new SecurityException(msg); 5925 } 5926 5927 /** 5928 * Determine if UID is holding permissions required to access {@link Uri} in 5929 * the given {@link ProviderInfo}. Final permission checking is always done 5930 * in {@link ContentProvider}. 5931 */ 5932 private final boolean checkHoldingPermissionsLocked( 5933 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 5934 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5935 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5936 5937 if (pi.applicationInfo.uid == uid) { 5938 return true; 5939 } else if (!pi.exported) { 5940 return false; 5941 } 5942 5943 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5944 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5945 try { 5946 // check if target holds top-level <provider> permissions 5947 if (!readMet && pi.readPermission != null 5948 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5949 readMet = true; 5950 } 5951 if (!writeMet && pi.writePermission != null 5952 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5953 writeMet = true; 5954 } 5955 5956 // track if unprotected read/write is allowed; any denied 5957 // <path-permission> below removes this ability 5958 boolean allowDefaultRead = pi.readPermission == null; 5959 boolean allowDefaultWrite = pi.writePermission == null; 5960 5961 // check if target holds any <path-permission> that match uri 5962 final PathPermission[] pps = pi.pathPermissions; 5963 if (pps != null) { 5964 final String path = uri.getPath(); 5965 int i = pps.length; 5966 while (i > 0 && (!readMet || !writeMet)) { 5967 i--; 5968 PathPermission pp = pps[i]; 5969 if (pp.match(path)) { 5970 if (!readMet) { 5971 final String pprperm = pp.getReadPermission(); 5972 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5973 + pprperm + " for " + pp.getPath() 5974 + ": match=" + pp.match(path) 5975 + " check=" + pm.checkUidPermission(pprperm, uid)); 5976 if (pprperm != null) { 5977 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5978 readMet = true; 5979 } else { 5980 allowDefaultRead = false; 5981 } 5982 } 5983 } 5984 if (!writeMet) { 5985 final String ppwperm = pp.getWritePermission(); 5986 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5987 + ppwperm + " for " + pp.getPath() 5988 + ": match=" + pp.match(path) 5989 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5990 if (ppwperm != null) { 5991 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5992 writeMet = true; 5993 } else { 5994 allowDefaultWrite = false; 5995 } 5996 } 5997 } 5998 } 5999 } 6000 } 6001 6002 // grant unprotected <provider> read/write, if not blocked by 6003 // <path-permission> above 6004 if (allowDefaultRead) readMet = true; 6005 if (allowDefaultWrite) writeMet = true; 6006 6007 } catch (RemoteException e) { 6008 return false; 6009 } 6010 6011 return readMet && writeMet; 6012 } 6013 6014 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6015 ProviderInfo pi = null; 6016 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6017 if (cpr != null) { 6018 pi = cpr.info; 6019 } else { 6020 try { 6021 pi = AppGlobals.getPackageManager().resolveContentProvider( 6022 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6023 } catch (RemoteException ex) { 6024 } 6025 } 6026 return pi; 6027 } 6028 6029 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 6030 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6031 if (targetUris != null) { 6032 return targetUris.get(uri); 6033 } 6034 return null; 6035 } 6036 6037 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6038 String targetPkg, int targetUid, GrantUri uri) { 6039 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6040 if (targetUris == null) { 6041 targetUris = Maps.newArrayMap(); 6042 mGrantedUriPermissions.put(targetUid, targetUris); 6043 } 6044 6045 UriPermission perm = targetUris.get(uri); 6046 if (perm == null) { 6047 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 6048 targetUris.put(uri, perm); 6049 } 6050 6051 return perm; 6052 } 6053 6054 private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) { 6055 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6056 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6057 : UriPermission.STRENGTH_OWNED; 6058 6059 // Root gets to do everything. 6060 if (uid == 0) { 6061 return true; 6062 } 6063 6064 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6065 if (perms == null) return false; 6066 6067 // First look for exact match 6068 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 6069 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6070 return true; 6071 } 6072 6073 // No exact match, look for prefixes 6074 final int N = perms.size(); 6075 for (int i = 0; i < N; i++) { 6076 final UriPermission perm = perms.valueAt(i); 6077 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6078 && perm.getStrength(modeFlags) >= minStrength) { 6079 return true; 6080 } 6081 } 6082 6083 return false; 6084 } 6085 6086 @Override 6087 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6088 enforceNotIsolatedCaller("checkUriPermission"); 6089 6090 // Another redirected-binder-call permissions check as in 6091 // {@link checkComponentPermission}. 6092 Identity tlsIdentity = sCallerIdentity.get(); 6093 if (tlsIdentity != null) { 6094 uid = tlsIdentity.uid; 6095 pid = tlsIdentity.pid; 6096 } 6097 6098 // Our own process gets to do everything. 6099 if (pid == MY_PID) { 6100 return PackageManager.PERMISSION_GRANTED; 6101 } 6102 synchronized (this) { 6103 return checkUriPermissionLocked(uri, uid, modeFlags) 6104 ? PackageManager.PERMISSION_GRANTED 6105 : PackageManager.PERMISSION_DENIED; 6106 } 6107 } 6108 6109 /** 6110 * Check if the targetPkg can be granted permission to access uri by 6111 * the callingUid using the given modeFlags. Throws a security exception 6112 * if callingUid is not allowed to do this. Returns the uid of the target 6113 * if the URI permission grant should be performed; returns -1 if it is not 6114 * needed (for example targetPkg already has permission to access the URI). 6115 * If you already know the uid of the target, you can supply it in 6116 * lastTargetUid else set that to -1. 6117 */ 6118 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6119 Uri uri, final int modeFlags, int lastTargetUid) { 6120 if (!Intent.isAccessUriMode(modeFlags)) { 6121 return -1; 6122 } 6123 6124 if (targetPkg != null) { 6125 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6126 "Checking grant " + targetPkg + " permission to " + uri); 6127 } 6128 6129 final IPackageManager pm = AppGlobals.getPackageManager(); 6130 6131 // If this is not a content: uri, we can't do anything with it. 6132 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6133 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6134 "Can't grant URI permission for non-content URI: " + uri); 6135 return -1; 6136 } 6137 6138 final String authority = uri.getAuthority(); 6139 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6140 if (pi == null) { 6141 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6142 return -1; 6143 } 6144 6145 int targetUid = lastTargetUid; 6146 if (targetUid < 0 && targetPkg != null) { 6147 try { 6148 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6149 if (targetUid < 0) { 6150 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6151 "Can't grant URI permission no uid for: " + targetPkg); 6152 return -1; 6153 } 6154 } catch (RemoteException ex) { 6155 return -1; 6156 } 6157 } 6158 6159 if (targetUid >= 0) { 6160 // First... does the target actually need this permission? 6161 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6162 // No need to grant the target this permission. 6163 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6164 "Target " + targetPkg + " already has full permission to " + uri); 6165 return -1; 6166 } 6167 } else { 6168 // First... there is no target package, so can anyone access it? 6169 boolean allowed = pi.exported; 6170 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6171 if (pi.readPermission != null) { 6172 allowed = false; 6173 } 6174 } 6175 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6176 if (pi.writePermission != null) { 6177 allowed = false; 6178 } 6179 } 6180 if (allowed) { 6181 return -1; 6182 } 6183 } 6184 6185 // Second... is the provider allowing granting of URI permissions? 6186 if (!pi.grantUriPermissions) { 6187 throw new SecurityException("Provider " + pi.packageName 6188 + "/" + pi.name 6189 + " does not allow granting of Uri permissions (uri " 6190 + uri + ")"); 6191 } 6192 if (pi.uriPermissionPatterns != null) { 6193 final int N = pi.uriPermissionPatterns.length; 6194 boolean allowed = false; 6195 for (int i=0; i<N; i++) { 6196 if (pi.uriPermissionPatterns[i] != null 6197 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6198 allowed = true; 6199 break; 6200 } 6201 } 6202 if (!allowed) { 6203 throw new SecurityException("Provider " + pi.packageName 6204 + "/" + pi.name 6205 + " does not allow granting of permission to path of Uri " 6206 + uri); 6207 } 6208 } 6209 6210 // Third... does the caller itself have permission to access 6211 // this uri? 6212 if (callingUid != Process.myUid()) { 6213 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6214 // Require they hold a strong enough Uri permission 6215 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6216 throw new SecurityException("Uid " + callingUid 6217 + " does not have permission to uri " + uri); 6218 } 6219 } 6220 } 6221 6222 return targetUid; 6223 } 6224 6225 @Override 6226 public int checkGrantUriPermission(int callingUid, String targetPkg, 6227 Uri uri, final int modeFlags) { 6228 enforceNotIsolatedCaller("checkGrantUriPermission"); 6229 synchronized(this) { 6230 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6231 } 6232 } 6233 6234 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6235 final int modeFlags, UriPermissionOwner owner) { 6236 if (!Intent.isAccessUriMode(modeFlags)) { 6237 return; 6238 } 6239 6240 // So here we are: the caller has the assumed permission 6241 // to the uri, and the target doesn't. Let's now give this to 6242 // the target. 6243 6244 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6245 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6246 6247 final String authority = uri.getAuthority(); 6248 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6249 if (pi == null) { 6250 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6251 return; 6252 } 6253 6254 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6255 final UriPermission perm = findOrCreateUriPermissionLocked( 6256 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6257 perm.grantModes(modeFlags, owner); 6258 } 6259 6260 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6261 final int modeFlags, UriPermissionOwner owner) { 6262 if (targetPkg == null) { 6263 throw new NullPointerException("targetPkg"); 6264 } 6265 6266 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6267 if (targetUid < 0) { 6268 return; 6269 } 6270 6271 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6272 } 6273 6274 static class NeededUriGrants extends ArrayList<Uri> { 6275 final String targetPkg; 6276 final int targetUid; 6277 final int flags; 6278 6279 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6280 this.targetPkg = targetPkg; 6281 this.targetUid = targetUid; 6282 this.flags = flags; 6283 } 6284 } 6285 6286 /** 6287 * Like checkGrantUriPermissionLocked, but takes an Intent. 6288 */ 6289 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6290 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6291 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6292 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6293 + " clip=" + (intent != null ? intent.getClipData() : null) 6294 + " from " + intent + "; flags=0x" 6295 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6296 6297 if (targetPkg == null) { 6298 throw new NullPointerException("targetPkg"); 6299 } 6300 6301 if (intent == null) { 6302 return null; 6303 } 6304 Uri data = intent.getData(); 6305 ClipData clip = intent.getClipData(); 6306 if (data == null && clip == null) { 6307 return null; 6308 } 6309 6310 if (data != null) { 6311 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6312 mode, needed != null ? needed.targetUid : -1); 6313 if (targetUid > 0) { 6314 if (needed == null) { 6315 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6316 } 6317 needed.add(data); 6318 } 6319 } 6320 if (clip != null) { 6321 for (int i=0; i<clip.getItemCount(); i++) { 6322 Uri uri = clip.getItemAt(i).getUri(); 6323 if (uri != null) { 6324 int targetUid = -1; 6325 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6326 mode, needed != null ? needed.targetUid : -1); 6327 if (targetUid > 0) { 6328 if (needed == null) { 6329 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6330 } 6331 needed.add(uri); 6332 } 6333 } else { 6334 Intent clipIntent = clip.getItemAt(i).getIntent(); 6335 if (clipIntent != null) { 6336 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6337 callingUid, targetPkg, clipIntent, mode, needed); 6338 if (newNeeded != null) { 6339 needed = newNeeded; 6340 } 6341 } 6342 } 6343 } 6344 } 6345 6346 return needed; 6347 } 6348 6349 /** 6350 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6351 */ 6352 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6353 UriPermissionOwner owner) { 6354 if (needed != null) { 6355 for (int i=0; i<needed.size(); i++) { 6356 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6357 needed.get(i), needed.flags, owner); 6358 } 6359 } 6360 } 6361 6362 void grantUriPermissionFromIntentLocked(int callingUid, 6363 String targetPkg, Intent intent, UriPermissionOwner owner) { 6364 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6365 intent, intent != null ? intent.getFlags() : 0, null); 6366 if (needed == null) { 6367 return; 6368 } 6369 6370 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6371 } 6372 6373 @Override 6374 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6375 Uri uri, final int modeFlags) { 6376 enforceNotIsolatedCaller("grantUriPermission"); 6377 synchronized(this) { 6378 final ProcessRecord r = getRecordForAppLocked(caller); 6379 if (r == null) { 6380 throw new SecurityException("Unable to find app for caller " 6381 + caller 6382 + " when granting permission to uri " + uri); 6383 } 6384 if (targetPkg == null) { 6385 throw new IllegalArgumentException("null target"); 6386 } 6387 if (uri == null) { 6388 throw new IllegalArgumentException("null uri"); 6389 } 6390 6391 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6392 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6393 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6394 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6395 6396 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6397 } 6398 } 6399 6400 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6401 if (perm.modeFlags == 0) { 6402 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6403 perm.targetUid); 6404 if (perms != null) { 6405 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6406 "Removing " + perm.targetUid + " permission to " + perm.uri); 6407 6408 perms.remove(perm.uri); 6409 if (perms.isEmpty()) { 6410 mGrantedUriPermissions.remove(perm.targetUid); 6411 } 6412 } 6413 } 6414 } 6415 6416 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6417 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6418 6419 final IPackageManager pm = AppGlobals.getPackageManager(); 6420 final String authority = uri.getAuthority(); 6421 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6422 if (pi == null) { 6423 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6424 return; 6425 } 6426 6427 // Does the caller have this permission on the URI? 6428 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6429 // Right now, if you are not the original owner of the permission, 6430 // you are not allowed to revoke it. 6431 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6432 throw new SecurityException("Uid " + callingUid 6433 + " does not have permission to uri " + uri); 6434 //} 6435 } 6436 6437 boolean persistChanged = false; 6438 6439 // Go through all of the permissions and remove any that match. 6440 int N = mGrantedUriPermissions.size(); 6441 for (int i = 0; i < N; i++) { 6442 final int targetUid = mGrantedUriPermissions.keyAt(i); 6443 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6444 6445 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6446 final UriPermission perm = it.next(); 6447 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6448 if (DEBUG_URI_PERMISSION) 6449 Slog.v(TAG, 6450 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6451 persistChanged |= perm.revokeModes( 6452 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6453 if (perm.modeFlags == 0) { 6454 it.remove(); 6455 } 6456 } 6457 } 6458 6459 if (perms.isEmpty()) { 6460 mGrantedUriPermissions.remove(targetUid); 6461 N--; 6462 i--; 6463 } 6464 } 6465 6466 if (persistChanged) { 6467 schedulePersistUriGrants(); 6468 } 6469 } 6470 6471 @Override 6472 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6473 final int modeFlags) { 6474 enforceNotIsolatedCaller("revokeUriPermission"); 6475 synchronized(this) { 6476 final ProcessRecord r = getRecordForAppLocked(caller); 6477 if (r == null) { 6478 throw new SecurityException("Unable to find app for caller " 6479 + caller 6480 + " when revoking permission to uri " + uri); 6481 } 6482 if (uri == null) { 6483 Slog.w(TAG, "revokeUriPermission: null uri"); 6484 return; 6485 } 6486 6487 if (!Intent.isAccessUriMode(modeFlags)) { 6488 return; 6489 } 6490 6491 final IPackageManager pm = AppGlobals.getPackageManager(); 6492 final String authority = uri.getAuthority(); 6493 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6494 if (pi == null) { 6495 Slog.w(TAG, "No content provider found for permission revoke: " 6496 + uri.toSafeString()); 6497 return; 6498 } 6499 6500 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6501 } 6502 } 6503 6504 /** 6505 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6506 * given package. 6507 * 6508 * @param packageName Package name to match, or {@code null} to apply to all 6509 * packages. 6510 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6511 * to all users. 6512 * @param persistable If persistable grants should be removed. 6513 */ 6514 private void removeUriPermissionsForPackageLocked( 6515 String packageName, int userHandle, boolean persistable) { 6516 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6517 throw new IllegalArgumentException("Must narrow by either package or user"); 6518 } 6519 6520 boolean persistChanged = false; 6521 6522 int N = mGrantedUriPermissions.size(); 6523 for (int i = 0; i < N; i++) { 6524 final int targetUid = mGrantedUriPermissions.keyAt(i); 6525 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6526 6527 // Only inspect grants matching user 6528 if (userHandle == UserHandle.USER_ALL 6529 || userHandle == UserHandle.getUserId(targetUid)) { 6530 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6531 final UriPermission perm = it.next(); 6532 6533 // Only inspect grants matching package 6534 if (packageName == null || perm.sourcePkg.equals(packageName) 6535 || perm.targetPkg.equals(packageName)) { 6536 persistChanged |= perm.revokeModes( 6537 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6538 6539 // Only remove when no modes remain; any persisted grants 6540 // will keep this alive. 6541 if (perm.modeFlags == 0) { 6542 it.remove(); 6543 } 6544 } 6545 } 6546 6547 if (perms.isEmpty()) { 6548 mGrantedUriPermissions.remove(targetUid); 6549 N--; 6550 i--; 6551 } 6552 } 6553 } 6554 6555 if (persistChanged) { 6556 schedulePersistUriGrants(); 6557 } 6558 } 6559 6560 @Override 6561 public IBinder newUriPermissionOwner(String name) { 6562 enforceNotIsolatedCaller("newUriPermissionOwner"); 6563 synchronized(this) { 6564 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6565 return owner.getExternalTokenLocked(); 6566 } 6567 } 6568 6569 @Override 6570 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6571 Uri uri, final int modeFlags) { 6572 synchronized(this) { 6573 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6574 if (owner == null) { 6575 throw new IllegalArgumentException("Unknown owner: " + token); 6576 } 6577 if (fromUid != Binder.getCallingUid()) { 6578 if (Binder.getCallingUid() != Process.myUid()) { 6579 // Only system code can grant URI permissions on behalf 6580 // of other users. 6581 throw new SecurityException("nice try"); 6582 } 6583 } 6584 if (targetPkg == null) { 6585 throw new IllegalArgumentException("null target"); 6586 } 6587 if (uri == null) { 6588 throw new IllegalArgumentException("null uri"); 6589 } 6590 6591 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6592 } 6593 } 6594 6595 @Override 6596 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6597 synchronized(this) { 6598 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6599 if (owner == null) { 6600 throw new IllegalArgumentException("Unknown owner: " + token); 6601 } 6602 6603 if (uri == null) { 6604 owner.removeUriPermissionsLocked(mode); 6605 } else { 6606 owner.removeUriPermissionLocked(uri, mode); 6607 } 6608 } 6609 } 6610 6611 private void schedulePersistUriGrants() { 6612 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6613 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6614 10 * DateUtils.SECOND_IN_MILLIS); 6615 } 6616 } 6617 6618 private void writeGrantedUriPermissions() { 6619 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6620 6621 // Snapshot permissions so we can persist without lock 6622 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6623 synchronized (this) { 6624 final int size = mGrantedUriPermissions.size(); 6625 for (int i = 0; i < size; i++) { 6626 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6627 for (UriPermission perm : perms.values()) { 6628 if (perm.persistedModeFlags != 0) { 6629 persist.add(perm.snapshot()); 6630 } 6631 } 6632 } 6633 } 6634 6635 FileOutputStream fos = null; 6636 try { 6637 fos = mGrantFile.startWrite(); 6638 6639 XmlSerializer out = new FastXmlSerializer(); 6640 out.setOutput(fos, "utf-8"); 6641 out.startDocument(null, true); 6642 out.startTag(null, TAG_URI_GRANTS); 6643 for (UriPermission.Snapshot perm : persist) { 6644 out.startTag(null, TAG_URI_GRANT); 6645 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6646 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6647 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6648 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6649 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6650 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6651 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6652 out.endTag(null, TAG_URI_GRANT); 6653 } 6654 out.endTag(null, TAG_URI_GRANTS); 6655 out.endDocument(); 6656 6657 mGrantFile.finishWrite(fos); 6658 } catch (IOException e) { 6659 if (fos != null) { 6660 mGrantFile.failWrite(fos); 6661 } 6662 } 6663 } 6664 6665 private void readGrantedUriPermissionsLocked() { 6666 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6667 6668 final long now = System.currentTimeMillis(); 6669 6670 FileInputStream fis = null; 6671 try { 6672 fis = mGrantFile.openRead(); 6673 final XmlPullParser in = Xml.newPullParser(); 6674 in.setInput(fis, null); 6675 6676 int type; 6677 while ((type = in.next()) != END_DOCUMENT) { 6678 final String tag = in.getName(); 6679 if (type == START_TAG) { 6680 if (TAG_URI_GRANT.equals(tag)) { 6681 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6682 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6683 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6684 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6685 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6686 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6687 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6688 6689 // Sanity check that provider still belongs to source package 6690 final ProviderInfo pi = getProviderInfoLocked( 6691 uri.getAuthority(), userHandle); 6692 if (pi != null && sourcePkg.equals(pi.packageName)) { 6693 int targetUid = -1; 6694 try { 6695 targetUid = AppGlobals.getPackageManager() 6696 .getPackageUid(targetPkg, userHandle); 6697 } catch (RemoteException e) { 6698 } 6699 if (targetUid != -1) { 6700 final UriPermission perm = findOrCreateUriPermissionLocked( 6701 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6702 perm.initPersistedModes(modeFlags, createdTime); 6703 } 6704 } else { 6705 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6706 + " but instead found " + pi); 6707 } 6708 } 6709 } 6710 } 6711 } catch (FileNotFoundException e) { 6712 // Missing grants is okay 6713 } catch (IOException e) { 6714 Log.wtf(TAG, "Failed reading Uri grants", e); 6715 } catch (XmlPullParserException e) { 6716 Log.wtf(TAG, "Failed reading Uri grants", e); 6717 } finally { 6718 IoUtils.closeQuietly(fis); 6719 } 6720 } 6721 6722 @Override 6723 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6724 enforceNotIsolatedCaller("takePersistableUriPermission"); 6725 6726 Preconditions.checkFlagsArgument(modeFlags, 6727 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6728 6729 synchronized (this) { 6730 final int callingUid = Binder.getCallingUid(); 6731 boolean persistChanged = false; 6732 6733 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6734 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6735 6736 final boolean exactValid = (exactPerm != null) 6737 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6738 final boolean prefixValid = (prefixPerm != null) 6739 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6740 6741 if (!(exactValid || prefixValid)) { 6742 throw new SecurityException("No persistable permission grants found for UID " 6743 + callingUid + " and Uri " + uri.toSafeString()); 6744 } 6745 6746 if (exactValid) { 6747 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6748 } 6749 if (prefixValid) { 6750 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6751 } 6752 6753 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6754 6755 if (persistChanged) { 6756 schedulePersistUriGrants(); 6757 } 6758 } 6759 } 6760 6761 @Override 6762 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6763 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6764 6765 Preconditions.checkFlagsArgument(modeFlags, 6766 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6767 6768 synchronized (this) { 6769 final int callingUid = Binder.getCallingUid(); 6770 boolean persistChanged = false; 6771 6772 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6773 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6774 if (exactPerm == null && prefixPerm == null) { 6775 throw new SecurityException("No permission grants found for UID " + callingUid 6776 + " and Uri " + uri.toSafeString()); 6777 } 6778 6779 if (exactPerm != null) { 6780 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6781 removeUriPermissionIfNeededLocked(exactPerm); 6782 } 6783 if (prefixPerm != null) { 6784 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6785 removeUriPermissionIfNeededLocked(prefixPerm); 6786 } 6787 6788 if (persistChanged) { 6789 schedulePersistUriGrants(); 6790 } 6791 } 6792 } 6793 6794 /** 6795 * Prune any older {@link UriPermission} for the given UID until outstanding 6796 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6797 * 6798 * @return if any mutations occured that require persisting. 6799 */ 6800 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6801 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6802 if (perms == null) return false; 6803 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6804 6805 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6806 for (UriPermission perm : perms.values()) { 6807 if (perm.persistedModeFlags != 0) { 6808 persisted.add(perm); 6809 } 6810 } 6811 6812 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6813 if (trimCount <= 0) return false; 6814 6815 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6816 for (int i = 0; i < trimCount; i++) { 6817 final UriPermission perm = persisted.get(i); 6818 6819 if (DEBUG_URI_PERMISSION) { 6820 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6821 } 6822 6823 perm.releasePersistableModes(~0); 6824 removeUriPermissionIfNeededLocked(perm); 6825 } 6826 6827 return true; 6828 } 6829 6830 @Override 6831 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6832 String packageName, boolean incoming) { 6833 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6834 Preconditions.checkNotNull(packageName, "packageName"); 6835 6836 final int callingUid = Binder.getCallingUid(); 6837 final IPackageManager pm = AppGlobals.getPackageManager(); 6838 try { 6839 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6840 if (packageUid != callingUid) { 6841 throw new SecurityException( 6842 "Package " + packageName + " does not belong to calling UID " + callingUid); 6843 } 6844 } catch (RemoteException e) { 6845 throw new SecurityException("Failed to verify package name ownership"); 6846 } 6847 6848 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6849 synchronized (this) { 6850 if (incoming) { 6851 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6852 callingUid); 6853 if (perms == null) { 6854 Slog.w(TAG, "No permission grants found for " + packageName); 6855 } else { 6856 for (UriPermission perm : perms.values()) { 6857 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6858 result.add(perm.buildPersistedPublicApiObject()); 6859 } 6860 } 6861 } 6862 } else { 6863 final int size = mGrantedUriPermissions.size(); 6864 for (int i = 0; i < size; i++) { 6865 final ArrayMap<GrantUri, UriPermission> perms = 6866 mGrantedUriPermissions.valueAt(i); 6867 for (UriPermission perm : perms.values()) { 6868 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6869 result.add(perm.buildPersistedPublicApiObject()); 6870 } 6871 } 6872 } 6873 } 6874 } 6875 return new ParceledListSlice<android.content.UriPermission>(result); 6876 } 6877 6878 @Override 6879 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6880 synchronized (this) { 6881 ProcessRecord app = 6882 who != null ? getRecordForAppLocked(who) : null; 6883 if (app == null) return; 6884 6885 Message msg = Message.obtain(); 6886 msg.what = WAIT_FOR_DEBUGGER_MSG; 6887 msg.obj = app; 6888 msg.arg1 = waiting ? 1 : 0; 6889 mHandler.sendMessage(msg); 6890 } 6891 } 6892 6893 @Override 6894 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6895 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6896 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6897 outInfo.availMem = Process.getFreeMemory(); 6898 outInfo.totalMem = Process.getTotalMemory(); 6899 outInfo.threshold = homeAppMem; 6900 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6901 outInfo.hiddenAppThreshold = cachedAppMem; 6902 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6903 ProcessList.SERVICE_ADJ); 6904 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6905 ProcessList.VISIBLE_APP_ADJ); 6906 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6907 ProcessList.FOREGROUND_APP_ADJ); 6908 } 6909 6910 // ========================================================= 6911 // TASK MANAGEMENT 6912 // ========================================================= 6913 6914 @Override 6915 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6916 IThumbnailReceiver receiver) { 6917 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6918 6919 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6920 ActivityRecord topRecord = null; 6921 6922 synchronized(this) { 6923 if (localLOGV) Slog.v( 6924 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6925 + ", receiver=" + receiver); 6926 6927 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6928 != PackageManager.PERMISSION_GRANTED) { 6929 if (receiver != null) { 6930 // If the caller wants to wait for pending thumbnails, 6931 // it ain't gonna get them. 6932 try { 6933 receiver.finished(); 6934 } catch (RemoteException ex) { 6935 } 6936 } 6937 String msg = "Permission Denial: getTasks() from pid=" 6938 + Binder.getCallingPid() 6939 + ", uid=" + Binder.getCallingUid() 6940 + " requires " + android.Manifest.permission.GET_TASKS; 6941 Slog.w(TAG, msg); 6942 throw new SecurityException(msg); 6943 } 6944 6945 // TODO: Improve with MRU list from all ActivityStacks. 6946 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6947 6948 if (!pending.pendingRecords.isEmpty()) { 6949 mPendingThumbnails.add(pending); 6950 } 6951 } 6952 6953 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6954 6955 if (topRecord != null) { 6956 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6957 try { 6958 IApplicationThread topThumbnail = topRecord.app.thread; 6959 topThumbnail.requestThumbnail(topRecord.appToken); 6960 } catch (Exception e) { 6961 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6962 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6963 } 6964 } 6965 6966 if (pending.pendingRecords.isEmpty() && receiver != null) { 6967 // In this case all thumbnails were available and the client 6968 // is being asked to be told when the remaining ones come in... 6969 // which is unusually, since the top-most currently running 6970 // activity should never have a canned thumbnail! Oh well. 6971 try { 6972 receiver.finished(); 6973 } catch (RemoteException ex) { 6974 } 6975 } 6976 6977 return list; 6978 } 6979 6980 TaskRecord getMostRecentTask() { 6981 return mRecentTasks.get(0); 6982 } 6983 6984 @Override 6985 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6986 int flags, int userId) { 6987 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6988 false, true, "getRecentTasks", null); 6989 6990 synchronized (this) { 6991 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6992 "getRecentTasks()"); 6993 final boolean detailed = checkCallingPermission( 6994 android.Manifest.permission.GET_DETAILED_TASKS) 6995 == PackageManager.PERMISSION_GRANTED; 6996 6997 IPackageManager pm = AppGlobals.getPackageManager(); 6998 6999 final int N = mRecentTasks.size(); 7000 ArrayList<ActivityManager.RecentTaskInfo> res 7001 = new ArrayList<ActivityManager.RecentTaskInfo>( 7002 maxNum < N ? maxNum : N); 7003 7004 final Set<Integer> includedUsers; 7005 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7006 includedUsers = getProfileIdsLocked(userId); 7007 } else { 7008 includedUsers = new HashSet<Integer>(); 7009 } 7010 includedUsers.add(Integer.valueOf(userId)); 7011 for (int i=0; i<N && maxNum > 0; i++) { 7012 TaskRecord tr = mRecentTasks.get(i); 7013 // Only add calling user or related users recent tasks 7014 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7015 7016 // Return the entry if desired by the caller. We always return 7017 // the first entry, because callers always expect this to be the 7018 // foreground app. We may filter others if the caller has 7019 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7020 // we should exclude the entry. 7021 7022 if (i == 0 7023 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7024 || (tr.intent == null) 7025 || ((tr.intent.getFlags() 7026 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7027 ActivityManager.RecentTaskInfo rti 7028 = new ActivityManager.RecentTaskInfo(); 7029 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7030 rti.persistentId = tr.taskId; 7031 rti.baseIntent = new Intent( 7032 tr.intent != null ? tr.intent : tr.affinityIntent); 7033 if (!detailed) { 7034 rti.baseIntent.replaceExtras((Bundle)null); 7035 } 7036 rti.origActivity = tr.origActivity; 7037 rti.description = tr.lastDescription; 7038 rti.stackId = tr.stack.mStackId; 7039 rti.userId = tr.userId; 7040 7041 // Traverse upwards looking for any break between main task activities and 7042 // utility activities. 7043 final ArrayList<ActivityRecord> activities = tr.mActivities; 7044 int activityNdx; 7045 final int numActivities = activities.size(); 7046 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7047 ++activityNdx) { 7048 final ActivityRecord r = activities.get(activityNdx); 7049 if (r.intent != null && 7050 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7051 != 0) { 7052 break; 7053 } 7054 } 7055 // Traverse downwards starting below break looking for set label and icon. 7056 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7057 final ActivityRecord r = activities.get(activityNdx); 7058 if (r.activityLabel != null || r.activityIcon != null) { 7059 rti.activityLabel = r.activityLabel; 7060 rti.activityIcon = r.activityIcon; 7061 break; 7062 } 7063 } 7064 7065 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7066 // Check whether this activity is currently available. 7067 try { 7068 if (rti.origActivity != null) { 7069 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7070 == null) { 7071 continue; 7072 } 7073 } else if (rti.baseIntent != null) { 7074 if (pm.queryIntentActivities(rti.baseIntent, 7075 null, 0, userId) == null) { 7076 continue; 7077 } 7078 } 7079 } catch (RemoteException e) { 7080 // Will never happen. 7081 } 7082 } 7083 7084 res.add(rti); 7085 maxNum--; 7086 } 7087 } 7088 return res; 7089 } 7090 } 7091 7092 private TaskRecord recentTaskForIdLocked(int id) { 7093 final int N = mRecentTasks.size(); 7094 for (int i=0; i<N; i++) { 7095 TaskRecord tr = mRecentTasks.get(i); 7096 if (tr.taskId == id) { 7097 return tr; 7098 } 7099 } 7100 return null; 7101 } 7102 7103 @Override 7104 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7105 synchronized (this) { 7106 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7107 "getTaskThumbnails()"); 7108 TaskRecord tr = recentTaskForIdLocked(id); 7109 if (tr != null) { 7110 return tr.getTaskThumbnailsLocked(); 7111 } 7112 } 7113 return null; 7114 } 7115 7116 @Override 7117 public Bitmap getTaskTopThumbnail(int id) { 7118 synchronized (this) { 7119 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7120 "getTaskTopThumbnail()"); 7121 TaskRecord tr = recentTaskForIdLocked(id); 7122 if (tr != null) { 7123 return tr.getTaskTopThumbnailLocked(); 7124 } 7125 } 7126 return null; 7127 } 7128 7129 @Override 7130 public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel, 7131 Bitmap activityIcon) { 7132 synchronized (this) { 7133 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7134 if (r != null) { 7135 r.activityLabel = activityLabel.toString(); 7136 r.activityIcon = activityIcon; 7137 } 7138 } 7139 } 7140 7141 @Override 7142 public boolean removeSubTask(int taskId, int subTaskIndex) { 7143 synchronized (this) { 7144 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7145 "removeSubTask()"); 7146 long ident = Binder.clearCallingIdentity(); 7147 try { 7148 TaskRecord tr = recentTaskForIdLocked(taskId); 7149 if (tr != null) { 7150 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7151 } 7152 return false; 7153 } finally { 7154 Binder.restoreCallingIdentity(ident); 7155 } 7156 } 7157 } 7158 7159 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7160 if (!pr.killedByAm) { 7161 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7162 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7163 pr.processName, pr.setAdj, reason); 7164 pr.killedByAm = true; 7165 Process.killProcessQuiet(pr.pid); 7166 } 7167 } 7168 7169 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7170 tr.disposeThumbnail(); 7171 mRecentTasks.remove(tr); 7172 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7173 Intent baseIntent = new Intent( 7174 tr.intent != null ? tr.intent : tr.affinityIntent); 7175 ComponentName component = baseIntent.getComponent(); 7176 if (component == null) { 7177 Slog.w(TAG, "Now component for base intent of task: " + tr); 7178 return; 7179 } 7180 7181 // Find any running services associated with this app. 7182 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7183 7184 if (killProcesses) { 7185 // Find any running processes associated with this app. 7186 final String pkg = component.getPackageName(); 7187 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7188 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7189 for (int i=0; i<pmap.size(); i++) { 7190 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7191 for (int j=0; j<uids.size(); j++) { 7192 ProcessRecord proc = uids.valueAt(j); 7193 if (proc.userId != tr.userId) { 7194 continue; 7195 } 7196 if (!proc.pkgList.containsKey(pkg)) { 7197 continue; 7198 } 7199 procs.add(proc); 7200 } 7201 } 7202 7203 // Kill the running processes. 7204 for (int i=0; i<procs.size(); i++) { 7205 ProcessRecord pr = procs.get(i); 7206 if (pr == mHomeProcess) { 7207 // Don't kill the home process along with tasks from the same package. 7208 continue; 7209 } 7210 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7211 killUnneededProcessLocked(pr, "remove task"); 7212 } else { 7213 pr.waitingToKill = "remove task"; 7214 } 7215 } 7216 } 7217 } 7218 7219 /** 7220 * Removes the task with the specified task id. 7221 * 7222 * @param taskId Identifier of the task to be removed. 7223 * @param flags Additional operational flags. May be 0 or 7224 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7225 * @return Returns true if the given task was found and removed. 7226 */ 7227 private boolean removeTaskByIdLocked(int taskId, int flags) { 7228 TaskRecord tr = recentTaskForIdLocked(taskId); 7229 if (tr != null) { 7230 tr.removeTaskActivitiesLocked(-1, false); 7231 cleanUpRemovedTaskLocked(tr, flags); 7232 return true; 7233 } 7234 return false; 7235 } 7236 7237 @Override 7238 public boolean removeTask(int taskId, int flags) { 7239 synchronized (this) { 7240 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7241 "removeTask()"); 7242 long ident = Binder.clearCallingIdentity(); 7243 try { 7244 return removeTaskByIdLocked(taskId, flags); 7245 } finally { 7246 Binder.restoreCallingIdentity(ident); 7247 } 7248 } 7249 } 7250 7251 /** 7252 * TODO: Add mController hook 7253 */ 7254 @Override 7255 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7256 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7257 "moveTaskToFront()"); 7258 7259 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7260 synchronized(this) { 7261 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7262 Binder.getCallingUid(), "Task to front")) { 7263 ActivityOptions.abort(options); 7264 return; 7265 } 7266 final long origId = Binder.clearCallingIdentity(); 7267 try { 7268 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7269 if (task == null) { 7270 return; 7271 } 7272 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7273 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7274 return; 7275 } 7276 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7277 } finally { 7278 Binder.restoreCallingIdentity(origId); 7279 } 7280 ActivityOptions.abort(options); 7281 } 7282 } 7283 7284 @Override 7285 public void moveTaskToBack(int taskId) { 7286 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7287 "moveTaskToBack()"); 7288 7289 synchronized(this) { 7290 TaskRecord tr = recentTaskForIdLocked(taskId); 7291 if (tr != null) { 7292 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7293 ActivityStack stack = tr.stack; 7294 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7295 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7296 Binder.getCallingUid(), "Task to back")) { 7297 return; 7298 } 7299 } 7300 final long origId = Binder.clearCallingIdentity(); 7301 try { 7302 stack.moveTaskToBackLocked(taskId, null); 7303 } finally { 7304 Binder.restoreCallingIdentity(origId); 7305 } 7306 } 7307 } 7308 } 7309 7310 /** 7311 * Moves an activity, and all of the other activities within the same task, to the bottom 7312 * of the history stack. The activity's order within the task is unchanged. 7313 * 7314 * @param token A reference to the activity we wish to move 7315 * @param nonRoot If false then this only works if the activity is the root 7316 * of a task; if true it will work for any activity in a task. 7317 * @return Returns true if the move completed, false if not. 7318 */ 7319 @Override 7320 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7321 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7322 synchronized(this) { 7323 final long origId = Binder.clearCallingIdentity(); 7324 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7325 if (taskId >= 0) { 7326 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7327 } 7328 Binder.restoreCallingIdentity(origId); 7329 } 7330 return false; 7331 } 7332 7333 @Override 7334 public void moveTaskBackwards(int task) { 7335 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7336 "moveTaskBackwards()"); 7337 7338 synchronized(this) { 7339 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7340 Binder.getCallingUid(), "Task backwards")) { 7341 return; 7342 } 7343 final long origId = Binder.clearCallingIdentity(); 7344 moveTaskBackwardsLocked(task); 7345 Binder.restoreCallingIdentity(origId); 7346 } 7347 } 7348 7349 private final void moveTaskBackwardsLocked(int task) { 7350 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7351 } 7352 7353 @Override 7354 public IBinder getHomeActivityToken() throws RemoteException { 7355 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7356 "getHomeActivityToken()"); 7357 synchronized (this) { 7358 return mStackSupervisor.getHomeActivityToken(); 7359 } 7360 } 7361 7362 @Override 7363 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7364 IActivityContainerCallback callback) throws RemoteException { 7365 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7366 "createActivityContainer()"); 7367 synchronized (this) { 7368 if (parentActivityToken == null) { 7369 throw new IllegalArgumentException("parent token must not be null"); 7370 } 7371 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7372 if (r == null) { 7373 return null; 7374 } 7375 if (callback == null) { 7376 throw new IllegalArgumentException("callback must not be null"); 7377 } 7378 return mStackSupervisor.createActivityContainer(r, callback); 7379 } 7380 } 7381 7382 @Override 7383 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7384 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7385 "deleteActivityContainer()"); 7386 synchronized (this) { 7387 mStackSupervisor.deleteActivityContainer(container); 7388 } 7389 } 7390 7391 @Override 7392 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7393 throws RemoteException { 7394 synchronized (this) { 7395 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7396 if (stack != null) { 7397 return stack.mActivityContainer; 7398 } 7399 return null; 7400 } 7401 } 7402 7403 @Override 7404 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7405 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7406 "moveTaskToStack()"); 7407 if (stackId == HOME_STACK_ID) { 7408 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7409 new RuntimeException("here").fillInStackTrace()); 7410 } 7411 synchronized (this) { 7412 long ident = Binder.clearCallingIdentity(); 7413 try { 7414 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7415 + stackId + " toTop=" + toTop); 7416 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7417 } finally { 7418 Binder.restoreCallingIdentity(ident); 7419 } 7420 } 7421 } 7422 7423 @Override 7424 public void resizeStack(int stackBoxId, Rect bounds) { 7425 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7426 "resizeStackBox()"); 7427 long ident = Binder.clearCallingIdentity(); 7428 try { 7429 mWindowManager.resizeStack(stackBoxId, bounds); 7430 } finally { 7431 Binder.restoreCallingIdentity(ident); 7432 } 7433 } 7434 7435 @Override 7436 public List<StackInfo> getAllStackInfos() { 7437 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7438 "getAllStackInfos()"); 7439 long ident = Binder.clearCallingIdentity(); 7440 try { 7441 synchronized (this) { 7442 return mStackSupervisor.getAllStackInfosLocked(); 7443 } 7444 } finally { 7445 Binder.restoreCallingIdentity(ident); 7446 } 7447 } 7448 7449 @Override 7450 public StackInfo getStackInfo(int stackId) { 7451 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7452 "getStackInfo()"); 7453 long ident = Binder.clearCallingIdentity(); 7454 try { 7455 synchronized (this) { 7456 return mStackSupervisor.getStackInfoLocked(stackId); 7457 } 7458 } finally { 7459 Binder.restoreCallingIdentity(ident); 7460 } 7461 } 7462 7463 @Override 7464 public boolean isInHomeStack(int taskId) { 7465 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7466 "getStackInfo()"); 7467 long ident = Binder.clearCallingIdentity(); 7468 try { 7469 synchronized (this) { 7470 TaskRecord tr = recentTaskForIdLocked(taskId); 7471 if (tr != null) { 7472 return tr.stack.isHomeStack(); 7473 } 7474 } 7475 } finally { 7476 Binder.restoreCallingIdentity(ident); 7477 } 7478 return false; 7479 } 7480 7481 @Override 7482 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7483 synchronized(this) { 7484 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7485 } 7486 } 7487 7488 private boolean isLockTaskAuthorized(ComponentName name) { 7489// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7490// "startLockTaskMode()"); 7491// DevicePolicyManager dpm = (DevicePolicyManager) 7492// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7493// return dpm != null && dpm.isLockTaskPermitted(name); 7494 return true; 7495 } 7496 7497 private void startLockTaskMode(TaskRecord task) { 7498 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7499 return; 7500 } 7501 long ident = Binder.clearCallingIdentity(); 7502 try { 7503 synchronized (this) { 7504 // Since we lost lock on task, make sure it is still there. 7505 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7506 if (task != null) { 7507 mStackSupervisor.setLockTaskModeLocked(task); 7508 } 7509 } 7510 } finally { 7511 Binder.restoreCallingIdentity(ident); 7512 } 7513 } 7514 7515 @Override 7516 public void startLockTaskMode(int taskId) { 7517 long ident = Binder.clearCallingIdentity(); 7518 try { 7519 final TaskRecord task; 7520 synchronized (this) { 7521 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7522 } 7523 if (task != null) { 7524 startLockTaskMode(task); 7525 } 7526 } finally { 7527 Binder.restoreCallingIdentity(ident); 7528 } 7529 } 7530 7531 @Override 7532 public void startLockTaskMode(IBinder token) { 7533 long ident = Binder.clearCallingIdentity(); 7534 try { 7535 final TaskRecord task; 7536 synchronized (this) { 7537 final ActivityRecord r = ActivityRecord.forToken(token); 7538 if (r == null) { 7539 return; 7540 } 7541 task = r.task; 7542 } 7543 if (task != null) { 7544 startLockTaskMode(task); 7545 } 7546 } finally { 7547 Binder.restoreCallingIdentity(ident); 7548 } 7549 } 7550 7551 @Override 7552 public void stopLockTaskMode() { 7553// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7554// "stopLockTaskMode()"); 7555 synchronized (this) { 7556 mStackSupervisor.setLockTaskModeLocked(null); 7557 } 7558 } 7559 7560 @Override 7561 public boolean isInLockTaskMode() { 7562 synchronized (this) { 7563 return mStackSupervisor.isInLockTaskMode(); 7564 } 7565 } 7566 7567 // ========================================================= 7568 // THUMBNAILS 7569 // ========================================================= 7570 7571 public void reportThumbnail(IBinder token, 7572 Bitmap thumbnail, CharSequence description) { 7573 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7574 final long origId = Binder.clearCallingIdentity(); 7575 sendPendingThumbnail(null, token, thumbnail, description, true); 7576 Binder.restoreCallingIdentity(origId); 7577 } 7578 7579 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7580 Bitmap thumbnail, CharSequence description, boolean always) { 7581 TaskRecord task; 7582 ArrayList<PendingThumbnailsRecord> receivers = null; 7583 7584 //System.out.println("Send pending thumbnail: " + r); 7585 7586 synchronized(this) { 7587 if (r == null) { 7588 r = ActivityRecord.isInStackLocked(token); 7589 if (r == null) { 7590 return; 7591 } 7592 } 7593 if (thumbnail == null && r.thumbHolder != null) { 7594 thumbnail = r.thumbHolder.lastThumbnail; 7595 description = r.thumbHolder.lastDescription; 7596 } 7597 if (thumbnail == null && !always) { 7598 // If there is no thumbnail, and this entry is not actually 7599 // going away, then abort for now and pick up the next 7600 // thumbnail we get. 7601 return; 7602 } 7603 task = r.task; 7604 7605 int N = mPendingThumbnails.size(); 7606 int i=0; 7607 while (i<N) { 7608 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7609 //System.out.println("Looking in " + pr.pendingRecords); 7610 if (pr.pendingRecords.remove(r)) { 7611 if (receivers == null) { 7612 receivers = new ArrayList<PendingThumbnailsRecord>(); 7613 } 7614 receivers.add(pr); 7615 if (pr.pendingRecords.size() == 0) { 7616 pr.finished = true; 7617 mPendingThumbnails.remove(i); 7618 N--; 7619 continue; 7620 } 7621 } 7622 i++; 7623 } 7624 } 7625 7626 if (receivers != null) { 7627 final int N = receivers.size(); 7628 for (int i=0; i<N; i++) { 7629 try { 7630 PendingThumbnailsRecord pr = receivers.get(i); 7631 pr.receiver.newThumbnail( 7632 task != null ? task.taskId : -1, thumbnail, description); 7633 if (pr.finished) { 7634 pr.receiver.finished(); 7635 } 7636 } catch (Exception e) { 7637 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7638 } 7639 } 7640 } 7641 } 7642 7643 // ========================================================= 7644 // CONTENT PROVIDERS 7645 // ========================================================= 7646 7647 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7648 List<ProviderInfo> providers = null; 7649 try { 7650 providers = AppGlobals.getPackageManager(). 7651 queryContentProviders(app.processName, app.uid, 7652 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7653 } catch (RemoteException ex) { 7654 } 7655 if (DEBUG_MU) 7656 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7657 int userId = app.userId; 7658 if (providers != null) { 7659 int N = providers.size(); 7660 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7661 for (int i=0; i<N; i++) { 7662 ProviderInfo cpi = 7663 (ProviderInfo)providers.get(i); 7664 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7665 cpi.name, cpi.flags); 7666 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7667 // This is a singleton provider, but a user besides the 7668 // default user is asking to initialize a process it runs 7669 // in... well, no, it doesn't actually run in this process, 7670 // it runs in the process of the default user. Get rid of it. 7671 providers.remove(i); 7672 N--; 7673 i--; 7674 continue; 7675 } 7676 7677 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7678 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7679 if (cpr == null) { 7680 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7681 mProviderMap.putProviderByClass(comp, cpr); 7682 } 7683 if (DEBUG_MU) 7684 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7685 app.pubProviders.put(cpi.name, cpr); 7686 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7687 // Don't add this if it is a platform component that is marked 7688 // to run in multiple processes, because this is actually 7689 // part of the framework so doesn't make sense to track as a 7690 // separate apk in the process. 7691 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7692 } 7693 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7694 } 7695 } 7696 return providers; 7697 } 7698 7699 /** 7700 * Check if {@link ProcessRecord} has a possible chance at accessing the 7701 * given {@link ProviderInfo}. Final permission checking is always done 7702 * in {@link ContentProvider}. 7703 */ 7704 private final String checkContentProviderPermissionLocked( 7705 ProviderInfo cpi, ProcessRecord r) { 7706 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7707 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7708 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7709 cpi.applicationInfo.uid, cpi.exported) 7710 == PackageManager.PERMISSION_GRANTED) { 7711 return null; 7712 } 7713 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7714 cpi.applicationInfo.uid, cpi.exported) 7715 == PackageManager.PERMISSION_GRANTED) { 7716 return null; 7717 } 7718 7719 PathPermission[] pps = cpi.pathPermissions; 7720 if (pps != null) { 7721 int i = pps.length; 7722 while (i > 0) { 7723 i--; 7724 PathPermission pp = pps[i]; 7725 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7726 cpi.applicationInfo.uid, cpi.exported) 7727 == PackageManager.PERMISSION_GRANTED) { 7728 return null; 7729 } 7730 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7731 cpi.applicationInfo.uid, cpi.exported) 7732 == PackageManager.PERMISSION_GRANTED) { 7733 return null; 7734 } 7735 } 7736 } 7737 7738 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7739 if (perms != null) { 7740 for (GrantUri uri : perms.keySet()) { 7741 if (uri.uri.getAuthority().equals(cpi.authority)) { 7742 return null; 7743 } 7744 } 7745 } 7746 7747 String msg; 7748 if (!cpi.exported) { 7749 msg = "Permission Denial: opening provider " + cpi.name 7750 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7751 + ", uid=" + callingUid + ") that is not exported from uid " 7752 + cpi.applicationInfo.uid; 7753 } else { 7754 msg = "Permission Denial: opening provider " + cpi.name 7755 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7756 + ", uid=" + callingUid + ") requires " 7757 + cpi.readPermission + " or " + cpi.writePermission; 7758 } 7759 Slog.w(TAG, msg); 7760 return msg; 7761 } 7762 7763 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7764 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7765 if (r != null) { 7766 for (int i=0; i<r.conProviders.size(); i++) { 7767 ContentProviderConnection conn = r.conProviders.get(i); 7768 if (conn.provider == cpr) { 7769 if (DEBUG_PROVIDER) Slog.v(TAG, 7770 "Adding provider requested by " 7771 + r.processName + " from process " 7772 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7773 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7774 if (stable) { 7775 conn.stableCount++; 7776 conn.numStableIncs++; 7777 } else { 7778 conn.unstableCount++; 7779 conn.numUnstableIncs++; 7780 } 7781 return conn; 7782 } 7783 } 7784 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7785 if (stable) { 7786 conn.stableCount = 1; 7787 conn.numStableIncs = 1; 7788 } else { 7789 conn.unstableCount = 1; 7790 conn.numUnstableIncs = 1; 7791 } 7792 cpr.connections.add(conn); 7793 r.conProviders.add(conn); 7794 return conn; 7795 } 7796 cpr.addExternalProcessHandleLocked(externalProcessToken); 7797 return null; 7798 } 7799 7800 boolean decProviderCountLocked(ContentProviderConnection conn, 7801 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7802 if (conn != null) { 7803 cpr = conn.provider; 7804 if (DEBUG_PROVIDER) Slog.v(TAG, 7805 "Removing provider requested by " 7806 + conn.client.processName + " from process " 7807 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7808 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7809 if (stable) { 7810 conn.stableCount--; 7811 } else { 7812 conn.unstableCount--; 7813 } 7814 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7815 cpr.connections.remove(conn); 7816 conn.client.conProviders.remove(conn); 7817 return true; 7818 } 7819 return false; 7820 } 7821 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7822 return false; 7823 } 7824 7825 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7826 String name, IBinder token, boolean stable, int userId) { 7827 ContentProviderRecord cpr; 7828 ContentProviderConnection conn = null; 7829 ProviderInfo cpi = null; 7830 7831 synchronized(this) { 7832 ProcessRecord r = null; 7833 if (caller != null) { 7834 r = getRecordForAppLocked(caller); 7835 if (r == null) { 7836 throw new SecurityException( 7837 "Unable to find app for caller " + caller 7838 + " (pid=" + Binder.getCallingPid() 7839 + ") when getting content provider " + name); 7840 } 7841 } 7842 7843 // First check if this content provider has been published... 7844 cpr = mProviderMap.getProviderByName(name, userId); 7845 boolean providerRunning = cpr != null; 7846 if (providerRunning) { 7847 cpi = cpr.info; 7848 String msg; 7849 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7850 throw new SecurityException(msg); 7851 } 7852 7853 if (r != null && cpr.canRunHere(r)) { 7854 // This provider has been published or is in the process 7855 // of being published... but it is also allowed to run 7856 // in the caller's process, so don't make a connection 7857 // and just let the caller instantiate its own instance. 7858 ContentProviderHolder holder = cpr.newHolder(null); 7859 // don't give caller the provider object, it needs 7860 // to make its own. 7861 holder.provider = null; 7862 return holder; 7863 } 7864 7865 final long origId = Binder.clearCallingIdentity(); 7866 7867 // In this case the provider instance already exists, so we can 7868 // return it right away. 7869 conn = incProviderCountLocked(r, cpr, token, stable); 7870 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7871 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7872 // If this is a perceptible app accessing the provider, 7873 // make sure to count it as being accessed and thus 7874 // back up on the LRU list. This is good because 7875 // content providers are often expensive to start. 7876 updateLruProcessLocked(cpr.proc, false, null); 7877 } 7878 } 7879 7880 if (cpr.proc != null) { 7881 if (false) { 7882 if (cpr.name.flattenToShortString().equals( 7883 "com.android.providers.calendar/.CalendarProvider2")) { 7884 Slog.v(TAG, "****************** KILLING " 7885 + cpr.name.flattenToShortString()); 7886 Process.killProcess(cpr.proc.pid); 7887 } 7888 } 7889 boolean success = updateOomAdjLocked(cpr.proc); 7890 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7891 // NOTE: there is still a race here where a signal could be 7892 // pending on the process even though we managed to update its 7893 // adj level. Not sure what to do about this, but at least 7894 // the race is now smaller. 7895 if (!success) { 7896 // Uh oh... it looks like the provider's process 7897 // has been killed on us. We need to wait for a new 7898 // process to be started, and make sure its death 7899 // doesn't kill our process. 7900 Slog.i(TAG, 7901 "Existing provider " + cpr.name.flattenToShortString() 7902 + " is crashing; detaching " + r); 7903 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7904 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7905 if (!lastRef) { 7906 // This wasn't the last ref our process had on 7907 // the provider... we have now been killed, bail. 7908 return null; 7909 } 7910 providerRunning = false; 7911 conn = null; 7912 } 7913 } 7914 7915 Binder.restoreCallingIdentity(origId); 7916 } 7917 7918 boolean singleton; 7919 if (!providerRunning) { 7920 try { 7921 cpi = AppGlobals.getPackageManager(). 7922 resolveContentProvider(name, 7923 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7924 } catch (RemoteException ex) { 7925 } 7926 if (cpi == null) { 7927 return null; 7928 } 7929 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7930 cpi.name, cpi.flags); 7931 if (singleton) { 7932 userId = 0; 7933 } 7934 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7935 7936 String msg; 7937 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7938 throw new SecurityException(msg); 7939 } 7940 7941 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7942 && !cpi.processName.equals("system")) { 7943 // If this content provider does not run in the system 7944 // process, and the system is not yet ready to run other 7945 // processes, then fail fast instead of hanging. 7946 throw new IllegalArgumentException( 7947 "Attempt to launch content provider before system ready"); 7948 } 7949 7950 // Make sure that the user who owns this provider is started. If not, 7951 // we don't want to allow it to run. 7952 if (mStartedUsers.get(userId) == null) { 7953 Slog.w(TAG, "Unable to launch app " 7954 + cpi.applicationInfo.packageName + "/" 7955 + cpi.applicationInfo.uid + " for provider " 7956 + name + ": user " + userId + " is stopped"); 7957 return null; 7958 } 7959 7960 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7961 cpr = mProviderMap.getProviderByClass(comp, userId); 7962 final boolean firstClass = cpr == null; 7963 if (firstClass) { 7964 try { 7965 ApplicationInfo ai = 7966 AppGlobals.getPackageManager(). 7967 getApplicationInfo( 7968 cpi.applicationInfo.packageName, 7969 STOCK_PM_FLAGS, userId); 7970 if (ai == null) { 7971 Slog.w(TAG, "No package info for content provider " 7972 + cpi.name); 7973 return null; 7974 } 7975 ai = getAppInfoForUser(ai, userId); 7976 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7977 } catch (RemoteException ex) { 7978 // pm is in same process, this will never happen. 7979 } 7980 } 7981 7982 if (r != null && cpr.canRunHere(r)) { 7983 // If this is a multiprocess provider, then just return its 7984 // info and allow the caller to instantiate it. Only do 7985 // this if the provider is the same user as the caller's 7986 // process, or can run as root (so can be in any process). 7987 return cpr.newHolder(null); 7988 } 7989 7990 if (DEBUG_PROVIDER) { 7991 RuntimeException e = new RuntimeException("here"); 7992 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7993 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7994 } 7995 7996 // This is single process, and our app is now connecting to it. 7997 // See if we are already in the process of launching this 7998 // provider. 7999 final int N = mLaunchingProviders.size(); 8000 int i; 8001 for (i=0; i<N; i++) { 8002 if (mLaunchingProviders.get(i) == cpr) { 8003 break; 8004 } 8005 } 8006 8007 // If the provider is not already being launched, then get it 8008 // started. 8009 if (i >= N) { 8010 final long origId = Binder.clearCallingIdentity(); 8011 8012 try { 8013 // Content provider is now in use, its package can't be stopped. 8014 try { 8015 AppGlobals.getPackageManager().setPackageStoppedState( 8016 cpr.appInfo.packageName, false, userId); 8017 } catch (RemoteException e) { 8018 } catch (IllegalArgumentException e) { 8019 Slog.w(TAG, "Failed trying to unstop package " 8020 + cpr.appInfo.packageName + ": " + e); 8021 } 8022 8023 // Use existing process if already started 8024 ProcessRecord proc = getProcessRecordLocked( 8025 cpi.processName, cpr.appInfo.uid, false); 8026 if (proc != null && proc.thread != null) { 8027 if (DEBUG_PROVIDER) { 8028 Slog.d(TAG, "Installing in existing process " + proc); 8029 } 8030 proc.pubProviders.put(cpi.name, cpr); 8031 try { 8032 proc.thread.scheduleInstallProvider(cpi); 8033 } catch (RemoteException e) { 8034 } 8035 } else { 8036 proc = startProcessLocked(cpi.processName, 8037 cpr.appInfo, false, 0, "content provider", 8038 new ComponentName(cpi.applicationInfo.packageName, 8039 cpi.name), false, false, false); 8040 if (proc == null) { 8041 Slog.w(TAG, "Unable to launch app " 8042 + cpi.applicationInfo.packageName + "/" 8043 + cpi.applicationInfo.uid + " for provider " 8044 + name + ": process is bad"); 8045 return null; 8046 } 8047 } 8048 cpr.launchingApp = proc; 8049 mLaunchingProviders.add(cpr); 8050 } finally { 8051 Binder.restoreCallingIdentity(origId); 8052 } 8053 } 8054 8055 // Make sure the provider is published (the same provider class 8056 // may be published under multiple names). 8057 if (firstClass) { 8058 mProviderMap.putProviderByClass(comp, cpr); 8059 } 8060 8061 mProviderMap.putProviderByName(name, cpr); 8062 conn = incProviderCountLocked(r, cpr, token, stable); 8063 if (conn != null) { 8064 conn.waiting = true; 8065 } 8066 } 8067 } 8068 8069 // Wait for the provider to be published... 8070 synchronized (cpr) { 8071 while (cpr.provider == null) { 8072 if (cpr.launchingApp == null) { 8073 Slog.w(TAG, "Unable to launch app " 8074 + cpi.applicationInfo.packageName + "/" 8075 + cpi.applicationInfo.uid + " for provider " 8076 + name + ": launching app became null"); 8077 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8078 UserHandle.getUserId(cpi.applicationInfo.uid), 8079 cpi.applicationInfo.packageName, 8080 cpi.applicationInfo.uid, name); 8081 return null; 8082 } 8083 try { 8084 if (DEBUG_MU) { 8085 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8086 + cpr.launchingApp); 8087 } 8088 if (conn != null) { 8089 conn.waiting = true; 8090 } 8091 cpr.wait(); 8092 } catch (InterruptedException ex) { 8093 } finally { 8094 if (conn != null) { 8095 conn.waiting = false; 8096 } 8097 } 8098 } 8099 } 8100 return cpr != null ? cpr.newHolder(conn) : null; 8101 } 8102 8103 public final ContentProviderHolder getContentProvider( 8104 IApplicationThread caller, String name, int userId, boolean stable) { 8105 enforceNotIsolatedCaller("getContentProvider"); 8106 if (caller == null) { 8107 String msg = "null IApplicationThread when getting content provider " 8108 + name; 8109 Slog.w(TAG, msg); 8110 throw new SecurityException(msg); 8111 } 8112 8113 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8114 false, true, "getContentProvider", null); 8115 return getContentProviderImpl(caller, name, null, stable, userId); 8116 } 8117 8118 public ContentProviderHolder getContentProviderExternal( 8119 String name, int userId, IBinder token) { 8120 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8121 "Do not have permission in call getContentProviderExternal()"); 8122 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8123 false, true, "getContentProvider", null); 8124 return getContentProviderExternalUnchecked(name, token, userId); 8125 } 8126 8127 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8128 IBinder token, int userId) { 8129 return getContentProviderImpl(null, name, token, true, userId); 8130 } 8131 8132 /** 8133 * Drop a content provider from a ProcessRecord's bookkeeping 8134 */ 8135 public void removeContentProvider(IBinder connection, boolean stable) { 8136 enforceNotIsolatedCaller("removeContentProvider"); 8137 long ident = Binder.clearCallingIdentity(); 8138 try { 8139 synchronized (this) { 8140 ContentProviderConnection conn; 8141 try { 8142 conn = (ContentProviderConnection)connection; 8143 } catch (ClassCastException e) { 8144 String msg ="removeContentProvider: " + connection 8145 + " not a ContentProviderConnection"; 8146 Slog.w(TAG, msg); 8147 throw new IllegalArgumentException(msg); 8148 } 8149 if (conn == null) { 8150 throw new NullPointerException("connection is null"); 8151 } 8152 if (decProviderCountLocked(conn, null, null, stable)) { 8153 updateOomAdjLocked(); 8154 } 8155 } 8156 } finally { 8157 Binder.restoreCallingIdentity(ident); 8158 } 8159 } 8160 8161 public void removeContentProviderExternal(String name, IBinder token) { 8162 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8163 "Do not have permission in call removeContentProviderExternal()"); 8164 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8165 } 8166 8167 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8168 synchronized (this) { 8169 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8170 if(cpr == null) { 8171 //remove from mProvidersByClass 8172 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8173 return; 8174 } 8175 8176 //update content provider record entry info 8177 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8178 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8179 if (localCpr.hasExternalProcessHandles()) { 8180 if (localCpr.removeExternalProcessHandleLocked(token)) { 8181 updateOomAdjLocked(); 8182 } else { 8183 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8184 + " with no external reference for token: " 8185 + token + "."); 8186 } 8187 } else { 8188 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8189 + " with no external references."); 8190 } 8191 } 8192 } 8193 8194 public final void publishContentProviders(IApplicationThread caller, 8195 List<ContentProviderHolder> providers) { 8196 if (providers == null) { 8197 return; 8198 } 8199 8200 enforceNotIsolatedCaller("publishContentProviders"); 8201 synchronized (this) { 8202 final ProcessRecord r = getRecordForAppLocked(caller); 8203 if (DEBUG_MU) 8204 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8205 if (r == null) { 8206 throw new SecurityException( 8207 "Unable to find app for caller " + caller 8208 + " (pid=" + Binder.getCallingPid() 8209 + ") when publishing content providers"); 8210 } 8211 8212 final long origId = Binder.clearCallingIdentity(); 8213 8214 final int N = providers.size(); 8215 for (int i=0; i<N; i++) { 8216 ContentProviderHolder src = providers.get(i); 8217 if (src == null || src.info == null || src.provider == null) { 8218 continue; 8219 } 8220 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8221 if (DEBUG_MU) 8222 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8223 if (dst != null) { 8224 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8225 mProviderMap.putProviderByClass(comp, dst); 8226 String names[] = dst.info.authority.split(";"); 8227 for (int j = 0; j < names.length; j++) { 8228 mProviderMap.putProviderByName(names[j], dst); 8229 } 8230 8231 int NL = mLaunchingProviders.size(); 8232 int j; 8233 for (j=0; j<NL; j++) { 8234 if (mLaunchingProviders.get(j) == dst) { 8235 mLaunchingProviders.remove(j); 8236 j--; 8237 NL--; 8238 } 8239 } 8240 synchronized (dst) { 8241 dst.provider = src.provider; 8242 dst.proc = r; 8243 dst.notifyAll(); 8244 } 8245 updateOomAdjLocked(r); 8246 } 8247 } 8248 8249 Binder.restoreCallingIdentity(origId); 8250 } 8251 } 8252 8253 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8254 ContentProviderConnection conn; 8255 try { 8256 conn = (ContentProviderConnection)connection; 8257 } catch (ClassCastException e) { 8258 String msg ="refContentProvider: " + connection 8259 + " not a ContentProviderConnection"; 8260 Slog.w(TAG, msg); 8261 throw new IllegalArgumentException(msg); 8262 } 8263 if (conn == null) { 8264 throw new NullPointerException("connection is null"); 8265 } 8266 8267 synchronized (this) { 8268 if (stable > 0) { 8269 conn.numStableIncs += stable; 8270 } 8271 stable = conn.stableCount + stable; 8272 if (stable < 0) { 8273 throw new IllegalStateException("stableCount < 0: " + stable); 8274 } 8275 8276 if (unstable > 0) { 8277 conn.numUnstableIncs += unstable; 8278 } 8279 unstable = conn.unstableCount + unstable; 8280 if (unstable < 0) { 8281 throw new IllegalStateException("unstableCount < 0: " + unstable); 8282 } 8283 8284 if ((stable+unstable) <= 0) { 8285 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8286 + stable + " unstable=" + unstable); 8287 } 8288 conn.stableCount = stable; 8289 conn.unstableCount = unstable; 8290 return !conn.dead; 8291 } 8292 } 8293 8294 public void unstableProviderDied(IBinder connection) { 8295 ContentProviderConnection conn; 8296 try { 8297 conn = (ContentProviderConnection)connection; 8298 } catch (ClassCastException e) { 8299 String msg ="refContentProvider: " + connection 8300 + " not a ContentProviderConnection"; 8301 Slog.w(TAG, msg); 8302 throw new IllegalArgumentException(msg); 8303 } 8304 if (conn == null) { 8305 throw new NullPointerException("connection is null"); 8306 } 8307 8308 // Safely retrieve the content provider associated with the connection. 8309 IContentProvider provider; 8310 synchronized (this) { 8311 provider = conn.provider.provider; 8312 } 8313 8314 if (provider == null) { 8315 // Um, yeah, we're way ahead of you. 8316 return; 8317 } 8318 8319 // Make sure the caller is being honest with us. 8320 if (provider.asBinder().pingBinder()) { 8321 // Er, no, still looks good to us. 8322 synchronized (this) { 8323 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8324 + " says " + conn + " died, but we don't agree"); 8325 return; 8326 } 8327 } 8328 8329 // Well look at that! It's dead! 8330 synchronized (this) { 8331 if (conn.provider.provider != provider) { 8332 // But something changed... good enough. 8333 return; 8334 } 8335 8336 ProcessRecord proc = conn.provider.proc; 8337 if (proc == null || proc.thread == null) { 8338 // Seems like the process is already cleaned up. 8339 return; 8340 } 8341 8342 // As far as we're concerned, this is just like receiving a 8343 // death notification... just a bit prematurely. 8344 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8345 + ") early provider death"); 8346 final long ident = Binder.clearCallingIdentity(); 8347 try { 8348 appDiedLocked(proc, proc.pid, proc.thread); 8349 } finally { 8350 Binder.restoreCallingIdentity(ident); 8351 } 8352 } 8353 } 8354 8355 @Override 8356 public void appNotRespondingViaProvider(IBinder connection) { 8357 enforceCallingPermission( 8358 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8359 8360 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8361 if (conn == null) { 8362 Slog.w(TAG, "ContentProviderConnection is null"); 8363 return; 8364 } 8365 8366 final ProcessRecord host = conn.provider.proc; 8367 if (host == null) { 8368 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8369 return; 8370 } 8371 8372 final long token = Binder.clearCallingIdentity(); 8373 try { 8374 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8375 } finally { 8376 Binder.restoreCallingIdentity(token); 8377 } 8378 } 8379 8380 public final void installSystemProviders() { 8381 List<ProviderInfo> providers; 8382 synchronized (this) { 8383 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8384 providers = generateApplicationProvidersLocked(app); 8385 if (providers != null) { 8386 for (int i=providers.size()-1; i>=0; i--) { 8387 ProviderInfo pi = (ProviderInfo)providers.get(i); 8388 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8389 Slog.w(TAG, "Not installing system proc provider " + pi.name 8390 + ": not system .apk"); 8391 providers.remove(i); 8392 } 8393 } 8394 } 8395 } 8396 if (providers != null) { 8397 mSystemThread.installSystemProviders(providers); 8398 } 8399 8400 mCoreSettingsObserver = new CoreSettingsObserver(this); 8401 8402 mUsageStatsService.monitorPackages(); 8403 } 8404 8405 /** 8406 * Allows app to retrieve the MIME type of a URI without having permission 8407 * to access its content provider. 8408 * 8409 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8410 * 8411 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8412 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8413 */ 8414 public String getProviderMimeType(Uri uri, int userId) { 8415 enforceNotIsolatedCaller("getProviderMimeType"); 8416 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8417 userId, false, true, "getProviderMimeType", null); 8418 final String name = uri.getAuthority(); 8419 final long ident = Binder.clearCallingIdentity(); 8420 ContentProviderHolder holder = null; 8421 8422 try { 8423 holder = getContentProviderExternalUnchecked(name, null, userId); 8424 if (holder != null) { 8425 return holder.provider.getType(uri); 8426 } 8427 } catch (RemoteException e) { 8428 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8429 return null; 8430 } finally { 8431 if (holder != null) { 8432 removeContentProviderExternalUnchecked(name, null, userId); 8433 } 8434 Binder.restoreCallingIdentity(ident); 8435 } 8436 8437 return null; 8438 } 8439 8440 // ========================================================= 8441 // GLOBAL MANAGEMENT 8442 // ========================================================= 8443 8444 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8445 boolean isolated) { 8446 String proc = customProcess != null ? customProcess : info.processName; 8447 BatteryStatsImpl.Uid.Proc ps = null; 8448 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8449 int uid = info.uid; 8450 if (isolated) { 8451 int userId = UserHandle.getUserId(uid); 8452 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8453 while (true) { 8454 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8455 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8456 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8457 } 8458 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8459 mNextIsolatedProcessUid++; 8460 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8461 // No process for this uid, use it. 8462 break; 8463 } 8464 stepsLeft--; 8465 if (stepsLeft <= 0) { 8466 return null; 8467 } 8468 } 8469 } 8470 return new ProcessRecord(stats, info, proc, uid); 8471 } 8472 8473 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8474 ProcessRecord app; 8475 if (!isolated) { 8476 app = getProcessRecordLocked(info.processName, info.uid, true); 8477 } else { 8478 app = null; 8479 } 8480 8481 if (app == null) { 8482 app = newProcessRecordLocked(info, null, isolated); 8483 mProcessNames.put(info.processName, app.uid, app); 8484 if (isolated) { 8485 mIsolatedProcesses.put(app.uid, app); 8486 } 8487 updateLruProcessLocked(app, false, null); 8488 updateOomAdjLocked(); 8489 } 8490 8491 // This package really, really can not be stopped. 8492 try { 8493 AppGlobals.getPackageManager().setPackageStoppedState( 8494 info.packageName, false, UserHandle.getUserId(app.uid)); 8495 } catch (RemoteException e) { 8496 } catch (IllegalArgumentException e) { 8497 Slog.w(TAG, "Failed trying to unstop package " 8498 + info.packageName + ": " + e); 8499 } 8500 8501 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8502 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8503 app.persistent = true; 8504 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8505 } 8506 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8507 mPersistentStartingProcesses.add(app); 8508 startProcessLocked(app, "added application", app.processName); 8509 } 8510 8511 return app; 8512 } 8513 8514 public void unhandledBack() { 8515 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8516 "unhandledBack()"); 8517 8518 synchronized(this) { 8519 final long origId = Binder.clearCallingIdentity(); 8520 try { 8521 getFocusedStack().unhandledBackLocked(); 8522 } finally { 8523 Binder.restoreCallingIdentity(origId); 8524 } 8525 } 8526 } 8527 8528 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8529 enforceNotIsolatedCaller("openContentUri"); 8530 final int userId = UserHandle.getCallingUserId(); 8531 String name = uri.getAuthority(); 8532 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8533 ParcelFileDescriptor pfd = null; 8534 if (cph != null) { 8535 // We record the binder invoker's uid in thread-local storage before 8536 // going to the content provider to open the file. Later, in the code 8537 // that handles all permissions checks, we look for this uid and use 8538 // that rather than the Activity Manager's own uid. The effect is that 8539 // we do the check against the caller's permissions even though it looks 8540 // to the content provider like the Activity Manager itself is making 8541 // the request. 8542 sCallerIdentity.set(new Identity( 8543 Binder.getCallingPid(), Binder.getCallingUid())); 8544 try { 8545 pfd = cph.provider.openFile(null, uri, "r", null); 8546 } catch (FileNotFoundException e) { 8547 // do nothing; pfd will be returned null 8548 } finally { 8549 // Ensure that whatever happens, we clean up the identity state 8550 sCallerIdentity.remove(); 8551 } 8552 8553 // We've got the fd now, so we're done with the provider. 8554 removeContentProviderExternalUnchecked(name, null, userId); 8555 } else { 8556 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8557 } 8558 return pfd; 8559 } 8560 8561 // Actually is sleeping or shutting down or whatever else in the future 8562 // is an inactive state. 8563 public boolean isSleepingOrShuttingDown() { 8564 return mSleeping || mShuttingDown; 8565 } 8566 8567 void goingToSleep() { 8568 synchronized(this) { 8569 mWentToSleep = true; 8570 updateEventDispatchingLocked(); 8571 8572 if (!mSleeping) { 8573 mSleeping = true; 8574 mStackSupervisor.goingToSleepLocked(); 8575 8576 // Initialize the wake times of all processes. 8577 checkExcessivePowerUsageLocked(false); 8578 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8579 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8580 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8581 } 8582 } 8583 } 8584 8585 @Override 8586 public boolean shutdown(int timeout) { 8587 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8588 != PackageManager.PERMISSION_GRANTED) { 8589 throw new SecurityException("Requires permission " 8590 + android.Manifest.permission.SHUTDOWN); 8591 } 8592 8593 boolean timedout = false; 8594 8595 synchronized(this) { 8596 mShuttingDown = true; 8597 updateEventDispatchingLocked(); 8598 timedout = mStackSupervisor.shutdownLocked(timeout); 8599 } 8600 8601 mAppOpsService.shutdown(); 8602 mUsageStatsService.shutdown(); 8603 mBatteryStatsService.shutdown(); 8604 synchronized (this) { 8605 mProcessStats.shutdownLocked(); 8606 } 8607 8608 return timedout; 8609 } 8610 8611 public final void activitySlept(IBinder token) { 8612 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8613 8614 final long origId = Binder.clearCallingIdentity(); 8615 8616 synchronized (this) { 8617 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8618 if (r != null) { 8619 mStackSupervisor.activitySleptLocked(r); 8620 } 8621 } 8622 8623 Binder.restoreCallingIdentity(origId); 8624 } 8625 8626 void logLockScreen(String msg) { 8627 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8628 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8629 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8630 mStackSupervisor.mDismissKeyguardOnNextActivity); 8631 } 8632 8633 private void comeOutOfSleepIfNeededLocked() { 8634 if (!mWentToSleep && !mLockScreenShown) { 8635 if (mSleeping) { 8636 mSleeping = false; 8637 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8638 } 8639 } 8640 } 8641 8642 void wakingUp() { 8643 synchronized(this) { 8644 mWentToSleep = false; 8645 updateEventDispatchingLocked(); 8646 comeOutOfSleepIfNeededLocked(); 8647 } 8648 } 8649 8650 private void updateEventDispatchingLocked() { 8651 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8652 } 8653 8654 public void setLockScreenShown(boolean shown) { 8655 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8656 != PackageManager.PERMISSION_GRANTED) { 8657 throw new SecurityException("Requires permission " 8658 + android.Manifest.permission.DEVICE_POWER); 8659 } 8660 8661 synchronized(this) { 8662 long ident = Binder.clearCallingIdentity(); 8663 try { 8664 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8665 mLockScreenShown = shown; 8666 comeOutOfSleepIfNeededLocked(); 8667 } finally { 8668 Binder.restoreCallingIdentity(ident); 8669 } 8670 } 8671 } 8672 8673 public void stopAppSwitches() { 8674 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8675 != PackageManager.PERMISSION_GRANTED) { 8676 throw new SecurityException("Requires permission " 8677 + android.Manifest.permission.STOP_APP_SWITCHES); 8678 } 8679 8680 synchronized(this) { 8681 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8682 + APP_SWITCH_DELAY_TIME; 8683 mDidAppSwitch = false; 8684 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8685 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8686 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8687 } 8688 } 8689 8690 public void resumeAppSwitches() { 8691 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8692 != PackageManager.PERMISSION_GRANTED) { 8693 throw new SecurityException("Requires permission " 8694 + android.Manifest.permission.STOP_APP_SWITCHES); 8695 } 8696 8697 synchronized(this) { 8698 // Note that we don't execute any pending app switches... we will 8699 // let those wait until either the timeout, or the next start 8700 // activity request. 8701 mAppSwitchesAllowedTime = 0; 8702 } 8703 } 8704 8705 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8706 String name) { 8707 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8708 return true; 8709 } 8710 8711 final int perm = checkComponentPermission( 8712 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8713 callingUid, -1, true); 8714 if (perm == PackageManager.PERMISSION_GRANTED) { 8715 return true; 8716 } 8717 8718 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8719 return false; 8720 } 8721 8722 public void setDebugApp(String packageName, boolean waitForDebugger, 8723 boolean persistent) { 8724 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8725 "setDebugApp()"); 8726 8727 long ident = Binder.clearCallingIdentity(); 8728 try { 8729 // Note that this is not really thread safe if there are multiple 8730 // callers into it at the same time, but that's not a situation we 8731 // care about. 8732 if (persistent) { 8733 final ContentResolver resolver = mContext.getContentResolver(); 8734 Settings.Global.putString( 8735 resolver, Settings.Global.DEBUG_APP, 8736 packageName); 8737 Settings.Global.putInt( 8738 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8739 waitForDebugger ? 1 : 0); 8740 } 8741 8742 synchronized (this) { 8743 if (!persistent) { 8744 mOrigDebugApp = mDebugApp; 8745 mOrigWaitForDebugger = mWaitForDebugger; 8746 } 8747 mDebugApp = packageName; 8748 mWaitForDebugger = waitForDebugger; 8749 mDebugTransient = !persistent; 8750 if (packageName != null) { 8751 forceStopPackageLocked(packageName, -1, false, false, true, true, 8752 false, UserHandle.USER_ALL, "set debug app"); 8753 } 8754 } 8755 } finally { 8756 Binder.restoreCallingIdentity(ident); 8757 } 8758 } 8759 8760 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8761 synchronized (this) { 8762 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8763 if (!isDebuggable) { 8764 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8765 throw new SecurityException("Process not debuggable: " + app.packageName); 8766 } 8767 } 8768 8769 mOpenGlTraceApp = processName; 8770 } 8771 } 8772 8773 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8774 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8775 synchronized (this) { 8776 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8777 if (!isDebuggable) { 8778 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8779 throw new SecurityException("Process not debuggable: " + app.packageName); 8780 } 8781 } 8782 mProfileApp = processName; 8783 mProfileFile = profileFile; 8784 if (mProfileFd != null) { 8785 try { 8786 mProfileFd.close(); 8787 } catch (IOException e) { 8788 } 8789 mProfileFd = null; 8790 } 8791 mProfileFd = profileFd; 8792 mProfileType = 0; 8793 mAutoStopProfiler = autoStopProfiler; 8794 } 8795 } 8796 8797 @Override 8798 public void setAlwaysFinish(boolean enabled) { 8799 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8800 "setAlwaysFinish()"); 8801 8802 Settings.Global.putInt( 8803 mContext.getContentResolver(), 8804 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8805 8806 synchronized (this) { 8807 mAlwaysFinishActivities = enabled; 8808 } 8809 } 8810 8811 @Override 8812 public void setActivityController(IActivityController controller) { 8813 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8814 "setActivityController()"); 8815 synchronized (this) { 8816 mController = controller; 8817 Watchdog.getInstance().setActivityController(controller); 8818 } 8819 } 8820 8821 @Override 8822 public void setUserIsMonkey(boolean userIsMonkey) { 8823 synchronized (this) { 8824 synchronized (mPidsSelfLocked) { 8825 final int callingPid = Binder.getCallingPid(); 8826 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8827 if (precessRecord == null) { 8828 throw new SecurityException("Unknown process: " + callingPid); 8829 } 8830 if (precessRecord.instrumentationUiAutomationConnection == null) { 8831 throw new SecurityException("Only an instrumentation process " 8832 + "with a UiAutomation can call setUserIsMonkey"); 8833 } 8834 } 8835 mUserIsMonkey = userIsMonkey; 8836 } 8837 } 8838 8839 @Override 8840 public boolean isUserAMonkey() { 8841 synchronized (this) { 8842 // If there is a controller also implies the user is a monkey. 8843 return (mUserIsMonkey || mController != null); 8844 } 8845 } 8846 8847 public void requestBugReport() { 8848 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8849 SystemProperties.set("ctl.start", "bugreport"); 8850 } 8851 8852 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8853 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8854 } 8855 8856 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8857 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8858 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8859 } 8860 return KEY_DISPATCHING_TIMEOUT; 8861 } 8862 8863 @Override 8864 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8865 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8866 != PackageManager.PERMISSION_GRANTED) { 8867 throw new SecurityException("Requires permission " 8868 + android.Manifest.permission.FILTER_EVENTS); 8869 } 8870 ProcessRecord proc; 8871 long timeout; 8872 synchronized (this) { 8873 synchronized (mPidsSelfLocked) { 8874 proc = mPidsSelfLocked.get(pid); 8875 } 8876 timeout = getInputDispatchingTimeoutLocked(proc); 8877 } 8878 8879 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8880 return -1; 8881 } 8882 8883 return timeout; 8884 } 8885 8886 /** 8887 * Handle input dispatching timeouts. 8888 * Returns whether input dispatching should be aborted or not. 8889 */ 8890 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8891 final ActivityRecord activity, final ActivityRecord parent, 8892 final boolean aboveSystem, String reason) { 8893 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8894 != PackageManager.PERMISSION_GRANTED) { 8895 throw new SecurityException("Requires permission " 8896 + android.Manifest.permission.FILTER_EVENTS); 8897 } 8898 8899 final String annotation; 8900 if (reason == null) { 8901 annotation = "Input dispatching timed out"; 8902 } else { 8903 annotation = "Input dispatching timed out (" + reason + ")"; 8904 } 8905 8906 if (proc != null) { 8907 synchronized (this) { 8908 if (proc.debugging) { 8909 return false; 8910 } 8911 8912 if (mDidDexOpt) { 8913 // Give more time since we were dexopting. 8914 mDidDexOpt = false; 8915 return false; 8916 } 8917 8918 if (proc.instrumentationClass != null) { 8919 Bundle info = new Bundle(); 8920 info.putString("shortMsg", "keyDispatchingTimedOut"); 8921 info.putString("longMsg", annotation); 8922 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8923 return true; 8924 } 8925 } 8926 mHandler.post(new Runnable() { 8927 @Override 8928 public void run() { 8929 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8930 } 8931 }); 8932 } 8933 8934 return true; 8935 } 8936 8937 public Bundle getAssistContextExtras(int requestType) { 8938 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8939 "getAssistContextExtras()"); 8940 PendingAssistExtras pae; 8941 Bundle extras = new Bundle(); 8942 synchronized (this) { 8943 ActivityRecord activity = getFocusedStack().mResumedActivity; 8944 if (activity == null) { 8945 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8946 return null; 8947 } 8948 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8949 if (activity.app == null || activity.app.thread == null) { 8950 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8951 return extras; 8952 } 8953 if (activity.app.pid == Binder.getCallingPid()) { 8954 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8955 return extras; 8956 } 8957 pae = new PendingAssistExtras(activity); 8958 try { 8959 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8960 requestType); 8961 mPendingAssistExtras.add(pae); 8962 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8963 } catch (RemoteException e) { 8964 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8965 return extras; 8966 } 8967 } 8968 synchronized (pae) { 8969 while (!pae.haveResult) { 8970 try { 8971 pae.wait(); 8972 } catch (InterruptedException e) { 8973 } 8974 } 8975 if (pae.result != null) { 8976 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8977 } 8978 } 8979 synchronized (this) { 8980 mPendingAssistExtras.remove(pae); 8981 mHandler.removeCallbacks(pae); 8982 } 8983 return extras; 8984 } 8985 8986 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8987 PendingAssistExtras pae = (PendingAssistExtras)token; 8988 synchronized (pae) { 8989 pae.result = extras; 8990 pae.haveResult = true; 8991 pae.notifyAll(); 8992 } 8993 } 8994 8995 public void registerProcessObserver(IProcessObserver observer) { 8996 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8997 "registerProcessObserver()"); 8998 synchronized (this) { 8999 mProcessObservers.register(observer); 9000 } 9001 } 9002 9003 @Override 9004 public void unregisterProcessObserver(IProcessObserver observer) { 9005 synchronized (this) { 9006 mProcessObservers.unregister(observer); 9007 } 9008 } 9009 9010 @Override 9011 public boolean convertFromTranslucent(IBinder token) { 9012 final long origId = Binder.clearCallingIdentity(); 9013 try { 9014 synchronized (this) { 9015 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9016 if (r == null) { 9017 return false; 9018 } 9019 if (r.changeWindowTranslucency(true)) { 9020 mWindowManager.setAppFullscreen(token, true); 9021 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9022 return true; 9023 } 9024 return false; 9025 } 9026 } finally { 9027 Binder.restoreCallingIdentity(origId); 9028 } 9029 } 9030 9031 @Override 9032 public boolean convertToTranslucent(IBinder token) { 9033 final long origId = Binder.clearCallingIdentity(); 9034 try { 9035 synchronized (this) { 9036 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9037 if (r == null) { 9038 return false; 9039 } 9040 if (r.changeWindowTranslucency(false)) { 9041 r.task.stack.convertToTranslucent(r); 9042 mWindowManager.setAppFullscreen(token, false); 9043 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9044 return true; 9045 } 9046 return false; 9047 } 9048 } finally { 9049 Binder.restoreCallingIdentity(origId); 9050 } 9051 } 9052 9053 @Override 9054 public void setImmersive(IBinder token, boolean immersive) { 9055 synchronized(this) { 9056 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9057 if (r == null) { 9058 throw new IllegalArgumentException(); 9059 } 9060 r.immersive = immersive; 9061 9062 // update associated state if we're frontmost 9063 if (r == mFocusedActivity) { 9064 if (DEBUG_IMMERSIVE) { 9065 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9066 } 9067 applyUpdateLockStateLocked(r); 9068 } 9069 } 9070 } 9071 9072 @Override 9073 public boolean isImmersive(IBinder token) { 9074 synchronized (this) { 9075 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9076 if (r == null) { 9077 throw new IllegalArgumentException(); 9078 } 9079 return r.immersive; 9080 } 9081 } 9082 9083 public boolean isTopActivityImmersive() { 9084 enforceNotIsolatedCaller("startActivity"); 9085 synchronized (this) { 9086 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9087 return (r != null) ? r.immersive : false; 9088 } 9089 } 9090 9091 public final void enterSafeMode() { 9092 synchronized(this) { 9093 // It only makes sense to do this before the system is ready 9094 // and started launching other packages. 9095 if (!mSystemReady) { 9096 try { 9097 AppGlobals.getPackageManager().enterSafeMode(); 9098 } catch (RemoteException e) { 9099 } 9100 } 9101 9102 mSafeMode = true; 9103 } 9104 } 9105 9106 public final void showSafeModeOverlay() { 9107 View v = LayoutInflater.from(mContext).inflate( 9108 com.android.internal.R.layout.safe_mode, null); 9109 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9110 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9111 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9112 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9113 lp.gravity = Gravity.BOTTOM | Gravity.START; 9114 lp.format = v.getBackground().getOpacity(); 9115 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9116 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9117 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9118 ((WindowManager)mContext.getSystemService( 9119 Context.WINDOW_SERVICE)).addView(v, lp); 9120 } 9121 9122 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9123 if (!(sender instanceof PendingIntentRecord)) { 9124 return; 9125 } 9126 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9127 synchronized (stats) { 9128 if (mBatteryStatsService.isOnBattery()) { 9129 mBatteryStatsService.enforceCallingPermission(); 9130 PendingIntentRecord rec = (PendingIntentRecord)sender; 9131 int MY_UID = Binder.getCallingUid(); 9132 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9133 BatteryStatsImpl.Uid.Pkg pkg = 9134 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9135 sourcePkg != null ? sourcePkg : rec.key.packageName); 9136 pkg.incWakeupsLocked(); 9137 } 9138 } 9139 } 9140 9141 public boolean killPids(int[] pids, String pReason, boolean secure) { 9142 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9143 throw new SecurityException("killPids only available to the system"); 9144 } 9145 String reason = (pReason == null) ? "Unknown" : pReason; 9146 // XXX Note: don't acquire main activity lock here, because the window 9147 // manager calls in with its locks held. 9148 9149 boolean killed = false; 9150 synchronized (mPidsSelfLocked) { 9151 int[] types = new int[pids.length]; 9152 int worstType = 0; 9153 for (int i=0; i<pids.length; i++) { 9154 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9155 if (proc != null) { 9156 int type = proc.setAdj; 9157 types[i] = type; 9158 if (type > worstType) { 9159 worstType = type; 9160 } 9161 } 9162 } 9163 9164 // If the worst oom_adj is somewhere in the cached proc LRU range, 9165 // then constrain it so we will kill all cached procs. 9166 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9167 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9168 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9169 } 9170 9171 // If this is not a secure call, don't let it kill processes that 9172 // are important. 9173 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9174 worstType = ProcessList.SERVICE_ADJ; 9175 } 9176 9177 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9178 for (int i=0; i<pids.length; i++) { 9179 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9180 if (proc == null) { 9181 continue; 9182 } 9183 int adj = proc.setAdj; 9184 if (adj >= worstType && !proc.killedByAm) { 9185 killUnneededProcessLocked(proc, reason); 9186 killed = true; 9187 } 9188 } 9189 } 9190 return killed; 9191 } 9192 9193 @Override 9194 public void killUid(int uid, String reason) { 9195 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9196 throw new SecurityException("killUid only available to the system"); 9197 } 9198 synchronized (this) { 9199 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9200 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9201 reason != null ? reason : "kill uid"); 9202 } 9203 } 9204 9205 @Override 9206 public boolean killProcessesBelowForeground(String reason) { 9207 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9208 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9209 } 9210 9211 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9212 } 9213 9214 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9215 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9216 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9217 } 9218 9219 boolean killed = false; 9220 synchronized (mPidsSelfLocked) { 9221 final int size = mPidsSelfLocked.size(); 9222 for (int i = 0; i < size; i++) { 9223 final int pid = mPidsSelfLocked.keyAt(i); 9224 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9225 if (proc == null) continue; 9226 9227 final int adj = proc.setAdj; 9228 if (adj > belowAdj && !proc.killedByAm) { 9229 killUnneededProcessLocked(proc, reason); 9230 killed = true; 9231 } 9232 } 9233 } 9234 return killed; 9235 } 9236 9237 @Override 9238 public void hang(final IBinder who, boolean allowRestart) { 9239 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9240 != PackageManager.PERMISSION_GRANTED) { 9241 throw new SecurityException("Requires permission " 9242 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9243 } 9244 9245 final IBinder.DeathRecipient death = new DeathRecipient() { 9246 @Override 9247 public void binderDied() { 9248 synchronized (this) { 9249 notifyAll(); 9250 } 9251 } 9252 }; 9253 9254 try { 9255 who.linkToDeath(death, 0); 9256 } catch (RemoteException e) { 9257 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9258 return; 9259 } 9260 9261 synchronized (this) { 9262 Watchdog.getInstance().setAllowRestart(allowRestart); 9263 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9264 synchronized (death) { 9265 while (who.isBinderAlive()) { 9266 try { 9267 death.wait(); 9268 } catch (InterruptedException e) { 9269 } 9270 } 9271 } 9272 Watchdog.getInstance().setAllowRestart(true); 9273 } 9274 } 9275 9276 @Override 9277 public void restart() { 9278 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9279 != PackageManager.PERMISSION_GRANTED) { 9280 throw new SecurityException("Requires permission " 9281 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9282 } 9283 9284 Log.i(TAG, "Sending shutdown broadcast..."); 9285 9286 BroadcastReceiver br = new BroadcastReceiver() { 9287 @Override public void onReceive(Context context, Intent intent) { 9288 // Now the broadcast is done, finish up the low-level shutdown. 9289 Log.i(TAG, "Shutting down activity manager..."); 9290 shutdown(10000); 9291 Log.i(TAG, "Shutdown complete, restarting!"); 9292 Process.killProcess(Process.myPid()); 9293 System.exit(10); 9294 } 9295 }; 9296 9297 // First send the high-level shut down broadcast. 9298 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9299 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9300 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9301 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9302 mContext.sendOrderedBroadcastAsUser(intent, 9303 UserHandle.ALL, null, br, mHandler, 0, null, null); 9304 */ 9305 br.onReceive(mContext, intent); 9306 } 9307 9308 private long getLowRamTimeSinceIdle(long now) { 9309 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9310 } 9311 9312 @Override 9313 public void performIdleMaintenance() { 9314 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9315 != PackageManager.PERMISSION_GRANTED) { 9316 throw new SecurityException("Requires permission " 9317 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9318 } 9319 9320 synchronized (this) { 9321 final long now = SystemClock.uptimeMillis(); 9322 final long timeSinceLastIdle = now - mLastIdleTime; 9323 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9324 mLastIdleTime = now; 9325 mLowRamTimeSinceLastIdle = 0; 9326 if (mLowRamStartTime != 0) { 9327 mLowRamStartTime = now; 9328 } 9329 9330 StringBuilder sb = new StringBuilder(128); 9331 sb.append("Idle maintenance over "); 9332 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9333 sb.append(" low RAM for "); 9334 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9335 Slog.i(TAG, sb.toString()); 9336 9337 // If at least 1/3 of our time since the last idle period has been spent 9338 // with RAM low, then we want to kill processes. 9339 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9340 9341 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9342 ProcessRecord proc = mLruProcesses.get(i); 9343 if (proc.notCachedSinceIdle) { 9344 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9345 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9346 if (doKilling && proc.initialIdlePss != 0 9347 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9348 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9349 + " from " + proc.initialIdlePss + ")"); 9350 } 9351 } 9352 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9353 proc.notCachedSinceIdle = true; 9354 proc.initialIdlePss = 0; 9355 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9356 mSleeping, now); 9357 } 9358 } 9359 9360 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9361 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9362 } 9363 } 9364 9365 private void retrieveSettings() { 9366 final ContentResolver resolver = mContext.getContentResolver(); 9367 String debugApp = Settings.Global.getString( 9368 resolver, Settings.Global.DEBUG_APP); 9369 boolean waitForDebugger = Settings.Global.getInt( 9370 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9371 boolean alwaysFinishActivities = Settings.Global.getInt( 9372 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9373 boolean forceRtl = Settings.Global.getInt( 9374 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9375 // Transfer any global setting for forcing RTL layout, into a System Property 9376 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9377 9378 Configuration configuration = new Configuration(); 9379 Settings.System.getConfiguration(resolver, configuration); 9380 if (forceRtl) { 9381 // This will take care of setting the correct layout direction flags 9382 configuration.setLayoutDirection(configuration.locale); 9383 } 9384 9385 synchronized (this) { 9386 mDebugApp = mOrigDebugApp = debugApp; 9387 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9388 mAlwaysFinishActivities = alwaysFinishActivities; 9389 // This happens before any activities are started, so we can 9390 // change mConfiguration in-place. 9391 updateConfigurationLocked(configuration, null, false, true); 9392 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9393 } 9394 } 9395 9396 public boolean testIsSystemReady() { 9397 // no need to synchronize(this) just to read & return the value 9398 return mSystemReady; 9399 } 9400 9401 private static File getCalledPreBootReceiversFile() { 9402 File dataDir = Environment.getDataDirectory(); 9403 File systemDir = new File(dataDir, "system"); 9404 File fname = new File(systemDir, "called_pre_boots.dat"); 9405 return fname; 9406 } 9407 9408 static final int LAST_DONE_VERSION = 10000; 9409 9410 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9411 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9412 File file = getCalledPreBootReceiversFile(); 9413 FileInputStream fis = null; 9414 try { 9415 fis = new FileInputStream(file); 9416 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9417 int fvers = dis.readInt(); 9418 if (fvers == LAST_DONE_VERSION) { 9419 String vers = dis.readUTF(); 9420 String codename = dis.readUTF(); 9421 String build = dis.readUTF(); 9422 if (android.os.Build.VERSION.RELEASE.equals(vers) 9423 && android.os.Build.VERSION.CODENAME.equals(codename) 9424 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9425 int num = dis.readInt(); 9426 while (num > 0) { 9427 num--; 9428 String pkg = dis.readUTF(); 9429 String cls = dis.readUTF(); 9430 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9431 } 9432 } 9433 } 9434 } catch (FileNotFoundException e) { 9435 } catch (IOException e) { 9436 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9437 } finally { 9438 if (fis != null) { 9439 try { 9440 fis.close(); 9441 } catch (IOException e) { 9442 } 9443 } 9444 } 9445 return lastDoneReceivers; 9446 } 9447 9448 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9449 File file = getCalledPreBootReceiversFile(); 9450 FileOutputStream fos = null; 9451 DataOutputStream dos = null; 9452 try { 9453 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9454 fos = new FileOutputStream(file); 9455 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9456 dos.writeInt(LAST_DONE_VERSION); 9457 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9458 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9459 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9460 dos.writeInt(list.size()); 9461 for (int i=0; i<list.size(); i++) { 9462 dos.writeUTF(list.get(i).getPackageName()); 9463 dos.writeUTF(list.get(i).getClassName()); 9464 } 9465 } catch (IOException e) { 9466 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9467 file.delete(); 9468 } finally { 9469 FileUtils.sync(fos); 9470 if (dos != null) { 9471 try { 9472 dos.close(); 9473 } catch (IOException e) { 9474 // TODO Auto-generated catch block 9475 e.printStackTrace(); 9476 } 9477 } 9478 } 9479 } 9480 9481 public void systemReady(final Runnable goingCallback) { 9482 synchronized(this) { 9483 if (mSystemReady) { 9484 if (goingCallback != null) goingCallback.run(); 9485 return; 9486 } 9487 9488 // Check to see if there are any update receivers to run. 9489 if (!mDidUpdate) { 9490 if (mWaitingUpdate) { 9491 return; 9492 } 9493 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9494 List<ResolveInfo> ris = null; 9495 try { 9496 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9497 intent, null, 0, 0); 9498 } catch (RemoteException e) { 9499 } 9500 if (ris != null) { 9501 for (int i=ris.size()-1; i>=0; i--) { 9502 if ((ris.get(i).activityInfo.applicationInfo.flags 9503 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9504 ris.remove(i); 9505 } 9506 } 9507 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9508 9509 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9510 9511 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9512 for (int i=0; i<ris.size(); i++) { 9513 ActivityInfo ai = ris.get(i).activityInfo; 9514 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9515 if (lastDoneReceivers.contains(comp)) { 9516 // We already did the pre boot receiver for this app with the current 9517 // platform version, so don't do it again... 9518 ris.remove(i); 9519 i--; 9520 // ...however, do keep it as one that has been done, so we don't 9521 // forget about it when rewriting the file of last done receivers. 9522 doneReceivers.add(comp); 9523 } 9524 } 9525 9526 final int[] users = getUsersLocked(); 9527 for (int i=0; i<ris.size(); i++) { 9528 ActivityInfo ai = ris.get(i).activityInfo; 9529 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9530 doneReceivers.add(comp); 9531 intent.setComponent(comp); 9532 for (int j=0; j<users.length; j++) { 9533 IIntentReceiver finisher = null; 9534 if (i == ris.size()-1 && j == users.length-1) { 9535 finisher = new IIntentReceiver.Stub() { 9536 public void performReceive(Intent intent, int resultCode, 9537 String data, Bundle extras, boolean ordered, 9538 boolean sticky, int sendingUser) { 9539 // The raw IIntentReceiver interface is called 9540 // with the AM lock held, so redispatch to 9541 // execute our code without the lock. 9542 mHandler.post(new Runnable() { 9543 public void run() { 9544 synchronized (ActivityManagerService.this) { 9545 mDidUpdate = true; 9546 } 9547 writeLastDonePreBootReceivers(doneReceivers); 9548 showBootMessage(mContext.getText( 9549 R.string.android_upgrading_complete), 9550 false); 9551 systemReady(goingCallback); 9552 } 9553 }); 9554 } 9555 }; 9556 } 9557 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9558 + " for user " + users[j]); 9559 broadcastIntentLocked(null, null, intent, null, finisher, 9560 0, null, null, null, AppOpsManager.OP_NONE, 9561 true, false, MY_PID, Process.SYSTEM_UID, 9562 users[j]); 9563 if (finisher != null) { 9564 mWaitingUpdate = true; 9565 } 9566 } 9567 } 9568 } 9569 if (mWaitingUpdate) { 9570 return; 9571 } 9572 mDidUpdate = true; 9573 } 9574 9575 mAppOpsService.systemReady(); 9576 mSystemReady = true; 9577 } 9578 9579 ArrayList<ProcessRecord> procsToKill = null; 9580 synchronized(mPidsSelfLocked) { 9581 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9582 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9583 if (!isAllowedWhileBooting(proc.info)){ 9584 if (procsToKill == null) { 9585 procsToKill = new ArrayList<ProcessRecord>(); 9586 } 9587 procsToKill.add(proc); 9588 } 9589 } 9590 } 9591 9592 synchronized(this) { 9593 if (procsToKill != null) { 9594 for (int i=procsToKill.size()-1; i>=0; i--) { 9595 ProcessRecord proc = procsToKill.get(i); 9596 Slog.i(TAG, "Removing system update proc: " + proc); 9597 removeProcessLocked(proc, true, false, "system update done"); 9598 } 9599 } 9600 9601 // Now that we have cleaned up any update processes, we 9602 // are ready to start launching real processes and know that 9603 // we won't trample on them any more. 9604 mProcessesReady = true; 9605 } 9606 9607 Slog.i(TAG, "System now ready"); 9608 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9609 SystemClock.uptimeMillis()); 9610 9611 synchronized(this) { 9612 // Make sure we have no pre-ready processes sitting around. 9613 9614 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9615 ResolveInfo ri = mContext.getPackageManager() 9616 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9617 STOCK_PM_FLAGS); 9618 CharSequence errorMsg = null; 9619 if (ri != null) { 9620 ActivityInfo ai = ri.activityInfo; 9621 ApplicationInfo app = ai.applicationInfo; 9622 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9623 mTopAction = Intent.ACTION_FACTORY_TEST; 9624 mTopData = null; 9625 mTopComponent = new ComponentName(app.packageName, 9626 ai.name); 9627 } else { 9628 errorMsg = mContext.getResources().getText( 9629 com.android.internal.R.string.factorytest_not_system); 9630 } 9631 } else { 9632 errorMsg = mContext.getResources().getText( 9633 com.android.internal.R.string.factorytest_no_action); 9634 } 9635 if (errorMsg != null) { 9636 mTopAction = null; 9637 mTopData = null; 9638 mTopComponent = null; 9639 Message msg = Message.obtain(); 9640 msg.what = SHOW_FACTORY_ERROR_MSG; 9641 msg.getData().putCharSequence("msg", errorMsg); 9642 mHandler.sendMessage(msg); 9643 } 9644 } 9645 } 9646 9647 retrieveSettings(); 9648 9649 synchronized (this) { 9650 readGrantedUriPermissionsLocked(); 9651 } 9652 9653 if (goingCallback != null) goingCallback.run(); 9654 9655 synchronized (this) { 9656 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9657 try { 9658 List apps = AppGlobals.getPackageManager(). 9659 getPersistentApplications(STOCK_PM_FLAGS); 9660 if (apps != null) { 9661 int N = apps.size(); 9662 int i; 9663 for (i=0; i<N; i++) { 9664 ApplicationInfo info 9665 = (ApplicationInfo)apps.get(i); 9666 if (info != null && 9667 !info.packageName.equals("android")) { 9668 addAppLocked(info, false); 9669 } 9670 } 9671 } 9672 } catch (RemoteException ex) { 9673 // pm is in same process, this will never happen. 9674 } 9675 } 9676 9677 // Start up initial activity. 9678 mBooting = true; 9679 9680 try { 9681 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9682 Message msg = Message.obtain(); 9683 msg.what = SHOW_UID_ERROR_MSG; 9684 mHandler.sendMessage(msg); 9685 } 9686 } catch (RemoteException e) { 9687 } 9688 9689 long ident = Binder.clearCallingIdentity(); 9690 try { 9691 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9692 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9693 | Intent.FLAG_RECEIVER_FOREGROUND); 9694 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9695 broadcastIntentLocked(null, null, intent, 9696 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9697 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9698 intent = new Intent(Intent.ACTION_USER_STARTING); 9699 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9700 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9701 broadcastIntentLocked(null, null, intent, 9702 null, new IIntentReceiver.Stub() { 9703 @Override 9704 public void performReceive(Intent intent, int resultCode, String data, 9705 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9706 throws RemoteException { 9707 } 9708 }, 0, null, null, 9709 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9710 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9711 } finally { 9712 Binder.restoreCallingIdentity(ident); 9713 } 9714 mStackSupervisor.resumeTopActivitiesLocked(); 9715 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9716 } 9717 } 9718 9719 private boolean makeAppCrashingLocked(ProcessRecord app, 9720 String shortMsg, String longMsg, String stackTrace) { 9721 app.crashing = true; 9722 app.crashingReport = generateProcessError(app, 9723 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9724 startAppProblemLocked(app); 9725 app.stopFreezingAllLocked(); 9726 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9727 } 9728 9729 private void makeAppNotRespondingLocked(ProcessRecord app, 9730 String activity, String shortMsg, String longMsg) { 9731 app.notResponding = true; 9732 app.notRespondingReport = generateProcessError(app, 9733 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9734 activity, shortMsg, longMsg, null); 9735 startAppProblemLocked(app); 9736 app.stopFreezingAllLocked(); 9737 } 9738 9739 /** 9740 * Generate a process error record, suitable for attachment to a ProcessRecord. 9741 * 9742 * @param app The ProcessRecord in which the error occurred. 9743 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9744 * ActivityManager.AppErrorStateInfo 9745 * @param activity The activity associated with the crash, if known. 9746 * @param shortMsg Short message describing the crash. 9747 * @param longMsg Long message describing the crash. 9748 * @param stackTrace Full crash stack trace, may be null. 9749 * 9750 * @return Returns a fully-formed AppErrorStateInfo record. 9751 */ 9752 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9753 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9754 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9755 9756 report.condition = condition; 9757 report.processName = app.processName; 9758 report.pid = app.pid; 9759 report.uid = app.info.uid; 9760 report.tag = activity; 9761 report.shortMsg = shortMsg; 9762 report.longMsg = longMsg; 9763 report.stackTrace = stackTrace; 9764 9765 return report; 9766 } 9767 9768 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9769 synchronized (this) { 9770 app.crashing = false; 9771 app.crashingReport = null; 9772 app.notResponding = false; 9773 app.notRespondingReport = null; 9774 if (app.anrDialog == fromDialog) { 9775 app.anrDialog = null; 9776 } 9777 if (app.waitDialog == fromDialog) { 9778 app.waitDialog = null; 9779 } 9780 if (app.pid > 0 && app.pid != MY_PID) { 9781 handleAppCrashLocked(app, null, null, null); 9782 killUnneededProcessLocked(app, "user request after error"); 9783 } 9784 } 9785 } 9786 9787 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9788 String stackTrace) { 9789 long now = SystemClock.uptimeMillis(); 9790 9791 Long crashTime; 9792 if (!app.isolated) { 9793 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9794 } else { 9795 crashTime = null; 9796 } 9797 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9798 // This process loses! 9799 Slog.w(TAG, "Process " + app.info.processName 9800 + " has crashed too many times: killing!"); 9801 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9802 app.userId, app.info.processName, app.uid); 9803 mStackSupervisor.handleAppCrashLocked(app); 9804 if (!app.persistent) { 9805 // We don't want to start this process again until the user 9806 // explicitly does so... but for persistent process, we really 9807 // need to keep it running. If a persistent process is actually 9808 // repeatedly crashing, then badness for everyone. 9809 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9810 app.info.processName); 9811 if (!app.isolated) { 9812 // XXX We don't have a way to mark isolated processes 9813 // as bad, since they don't have a peristent identity. 9814 mBadProcesses.put(app.info.processName, app.uid, 9815 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9816 mProcessCrashTimes.remove(app.info.processName, app.uid); 9817 } 9818 app.bad = true; 9819 app.removed = true; 9820 // Don't let services in this process be restarted and potentially 9821 // annoy the user repeatedly. Unless it is persistent, since those 9822 // processes run critical code. 9823 removeProcessLocked(app, false, false, "crash"); 9824 mStackSupervisor.resumeTopActivitiesLocked(); 9825 return false; 9826 } 9827 mStackSupervisor.resumeTopActivitiesLocked(); 9828 } else { 9829 mStackSupervisor.finishTopRunningActivityLocked(app); 9830 } 9831 9832 // Bump up the crash count of any services currently running in the proc. 9833 for (int i=app.services.size()-1; i>=0; i--) { 9834 // Any services running in the application need to be placed 9835 // back in the pending list. 9836 ServiceRecord sr = app.services.valueAt(i); 9837 sr.crashCount++; 9838 } 9839 9840 // If the crashing process is what we consider to be the "home process" and it has been 9841 // replaced by a third-party app, clear the package preferred activities from packages 9842 // with a home activity running in the process to prevent a repeatedly crashing app 9843 // from blocking the user to manually clear the list. 9844 final ArrayList<ActivityRecord> activities = app.activities; 9845 if (app == mHomeProcess && activities.size() > 0 9846 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9847 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9848 final ActivityRecord r = activities.get(activityNdx); 9849 if (r.isHomeActivity()) { 9850 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9851 try { 9852 ActivityThread.getPackageManager() 9853 .clearPackagePreferredActivities(r.packageName); 9854 } catch (RemoteException c) { 9855 // pm is in same process, this will never happen. 9856 } 9857 } 9858 } 9859 } 9860 9861 if (!app.isolated) { 9862 // XXX Can't keep track of crash times for isolated processes, 9863 // because they don't have a perisistent identity. 9864 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9865 } 9866 9867 return true; 9868 } 9869 9870 void startAppProblemLocked(ProcessRecord app) { 9871 if (app.userId == mCurrentUserId) { 9872 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9873 mContext, app.info.packageName, app.info.flags); 9874 } else { 9875 // If this app is not running under the current user, then we 9876 // can't give it a report button because that would require 9877 // launching the report UI under a different user. 9878 app.errorReportReceiver = null; 9879 } 9880 skipCurrentReceiverLocked(app); 9881 } 9882 9883 void skipCurrentReceiverLocked(ProcessRecord app) { 9884 for (BroadcastQueue queue : mBroadcastQueues) { 9885 queue.skipCurrentReceiverLocked(app); 9886 } 9887 } 9888 9889 /** 9890 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9891 * The application process will exit immediately after this call returns. 9892 * @param app object of the crashing app, null for the system server 9893 * @param crashInfo describing the exception 9894 */ 9895 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9896 ProcessRecord r = findAppProcess(app, "Crash"); 9897 final String processName = app == null ? "system_server" 9898 : (r == null ? "unknown" : r.processName); 9899 9900 handleApplicationCrashInner("crash", r, processName, crashInfo); 9901 } 9902 9903 /* Native crash reporting uses this inner version because it needs to be somewhat 9904 * decoupled from the AM-managed cleanup lifecycle 9905 */ 9906 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9907 ApplicationErrorReport.CrashInfo crashInfo) { 9908 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9909 UserHandle.getUserId(Binder.getCallingUid()), processName, 9910 r == null ? -1 : r.info.flags, 9911 crashInfo.exceptionClassName, 9912 crashInfo.exceptionMessage, 9913 crashInfo.throwFileName, 9914 crashInfo.throwLineNumber); 9915 9916 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9917 9918 crashApplication(r, crashInfo); 9919 } 9920 9921 public void handleApplicationStrictModeViolation( 9922 IBinder app, 9923 int violationMask, 9924 StrictMode.ViolationInfo info) { 9925 ProcessRecord r = findAppProcess(app, "StrictMode"); 9926 if (r == null) { 9927 return; 9928 } 9929 9930 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9931 Integer stackFingerprint = info.hashCode(); 9932 boolean logIt = true; 9933 synchronized (mAlreadyLoggedViolatedStacks) { 9934 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9935 logIt = false; 9936 // TODO: sub-sample into EventLog for these, with 9937 // the info.durationMillis? Then we'd get 9938 // the relative pain numbers, without logging all 9939 // the stack traces repeatedly. We'd want to do 9940 // likewise in the client code, which also does 9941 // dup suppression, before the Binder call. 9942 } else { 9943 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9944 mAlreadyLoggedViolatedStacks.clear(); 9945 } 9946 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9947 } 9948 } 9949 if (logIt) { 9950 logStrictModeViolationToDropBox(r, info); 9951 } 9952 } 9953 9954 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9955 AppErrorResult result = new AppErrorResult(); 9956 synchronized (this) { 9957 final long origId = Binder.clearCallingIdentity(); 9958 9959 Message msg = Message.obtain(); 9960 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9961 HashMap<String, Object> data = new HashMap<String, Object>(); 9962 data.put("result", result); 9963 data.put("app", r); 9964 data.put("violationMask", violationMask); 9965 data.put("info", info); 9966 msg.obj = data; 9967 mHandler.sendMessage(msg); 9968 9969 Binder.restoreCallingIdentity(origId); 9970 } 9971 int res = result.get(); 9972 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9973 } 9974 } 9975 9976 // Depending on the policy in effect, there could be a bunch of 9977 // these in quick succession so we try to batch these together to 9978 // minimize disk writes, number of dropbox entries, and maximize 9979 // compression, by having more fewer, larger records. 9980 private void logStrictModeViolationToDropBox( 9981 ProcessRecord process, 9982 StrictMode.ViolationInfo info) { 9983 if (info == null) { 9984 return; 9985 } 9986 final boolean isSystemApp = process == null || 9987 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9988 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9989 final String processName = process == null ? "unknown" : process.processName; 9990 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9991 final DropBoxManager dbox = (DropBoxManager) 9992 mContext.getSystemService(Context.DROPBOX_SERVICE); 9993 9994 // Exit early if the dropbox isn't configured to accept this report type. 9995 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9996 9997 boolean bufferWasEmpty; 9998 boolean needsFlush; 9999 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10000 synchronized (sb) { 10001 bufferWasEmpty = sb.length() == 0; 10002 appendDropBoxProcessHeaders(process, processName, sb); 10003 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10004 sb.append("System-App: ").append(isSystemApp).append("\n"); 10005 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10006 if (info.violationNumThisLoop != 0) { 10007 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10008 } 10009 if (info.numAnimationsRunning != 0) { 10010 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10011 } 10012 if (info.broadcastIntentAction != null) { 10013 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10014 } 10015 if (info.durationMillis != -1) { 10016 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10017 } 10018 if (info.numInstances != -1) { 10019 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10020 } 10021 if (info.tags != null) { 10022 for (String tag : info.tags) { 10023 sb.append("Span-Tag: ").append(tag).append("\n"); 10024 } 10025 } 10026 sb.append("\n"); 10027 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10028 sb.append(info.crashInfo.stackTrace); 10029 } 10030 sb.append("\n"); 10031 10032 // Only buffer up to ~64k. Various logging bits truncate 10033 // things at 128k. 10034 needsFlush = (sb.length() > 64 * 1024); 10035 } 10036 10037 // Flush immediately if the buffer's grown too large, or this 10038 // is a non-system app. Non-system apps are isolated with a 10039 // different tag & policy and not batched. 10040 // 10041 // Batching is useful during internal testing with 10042 // StrictMode settings turned up high. Without batching, 10043 // thousands of separate files could be created on boot. 10044 if (!isSystemApp || needsFlush) { 10045 new Thread("Error dump: " + dropboxTag) { 10046 @Override 10047 public void run() { 10048 String report; 10049 synchronized (sb) { 10050 report = sb.toString(); 10051 sb.delete(0, sb.length()); 10052 sb.trimToSize(); 10053 } 10054 if (report.length() != 0) { 10055 dbox.addText(dropboxTag, report); 10056 } 10057 } 10058 }.start(); 10059 return; 10060 } 10061 10062 // System app batching: 10063 if (!bufferWasEmpty) { 10064 // An existing dropbox-writing thread is outstanding, so 10065 // we don't need to start it up. The existing thread will 10066 // catch the buffer appends we just did. 10067 return; 10068 } 10069 10070 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10071 // (After this point, we shouldn't access AMS internal data structures.) 10072 new Thread("Error dump: " + dropboxTag) { 10073 @Override 10074 public void run() { 10075 // 5 second sleep to let stacks arrive and be batched together 10076 try { 10077 Thread.sleep(5000); // 5 seconds 10078 } catch (InterruptedException e) {} 10079 10080 String errorReport; 10081 synchronized (mStrictModeBuffer) { 10082 errorReport = mStrictModeBuffer.toString(); 10083 if (errorReport.length() == 0) { 10084 return; 10085 } 10086 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10087 mStrictModeBuffer.trimToSize(); 10088 } 10089 dbox.addText(dropboxTag, errorReport); 10090 } 10091 }.start(); 10092 } 10093 10094 /** 10095 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10096 * @param app object of the crashing app, null for the system server 10097 * @param tag reported by the caller 10098 * @param crashInfo describing the context of the error 10099 * @return true if the process should exit immediately (WTF is fatal) 10100 */ 10101 public boolean handleApplicationWtf(IBinder app, String tag, 10102 ApplicationErrorReport.CrashInfo crashInfo) { 10103 ProcessRecord r = findAppProcess(app, "WTF"); 10104 final String processName = app == null ? "system_server" 10105 : (r == null ? "unknown" : r.processName); 10106 10107 EventLog.writeEvent(EventLogTags.AM_WTF, 10108 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10109 processName, 10110 r == null ? -1 : r.info.flags, 10111 tag, crashInfo.exceptionMessage); 10112 10113 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10114 10115 if (r != null && r.pid != Process.myPid() && 10116 Settings.Global.getInt(mContext.getContentResolver(), 10117 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10118 crashApplication(r, crashInfo); 10119 return true; 10120 } else { 10121 return false; 10122 } 10123 } 10124 10125 /** 10126 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10127 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10128 */ 10129 private ProcessRecord findAppProcess(IBinder app, String reason) { 10130 if (app == null) { 10131 return null; 10132 } 10133 10134 synchronized (this) { 10135 final int NP = mProcessNames.getMap().size(); 10136 for (int ip=0; ip<NP; ip++) { 10137 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10138 final int NA = apps.size(); 10139 for (int ia=0; ia<NA; ia++) { 10140 ProcessRecord p = apps.valueAt(ia); 10141 if (p.thread != null && p.thread.asBinder() == app) { 10142 return p; 10143 } 10144 } 10145 } 10146 10147 Slog.w(TAG, "Can't find mystery application for " + reason 10148 + " from pid=" + Binder.getCallingPid() 10149 + " uid=" + Binder.getCallingUid() + ": " + app); 10150 return null; 10151 } 10152 } 10153 10154 /** 10155 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10156 * to append various headers to the dropbox log text. 10157 */ 10158 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10159 StringBuilder sb) { 10160 // Watchdog thread ends up invoking this function (with 10161 // a null ProcessRecord) to add the stack file to dropbox. 10162 // Do not acquire a lock on this (am) in such cases, as it 10163 // could cause a potential deadlock, if and when watchdog 10164 // is invoked due to unavailability of lock on am and it 10165 // would prevent watchdog from killing system_server. 10166 if (process == null) { 10167 sb.append("Process: ").append(processName).append("\n"); 10168 return; 10169 } 10170 // Note: ProcessRecord 'process' is guarded by the service 10171 // instance. (notably process.pkgList, which could otherwise change 10172 // concurrently during execution of this method) 10173 synchronized (this) { 10174 sb.append("Process: ").append(processName).append("\n"); 10175 int flags = process.info.flags; 10176 IPackageManager pm = AppGlobals.getPackageManager(); 10177 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10178 for (int ip=0; ip<process.pkgList.size(); ip++) { 10179 String pkg = process.pkgList.keyAt(ip); 10180 sb.append("Package: ").append(pkg); 10181 try { 10182 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10183 if (pi != null) { 10184 sb.append(" v").append(pi.versionCode); 10185 if (pi.versionName != null) { 10186 sb.append(" (").append(pi.versionName).append(")"); 10187 } 10188 } 10189 } catch (RemoteException e) { 10190 Slog.e(TAG, "Error getting package info: " + pkg, e); 10191 } 10192 sb.append("\n"); 10193 } 10194 } 10195 } 10196 10197 private static String processClass(ProcessRecord process) { 10198 if (process == null || process.pid == MY_PID) { 10199 return "system_server"; 10200 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10201 return "system_app"; 10202 } else { 10203 return "data_app"; 10204 } 10205 } 10206 10207 /** 10208 * Write a description of an error (crash, WTF, ANR) to the drop box. 10209 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10210 * @param process which caused the error, null means the system server 10211 * @param activity which triggered the error, null if unknown 10212 * @param parent activity related to the error, null if unknown 10213 * @param subject line related to the error, null if absent 10214 * @param report in long form describing the error, null if absent 10215 * @param logFile to include in the report, null if none 10216 * @param crashInfo giving an application stack trace, null if absent 10217 */ 10218 public void addErrorToDropBox(String eventType, 10219 ProcessRecord process, String processName, ActivityRecord activity, 10220 ActivityRecord parent, String subject, 10221 final String report, final File logFile, 10222 final ApplicationErrorReport.CrashInfo crashInfo) { 10223 // NOTE -- this must never acquire the ActivityManagerService lock, 10224 // otherwise the watchdog may be prevented from resetting the system. 10225 10226 final String dropboxTag = processClass(process) + "_" + eventType; 10227 final DropBoxManager dbox = (DropBoxManager) 10228 mContext.getSystemService(Context.DROPBOX_SERVICE); 10229 10230 // Exit early if the dropbox isn't configured to accept this report type. 10231 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10232 10233 final StringBuilder sb = new StringBuilder(1024); 10234 appendDropBoxProcessHeaders(process, processName, sb); 10235 if (activity != null) { 10236 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10237 } 10238 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10239 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10240 } 10241 if (parent != null && parent != activity) { 10242 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10243 } 10244 if (subject != null) { 10245 sb.append("Subject: ").append(subject).append("\n"); 10246 } 10247 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10248 if (Debug.isDebuggerConnected()) { 10249 sb.append("Debugger: Connected\n"); 10250 } 10251 sb.append("\n"); 10252 10253 // Do the rest in a worker thread to avoid blocking the caller on I/O 10254 // (After this point, we shouldn't access AMS internal data structures.) 10255 Thread worker = new Thread("Error dump: " + dropboxTag) { 10256 @Override 10257 public void run() { 10258 if (report != null) { 10259 sb.append(report); 10260 } 10261 if (logFile != null) { 10262 try { 10263 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10264 "\n\n[[TRUNCATED]]")); 10265 } catch (IOException e) { 10266 Slog.e(TAG, "Error reading " + logFile, e); 10267 } 10268 } 10269 if (crashInfo != null && crashInfo.stackTrace != null) { 10270 sb.append(crashInfo.stackTrace); 10271 } 10272 10273 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10274 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10275 if (lines > 0) { 10276 sb.append("\n"); 10277 10278 // Merge several logcat streams, and take the last N lines 10279 InputStreamReader input = null; 10280 try { 10281 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10282 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10283 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10284 10285 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10286 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10287 input = new InputStreamReader(logcat.getInputStream()); 10288 10289 int num; 10290 char[] buf = new char[8192]; 10291 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10292 } catch (IOException e) { 10293 Slog.e(TAG, "Error running logcat", e); 10294 } finally { 10295 if (input != null) try { input.close(); } catch (IOException e) {} 10296 } 10297 } 10298 10299 dbox.addText(dropboxTag, sb.toString()); 10300 } 10301 }; 10302 10303 if (process == null) { 10304 // If process is null, we are being called from some internal code 10305 // and may be about to die -- run this synchronously. 10306 worker.run(); 10307 } else { 10308 worker.start(); 10309 } 10310 } 10311 10312 /** 10313 * Bring up the "unexpected error" dialog box for a crashing app. 10314 * Deal with edge cases (intercepts from instrumented applications, 10315 * ActivityController, error intent receivers, that sort of thing). 10316 * @param r the application crashing 10317 * @param crashInfo describing the failure 10318 */ 10319 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10320 long timeMillis = System.currentTimeMillis(); 10321 String shortMsg = crashInfo.exceptionClassName; 10322 String longMsg = crashInfo.exceptionMessage; 10323 String stackTrace = crashInfo.stackTrace; 10324 if (shortMsg != null && longMsg != null) { 10325 longMsg = shortMsg + ": " + longMsg; 10326 } else if (shortMsg != null) { 10327 longMsg = shortMsg; 10328 } 10329 10330 AppErrorResult result = new AppErrorResult(); 10331 synchronized (this) { 10332 if (mController != null) { 10333 try { 10334 String name = r != null ? r.processName : null; 10335 int pid = r != null ? r.pid : Binder.getCallingPid(); 10336 if (!mController.appCrashed(name, pid, 10337 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10338 Slog.w(TAG, "Force-killing crashed app " + name 10339 + " at watcher's request"); 10340 Process.killProcess(pid); 10341 return; 10342 } 10343 } catch (RemoteException e) { 10344 mController = null; 10345 Watchdog.getInstance().setActivityController(null); 10346 } 10347 } 10348 10349 final long origId = Binder.clearCallingIdentity(); 10350 10351 // If this process is running instrumentation, finish it. 10352 if (r != null && r.instrumentationClass != null) { 10353 Slog.w(TAG, "Error in app " + r.processName 10354 + " running instrumentation " + r.instrumentationClass + ":"); 10355 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10356 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10357 Bundle info = new Bundle(); 10358 info.putString("shortMsg", shortMsg); 10359 info.putString("longMsg", longMsg); 10360 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10361 Binder.restoreCallingIdentity(origId); 10362 return; 10363 } 10364 10365 // If we can't identify the process or it's already exceeded its crash quota, 10366 // quit right away without showing a crash dialog. 10367 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10368 Binder.restoreCallingIdentity(origId); 10369 return; 10370 } 10371 10372 Message msg = Message.obtain(); 10373 msg.what = SHOW_ERROR_MSG; 10374 HashMap data = new HashMap(); 10375 data.put("result", result); 10376 data.put("app", r); 10377 msg.obj = data; 10378 mHandler.sendMessage(msg); 10379 10380 Binder.restoreCallingIdentity(origId); 10381 } 10382 10383 int res = result.get(); 10384 10385 Intent appErrorIntent = null; 10386 synchronized (this) { 10387 if (r != null && !r.isolated) { 10388 // XXX Can't keep track of crash time for isolated processes, 10389 // since they don't have a persistent identity. 10390 mProcessCrashTimes.put(r.info.processName, r.uid, 10391 SystemClock.uptimeMillis()); 10392 } 10393 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10394 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10395 } 10396 } 10397 10398 if (appErrorIntent != null) { 10399 try { 10400 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10401 } catch (ActivityNotFoundException e) { 10402 Slog.w(TAG, "bug report receiver dissappeared", e); 10403 } 10404 } 10405 } 10406 10407 Intent createAppErrorIntentLocked(ProcessRecord r, 10408 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10409 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10410 if (report == null) { 10411 return null; 10412 } 10413 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10414 result.setComponent(r.errorReportReceiver); 10415 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10416 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10417 return result; 10418 } 10419 10420 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10421 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10422 if (r.errorReportReceiver == null) { 10423 return null; 10424 } 10425 10426 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10427 return null; 10428 } 10429 10430 ApplicationErrorReport report = new ApplicationErrorReport(); 10431 report.packageName = r.info.packageName; 10432 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10433 report.processName = r.processName; 10434 report.time = timeMillis; 10435 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10436 10437 if (r.crashing || r.forceCrashReport) { 10438 report.type = ApplicationErrorReport.TYPE_CRASH; 10439 report.crashInfo = crashInfo; 10440 } else if (r.notResponding) { 10441 report.type = ApplicationErrorReport.TYPE_ANR; 10442 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10443 10444 report.anrInfo.activity = r.notRespondingReport.tag; 10445 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10446 report.anrInfo.info = r.notRespondingReport.longMsg; 10447 } 10448 10449 return report; 10450 } 10451 10452 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10453 enforceNotIsolatedCaller("getProcessesInErrorState"); 10454 // assume our apps are happy - lazy create the list 10455 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10456 10457 final boolean allUsers = ActivityManager.checkUidPermission( 10458 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10459 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10460 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10461 10462 synchronized (this) { 10463 10464 // iterate across all processes 10465 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10466 ProcessRecord app = mLruProcesses.get(i); 10467 if (!allUsers && app.userId != userId) { 10468 continue; 10469 } 10470 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10471 // This one's in trouble, so we'll generate a report for it 10472 // crashes are higher priority (in case there's a crash *and* an anr) 10473 ActivityManager.ProcessErrorStateInfo report = null; 10474 if (app.crashing) { 10475 report = app.crashingReport; 10476 } else if (app.notResponding) { 10477 report = app.notRespondingReport; 10478 } 10479 10480 if (report != null) { 10481 if (errList == null) { 10482 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10483 } 10484 errList.add(report); 10485 } else { 10486 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10487 " crashing = " + app.crashing + 10488 " notResponding = " + app.notResponding); 10489 } 10490 } 10491 } 10492 } 10493 10494 return errList; 10495 } 10496 10497 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10498 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10499 if (currApp != null) { 10500 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10501 } 10502 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10503 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10504 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10505 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10506 if (currApp != null) { 10507 currApp.lru = 0; 10508 } 10509 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10510 } else if (adj >= ProcessList.SERVICE_ADJ) { 10511 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10512 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10513 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10514 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10515 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10516 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10517 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10518 } else { 10519 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10520 } 10521 } 10522 10523 private void fillInProcMemInfo(ProcessRecord app, 10524 ActivityManager.RunningAppProcessInfo outInfo) { 10525 outInfo.pid = app.pid; 10526 outInfo.uid = app.info.uid; 10527 if (mHeavyWeightProcess == app) { 10528 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10529 } 10530 if (app.persistent) { 10531 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10532 } 10533 if (app.activities.size() > 0) { 10534 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10535 } 10536 outInfo.lastTrimLevel = app.trimMemoryLevel; 10537 int adj = app.curAdj; 10538 outInfo.importance = oomAdjToImportance(adj, outInfo); 10539 outInfo.importanceReasonCode = app.adjTypeCode; 10540 } 10541 10542 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10543 enforceNotIsolatedCaller("getRunningAppProcesses"); 10544 // Lazy instantiation of list 10545 List<ActivityManager.RunningAppProcessInfo> runList = null; 10546 final boolean allUsers = ActivityManager.checkUidPermission( 10547 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10548 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10549 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10550 synchronized (this) { 10551 // Iterate across all processes 10552 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10553 ProcessRecord app = mLruProcesses.get(i); 10554 if (!allUsers && app.userId != userId) { 10555 continue; 10556 } 10557 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10558 // Generate process state info for running application 10559 ActivityManager.RunningAppProcessInfo currApp = 10560 new ActivityManager.RunningAppProcessInfo(app.processName, 10561 app.pid, app.getPackageList()); 10562 fillInProcMemInfo(app, currApp); 10563 if (app.adjSource instanceof ProcessRecord) { 10564 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10565 currApp.importanceReasonImportance = oomAdjToImportance( 10566 app.adjSourceOom, null); 10567 } else if (app.adjSource instanceof ActivityRecord) { 10568 ActivityRecord r = (ActivityRecord)app.adjSource; 10569 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10570 } 10571 if (app.adjTarget instanceof ComponentName) { 10572 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10573 } 10574 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10575 // + " lru=" + currApp.lru); 10576 if (runList == null) { 10577 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10578 } 10579 runList.add(currApp); 10580 } 10581 } 10582 } 10583 return runList; 10584 } 10585 10586 public List<ApplicationInfo> getRunningExternalApplications() { 10587 enforceNotIsolatedCaller("getRunningExternalApplications"); 10588 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10589 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10590 if (runningApps != null && runningApps.size() > 0) { 10591 Set<String> extList = new HashSet<String>(); 10592 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10593 if (app.pkgList != null) { 10594 for (String pkg : app.pkgList) { 10595 extList.add(pkg); 10596 } 10597 } 10598 } 10599 IPackageManager pm = AppGlobals.getPackageManager(); 10600 for (String pkg : extList) { 10601 try { 10602 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10603 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10604 retList.add(info); 10605 } 10606 } catch (RemoteException e) { 10607 } 10608 } 10609 } 10610 return retList; 10611 } 10612 10613 @Override 10614 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10615 enforceNotIsolatedCaller("getMyMemoryState"); 10616 synchronized (this) { 10617 ProcessRecord proc; 10618 synchronized (mPidsSelfLocked) { 10619 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10620 } 10621 fillInProcMemInfo(proc, outInfo); 10622 } 10623 } 10624 10625 @Override 10626 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10627 if (checkCallingPermission(android.Manifest.permission.DUMP) 10628 != PackageManager.PERMISSION_GRANTED) { 10629 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10630 + Binder.getCallingPid() 10631 + ", uid=" + Binder.getCallingUid() 10632 + " without permission " 10633 + android.Manifest.permission.DUMP); 10634 return; 10635 } 10636 10637 boolean dumpAll = false; 10638 boolean dumpClient = false; 10639 String dumpPackage = null; 10640 10641 int opti = 0; 10642 while (opti < args.length) { 10643 String opt = args[opti]; 10644 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10645 break; 10646 } 10647 opti++; 10648 if ("-a".equals(opt)) { 10649 dumpAll = true; 10650 } else if ("-c".equals(opt)) { 10651 dumpClient = true; 10652 } else if ("-h".equals(opt)) { 10653 pw.println("Activity manager dump options:"); 10654 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10655 pw.println(" cmd may be one of:"); 10656 pw.println(" a[ctivities]: activity stack state"); 10657 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10658 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10659 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10660 pw.println(" o[om]: out of memory management"); 10661 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10662 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10663 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10664 pw.println(" service [COMP_SPEC]: service client-side state"); 10665 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10666 pw.println(" all: dump all activities"); 10667 pw.println(" top: dump the top activity"); 10668 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10669 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10670 pw.println(" a partial substring in a component name, a"); 10671 pw.println(" hex object identifier."); 10672 pw.println(" -a: include all available server state."); 10673 pw.println(" -c: include client state."); 10674 return; 10675 } else { 10676 pw.println("Unknown argument: " + opt + "; use -h for help"); 10677 } 10678 } 10679 10680 long origId = Binder.clearCallingIdentity(); 10681 boolean more = false; 10682 // Is the caller requesting to dump a particular piece of data? 10683 if (opti < args.length) { 10684 String cmd = args[opti]; 10685 opti++; 10686 if ("activities".equals(cmd) || "a".equals(cmd)) { 10687 synchronized (this) { 10688 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10689 } 10690 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10691 String[] newArgs; 10692 String name; 10693 if (opti >= args.length) { 10694 name = null; 10695 newArgs = EMPTY_STRING_ARRAY; 10696 } else { 10697 name = args[opti]; 10698 opti++; 10699 newArgs = new String[args.length - opti]; 10700 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10701 args.length - opti); 10702 } 10703 synchronized (this) { 10704 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10705 } 10706 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10707 String[] newArgs; 10708 String name; 10709 if (opti >= args.length) { 10710 name = null; 10711 newArgs = EMPTY_STRING_ARRAY; 10712 } else { 10713 name = args[opti]; 10714 opti++; 10715 newArgs = new String[args.length - opti]; 10716 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10717 args.length - opti); 10718 } 10719 synchronized (this) { 10720 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10721 } 10722 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10723 String[] newArgs; 10724 String name; 10725 if (opti >= args.length) { 10726 name = null; 10727 newArgs = EMPTY_STRING_ARRAY; 10728 } else { 10729 name = args[opti]; 10730 opti++; 10731 newArgs = new String[args.length - opti]; 10732 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10733 args.length - opti); 10734 } 10735 synchronized (this) { 10736 dumpProcessesLocked(fd, pw, args, opti, true, name); 10737 } 10738 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10739 synchronized (this) { 10740 dumpOomLocked(fd, pw, args, opti, true); 10741 } 10742 } else if ("provider".equals(cmd)) { 10743 String[] newArgs; 10744 String name; 10745 if (opti >= args.length) { 10746 name = null; 10747 newArgs = EMPTY_STRING_ARRAY; 10748 } else { 10749 name = args[opti]; 10750 opti++; 10751 newArgs = new String[args.length - opti]; 10752 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10753 } 10754 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10755 pw.println("No providers match: " + name); 10756 pw.println("Use -h for help."); 10757 } 10758 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10759 synchronized (this) { 10760 dumpProvidersLocked(fd, pw, args, opti, true, null); 10761 } 10762 } else if ("service".equals(cmd)) { 10763 String[] newArgs; 10764 String name; 10765 if (opti >= args.length) { 10766 name = null; 10767 newArgs = EMPTY_STRING_ARRAY; 10768 } else { 10769 name = args[opti]; 10770 opti++; 10771 newArgs = new String[args.length - opti]; 10772 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10773 args.length - opti); 10774 } 10775 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10776 pw.println("No services match: " + name); 10777 pw.println("Use -h for help."); 10778 } 10779 } else if ("package".equals(cmd)) { 10780 String[] newArgs; 10781 if (opti >= args.length) { 10782 pw.println("package: no package name specified"); 10783 pw.println("Use -h for help."); 10784 } else { 10785 dumpPackage = args[opti]; 10786 opti++; 10787 newArgs = new String[args.length - opti]; 10788 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10789 args.length - opti); 10790 args = newArgs; 10791 opti = 0; 10792 more = true; 10793 } 10794 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10795 synchronized (this) { 10796 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10797 } 10798 } else { 10799 // Dumping a single activity? 10800 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10801 pw.println("Bad activity command, or no activities match: " + cmd); 10802 pw.println("Use -h for help."); 10803 } 10804 } 10805 if (!more) { 10806 Binder.restoreCallingIdentity(origId); 10807 return; 10808 } 10809 } 10810 10811 // No piece of data specified, dump everything. 10812 synchronized (this) { 10813 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10814 pw.println(); 10815 if (dumpAll) { 10816 pw.println("-------------------------------------------------------------------------------"); 10817 } 10818 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10819 pw.println(); 10820 if (dumpAll) { 10821 pw.println("-------------------------------------------------------------------------------"); 10822 } 10823 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10824 pw.println(); 10825 if (dumpAll) { 10826 pw.println("-------------------------------------------------------------------------------"); 10827 } 10828 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10829 pw.println(); 10830 if (dumpAll) { 10831 pw.println("-------------------------------------------------------------------------------"); 10832 } 10833 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10834 pw.println(); 10835 if (dumpAll) { 10836 pw.println("-------------------------------------------------------------------------------"); 10837 } 10838 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10839 } 10840 Binder.restoreCallingIdentity(origId); 10841 } 10842 10843 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10844 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10845 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10846 10847 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10848 dumpPackage); 10849 boolean needSep = printedAnything; 10850 10851 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10852 dumpPackage, needSep, " mFocusedActivity: "); 10853 if (printed) { 10854 printedAnything = true; 10855 needSep = false; 10856 } 10857 10858 if (dumpPackage == null) { 10859 if (needSep) { 10860 pw.println(); 10861 } 10862 needSep = true; 10863 printedAnything = true; 10864 mStackSupervisor.dump(pw, " "); 10865 } 10866 10867 if (mRecentTasks.size() > 0) { 10868 boolean printedHeader = false; 10869 10870 final int N = mRecentTasks.size(); 10871 for (int i=0; i<N; i++) { 10872 TaskRecord tr = mRecentTasks.get(i); 10873 if (dumpPackage != null) { 10874 if (tr.realActivity == null || 10875 !dumpPackage.equals(tr.realActivity)) { 10876 continue; 10877 } 10878 } 10879 if (!printedHeader) { 10880 if (needSep) { 10881 pw.println(); 10882 } 10883 pw.println(" Recent tasks:"); 10884 printedHeader = true; 10885 printedAnything = true; 10886 } 10887 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10888 pw.println(tr); 10889 if (dumpAll) { 10890 mRecentTasks.get(i).dump(pw, " "); 10891 } 10892 } 10893 } 10894 10895 if (!printedAnything) { 10896 pw.println(" (nothing)"); 10897 } 10898 } 10899 10900 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10901 int opti, boolean dumpAll, String dumpPackage) { 10902 boolean needSep = false; 10903 boolean printedAnything = false; 10904 int numPers = 0; 10905 10906 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10907 10908 if (dumpAll) { 10909 final int NP = mProcessNames.getMap().size(); 10910 for (int ip=0; ip<NP; ip++) { 10911 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10912 final int NA = procs.size(); 10913 for (int ia=0; ia<NA; ia++) { 10914 ProcessRecord r = procs.valueAt(ia); 10915 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10916 continue; 10917 } 10918 if (!needSep) { 10919 pw.println(" All known processes:"); 10920 needSep = true; 10921 printedAnything = true; 10922 } 10923 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10924 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10925 pw.print(" "); pw.println(r); 10926 r.dump(pw, " "); 10927 if (r.persistent) { 10928 numPers++; 10929 } 10930 } 10931 } 10932 } 10933 10934 if (mIsolatedProcesses.size() > 0) { 10935 boolean printed = false; 10936 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10937 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10938 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10939 continue; 10940 } 10941 if (!printed) { 10942 if (needSep) { 10943 pw.println(); 10944 } 10945 pw.println(" Isolated process list (sorted by uid):"); 10946 printedAnything = true; 10947 printed = true; 10948 needSep = true; 10949 } 10950 pw.println(String.format("%sIsolated #%2d: %s", 10951 " ", i, r.toString())); 10952 } 10953 } 10954 10955 if (mLruProcesses.size() > 0) { 10956 if (needSep) { 10957 pw.println(); 10958 } 10959 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10960 pw.print(" total, non-act at "); 10961 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10962 pw.print(", non-svc at "); 10963 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10964 pw.println("):"); 10965 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10966 needSep = true; 10967 printedAnything = true; 10968 } 10969 10970 if (dumpAll || dumpPackage != null) { 10971 synchronized (mPidsSelfLocked) { 10972 boolean printed = false; 10973 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10974 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10975 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10976 continue; 10977 } 10978 if (!printed) { 10979 if (needSep) pw.println(); 10980 needSep = true; 10981 pw.println(" PID mappings:"); 10982 printed = true; 10983 printedAnything = true; 10984 } 10985 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10986 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10987 } 10988 } 10989 } 10990 10991 if (mForegroundProcesses.size() > 0) { 10992 synchronized (mPidsSelfLocked) { 10993 boolean printed = false; 10994 for (int i=0; i<mForegroundProcesses.size(); i++) { 10995 ProcessRecord r = mPidsSelfLocked.get( 10996 mForegroundProcesses.valueAt(i).pid); 10997 if (dumpPackage != null && (r == null 10998 || !r.pkgList.containsKey(dumpPackage))) { 10999 continue; 11000 } 11001 if (!printed) { 11002 if (needSep) pw.println(); 11003 needSep = true; 11004 pw.println(" Foreground Processes:"); 11005 printed = true; 11006 printedAnything = true; 11007 } 11008 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11009 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11010 } 11011 } 11012 } 11013 11014 if (mPersistentStartingProcesses.size() > 0) { 11015 if (needSep) pw.println(); 11016 needSep = true; 11017 printedAnything = true; 11018 pw.println(" Persisent processes that are starting:"); 11019 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11020 "Starting Norm", "Restarting PERS", dumpPackage); 11021 } 11022 11023 if (mRemovedProcesses.size() > 0) { 11024 if (needSep) pw.println(); 11025 needSep = true; 11026 printedAnything = true; 11027 pw.println(" Processes that are being removed:"); 11028 dumpProcessList(pw, this, mRemovedProcesses, " ", 11029 "Removed Norm", "Removed PERS", dumpPackage); 11030 } 11031 11032 if (mProcessesOnHold.size() > 0) { 11033 if (needSep) pw.println(); 11034 needSep = true; 11035 printedAnything = true; 11036 pw.println(" Processes that are on old until the system is ready:"); 11037 dumpProcessList(pw, this, mProcessesOnHold, " ", 11038 "OnHold Norm", "OnHold PERS", dumpPackage); 11039 } 11040 11041 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11042 11043 if (mProcessCrashTimes.getMap().size() > 0) { 11044 boolean printed = false; 11045 long now = SystemClock.uptimeMillis(); 11046 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11047 final int NP = pmap.size(); 11048 for (int ip=0; ip<NP; ip++) { 11049 String pname = pmap.keyAt(ip); 11050 SparseArray<Long> uids = pmap.valueAt(ip); 11051 final int N = uids.size(); 11052 for (int i=0; i<N; i++) { 11053 int puid = uids.keyAt(i); 11054 ProcessRecord r = mProcessNames.get(pname, puid); 11055 if (dumpPackage != null && (r == null 11056 || !r.pkgList.containsKey(dumpPackage))) { 11057 continue; 11058 } 11059 if (!printed) { 11060 if (needSep) pw.println(); 11061 needSep = true; 11062 pw.println(" Time since processes crashed:"); 11063 printed = true; 11064 printedAnything = true; 11065 } 11066 pw.print(" Process "); pw.print(pname); 11067 pw.print(" uid "); pw.print(puid); 11068 pw.print(": last crashed "); 11069 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11070 pw.println(" ago"); 11071 } 11072 } 11073 } 11074 11075 if (mBadProcesses.getMap().size() > 0) { 11076 boolean printed = false; 11077 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11078 final int NP = pmap.size(); 11079 for (int ip=0; ip<NP; ip++) { 11080 String pname = pmap.keyAt(ip); 11081 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11082 final int N = uids.size(); 11083 for (int i=0; i<N; i++) { 11084 int puid = uids.keyAt(i); 11085 ProcessRecord r = mProcessNames.get(pname, puid); 11086 if (dumpPackage != null && (r == null 11087 || !r.pkgList.containsKey(dumpPackage))) { 11088 continue; 11089 } 11090 if (!printed) { 11091 if (needSep) pw.println(); 11092 needSep = true; 11093 pw.println(" Bad processes:"); 11094 printedAnything = true; 11095 } 11096 BadProcessInfo info = uids.valueAt(i); 11097 pw.print(" Bad process "); pw.print(pname); 11098 pw.print(" uid "); pw.print(puid); 11099 pw.print(": crashed at time "); pw.println(info.time); 11100 if (info.shortMsg != null) { 11101 pw.print(" Short msg: "); pw.println(info.shortMsg); 11102 } 11103 if (info.longMsg != null) { 11104 pw.print(" Long msg: "); pw.println(info.longMsg); 11105 } 11106 if (info.stack != null) { 11107 pw.println(" Stack:"); 11108 int lastPos = 0; 11109 for (int pos=0; pos<info.stack.length(); pos++) { 11110 if (info.stack.charAt(pos) == '\n') { 11111 pw.print(" "); 11112 pw.write(info.stack, lastPos, pos-lastPos); 11113 pw.println(); 11114 lastPos = pos+1; 11115 } 11116 } 11117 if (lastPos < info.stack.length()) { 11118 pw.print(" "); 11119 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11120 pw.println(); 11121 } 11122 } 11123 } 11124 } 11125 } 11126 11127 if (dumpPackage == null) { 11128 pw.println(); 11129 needSep = false; 11130 pw.println(" mStartedUsers:"); 11131 for (int i=0; i<mStartedUsers.size(); i++) { 11132 UserStartedState uss = mStartedUsers.valueAt(i); 11133 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11134 pw.print(": "); uss.dump("", pw); 11135 } 11136 pw.print(" mStartedUserArray: ["); 11137 for (int i=0; i<mStartedUserArray.length; i++) { 11138 if (i > 0) pw.print(", "); 11139 pw.print(mStartedUserArray[i]); 11140 } 11141 pw.println("]"); 11142 pw.print(" mUserLru: ["); 11143 for (int i=0; i<mUserLru.size(); i++) { 11144 if (i > 0) pw.print(", "); 11145 pw.print(mUserLru.get(i)); 11146 } 11147 pw.println("]"); 11148 if (dumpAll) { 11149 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11150 } 11151 } 11152 if (mHomeProcess != null && (dumpPackage == null 11153 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11154 if (needSep) { 11155 pw.println(); 11156 needSep = false; 11157 } 11158 pw.println(" mHomeProcess: " + mHomeProcess); 11159 } 11160 if (mPreviousProcess != null && (dumpPackage == null 11161 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11162 if (needSep) { 11163 pw.println(); 11164 needSep = false; 11165 } 11166 pw.println(" mPreviousProcess: " + mPreviousProcess); 11167 } 11168 if (dumpAll) { 11169 StringBuilder sb = new StringBuilder(128); 11170 sb.append(" mPreviousProcessVisibleTime: "); 11171 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11172 pw.println(sb); 11173 } 11174 if (mHeavyWeightProcess != null && (dumpPackage == null 11175 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11176 if (needSep) { 11177 pw.println(); 11178 needSep = false; 11179 } 11180 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11181 } 11182 if (dumpPackage == null) { 11183 pw.println(" mConfiguration: " + mConfiguration); 11184 } 11185 if (dumpAll) { 11186 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11187 if (mCompatModePackages.getPackages().size() > 0) { 11188 boolean printed = false; 11189 for (Map.Entry<String, Integer> entry 11190 : mCompatModePackages.getPackages().entrySet()) { 11191 String pkg = entry.getKey(); 11192 int mode = entry.getValue(); 11193 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11194 continue; 11195 } 11196 if (!printed) { 11197 pw.println(" mScreenCompatPackages:"); 11198 printed = true; 11199 } 11200 pw.print(" "); pw.print(pkg); pw.print(": "); 11201 pw.print(mode); pw.println(); 11202 } 11203 } 11204 } 11205 if (dumpPackage == null) { 11206 if (mSleeping || mWentToSleep || mLockScreenShown) { 11207 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11208 + " mLockScreenShown " + mLockScreenShown); 11209 } 11210 if (mShuttingDown) { 11211 pw.println(" mShuttingDown=" + mShuttingDown); 11212 } 11213 } 11214 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11215 || mOrigWaitForDebugger) { 11216 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11217 || dumpPackage.equals(mOrigDebugApp)) { 11218 if (needSep) { 11219 pw.println(); 11220 needSep = false; 11221 } 11222 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11223 + " mDebugTransient=" + mDebugTransient 11224 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11225 } 11226 } 11227 if (mOpenGlTraceApp != null) { 11228 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11229 if (needSep) { 11230 pw.println(); 11231 needSep = false; 11232 } 11233 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11234 } 11235 } 11236 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11237 || mProfileFd != null) { 11238 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11239 if (needSep) { 11240 pw.println(); 11241 needSep = false; 11242 } 11243 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11244 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11245 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11246 + mAutoStopProfiler); 11247 } 11248 } 11249 if (dumpPackage == null) { 11250 if (mAlwaysFinishActivities || mController != null) { 11251 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11252 + " mController=" + mController); 11253 } 11254 if (dumpAll) { 11255 pw.println(" Total persistent processes: " + numPers); 11256 pw.println(" mProcessesReady=" + mProcessesReady 11257 + " mSystemReady=" + mSystemReady); 11258 pw.println(" mBooting=" + mBooting 11259 + " mBooted=" + mBooted 11260 + " mFactoryTest=" + mFactoryTest); 11261 pw.print(" mLastPowerCheckRealtime="); 11262 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11263 pw.println(""); 11264 pw.print(" mLastPowerCheckUptime="); 11265 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11266 pw.println(""); 11267 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11268 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11269 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11270 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11271 + " (" + mLruProcesses.size() + " total)" 11272 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11273 + " mNumServiceProcs=" + mNumServiceProcs 11274 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11275 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11276 + " mLastMemoryLevel" + mLastMemoryLevel 11277 + " mLastNumProcesses" + mLastNumProcesses); 11278 long now = SystemClock.uptimeMillis(); 11279 pw.print(" mLastIdleTime="); 11280 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11281 pw.print(" mLowRamSinceLastIdle="); 11282 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11283 pw.println(); 11284 } 11285 } 11286 11287 if (!printedAnything) { 11288 pw.println(" (nothing)"); 11289 } 11290 } 11291 11292 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11293 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11294 if (mProcessesToGc.size() > 0) { 11295 boolean printed = false; 11296 long now = SystemClock.uptimeMillis(); 11297 for (int i=0; i<mProcessesToGc.size(); i++) { 11298 ProcessRecord proc = mProcessesToGc.get(i); 11299 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11300 continue; 11301 } 11302 if (!printed) { 11303 if (needSep) pw.println(); 11304 needSep = true; 11305 pw.println(" Processes that are waiting to GC:"); 11306 printed = true; 11307 } 11308 pw.print(" Process "); pw.println(proc); 11309 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11310 pw.print(", last gced="); 11311 pw.print(now-proc.lastRequestedGc); 11312 pw.print(" ms ago, last lowMem="); 11313 pw.print(now-proc.lastLowMemory); 11314 pw.println(" ms ago"); 11315 11316 } 11317 } 11318 return needSep; 11319 } 11320 11321 void printOomLevel(PrintWriter pw, String name, int adj) { 11322 pw.print(" "); 11323 if (adj >= 0) { 11324 pw.print(' '); 11325 if (adj < 10) pw.print(' '); 11326 } else { 11327 if (adj > -10) pw.print(' '); 11328 } 11329 pw.print(adj); 11330 pw.print(": "); 11331 pw.print(name); 11332 pw.print(" ("); 11333 pw.print(mProcessList.getMemLevel(adj)/1024); 11334 pw.println(" kB)"); 11335 } 11336 11337 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11338 int opti, boolean dumpAll) { 11339 boolean needSep = false; 11340 11341 if (mLruProcesses.size() > 0) { 11342 if (needSep) pw.println(); 11343 needSep = true; 11344 pw.println(" OOM levels:"); 11345 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11346 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11347 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11348 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11349 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11350 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11351 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11352 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11353 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11354 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11355 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11356 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11357 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11358 11359 if (needSep) pw.println(); 11360 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11361 pw.print(" total, non-act at "); 11362 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11363 pw.print(", non-svc at "); 11364 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11365 pw.println("):"); 11366 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11367 needSep = true; 11368 } 11369 11370 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11371 11372 pw.println(); 11373 pw.println(" mHomeProcess: " + mHomeProcess); 11374 pw.println(" mPreviousProcess: " + mPreviousProcess); 11375 if (mHeavyWeightProcess != null) { 11376 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11377 } 11378 11379 return true; 11380 } 11381 11382 /** 11383 * There are three ways to call this: 11384 * - no provider specified: dump all the providers 11385 * - a flattened component name that matched an existing provider was specified as the 11386 * first arg: dump that one provider 11387 * - the first arg isn't the flattened component name of an existing provider: 11388 * dump all providers whose component contains the first arg as a substring 11389 */ 11390 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11391 int opti, boolean dumpAll) { 11392 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11393 } 11394 11395 static class ItemMatcher { 11396 ArrayList<ComponentName> components; 11397 ArrayList<String> strings; 11398 ArrayList<Integer> objects; 11399 boolean all; 11400 11401 ItemMatcher() { 11402 all = true; 11403 } 11404 11405 void build(String name) { 11406 ComponentName componentName = ComponentName.unflattenFromString(name); 11407 if (componentName != null) { 11408 if (components == null) { 11409 components = new ArrayList<ComponentName>(); 11410 } 11411 components.add(componentName); 11412 all = false; 11413 } else { 11414 int objectId = 0; 11415 // Not a '/' separated full component name; maybe an object ID? 11416 try { 11417 objectId = Integer.parseInt(name, 16); 11418 if (objects == null) { 11419 objects = new ArrayList<Integer>(); 11420 } 11421 objects.add(objectId); 11422 all = false; 11423 } catch (RuntimeException e) { 11424 // Not an integer; just do string match. 11425 if (strings == null) { 11426 strings = new ArrayList<String>(); 11427 } 11428 strings.add(name); 11429 all = false; 11430 } 11431 } 11432 } 11433 11434 int build(String[] args, int opti) { 11435 for (; opti<args.length; opti++) { 11436 String name = args[opti]; 11437 if ("--".equals(name)) { 11438 return opti+1; 11439 } 11440 build(name); 11441 } 11442 return opti; 11443 } 11444 11445 boolean match(Object object, ComponentName comp) { 11446 if (all) { 11447 return true; 11448 } 11449 if (components != null) { 11450 for (int i=0; i<components.size(); i++) { 11451 if (components.get(i).equals(comp)) { 11452 return true; 11453 } 11454 } 11455 } 11456 if (objects != null) { 11457 for (int i=0; i<objects.size(); i++) { 11458 if (System.identityHashCode(object) == objects.get(i)) { 11459 return true; 11460 } 11461 } 11462 } 11463 if (strings != null) { 11464 String flat = comp.flattenToString(); 11465 for (int i=0; i<strings.size(); i++) { 11466 if (flat.contains(strings.get(i))) { 11467 return true; 11468 } 11469 } 11470 } 11471 return false; 11472 } 11473 } 11474 11475 /** 11476 * There are three things that cmd can be: 11477 * - a flattened component name that matches an existing activity 11478 * - the cmd arg isn't the flattened component name of an existing activity: 11479 * dump all activity whose component contains the cmd as a substring 11480 * - A hex number of the ActivityRecord object instance. 11481 */ 11482 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11483 int opti, boolean dumpAll) { 11484 ArrayList<ActivityRecord> activities; 11485 11486 synchronized (this) { 11487 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11488 } 11489 11490 if (activities.size() <= 0) { 11491 return false; 11492 } 11493 11494 String[] newArgs = new String[args.length - opti]; 11495 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11496 11497 TaskRecord lastTask = null; 11498 boolean needSep = false; 11499 for (int i=activities.size()-1; i>=0; i--) { 11500 ActivityRecord r = activities.get(i); 11501 if (needSep) { 11502 pw.println(); 11503 } 11504 needSep = true; 11505 synchronized (this) { 11506 if (lastTask != r.task) { 11507 lastTask = r.task; 11508 pw.print("TASK "); pw.print(lastTask.affinity); 11509 pw.print(" id="); pw.println(lastTask.taskId); 11510 if (dumpAll) { 11511 lastTask.dump(pw, " "); 11512 } 11513 } 11514 } 11515 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11516 } 11517 return true; 11518 } 11519 11520 /** 11521 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11522 * there is a thread associated with the activity. 11523 */ 11524 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11525 final ActivityRecord r, String[] args, boolean dumpAll) { 11526 String innerPrefix = prefix + " "; 11527 synchronized (this) { 11528 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11529 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11530 pw.print(" pid="); 11531 if (r.app != null) pw.println(r.app.pid); 11532 else pw.println("(not running)"); 11533 if (dumpAll) { 11534 r.dump(pw, innerPrefix); 11535 } 11536 } 11537 if (r.app != null && r.app.thread != null) { 11538 // flush anything that is already in the PrintWriter since the thread is going 11539 // to write to the file descriptor directly 11540 pw.flush(); 11541 try { 11542 TransferPipe tp = new TransferPipe(); 11543 try { 11544 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11545 r.appToken, innerPrefix, args); 11546 tp.go(fd); 11547 } finally { 11548 tp.kill(); 11549 } 11550 } catch (IOException e) { 11551 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11552 } catch (RemoteException e) { 11553 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11554 } 11555 } 11556 } 11557 11558 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11559 int opti, boolean dumpAll, String dumpPackage) { 11560 boolean needSep = false; 11561 boolean onlyHistory = false; 11562 boolean printedAnything = false; 11563 11564 if ("history".equals(dumpPackage)) { 11565 if (opti < args.length && "-s".equals(args[opti])) { 11566 dumpAll = false; 11567 } 11568 onlyHistory = true; 11569 dumpPackage = null; 11570 } 11571 11572 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11573 if (!onlyHistory && dumpAll) { 11574 if (mRegisteredReceivers.size() > 0) { 11575 boolean printed = false; 11576 Iterator it = mRegisteredReceivers.values().iterator(); 11577 while (it.hasNext()) { 11578 ReceiverList r = (ReceiverList)it.next(); 11579 if (dumpPackage != null && (r.app == null || 11580 !dumpPackage.equals(r.app.info.packageName))) { 11581 continue; 11582 } 11583 if (!printed) { 11584 pw.println(" Registered Receivers:"); 11585 needSep = true; 11586 printed = true; 11587 printedAnything = true; 11588 } 11589 pw.print(" * "); pw.println(r); 11590 r.dump(pw, " "); 11591 } 11592 } 11593 11594 if (mReceiverResolver.dump(pw, needSep ? 11595 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11596 " ", dumpPackage, false)) { 11597 needSep = true; 11598 printedAnything = true; 11599 } 11600 } 11601 11602 for (BroadcastQueue q : mBroadcastQueues) { 11603 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11604 printedAnything |= needSep; 11605 } 11606 11607 needSep = true; 11608 11609 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11610 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11611 if (needSep) { 11612 pw.println(); 11613 } 11614 needSep = true; 11615 printedAnything = true; 11616 pw.print(" Sticky broadcasts for user "); 11617 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11618 StringBuilder sb = new StringBuilder(128); 11619 for (Map.Entry<String, ArrayList<Intent>> ent 11620 : mStickyBroadcasts.valueAt(user).entrySet()) { 11621 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11622 if (dumpAll) { 11623 pw.println(":"); 11624 ArrayList<Intent> intents = ent.getValue(); 11625 final int N = intents.size(); 11626 for (int i=0; i<N; i++) { 11627 sb.setLength(0); 11628 sb.append(" Intent: "); 11629 intents.get(i).toShortString(sb, false, true, false, false); 11630 pw.println(sb.toString()); 11631 Bundle bundle = intents.get(i).getExtras(); 11632 if (bundle != null) { 11633 pw.print(" "); 11634 pw.println(bundle.toString()); 11635 } 11636 } 11637 } else { 11638 pw.println(""); 11639 } 11640 } 11641 } 11642 } 11643 11644 if (!onlyHistory && dumpAll) { 11645 pw.println(); 11646 for (BroadcastQueue queue : mBroadcastQueues) { 11647 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11648 + queue.mBroadcastsScheduled); 11649 } 11650 pw.println(" mHandler:"); 11651 mHandler.dump(new PrintWriterPrinter(pw), " "); 11652 needSep = true; 11653 printedAnything = true; 11654 } 11655 11656 if (!printedAnything) { 11657 pw.println(" (nothing)"); 11658 } 11659 } 11660 11661 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11662 int opti, boolean dumpAll, String dumpPackage) { 11663 boolean needSep; 11664 boolean printedAnything = false; 11665 11666 ItemMatcher matcher = new ItemMatcher(); 11667 matcher.build(args, opti); 11668 11669 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11670 11671 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11672 printedAnything |= needSep; 11673 11674 if (mLaunchingProviders.size() > 0) { 11675 boolean printed = false; 11676 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11677 ContentProviderRecord r = mLaunchingProviders.get(i); 11678 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11679 continue; 11680 } 11681 if (!printed) { 11682 if (needSep) pw.println(); 11683 needSep = true; 11684 pw.println(" Launching content providers:"); 11685 printed = true; 11686 printedAnything = true; 11687 } 11688 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11689 pw.println(r); 11690 } 11691 } 11692 11693 if (mGrantedUriPermissions.size() > 0) { 11694 boolean printed = false; 11695 int dumpUid = -2; 11696 if (dumpPackage != null) { 11697 try { 11698 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11699 } catch (NameNotFoundException e) { 11700 dumpUid = -1; 11701 } 11702 } 11703 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11704 int uid = mGrantedUriPermissions.keyAt(i); 11705 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11706 continue; 11707 } 11708 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11709 if (!printed) { 11710 if (needSep) pw.println(); 11711 needSep = true; 11712 pw.println(" Granted Uri Permissions:"); 11713 printed = true; 11714 printedAnything = true; 11715 } 11716 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11717 for (UriPermission perm : perms.values()) { 11718 pw.print(" "); pw.println(perm); 11719 if (dumpAll) { 11720 perm.dump(pw, " "); 11721 } 11722 } 11723 } 11724 } 11725 11726 if (!printedAnything) { 11727 pw.println(" (nothing)"); 11728 } 11729 } 11730 11731 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11732 int opti, boolean dumpAll, String dumpPackage) { 11733 boolean printed = false; 11734 11735 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11736 11737 if (mIntentSenderRecords.size() > 0) { 11738 Iterator<WeakReference<PendingIntentRecord>> it 11739 = mIntentSenderRecords.values().iterator(); 11740 while (it.hasNext()) { 11741 WeakReference<PendingIntentRecord> ref = it.next(); 11742 PendingIntentRecord rec = ref != null ? ref.get(): null; 11743 if (dumpPackage != null && (rec == null 11744 || !dumpPackage.equals(rec.key.packageName))) { 11745 continue; 11746 } 11747 printed = true; 11748 if (rec != null) { 11749 pw.print(" * "); pw.println(rec); 11750 if (dumpAll) { 11751 rec.dump(pw, " "); 11752 } 11753 } else { 11754 pw.print(" * "); pw.println(ref); 11755 } 11756 } 11757 } 11758 11759 if (!printed) { 11760 pw.println(" (nothing)"); 11761 } 11762 } 11763 11764 private static final int dumpProcessList(PrintWriter pw, 11765 ActivityManagerService service, List list, 11766 String prefix, String normalLabel, String persistentLabel, 11767 String dumpPackage) { 11768 int numPers = 0; 11769 final int N = list.size()-1; 11770 for (int i=N; i>=0; i--) { 11771 ProcessRecord r = (ProcessRecord)list.get(i); 11772 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11773 continue; 11774 } 11775 pw.println(String.format("%s%s #%2d: %s", 11776 prefix, (r.persistent ? persistentLabel : normalLabel), 11777 i, r.toString())); 11778 if (r.persistent) { 11779 numPers++; 11780 } 11781 } 11782 return numPers; 11783 } 11784 11785 private static final boolean dumpProcessOomList(PrintWriter pw, 11786 ActivityManagerService service, List<ProcessRecord> origList, 11787 String prefix, String normalLabel, String persistentLabel, 11788 boolean inclDetails, String dumpPackage) { 11789 11790 ArrayList<Pair<ProcessRecord, Integer>> list 11791 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11792 for (int i=0; i<origList.size(); i++) { 11793 ProcessRecord r = origList.get(i); 11794 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11795 continue; 11796 } 11797 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11798 } 11799 11800 if (list.size() <= 0) { 11801 return false; 11802 } 11803 11804 Comparator<Pair<ProcessRecord, Integer>> comparator 11805 = new Comparator<Pair<ProcessRecord, Integer>>() { 11806 @Override 11807 public int compare(Pair<ProcessRecord, Integer> object1, 11808 Pair<ProcessRecord, Integer> object2) { 11809 if (object1.first.setAdj != object2.first.setAdj) { 11810 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11811 } 11812 if (object1.second.intValue() != object2.second.intValue()) { 11813 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11814 } 11815 return 0; 11816 } 11817 }; 11818 11819 Collections.sort(list, comparator); 11820 11821 final long curRealtime = SystemClock.elapsedRealtime(); 11822 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11823 final long curUptime = SystemClock.uptimeMillis(); 11824 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11825 11826 for (int i=list.size()-1; i>=0; i--) { 11827 ProcessRecord r = list.get(i).first; 11828 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11829 char schedGroup; 11830 switch (r.setSchedGroup) { 11831 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11832 schedGroup = 'B'; 11833 break; 11834 case Process.THREAD_GROUP_DEFAULT: 11835 schedGroup = 'F'; 11836 break; 11837 default: 11838 schedGroup = '?'; 11839 break; 11840 } 11841 char foreground; 11842 if (r.foregroundActivities) { 11843 foreground = 'A'; 11844 } else if (r.foregroundServices) { 11845 foreground = 'S'; 11846 } else { 11847 foreground = ' '; 11848 } 11849 String procState = ProcessList.makeProcStateString(r.curProcState); 11850 pw.print(prefix); 11851 pw.print(r.persistent ? persistentLabel : normalLabel); 11852 pw.print(" #"); 11853 int num = (origList.size()-1)-list.get(i).second; 11854 if (num < 10) pw.print(' '); 11855 pw.print(num); 11856 pw.print(": "); 11857 pw.print(oomAdj); 11858 pw.print(' '); 11859 pw.print(schedGroup); 11860 pw.print('/'); 11861 pw.print(foreground); 11862 pw.print('/'); 11863 pw.print(procState); 11864 pw.print(" trm:"); 11865 if (r.trimMemoryLevel < 10) pw.print(' '); 11866 pw.print(r.trimMemoryLevel); 11867 pw.print(' '); 11868 pw.print(r.toShortString()); 11869 pw.print(" ("); 11870 pw.print(r.adjType); 11871 pw.println(')'); 11872 if (r.adjSource != null || r.adjTarget != null) { 11873 pw.print(prefix); 11874 pw.print(" "); 11875 if (r.adjTarget instanceof ComponentName) { 11876 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11877 } else if (r.adjTarget != null) { 11878 pw.print(r.adjTarget.toString()); 11879 } else { 11880 pw.print("{null}"); 11881 } 11882 pw.print("<="); 11883 if (r.adjSource instanceof ProcessRecord) { 11884 pw.print("Proc{"); 11885 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11886 pw.println("}"); 11887 } else if (r.adjSource != null) { 11888 pw.println(r.adjSource.toString()); 11889 } else { 11890 pw.println("{null}"); 11891 } 11892 } 11893 if (inclDetails) { 11894 pw.print(prefix); 11895 pw.print(" "); 11896 pw.print("oom: max="); pw.print(r.maxAdj); 11897 pw.print(" curRaw="); pw.print(r.curRawAdj); 11898 pw.print(" setRaw="); pw.print(r.setRawAdj); 11899 pw.print(" cur="); pw.print(r.curAdj); 11900 pw.print(" set="); pw.println(r.setAdj); 11901 pw.print(prefix); 11902 pw.print(" "); 11903 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11904 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11905 pw.print(" lastPss="); pw.print(r.lastPss); 11906 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11907 pw.print(prefix); 11908 pw.print(" "); 11909 pw.print("keeping="); pw.print(r.keeping); 11910 pw.print(" cached="); pw.print(r.cached); 11911 pw.print(" empty="); pw.print(r.empty); 11912 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11913 11914 if (!r.keeping) { 11915 if (r.lastWakeTime != 0) { 11916 long wtime; 11917 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11918 synchronized (stats) { 11919 wtime = stats.getProcessWakeTime(r.info.uid, 11920 r.pid, curRealtime); 11921 } 11922 long timeUsed = wtime - r.lastWakeTime; 11923 pw.print(prefix); 11924 pw.print(" "); 11925 pw.print("keep awake over "); 11926 TimeUtils.formatDuration(realtimeSince, pw); 11927 pw.print(" used "); 11928 TimeUtils.formatDuration(timeUsed, pw); 11929 pw.print(" ("); 11930 pw.print((timeUsed*100)/realtimeSince); 11931 pw.println("%)"); 11932 } 11933 if (r.lastCpuTime != 0) { 11934 long timeUsed = r.curCpuTime - r.lastCpuTime; 11935 pw.print(prefix); 11936 pw.print(" "); 11937 pw.print("run cpu over "); 11938 TimeUtils.formatDuration(uptimeSince, pw); 11939 pw.print(" used "); 11940 TimeUtils.formatDuration(timeUsed, pw); 11941 pw.print(" ("); 11942 pw.print((timeUsed*100)/uptimeSince); 11943 pw.println("%)"); 11944 } 11945 } 11946 } 11947 } 11948 return true; 11949 } 11950 11951 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11952 ArrayList<ProcessRecord> procs; 11953 synchronized (this) { 11954 if (args != null && args.length > start 11955 && args[start].charAt(0) != '-') { 11956 procs = new ArrayList<ProcessRecord>(); 11957 int pid = -1; 11958 try { 11959 pid = Integer.parseInt(args[start]); 11960 } catch (NumberFormatException e) { 11961 } 11962 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11963 ProcessRecord proc = mLruProcesses.get(i); 11964 if (proc.pid == pid) { 11965 procs.add(proc); 11966 } else if (proc.processName.equals(args[start])) { 11967 procs.add(proc); 11968 } 11969 } 11970 if (procs.size() <= 0) { 11971 return null; 11972 } 11973 } else { 11974 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11975 } 11976 } 11977 return procs; 11978 } 11979 11980 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11981 PrintWriter pw, String[] args) { 11982 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11983 if (procs == null) { 11984 pw.println("No process found for: " + args[0]); 11985 return; 11986 } 11987 11988 long uptime = SystemClock.uptimeMillis(); 11989 long realtime = SystemClock.elapsedRealtime(); 11990 pw.println("Applications Graphics Acceleration Info:"); 11991 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11992 11993 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11994 ProcessRecord r = procs.get(i); 11995 if (r.thread != null) { 11996 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11997 pw.flush(); 11998 try { 11999 TransferPipe tp = new TransferPipe(); 12000 try { 12001 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12002 tp.go(fd); 12003 } finally { 12004 tp.kill(); 12005 } 12006 } catch (IOException e) { 12007 pw.println("Failure while dumping the app: " + r); 12008 pw.flush(); 12009 } catch (RemoteException e) { 12010 pw.println("Got a RemoteException while dumping the app " + r); 12011 pw.flush(); 12012 } 12013 } 12014 } 12015 } 12016 12017 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12018 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12019 if (procs == null) { 12020 pw.println("No process found for: " + args[0]); 12021 return; 12022 } 12023 12024 pw.println("Applications Database Info:"); 12025 12026 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12027 ProcessRecord r = procs.get(i); 12028 if (r.thread != null) { 12029 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12030 pw.flush(); 12031 try { 12032 TransferPipe tp = new TransferPipe(); 12033 try { 12034 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12035 tp.go(fd); 12036 } finally { 12037 tp.kill(); 12038 } 12039 } catch (IOException e) { 12040 pw.println("Failure while dumping the app: " + r); 12041 pw.flush(); 12042 } catch (RemoteException e) { 12043 pw.println("Got a RemoteException while dumping the app " + r); 12044 pw.flush(); 12045 } 12046 } 12047 } 12048 } 12049 12050 final static class MemItem { 12051 final boolean isProc; 12052 final String label; 12053 final String shortLabel; 12054 final long pss; 12055 final int id; 12056 final boolean hasActivities; 12057 ArrayList<MemItem> subitems; 12058 12059 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12060 boolean _hasActivities) { 12061 isProc = true; 12062 label = _label; 12063 shortLabel = _shortLabel; 12064 pss = _pss; 12065 id = _id; 12066 hasActivities = _hasActivities; 12067 } 12068 12069 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12070 isProc = false; 12071 label = _label; 12072 shortLabel = _shortLabel; 12073 pss = _pss; 12074 id = _id; 12075 hasActivities = false; 12076 } 12077 } 12078 12079 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12080 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12081 if (sort && !isCompact) { 12082 Collections.sort(items, new Comparator<MemItem>() { 12083 @Override 12084 public int compare(MemItem lhs, MemItem rhs) { 12085 if (lhs.pss < rhs.pss) { 12086 return 1; 12087 } else if (lhs.pss > rhs.pss) { 12088 return -1; 12089 } 12090 return 0; 12091 } 12092 }); 12093 } 12094 12095 for (int i=0; i<items.size(); i++) { 12096 MemItem mi = items.get(i); 12097 if (!isCompact) { 12098 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12099 } else if (mi.isProc) { 12100 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12101 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12102 pw.println(mi.hasActivities ? ",a" : ",e"); 12103 } else { 12104 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12105 pw.println(mi.pss); 12106 } 12107 if (mi.subitems != null) { 12108 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12109 true, isCompact); 12110 } 12111 } 12112 } 12113 12114 // These are in KB. 12115 static final long[] DUMP_MEM_BUCKETS = new long[] { 12116 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12117 120*1024, 160*1024, 200*1024, 12118 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12119 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12120 }; 12121 12122 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12123 boolean stackLike) { 12124 int start = label.lastIndexOf('.'); 12125 if (start >= 0) start++; 12126 else start = 0; 12127 int end = label.length(); 12128 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12129 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12130 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12131 out.append(bucket); 12132 out.append(stackLike ? "MB." : "MB "); 12133 out.append(label, start, end); 12134 return; 12135 } 12136 } 12137 out.append(memKB/1024); 12138 out.append(stackLike ? "MB." : "MB "); 12139 out.append(label, start, end); 12140 } 12141 12142 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12143 ProcessList.NATIVE_ADJ, 12144 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12145 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12146 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12147 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12148 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12149 }; 12150 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12151 "Native", 12152 "System", "Persistent", "Foreground", 12153 "Visible", "Perceptible", 12154 "Heavy Weight", "Backup", 12155 "A Services", "Home", 12156 "Previous", "B Services", "Cached" 12157 }; 12158 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12159 "native", 12160 "sys", "pers", "fore", 12161 "vis", "percept", 12162 "heavy", "backup", 12163 "servicea", "home", 12164 "prev", "serviceb", "cached" 12165 }; 12166 12167 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12168 long realtime, boolean isCheckinRequest, boolean isCompact) { 12169 if (isCheckinRequest || isCompact) { 12170 // short checkin version 12171 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12172 } else { 12173 pw.println("Applications Memory Usage (kB):"); 12174 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12175 } 12176 } 12177 12178 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12179 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12180 boolean dumpDetails = false; 12181 boolean dumpFullDetails = false; 12182 boolean dumpDalvik = false; 12183 boolean oomOnly = false; 12184 boolean isCompact = false; 12185 boolean localOnly = false; 12186 12187 int opti = 0; 12188 while (opti < args.length) { 12189 String opt = args[opti]; 12190 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12191 break; 12192 } 12193 opti++; 12194 if ("-a".equals(opt)) { 12195 dumpDetails = true; 12196 dumpFullDetails = true; 12197 dumpDalvik = true; 12198 } else if ("-d".equals(opt)) { 12199 dumpDalvik = true; 12200 } else if ("-c".equals(opt)) { 12201 isCompact = true; 12202 } else if ("--oom".equals(opt)) { 12203 oomOnly = true; 12204 } else if ("--local".equals(opt)) { 12205 localOnly = true; 12206 } else if ("-h".equals(opt)) { 12207 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12208 pw.println(" -a: include all available information for each process."); 12209 pw.println(" -d: include dalvik details when dumping process details."); 12210 pw.println(" -c: dump in a compact machine-parseable representation."); 12211 pw.println(" --oom: only show processes organized by oom adj."); 12212 pw.println(" --local: only collect details locally, don't call process."); 12213 pw.println("If [process] is specified it can be the name or "); 12214 pw.println("pid of a specific process to dump."); 12215 return; 12216 } else { 12217 pw.println("Unknown argument: " + opt + "; use -h for help"); 12218 } 12219 } 12220 12221 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12222 long uptime = SystemClock.uptimeMillis(); 12223 long realtime = SystemClock.elapsedRealtime(); 12224 final long[] tmpLong = new long[1]; 12225 12226 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12227 if (procs == null) { 12228 // No Java processes. Maybe they want to print a native process. 12229 if (args != null && args.length > opti 12230 && args[opti].charAt(0) != '-') { 12231 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12232 = new ArrayList<ProcessCpuTracker.Stats>(); 12233 updateCpuStatsNow(); 12234 int findPid = -1; 12235 try { 12236 findPid = Integer.parseInt(args[opti]); 12237 } catch (NumberFormatException e) { 12238 } 12239 synchronized (mProcessCpuThread) { 12240 final int N = mProcessCpuTracker.countStats(); 12241 for (int i=0; i<N; i++) { 12242 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12243 if (st.pid == findPid || (st.baseName != null 12244 && st.baseName.equals(args[opti]))) { 12245 nativeProcs.add(st); 12246 } 12247 } 12248 } 12249 if (nativeProcs.size() > 0) { 12250 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12251 isCompact); 12252 Debug.MemoryInfo mi = null; 12253 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12254 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12255 final int pid = r.pid; 12256 if (!isCheckinRequest && dumpDetails) { 12257 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12258 } 12259 if (mi == null) { 12260 mi = new Debug.MemoryInfo(); 12261 } 12262 if (dumpDetails || (!brief && !oomOnly)) { 12263 Debug.getMemoryInfo(pid, mi); 12264 } else { 12265 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12266 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12267 } 12268 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12269 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12270 if (isCheckinRequest) { 12271 pw.println(); 12272 } 12273 } 12274 return; 12275 } 12276 } 12277 pw.println("No process found for: " + args[opti]); 12278 return; 12279 } 12280 12281 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12282 dumpDetails = true; 12283 } 12284 12285 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12286 12287 String[] innerArgs = new String[args.length-opti]; 12288 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12289 12290 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12291 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12292 long nativePss=0, dalvikPss=0, otherPss=0; 12293 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12294 12295 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12296 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12297 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12298 12299 long totalPss = 0; 12300 long cachedPss = 0; 12301 12302 Debug.MemoryInfo mi = null; 12303 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12304 final ProcessRecord r = procs.get(i); 12305 final IApplicationThread thread; 12306 final int pid; 12307 final int oomAdj; 12308 final boolean hasActivities; 12309 synchronized (this) { 12310 thread = r.thread; 12311 pid = r.pid; 12312 oomAdj = r.getSetAdjWithServices(); 12313 hasActivities = r.activities.size() > 0; 12314 } 12315 if (thread != null) { 12316 if (!isCheckinRequest && dumpDetails) { 12317 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12318 } 12319 if (mi == null) { 12320 mi = new Debug.MemoryInfo(); 12321 } 12322 if (dumpDetails || (!brief && !oomOnly)) { 12323 Debug.getMemoryInfo(pid, mi); 12324 } else { 12325 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12326 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12327 } 12328 if (dumpDetails) { 12329 if (localOnly) { 12330 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12331 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12332 if (isCheckinRequest) { 12333 pw.println(); 12334 } 12335 } else { 12336 try { 12337 pw.flush(); 12338 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12339 dumpDalvik, innerArgs); 12340 } catch (RemoteException e) { 12341 if (!isCheckinRequest) { 12342 pw.println("Got RemoteException!"); 12343 pw.flush(); 12344 } 12345 } 12346 } 12347 } 12348 12349 final long myTotalPss = mi.getTotalPss(); 12350 final long myTotalUss = mi.getTotalUss(); 12351 12352 synchronized (this) { 12353 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12354 // Record this for posterity if the process has been stable. 12355 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12356 } 12357 } 12358 12359 if (!isCheckinRequest && mi != null) { 12360 totalPss += myTotalPss; 12361 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12362 (hasActivities ? " / activities)" : ")"), 12363 r.processName, myTotalPss, pid, hasActivities); 12364 procMems.add(pssItem); 12365 procMemsMap.put(pid, pssItem); 12366 12367 nativePss += mi.nativePss; 12368 dalvikPss += mi.dalvikPss; 12369 otherPss += mi.otherPss; 12370 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12371 long mem = mi.getOtherPss(j); 12372 miscPss[j] += mem; 12373 otherPss -= mem; 12374 } 12375 12376 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12377 cachedPss += myTotalPss; 12378 } 12379 12380 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12381 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12382 || oomIndex == (oomPss.length-1)) { 12383 oomPss[oomIndex] += myTotalPss; 12384 if (oomProcs[oomIndex] == null) { 12385 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12386 } 12387 oomProcs[oomIndex].add(pssItem); 12388 break; 12389 } 12390 } 12391 } 12392 } 12393 } 12394 12395 if (!isCheckinRequest && procs.size() > 1) { 12396 // If we are showing aggregations, also look for native processes to 12397 // include so that our aggregations are more accurate. 12398 updateCpuStatsNow(); 12399 synchronized (mProcessCpuThread) { 12400 final int N = mProcessCpuTracker.countStats(); 12401 for (int i=0; i<N; i++) { 12402 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12403 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12404 if (mi == null) { 12405 mi = new Debug.MemoryInfo(); 12406 } 12407 if (!brief && !oomOnly) { 12408 Debug.getMemoryInfo(st.pid, mi); 12409 } else { 12410 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12411 mi.nativePrivateDirty = (int)tmpLong[0]; 12412 } 12413 12414 final long myTotalPss = mi.getTotalPss(); 12415 totalPss += myTotalPss; 12416 12417 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12418 st.name, myTotalPss, st.pid, false); 12419 procMems.add(pssItem); 12420 12421 nativePss += mi.nativePss; 12422 dalvikPss += mi.dalvikPss; 12423 otherPss += mi.otherPss; 12424 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12425 long mem = mi.getOtherPss(j); 12426 miscPss[j] += mem; 12427 otherPss -= mem; 12428 } 12429 oomPss[0] += myTotalPss; 12430 if (oomProcs[0] == null) { 12431 oomProcs[0] = new ArrayList<MemItem>(); 12432 } 12433 oomProcs[0].add(pssItem); 12434 } 12435 } 12436 } 12437 12438 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12439 12440 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12441 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12442 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12443 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12444 String label = Debug.MemoryInfo.getOtherLabel(j); 12445 catMems.add(new MemItem(label, label, miscPss[j], j)); 12446 } 12447 12448 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12449 for (int j=0; j<oomPss.length; j++) { 12450 if (oomPss[j] != 0) { 12451 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12452 : DUMP_MEM_OOM_LABEL[j]; 12453 MemItem item = new MemItem(label, label, oomPss[j], 12454 DUMP_MEM_OOM_ADJ[j]); 12455 item.subitems = oomProcs[j]; 12456 oomMems.add(item); 12457 } 12458 } 12459 12460 if (!brief && !oomOnly && !isCompact) { 12461 pw.println(); 12462 pw.println("Total PSS by process:"); 12463 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12464 pw.println(); 12465 } 12466 if (!isCompact) { 12467 pw.println("Total PSS by OOM adjustment:"); 12468 } 12469 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12470 if (!brief && !oomOnly) { 12471 PrintWriter out = categoryPw != null ? categoryPw : pw; 12472 if (!isCompact) { 12473 out.println(); 12474 out.println("Total PSS by category:"); 12475 } 12476 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12477 } 12478 if (!isCompact) { 12479 pw.println(); 12480 } 12481 MemInfoReader memInfo = new MemInfoReader(); 12482 memInfo.readMemInfo(); 12483 if (!brief) { 12484 if (!isCompact) { 12485 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12486 pw.print(" kB (status "); 12487 switch (mLastMemoryLevel) { 12488 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12489 pw.println("normal)"); 12490 break; 12491 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12492 pw.println("moderate)"); 12493 break; 12494 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12495 pw.println("low)"); 12496 break; 12497 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12498 pw.println("critical)"); 12499 break; 12500 default: 12501 pw.print(mLastMemoryLevel); 12502 pw.println(")"); 12503 break; 12504 } 12505 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12506 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12507 pw.print(cachedPss); pw.print(" cached pss + "); 12508 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12509 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12510 } else { 12511 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12512 pw.print(cachedPss + memInfo.getCachedSizeKb() 12513 + memInfo.getFreeSizeKb()); pw.print(","); 12514 pw.println(totalPss - cachedPss); 12515 } 12516 } 12517 if (!isCompact) { 12518 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12519 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12520 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12521 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12522 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12523 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12524 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12525 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12526 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12527 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12528 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12529 } 12530 if (!brief) { 12531 if (memInfo.getZramTotalSizeKb() != 0) { 12532 if (!isCompact) { 12533 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12534 pw.print(" kB physical used for "); 12535 pw.print(memInfo.getSwapTotalSizeKb() 12536 - memInfo.getSwapFreeSizeKb()); 12537 pw.print(" kB in swap ("); 12538 pw.print(memInfo.getSwapTotalSizeKb()); 12539 pw.println(" kB total swap)"); 12540 } else { 12541 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12542 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12543 pw.println(memInfo.getSwapFreeSizeKb()); 12544 } 12545 } 12546 final int[] SINGLE_LONG_FORMAT = new int[] { 12547 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12548 }; 12549 long[] longOut = new long[1]; 12550 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12551 SINGLE_LONG_FORMAT, null, longOut, null); 12552 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12553 longOut[0] = 0; 12554 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12555 SINGLE_LONG_FORMAT, null, longOut, null); 12556 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12557 longOut[0] = 0; 12558 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12559 SINGLE_LONG_FORMAT, null, longOut, null); 12560 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12561 longOut[0] = 0; 12562 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12563 SINGLE_LONG_FORMAT, null, longOut, null); 12564 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12565 if (!isCompact) { 12566 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12567 pw.print(" KSM: "); pw.print(sharing); 12568 pw.print(" kB saved from shared "); 12569 pw.print(shared); pw.println(" kB"); 12570 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12571 pw.print(voltile); pw.println(" kB volatile"); 12572 } 12573 pw.print(" Tuning: "); 12574 pw.print(ActivityManager.staticGetMemoryClass()); 12575 pw.print(" (large "); 12576 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12577 pw.print("), oom "); 12578 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12579 pw.print(" kB"); 12580 pw.print(", restore limit "); 12581 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12582 pw.print(" kB"); 12583 if (ActivityManager.isLowRamDeviceStatic()) { 12584 pw.print(" (low-ram)"); 12585 } 12586 if (ActivityManager.isHighEndGfx()) { 12587 pw.print(" (high-end-gfx)"); 12588 } 12589 pw.println(); 12590 } else { 12591 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12592 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12593 pw.println(voltile); 12594 pw.print("tuning,"); 12595 pw.print(ActivityManager.staticGetMemoryClass()); 12596 pw.print(','); 12597 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12598 pw.print(','); 12599 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12600 if (ActivityManager.isLowRamDeviceStatic()) { 12601 pw.print(",low-ram"); 12602 } 12603 if (ActivityManager.isHighEndGfx()) { 12604 pw.print(",high-end-gfx"); 12605 } 12606 pw.println(); 12607 } 12608 } 12609 } 12610 } 12611 12612 /** 12613 * Searches array of arguments for the specified string 12614 * @param args array of argument strings 12615 * @param value value to search for 12616 * @return true if the value is contained in the array 12617 */ 12618 private static boolean scanArgs(String[] args, String value) { 12619 if (args != null) { 12620 for (String arg : args) { 12621 if (value.equals(arg)) { 12622 return true; 12623 } 12624 } 12625 } 12626 return false; 12627 } 12628 12629 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12630 ContentProviderRecord cpr, boolean always) { 12631 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12632 12633 if (!inLaunching || always) { 12634 synchronized (cpr) { 12635 cpr.launchingApp = null; 12636 cpr.notifyAll(); 12637 } 12638 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12639 String names[] = cpr.info.authority.split(";"); 12640 for (int j = 0; j < names.length; j++) { 12641 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12642 } 12643 } 12644 12645 for (int i=0; i<cpr.connections.size(); i++) { 12646 ContentProviderConnection conn = cpr.connections.get(i); 12647 if (conn.waiting) { 12648 // If this connection is waiting for the provider, then we don't 12649 // need to mess with its process unless we are always removing 12650 // or for some reason the provider is not currently launching. 12651 if (inLaunching && !always) { 12652 continue; 12653 } 12654 } 12655 ProcessRecord capp = conn.client; 12656 conn.dead = true; 12657 if (conn.stableCount > 0) { 12658 if (!capp.persistent && capp.thread != null 12659 && capp.pid != 0 12660 && capp.pid != MY_PID) { 12661 killUnneededProcessLocked(capp, "depends on provider " 12662 + cpr.name.flattenToShortString() 12663 + " in dying proc " + (proc != null ? proc.processName : "??")); 12664 } 12665 } else if (capp.thread != null && conn.provider.provider != null) { 12666 try { 12667 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12668 } catch (RemoteException e) { 12669 } 12670 // In the protocol here, we don't expect the client to correctly 12671 // clean up this connection, we'll just remove it. 12672 cpr.connections.remove(i); 12673 conn.client.conProviders.remove(conn); 12674 } 12675 } 12676 12677 if (inLaunching && always) { 12678 mLaunchingProviders.remove(cpr); 12679 } 12680 return inLaunching; 12681 } 12682 12683 /** 12684 * Main code for cleaning up a process when it has gone away. This is 12685 * called both as a result of the process dying, or directly when stopping 12686 * a process when running in single process mode. 12687 */ 12688 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12689 boolean restarting, boolean allowRestart, int index) { 12690 if (index >= 0) { 12691 removeLruProcessLocked(app); 12692 ProcessList.remove(app.pid); 12693 } 12694 12695 mProcessesToGc.remove(app); 12696 mPendingPssProcesses.remove(app); 12697 12698 // Dismiss any open dialogs. 12699 if (app.crashDialog != null && !app.forceCrashReport) { 12700 app.crashDialog.dismiss(); 12701 app.crashDialog = null; 12702 } 12703 if (app.anrDialog != null) { 12704 app.anrDialog.dismiss(); 12705 app.anrDialog = null; 12706 } 12707 if (app.waitDialog != null) { 12708 app.waitDialog.dismiss(); 12709 app.waitDialog = null; 12710 } 12711 12712 app.crashing = false; 12713 app.notResponding = false; 12714 12715 app.resetPackageList(mProcessStats); 12716 app.unlinkDeathRecipient(); 12717 app.makeInactive(mProcessStats); 12718 app.forcingToForeground = null; 12719 updateProcessForegroundLocked(app, false, false); 12720 app.foregroundActivities = false; 12721 app.hasShownUi = false; 12722 app.treatLikeActivity = false; 12723 app.hasAboveClient = false; 12724 app.hasClientActivities = false; 12725 12726 mServices.killServicesLocked(app, allowRestart); 12727 12728 boolean restart = false; 12729 12730 // Remove published content providers. 12731 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12732 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12733 final boolean always = app.bad || !allowRestart; 12734 if (removeDyingProviderLocked(app, cpr, always) || always) { 12735 // We left the provider in the launching list, need to 12736 // restart it. 12737 restart = true; 12738 } 12739 12740 cpr.provider = null; 12741 cpr.proc = null; 12742 } 12743 app.pubProviders.clear(); 12744 12745 // Take care of any launching providers waiting for this process. 12746 if (checkAppInLaunchingProvidersLocked(app, false)) { 12747 restart = true; 12748 } 12749 12750 // Unregister from connected content providers. 12751 if (!app.conProviders.isEmpty()) { 12752 for (int i=0; i<app.conProviders.size(); i++) { 12753 ContentProviderConnection conn = app.conProviders.get(i); 12754 conn.provider.connections.remove(conn); 12755 } 12756 app.conProviders.clear(); 12757 } 12758 12759 // At this point there may be remaining entries in mLaunchingProviders 12760 // where we were the only one waiting, so they are no longer of use. 12761 // Look for these and clean up if found. 12762 // XXX Commented out for now. Trying to figure out a way to reproduce 12763 // the actual situation to identify what is actually going on. 12764 if (false) { 12765 for (int i=0; i<mLaunchingProviders.size(); i++) { 12766 ContentProviderRecord cpr = (ContentProviderRecord) 12767 mLaunchingProviders.get(i); 12768 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12769 synchronized (cpr) { 12770 cpr.launchingApp = null; 12771 cpr.notifyAll(); 12772 } 12773 } 12774 } 12775 } 12776 12777 skipCurrentReceiverLocked(app); 12778 12779 // Unregister any receivers. 12780 for (int i=app.receivers.size()-1; i>=0; i--) { 12781 removeReceiverLocked(app.receivers.valueAt(i)); 12782 } 12783 app.receivers.clear(); 12784 12785 // If the app is undergoing backup, tell the backup manager about it 12786 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12787 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12788 + mBackupTarget.appInfo + " died during backup"); 12789 try { 12790 IBackupManager bm = IBackupManager.Stub.asInterface( 12791 ServiceManager.getService(Context.BACKUP_SERVICE)); 12792 bm.agentDisconnected(app.info.packageName); 12793 } catch (RemoteException e) { 12794 // can't happen; backup manager is local 12795 } 12796 } 12797 12798 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12799 ProcessChangeItem item = mPendingProcessChanges.get(i); 12800 if (item.pid == app.pid) { 12801 mPendingProcessChanges.remove(i); 12802 mAvailProcessChanges.add(item); 12803 } 12804 } 12805 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12806 12807 // If the caller is restarting this app, then leave it in its 12808 // current lists and let the caller take care of it. 12809 if (restarting) { 12810 return; 12811 } 12812 12813 if (!app.persistent || app.isolated) { 12814 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12815 "Removing non-persistent process during cleanup: " + app); 12816 mProcessNames.remove(app.processName, app.uid); 12817 mIsolatedProcesses.remove(app.uid); 12818 if (mHeavyWeightProcess == app) { 12819 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12820 mHeavyWeightProcess.userId, 0)); 12821 mHeavyWeightProcess = null; 12822 } 12823 } else if (!app.removed) { 12824 // This app is persistent, so we need to keep its record around. 12825 // If it is not already on the pending app list, add it there 12826 // and start a new process for it. 12827 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12828 mPersistentStartingProcesses.add(app); 12829 restart = true; 12830 } 12831 } 12832 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12833 "Clean-up removing on hold: " + app); 12834 mProcessesOnHold.remove(app); 12835 12836 if (app == mHomeProcess) { 12837 mHomeProcess = null; 12838 } 12839 if (app == mPreviousProcess) { 12840 mPreviousProcess = null; 12841 } 12842 12843 if (restart && !app.isolated) { 12844 // We have components that still need to be running in the 12845 // process, so re-launch it. 12846 mProcessNames.put(app.processName, app.uid, app); 12847 startProcessLocked(app, "restart", app.processName); 12848 } else if (app.pid > 0 && app.pid != MY_PID) { 12849 // Goodbye! 12850 boolean removed; 12851 synchronized (mPidsSelfLocked) { 12852 mPidsSelfLocked.remove(app.pid); 12853 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12854 } 12855 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12856 app.processName, app.info.uid); 12857 if (app.isolated) { 12858 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12859 } 12860 app.setPid(0); 12861 } 12862 } 12863 12864 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12865 // Look through the content providers we are waiting to have launched, 12866 // and if any run in this process then either schedule a restart of 12867 // the process or kill the client waiting for it if this process has 12868 // gone bad. 12869 int NL = mLaunchingProviders.size(); 12870 boolean restart = false; 12871 for (int i=0; i<NL; i++) { 12872 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12873 if (cpr.launchingApp == app) { 12874 if (!alwaysBad && !app.bad) { 12875 restart = true; 12876 } else { 12877 removeDyingProviderLocked(app, cpr, true); 12878 // cpr should have been removed from mLaunchingProviders 12879 NL = mLaunchingProviders.size(); 12880 i--; 12881 } 12882 } 12883 } 12884 return restart; 12885 } 12886 12887 // ========================================================= 12888 // SERVICES 12889 // ========================================================= 12890 12891 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12892 int flags) { 12893 enforceNotIsolatedCaller("getServices"); 12894 synchronized (this) { 12895 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12896 } 12897 } 12898 12899 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12900 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12901 synchronized (this) { 12902 return mServices.getRunningServiceControlPanelLocked(name); 12903 } 12904 } 12905 12906 public ComponentName startService(IApplicationThread caller, Intent service, 12907 String resolvedType, int userId) { 12908 enforceNotIsolatedCaller("startService"); 12909 // Refuse possible leaked file descriptors 12910 if (service != null && service.hasFileDescriptors() == true) { 12911 throw new IllegalArgumentException("File descriptors passed in Intent"); 12912 } 12913 12914 if (DEBUG_SERVICE) 12915 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12916 synchronized(this) { 12917 final int callingPid = Binder.getCallingPid(); 12918 final int callingUid = Binder.getCallingUid(); 12919 final long origId = Binder.clearCallingIdentity(); 12920 ComponentName res = mServices.startServiceLocked(caller, service, 12921 resolvedType, callingPid, callingUid, userId); 12922 Binder.restoreCallingIdentity(origId); 12923 return res; 12924 } 12925 } 12926 12927 ComponentName startServiceInPackage(int uid, 12928 Intent service, String resolvedType, int userId) { 12929 synchronized(this) { 12930 if (DEBUG_SERVICE) 12931 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12932 final long origId = Binder.clearCallingIdentity(); 12933 ComponentName res = mServices.startServiceLocked(null, service, 12934 resolvedType, -1, uid, userId); 12935 Binder.restoreCallingIdentity(origId); 12936 return res; 12937 } 12938 } 12939 12940 public int stopService(IApplicationThread caller, Intent service, 12941 String resolvedType, int userId) { 12942 enforceNotIsolatedCaller("stopService"); 12943 // Refuse possible leaked file descriptors 12944 if (service != null && service.hasFileDescriptors() == true) { 12945 throw new IllegalArgumentException("File descriptors passed in Intent"); 12946 } 12947 12948 synchronized(this) { 12949 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12950 } 12951 } 12952 12953 public IBinder peekService(Intent service, String resolvedType) { 12954 enforceNotIsolatedCaller("peekService"); 12955 // Refuse possible leaked file descriptors 12956 if (service != null && service.hasFileDescriptors() == true) { 12957 throw new IllegalArgumentException("File descriptors passed in Intent"); 12958 } 12959 synchronized(this) { 12960 return mServices.peekServiceLocked(service, resolvedType); 12961 } 12962 } 12963 12964 public boolean stopServiceToken(ComponentName className, IBinder token, 12965 int startId) { 12966 synchronized(this) { 12967 return mServices.stopServiceTokenLocked(className, token, startId); 12968 } 12969 } 12970 12971 public void setServiceForeground(ComponentName className, IBinder token, 12972 int id, Notification notification, boolean removeNotification) { 12973 synchronized(this) { 12974 mServices.setServiceForegroundLocked(className, token, id, notification, 12975 removeNotification); 12976 } 12977 } 12978 12979 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12980 boolean requireFull, String name, String callerPackage) { 12981 final int callingUserId = UserHandle.getUserId(callingUid); 12982 if (callingUserId != userId) { 12983 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12984 if ((requireFull || checkComponentPermission( 12985 android.Manifest.permission.INTERACT_ACROSS_USERS, 12986 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12987 && checkComponentPermission( 12988 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12989 callingPid, callingUid, -1, true) 12990 != PackageManager.PERMISSION_GRANTED) { 12991 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12992 // In this case, they would like to just execute as their 12993 // owner user instead of failing. 12994 userId = callingUserId; 12995 } else { 12996 StringBuilder builder = new StringBuilder(128); 12997 builder.append("Permission Denial: "); 12998 builder.append(name); 12999 if (callerPackage != null) { 13000 builder.append(" from "); 13001 builder.append(callerPackage); 13002 } 13003 builder.append(" asks to run as user "); 13004 builder.append(userId); 13005 builder.append(" but is calling from user "); 13006 builder.append(UserHandle.getUserId(callingUid)); 13007 builder.append("; this requires "); 13008 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13009 if (!requireFull) { 13010 builder.append(" or "); 13011 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13012 } 13013 String msg = builder.toString(); 13014 Slog.w(TAG, msg); 13015 throw new SecurityException(msg); 13016 } 13017 } 13018 } 13019 if (userId == UserHandle.USER_CURRENT 13020 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13021 // Note that we may be accessing this outside of a lock... 13022 // shouldn't be a big deal, if this is being called outside 13023 // of a locked context there is intrinsically a race with 13024 // the value the caller will receive and someone else changing it. 13025 userId = mCurrentUserId; 13026 } 13027 if (!allowAll && userId < 0) { 13028 throw new IllegalArgumentException( 13029 "Call does not support special user #" + userId); 13030 } 13031 } 13032 return userId; 13033 } 13034 13035 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13036 String className, int flags) { 13037 boolean result = false; 13038 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13039 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13040 if (ActivityManager.checkUidPermission( 13041 android.Manifest.permission.INTERACT_ACROSS_USERS, 13042 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13043 ComponentName comp = new ComponentName(aInfo.packageName, className); 13044 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13045 + " requests FLAG_SINGLE_USER, but app does not hold " 13046 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13047 Slog.w(TAG, msg); 13048 throw new SecurityException(msg); 13049 } 13050 result = true; 13051 } 13052 } else if (componentProcessName == aInfo.packageName) { 13053 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13054 } else if ("system".equals(componentProcessName)) { 13055 result = true; 13056 } 13057 if (DEBUG_MU) { 13058 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13059 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13060 } 13061 return result; 13062 } 13063 13064 public int bindService(IApplicationThread caller, IBinder token, 13065 Intent service, String resolvedType, 13066 IServiceConnection connection, int flags, int userId) { 13067 enforceNotIsolatedCaller("bindService"); 13068 // Refuse possible leaked file descriptors 13069 if (service != null && service.hasFileDescriptors() == true) { 13070 throw new IllegalArgumentException("File descriptors passed in Intent"); 13071 } 13072 13073 synchronized(this) { 13074 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13075 connection, flags, userId); 13076 } 13077 } 13078 13079 public boolean unbindService(IServiceConnection connection) { 13080 synchronized (this) { 13081 return mServices.unbindServiceLocked(connection); 13082 } 13083 } 13084 13085 public void publishService(IBinder token, Intent intent, IBinder service) { 13086 // Refuse possible leaked file descriptors 13087 if (intent != null && intent.hasFileDescriptors() == true) { 13088 throw new IllegalArgumentException("File descriptors passed in Intent"); 13089 } 13090 13091 synchronized(this) { 13092 if (!(token instanceof ServiceRecord)) { 13093 throw new IllegalArgumentException("Invalid service token"); 13094 } 13095 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13096 } 13097 } 13098 13099 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13100 // Refuse possible leaked file descriptors 13101 if (intent != null && intent.hasFileDescriptors() == true) { 13102 throw new IllegalArgumentException("File descriptors passed in Intent"); 13103 } 13104 13105 synchronized(this) { 13106 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13107 } 13108 } 13109 13110 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13111 synchronized(this) { 13112 if (!(token instanceof ServiceRecord)) { 13113 throw new IllegalArgumentException("Invalid service token"); 13114 } 13115 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13116 } 13117 } 13118 13119 // ========================================================= 13120 // BACKUP AND RESTORE 13121 // ========================================================= 13122 13123 // Cause the target app to be launched if necessary and its backup agent 13124 // instantiated. The backup agent will invoke backupAgentCreated() on the 13125 // activity manager to announce its creation. 13126 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13127 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13128 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13129 13130 synchronized(this) { 13131 // !!! TODO: currently no check here that we're already bound 13132 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13133 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13134 synchronized (stats) { 13135 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13136 } 13137 13138 // Backup agent is now in use, its package can't be stopped. 13139 try { 13140 AppGlobals.getPackageManager().setPackageStoppedState( 13141 app.packageName, false, UserHandle.getUserId(app.uid)); 13142 } catch (RemoteException e) { 13143 } catch (IllegalArgumentException e) { 13144 Slog.w(TAG, "Failed trying to unstop package " 13145 + app.packageName + ": " + e); 13146 } 13147 13148 BackupRecord r = new BackupRecord(ss, app, backupMode); 13149 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13150 ? new ComponentName(app.packageName, app.backupAgentName) 13151 : new ComponentName("android", "FullBackupAgent"); 13152 // startProcessLocked() returns existing proc's record if it's already running 13153 ProcessRecord proc = startProcessLocked(app.processName, app, 13154 false, 0, "backup", hostingName, false, false, false); 13155 if (proc == null) { 13156 Slog.e(TAG, "Unable to start backup agent process " + r); 13157 return false; 13158 } 13159 13160 r.app = proc; 13161 mBackupTarget = r; 13162 mBackupAppName = app.packageName; 13163 13164 // Try not to kill the process during backup 13165 updateOomAdjLocked(proc); 13166 13167 // If the process is already attached, schedule the creation of the backup agent now. 13168 // If it is not yet live, this will be done when it attaches to the framework. 13169 if (proc.thread != null) { 13170 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13171 try { 13172 proc.thread.scheduleCreateBackupAgent(app, 13173 compatibilityInfoForPackageLocked(app), backupMode); 13174 } catch (RemoteException e) { 13175 // Will time out on the backup manager side 13176 } 13177 } else { 13178 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13179 } 13180 // Invariants: at this point, the target app process exists and the application 13181 // is either already running or in the process of coming up. mBackupTarget and 13182 // mBackupAppName describe the app, so that when it binds back to the AM we 13183 // know that it's scheduled for a backup-agent operation. 13184 } 13185 13186 return true; 13187 } 13188 13189 @Override 13190 public void clearPendingBackup() { 13191 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13192 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13193 13194 synchronized (this) { 13195 mBackupTarget = null; 13196 mBackupAppName = null; 13197 } 13198 } 13199 13200 // A backup agent has just come up 13201 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13202 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13203 + " = " + agent); 13204 13205 synchronized(this) { 13206 if (!agentPackageName.equals(mBackupAppName)) { 13207 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13208 return; 13209 } 13210 } 13211 13212 long oldIdent = Binder.clearCallingIdentity(); 13213 try { 13214 IBackupManager bm = IBackupManager.Stub.asInterface( 13215 ServiceManager.getService(Context.BACKUP_SERVICE)); 13216 bm.agentConnected(agentPackageName, agent); 13217 } catch (RemoteException e) { 13218 // can't happen; the backup manager service is local 13219 } catch (Exception e) { 13220 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13221 e.printStackTrace(); 13222 } finally { 13223 Binder.restoreCallingIdentity(oldIdent); 13224 } 13225 } 13226 13227 // done with this agent 13228 public void unbindBackupAgent(ApplicationInfo appInfo) { 13229 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13230 if (appInfo == null) { 13231 Slog.w(TAG, "unbind backup agent for null app"); 13232 return; 13233 } 13234 13235 synchronized(this) { 13236 try { 13237 if (mBackupAppName == null) { 13238 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13239 return; 13240 } 13241 13242 if (!mBackupAppName.equals(appInfo.packageName)) { 13243 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13244 return; 13245 } 13246 13247 // Not backing this app up any more; reset its OOM adjustment 13248 final ProcessRecord proc = mBackupTarget.app; 13249 updateOomAdjLocked(proc); 13250 13251 // If the app crashed during backup, 'thread' will be null here 13252 if (proc.thread != null) { 13253 try { 13254 proc.thread.scheduleDestroyBackupAgent(appInfo, 13255 compatibilityInfoForPackageLocked(appInfo)); 13256 } catch (Exception e) { 13257 Slog.e(TAG, "Exception when unbinding backup agent:"); 13258 e.printStackTrace(); 13259 } 13260 } 13261 } finally { 13262 mBackupTarget = null; 13263 mBackupAppName = null; 13264 } 13265 } 13266 } 13267 // ========================================================= 13268 // BROADCASTS 13269 // ========================================================= 13270 13271 private final List getStickiesLocked(String action, IntentFilter filter, 13272 List cur, int userId) { 13273 final ContentResolver resolver = mContext.getContentResolver(); 13274 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13275 if (stickies == null) { 13276 return cur; 13277 } 13278 final ArrayList<Intent> list = stickies.get(action); 13279 if (list == null) { 13280 return cur; 13281 } 13282 int N = list.size(); 13283 for (int i=0; i<N; i++) { 13284 Intent intent = list.get(i); 13285 if (filter.match(resolver, intent, true, TAG) >= 0) { 13286 if (cur == null) { 13287 cur = new ArrayList<Intent>(); 13288 } 13289 cur.add(intent); 13290 } 13291 } 13292 return cur; 13293 } 13294 13295 boolean isPendingBroadcastProcessLocked(int pid) { 13296 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13297 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13298 } 13299 13300 void skipPendingBroadcastLocked(int pid) { 13301 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13302 for (BroadcastQueue queue : mBroadcastQueues) { 13303 queue.skipPendingBroadcastLocked(pid); 13304 } 13305 } 13306 13307 // The app just attached; send any pending broadcasts that it should receive 13308 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13309 boolean didSomething = false; 13310 for (BroadcastQueue queue : mBroadcastQueues) { 13311 didSomething |= queue.sendPendingBroadcastsLocked(app); 13312 } 13313 return didSomething; 13314 } 13315 13316 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13317 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13318 enforceNotIsolatedCaller("registerReceiver"); 13319 int callingUid; 13320 int callingPid; 13321 synchronized(this) { 13322 ProcessRecord callerApp = null; 13323 if (caller != null) { 13324 callerApp = getRecordForAppLocked(caller); 13325 if (callerApp == null) { 13326 throw new SecurityException( 13327 "Unable to find app for caller " + caller 13328 + " (pid=" + Binder.getCallingPid() 13329 + ") when registering receiver " + receiver); 13330 } 13331 if (callerApp.info.uid != Process.SYSTEM_UID && 13332 !callerApp.pkgList.containsKey(callerPackage) && 13333 !"android".equals(callerPackage)) { 13334 throw new SecurityException("Given caller package " + callerPackage 13335 + " is not running in process " + callerApp); 13336 } 13337 callingUid = callerApp.info.uid; 13338 callingPid = callerApp.pid; 13339 } else { 13340 callerPackage = null; 13341 callingUid = Binder.getCallingUid(); 13342 callingPid = Binder.getCallingPid(); 13343 } 13344 13345 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13346 true, true, "registerReceiver", callerPackage); 13347 13348 List allSticky = null; 13349 13350 // Look for any matching sticky broadcasts... 13351 Iterator actions = filter.actionsIterator(); 13352 if (actions != null) { 13353 while (actions.hasNext()) { 13354 String action = (String)actions.next(); 13355 allSticky = getStickiesLocked(action, filter, allSticky, 13356 UserHandle.USER_ALL); 13357 allSticky = getStickiesLocked(action, filter, allSticky, 13358 UserHandle.getUserId(callingUid)); 13359 } 13360 } else { 13361 allSticky = getStickiesLocked(null, filter, allSticky, 13362 UserHandle.USER_ALL); 13363 allSticky = getStickiesLocked(null, filter, allSticky, 13364 UserHandle.getUserId(callingUid)); 13365 } 13366 13367 // The first sticky in the list is returned directly back to 13368 // the client. 13369 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13370 13371 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13372 + ": " + sticky); 13373 13374 if (receiver == null) { 13375 return sticky; 13376 } 13377 13378 ReceiverList rl 13379 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13380 if (rl == null) { 13381 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13382 userId, receiver); 13383 if (rl.app != null) { 13384 rl.app.receivers.add(rl); 13385 } else { 13386 try { 13387 receiver.asBinder().linkToDeath(rl, 0); 13388 } catch (RemoteException e) { 13389 return sticky; 13390 } 13391 rl.linkedToDeath = true; 13392 } 13393 mRegisteredReceivers.put(receiver.asBinder(), rl); 13394 } else if (rl.uid != callingUid) { 13395 throw new IllegalArgumentException( 13396 "Receiver requested to register for uid " + callingUid 13397 + " was previously registered for uid " + rl.uid); 13398 } else if (rl.pid != callingPid) { 13399 throw new IllegalArgumentException( 13400 "Receiver requested to register for pid " + callingPid 13401 + " was previously registered for pid " + rl.pid); 13402 } else if (rl.userId != userId) { 13403 throw new IllegalArgumentException( 13404 "Receiver requested to register for user " + userId 13405 + " was previously registered for user " + rl.userId); 13406 } 13407 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13408 permission, callingUid, userId); 13409 rl.add(bf); 13410 if (!bf.debugCheck()) { 13411 Slog.w(TAG, "==> For Dynamic broadast"); 13412 } 13413 mReceiverResolver.addFilter(bf); 13414 13415 // Enqueue broadcasts for all existing stickies that match 13416 // this filter. 13417 if (allSticky != null) { 13418 ArrayList receivers = new ArrayList(); 13419 receivers.add(bf); 13420 13421 int N = allSticky.size(); 13422 for (int i=0; i<N; i++) { 13423 Intent intent = (Intent)allSticky.get(i); 13424 BroadcastQueue queue = broadcastQueueForIntent(intent); 13425 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13426 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13427 null, null, false, true, true, -1); 13428 queue.enqueueParallelBroadcastLocked(r); 13429 queue.scheduleBroadcastsLocked(); 13430 } 13431 } 13432 13433 return sticky; 13434 } 13435 } 13436 13437 public void unregisterReceiver(IIntentReceiver receiver) { 13438 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13439 13440 final long origId = Binder.clearCallingIdentity(); 13441 try { 13442 boolean doTrim = false; 13443 13444 synchronized(this) { 13445 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13446 if (rl != null) { 13447 if (rl.curBroadcast != null) { 13448 BroadcastRecord r = rl.curBroadcast; 13449 final boolean doNext = finishReceiverLocked( 13450 receiver.asBinder(), r.resultCode, r.resultData, 13451 r.resultExtras, r.resultAbort); 13452 if (doNext) { 13453 doTrim = true; 13454 r.queue.processNextBroadcast(false); 13455 } 13456 } 13457 13458 if (rl.app != null) { 13459 rl.app.receivers.remove(rl); 13460 } 13461 removeReceiverLocked(rl); 13462 if (rl.linkedToDeath) { 13463 rl.linkedToDeath = false; 13464 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13465 } 13466 } 13467 } 13468 13469 // If we actually concluded any broadcasts, we might now be able 13470 // to trim the recipients' apps from our working set 13471 if (doTrim) { 13472 trimApplications(); 13473 return; 13474 } 13475 13476 } finally { 13477 Binder.restoreCallingIdentity(origId); 13478 } 13479 } 13480 13481 void removeReceiverLocked(ReceiverList rl) { 13482 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13483 int N = rl.size(); 13484 for (int i=0; i<N; i++) { 13485 mReceiverResolver.removeFilter(rl.get(i)); 13486 } 13487 } 13488 13489 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13490 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13491 ProcessRecord r = mLruProcesses.get(i); 13492 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13493 try { 13494 r.thread.dispatchPackageBroadcast(cmd, packages); 13495 } catch (RemoteException ex) { 13496 } 13497 } 13498 } 13499 } 13500 13501 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13502 int[] users) { 13503 List<ResolveInfo> receivers = null; 13504 try { 13505 HashSet<ComponentName> singleUserReceivers = null; 13506 boolean scannedFirstReceivers = false; 13507 for (int user : users) { 13508 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13509 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13510 if (user != 0 && newReceivers != null) { 13511 // If this is not the primary user, we need to check for 13512 // any receivers that should be filtered out. 13513 for (int i=0; i<newReceivers.size(); i++) { 13514 ResolveInfo ri = newReceivers.get(i); 13515 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13516 newReceivers.remove(i); 13517 i--; 13518 } 13519 } 13520 } 13521 if (newReceivers != null && newReceivers.size() == 0) { 13522 newReceivers = null; 13523 } 13524 if (receivers == null) { 13525 receivers = newReceivers; 13526 } else if (newReceivers != null) { 13527 // We need to concatenate the additional receivers 13528 // found with what we have do far. This would be easy, 13529 // but we also need to de-dup any receivers that are 13530 // singleUser. 13531 if (!scannedFirstReceivers) { 13532 // Collect any single user receivers we had already retrieved. 13533 scannedFirstReceivers = true; 13534 for (int i=0; i<receivers.size(); i++) { 13535 ResolveInfo ri = receivers.get(i); 13536 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13537 ComponentName cn = new ComponentName( 13538 ri.activityInfo.packageName, ri.activityInfo.name); 13539 if (singleUserReceivers == null) { 13540 singleUserReceivers = new HashSet<ComponentName>(); 13541 } 13542 singleUserReceivers.add(cn); 13543 } 13544 } 13545 } 13546 // Add the new results to the existing results, tracking 13547 // and de-dupping single user receivers. 13548 for (int i=0; i<newReceivers.size(); i++) { 13549 ResolveInfo ri = newReceivers.get(i); 13550 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13551 ComponentName cn = new ComponentName( 13552 ri.activityInfo.packageName, ri.activityInfo.name); 13553 if (singleUserReceivers == null) { 13554 singleUserReceivers = new HashSet<ComponentName>(); 13555 } 13556 if (!singleUserReceivers.contains(cn)) { 13557 singleUserReceivers.add(cn); 13558 receivers.add(ri); 13559 } 13560 } else { 13561 receivers.add(ri); 13562 } 13563 } 13564 } 13565 } 13566 } catch (RemoteException ex) { 13567 // pm is in same process, this will never happen. 13568 } 13569 return receivers; 13570 } 13571 13572 private final int broadcastIntentLocked(ProcessRecord callerApp, 13573 String callerPackage, Intent intent, String resolvedType, 13574 IIntentReceiver resultTo, int resultCode, String resultData, 13575 Bundle map, String requiredPermission, int appOp, 13576 boolean ordered, boolean sticky, int callingPid, int callingUid, 13577 int userId) { 13578 intent = new Intent(intent); 13579 13580 // By default broadcasts do not go to stopped apps. 13581 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13582 13583 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13584 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13585 + " ordered=" + ordered + " userid=" + userId); 13586 if ((resultTo != null) && !ordered) { 13587 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13588 } 13589 13590 userId = handleIncomingUser(callingPid, callingUid, userId, 13591 true, false, "broadcast", callerPackage); 13592 13593 // Make sure that the user who is receiving this broadcast is started. 13594 // If not, we will just skip it. 13595 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13596 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13597 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13598 Slog.w(TAG, "Skipping broadcast of " + intent 13599 + ": user " + userId + " is stopped"); 13600 return ActivityManager.BROADCAST_SUCCESS; 13601 } 13602 } 13603 13604 /* 13605 * Prevent non-system code (defined here to be non-persistent 13606 * processes) from sending protected broadcasts. 13607 */ 13608 int callingAppId = UserHandle.getAppId(callingUid); 13609 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13610 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13611 callingUid == 0) { 13612 // Always okay. 13613 } else if (callerApp == null || !callerApp.persistent) { 13614 try { 13615 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13616 intent.getAction())) { 13617 String msg = "Permission Denial: not allowed to send broadcast " 13618 + intent.getAction() + " from pid=" 13619 + callingPid + ", uid=" + callingUid; 13620 Slog.w(TAG, msg); 13621 throw new SecurityException(msg); 13622 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13623 // Special case for compatibility: we don't want apps to send this, 13624 // but historically it has not been protected and apps may be using it 13625 // to poke their own app widget. So, instead of making it protected, 13626 // just limit it to the caller. 13627 if (callerApp == null) { 13628 String msg = "Permission Denial: not allowed to send broadcast " 13629 + intent.getAction() + " from unknown caller."; 13630 Slog.w(TAG, msg); 13631 throw new SecurityException(msg); 13632 } else if (intent.getComponent() != null) { 13633 // They are good enough to send to an explicit component... verify 13634 // it is being sent to the calling app. 13635 if (!intent.getComponent().getPackageName().equals( 13636 callerApp.info.packageName)) { 13637 String msg = "Permission Denial: not allowed to send broadcast " 13638 + intent.getAction() + " to " 13639 + intent.getComponent().getPackageName() + " from " 13640 + callerApp.info.packageName; 13641 Slog.w(TAG, msg); 13642 throw new SecurityException(msg); 13643 } 13644 } else { 13645 // Limit broadcast to their own package. 13646 intent.setPackage(callerApp.info.packageName); 13647 } 13648 } 13649 } catch (RemoteException e) { 13650 Slog.w(TAG, "Remote exception", e); 13651 return ActivityManager.BROADCAST_SUCCESS; 13652 } 13653 } 13654 13655 // Handle special intents: if this broadcast is from the package 13656 // manager about a package being removed, we need to remove all of 13657 // its activities from the history stack. 13658 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13659 intent.getAction()); 13660 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13661 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13662 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13663 || uidRemoved) { 13664 if (checkComponentPermission( 13665 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13666 callingPid, callingUid, -1, true) 13667 == PackageManager.PERMISSION_GRANTED) { 13668 if (uidRemoved) { 13669 final Bundle intentExtras = intent.getExtras(); 13670 final int uid = intentExtras != null 13671 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13672 if (uid >= 0) { 13673 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13674 synchronized (bs) { 13675 bs.removeUidStatsLocked(uid); 13676 } 13677 mAppOpsService.uidRemoved(uid); 13678 } 13679 } else { 13680 // If resources are unavailable just force stop all 13681 // those packages and flush the attribute cache as well. 13682 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13683 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13684 if (list != null && (list.length > 0)) { 13685 for (String pkg : list) { 13686 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13687 "storage unmount"); 13688 } 13689 sendPackageBroadcastLocked( 13690 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13691 } 13692 } else { 13693 Uri data = intent.getData(); 13694 String ssp; 13695 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13696 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13697 intent.getAction()); 13698 boolean fullUninstall = removed && 13699 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13700 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13701 forceStopPackageLocked(ssp, UserHandle.getAppId( 13702 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13703 false, fullUninstall, userId, 13704 removed ? "pkg removed" : "pkg changed"); 13705 } 13706 if (removed) { 13707 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13708 new String[] {ssp}, userId); 13709 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13710 mAppOpsService.packageRemoved( 13711 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13712 13713 // Remove all permissions granted from/to this package 13714 removeUriPermissionsForPackageLocked(ssp, userId, true); 13715 } 13716 } 13717 } 13718 } 13719 } 13720 } else { 13721 String msg = "Permission Denial: " + intent.getAction() 13722 + " broadcast from " + callerPackage + " (pid=" + callingPid 13723 + ", uid=" + callingUid + ")" 13724 + " requires " 13725 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13726 Slog.w(TAG, msg); 13727 throw new SecurityException(msg); 13728 } 13729 13730 // Special case for adding a package: by default turn on compatibility 13731 // mode. 13732 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13733 Uri data = intent.getData(); 13734 String ssp; 13735 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13736 mCompatModePackages.handlePackageAddedLocked(ssp, 13737 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13738 } 13739 } 13740 13741 /* 13742 * If this is the time zone changed action, queue up a message that will reset the timezone 13743 * of all currently running processes. This message will get queued up before the broadcast 13744 * happens. 13745 */ 13746 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13747 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13748 } 13749 13750 /* 13751 * If the user set the time, let all running processes know. 13752 */ 13753 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13754 final int is24Hour = intent.getBooleanExtra( 13755 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13756 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13757 } 13758 13759 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13760 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13761 } 13762 13763 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13764 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13765 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13766 } 13767 13768 // Add to the sticky list if requested. 13769 if (sticky) { 13770 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13771 callingPid, callingUid) 13772 != PackageManager.PERMISSION_GRANTED) { 13773 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13774 + callingPid + ", uid=" + callingUid 13775 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13776 Slog.w(TAG, msg); 13777 throw new SecurityException(msg); 13778 } 13779 if (requiredPermission != null) { 13780 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13781 + " and enforce permission " + requiredPermission); 13782 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13783 } 13784 if (intent.getComponent() != null) { 13785 throw new SecurityException( 13786 "Sticky broadcasts can't target a specific component"); 13787 } 13788 // We use userId directly here, since the "all" target is maintained 13789 // as a separate set of sticky broadcasts. 13790 if (userId != UserHandle.USER_ALL) { 13791 // But first, if this is not a broadcast to all users, then 13792 // make sure it doesn't conflict with an existing broadcast to 13793 // all users. 13794 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13795 UserHandle.USER_ALL); 13796 if (stickies != null) { 13797 ArrayList<Intent> list = stickies.get(intent.getAction()); 13798 if (list != null) { 13799 int N = list.size(); 13800 int i; 13801 for (i=0; i<N; i++) { 13802 if (intent.filterEquals(list.get(i))) { 13803 throw new IllegalArgumentException( 13804 "Sticky broadcast " + intent + " for user " 13805 + userId + " conflicts with existing global broadcast"); 13806 } 13807 } 13808 } 13809 } 13810 } 13811 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13812 if (stickies == null) { 13813 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13814 mStickyBroadcasts.put(userId, stickies); 13815 } 13816 ArrayList<Intent> list = stickies.get(intent.getAction()); 13817 if (list == null) { 13818 list = new ArrayList<Intent>(); 13819 stickies.put(intent.getAction(), list); 13820 } 13821 int N = list.size(); 13822 int i; 13823 for (i=0; i<N; i++) { 13824 if (intent.filterEquals(list.get(i))) { 13825 // This sticky already exists, replace it. 13826 list.set(i, new Intent(intent)); 13827 break; 13828 } 13829 } 13830 if (i >= N) { 13831 list.add(new Intent(intent)); 13832 } 13833 } 13834 13835 int[] users; 13836 if (userId == UserHandle.USER_ALL) { 13837 // Caller wants broadcast to go to all started users. 13838 users = mStartedUserArray; 13839 } else { 13840 // Caller wants broadcast to go to one specific user. 13841 users = new int[] {userId}; 13842 } 13843 13844 // Figure out who all will receive this broadcast. 13845 List receivers = null; 13846 List<BroadcastFilter> registeredReceivers = null; 13847 // Need to resolve the intent to interested receivers... 13848 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13849 == 0) { 13850 receivers = collectReceiverComponents(intent, resolvedType, users); 13851 } 13852 if (intent.getComponent() == null) { 13853 registeredReceivers = mReceiverResolver.queryIntent(intent, 13854 resolvedType, false, userId); 13855 } 13856 13857 final boolean replacePending = 13858 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13859 13860 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13861 + " replacePending=" + replacePending); 13862 13863 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13864 if (!ordered && NR > 0) { 13865 // If we are not serializing this broadcast, then send the 13866 // registered receivers separately so they don't wait for the 13867 // components to be launched. 13868 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13869 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13870 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13871 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13872 ordered, sticky, false, userId); 13873 if (DEBUG_BROADCAST) Slog.v( 13874 TAG, "Enqueueing parallel broadcast " + r); 13875 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13876 if (!replaced) { 13877 queue.enqueueParallelBroadcastLocked(r); 13878 queue.scheduleBroadcastsLocked(); 13879 } 13880 registeredReceivers = null; 13881 NR = 0; 13882 } 13883 13884 // Merge into one list. 13885 int ir = 0; 13886 if (receivers != null) { 13887 // A special case for PACKAGE_ADDED: do not allow the package 13888 // being added to see this broadcast. This prevents them from 13889 // using this as a back door to get run as soon as they are 13890 // installed. Maybe in the future we want to have a special install 13891 // broadcast or such for apps, but we'd like to deliberately make 13892 // this decision. 13893 String skipPackages[] = null; 13894 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13895 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13896 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13897 Uri data = intent.getData(); 13898 if (data != null) { 13899 String pkgName = data.getSchemeSpecificPart(); 13900 if (pkgName != null) { 13901 skipPackages = new String[] { pkgName }; 13902 } 13903 } 13904 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13905 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13906 } 13907 if (skipPackages != null && (skipPackages.length > 0)) { 13908 for (String skipPackage : skipPackages) { 13909 if (skipPackage != null) { 13910 int NT = receivers.size(); 13911 for (int it=0; it<NT; it++) { 13912 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13913 if (curt.activityInfo.packageName.equals(skipPackage)) { 13914 receivers.remove(it); 13915 it--; 13916 NT--; 13917 } 13918 } 13919 } 13920 } 13921 } 13922 13923 int NT = receivers != null ? receivers.size() : 0; 13924 int it = 0; 13925 ResolveInfo curt = null; 13926 BroadcastFilter curr = null; 13927 while (it < NT && ir < NR) { 13928 if (curt == null) { 13929 curt = (ResolveInfo)receivers.get(it); 13930 } 13931 if (curr == null) { 13932 curr = registeredReceivers.get(ir); 13933 } 13934 if (curr.getPriority() >= curt.priority) { 13935 // Insert this broadcast record into the final list. 13936 receivers.add(it, curr); 13937 ir++; 13938 curr = null; 13939 it++; 13940 NT++; 13941 } else { 13942 // Skip to the next ResolveInfo in the final list. 13943 it++; 13944 curt = null; 13945 } 13946 } 13947 } 13948 while (ir < NR) { 13949 if (receivers == null) { 13950 receivers = new ArrayList(); 13951 } 13952 receivers.add(registeredReceivers.get(ir)); 13953 ir++; 13954 } 13955 13956 if ((receivers != null && receivers.size() > 0) 13957 || resultTo != null) { 13958 BroadcastQueue queue = broadcastQueueForIntent(intent); 13959 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13960 callerPackage, callingPid, callingUid, resolvedType, 13961 requiredPermission, appOp, receivers, resultTo, resultCode, 13962 resultData, map, ordered, sticky, false, userId); 13963 if (DEBUG_BROADCAST) Slog.v( 13964 TAG, "Enqueueing ordered broadcast " + r 13965 + ": prev had " + queue.mOrderedBroadcasts.size()); 13966 if (DEBUG_BROADCAST) { 13967 int seq = r.intent.getIntExtra("seq", -1); 13968 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13969 } 13970 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13971 if (!replaced) { 13972 queue.enqueueOrderedBroadcastLocked(r); 13973 queue.scheduleBroadcastsLocked(); 13974 } 13975 } 13976 13977 return ActivityManager.BROADCAST_SUCCESS; 13978 } 13979 13980 final Intent verifyBroadcastLocked(Intent intent) { 13981 // Refuse possible leaked file descriptors 13982 if (intent != null && intent.hasFileDescriptors() == true) { 13983 throw new IllegalArgumentException("File descriptors passed in Intent"); 13984 } 13985 13986 int flags = intent.getFlags(); 13987 13988 if (!mProcessesReady) { 13989 // if the caller really truly claims to know what they're doing, go 13990 // ahead and allow the broadcast without launching any receivers 13991 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13992 intent = new Intent(intent); 13993 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13994 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13995 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13996 + " before boot completion"); 13997 throw new IllegalStateException("Cannot broadcast before boot completed"); 13998 } 13999 } 14000 14001 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14002 throw new IllegalArgumentException( 14003 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14004 } 14005 14006 return intent; 14007 } 14008 14009 public final int broadcastIntent(IApplicationThread caller, 14010 Intent intent, String resolvedType, IIntentReceiver resultTo, 14011 int resultCode, String resultData, Bundle map, 14012 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14013 enforceNotIsolatedCaller("broadcastIntent"); 14014 synchronized(this) { 14015 intent = verifyBroadcastLocked(intent); 14016 14017 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14018 final int callingPid = Binder.getCallingPid(); 14019 final int callingUid = Binder.getCallingUid(); 14020 final long origId = Binder.clearCallingIdentity(); 14021 int res = broadcastIntentLocked(callerApp, 14022 callerApp != null ? callerApp.info.packageName : null, 14023 intent, resolvedType, resultTo, 14024 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14025 callingPid, callingUid, userId); 14026 Binder.restoreCallingIdentity(origId); 14027 return res; 14028 } 14029 } 14030 14031 int broadcastIntentInPackage(String packageName, int uid, 14032 Intent intent, String resolvedType, IIntentReceiver resultTo, 14033 int resultCode, String resultData, Bundle map, 14034 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14035 synchronized(this) { 14036 intent = verifyBroadcastLocked(intent); 14037 14038 final long origId = Binder.clearCallingIdentity(); 14039 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14040 resultTo, resultCode, resultData, map, requiredPermission, 14041 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14042 Binder.restoreCallingIdentity(origId); 14043 return res; 14044 } 14045 } 14046 14047 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14048 // Refuse possible leaked file descriptors 14049 if (intent != null && intent.hasFileDescriptors() == true) { 14050 throw new IllegalArgumentException("File descriptors passed in Intent"); 14051 } 14052 14053 userId = handleIncomingUser(Binder.getCallingPid(), 14054 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14055 14056 synchronized(this) { 14057 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14058 != PackageManager.PERMISSION_GRANTED) { 14059 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14060 + Binder.getCallingPid() 14061 + ", uid=" + Binder.getCallingUid() 14062 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14063 Slog.w(TAG, msg); 14064 throw new SecurityException(msg); 14065 } 14066 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14067 if (stickies != null) { 14068 ArrayList<Intent> list = stickies.get(intent.getAction()); 14069 if (list != null) { 14070 int N = list.size(); 14071 int i; 14072 for (i=0; i<N; i++) { 14073 if (intent.filterEquals(list.get(i))) { 14074 list.remove(i); 14075 break; 14076 } 14077 } 14078 if (list.size() <= 0) { 14079 stickies.remove(intent.getAction()); 14080 } 14081 } 14082 if (stickies.size() <= 0) { 14083 mStickyBroadcasts.remove(userId); 14084 } 14085 } 14086 } 14087 } 14088 14089 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14090 String resultData, Bundle resultExtras, boolean resultAbort) { 14091 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14092 if (r == null) { 14093 Slog.w(TAG, "finishReceiver called but not found on queue"); 14094 return false; 14095 } 14096 14097 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14098 } 14099 14100 void backgroundServicesFinishedLocked(int userId) { 14101 for (BroadcastQueue queue : mBroadcastQueues) { 14102 queue.backgroundServicesFinishedLocked(userId); 14103 } 14104 } 14105 14106 public void finishReceiver(IBinder who, int resultCode, String resultData, 14107 Bundle resultExtras, boolean resultAbort) { 14108 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14109 14110 // Refuse possible leaked file descriptors 14111 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14112 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14113 } 14114 14115 final long origId = Binder.clearCallingIdentity(); 14116 try { 14117 boolean doNext = false; 14118 BroadcastRecord r; 14119 14120 synchronized(this) { 14121 r = broadcastRecordForReceiverLocked(who); 14122 if (r != null) { 14123 doNext = r.queue.finishReceiverLocked(r, resultCode, 14124 resultData, resultExtras, resultAbort, true); 14125 } 14126 } 14127 14128 if (doNext) { 14129 r.queue.processNextBroadcast(false); 14130 } 14131 trimApplications(); 14132 } finally { 14133 Binder.restoreCallingIdentity(origId); 14134 } 14135 } 14136 14137 // ========================================================= 14138 // INSTRUMENTATION 14139 // ========================================================= 14140 14141 public boolean startInstrumentation(ComponentName className, 14142 String profileFile, int flags, Bundle arguments, 14143 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14144 int userId) { 14145 enforceNotIsolatedCaller("startInstrumentation"); 14146 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14147 userId, false, true, "startInstrumentation", null); 14148 // Refuse possible leaked file descriptors 14149 if (arguments != null && arguments.hasFileDescriptors()) { 14150 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14151 } 14152 14153 synchronized(this) { 14154 InstrumentationInfo ii = null; 14155 ApplicationInfo ai = null; 14156 try { 14157 ii = mContext.getPackageManager().getInstrumentationInfo( 14158 className, STOCK_PM_FLAGS); 14159 ai = AppGlobals.getPackageManager().getApplicationInfo( 14160 ii.targetPackage, STOCK_PM_FLAGS, userId); 14161 } catch (PackageManager.NameNotFoundException e) { 14162 } catch (RemoteException e) { 14163 } 14164 if (ii == null) { 14165 reportStartInstrumentationFailure(watcher, className, 14166 "Unable to find instrumentation info for: " + className); 14167 return false; 14168 } 14169 if (ai == null) { 14170 reportStartInstrumentationFailure(watcher, className, 14171 "Unable to find instrumentation target package: " + ii.targetPackage); 14172 return false; 14173 } 14174 14175 int match = mContext.getPackageManager().checkSignatures( 14176 ii.targetPackage, ii.packageName); 14177 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14178 String msg = "Permission Denial: starting instrumentation " 14179 + className + " from pid=" 14180 + Binder.getCallingPid() 14181 + ", uid=" + Binder.getCallingPid() 14182 + " not allowed because package " + ii.packageName 14183 + " does not have a signature matching the target " 14184 + ii.targetPackage; 14185 reportStartInstrumentationFailure(watcher, className, msg); 14186 throw new SecurityException(msg); 14187 } 14188 14189 final long origId = Binder.clearCallingIdentity(); 14190 // Instrumentation can kill and relaunch even persistent processes 14191 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14192 "start instr"); 14193 ProcessRecord app = addAppLocked(ai, false); 14194 app.instrumentationClass = className; 14195 app.instrumentationInfo = ai; 14196 app.instrumentationProfileFile = profileFile; 14197 app.instrumentationArguments = arguments; 14198 app.instrumentationWatcher = watcher; 14199 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14200 app.instrumentationResultClass = className; 14201 Binder.restoreCallingIdentity(origId); 14202 } 14203 14204 return true; 14205 } 14206 14207 /** 14208 * Report errors that occur while attempting to start Instrumentation. Always writes the 14209 * error to the logs, but if somebody is watching, send the report there too. This enables 14210 * the "am" command to report errors with more information. 14211 * 14212 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14213 * @param cn The component name of the instrumentation. 14214 * @param report The error report. 14215 */ 14216 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14217 ComponentName cn, String report) { 14218 Slog.w(TAG, report); 14219 try { 14220 if (watcher != null) { 14221 Bundle results = new Bundle(); 14222 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14223 results.putString("Error", report); 14224 watcher.instrumentationStatus(cn, -1, results); 14225 } 14226 } catch (RemoteException e) { 14227 Slog.w(TAG, e); 14228 } 14229 } 14230 14231 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14232 if (app.instrumentationWatcher != null) { 14233 try { 14234 // NOTE: IInstrumentationWatcher *must* be oneway here 14235 app.instrumentationWatcher.instrumentationFinished( 14236 app.instrumentationClass, 14237 resultCode, 14238 results); 14239 } catch (RemoteException e) { 14240 } 14241 } 14242 if (app.instrumentationUiAutomationConnection != null) { 14243 try { 14244 app.instrumentationUiAutomationConnection.shutdown(); 14245 } catch (RemoteException re) { 14246 /* ignore */ 14247 } 14248 // Only a UiAutomation can set this flag and now that 14249 // it is finished we make sure it is reset to its default. 14250 mUserIsMonkey = false; 14251 } 14252 app.instrumentationWatcher = null; 14253 app.instrumentationUiAutomationConnection = null; 14254 app.instrumentationClass = null; 14255 app.instrumentationInfo = null; 14256 app.instrumentationProfileFile = null; 14257 app.instrumentationArguments = null; 14258 14259 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14260 "finished inst"); 14261 } 14262 14263 public void finishInstrumentation(IApplicationThread target, 14264 int resultCode, Bundle results) { 14265 int userId = UserHandle.getCallingUserId(); 14266 // Refuse possible leaked file descriptors 14267 if (results != null && results.hasFileDescriptors()) { 14268 throw new IllegalArgumentException("File descriptors passed in Intent"); 14269 } 14270 14271 synchronized(this) { 14272 ProcessRecord app = getRecordForAppLocked(target); 14273 if (app == null) { 14274 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14275 return; 14276 } 14277 final long origId = Binder.clearCallingIdentity(); 14278 finishInstrumentationLocked(app, resultCode, results); 14279 Binder.restoreCallingIdentity(origId); 14280 } 14281 } 14282 14283 // ========================================================= 14284 // CONFIGURATION 14285 // ========================================================= 14286 14287 public ConfigurationInfo getDeviceConfigurationInfo() { 14288 ConfigurationInfo config = new ConfigurationInfo(); 14289 synchronized (this) { 14290 config.reqTouchScreen = mConfiguration.touchscreen; 14291 config.reqKeyboardType = mConfiguration.keyboard; 14292 config.reqNavigation = mConfiguration.navigation; 14293 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14294 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14295 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14296 } 14297 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14298 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14299 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14300 } 14301 config.reqGlEsVersion = GL_ES_VERSION; 14302 } 14303 return config; 14304 } 14305 14306 ActivityStack getFocusedStack() { 14307 return mStackSupervisor.getFocusedStack(); 14308 } 14309 14310 public Configuration getConfiguration() { 14311 Configuration ci; 14312 synchronized(this) { 14313 ci = new Configuration(mConfiguration); 14314 } 14315 return ci; 14316 } 14317 14318 public void updatePersistentConfiguration(Configuration values) { 14319 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14320 "updateConfiguration()"); 14321 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14322 "updateConfiguration()"); 14323 if (values == null) { 14324 throw new NullPointerException("Configuration must not be null"); 14325 } 14326 14327 synchronized(this) { 14328 final long origId = Binder.clearCallingIdentity(); 14329 updateConfigurationLocked(values, null, true, false); 14330 Binder.restoreCallingIdentity(origId); 14331 } 14332 } 14333 14334 public void updateConfiguration(Configuration values) { 14335 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14336 "updateConfiguration()"); 14337 14338 synchronized(this) { 14339 if (values == null && mWindowManager != null) { 14340 // sentinel: fetch the current configuration from the window manager 14341 values = mWindowManager.computeNewConfiguration(); 14342 } 14343 14344 if (mWindowManager != null) { 14345 mProcessList.applyDisplaySize(mWindowManager); 14346 } 14347 14348 final long origId = Binder.clearCallingIdentity(); 14349 if (values != null) { 14350 Settings.System.clearConfiguration(values); 14351 } 14352 updateConfigurationLocked(values, null, false, false); 14353 Binder.restoreCallingIdentity(origId); 14354 } 14355 } 14356 14357 /** 14358 * Do either or both things: (1) change the current configuration, and (2) 14359 * make sure the given activity is running with the (now) current 14360 * configuration. Returns true if the activity has been left running, or 14361 * false if <var>starting</var> is being destroyed to match the new 14362 * configuration. 14363 * @param persistent TODO 14364 */ 14365 boolean updateConfigurationLocked(Configuration values, 14366 ActivityRecord starting, boolean persistent, boolean initLocale) { 14367 int changes = 0; 14368 14369 if (values != null) { 14370 Configuration newConfig = new Configuration(mConfiguration); 14371 changes = newConfig.updateFrom(values); 14372 if (changes != 0) { 14373 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14374 Slog.i(TAG, "Updating configuration to: " + values); 14375 } 14376 14377 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14378 14379 if (values.locale != null && !initLocale) { 14380 saveLocaleLocked(values.locale, 14381 !values.locale.equals(mConfiguration.locale), 14382 values.userSetLocale); 14383 } 14384 14385 mConfigurationSeq++; 14386 if (mConfigurationSeq <= 0) { 14387 mConfigurationSeq = 1; 14388 } 14389 newConfig.seq = mConfigurationSeq; 14390 mConfiguration = newConfig; 14391 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14392 14393 final Configuration configCopy = new Configuration(mConfiguration); 14394 14395 // TODO: If our config changes, should we auto dismiss any currently 14396 // showing dialogs? 14397 mShowDialogs = shouldShowDialogs(newConfig); 14398 14399 AttributeCache ac = AttributeCache.instance(); 14400 if (ac != null) { 14401 ac.updateConfiguration(configCopy); 14402 } 14403 14404 // Make sure all resources in our process are updated 14405 // right now, so that anyone who is going to retrieve 14406 // resource values after we return will be sure to get 14407 // the new ones. This is especially important during 14408 // boot, where the first config change needs to guarantee 14409 // all resources have that config before following boot 14410 // code is executed. 14411 mSystemThread.applyConfigurationToResources(configCopy); 14412 14413 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14414 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14415 msg.obj = new Configuration(configCopy); 14416 mHandler.sendMessage(msg); 14417 } 14418 14419 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14420 ProcessRecord app = mLruProcesses.get(i); 14421 try { 14422 if (app.thread != null) { 14423 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14424 + app.processName + " new config " + mConfiguration); 14425 app.thread.scheduleConfigurationChanged(configCopy); 14426 } 14427 } catch (Exception e) { 14428 } 14429 } 14430 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14431 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14432 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14433 | Intent.FLAG_RECEIVER_FOREGROUND); 14434 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14435 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14436 Process.SYSTEM_UID, UserHandle.USER_ALL); 14437 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14438 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14439 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14440 broadcastIntentLocked(null, null, intent, 14441 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14442 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14443 } 14444 } 14445 } 14446 14447 boolean kept = true; 14448 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14449 // mainStack is null during startup. 14450 if (mainStack != null) { 14451 if (changes != 0 && starting == null) { 14452 // If the configuration changed, and the caller is not already 14453 // in the process of starting an activity, then find the top 14454 // activity to check if its configuration needs to change. 14455 starting = mainStack.topRunningActivityLocked(null); 14456 } 14457 14458 if (starting != null) { 14459 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14460 // And we need to make sure at this point that all other activities 14461 // are made visible with the correct configuration. 14462 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14463 } 14464 } 14465 14466 if (values != null && mWindowManager != null) { 14467 mWindowManager.setNewConfiguration(mConfiguration); 14468 } 14469 14470 return kept; 14471 } 14472 14473 /** 14474 * Decide based on the configuration whether we should shouw the ANR, 14475 * crash, etc dialogs. The idea is that if there is no affordnace to 14476 * press the on-screen buttons, we shouldn't show the dialog. 14477 * 14478 * A thought: SystemUI might also want to get told about this, the Power 14479 * dialog / global actions also might want different behaviors. 14480 */ 14481 private static final boolean shouldShowDialogs(Configuration config) { 14482 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14483 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14484 } 14485 14486 /** 14487 * Save the locale. You must be inside a synchronized (this) block. 14488 */ 14489 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14490 if(isDiff) { 14491 SystemProperties.set("user.language", l.getLanguage()); 14492 SystemProperties.set("user.region", l.getCountry()); 14493 } 14494 14495 if(isPersist) { 14496 SystemProperties.set("persist.sys.language", l.getLanguage()); 14497 SystemProperties.set("persist.sys.country", l.getCountry()); 14498 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14499 } 14500 } 14501 14502 @Override 14503 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14504 ActivityRecord srec = ActivityRecord.forToken(token); 14505 return srec != null && srec.task.affinity != null && 14506 srec.task.affinity.equals(destAffinity); 14507 } 14508 14509 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14510 Intent resultData) { 14511 14512 synchronized (this) { 14513 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14514 if (stack != null) { 14515 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14516 } 14517 return false; 14518 } 14519 } 14520 14521 public int getLaunchedFromUid(IBinder activityToken) { 14522 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14523 if (srec == null) { 14524 return -1; 14525 } 14526 return srec.launchedFromUid; 14527 } 14528 14529 public String getLaunchedFromPackage(IBinder activityToken) { 14530 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14531 if (srec == null) { 14532 return null; 14533 } 14534 return srec.launchedFromPackage; 14535 } 14536 14537 // ========================================================= 14538 // LIFETIME MANAGEMENT 14539 // ========================================================= 14540 14541 // Returns which broadcast queue the app is the current [or imminent] receiver 14542 // on, or 'null' if the app is not an active broadcast recipient. 14543 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14544 BroadcastRecord r = app.curReceiver; 14545 if (r != null) { 14546 return r.queue; 14547 } 14548 14549 // It's not the current receiver, but it might be starting up to become one 14550 synchronized (this) { 14551 for (BroadcastQueue queue : mBroadcastQueues) { 14552 r = queue.mPendingBroadcast; 14553 if (r != null && r.curApp == app) { 14554 // found it; report which queue it's in 14555 return queue; 14556 } 14557 } 14558 } 14559 14560 return null; 14561 } 14562 14563 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14564 boolean doingAll, long now) { 14565 if (mAdjSeq == app.adjSeq) { 14566 // This adjustment has already been computed. 14567 return app.curRawAdj; 14568 } 14569 14570 if (app.thread == null) { 14571 app.adjSeq = mAdjSeq; 14572 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14573 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14574 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14575 } 14576 14577 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14578 app.adjSource = null; 14579 app.adjTarget = null; 14580 app.empty = false; 14581 app.cached = false; 14582 14583 final int activitiesSize = app.activities.size(); 14584 14585 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14586 // The max adjustment doesn't allow this app to be anything 14587 // below foreground, so it is not worth doing work for it. 14588 app.adjType = "fixed"; 14589 app.adjSeq = mAdjSeq; 14590 app.curRawAdj = app.maxAdj; 14591 app.foregroundActivities = false; 14592 app.keeping = true; 14593 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14594 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14595 // System process can do UI, and when they do we want to have 14596 // them trim their memory after the user leaves the UI. To 14597 // facilitate this, here we need to determine whether or not it 14598 // is currently showing UI. 14599 app.systemNoUi = true; 14600 if (app == TOP_APP) { 14601 app.systemNoUi = false; 14602 } else if (activitiesSize > 0) { 14603 for (int j = 0; j < activitiesSize; j++) { 14604 final ActivityRecord r = app.activities.get(j); 14605 if (r.visible) { 14606 app.systemNoUi = false; 14607 } 14608 } 14609 } 14610 if (!app.systemNoUi) { 14611 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14612 } 14613 return (app.curAdj=app.maxAdj); 14614 } 14615 14616 app.keeping = false; 14617 app.systemNoUi = false; 14618 14619 // Determine the importance of the process, starting with most 14620 // important to least, and assign an appropriate OOM adjustment. 14621 int adj; 14622 int schedGroup; 14623 int procState; 14624 boolean foregroundActivities = false; 14625 boolean interesting = false; 14626 BroadcastQueue queue; 14627 if (app == TOP_APP) { 14628 // The last app on the list is the foreground app. 14629 adj = ProcessList.FOREGROUND_APP_ADJ; 14630 schedGroup = Process.THREAD_GROUP_DEFAULT; 14631 app.adjType = "top-activity"; 14632 foregroundActivities = true; 14633 interesting = true; 14634 procState = ActivityManager.PROCESS_STATE_TOP; 14635 } else if (app.instrumentationClass != null) { 14636 // Don't want to kill running instrumentation. 14637 adj = ProcessList.FOREGROUND_APP_ADJ; 14638 schedGroup = Process.THREAD_GROUP_DEFAULT; 14639 app.adjType = "instrumentation"; 14640 interesting = true; 14641 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14642 } else if ((queue = isReceivingBroadcast(app)) != null) { 14643 // An app that is currently receiving a broadcast also 14644 // counts as being in the foreground for OOM killer purposes. 14645 // It's placed in a sched group based on the nature of the 14646 // broadcast as reflected by which queue it's active in. 14647 adj = ProcessList.FOREGROUND_APP_ADJ; 14648 schedGroup = (queue == mFgBroadcastQueue) 14649 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14650 app.adjType = "broadcast"; 14651 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14652 } else if (app.executingServices.size() > 0) { 14653 // An app that is currently executing a service callback also 14654 // counts as being in the foreground. 14655 adj = ProcessList.FOREGROUND_APP_ADJ; 14656 schedGroup = app.execServicesFg ? 14657 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14658 app.adjType = "exec-service"; 14659 procState = ActivityManager.PROCESS_STATE_SERVICE; 14660 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14661 } else { 14662 // As far as we know the process is empty. We may change our mind later. 14663 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14664 // At this point we don't actually know the adjustment. Use the cached adj 14665 // value that the caller wants us to. 14666 adj = cachedAdj; 14667 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14668 app.cached = true; 14669 app.empty = true; 14670 app.adjType = "cch-empty"; 14671 } 14672 14673 // Examine all activities if not already foreground. 14674 if (!foregroundActivities && activitiesSize > 0) { 14675 for (int j = 0; j < activitiesSize; j++) { 14676 final ActivityRecord r = app.activities.get(j); 14677 if (r.app != app) { 14678 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14679 + app + "?!?"); 14680 continue; 14681 } 14682 if (r.visible) { 14683 // App has a visible activity; only upgrade adjustment. 14684 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14685 adj = ProcessList.VISIBLE_APP_ADJ; 14686 app.adjType = "visible"; 14687 } 14688 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14689 procState = ActivityManager.PROCESS_STATE_TOP; 14690 } 14691 schedGroup = Process.THREAD_GROUP_DEFAULT; 14692 app.cached = false; 14693 app.empty = false; 14694 foregroundActivities = true; 14695 break; 14696 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14697 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14698 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14699 app.adjType = "pausing"; 14700 } 14701 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14702 procState = ActivityManager.PROCESS_STATE_TOP; 14703 } 14704 schedGroup = Process.THREAD_GROUP_DEFAULT; 14705 app.cached = false; 14706 app.empty = false; 14707 foregroundActivities = true; 14708 } else if (r.state == ActivityState.STOPPING) { 14709 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14710 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14711 app.adjType = "stopping"; 14712 } 14713 // For the process state, we will at this point consider the 14714 // process to be cached. It will be cached either as an activity 14715 // or empty depending on whether the activity is finishing. We do 14716 // this so that we can treat the process as cached for purposes of 14717 // memory trimming (determing current memory level, trim command to 14718 // send to process) since there can be an arbitrary number of stopping 14719 // processes and they should soon all go into the cached state. 14720 if (!r.finishing) { 14721 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14722 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14723 } 14724 } 14725 app.cached = false; 14726 app.empty = false; 14727 foregroundActivities = true; 14728 } else { 14729 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14730 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14731 app.adjType = "cch-act"; 14732 } 14733 } 14734 } 14735 } 14736 14737 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14738 if (app.foregroundServices) { 14739 // The user is aware of this app, so make it visible. 14740 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14741 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14742 app.cached = false; 14743 app.adjType = "fg-service"; 14744 schedGroup = Process.THREAD_GROUP_DEFAULT; 14745 } else if (app.forcingToForeground != null) { 14746 // The user is aware of this app, so make it visible. 14747 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14748 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14749 app.cached = false; 14750 app.adjType = "force-fg"; 14751 app.adjSource = app.forcingToForeground; 14752 schedGroup = Process.THREAD_GROUP_DEFAULT; 14753 } 14754 } 14755 14756 if (app.foregroundServices) { 14757 interesting = true; 14758 } 14759 14760 if (app == mHeavyWeightProcess) { 14761 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14762 // We don't want to kill the current heavy-weight process. 14763 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14764 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14765 app.cached = false; 14766 app.adjType = "heavy"; 14767 } 14768 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14769 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14770 } 14771 } 14772 14773 if (app == mHomeProcess) { 14774 if (adj > ProcessList.HOME_APP_ADJ) { 14775 // This process is hosting what we currently consider to be the 14776 // home app, so we don't want to let it go into the background. 14777 adj = ProcessList.HOME_APP_ADJ; 14778 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14779 app.cached = false; 14780 app.adjType = "home"; 14781 } 14782 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14783 procState = ActivityManager.PROCESS_STATE_HOME; 14784 } 14785 } 14786 14787 if (app == mPreviousProcess && app.activities.size() > 0) { 14788 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14789 // This was the previous process that showed UI to the user. 14790 // We want to try to keep it around more aggressively, to give 14791 // a good experience around switching between two apps. 14792 adj = ProcessList.PREVIOUS_APP_ADJ; 14793 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14794 app.cached = false; 14795 app.adjType = "previous"; 14796 } 14797 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14798 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14799 } 14800 } 14801 14802 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14803 + " reason=" + app.adjType); 14804 14805 // By default, we use the computed adjustment. It may be changed if 14806 // there are applications dependent on our services or providers, but 14807 // this gives us a baseline and makes sure we don't get into an 14808 // infinite recursion. 14809 app.adjSeq = mAdjSeq; 14810 app.curRawAdj = adj; 14811 app.hasStartedServices = false; 14812 14813 if (mBackupTarget != null && app == mBackupTarget.app) { 14814 // If possible we want to avoid killing apps while they're being backed up 14815 if (adj > ProcessList.BACKUP_APP_ADJ) { 14816 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14817 adj = ProcessList.BACKUP_APP_ADJ; 14818 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14819 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14820 } 14821 app.adjType = "backup"; 14822 app.cached = false; 14823 } 14824 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14825 procState = ActivityManager.PROCESS_STATE_BACKUP; 14826 } 14827 } 14828 14829 boolean mayBeTop = false; 14830 14831 for (int is = app.services.size()-1; 14832 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14833 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14834 || procState > ActivityManager.PROCESS_STATE_TOP); 14835 is--) { 14836 ServiceRecord s = app.services.valueAt(is); 14837 if (s.startRequested) { 14838 app.hasStartedServices = true; 14839 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14840 procState = ActivityManager.PROCESS_STATE_SERVICE; 14841 } 14842 if (app.hasShownUi && app != mHomeProcess) { 14843 // If this process has shown some UI, let it immediately 14844 // go to the LRU list because it may be pretty heavy with 14845 // UI stuff. We'll tag it with a label just to help 14846 // debug and understand what is going on. 14847 if (adj > ProcessList.SERVICE_ADJ) { 14848 app.adjType = "cch-started-ui-services"; 14849 } 14850 } else { 14851 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14852 // This service has seen some activity within 14853 // recent memory, so we will keep its process ahead 14854 // of the background processes. 14855 if (adj > ProcessList.SERVICE_ADJ) { 14856 adj = ProcessList.SERVICE_ADJ; 14857 app.adjType = "started-services"; 14858 app.cached = false; 14859 } 14860 } 14861 // If we have let the service slide into the background 14862 // state, still have some text describing what it is doing 14863 // even though the service no longer has an impact. 14864 if (adj > ProcessList.SERVICE_ADJ) { 14865 app.adjType = "cch-started-services"; 14866 } 14867 } 14868 // Don't kill this process because it is doing work; it 14869 // has said it is doing work. 14870 app.keeping = true; 14871 } 14872 for (int conni = s.connections.size()-1; 14873 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14874 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14875 || procState > ActivityManager.PROCESS_STATE_TOP); 14876 conni--) { 14877 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14878 for (int i = 0; 14879 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14880 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14881 || procState > ActivityManager.PROCESS_STATE_TOP); 14882 i++) { 14883 // XXX should compute this based on the max of 14884 // all connected clients. 14885 ConnectionRecord cr = clist.get(i); 14886 if (cr.binding.client == app) { 14887 // Binding to ourself is not interesting. 14888 continue; 14889 } 14890 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14891 ProcessRecord client = cr.binding.client; 14892 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14893 TOP_APP, doingAll, now); 14894 int clientProcState = client.curProcState; 14895 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14896 // If the other app is cached for any reason, for purposes here 14897 // we are going to consider it empty. The specific cached state 14898 // doesn't propagate except under certain conditions. 14899 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14900 } 14901 String adjType = null; 14902 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14903 // Not doing bind OOM management, so treat 14904 // this guy more like a started service. 14905 if (app.hasShownUi && app != mHomeProcess) { 14906 // If this process has shown some UI, let it immediately 14907 // go to the LRU list because it may be pretty heavy with 14908 // UI stuff. We'll tag it with a label just to help 14909 // debug and understand what is going on. 14910 if (adj > clientAdj) { 14911 adjType = "cch-bound-ui-services"; 14912 } 14913 app.cached = false; 14914 clientAdj = adj; 14915 clientProcState = procState; 14916 } else { 14917 if (now >= (s.lastActivity 14918 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14919 // This service has not seen activity within 14920 // recent memory, so allow it to drop to the 14921 // LRU list if there is no other reason to keep 14922 // it around. We'll also tag it with a label just 14923 // to help debug and undertand what is going on. 14924 if (adj > clientAdj) { 14925 adjType = "cch-bound-services"; 14926 } 14927 clientAdj = adj; 14928 } 14929 } 14930 } 14931 if (adj > clientAdj) { 14932 // If this process has recently shown UI, and 14933 // the process that is binding to it is less 14934 // important than being visible, then we don't 14935 // care about the binding as much as we care 14936 // about letting this process get into the LRU 14937 // list to be killed and restarted if needed for 14938 // memory. 14939 if (app.hasShownUi && app != mHomeProcess 14940 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14941 adjType = "cch-bound-ui-services"; 14942 } else { 14943 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14944 |Context.BIND_IMPORTANT)) != 0) { 14945 adj = clientAdj; 14946 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14947 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14948 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14949 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14950 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14951 adj = clientAdj; 14952 } else { 14953 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14954 adj = ProcessList.VISIBLE_APP_ADJ; 14955 } 14956 } 14957 if (!client.cached) { 14958 app.cached = false; 14959 } 14960 if (client.keeping) { 14961 app.keeping = true; 14962 } 14963 adjType = "service"; 14964 } 14965 } 14966 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14967 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14968 schedGroup = Process.THREAD_GROUP_DEFAULT; 14969 } 14970 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14971 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14972 // Special handling of clients who are in the top state. 14973 // We *may* want to consider this process to be in the 14974 // top state as well, but only if there is not another 14975 // reason for it to be running. Being on the top is a 14976 // special state, meaning you are specifically running 14977 // for the current top app. If the process is already 14978 // running in the background for some other reason, it 14979 // is more important to continue considering it to be 14980 // in the background state. 14981 mayBeTop = true; 14982 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14983 } else { 14984 // Special handling for above-top states (persistent 14985 // processes). These should not bring the current process 14986 // into the top state, since they are not on top. Instead 14987 // give them the best state after that. 14988 clientProcState = 14989 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14990 } 14991 } 14992 } else { 14993 if (clientProcState < 14994 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14995 clientProcState = 14996 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14997 } 14998 } 14999 if (procState > clientProcState) { 15000 procState = clientProcState; 15001 } 15002 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15003 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15004 app.pendingUiClean = true; 15005 } 15006 if (adjType != null) { 15007 app.adjType = adjType; 15008 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15009 .REASON_SERVICE_IN_USE; 15010 app.adjSource = cr.binding.client; 15011 app.adjSourceOom = clientAdj; 15012 app.adjTarget = s.name; 15013 } 15014 } 15015 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15016 app.treatLikeActivity = true; 15017 } 15018 final ActivityRecord a = cr.activity; 15019 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15020 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15021 (a.visible || a.state == ActivityState.RESUMED 15022 || a.state == ActivityState.PAUSING)) { 15023 adj = ProcessList.FOREGROUND_APP_ADJ; 15024 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15025 schedGroup = Process.THREAD_GROUP_DEFAULT; 15026 } 15027 app.cached = false; 15028 app.adjType = "service"; 15029 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15030 .REASON_SERVICE_IN_USE; 15031 app.adjSource = a; 15032 app.adjSourceOom = adj; 15033 app.adjTarget = s.name; 15034 } 15035 } 15036 } 15037 } 15038 } 15039 15040 for (int provi = app.pubProviders.size()-1; 15041 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15042 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15043 || procState > ActivityManager.PROCESS_STATE_TOP); 15044 provi--) { 15045 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15046 for (int i = cpr.connections.size()-1; 15047 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15048 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15049 || procState > ActivityManager.PROCESS_STATE_TOP); 15050 i--) { 15051 ContentProviderConnection conn = cpr.connections.get(i); 15052 ProcessRecord client = conn.client; 15053 if (client == app) { 15054 // Being our own client is not interesting. 15055 continue; 15056 } 15057 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15058 int clientProcState = client.curProcState; 15059 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15060 // If the other app is cached for any reason, for purposes here 15061 // we are going to consider it empty. 15062 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15063 } 15064 if (adj > clientAdj) { 15065 if (app.hasShownUi && app != mHomeProcess 15066 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15067 app.adjType = "cch-ui-provider"; 15068 } else { 15069 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15070 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15071 app.adjType = "provider"; 15072 } 15073 app.cached &= client.cached; 15074 app.keeping |= client.keeping; 15075 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15076 .REASON_PROVIDER_IN_USE; 15077 app.adjSource = client; 15078 app.adjSourceOom = clientAdj; 15079 app.adjTarget = cpr.name; 15080 } 15081 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15082 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15083 // Special handling of clients who are in the top state. 15084 // We *may* want to consider this process to be in the 15085 // top state as well, but only if there is not another 15086 // reason for it to be running. Being on the top is a 15087 // special state, meaning you are specifically running 15088 // for the current top app. If the process is already 15089 // running in the background for some other reason, it 15090 // is more important to continue considering it to be 15091 // in the background state. 15092 mayBeTop = true; 15093 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15094 } else { 15095 // Special handling for above-top states (persistent 15096 // processes). These should not bring the current process 15097 // into the top state, since they are not on top. Instead 15098 // give them the best state after that. 15099 clientProcState = 15100 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15101 } 15102 } 15103 if (procState > clientProcState) { 15104 procState = clientProcState; 15105 } 15106 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15107 schedGroup = Process.THREAD_GROUP_DEFAULT; 15108 } 15109 } 15110 // If the provider has external (non-framework) process 15111 // dependencies, ensure that its adjustment is at least 15112 // FOREGROUND_APP_ADJ. 15113 if (cpr.hasExternalProcessHandles()) { 15114 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15115 adj = ProcessList.FOREGROUND_APP_ADJ; 15116 schedGroup = Process.THREAD_GROUP_DEFAULT; 15117 app.cached = false; 15118 app.keeping = true; 15119 app.adjType = "provider"; 15120 app.adjTarget = cpr.name; 15121 } 15122 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15123 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15124 } 15125 } 15126 } 15127 15128 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15129 // A client of one of our services or providers is in the top state. We 15130 // *may* want to be in the top state, but not if we are already running in 15131 // the background for some other reason. For the decision here, we are going 15132 // to pick out a few specific states that we want to remain in when a client 15133 // is top (states that tend to be longer-term) and otherwise allow it to go 15134 // to the top state. 15135 switch (procState) { 15136 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15137 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15138 case ActivityManager.PROCESS_STATE_SERVICE: 15139 // These all are longer-term states, so pull them up to the top 15140 // of the background states, but not all the way to the top state. 15141 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15142 break; 15143 default: 15144 // Otherwise, top is a better choice, so take it. 15145 procState = ActivityManager.PROCESS_STATE_TOP; 15146 break; 15147 } 15148 } 15149 15150 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15151 if (app.hasClientActivities) { 15152 // This is a cached process, but with client activities. Mark it so. 15153 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15154 app.adjType = "cch-client-act"; 15155 } else if (app.treatLikeActivity) { 15156 // This is a cached process, but somebody wants us to treat it like it has 15157 // an activity, okay! 15158 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15159 app.adjType = "cch-as-act"; 15160 } 15161 } 15162 15163 if (adj == ProcessList.SERVICE_ADJ) { 15164 if (doingAll) { 15165 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15166 mNewNumServiceProcs++; 15167 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15168 if (!app.serviceb) { 15169 // This service isn't far enough down on the LRU list to 15170 // normally be a B service, but if we are low on RAM and it 15171 // is large we want to force it down since we would prefer to 15172 // keep launcher over it. 15173 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15174 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15175 app.serviceHighRam = true; 15176 app.serviceb = true; 15177 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15178 } else { 15179 mNewNumAServiceProcs++; 15180 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15181 } 15182 } else { 15183 app.serviceHighRam = false; 15184 } 15185 } 15186 if (app.serviceb) { 15187 adj = ProcessList.SERVICE_B_ADJ; 15188 } 15189 } 15190 15191 app.curRawAdj = adj; 15192 15193 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15194 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15195 if (adj > app.maxAdj) { 15196 adj = app.maxAdj; 15197 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15198 schedGroup = Process.THREAD_GROUP_DEFAULT; 15199 } 15200 } 15201 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15202 app.keeping = true; 15203 } 15204 15205 // Do final modification to adj. Everything we do between here and applying 15206 // the final setAdj must be done in this function, because we will also use 15207 // it when computing the final cached adj later. Note that we don't need to 15208 // worry about this for max adj above, since max adj will always be used to 15209 // keep it out of the cached vaues. 15210 adj = app.modifyRawOomAdj(adj); 15211 15212 app.curProcState = procState; 15213 15214 int importance = app.memImportance; 15215 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15216 app.curAdj = adj; 15217 app.curSchedGroup = schedGroup; 15218 if (!interesting) { 15219 // For this reporting, if there is not something explicitly 15220 // interesting in this process then we will push it to the 15221 // background importance. 15222 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15223 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15224 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15225 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15226 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15227 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15228 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15229 } else if (adj >= ProcessList.SERVICE_ADJ) { 15230 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15231 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15232 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15233 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15234 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15235 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15236 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15237 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15238 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15239 } else { 15240 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15241 } 15242 } 15243 15244 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15245 if (foregroundActivities != app.foregroundActivities) { 15246 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15247 } 15248 if (changes != 0) { 15249 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15250 app.memImportance = importance; 15251 app.foregroundActivities = foregroundActivities; 15252 int i = mPendingProcessChanges.size()-1; 15253 ProcessChangeItem item = null; 15254 while (i >= 0) { 15255 item = mPendingProcessChanges.get(i); 15256 if (item.pid == app.pid) { 15257 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15258 break; 15259 } 15260 i--; 15261 } 15262 if (i < 0) { 15263 // No existing item in pending changes; need a new one. 15264 final int NA = mAvailProcessChanges.size(); 15265 if (NA > 0) { 15266 item = mAvailProcessChanges.remove(NA-1); 15267 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15268 } else { 15269 item = new ProcessChangeItem(); 15270 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15271 } 15272 item.changes = 0; 15273 item.pid = app.pid; 15274 item.uid = app.info.uid; 15275 if (mPendingProcessChanges.size() == 0) { 15276 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15277 "*** Enqueueing dispatch processes changed!"); 15278 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15279 } 15280 mPendingProcessChanges.add(item); 15281 } 15282 item.changes |= changes; 15283 item.importance = importance; 15284 item.foregroundActivities = foregroundActivities; 15285 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15286 + Integer.toHexString(System.identityHashCode(item)) 15287 + " " + app.toShortString() + ": changes=" + item.changes 15288 + " importance=" + item.importance 15289 + " foreground=" + item.foregroundActivities 15290 + " type=" + app.adjType + " source=" + app.adjSource 15291 + " target=" + app.adjTarget); 15292 } 15293 15294 return app.curRawAdj; 15295 } 15296 15297 /** 15298 * Schedule PSS collection of a process. 15299 */ 15300 void requestPssLocked(ProcessRecord proc, int procState) { 15301 if (mPendingPssProcesses.contains(proc)) { 15302 return; 15303 } 15304 if (mPendingPssProcesses.size() == 0) { 15305 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15306 } 15307 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15308 proc.pssProcState = procState; 15309 mPendingPssProcesses.add(proc); 15310 } 15311 15312 /** 15313 * Schedule PSS collection of all processes. 15314 */ 15315 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15316 if (!always) { 15317 if (now < (mLastFullPssTime + 15318 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15319 return; 15320 } 15321 } 15322 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15323 mLastFullPssTime = now; 15324 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15325 mPendingPssProcesses.clear(); 15326 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15327 ProcessRecord app = mLruProcesses.get(i); 15328 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15329 app.pssProcState = app.setProcState; 15330 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15331 mSleeping, now); 15332 mPendingPssProcesses.add(app); 15333 } 15334 } 15335 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15336 } 15337 15338 /** 15339 * Ask a given process to GC right now. 15340 */ 15341 final void performAppGcLocked(ProcessRecord app) { 15342 try { 15343 app.lastRequestedGc = SystemClock.uptimeMillis(); 15344 if (app.thread != null) { 15345 if (app.reportLowMemory) { 15346 app.reportLowMemory = false; 15347 app.thread.scheduleLowMemory(); 15348 } else { 15349 app.thread.processInBackground(); 15350 } 15351 } 15352 } catch (Exception e) { 15353 // whatever. 15354 } 15355 } 15356 15357 /** 15358 * Returns true if things are idle enough to perform GCs. 15359 */ 15360 private final boolean canGcNowLocked() { 15361 boolean processingBroadcasts = false; 15362 for (BroadcastQueue q : mBroadcastQueues) { 15363 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15364 processingBroadcasts = true; 15365 } 15366 } 15367 return !processingBroadcasts 15368 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15369 } 15370 15371 /** 15372 * Perform GCs on all processes that are waiting for it, but only 15373 * if things are idle. 15374 */ 15375 final void performAppGcsLocked() { 15376 final int N = mProcessesToGc.size(); 15377 if (N <= 0) { 15378 return; 15379 } 15380 if (canGcNowLocked()) { 15381 while (mProcessesToGc.size() > 0) { 15382 ProcessRecord proc = mProcessesToGc.remove(0); 15383 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15384 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15385 <= SystemClock.uptimeMillis()) { 15386 // To avoid spamming the system, we will GC processes one 15387 // at a time, waiting a few seconds between each. 15388 performAppGcLocked(proc); 15389 scheduleAppGcsLocked(); 15390 return; 15391 } else { 15392 // It hasn't been long enough since we last GCed this 15393 // process... put it in the list to wait for its time. 15394 addProcessToGcListLocked(proc); 15395 break; 15396 } 15397 } 15398 } 15399 15400 scheduleAppGcsLocked(); 15401 } 15402 } 15403 15404 /** 15405 * If all looks good, perform GCs on all processes waiting for them. 15406 */ 15407 final void performAppGcsIfAppropriateLocked() { 15408 if (canGcNowLocked()) { 15409 performAppGcsLocked(); 15410 return; 15411 } 15412 // Still not idle, wait some more. 15413 scheduleAppGcsLocked(); 15414 } 15415 15416 /** 15417 * Schedule the execution of all pending app GCs. 15418 */ 15419 final void scheduleAppGcsLocked() { 15420 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15421 15422 if (mProcessesToGc.size() > 0) { 15423 // Schedule a GC for the time to the next process. 15424 ProcessRecord proc = mProcessesToGc.get(0); 15425 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15426 15427 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15428 long now = SystemClock.uptimeMillis(); 15429 if (when < (now+GC_TIMEOUT)) { 15430 when = now + GC_TIMEOUT; 15431 } 15432 mHandler.sendMessageAtTime(msg, when); 15433 } 15434 } 15435 15436 /** 15437 * Add a process to the array of processes waiting to be GCed. Keeps the 15438 * list in sorted order by the last GC time. The process can't already be 15439 * on the list. 15440 */ 15441 final void addProcessToGcListLocked(ProcessRecord proc) { 15442 boolean added = false; 15443 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15444 if (mProcessesToGc.get(i).lastRequestedGc < 15445 proc.lastRequestedGc) { 15446 added = true; 15447 mProcessesToGc.add(i+1, proc); 15448 break; 15449 } 15450 } 15451 if (!added) { 15452 mProcessesToGc.add(0, proc); 15453 } 15454 } 15455 15456 /** 15457 * Set up to ask a process to GC itself. This will either do it 15458 * immediately, or put it on the list of processes to gc the next 15459 * time things are idle. 15460 */ 15461 final void scheduleAppGcLocked(ProcessRecord app) { 15462 long now = SystemClock.uptimeMillis(); 15463 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15464 return; 15465 } 15466 if (!mProcessesToGc.contains(app)) { 15467 addProcessToGcListLocked(app); 15468 scheduleAppGcsLocked(); 15469 } 15470 } 15471 15472 final void checkExcessivePowerUsageLocked(boolean doKills) { 15473 updateCpuStatsNow(); 15474 15475 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15476 boolean doWakeKills = doKills; 15477 boolean doCpuKills = doKills; 15478 if (mLastPowerCheckRealtime == 0) { 15479 doWakeKills = false; 15480 } 15481 if (mLastPowerCheckUptime == 0) { 15482 doCpuKills = false; 15483 } 15484 if (stats.isScreenOn()) { 15485 doWakeKills = false; 15486 } 15487 final long curRealtime = SystemClock.elapsedRealtime(); 15488 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15489 final long curUptime = SystemClock.uptimeMillis(); 15490 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15491 mLastPowerCheckRealtime = curRealtime; 15492 mLastPowerCheckUptime = curUptime; 15493 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15494 doWakeKills = false; 15495 } 15496 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15497 doCpuKills = false; 15498 } 15499 int i = mLruProcesses.size(); 15500 while (i > 0) { 15501 i--; 15502 ProcessRecord app = mLruProcesses.get(i); 15503 if (!app.keeping) { 15504 long wtime; 15505 synchronized (stats) { 15506 wtime = stats.getProcessWakeTime(app.info.uid, 15507 app.pid, curRealtime); 15508 } 15509 long wtimeUsed = wtime - app.lastWakeTime; 15510 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15511 if (DEBUG_POWER) { 15512 StringBuilder sb = new StringBuilder(128); 15513 sb.append("Wake for "); 15514 app.toShortString(sb); 15515 sb.append(": over "); 15516 TimeUtils.formatDuration(realtimeSince, sb); 15517 sb.append(" used "); 15518 TimeUtils.formatDuration(wtimeUsed, sb); 15519 sb.append(" ("); 15520 sb.append((wtimeUsed*100)/realtimeSince); 15521 sb.append("%)"); 15522 Slog.i(TAG, sb.toString()); 15523 sb.setLength(0); 15524 sb.append("CPU for "); 15525 app.toShortString(sb); 15526 sb.append(": over "); 15527 TimeUtils.formatDuration(uptimeSince, sb); 15528 sb.append(" used "); 15529 TimeUtils.formatDuration(cputimeUsed, sb); 15530 sb.append(" ("); 15531 sb.append((cputimeUsed*100)/uptimeSince); 15532 sb.append("%)"); 15533 Slog.i(TAG, sb.toString()); 15534 } 15535 // If a process has held a wake lock for more 15536 // than 50% of the time during this period, 15537 // that sounds bad. Kill! 15538 if (doWakeKills && realtimeSince > 0 15539 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15540 synchronized (stats) { 15541 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15542 realtimeSince, wtimeUsed); 15543 } 15544 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15545 + " during " + realtimeSince); 15546 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15547 } else if (doCpuKills && uptimeSince > 0 15548 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15549 synchronized (stats) { 15550 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15551 uptimeSince, cputimeUsed); 15552 } 15553 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15554 + " during " + uptimeSince); 15555 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15556 } else { 15557 app.lastWakeTime = wtime; 15558 app.lastCpuTime = app.curCpuTime; 15559 } 15560 } 15561 } 15562 } 15563 15564 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15565 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15566 boolean success = true; 15567 15568 if (app.curRawAdj != app.setRawAdj) { 15569 if (wasKeeping && !app.keeping) { 15570 // This app is no longer something we want to keep. Note 15571 // its current wake lock time to later know to kill it if 15572 // it is not behaving well. 15573 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15574 synchronized (stats) { 15575 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15576 app.pid, SystemClock.elapsedRealtime()); 15577 } 15578 app.lastCpuTime = app.curCpuTime; 15579 } 15580 15581 app.setRawAdj = app.curRawAdj; 15582 } 15583 15584 if (app.curAdj != app.setAdj) { 15585 ProcessList.setOomAdj(app.pid, app.curAdj); 15586 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15587 TAG, "Set " + app.pid + " " + app.processName + 15588 " adj " + app.curAdj + ": " + app.adjType); 15589 app.setAdj = app.curAdj; 15590 } 15591 15592 if (app.setSchedGroup != app.curSchedGroup) { 15593 app.setSchedGroup = app.curSchedGroup; 15594 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15595 "Setting process group of " + app.processName 15596 + " to " + app.curSchedGroup); 15597 if (app.waitingToKill != null && 15598 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15599 killUnneededProcessLocked(app, app.waitingToKill); 15600 success = false; 15601 } else { 15602 if (true) { 15603 long oldId = Binder.clearCallingIdentity(); 15604 try { 15605 Process.setProcessGroup(app.pid, app.curSchedGroup); 15606 } catch (Exception e) { 15607 Slog.w(TAG, "Failed setting process group of " + app.pid 15608 + " to " + app.curSchedGroup); 15609 e.printStackTrace(); 15610 } finally { 15611 Binder.restoreCallingIdentity(oldId); 15612 } 15613 } else { 15614 if (app.thread != null) { 15615 try { 15616 app.thread.setSchedulingGroup(app.curSchedGroup); 15617 } catch (RemoteException e) { 15618 } 15619 } 15620 } 15621 Process.setSwappiness(app.pid, 15622 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15623 } 15624 } 15625 if (app.repProcState != app.curProcState) { 15626 app.repProcState = app.curProcState; 15627 if (!reportingProcessState && app.thread != null) { 15628 try { 15629 if (false) { 15630 //RuntimeException h = new RuntimeException("here"); 15631 Slog.i(TAG, "Sending new process state " + app.repProcState 15632 + " to " + app /*, h*/); 15633 } 15634 app.thread.setProcessState(app.repProcState); 15635 } catch (RemoteException e) { 15636 } 15637 } 15638 } 15639 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15640 app.setProcState)) { 15641 app.lastStateTime = now; 15642 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15643 mSleeping, now); 15644 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15645 + ProcessList.makeProcStateString(app.setProcState) + " to " 15646 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15647 + (app.nextPssTime-now) + ": " + app); 15648 } else { 15649 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15650 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15651 requestPssLocked(app, app.setProcState); 15652 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15653 mSleeping, now); 15654 } else if (false && DEBUG_PSS) { 15655 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15656 } 15657 } 15658 if (app.setProcState != app.curProcState) { 15659 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15660 "Proc state change of " + app.processName 15661 + " to " + app.curProcState); 15662 app.setProcState = app.curProcState; 15663 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15664 app.notCachedSinceIdle = false; 15665 } 15666 if (!doingAll) { 15667 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15668 } else { 15669 app.procStateChanged = true; 15670 } 15671 } 15672 return success; 15673 } 15674 15675 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15676 if (proc.thread != null && proc.baseProcessTracker != null) { 15677 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15678 } 15679 } 15680 15681 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15682 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15683 if (app.thread == null) { 15684 return false; 15685 } 15686 15687 final boolean wasKeeping = app.keeping; 15688 15689 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15690 15691 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15692 reportingProcessState, now); 15693 } 15694 15695 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15696 boolean oomAdj) { 15697 if (isForeground != proc.foregroundServices) { 15698 proc.foregroundServices = isForeground; 15699 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15700 proc.info.uid); 15701 if (isForeground) { 15702 if (curProcs == null) { 15703 curProcs = new ArrayList<ProcessRecord>(); 15704 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15705 } 15706 if (!curProcs.contains(proc)) { 15707 curProcs.add(proc); 15708 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15709 proc.info.packageName, proc.info.uid); 15710 } 15711 } else { 15712 if (curProcs != null) { 15713 if (curProcs.remove(proc)) { 15714 mBatteryStatsService.noteEvent( 15715 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15716 proc.info.packageName, proc.info.uid); 15717 if (curProcs.size() <= 0) { 15718 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15719 } 15720 } 15721 } 15722 } 15723 if (oomAdj) { 15724 updateOomAdjLocked(); 15725 } 15726 } 15727 } 15728 15729 private final ActivityRecord resumedAppLocked() { 15730 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15731 String pkg; 15732 int uid; 15733 if (act != null && !act.sleeping) { 15734 pkg = act.packageName; 15735 uid = act.info.applicationInfo.uid; 15736 } else { 15737 pkg = null; 15738 uid = -1; 15739 } 15740 // Has the UID or resumed package name changed? 15741 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15742 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15743 if (mCurResumedPackage != null) { 15744 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15745 mCurResumedPackage, mCurResumedUid); 15746 } 15747 mCurResumedPackage = pkg; 15748 mCurResumedUid = uid; 15749 if (mCurResumedPackage != null) { 15750 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15751 mCurResumedPackage, mCurResumedUid); 15752 } 15753 } 15754 return act; 15755 } 15756 15757 final boolean updateOomAdjLocked(ProcessRecord app) { 15758 return updateOomAdjLocked(app, false); 15759 } 15760 15761 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15762 final ActivityRecord TOP_ACT = resumedAppLocked(); 15763 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15764 final boolean wasCached = app.cached; 15765 15766 mAdjSeq++; 15767 15768 // This is the desired cached adjusment we want to tell it to use. 15769 // If our app is currently cached, we know it, and that is it. Otherwise, 15770 // we don't know it yet, and it needs to now be cached we will then 15771 // need to do a complete oom adj. 15772 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15773 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15774 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15775 SystemClock.uptimeMillis()); 15776 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15777 // Changed to/from cached state, so apps after it in the LRU 15778 // list may also be changed. 15779 updateOomAdjLocked(); 15780 } 15781 return success; 15782 } 15783 15784 final void updateOomAdjLocked() { 15785 final ActivityRecord TOP_ACT = resumedAppLocked(); 15786 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15787 final long now = SystemClock.uptimeMillis(); 15788 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15789 final int N = mLruProcesses.size(); 15790 15791 if (false) { 15792 RuntimeException e = new RuntimeException(); 15793 e.fillInStackTrace(); 15794 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15795 } 15796 15797 mAdjSeq++; 15798 mNewNumServiceProcs = 0; 15799 mNewNumAServiceProcs = 0; 15800 15801 final int emptyProcessLimit; 15802 final int cachedProcessLimit; 15803 if (mProcessLimit <= 0) { 15804 emptyProcessLimit = cachedProcessLimit = 0; 15805 } else if (mProcessLimit == 1) { 15806 emptyProcessLimit = 1; 15807 cachedProcessLimit = 0; 15808 } else { 15809 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15810 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15811 } 15812 15813 // Let's determine how many processes we have running vs. 15814 // how many slots we have for background processes; we may want 15815 // to put multiple processes in a slot of there are enough of 15816 // them. 15817 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15818 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15819 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15820 if (numEmptyProcs > cachedProcessLimit) { 15821 // If there are more empty processes than our limit on cached 15822 // processes, then use the cached process limit for the factor. 15823 // This ensures that the really old empty processes get pushed 15824 // down to the bottom, so if we are running low on memory we will 15825 // have a better chance at keeping around more cached processes 15826 // instead of a gazillion empty processes. 15827 numEmptyProcs = cachedProcessLimit; 15828 } 15829 int emptyFactor = numEmptyProcs/numSlots; 15830 if (emptyFactor < 1) emptyFactor = 1; 15831 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15832 if (cachedFactor < 1) cachedFactor = 1; 15833 int stepCached = 0; 15834 int stepEmpty = 0; 15835 int numCached = 0; 15836 int numEmpty = 0; 15837 int numTrimming = 0; 15838 15839 mNumNonCachedProcs = 0; 15840 mNumCachedHiddenProcs = 0; 15841 15842 // First update the OOM adjustment for each of the 15843 // application processes based on their current state. 15844 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15845 int nextCachedAdj = curCachedAdj+1; 15846 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15847 int nextEmptyAdj = curEmptyAdj+2; 15848 for (int i=N-1; i>=0; i--) { 15849 ProcessRecord app = mLruProcesses.get(i); 15850 if (!app.killedByAm && app.thread != null) { 15851 app.procStateChanged = false; 15852 final boolean wasKeeping = app.keeping; 15853 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15854 15855 // If we haven't yet assigned the final cached adj 15856 // to the process, do that now. 15857 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15858 switch (app.curProcState) { 15859 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15860 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15861 // This process is a cached process holding activities... 15862 // assign it the next cached value for that type, and then 15863 // step that cached level. 15864 app.curRawAdj = curCachedAdj; 15865 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15866 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15867 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15868 + ")"); 15869 if (curCachedAdj != nextCachedAdj) { 15870 stepCached++; 15871 if (stepCached >= cachedFactor) { 15872 stepCached = 0; 15873 curCachedAdj = nextCachedAdj; 15874 nextCachedAdj += 2; 15875 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15876 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15877 } 15878 } 15879 } 15880 break; 15881 default: 15882 // For everything else, assign next empty cached process 15883 // level and bump that up. Note that this means that 15884 // long-running services that have dropped down to the 15885 // cached level will be treated as empty (since their process 15886 // state is still as a service), which is what we want. 15887 app.curRawAdj = curEmptyAdj; 15888 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15889 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15890 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15891 + ")"); 15892 if (curEmptyAdj != nextEmptyAdj) { 15893 stepEmpty++; 15894 if (stepEmpty >= emptyFactor) { 15895 stepEmpty = 0; 15896 curEmptyAdj = nextEmptyAdj; 15897 nextEmptyAdj += 2; 15898 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15899 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15900 } 15901 } 15902 } 15903 break; 15904 } 15905 } 15906 15907 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15908 15909 // Count the number of process types. 15910 switch (app.curProcState) { 15911 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15912 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15913 mNumCachedHiddenProcs++; 15914 numCached++; 15915 if (numCached > cachedProcessLimit) { 15916 killUnneededProcessLocked(app, "cached #" + numCached); 15917 } 15918 break; 15919 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15920 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15921 && app.lastActivityTime < oldTime) { 15922 killUnneededProcessLocked(app, "empty for " 15923 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15924 / 1000) + "s"); 15925 } else { 15926 numEmpty++; 15927 if (numEmpty > emptyProcessLimit) { 15928 killUnneededProcessLocked(app, "empty #" + numEmpty); 15929 } 15930 } 15931 break; 15932 default: 15933 mNumNonCachedProcs++; 15934 break; 15935 } 15936 15937 if (app.isolated && app.services.size() <= 0) { 15938 // If this is an isolated process, and there are no 15939 // services running in it, then the process is no longer 15940 // needed. We agressively kill these because we can by 15941 // definition not re-use the same process again, and it is 15942 // good to avoid having whatever code was running in them 15943 // left sitting around after no longer needed. 15944 killUnneededProcessLocked(app, "isolated not needed"); 15945 } 15946 15947 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15948 && !app.killedByAm) { 15949 numTrimming++; 15950 } 15951 } 15952 } 15953 15954 mNumServiceProcs = mNewNumServiceProcs; 15955 15956 // Now determine the memory trimming level of background processes. 15957 // Unfortunately we need to start at the back of the list to do this 15958 // properly. We only do this if the number of background apps we 15959 // are managing to keep around is less than half the maximum we desire; 15960 // if we are keeping a good number around, we'll let them use whatever 15961 // memory they want. 15962 final int numCachedAndEmpty = numCached + numEmpty; 15963 int memFactor; 15964 if (numCached <= ProcessList.TRIM_CACHED_APPS 15965 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15966 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15967 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15968 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15969 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15970 } else { 15971 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15972 } 15973 } else { 15974 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15975 } 15976 // We always allow the memory level to go up (better). We only allow it to go 15977 // down if we are in a state where that is allowed, *and* the total number of processes 15978 // has gone down since last time. 15979 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15980 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15981 + " last=" + mLastNumProcesses); 15982 if (memFactor > mLastMemoryLevel) { 15983 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15984 memFactor = mLastMemoryLevel; 15985 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15986 } 15987 } 15988 mLastMemoryLevel = memFactor; 15989 mLastNumProcesses = mLruProcesses.size(); 15990 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15991 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15992 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15993 if (mLowRamStartTime == 0) { 15994 mLowRamStartTime = now; 15995 } 15996 int step = 0; 15997 int fgTrimLevel; 15998 switch (memFactor) { 15999 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16000 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16001 break; 16002 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16003 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16004 break; 16005 default: 16006 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16007 break; 16008 } 16009 int factor = numTrimming/3; 16010 int minFactor = 2; 16011 if (mHomeProcess != null) minFactor++; 16012 if (mPreviousProcess != null) minFactor++; 16013 if (factor < minFactor) factor = minFactor; 16014 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16015 for (int i=N-1; i>=0; i--) { 16016 ProcessRecord app = mLruProcesses.get(i); 16017 if (allChanged || app.procStateChanged) { 16018 setProcessTrackerState(app, trackerMemFactor, now); 16019 app.procStateChanged = false; 16020 } 16021 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16022 && !app.killedByAm) { 16023 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16024 try { 16025 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16026 "Trimming memory of " + app.processName 16027 + " to " + curLevel); 16028 app.thread.scheduleTrimMemory(curLevel); 16029 } catch (RemoteException e) { 16030 } 16031 if (false) { 16032 // For now we won't do this; our memory trimming seems 16033 // to be good enough at this point that destroying 16034 // activities causes more harm than good. 16035 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16036 && app != mHomeProcess && app != mPreviousProcess) { 16037 // Need to do this on its own message because the stack may not 16038 // be in a consistent state at this point. 16039 // For these apps we will also finish their activities 16040 // to help them free memory. 16041 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16042 } 16043 } 16044 } 16045 app.trimMemoryLevel = curLevel; 16046 step++; 16047 if (step >= factor) { 16048 step = 0; 16049 switch (curLevel) { 16050 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16051 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16052 break; 16053 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16054 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16055 break; 16056 } 16057 } 16058 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16059 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16060 && app.thread != null) { 16061 try { 16062 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16063 "Trimming memory of heavy-weight " + app.processName 16064 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16065 app.thread.scheduleTrimMemory( 16066 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16067 } catch (RemoteException e) { 16068 } 16069 } 16070 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16071 } else { 16072 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16073 || app.systemNoUi) && app.pendingUiClean) { 16074 // If this application is now in the background and it 16075 // had done UI, then give it the special trim level to 16076 // have it free UI resources. 16077 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16078 if (app.trimMemoryLevel < level && app.thread != null) { 16079 try { 16080 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16081 "Trimming memory of bg-ui " + app.processName 16082 + " to " + level); 16083 app.thread.scheduleTrimMemory(level); 16084 } catch (RemoteException e) { 16085 } 16086 } 16087 app.pendingUiClean = false; 16088 } 16089 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16090 try { 16091 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16092 "Trimming memory of fg " + app.processName 16093 + " to " + fgTrimLevel); 16094 app.thread.scheduleTrimMemory(fgTrimLevel); 16095 } catch (RemoteException e) { 16096 } 16097 } 16098 app.trimMemoryLevel = fgTrimLevel; 16099 } 16100 } 16101 } else { 16102 if (mLowRamStartTime != 0) { 16103 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16104 mLowRamStartTime = 0; 16105 } 16106 for (int i=N-1; i>=0; i--) { 16107 ProcessRecord app = mLruProcesses.get(i); 16108 if (allChanged || app.procStateChanged) { 16109 setProcessTrackerState(app, trackerMemFactor, now); 16110 app.procStateChanged = false; 16111 } 16112 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16113 || app.systemNoUi) && app.pendingUiClean) { 16114 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16115 && app.thread != null) { 16116 try { 16117 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16118 "Trimming memory of ui hidden " + app.processName 16119 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16120 app.thread.scheduleTrimMemory( 16121 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16122 } catch (RemoteException e) { 16123 } 16124 } 16125 app.pendingUiClean = false; 16126 } 16127 app.trimMemoryLevel = 0; 16128 } 16129 } 16130 16131 if (mAlwaysFinishActivities) { 16132 // Need to do this on its own message because the stack may not 16133 // be in a consistent state at this point. 16134 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16135 } 16136 16137 if (allChanged) { 16138 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16139 } 16140 16141 if (mProcessStats.shouldWriteNowLocked(now)) { 16142 mHandler.post(new Runnable() { 16143 @Override public void run() { 16144 synchronized (ActivityManagerService.this) { 16145 mProcessStats.writeStateAsyncLocked(); 16146 } 16147 } 16148 }); 16149 } 16150 16151 if (DEBUG_OOM_ADJ) { 16152 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16153 } 16154 } 16155 16156 final void trimApplications() { 16157 synchronized (this) { 16158 int i; 16159 16160 // First remove any unused application processes whose package 16161 // has been removed. 16162 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16163 final ProcessRecord app = mRemovedProcesses.get(i); 16164 if (app.activities.size() == 0 16165 && app.curReceiver == null && app.services.size() == 0) { 16166 Slog.i( 16167 TAG, "Exiting empty application process " 16168 + app.processName + " (" 16169 + (app.thread != null ? app.thread.asBinder() : null) 16170 + ")\n"); 16171 if (app.pid > 0 && app.pid != MY_PID) { 16172 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16173 app.processName, app.setAdj, "empty"); 16174 app.killedByAm = true; 16175 Process.killProcessQuiet(app.pid); 16176 } else { 16177 try { 16178 app.thread.scheduleExit(); 16179 } catch (Exception e) { 16180 // Ignore exceptions. 16181 } 16182 } 16183 cleanUpApplicationRecordLocked(app, false, true, -1); 16184 mRemovedProcesses.remove(i); 16185 16186 if (app.persistent) { 16187 if (app.persistent) { 16188 addAppLocked(app.info, false); 16189 } 16190 } 16191 } 16192 } 16193 16194 // Now update the oom adj for all processes. 16195 updateOomAdjLocked(); 16196 } 16197 } 16198 16199 /** This method sends the specified signal to each of the persistent apps */ 16200 public void signalPersistentProcesses(int sig) throws RemoteException { 16201 if (sig != Process.SIGNAL_USR1) { 16202 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16203 } 16204 16205 synchronized (this) { 16206 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16207 != PackageManager.PERMISSION_GRANTED) { 16208 throw new SecurityException("Requires permission " 16209 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16210 } 16211 16212 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16213 ProcessRecord r = mLruProcesses.get(i); 16214 if (r.thread != null && r.persistent) { 16215 Process.sendSignal(r.pid, sig); 16216 } 16217 } 16218 } 16219 } 16220 16221 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16222 if (proc == null || proc == mProfileProc) { 16223 proc = mProfileProc; 16224 path = mProfileFile; 16225 profileType = mProfileType; 16226 clearProfilerLocked(); 16227 } 16228 if (proc == null) { 16229 return; 16230 } 16231 try { 16232 proc.thread.profilerControl(false, path, null, profileType); 16233 } catch (RemoteException e) { 16234 throw new IllegalStateException("Process disappeared"); 16235 } 16236 } 16237 16238 private void clearProfilerLocked() { 16239 if (mProfileFd != null) { 16240 try { 16241 mProfileFd.close(); 16242 } catch (IOException e) { 16243 } 16244 } 16245 mProfileApp = null; 16246 mProfileProc = null; 16247 mProfileFile = null; 16248 mProfileType = 0; 16249 mAutoStopProfiler = false; 16250 } 16251 16252 public boolean profileControl(String process, int userId, boolean start, 16253 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16254 16255 try { 16256 synchronized (this) { 16257 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16258 // its own permission. 16259 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16260 != PackageManager.PERMISSION_GRANTED) { 16261 throw new SecurityException("Requires permission " 16262 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16263 } 16264 16265 if (start && fd == null) { 16266 throw new IllegalArgumentException("null fd"); 16267 } 16268 16269 ProcessRecord proc = null; 16270 if (process != null) { 16271 proc = findProcessLocked(process, userId, "profileControl"); 16272 } 16273 16274 if (start && (proc == null || proc.thread == null)) { 16275 throw new IllegalArgumentException("Unknown process: " + process); 16276 } 16277 16278 if (start) { 16279 stopProfilerLocked(null, null, 0); 16280 setProfileApp(proc.info, proc.processName, path, fd, false); 16281 mProfileProc = proc; 16282 mProfileType = profileType; 16283 try { 16284 fd = fd.dup(); 16285 } catch (IOException e) { 16286 fd = null; 16287 } 16288 proc.thread.profilerControl(start, path, fd, profileType); 16289 fd = null; 16290 mProfileFd = null; 16291 } else { 16292 stopProfilerLocked(proc, path, profileType); 16293 if (fd != null) { 16294 try { 16295 fd.close(); 16296 } catch (IOException e) { 16297 } 16298 } 16299 } 16300 16301 return true; 16302 } 16303 } catch (RemoteException e) { 16304 throw new IllegalStateException("Process disappeared"); 16305 } finally { 16306 if (fd != null) { 16307 try { 16308 fd.close(); 16309 } catch (IOException e) { 16310 } 16311 } 16312 } 16313 } 16314 16315 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16316 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16317 userId, true, true, callName, null); 16318 ProcessRecord proc = null; 16319 try { 16320 int pid = Integer.parseInt(process); 16321 synchronized (mPidsSelfLocked) { 16322 proc = mPidsSelfLocked.get(pid); 16323 } 16324 } catch (NumberFormatException e) { 16325 } 16326 16327 if (proc == null) { 16328 ArrayMap<String, SparseArray<ProcessRecord>> all 16329 = mProcessNames.getMap(); 16330 SparseArray<ProcessRecord> procs = all.get(process); 16331 if (procs != null && procs.size() > 0) { 16332 proc = procs.valueAt(0); 16333 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16334 for (int i=1; i<procs.size(); i++) { 16335 ProcessRecord thisProc = procs.valueAt(i); 16336 if (thisProc.userId == userId) { 16337 proc = thisProc; 16338 break; 16339 } 16340 } 16341 } 16342 } 16343 } 16344 16345 return proc; 16346 } 16347 16348 public boolean dumpHeap(String process, int userId, boolean managed, 16349 String path, ParcelFileDescriptor fd) throws RemoteException { 16350 16351 try { 16352 synchronized (this) { 16353 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16354 // its own permission (same as profileControl). 16355 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16356 != PackageManager.PERMISSION_GRANTED) { 16357 throw new SecurityException("Requires permission " 16358 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16359 } 16360 16361 if (fd == null) { 16362 throw new IllegalArgumentException("null fd"); 16363 } 16364 16365 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16366 if (proc == null || proc.thread == null) { 16367 throw new IllegalArgumentException("Unknown process: " + process); 16368 } 16369 16370 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16371 if (!isDebuggable) { 16372 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16373 throw new SecurityException("Process not debuggable: " + proc); 16374 } 16375 } 16376 16377 proc.thread.dumpHeap(managed, path, fd); 16378 fd = null; 16379 return true; 16380 } 16381 } catch (RemoteException e) { 16382 throw new IllegalStateException("Process disappeared"); 16383 } finally { 16384 if (fd != null) { 16385 try { 16386 fd.close(); 16387 } catch (IOException e) { 16388 } 16389 } 16390 } 16391 } 16392 16393 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16394 public void monitor() { 16395 synchronized (this) { } 16396 } 16397 16398 void onCoreSettingsChange(Bundle settings) { 16399 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16400 ProcessRecord processRecord = mLruProcesses.get(i); 16401 try { 16402 if (processRecord.thread != null) { 16403 processRecord.thread.setCoreSettings(settings); 16404 } 16405 } catch (RemoteException re) { 16406 /* ignore */ 16407 } 16408 } 16409 } 16410 16411 // Multi-user methods 16412 16413 /** 16414 * Start user, if its not already running, but don't bring it to foreground. 16415 */ 16416 @Override 16417 public boolean startUserInBackground(final int userId) { 16418 return startUser(userId, /* foreground */ false); 16419 } 16420 16421 /** 16422 * Refreshes the list of users related to the current user when either a 16423 * user switch happens or when a new related user is started in the 16424 * background. 16425 */ 16426 private void updateCurrentProfileIdsLocked() { 16427 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16428 mCurrentUserId, false /* enabledOnly */); 16429 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16430 for (int i = 0; i < currentProfileIds.length; i++) { 16431 currentProfileIds[i] = profiles.get(i).id; 16432 } 16433 mCurrentProfileIds = currentProfileIds; 16434 } 16435 16436 private Set getProfileIdsLocked(int userId) { 16437 Set userIds = new HashSet<Integer>(); 16438 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16439 userId, false /* enabledOnly */); 16440 for (UserInfo user : profiles) { 16441 userIds.add(Integer.valueOf(user.id)); 16442 } 16443 return userIds; 16444 } 16445 16446 @Override 16447 public boolean switchUser(final int userId) { 16448 return startUser(userId, /* foregound */ true); 16449 } 16450 16451 private boolean startUser(final int userId, boolean foreground) { 16452 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16453 != PackageManager.PERMISSION_GRANTED) { 16454 String msg = "Permission Denial: switchUser() from pid=" 16455 + Binder.getCallingPid() 16456 + ", uid=" + Binder.getCallingUid() 16457 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16458 Slog.w(TAG, msg); 16459 throw new SecurityException(msg); 16460 } 16461 16462 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16463 16464 final long ident = Binder.clearCallingIdentity(); 16465 try { 16466 synchronized (this) { 16467 final int oldUserId = mCurrentUserId; 16468 if (oldUserId == userId) { 16469 return true; 16470 } 16471 16472 mStackSupervisor.setLockTaskModeLocked(null); 16473 16474 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16475 if (userInfo == null) { 16476 Slog.w(TAG, "No user info for user #" + userId); 16477 return false; 16478 } 16479 16480 if (foreground) { 16481 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16482 R.anim.screen_user_enter); 16483 } 16484 16485 boolean needStart = false; 16486 16487 // If the user we are switching to is not currently started, then 16488 // we need to start it now. 16489 if (mStartedUsers.get(userId) == null) { 16490 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16491 updateStartedUserArrayLocked(); 16492 needStart = true; 16493 } 16494 16495 final Integer userIdInt = Integer.valueOf(userId); 16496 mUserLru.remove(userIdInt); 16497 mUserLru.add(userIdInt); 16498 16499 if (foreground) { 16500 mCurrentUserId = userId; 16501 updateCurrentProfileIdsLocked(); 16502 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16503 // Once the internal notion of the active user has switched, we lock the device 16504 // with the option to show the user switcher on the keyguard. 16505 mWindowManager.lockNow(null); 16506 } else { 16507 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16508 updateCurrentProfileIdsLocked(); 16509 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16510 mUserLru.remove(currentUserIdInt); 16511 mUserLru.add(currentUserIdInt); 16512 } 16513 16514 final UserStartedState uss = mStartedUsers.get(userId); 16515 16516 // Make sure user is in the started state. If it is currently 16517 // stopping, we need to knock that off. 16518 if (uss.mState == UserStartedState.STATE_STOPPING) { 16519 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16520 // so we can just fairly silently bring the user back from 16521 // the almost-dead. 16522 uss.mState = UserStartedState.STATE_RUNNING; 16523 updateStartedUserArrayLocked(); 16524 needStart = true; 16525 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16526 // This means ACTION_SHUTDOWN has been sent, so we will 16527 // need to treat this as a new boot of the user. 16528 uss.mState = UserStartedState.STATE_BOOTING; 16529 updateStartedUserArrayLocked(); 16530 needStart = true; 16531 } 16532 16533 if (foreground) { 16534 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16535 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16536 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16537 oldUserId, userId, uss)); 16538 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16539 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16540 } 16541 16542 if (needStart) { 16543 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16544 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16545 | Intent.FLAG_RECEIVER_FOREGROUND); 16546 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16547 broadcastIntentLocked(null, null, intent, 16548 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16549 false, false, MY_PID, Process.SYSTEM_UID, userId); 16550 } 16551 16552 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16553 if (userId != 0) { 16554 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16555 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16556 broadcastIntentLocked(null, null, intent, null, 16557 new IIntentReceiver.Stub() { 16558 public void performReceive(Intent intent, int resultCode, 16559 String data, Bundle extras, boolean ordered, 16560 boolean sticky, int sendingUser) { 16561 userInitialized(uss, userId); 16562 } 16563 }, 0, null, null, null, AppOpsManager.OP_NONE, 16564 true, false, MY_PID, Process.SYSTEM_UID, 16565 userId); 16566 uss.initializing = true; 16567 } else { 16568 getUserManagerLocked().makeInitialized(userInfo.id); 16569 } 16570 } 16571 16572 if (foreground) { 16573 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16574 if (homeInFront) { 16575 startHomeActivityLocked(userId); 16576 } else { 16577 mStackSupervisor.resumeTopActivitiesLocked(); 16578 } 16579 EventLogTags.writeAmSwitchUser(userId); 16580 getUserManagerLocked().userForeground(userId); 16581 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16582 } 16583 16584 if (needStart) { 16585 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16586 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16587 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16588 broadcastIntentLocked(null, null, intent, 16589 null, new IIntentReceiver.Stub() { 16590 @Override 16591 public void performReceive(Intent intent, int resultCode, String data, 16592 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16593 throws RemoteException { 16594 } 16595 }, 0, null, null, 16596 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16597 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16598 } 16599 } 16600 } finally { 16601 Binder.restoreCallingIdentity(ident); 16602 } 16603 16604 return true; 16605 } 16606 16607 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16608 long ident = Binder.clearCallingIdentity(); 16609 try { 16610 Intent intent; 16611 if (oldUserId >= 0) { 16612 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16613 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16614 | Intent.FLAG_RECEIVER_FOREGROUND); 16615 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16616 broadcastIntentLocked(null, null, intent, 16617 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16618 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16619 } 16620 if (newUserId >= 0) { 16621 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16622 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16623 | Intent.FLAG_RECEIVER_FOREGROUND); 16624 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16625 broadcastIntentLocked(null, null, intent, 16626 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16627 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16628 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16629 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16630 | Intent.FLAG_RECEIVER_FOREGROUND); 16631 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16632 broadcastIntentLocked(null, null, intent, 16633 null, null, 0, null, null, 16634 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16635 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16636 } 16637 } finally { 16638 Binder.restoreCallingIdentity(ident); 16639 } 16640 } 16641 16642 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16643 final int newUserId) { 16644 final int N = mUserSwitchObservers.beginBroadcast(); 16645 if (N > 0) { 16646 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16647 int mCount = 0; 16648 @Override 16649 public void sendResult(Bundle data) throws RemoteException { 16650 synchronized (ActivityManagerService.this) { 16651 if (mCurUserSwitchCallback == this) { 16652 mCount++; 16653 if (mCount == N) { 16654 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16655 } 16656 } 16657 } 16658 } 16659 }; 16660 synchronized (this) { 16661 uss.switching = true; 16662 mCurUserSwitchCallback = callback; 16663 } 16664 for (int i=0; i<N; i++) { 16665 try { 16666 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16667 newUserId, callback); 16668 } catch (RemoteException e) { 16669 } 16670 } 16671 } else { 16672 synchronized (this) { 16673 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16674 } 16675 } 16676 mUserSwitchObservers.finishBroadcast(); 16677 } 16678 16679 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16680 synchronized (this) { 16681 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16682 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16683 } 16684 } 16685 16686 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16687 mCurUserSwitchCallback = null; 16688 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16689 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16690 oldUserId, newUserId, uss)); 16691 } 16692 16693 void userInitialized(UserStartedState uss, int newUserId) { 16694 completeSwitchAndInitalize(uss, newUserId, true, false); 16695 } 16696 16697 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16698 completeSwitchAndInitalize(uss, newUserId, false, true); 16699 } 16700 16701 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16702 boolean clearInitializing, boolean clearSwitching) { 16703 boolean unfrozen = false; 16704 synchronized (this) { 16705 if (clearInitializing) { 16706 uss.initializing = false; 16707 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16708 } 16709 if (clearSwitching) { 16710 uss.switching = false; 16711 } 16712 if (!uss.switching && !uss.initializing) { 16713 mWindowManager.stopFreezingScreen(); 16714 unfrozen = true; 16715 } 16716 } 16717 if (unfrozen) { 16718 final int N = mUserSwitchObservers.beginBroadcast(); 16719 for (int i=0; i<N; i++) { 16720 try { 16721 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16722 } catch (RemoteException e) { 16723 } 16724 } 16725 mUserSwitchObservers.finishBroadcast(); 16726 } 16727 } 16728 16729 void scheduleStartProfilesLocked() { 16730 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16731 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16732 DateUtils.SECOND_IN_MILLIS); 16733 } 16734 } 16735 16736 void startProfilesLocked() { 16737 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16738 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16739 mCurrentUserId, false /* enabledOnly */); 16740 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16741 for (UserInfo user : profiles) { 16742 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16743 && user.id != mCurrentUserId) { 16744 toStart.add(user); 16745 } 16746 } 16747 final int n = toStart.size(); 16748 int i = 0; 16749 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16750 startUserInBackground(toStart.get(i).id); 16751 } 16752 if (i < n) { 16753 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16754 } 16755 } 16756 16757 void finishUserSwitch(UserStartedState uss) { 16758 synchronized (this) { 16759 if (uss.mState == UserStartedState.STATE_BOOTING 16760 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16761 uss.mState = UserStartedState.STATE_RUNNING; 16762 final int userId = uss.mHandle.getIdentifier(); 16763 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16764 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16765 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16766 broadcastIntentLocked(null, null, intent, 16767 null, null, 0, null, null, 16768 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16769 true, false, MY_PID, Process.SYSTEM_UID, userId); 16770 } 16771 16772 startProfilesLocked(); 16773 16774 int num = mUserLru.size(); 16775 int i = 0; 16776 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16777 Integer oldUserId = mUserLru.get(i); 16778 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16779 if (oldUss == null) { 16780 // Shouldn't happen, but be sane if it does. 16781 mUserLru.remove(i); 16782 num--; 16783 continue; 16784 } 16785 if (oldUss.mState == UserStartedState.STATE_STOPPING 16786 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16787 // This user is already stopping, doesn't count. 16788 num--; 16789 i++; 16790 continue; 16791 } 16792 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16793 // Owner and current can't be stopped, but count as running. 16794 i++; 16795 continue; 16796 } 16797 // This is a user to be stopped. 16798 stopUserLocked(oldUserId, null); 16799 num--; 16800 i++; 16801 } 16802 } 16803 } 16804 16805 @Override 16806 public int stopUser(final int userId, final IStopUserCallback callback) { 16807 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16808 != PackageManager.PERMISSION_GRANTED) { 16809 String msg = "Permission Denial: switchUser() from pid=" 16810 + Binder.getCallingPid() 16811 + ", uid=" + Binder.getCallingUid() 16812 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16813 Slog.w(TAG, msg); 16814 throw new SecurityException(msg); 16815 } 16816 if (userId <= 0) { 16817 throw new IllegalArgumentException("Can't stop primary user " + userId); 16818 } 16819 synchronized (this) { 16820 return stopUserLocked(userId, callback); 16821 } 16822 } 16823 16824 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16825 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16826 if (mCurrentUserId == userId) { 16827 return ActivityManager.USER_OP_IS_CURRENT; 16828 } 16829 16830 final UserStartedState uss = mStartedUsers.get(userId); 16831 if (uss == null) { 16832 // User is not started, nothing to do... but we do need to 16833 // callback if requested. 16834 if (callback != null) { 16835 mHandler.post(new Runnable() { 16836 @Override 16837 public void run() { 16838 try { 16839 callback.userStopped(userId); 16840 } catch (RemoteException e) { 16841 } 16842 } 16843 }); 16844 } 16845 return ActivityManager.USER_OP_SUCCESS; 16846 } 16847 16848 if (callback != null) { 16849 uss.mStopCallbacks.add(callback); 16850 } 16851 16852 if (uss.mState != UserStartedState.STATE_STOPPING 16853 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16854 uss.mState = UserStartedState.STATE_STOPPING; 16855 updateStartedUserArrayLocked(); 16856 16857 long ident = Binder.clearCallingIdentity(); 16858 try { 16859 // We are going to broadcast ACTION_USER_STOPPING and then 16860 // once that is done send a final ACTION_SHUTDOWN and then 16861 // stop the user. 16862 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16863 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16864 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16865 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16866 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16867 // This is the result receiver for the final shutdown broadcast. 16868 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16869 @Override 16870 public void performReceive(Intent intent, int resultCode, String data, 16871 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16872 finishUserStop(uss); 16873 } 16874 }; 16875 // This is the result receiver for the initial stopping broadcast. 16876 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16877 @Override 16878 public void performReceive(Intent intent, int resultCode, String data, 16879 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16880 // On to the next. 16881 synchronized (ActivityManagerService.this) { 16882 if (uss.mState != UserStartedState.STATE_STOPPING) { 16883 // Whoops, we are being started back up. Abort, abort! 16884 return; 16885 } 16886 uss.mState = UserStartedState.STATE_SHUTDOWN; 16887 } 16888 broadcastIntentLocked(null, null, shutdownIntent, 16889 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16890 true, false, MY_PID, Process.SYSTEM_UID, userId); 16891 } 16892 }; 16893 // Kick things off. 16894 broadcastIntentLocked(null, null, stoppingIntent, 16895 null, stoppingReceiver, 0, null, null, 16896 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16897 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16898 } finally { 16899 Binder.restoreCallingIdentity(ident); 16900 } 16901 } 16902 16903 return ActivityManager.USER_OP_SUCCESS; 16904 } 16905 16906 void finishUserStop(UserStartedState uss) { 16907 final int userId = uss.mHandle.getIdentifier(); 16908 boolean stopped; 16909 ArrayList<IStopUserCallback> callbacks; 16910 synchronized (this) { 16911 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16912 if (mStartedUsers.get(userId) != uss) { 16913 stopped = false; 16914 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16915 stopped = false; 16916 } else { 16917 stopped = true; 16918 // User can no longer run. 16919 mStartedUsers.remove(userId); 16920 mUserLru.remove(Integer.valueOf(userId)); 16921 updateStartedUserArrayLocked(); 16922 16923 // Clean up all state and processes associated with the user. 16924 // Kill all the processes for the user. 16925 forceStopUserLocked(userId, "finish user"); 16926 } 16927 } 16928 16929 for (int i=0; i<callbacks.size(); i++) { 16930 try { 16931 if (stopped) callbacks.get(i).userStopped(userId); 16932 else callbacks.get(i).userStopAborted(userId); 16933 } catch (RemoteException e) { 16934 } 16935 } 16936 16937 mStackSupervisor.removeUserLocked(userId); 16938 } 16939 16940 @Override 16941 public UserInfo getCurrentUser() { 16942 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16943 != PackageManager.PERMISSION_GRANTED) && ( 16944 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16945 != PackageManager.PERMISSION_GRANTED)) { 16946 String msg = "Permission Denial: getCurrentUser() from pid=" 16947 + Binder.getCallingPid() 16948 + ", uid=" + Binder.getCallingUid() 16949 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16950 Slog.w(TAG, msg); 16951 throw new SecurityException(msg); 16952 } 16953 synchronized (this) { 16954 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16955 } 16956 } 16957 16958 int getCurrentUserIdLocked() { 16959 return mCurrentUserId; 16960 } 16961 16962 @Override 16963 public boolean isUserRunning(int userId, boolean orStopped) { 16964 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16965 != PackageManager.PERMISSION_GRANTED) { 16966 String msg = "Permission Denial: isUserRunning() from pid=" 16967 + Binder.getCallingPid() 16968 + ", uid=" + Binder.getCallingUid() 16969 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16970 Slog.w(TAG, msg); 16971 throw new SecurityException(msg); 16972 } 16973 synchronized (this) { 16974 return isUserRunningLocked(userId, orStopped); 16975 } 16976 } 16977 16978 boolean isUserRunningLocked(int userId, boolean orStopped) { 16979 UserStartedState state = mStartedUsers.get(userId); 16980 if (state == null) { 16981 return false; 16982 } 16983 if (orStopped) { 16984 return true; 16985 } 16986 return state.mState != UserStartedState.STATE_STOPPING 16987 && state.mState != UserStartedState.STATE_SHUTDOWN; 16988 } 16989 16990 @Override 16991 public int[] getRunningUserIds() { 16992 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16993 != PackageManager.PERMISSION_GRANTED) { 16994 String msg = "Permission Denial: isUserRunning() from pid=" 16995 + Binder.getCallingPid() 16996 + ", uid=" + Binder.getCallingUid() 16997 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16998 Slog.w(TAG, msg); 16999 throw new SecurityException(msg); 17000 } 17001 synchronized (this) { 17002 return mStartedUserArray; 17003 } 17004 } 17005 17006 private void updateStartedUserArrayLocked() { 17007 int num = 0; 17008 for (int i=0; i<mStartedUsers.size(); i++) { 17009 UserStartedState uss = mStartedUsers.valueAt(i); 17010 // This list does not include stopping users. 17011 if (uss.mState != UserStartedState.STATE_STOPPING 17012 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17013 num++; 17014 } 17015 } 17016 mStartedUserArray = new int[num]; 17017 num = 0; 17018 for (int i=0; i<mStartedUsers.size(); i++) { 17019 UserStartedState uss = mStartedUsers.valueAt(i); 17020 if (uss.mState != UserStartedState.STATE_STOPPING 17021 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17022 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17023 num++; 17024 } 17025 } 17026 } 17027 17028 @Override 17029 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17030 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17031 != PackageManager.PERMISSION_GRANTED) { 17032 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17033 + Binder.getCallingPid() 17034 + ", uid=" + Binder.getCallingUid() 17035 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17036 Slog.w(TAG, msg); 17037 throw new SecurityException(msg); 17038 } 17039 17040 mUserSwitchObservers.register(observer); 17041 } 17042 17043 @Override 17044 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17045 mUserSwitchObservers.unregister(observer); 17046 } 17047 17048 private boolean userExists(int userId) { 17049 if (userId == 0) { 17050 return true; 17051 } 17052 UserManagerService ums = getUserManagerLocked(); 17053 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17054 } 17055 17056 int[] getUsersLocked() { 17057 UserManagerService ums = getUserManagerLocked(); 17058 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17059 } 17060 17061 UserManagerService getUserManagerLocked() { 17062 if (mUserManager == null) { 17063 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17064 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17065 } 17066 return mUserManager; 17067 } 17068 17069 private int applyUserId(int uid, int userId) { 17070 return UserHandle.getUid(userId, uid); 17071 } 17072 17073 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17074 if (info == null) return null; 17075 ApplicationInfo newInfo = new ApplicationInfo(info); 17076 newInfo.uid = applyUserId(info.uid, userId); 17077 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17078 + info.packageName; 17079 return newInfo; 17080 } 17081 17082 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17083 if (aInfo == null 17084 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17085 return aInfo; 17086 } 17087 17088 ActivityInfo info = new ActivityInfo(aInfo); 17089 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17090 return info; 17091 } 17092 17093 private final class LocalService extends ActivityManagerInternal { 17094 @Override 17095 public void goingToSleep() { 17096 ActivityManagerService.this.goingToSleep(); 17097 } 17098 17099 @Override 17100 public void wakingUp() { 17101 ActivityManagerService.this.wakingUp(); 17102 } 17103 } 17104} 17105