ActivityManagerService.java revision 2a764949c943681a4d25a17a0b203a0127a4a486
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30import android.app.AppOpsManager; 31import android.app.IActivityContainer; 32import android.app.IActivityContainerCallback; 33import android.appwidget.AppWidgetManager; 34import android.graphics.Rect; 35import android.os.BatteryStats; 36import android.util.ArrayMap; 37import com.android.internal.R; 38import com.android.internal.annotations.GuardedBy; 39import com.android.internal.app.IAppOpsService; 40import com.android.internal.app.ProcessMap; 41import com.android.internal.app.ProcessStats; 42import com.android.internal.os.BackgroundThread; 43import com.android.internal.os.BatteryStatsImpl; 44import com.android.internal.os.ProcessCpuTracker; 45import com.android.internal.os.TransferPipe; 46import com.android.internal.util.FastPrintWriter; 47import com.android.internal.util.FastXmlSerializer; 48import com.android.internal.util.MemInfoReader; 49import com.android.internal.util.Preconditions; 50import com.android.server.AppOpsService; 51import com.android.server.AttributeCache; 52import com.android.server.IntentResolver; 53import com.android.server.ServiceThread; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 65 66import libcore.io.IoUtils; 67 68import org.xmlpull.v1.XmlPullParser; 69import org.xmlpull.v1.XmlPullParserException; 70import org.xmlpull.v1.XmlSerializer; 71 72import android.app.Activity; 73import android.app.ActivityManager; 74import android.app.ActivityManager.RunningTaskInfo; 75import android.app.ActivityManager.StackInfo; 76import android.app.ActivityManagerNative; 77import android.app.ActivityOptions; 78import android.app.ActivityThread; 79import android.app.AlertDialog; 80import android.app.AppGlobals; 81import android.app.ApplicationErrorReport; 82import android.app.Dialog; 83import android.app.IActivityController; 84import android.app.IApplicationThread; 85import android.app.IInstrumentationWatcher; 86import android.app.INotificationManager; 87import android.app.IProcessObserver; 88import android.app.IServiceConnection; 89import android.app.IStopUserCallback; 90import android.app.IThumbnailReceiver; 91import android.app.IUiAutomationConnection; 92import android.app.IUserSwitchObserver; 93import android.app.Instrumentation; 94import android.app.Notification; 95import android.app.NotificationManager; 96import android.app.PendingIntent; 97import android.app.backup.IBackupManager; 98import android.content.ActivityNotFoundException; 99import android.content.BroadcastReceiver; 100import android.content.ClipData; 101import android.content.ComponentCallbacks2; 102import android.content.ComponentName; 103import android.content.ContentProvider; 104import android.content.ContentResolver; 105import android.content.Context; 106import android.content.DialogInterface; 107import android.content.IContentProvider; 108import android.content.IIntentReceiver; 109import android.content.IIntentSender; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.pm.ActivityInfo; 114import android.content.pm.ApplicationInfo; 115import android.content.pm.ConfigurationInfo; 116import android.content.pm.IPackageDataObserver; 117import android.content.pm.IPackageManager; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.PackageInfo; 120import android.content.pm.PackageManager; 121import android.content.pm.ParceledListSlice; 122import android.content.pm.UserInfo; 123import android.content.pm.PackageManager.NameNotFoundException; 124import android.content.pm.PathPermission; 125import android.content.pm.ProviderInfo; 126import android.content.pm.ResolveInfo; 127import android.content.pm.ServiceInfo; 128import android.content.res.CompatibilityInfo; 129import android.content.res.Configuration; 130import android.graphics.Bitmap; 131import android.net.Proxy; 132import android.net.ProxyProperties; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.DropBoxManager; 139import android.os.Environment; 140import android.os.FactoryTest; 141import android.os.FileObserver; 142import android.os.FileUtils; 143import android.os.Handler; 144import android.os.IBinder; 145import android.os.IPermissionController; 146import android.os.IRemoteCallback; 147import android.os.IUserManager; 148import android.os.Looper; 149import android.os.Message; 150import android.os.Parcel; 151import android.os.ParcelFileDescriptor; 152import android.os.Process; 153import android.os.RemoteCallbackList; 154import android.os.RemoteException; 155import android.os.SELinux; 156import android.os.ServiceManager; 157import android.os.StrictMode; 158import android.os.SystemClock; 159import android.os.SystemProperties; 160import android.os.UpdateLock; 161import android.os.UserHandle; 162import android.provider.Settings; 163import android.text.format.DateUtils; 164import android.text.format.Time; 165import android.util.AtomicFile; 166import android.util.EventLog; 167import android.util.Log; 168import android.util.Pair; 169import android.util.PrintWriterPrinter; 170import android.util.Slog; 171import android.util.SparseArray; 172import android.util.TimeUtils; 173import android.util.Xml; 174import android.view.Gravity; 175import android.view.LayoutInflater; 176import android.view.View; 177import android.view.WindowManager; 178 179import java.io.BufferedInputStream; 180import java.io.BufferedOutputStream; 181import java.io.DataInputStream; 182import java.io.DataOutputStream; 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.InputStreamReader; 190import java.io.PrintWriter; 191import java.io.StringWriter; 192import java.lang.ref.WeakReference; 193import java.util.ArrayList; 194import java.util.Arrays; 195import java.util.Collections; 196import java.util.Comparator; 197import java.util.HashMap; 198import java.util.HashSet; 199import java.util.Iterator; 200import java.util.List; 201import java.util.Locale; 202import java.util.Map; 203import java.util.Set; 204import java.util.concurrent.atomic.AtomicBoolean; 205import java.util.concurrent.atomic.AtomicLong; 206 207public final class ActivityManagerService extends ActivityManagerNative 208 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 209 private static final String USER_DATA_DIR = "/data/user/"; 210 static final String TAG = "ActivityManager"; 211 static final String TAG_MU = "ActivityManagerServiceMU"; 212 static final boolean DEBUG = false; 213 static final boolean localLOGV = DEBUG; 214 static final boolean DEBUG_BACKUP = localLOGV || false; 215 static final boolean DEBUG_BROADCAST = localLOGV || false; 216 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_CLEANUP = localLOGV || false; 219 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 220 static final boolean DEBUG_FOCUS = false; 221 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 222 static final boolean DEBUG_MU = localLOGV || false; 223 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 224 static final boolean DEBUG_LRU = localLOGV || false; 225 static final boolean DEBUG_PAUSE = localLOGV || false; 226 static final boolean DEBUG_POWER = localLOGV || false; 227 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 228 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 229 static final boolean DEBUG_PROCESSES = localLOGV || false; 230 static final boolean DEBUG_PROVIDER = localLOGV || false; 231 static final boolean DEBUG_RESULTS = localLOGV || false; 232 static final boolean DEBUG_SERVICE = localLOGV || false; 233 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 234 static final boolean DEBUG_STACK = localLOGV || false; 235 static final boolean DEBUG_SWITCH = localLOGV || false; 236 static final boolean DEBUG_TASKS = localLOGV || false; 237 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 238 static final boolean DEBUG_TRANSITION = localLOGV || false; 239 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 240 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 241 static final boolean DEBUG_VISBILITY = localLOGV || false; 242 static final boolean DEBUG_PSS = localLOGV || false; 243 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 244 static final boolean VALIDATE_TOKENS = false; 245 static final boolean SHOW_ACTIVITY_START_TIME = true; 246 247 // Control over CPU and battery monitoring. 248 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 249 static final boolean MONITOR_CPU_USAGE = true; 250 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 251 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 252 static final boolean MONITOR_THREAD_CPU_USAGE = false; 253 254 // The flags that are set for all calls we make to the package manager. 255 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 256 257 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 258 259 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 260 261 // Maximum number of recent tasks that we can remember. 262 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 263 264 // Amount of time after a call to stopAppSwitches() during which we will 265 // prevent further untrusted switches from happening. 266 static final long APP_SWITCH_DELAY_TIME = 5*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real. 270 static final int PROC_START_TIMEOUT = 10*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, when the process was 274 // started with a wrapper for instrumentation (such as Valgrind) because it 275 // could take much longer than usual. 276 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 boolean mStartRunning = false; 803 ComponentName mTopComponent; 804 String mTopAction; 805 String mTopData; 806 boolean mProcessesReady = false; 807 boolean mSystemReady = false; 808 boolean mBooting = false; 809 boolean mWaitingUpdate = false; 810 boolean mDidUpdate = false; 811 boolean mOnBattery = false; 812 boolean mLaunchWarningShown = false; 813 814 Context mContext; 815 816 int mFactoryTest; 817 818 boolean mCheckedForSetup; 819 820 /** 821 * The time at which we will allow normal application switches again, 822 * after a call to {@link #stopAppSwitches()}. 823 */ 824 long mAppSwitchesAllowedTime; 825 826 /** 827 * This is set to true after the first switch after mAppSwitchesAllowedTime 828 * is set; any switches after that will clear the time. 829 */ 830 boolean mDidAppSwitch; 831 832 /** 833 * Last time (in realtime) at which we checked for power usage. 834 */ 835 long mLastPowerCheckRealtime; 836 837 /** 838 * Last time (in uptime) at which we checked for power usage. 839 */ 840 long mLastPowerCheckUptime; 841 842 /** 843 * Set while we are wanting to sleep, to prevent any 844 * activities from being started/resumed. 845 */ 846 boolean mSleeping = false; 847 848 /** 849 * State of external calls telling us if the device is asleep. 850 */ 851 boolean mWentToSleep = false; 852 853 /** 854 * State of external call telling us if the lock screen is shown. 855 */ 856 boolean mLockScreenShown = false; 857 858 /** 859 * Set if we are shutting down the system, similar to sleeping. 860 */ 861 boolean mShuttingDown = false; 862 863 /** 864 * Current sequence id for oom_adj computation traversal. 865 */ 866 int mAdjSeq = 0; 867 868 /** 869 * Current sequence id for process LRU updating. 870 */ 871 int mLruSeq = 0; 872 873 /** 874 * Keep track of the non-cached/empty process we last found, to help 875 * determine how to distribute cached/empty processes next time. 876 */ 877 int mNumNonCachedProcs = 0; 878 879 /** 880 * Keep track of the number of cached hidden procs, to balance oom adj 881 * distribution between those and empty procs. 882 */ 883 int mNumCachedHiddenProcs = 0; 884 885 /** 886 * Keep track of the number of service processes we last found, to 887 * determine on the next iteration which should be B services. 888 */ 889 int mNumServiceProcs = 0; 890 int mNewNumAServiceProcs = 0; 891 int mNewNumServiceProcs = 0; 892 893 /** 894 * Allow the current computed overall memory level of the system to go down? 895 * This is set to false when we are killing processes for reasons other than 896 * memory management, so that the now smaller process list will not be taken as 897 * an indication that memory is tighter. 898 */ 899 boolean mAllowLowerMemLevel = false; 900 901 /** 902 * The last computed memory level, for holding when we are in a state that 903 * processes are going away for other reasons. 904 */ 905 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 906 907 /** 908 * The last total number of process we have, to determine if changes actually look 909 * like a shrinking number of process due to lower RAM. 910 */ 911 int mLastNumProcesses; 912 913 /** 914 * The uptime of the last time we performed idle maintenance. 915 */ 916 long mLastIdleTime = SystemClock.uptimeMillis(); 917 918 /** 919 * Total time spent with RAM that has been added in the past since the last idle time. 920 */ 921 long mLowRamTimeSinceLastIdle = 0; 922 923 /** 924 * If RAM is currently low, when that horrible situation started. 925 */ 926 long mLowRamStartTime = 0; 927 928 /** 929 * For reporting to battery stats the current top application. 930 */ 931 private String mCurResumedPackage = null; 932 private int mCurResumedUid = -1; 933 934 /** 935 * For reporting to battery stats the apps currently running foreground 936 * service. The ProcessMap is package/uid tuples; each of these contain 937 * an array of the currently foreground processes. 938 */ 939 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 940 = new ProcessMap<ArrayList<ProcessRecord>>(); 941 942 /** 943 * This is set if we had to do a delayed dexopt of an app before launching 944 * it, to increasing the ANR timeouts in that case. 945 */ 946 boolean mDidDexOpt; 947 948 /** 949 * Set if the systemServer made a call to enterSafeMode. 950 */ 951 boolean mSafeMode; 952 953 String mDebugApp = null; 954 boolean mWaitForDebugger = false; 955 boolean mDebugTransient = false; 956 String mOrigDebugApp = null; 957 boolean mOrigWaitForDebugger = false; 958 boolean mAlwaysFinishActivities = false; 959 IActivityController mController = null; 960 String mProfileApp = null; 961 ProcessRecord mProfileProc = null; 962 String mProfileFile; 963 ParcelFileDescriptor mProfileFd; 964 int mProfileType = 0; 965 boolean mAutoStopProfiler = false; 966 String mOpenGlTraceApp = null; 967 968 static class ProcessChangeItem { 969 static final int CHANGE_ACTIVITIES = 1<<0; 970 static final int CHANGE_IMPORTANCE= 1<<1; 971 int changes; 972 int uid; 973 int pid; 974 int importance; 975 boolean foregroundActivities; 976 } 977 978 final RemoteCallbackList<IProcessObserver> mProcessObservers 979 = new RemoteCallbackList<IProcessObserver>(); 980 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 981 982 final ArrayList<ProcessChangeItem> mPendingProcessChanges 983 = new ArrayList<ProcessChangeItem>(); 984 final ArrayList<ProcessChangeItem> mAvailProcessChanges 985 = new ArrayList<ProcessChangeItem>(); 986 987 /** 988 * Runtime CPU use collection thread. This object's lock is used to 989 * protect all related state. 990 */ 991 final Thread mProcessCpuThread; 992 993 /** 994 * Used to collect process stats when showing not responding dialog. 995 * Protected by mProcessCpuThread. 996 */ 997 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 998 MONITOR_THREAD_CPU_USAGE); 999 final AtomicLong mLastCpuTime = new AtomicLong(0); 1000 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1001 1002 long mLastWriteTime = 0; 1003 1004 /** 1005 * Used to retain an update lock when the foreground activity is in 1006 * immersive mode. 1007 */ 1008 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1009 1010 /** 1011 * Set to true after the system has finished booting. 1012 */ 1013 boolean mBooted = false; 1014 1015 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1016 int mProcessLimitOverride = -1; 1017 1018 WindowManagerService mWindowManager; 1019 1020 final ActivityThread mSystemThread; 1021 1022 int mCurrentUserId = 0; 1023 int[] mCurrentProfileIds = new int[0]; // Accessed by ActivityStack 1024 private UserManagerService mUserManager; 1025 1026 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1027 final ProcessRecord mApp; 1028 final int mPid; 1029 final IApplicationThread mAppThread; 1030 1031 AppDeathRecipient(ProcessRecord app, int pid, 1032 IApplicationThread thread) { 1033 if (localLOGV) Slog.v( 1034 TAG, "New death recipient " + this 1035 + " for thread " + thread.asBinder()); 1036 mApp = app; 1037 mPid = pid; 1038 mAppThread = thread; 1039 } 1040 1041 @Override 1042 public void binderDied() { 1043 if (localLOGV) Slog.v( 1044 TAG, "Death received in " + this 1045 + " for thread " + mAppThread.asBinder()); 1046 synchronized(ActivityManagerService.this) { 1047 appDiedLocked(mApp, mPid, mAppThread); 1048 } 1049 } 1050 } 1051 1052 static final int SHOW_ERROR_MSG = 1; 1053 static final int SHOW_NOT_RESPONDING_MSG = 2; 1054 static final int SHOW_FACTORY_ERROR_MSG = 3; 1055 static final int UPDATE_CONFIGURATION_MSG = 4; 1056 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1057 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1058 static final int SERVICE_TIMEOUT_MSG = 12; 1059 static final int UPDATE_TIME_ZONE = 13; 1060 static final int SHOW_UID_ERROR_MSG = 14; 1061 static final int IM_FEELING_LUCKY_MSG = 15; 1062 static final int PROC_START_TIMEOUT_MSG = 20; 1063 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1064 static final int KILL_APPLICATION_MSG = 22; 1065 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1066 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1067 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1068 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1069 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1070 static final int CLEAR_DNS_CACHE_MSG = 28; 1071 static final int UPDATE_HTTP_PROXY_MSG = 29; 1072 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1073 static final int DISPATCH_PROCESSES_CHANGED = 31; 1074 static final int DISPATCH_PROCESS_DIED = 32; 1075 static final int REPORT_MEM_USAGE_MSG = 33; 1076 static final int REPORT_USER_SWITCH_MSG = 34; 1077 static final int CONTINUE_USER_SWITCH_MSG = 35; 1078 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1079 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1080 static final int PERSIST_URI_GRANTS_MSG = 38; 1081 static final int REQUEST_ALL_PSS_MSG = 39; 1082 static final int START_PROFILES_MSG = 40; 1083 static final int UPDATE_TIME = 41; 1084 1085 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1086 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1087 static final int FIRST_COMPAT_MODE_MSG = 300; 1088 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1089 1090 AlertDialog mUidAlert; 1091 CompatModeDialog mCompatModeDialog; 1092 long mLastMemUsageReportTime = 0; 1093 1094 /** 1095 * Flag whether the current user is a "monkey", i.e. whether 1096 * the UI is driven by a UI automation tool. 1097 */ 1098 private boolean mUserIsMonkey; 1099 1100 final ServiceThread mHandlerThread; 1101 final MainHandler mHandler; 1102 1103 final class MainHandler extends Handler { 1104 public MainHandler(Looper looper) { 1105 super(looper, null, true); 1106 } 1107 1108 @Override 1109 public void handleMessage(Message msg) { 1110 switch (msg.what) { 1111 case SHOW_ERROR_MSG: { 1112 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1113 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1114 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1115 synchronized (ActivityManagerService.this) { 1116 ProcessRecord proc = (ProcessRecord)data.get("app"); 1117 AppErrorResult res = (AppErrorResult) data.get("result"); 1118 if (proc != null && proc.crashDialog != null) { 1119 Slog.e(TAG, "App already has crash dialog: " + proc); 1120 if (res != null) { 1121 res.set(0); 1122 } 1123 return; 1124 } 1125 if (!showBackground && UserHandle.getAppId(proc.uid) 1126 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1127 && proc.pid != MY_PID) { 1128 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1129 if (res != null) { 1130 res.set(0); 1131 } 1132 return; 1133 } 1134 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1135 Dialog d = new AppErrorDialog(mContext, 1136 ActivityManagerService.this, res, proc); 1137 d.show(); 1138 proc.crashDialog = d; 1139 } else { 1140 // The device is asleep, so just pretend that the user 1141 // saw a crash dialog and hit "force quit". 1142 if (res != null) { 1143 res.set(0); 1144 } 1145 } 1146 } 1147 1148 ensureBootCompleted(); 1149 } break; 1150 case SHOW_NOT_RESPONDING_MSG: { 1151 synchronized (ActivityManagerService.this) { 1152 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1153 ProcessRecord proc = (ProcessRecord)data.get("app"); 1154 if (proc != null && proc.anrDialog != null) { 1155 Slog.e(TAG, "App already has anr dialog: " + proc); 1156 return; 1157 } 1158 1159 Intent intent = new Intent("android.intent.action.ANR"); 1160 if (!mProcessesReady) { 1161 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1162 | Intent.FLAG_RECEIVER_FOREGROUND); 1163 } 1164 broadcastIntentLocked(null, null, intent, 1165 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1166 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1167 1168 if (mShowDialogs) { 1169 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1170 mContext, proc, (ActivityRecord)data.get("activity"), 1171 msg.arg1 != 0); 1172 d.show(); 1173 proc.anrDialog = d; 1174 } else { 1175 // Just kill the app if there is no dialog to be shown. 1176 killAppAtUsersRequest(proc, null); 1177 } 1178 } 1179 1180 ensureBootCompleted(); 1181 } break; 1182 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1183 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1184 synchronized (ActivityManagerService.this) { 1185 ProcessRecord proc = (ProcessRecord) data.get("app"); 1186 if (proc == null) { 1187 Slog.e(TAG, "App not found when showing strict mode dialog."); 1188 break; 1189 } 1190 if (proc.crashDialog != null) { 1191 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1192 return; 1193 } 1194 AppErrorResult res = (AppErrorResult) data.get("result"); 1195 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1196 Dialog d = new StrictModeViolationDialog(mContext, 1197 ActivityManagerService.this, res, proc); 1198 d.show(); 1199 proc.crashDialog = d; 1200 } else { 1201 // The device is asleep, so just pretend that the user 1202 // saw a crash dialog and hit "force quit". 1203 res.set(0); 1204 } 1205 } 1206 ensureBootCompleted(); 1207 } break; 1208 case SHOW_FACTORY_ERROR_MSG: { 1209 Dialog d = new FactoryErrorDialog( 1210 mContext, msg.getData().getCharSequence("msg")); 1211 d.show(); 1212 ensureBootCompleted(); 1213 } break; 1214 case UPDATE_CONFIGURATION_MSG: { 1215 final ContentResolver resolver = mContext.getContentResolver(); 1216 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1217 } break; 1218 case GC_BACKGROUND_PROCESSES_MSG: { 1219 synchronized (ActivityManagerService.this) { 1220 performAppGcsIfAppropriateLocked(); 1221 } 1222 } break; 1223 case WAIT_FOR_DEBUGGER_MSG: { 1224 synchronized (ActivityManagerService.this) { 1225 ProcessRecord app = (ProcessRecord)msg.obj; 1226 if (msg.arg1 != 0) { 1227 if (!app.waitedForDebugger) { 1228 Dialog d = new AppWaitingForDebuggerDialog( 1229 ActivityManagerService.this, 1230 mContext, app); 1231 app.waitDialog = d; 1232 app.waitedForDebugger = true; 1233 d.show(); 1234 } 1235 } else { 1236 if (app.waitDialog != null) { 1237 app.waitDialog.dismiss(); 1238 app.waitDialog = null; 1239 } 1240 } 1241 } 1242 } break; 1243 case SERVICE_TIMEOUT_MSG: { 1244 if (mDidDexOpt) { 1245 mDidDexOpt = false; 1246 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1247 nmsg.obj = msg.obj; 1248 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1249 return; 1250 } 1251 mServices.serviceTimeout((ProcessRecord)msg.obj); 1252 } break; 1253 case UPDATE_TIME_ZONE: { 1254 synchronized (ActivityManagerService.this) { 1255 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1256 ProcessRecord r = mLruProcesses.get(i); 1257 if (r.thread != null) { 1258 try { 1259 r.thread.updateTimeZone(); 1260 } catch (RemoteException ex) { 1261 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1262 } 1263 } 1264 } 1265 } 1266 } break; 1267 case CLEAR_DNS_CACHE_MSG: { 1268 synchronized (ActivityManagerService.this) { 1269 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1270 ProcessRecord r = mLruProcesses.get(i); 1271 if (r.thread != null) { 1272 try { 1273 r.thread.clearDnsCache(); 1274 } catch (RemoteException ex) { 1275 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1276 } 1277 } 1278 } 1279 } 1280 } break; 1281 case UPDATE_HTTP_PROXY_MSG: { 1282 ProxyProperties proxy = (ProxyProperties)msg.obj; 1283 String host = ""; 1284 String port = ""; 1285 String exclList = ""; 1286 String pacFileUrl = null; 1287 if (proxy != null) { 1288 host = proxy.getHost(); 1289 port = Integer.toString(proxy.getPort()); 1290 exclList = proxy.getExclusionList(); 1291 pacFileUrl = proxy.getPacFileUrl(); 1292 } 1293 synchronized (ActivityManagerService.this) { 1294 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1295 ProcessRecord r = mLruProcesses.get(i); 1296 if (r.thread != null) { 1297 try { 1298 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1299 } catch (RemoteException ex) { 1300 Slog.w(TAG, "Failed to update http proxy for: " + 1301 r.info.processName); 1302 } 1303 } 1304 } 1305 } 1306 } break; 1307 case SHOW_UID_ERROR_MSG: { 1308 String title = "System UIDs Inconsistent"; 1309 String text = "UIDs on the system are inconsistent, you need to wipe your" 1310 + " data partition or your device will be unstable."; 1311 Log.e(TAG, title + ": " + text); 1312 if (mShowDialogs) { 1313 // XXX This is a temporary dialog, no need to localize. 1314 AlertDialog d = new BaseErrorDialog(mContext); 1315 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1316 d.setCancelable(false); 1317 d.setTitle(title); 1318 d.setMessage(text); 1319 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1320 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1321 mUidAlert = d; 1322 d.show(); 1323 } 1324 } break; 1325 case IM_FEELING_LUCKY_MSG: { 1326 if (mUidAlert != null) { 1327 mUidAlert.dismiss(); 1328 mUidAlert = null; 1329 } 1330 } break; 1331 case PROC_START_TIMEOUT_MSG: { 1332 if (mDidDexOpt) { 1333 mDidDexOpt = false; 1334 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1335 nmsg.obj = msg.obj; 1336 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1337 return; 1338 } 1339 ProcessRecord app = (ProcessRecord)msg.obj; 1340 synchronized (ActivityManagerService.this) { 1341 processStartTimedOutLocked(app); 1342 } 1343 } break; 1344 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1345 synchronized (ActivityManagerService.this) { 1346 doPendingActivityLaunchesLocked(true); 1347 } 1348 } break; 1349 case KILL_APPLICATION_MSG: { 1350 synchronized (ActivityManagerService.this) { 1351 int appid = msg.arg1; 1352 boolean restart = (msg.arg2 == 1); 1353 Bundle bundle = (Bundle)msg.obj; 1354 String pkg = bundle.getString("pkg"); 1355 String reason = bundle.getString("reason"); 1356 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1357 false, UserHandle.USER_ALL, reason); 1358 } 1359 } break; 1360 case FINALIZE_PENDING_INTENT_MSG: { 1361 ((PendingIntentRecord)msg.obj).completeFinalize(); 1362 } break; 1363 case POST_HEAVY_NOTIFICATION_MSG: { 1364 INotificationManager inm = NotificationManager.getService(); 1365 if (inm == null) { 1366 return; 1367 } 1368 1369 ActivityRecord root = (ActivityRecord)msg.obj; 1370 ProcessRecord process = root.app; 1371 if (process == null) { 1372 return; 1373 } 1374 1375 try { 1376 Context context = mContext.createPackageContext(process.info.packageName, 0); 1377 String text = mContext.getString(R.string.heavy_weight_notification, 1378 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1379 Notification notification = new Notification(); 1380 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1381 notification.when = 0; 1382 notification.flags = Notification.FLAG_ONGOING_EVENT; 1383 notification.tickerText = text; 1384 notification.defaults = 0; // please be quiet 1385 notification.sound = null; 1386 notification.vibrate = null; 1387 notification.setLatestEventInfo(context, text, 1388 mContext.getText(R.string.heavy_weight_notification_detail), 1389 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1390 PendingIntent.FLAG_CANCEL_CURRENT, null, 1391 new UserHandle(root.userId))); 1392 1393 try { 1394 int[] outId = new int[1]; 1395 inm.enqueueNotificationWithTag("android", "android", null, 1396 R.string.heavy_weight_notification, 1397 notification, outId, root.userId); 1398 } catch (RuntimeException e) { 1399 Slog.w(ActivityManagerService.TAG, 1400 "Error showing notification for heavy-weight app", e); 1401 } catch (RemoteException e) { 1402 } 1403 } catch (NameNotFoundException e) { 1404 Slog.w(TAG, "Unable to create context for heavy notification", e); 1405 } 1406 } break; 1407 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1408 INotificationManager inm = NotificationManager.getService(); 1409 if (inm == null) { 1410 return; 1411 } 1412 try { 1413 inm.cancelNotificationWithTag("android", null, 1414 R.string.heavy_weight_notification, msg.arg1); 1415 } catch (RuntimeException e) { 1416 Slog.w(ActivityManagerService.TAG, 1417 "Error canceling notification for service", e); 1418 } catch (RemoteException e) { 1419 } 1420 } break; 1421 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1422 synchronized (ActivityManagerService.this) { 1423 checkExcessivePowerUsageLocked(true); 1424 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1425 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1426 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1427 } 1428 } break; 1429 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1430 synchronized (ActivityManagerService.this) { 1431 ActivityRecord ar = (ActivityRecord)msg.obj; 1432 if (mCompatModeDialog != null) { 1433 if (mCompatModeDialog.mAppInfo.packageName.equals( 1434 ar.info.applicationInfo.packageName)) { 1435 return; 1436 } 1437 mCompatModeDialog.dismiss(); 1438 mCompatModeDialog = null; 1439 } 1440 if (ar != null && false) { 1441 if (mCompatModePackages.getPackageAskCompatModeLocked( 1442 ar.packageName)) { 1443 int mode = mCompatModePackages.computeCompatModeLocked( 1444 ar.info.applicationInfo); 1445 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1446 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1447 mCompatModeDialog = new CompatModeDialog( 1448 ActivityManagerService.this, mContext, 1449 ar.info.applicationInfo); 1450 mCompatModeDialog.show(); 1451 } 1452 } 1453 } 1454 } 1455 break; 1456 } 1457 case DISPATCH_PROCESSES_CHANGED: { 1458 dispatchProcessesChanged(); 1459 break; 1460 } 1461 case DISPATCH_PROCESS_DIED: { 1462 final int pid = msg.arg1; 1463 final int uid = msg.arg2; 1464 dispatchProcessDied(pid, uid); 1465 break; 1466 } 1467 case REPORT_MEM_USAGE_MSG: { 1468 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1469 Thread thread = new Thread() { 1470 @Override public void run() { 1471 final SparseArray<ProcessMemInfo> infoMap 1472 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1473 for (int i=0, N=memInfos.size(); i<N; i++) { 1474 ProcessMemInfo mi = memInfos.get(i); 1475 infoMap.put(mi.pid, mi); 1476 } 1477 updateCpuStatsNow(); 1478 synchronized (mProcessCpuThread) { 1479 final int N = mProcessCpuTracker.countStats(); 1480 for (int i=0; i<N; i++) { 1481 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1482 if (st.vsize > 0) { 1483 long pss = Debug.getPss(st.pid, null); 1484 if (pss > 0) { 1485 if (infoMap.indexOfKey(st.pid) < 0) { 1486 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1487 ProcessList.NATIVE_ADJ, -1, "native", null); 1488 mi.pss = pss; 1489 memInfos.add(mi); 1490 } 1491 } 1492 } 1493 } 1494 } 1495 1496 long totalPss = 0; 1497 for (int i=0, N=memInfos.size(); i<N; i++) { 1498 ProcessMemInfo mi = memInfos.get(i); 1499 if (mi.pss == 0) { 1500 mi.pss = Debug.getPss(mi.pid, null); 1501 } 1502 totalPss += mi.pss; 1503 } 1504 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1505 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1506 if (lhs.oomAdj != rhs.oomAdj) { 1507 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1508 } 1509 if (lhs.pss != rhs.pss) { 1510 return lhs.pss < rhs.pss ? 1 : -1; 1511 } 1512 return 0; 1513 } 1514 }); 1515 1516 StringBuilder tag = new StringBuilder(128); 1517 StringBuilder stack = new StringBuilder(128); 1518 tag.append("Low on memory -- "); 1519 appendMemBucket(tag, totalPss, "total", false); 1520 appendMemBucket(stack, totalPss, "total", true); 1521 1522 StringBuilder logBuilder = new StringBuilder(1024); 1523 logBuilder.append("Low on memory:\n"); 1524 1525 boolean firstLine = true; 1526 int lastOomAdj = Integer.MIN_VALUE; 1527 for (int i=0, N=memInfos.size(); i<N; i++) { 1528 ProcessMemInfo mi = memInfos.get(i); 1529 1530 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1531 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1532 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1533 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1534 if (lastOomAdj != mi.oomAdj) { 1535 lastOomAdj = mi.oomAdj; 1536 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1537 tag.append(" / "); 1538 } 1539 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1540 if (firstLine) { 1541 stack.append(":"); 1542 firstLine = false; 1543 } 1544 stack.append("\n\t at "); 1545 } else { 1546 stack.append("$"); 1547 } 1548 } else { 1549 tag.append(" "); 1550 stack.append("$"); 1551 } 1552 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1553 appendMemBucket(tag, mi.pss, mi.name, false); 1554 } 1555 appendMemBucket(stack, mi.pss, mi.name, true); 1556 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1557 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1558 stack.append("("); 1559 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1560 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1561 stack.append(DUMP_MEM_OOM_LABEL[k]); 1562 stack.append(":"); 1563 stack.append(DUMP_MEM_OOM_ADJ[k]); 1564 } 1565 } 1566 stack.append(")"); 1567 } 1568 } 1569 1570 logBuilder.append(" "); 1571 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1572 logBuilder.append(' '); 1573 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1574 logBuilder.append(' '); 1575 ProcessList.appendRamKb(logBuilder, mi.pss); 1576 logBuilder.append(" kB: "); 1577 logBuilder.append(mi.name); 1578 logBuilder.append(" ("); 1579 logBuilder.append(mi.pid); 1580 logBuilder.append(") "); 1581 logBuilder.append(mi.adjType); 1582 logBuilder.append('\n'); 1583 if (mi.adjReason != null) { 1584 logBuilder.append(" "); 1585 logBuilder.append(mi.adjReason); 1586 logBuilder.append('\n'); 1587 } 1588 } 1589 1590 logBuilder.append(" "); 1591 ProcessList.appendRamKb(logBuilder, totalPss); 1592 logBuilder.append(" kB: TOTAL\n"); 1593 1594 long[] infos = new long[Debug.MEMINFO_COUNT]; 1595 Debug.getMemInfo(infos); 1596 logBuilder.append(" MemInfo: "); 1597 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1598 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1599 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1600 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1601 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1602 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1603 logBuilder.append(" ZRAM: "); 1604 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1605 logBuilder.append(" kB RAM, "); 1606 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1607 logBuilder.append(" kB swap total, "); 1608 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1609 logBuilder.append(" kB swap free\n"); 1610 } 1611 Slog.i(TAG, logBuilder.toString()); 1612 1613 StringBuilder dropBuilder = new StringBuilder(1024); 1614 /* 1615 StringWriter oomSw = new StringWriter(); 1616 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1617 StringWriter catSw = new StringWriter(); 1618 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1619 String[] emptyArgs = new String[] { }; 1620 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1621 oomPw.flush(); 1622 String oomString = oomSw.toString(); 1623 */ 1624 dropBuilder.append(stack); 1625 dropBuilder.append('\n'); 1626 dropBuilder.append('\n'); 1627 dropBuilder.append(logBuilder); 1628 dropBuilder.append('\n'); 1629 /* 1630 dropBuilder.append(oomString); 1631 dropBuilder.append('\n'); 1632 */ 1633 StringWriter catSw = new StringWriter(); 1634 synchronized (ActivityManagerService.this) { 1635 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1636 String[] emptyArgs = new String[] { }; 1637 catPw.println(); 1638 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1639 catPw.println(); 1640 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1641 false, false, null); 1642 catPw.println(); 1643 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1644 catPw.flush(); 1645 } 1646 dropBuilder.append(catSw.toString()); 1647 addErrorToDropBox("lowmem", null, "system_server", null, 1648 null, tag.toString(), dropBuilder.toString(), null, null); 1649 //Slog.i(TAG, "Sent to dropbox:"); 1650 //Slog.i(TAG, dropBuilder.toString()); 1651 synchronized (ActivityManagerService.this) { 1652 long now = SystemClock.uptimeMillis(); 1653 if (mLastMemUsageReportTime < now) { 1654 mLastMemUsageReportTime = now; 1655 } 1656 } 1657 } 1658 }; 1659 thread.start(); 1660 break; 1661 } 1662 case REPORT_USER_SWITCH_MSG: { 1663 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1664 break; 1665 } 1666 case CONTINUE_USER_SWITCH_MSG: { 1667 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1668 break; 1669 } 1670 case USER_SWITCH_TIMEOUT_MSG: { 1671 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1672 break; 1673 } 1674 case IMMERSIVE_MODE_LOCK_MSG: { 1675 final boolean nextState = (msg.arg1 != 0); 1676 if (mUpdateLock.isHeld() != nextState) { 1677 if (DEBUG_IMMERSIVE) { 1678 final ActivityRecord r = (ActivityRecord) msg.obj; 1679 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1680 } 1681 if (nextState) { 1682 mUpdateLock.acquire(); 1683 } else { 1684 mUpdateLock.release(); 1685 } 1686 } 1687 break; 1688 } 1689 case PERSIST_URI_GRANTS_MSG: { 1690 writeGrantedUriPermissions(); 1691 break; 1692 } 1693 case REQUEST_ALL_PSS_MSG: { 1694 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1695 break; 1696 } 1697 case START_PROFILES_MSG: { 1698 synchronized (ActivityManagerService.this) { 1699 startProfilesLocked(); 1700 } 1701 break; 1702 } 1703 case UPDATE_TIME: { 1704 synchronized (ActivityManagerService.this) { 1705 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1706 ProcessRecord r = mLruProcesses.get(i); 1707 if (r.thread != null) { 1708 try { 1709 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1710 } catch (RemoteException ex) { 1711 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1712 } 1713 } 1714 } 1715 } 1716 break; 1717 } 1718 } 1719 } 1720 }; 1721 1722 static final int COLLECT_PSS_BG_MSG = 1; 1723 1724 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1725 @Override 1726 public void handleMessage(Message msg) { 1727 switch (msg.what) { 1728 case COLLECT_PSS_BG_MSG: { 1729 int i=0, num=0; 1730 long start = SystemClock.uptimeMillis(); 1731 long[] tmp = new long[1]; 1732 do { 1733 ProcessRecord proc; 1734 int procState; 1735 int pid; 1736 synchronized (ActivityManagerService.this) { 1737 if (i >= mPendingPssProcesses.size()) { 1738 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1739 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1740 mPendingPssProcesses.clear(); 1741 return; 1742 } 1743 proc = mPendingPssProcesses.get(i); 1744 procState = proc.pssProcState; 1745 if (proc.thread != null && procState == proc.setProcState) { 1746 pid = proc.pid; 1747 } else { 1748 proc = null; 1749 pid = 0; 1750 } 1751 i++; 1752 } 1753 if (proc != null) { 1754 long pss = Debug.getPss(pid, tmp); 1755 synchronized (ActivityManagerService.this) { 1756 if (proc.thread != null && proc.setProcState == procState 1757 && proc.pid == pid) { 1758 num++; 1759 proc.lastPssTime = SystemClock.uptimeMillis(); 1760 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1761 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1762 + ": " + pss + " lastPss=" + proc.lastPss 1763 + " state=" + ProcessList.makeProcStateString(procState)); 1764 if (proc.initialIdlePss == 0) { 1765 proc.initialIdlePss = pss; 1766 } 1767 proc.lastPss = pss; 1768 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1769 proc.lastCachedPss = pss; 1770 } 1771 } 1772 } 1773 } 1774 } while (true); 1775 } 1776 } 1777 } 1778 }; 1779 1780 public void setSystemProcess() { 1781 try { 1782 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1783 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1784 ServiceManager.addService("meminfo", new MemBinder(this)); 1785 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1786 ServiceManager.addService("dbinfo", new DbBinder(this)); 1787 if (MONITOR_CPU_USAGE) { 1788 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1789 } 1790 ServiceManager.addService("permission", new PermissionController(this)); 1791 1792 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1793 "android", STOCK_PM_FLAGS); 1794 mSystemThread.installSystemApplicationInfo(info); 1795 1796 synchronized (this) { 1797 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1798 app.persistent = true; 1799 app.pid = MY_PID; 1800 app.maxAdj = ProcessList.SYSTEM_ADJ; 1801 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1802 mProcessNames.put(app.processName, app.uid, app); 1803 synchronized (mPidsSelfLocked) { 1804 mPidsSelfLocked.put(app.pid, app); 1805 } 1806 updateLruProcessLocked(app, false, null); 1807 updateOomAdjLocked(); 1808 } 1809 } catch (PackageManager.NameNotFoundException e) { 1810 throw new RuntimeException( 1811 "Unable to find android system package", e); 1812 } 1813 } 1814 1815 public void setWindowManager(WindowManagerService wm) { 1816 mWindowManager = wm; 1817 mStackSupervisor.setWindowManager(wm); 1818 } 1819 1820 public void startObservingNativeCrashes() { 1821 final NativeCrashListener ncl = new NativeCrashListener(this); 1822 ncl.start(); 1823 } 1824 1825 public IAppOpsService getAppOpsService() { 1826 return mAppOpsService; 1827 } 1828 1829 static class MemBinder extends Binder { 1830 ActivityManagerService mActivityManagerService; 1831 MemBinder(ActivityManagerService activityManagerService) { 1832 mActivityManagerService = activityManagerService; 1833 } 1834 1835 @Override 1836 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1837 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1838 != PackageManager.PERMISSION_GRANTED) { 1839 pw.println("Permission Denial: can't dump meminfo from from pid=" 1840 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1841 + " without permission " + android.Manifest.permission.DUMP); 1842 return; 1843 } 1844 1845 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1846 } 1847 } 1848 1849 static class GraphicsBinder extends Binder { 1850 ActivityManagerService mActivityManagerService; 1851 GraphicsBinder(ActivityManagerService activityManagerService) { 1852 mActivityManagerService = activityManagerService; 1853 } 1854 1855 @Override 1856 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1857 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1858 != PackageManager.PERMISSION_GRANTED) { 1859 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1860 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1861 + " without permission " + android.Manifest.permission.DUMP); 1862 return; 1863 } 1864 1865 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1866 } 1867 } 1868 1869 static class DbBinder extends Binder { 1870 ActivityManagerService mActivityManagerService; 1871 DbBinder(ActivityManagerService activityManagerService) { 1872 mActivityManagerService = activityManagerService; 1873 } 1874 1875 @Override 1876 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1877 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1878 != PackageManager.PERMISSION_GRANTED) { 1879 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1880 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1881 + " without permission " + android.Manifest.permission.DUMP); 1882 return; 1883 } 1884 1885 mActivityManagerService.dumpDbInfo(fd, pw, args); 1886 } 1887 } 1888 1889 static class CpuBinder extends Binder { 1890 ActivityManagerService mActivityManagerService; 1891 CpuBinder(ActivityManagerService activityManagerService) { 1892 mActivityManagerService = activityManagerService; 1893 } 1894 1895 @Override 1896 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1897 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1898 != PackageManager.PERMISSION_GRANTED) { 1899 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1900 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1901 + " without permission " + android.Manifest.permission.DUMP); 1902 return; 1903 } 1904 1905 synchronized (mActivityManagerService.mProcessCpuThread) { 1906 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1907 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1908 SystemClock.uptimeMillis())); 1909 } 1910 } 1911 } 1912 1913 public static final class Lifecycle extends SystemService { 1914 private final ActivityManagerService mService; 1915 1916 public Lifecycle(Context context) { 1917 super(context); 1918 mService = new ActivityManagerService(context); 1919 } 1920 1921 @Override 1922 public void onStart() { 1923 mService.start(); 1924 } 1925 1926 public ActivityManagerService getService() { 1927 return mService; 1928 } 1929 } 1930 1931 // Note: This method is invoked on the main thread but may need to attach various 1932 // handlers to other threads. So take care to be explicit about the looper. 1933 public ActivityManagerService(Context systemContext) { 1934 mContext = systemContext; 1935 mFactoryTest = FactoryTest.getMode(); 1936 mSystemThread = ActivityThread.currentActivityThread(); 1937 1938 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1939 1940 mHandlerThread = new ServiceThread(TAG, 1941 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1942 mHandlerThread.start(); 1943 mHandler = new MainHandler(mHandlerThread.getLooper()); 1944 1945 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1946 "foreground", BROADCAST_FG_TIMEOUT, false); 1947 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1948 "background", BROADCAST_BG_TIMEOUT, true); 1949 mBroadcastQueues[0] = mFgBroadcastQueue; 1950 mBroadcastQueues[1] = mBgBroadcastQueue; 1951 1952 mServices = new ActiveServices(this); 1953 mProviderMap = new ProviderMap(this); 1954 1955 // TODO: Move creation of battery stats service outside of activity manager service. 1956 File dataDir = Environment.getDataDirectory(); 1957 File systemDir = new File(dataDir, "system"); 1958 systemDir.mkdirs(); 1959 mBatteryStatsService = new BatteryStatsService(new File( 1960 systemDir, "batterystats.bin").toString(), mHandler); 1961 mBatteryStatsService.getActiveStatistics().readLocked(); 1962 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1963 mOnBattery = DEBUG_POWER ? true 1964 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1965 mBatteryStatsService.getActiveStatistics().setCallback(this); 1966 1967 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1968 1969 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1970 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1971 1972 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1973 1974 // User 0 is the first and only user that runs at boot. 1975 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1976 mUserLru.add(Integer.valueOf(0)); 1977 updateStartedUserArrayLocked(); 1978 1979 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1980 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1981 1982 mConfiguration.setToDefaults(); 1983 mConfiguration.setLocale(Locale.getDefault()); 1984 1985 mConfigurationSeq = mConfiguration.seq = 1; 1986 mProcessCpuTracker.init(); 1987 1988 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1989 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1990 mStackSupervisor = new ActivityStackSupervisor(this); 1991 1992 mProcessCpuThread = new Thread("CpuTracker") { 1993 @Override 1994 public void run() { 1995 while (true) { 1996 try { 1997 try { 1998 synchronized(this) { 1999 final long now = SystemClock.uptimeMillis(); 2000 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2001 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2002 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2003 // + ", write delay=" + nextWriteDelay); 2004 if (nextWriteDelay < nextCpuDelay) { 2005 nextCpuDelay = nextWriteDelay; 2006 } 2007 if (nextCpuDelay > 0) { 2008 mProcessCpuMutexFree.set(true); 2009 this.wait(nextCpuDelay); 2010 } 2011 } 2012 } catch (InterruptedException e) { 2013 } 2014 updateCpuStatsNow(); 2015 } catch (Exception e) { 2016 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2017 } 2018 } 2019 } 2020 }; 2021 2022 Watchdog.getInstance().addMonitor(this); 2023 Watchdog.getInstance().addThread(mHandler); 2024 } 2025 2026 private void start() { 2027 mProcessCpuThread.start(); 2028 2029 mBatteryStatsService.publish(mContext); 2030 mUsageStatsService.publish(mContext); 2031 mAppOpsService.publish(mContext); 2032 startRunning(null, null, null, null); 2033 } 2034 2035 @Override 2036 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2037 throws RemoteException { 2038 if (code == SYSPROPS_TRANSACTION) { 2039 // We need to tell all apps about the system property change. 2040 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2041 synchronized(this) { 2042 final int NP = mProcessNames.getMap().size(); 2043 for (int ip=0; ip<NP; ip++) { 2044 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2045 final int NA = apps.size(); 2046 for (int ia=0; ia<NA; ia++) { 2047 ProcessRecord app = apps.valueAt(ia); 2048 if (app.thread != null) { 2049 procs.add(app.thread.asBinder()); 2050 } 2051 } 2052 } 2053 } 2054 2055 int N = procs.size(); 2056 for (int i=0; i<N; i++) { 2057 Parcel data2 = Parcel.obtain(); 2058 try { 2059 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2060 } catch (RemoteException e) { 2061 } 2062 data2.recycle(); 2063 } 2064 } 2065 try { 2066 return super.onTransact(code, data, reply, flags); 2067 } catch (RuntimeException e) { 2068 // The activity manager only throws security exceptions, so let's 2069 // log all others. 2070 if (!(e instanceof SecurityException)) { 2071 Slog.wtf(TAG, "Activity Manager Crash", e); 2072 } 2073 throw e; 2074 } 2075 } 2076 2077 void updateCpuStats() { 2078 final long now = SystemClock.uptimeMillis(); 2079 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2080 return; 2081 } 2082 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2083 synchronized (mProcessCpuThread) { 2084 mProcessCpuThread.notify(); 2085 } 2086 } 2087 } 2088 2089 void updateCpuStatsNow() { 2090 synchronized (mProcessCpuThread) { 2091 mProcessCpuMutexFree.set(false); 2092 final long now = SystemClock.uptimeMillis(); 2093 boolean haveNewCpuStats = false; 2094 2095 if (MONITOR_CPU_USAGE && 2096 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2097 mLastCpuTime.set(now); 2098 haveNewCpuStats = true; 2099 mProcessCpuTracker.update(); 2100 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2101 //Slog.i(TAG, "Total CPU usage: " 2102 // + mProcessCpu.getTotalCpuPercent() + "%"); 2103 2104 // Slog the cpu usage if the property is set. 2105 if ("true".equals(SystemProperties.get("events.cpu"))) { 2106 int user = mProcessCpuTracker.getLastUserTime(); 2107 int system = mProcessCpuTracker.getLastSystemTime(); 2108 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2109 int irq = mProcessCpuTracker.getLastIrqTime(); 2110 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2111 int idle = mProcessCpuTracker.getLastIdleTime(); 2112 2113 int total = user + system + iowait + irq + softIrq + idle; 2114 if (total == 0) total = 1; 2115 2116 EventLog.writeEvent(EventLogTags.CPU, 2117 ((user+system+iowait+irq+softIrq) * 100) / total, 2118 (user * 100) / total, 2119 (system * 100) / total, 2120 (iowait * 100) / total, 2121 (irq * 100) / total, 2122 (softIrq * 100) / total); 2123 } 2124 } 2125 2126 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2127 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2128 synchronized(bstats) { 2129 synchronized(mPidsSelfLocked) { 2130 if (haveNewCpuStats) { 2131 if (mOnBattery) { 2132 int perc = bstats.startAddingCpuLocked(); 2133 int totalUTime = 0; 2134 int totalSTime = 0; 2135 final int N = mProcessCpuTracker.countStats(); 2136 for (int i=0; i<N; i++) { 2137 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2138 if (!st.working) { 2139 continue; 2140 } 2141 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2142 int otherUTime = (st.rel_utime*perc)/100; 2143 int otherSTime = (st.rel_stime*perc)/100; 2144 totalUTime += otherUTime; 2145 totalSTime += otherSTime; 2146 if (pr != null) { 2147 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2148 if (ps == null || !ps.isActive()) { 2149 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2150 pr.info.uid, pr.processName); 2151 } 2152 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2153 st.rel_stime-otherSTime); 2154 ps.addSpeedStepTimes(cpuSpeedTimes); 2155 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2156 } else { 2157 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2158 if (ps == null || !ps.isActive()) { 2159 st.batteryStats = ps = bstats.getProcessStatsLocked( 2160 bstats.mapUid(st.uid), st.name); 2161 } 2162 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2163 st.rel_stime-otherSTime); 2164 ps.addSpeedStepTimes(cpuSpeedTimes); 2165 } 2166 } 2167 bstats.finishAddingCpuLocked(perc, totalUTime, 2168 totalSTime, cpuSpeedTimes); 2169 } 2170 } 2171 } 2172 2173 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2174 mLastWriteTime = now; 2175 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2176 } 2177 } 2178 } 2179 } 2180 2181 @Override 2182 public void batteryNeedsCpuUpdate() { 2183 updateCpuStatsNow(); 2184 } 2185 2186 @Override 2187 public void batteryPowerChanged(boolean onBattery) { 2188 // When plugging in, update the CPU stats first before changing 2189 // the plug state. 2190 updateCpuStatsNow(); 2191 synchronized (this) { 2192 synchronized(mPidsSelfLocked) { 2193 mOnBattery = DEBUG_POWER ? true : onBattery; 2194 } 2195 } 2196 } 2197 2198 /** 2199 * Initialize the application bind args. These are passed to each 2200 * process when the bindApplication() IPC is sent to the process. They're 2201 * lazily setup to make sure the services are running when they're asked for. 2202 */ 2203 private HashMap<String, IBinder> getCommonServicesLocked() { 2204 if (mAppBindArgs == null) { 2205 mAppBindArgs = new HashMap<String, IBinder>(); 2206 2207 // Setup the application init args 2208 mAppBindArgs.put("package", ServiceManager.getService("package")); 2209 mAppBindArgs.put("window", ServiceManager.getService("window")); 2210 mAppBindArgs.put(Context.ALARM_SERVICE, 2211 ServiceManager.getService(Context.ALARM_SERVICE)); 2212 } 2213 return mAppBindArgs; 2214 } 2215 2216 final void setFocusedActivityLocked(ActivityRecord r) { 2217 if (mFocusedActivity != r) { 2218 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2219 mFocusedActivity = r; 2220 mStackSupervisor.setFocusedStack(r); 2221 if (r != null) { 2222 mWindowManager.setFocusedApp(r.appToken, true); 2223 } 2224 applyUpdateLockStateLocked(r); 2225 } 2226 } 2227 2228 @Override 2229 public void setFocusedStack(int stackId) { 2230 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2231 synchronized (ActivityManagerService.this) { 2232 ActivityStack stack = mStackSupervisor.getStack(stackId); 2233 if (stack != null) { 2234 ActivityRecord r = stack.topRunningActivityLocked(null); 2235 if (r != null) { 2236 setFocusedActivityLocked(r); 2237 } 2238 } 2239 } 2240 } 2241 2242 @Override 2243 public void notifyActivityDrawn(IBinder token) { 2244 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2245 synchronized (this) { 2246 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2247 if (r != null) { 2248 r.task.stack.notifyActivityDrawnLocked(r); 2249 } 2250 } 2251 } 2252 2253 final void applyUpdateLockStateLocked(ActivityRecord r) { 2254 // Modifications to the UpdateLock state are done on our handler, outside 2255 // the activity manager's locks. The new state is determined based on the 2256 // state *now* of the relevant activity record. The object is passed to 2257 // the handler solely for logging detail, not to be consulted/modified. 2258 final boolean nextState = r != null && r.immersive; 2259 mHandler.sendMessage( 2260 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2261 } 2262 2263 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2264 Message msg = Message.obtain(); 2265 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2266 msg.obj = r.task.askedCompatMode ? null : r; 2267 mHandler.sendMessage(msg); 2268 } 2269 2270 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2271 String what, Object obj, ProcessRecord srcApp) { 2272 app.lastActivityTime = now; 2273 2274 if (app.activities.size() > 0) { 2275 // Don't want to touch dependent processes that are hosting activities. 2276 return index; 2277 } 2278 2279 int lrui = mLruProcesses.lastIndexOf(app); 2280 if (lrui < 0) { 2281 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2282 + what + " " + obj + " from " + srcApp); 2283 return index; 2284 } 2285 2286 if (lrui >= index) { 2287 // Don't want to cause this to move dependent processes *back* in the 2288 // list as if they were less frequently used. 2289 return index; 2290 } 2291 2292 if (lrui >= mLruProcessActivityStart) { 2293 // Don't want to touch dependent processes that are hosting activities. 2294 return index; 2295 } 2296 2297 mLruProcesses.remove(lrui); 2298 if (index > 0) { 2299 index--; 2300 } 2301 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2302 + " in LRU list: " + app); 2303 mLruProcesses.add(index, app); 2304 return index; 2305 } 2306 2307 final void removeLruProcessLocked(ProcessRecord app) { 2308 int lrui = mLruProcesses.lastIndexOf(app); 2309 if (lrui >= 0) { 2310 if (lrui <= mLruProcessActivityStart) { 2311 mLruProcessActivityStart--; 2312 } 2313 if (lrui <= mLruProcessServiceStart) { 2314 mLruProcessServiceStart--; 2315 } 2316 mLruProcesses.remove(lrui); 2317 } 2318 } 2319 2320 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2321 ProcessRecord client) { 2322 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2323 || app.treatLikeActivity; 2324 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2325 if (!activityChange && hasActivity) { 2326 // The process has activities, so we are only allowing activity-based adjustments 2327 // to move it. It should be kept in the front of the list with other 2328 // processes that have activities, and we don't want those to change their 2329 // order except due to activity operations. 2330 return; 2331 } 2332 2333 mLruSeq++; 2334 final long now = SystemClock.uptimeMillis(); 2335 app.lastActivityTime = now; 2336 2337 // First a quick reject: if the app is already at the position we will 2338 // put it, then there is nothing to do. 2339 if (hasActivity) { 2340 final int N = mLruProcesses.size(); 2341 if (N > 0 && mLruProcesses.get(N-1) == app) { 2342 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2343 return; 2344 } 2345 } else { 2346 if (mLruProcessServiceStart > 0 2347 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2348 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2349 return; 2350 } 2351 } 2352 2353 int lrui = mLruProcesses.lastIndexOf(app); 2354 2355 if (app.persistent && lrui >= 0) { 2356 // We don't care about the position of persistent processes, as long as 2357 // they are in the list. 2358 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2359 return; 2360 } 2361 2362 /* In progress: compute new position first, so we can avoid doing work 2363 if the process is not actually going to move. Not yet working. 2364 int addIndex; 2365 int nextIndex; 2366 boolean inActivity = false, inService = false; 2367 if (hasActivity) { 2368 // Process has activities, put it at the very tipsy-top. 2369 addIndex = mLruProcesses.size(); 2370 nextIndex = mLruProcessServiceStart; 2371 inActivity = true; 2372 } else if (hasService) { 2373 // Process has services, put it at the top of the service list. 2374 addIndex = mLruProcessActivityStart; 2375 nextIndex = mLruProcessServiceStart; 2376 inActivity = true; 2377 inService = true; 2378 } else { 2379 // Process not otherwise of interest, it goes to the top of the non-service area. 2380 addIndex = mLruProcessServiceStart; 2381 if (client != null) { 2382 int clientIndex = mLruProcesses.lastIndexOf(client); 2383 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2384 + app); 2385 if (clientIndex >= 0 && addIndex > clientIndex) { 2386 addIndex = clientIndex; 2387 } 2388 } 2389 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2390 } 2391 2392 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2393 + mLruProcessActivityStart + "): " + app); 2394 */ 2395 2396 if (lrui >= 0) { 2397 if (lrui < mLruProcessActivityStart) { 2398 mLruProcessActivityStart--; 2399 } 2400 if (lrui < mLruProcessServiceStart) { 2401 mLruProcessServiceStart--; 2402 } 2403 /* 2404 if (addIndex > lrui) { 2405 addIndex--; 2406 } 2407 if (nextIndex > lrui) { 2408 nextIndex--; 2409 } 2410 */ 2411 mLruProcesses.remove(lrui); 2412 } 2413 2414 /* 2415 mLruProcesses.add(addIndex, app); 2416 if (inActivity) { 2417 mLruProcessActivityStart++; 2418 } 2419 if (inService) { 2420 mLruProcessActivityStart++; 2421 } 2422 */ 2423 2424 int nextIndex; 2425 if (hasActivity) { 2426 final int N = mLruProcesses.size(); 2427 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2428 // Process doesn't have activities, but has clients with 2429 // activities... move it up, but one below the top (the top 2430 // should always have a real activity). 2431 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2432 mLruProcesses.add(N-1, app); 2433 // To keep it from spamming the LRU list (by making a bunch of clients), 2434 // we will push down any other entries owned by the app. 2435 final int uid = app.info.uid; 2436 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2437 ProcessRecord subProc = mLruProcesses.get(i); 2438 if (subProc.info.uid == uid) { 2439 // We want to push this one down the list. If the process after 2440 // it is for the same uid, however, don't do so, because we don't 2441 // want them internally to be re-ordered. 2442 if (mLruProcesses.get(i-1).info.uid != uid) { 2443 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2444 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2445 ProcessRecord tmp = mLruProcesses.get(i); 2446 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2447 mLruProcesses.set(i-1, tmp); 2448 i--; 2449 } 2450 } else { 2451 // A gap, we can stop here. 2452 break; 2453 } 2454 } 2455 } else { 2456 // Process has activities, put it at the very tipsy-top. 2457 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2458 mLruProcesses.add(app); 2459 } 2460 nextIndex = mLruProcessServiceStart; 2461 } else if (hasService) { 2462 // Process has services, put it at the top of the service list. 2463 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2464 mLruProcesses.add(mLruProcessActivityStart, app); 2465 nextIndex = mLruProcessServiceStart; 2466 mLruProcessActivityStart++; 2467 } else { 2468 // Process not otherwise of interest, it goes to the top of the non-service area. 2469 int index = mLruProcessServiceStart; 2470 if (client != null) { 2471 // If there is a client, don't allow the process to be moved up higher 2472 // in the list than that client. 2473 int clientIndex = mLruProcesses.lastIndexOf(client); 2474 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2475 + " when updating " + app); 2476 if (clientIndex <= lrui) { 2477 // Don't allow the client index restriction to push it down farther in the 2478 // list than it already is. 2479 clientIndex = lrui; 2480 } 2481 if (clientIndex >= 0 && index > clientIndex) { 2482 index = clientIndex; 2483 } 2484 } 2485 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2486 mLruProcesses.add(index, app); 2487 nextIndex = index-1; 2488 mLruProcessActivityStart++; 2489 mLruProcessServiceStart++; 2490 } 2491 2492 // If the app is currently using a content provider or service, 2493 // bump those processes as well. 2494 for (int j=app.connections.size()-1; j>=0; j--) { 2495 ConnectionRecord cr = app.connections.valueAt(j); 2496 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2497 && cr.binding.service.app != null 2498 && cr.binding.service.app.lruSeq != mLruSeq 2499 && !cr.binding.service.app.persistent) { 2500 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2501 "service connection", cr, app); 2502 } 2503 } 2504 for (int j=app.conProviders.size()-1; j>=0; j--) { 2505 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2506 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2507 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2508 "provider reference", cpr, app); 2509 } 2510 } 2511 } 2512 2513 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2514 if (uid == Process.SYSTEM_UID) { 2515 // The system gets to run in any process. If there are multiple 2516 // processes with the same uid, just pick the first (this 2517 // should never happen). 2518 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2519 if (procs == null) return null; 2520 final int N = procs.size(); 2521 for (int i = 0; i < N; i++) { 2522 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2523 } 2524 } 2525 ProcessRecord proc = mProcessNames.get(processName, uid); 2526 if (false && proc != null && !keepIfLarge 2527 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2528 && proc.lastCachedPss >= 4000) { 2529 // Turn this condition on to cause killing to happen regularly, for testing. 2530 if (proc.baseProcessTracker != null) { 2531 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2532 } 2533 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2534 + "k from cached"); 2535 } else if (proc != null && !keepIfLarge 2536 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2537 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2538 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2539 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2540 if (proc.baseProcessTracker != null) { 2541 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2542 } 2543 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2544 + "k from cached"); 2545 } 2546 } 2547 return proc; 2548 } 2549 2550 void ensurePackageDexOpt(String packageName) { 2551 IPackageManager pm = AppGlobals.getPackageManager(); 2552 try { 2553 if (pm.performDexOpt(packageName)) { 2554 mDidDexOpt = true; 2555 } 2556 } catch (RemoteException e) { 2557 } 2558 } 2559 2560 boolean isNextTransitionForward() { 2561 int transit = mWindowManager.getPendingAppTransition(); 2562 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2563 || transit == AppTransition.TRANSIT_TASK_OPEN 2564 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2565 } 2566 2567 final ProcessRecord startProcessLocked(String processName, 2568 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2569 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2570 boolean isolated, boolean keepIfLarge) { 2571 ProcessRecord app; 2572 if (!isolated) { 2573 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2574 } else { 2575 // If this is an isolated process, it can't re-use an existing process. 2576 app = null; 2577 } 2578 // We don't have to do anything more if: 2579 // (1) There is an existing application record; and 2580 // (2) The caller doesn't think it is dead, OR there is no thread 2581 // object attached to it so we know it couldn't have crashed; and 2582 // (3) There is a pid assigned to it, so it is either starting or 2583 // already running. 2584 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2585 + " app=" + app + " knownToBeDead=" + knownToBeDead 2586 + " thread=" + (app != null ? app.thread : null) 2587 + " pid=" + (app != null ? app.pid : -1)); 2588 if (app != null && app.pid > 0) { 2589 if (!knownToBeDead || app.thread == null) { 2590 // We already have the app running, or are waiting for it to 2591 // come up (we have a pid but not yet its thread), so keep it. 2592 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2593 // If this is a new package in the process, add the package to the list 2594 app.addPackage(info.packageName, mProcessStats); 2595 return app; 2596 } 2597 2598 // An application record is attached to a previous process, 2599 // clean it up now. 2600 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2601 handleAppDiedLocked(app, true, true); 2602 } 2603 2604 String hostingNameStr = hostingName != null 2605 ? hostingName.flattenToShortString() : null; 2606 2607 if (!isolated) { 2608 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2609 // If we are in the background, then check to see if this process 2610 // is bad. If so, we will just silently fail. 2611 if (mBadProcesses.get(info.processName, info.uid) != null) { 2612 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2613 + "/" + info.processName); 2614 return null; 2615 } 2616 } else { 2617 // When the user is explicitly starting a process, then clear its 2618 // crash count so that we won't make it bad until they see at 2619 // least one crash dialog again, and make the process good again 2620 // if it had been bad. 2621 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2622 + "/" + info.processName); 2623 mProcessCrashTimes.remove(info.processName, info.uid); 2624 if (mBadProcesses.get(info.processName, info.uid) != null) { 2625 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2626 UserHandle.getUserId(info.uid), info.uid, 2627 info.processName); 2628 mBadProcesses.remove(info.processName, info.uid); 2629 if (app != null) { 2630 app.bad = false; 2631 } 2632 } 2633 } 2634 } 2635 2636 if (app == null) { 2637 app = newProcessRecordLocked(info, processName, isolated); 2638 if (app == null) { 2639 Slog.w(TAG, "Failed making new process record for " 2640 + processName + "/" + info.uid + " isolated=" + isolated); 2641 return null; 2642 } 2643 mProcessNames.put(processName, app.uid, app); 2644 if (isolated) { 2645 mIsolatedProcesses.put(app.uid, app); 2646 } 2647 } else { 2648 // If this is a new package in the process, add the package to the list 2649 app.addPackage(info.packageName, mProcessStats); 2650 } 2651 2652 // If the system is not ready yet, then hold off on starting this 2653 // process until it is. 2654 if (!mProcessesReady 2655 && !isAllowedWhileBooting(info) 2656 && !allowWhileBooting) { 2657 if (!mProcessesOnHold.contains(app)) { 2658 mProcessesOnHold.add(app); 2659 } 2660 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2661 return app; 2662 } 2663 2664 startProcessLocked(app, hostingType, hostingNameStr); 2665 return (app.pid != 0) ? app : null; 2666 } 2667 2668 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2669 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2670 } 2671 2672 private final void startProcessLocked(ProcessRecord app, 2673 String hostingType, String hostingNameStr) { 2674 if (app.pid > 0 && app.pid != MY_PID) { 2675 synchronized (mPidsSelfLocked) { 2676 mPidsSelfLocked.remove(app.pid); 2677 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2678 } 2679 app.setPid(0); 2680 } 2681 2682 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2683 "startProcessLocked removing on hold: " + app); 2684 mProcessesOnHold.remove(app); 2685 2686 updateCpuStats(); 2687 2688 try { 2689 int uid = app.uid; 2690 2691 int[] gids = null; 2692 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2693 if (!app.isolated) { 2694 int[] permGids = null; 2695 try { 2696 final PackageManager pm = mContext.getPackageManager(); 2697 permGids = pm.getPackageGids(app.info.packageName); 2698 2699 if (Environment.isExternalStorageEmulated()) { 2700 if (pm.checkPermission( 2701 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2702 app.info.packageName) == PERMISSION_GRANTED) { 2703 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2704 } else { 2705 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2706 } 2707 } 2708 } catch (PackageManager.NameNotFoundException e) { 2709 Slog.w(TAG, "Unable to retrieve gids", e); 2710 } 2711 2712 /* 2713 * Add shared application GID so applications can share some 2714 * resources like shared libraries 2715 */ 2716 if (permGids == null) { 2717 gids = new int[1]; 2718 } else { 2719 gids = new int[permGids.length + 1]; 2720 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2721 } 2722 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2723 } 2724 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2725 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2726 && mTopComponent != null 2727 && app.processName.equals(mTopComponent.getPackageName())) { 2728 uid = 0; 2729 } 2730 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2731 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2732 uid = 0; 2733 } 2734 } 2735 int debugFlags = 0; 2736 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2737 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2738 // Also turn on CheckJNI for debuggable apps. It's quite 2739 // awkward to turn on otherwise. 2740 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2741 } 2742 // Run the app in safe mode if its manifest requests so or the 2743 // system is booted in safe mode. 2744 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2745 mSafeMode == true) { 2746 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2747 } 2748 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2749 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2750 } 2751 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2752 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2753 } 2754 if ("1".equals(SystemProperties.get("debug.assert"))) { 2755 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2756 } 2757 2758 // Start the process. It will either succeed and return a result containing 2759 // the PID of the new process, or else throw a RuntimeException. 2760 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2761 app.processName, uid, uid, gids, debugFlags, mountExternal, 2762 app.info.targetSdkVersion, app.info.seinfo, null); 2763 2764 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2765 synchronized (bs) { 2766 if (bs.isOnBattery()) { 2767 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2768 } 2769 } 2770 2771 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2772 UserHandle.getUserId(uid), startResult.pid, uid, 2773 app.processName, hostingType, 2774 hostingNameStr != null ? hostingNameStr : ""); 2775 2776 if (app.persistent) { 2777 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2778 } 2779 2780 StringBuilder buf = mStringBuilder; 2781 buf.setLength(0); 2782 buf.append("Start proc "); 2783 buf.append(app.processName); 2784 buf.append(" for "); 2785 buf.append(hostingType); 2786 if (hostingNameStr != null) { 2787 buf.append(" "); 2788 buf.append(hostingNameStr); 2789 } 2790 buf.append(": pid="); 2791 buf.append(startResult.pid); 2792 buf.append(" uid="); 2793 buf.append(uid); 2794 buf.append(" gids={"); 2795 if (gids != null) { 2796 for (int gi=0; gi<gids.length; gi++) { 2797 if (gi != 0) buf.append(", "); 2798 buf.append(gids[gi]); 2799 2800 } 2801 } 2802 buf.append("}"); 2803 Slog.i(TAG, buf.toString()); 2804 app.setPid(startResult.pid); 2805 app.usingWrapper = startResult.usingWrapper; 2806 app.removed = false; 2807 synchronized (mPidsSelfLocked) { 2808 this.mPidsSelfLocked.put(startResult.pid, app); 2809 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2810 msg.obj = app; 2811 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2812 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2813 } 2814 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2815 app.processName, app.info.uid); 2816 if (app.isolated) { 2817 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2818 } 2819 } catch (RuntimeException e) { 2820 // XXX do better error recovery. 2821 app.setPid(0); 2822 Slog.e(TAG, "Failure starting process " + app.processName, e); 2823 } 2824 } 2825 2826 void updateUsageStats(ActivityRecord component, boolean resumed) { 2827 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2828 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2829 if (resumed) { 2830 mUsageStatsService.noteResumeComponent(component.realActivity); 2831 synchronized (stats) { 2832 stats.noteActivityResumedLocked(component.app.uid); 2833 } 2834 } else { 2835 mUsageStatsService.notePauseComponent(component.realActivity); 2836 synchronized (stats) { 2837 stats.noteActivityPausedLocked(component.app.uid); 2838 } 2839 } 2840 } 2841 2842 Intent getHomeIntent() { 2843 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2844 intent.setComponent(mTopComponent); 2845 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2846 intent.addCategory(Intent.CATEGORY_HOME); 2847 } 2848 return intent; 2849 } 2850 2851 boolean startHomeActivityLocked(int userId) { 2852 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2853 && mTopAction == null) { 2854 // We are running in factory test mode, but unable to find 2855 // the factory test app, so just sit around displaying the 2856 // error message and don't try to start anything. 2857 return false; 2858 } 2859 Intent intent = getHomeIntent(); 2860 ActivityInfo aInfo = 2861 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2862 if (aInfo != null) { 2863 intent.setComponent(new ComponentName( 2864 aInfo.applicationInfo.packageName, aInfo.name)); 2865 // Don't do this if the home app is currently being 2866 // instrumented. 2867 aInfo = new ActivityInfo(aInfo); 2868 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2869 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2870 aInfo.applicationInfo.uid, true); 2871 if (app == null || app.instrumentationClass == null) { 2872 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2873 mStackSupervisor.startHomeActivity(intent, aInfo); 2874 } 2875 } 2876 2877 return true; 2878 } 2879 2880 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2881 ActivityInfo ai = null; 2882 ComponentName comp = intent.getComponent(); 2883 try { 2884 if (comp != null) { 2885 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2886 } else { 2887 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2888 intent, 2889 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2890 flags, userId); 2891 2892 if (info != null) { 2893 ai = info.activityInfo; 2894 } 2895 } 2896 } catch (RemoteException e) { 2897 // ignore 2898 } 2899 2900 return ai; 2901 } 2902 2903 /** 2904 * Starts the "new version setup screen" if appropriate. 2905 */ 2906 void startSetupActivityLocked() { 2907 // Only do this once per boot. 2908 if (mCheckedForSetup) { 2909 return; 2910 } 2911 2912 // We will show this screen if the current one is a different 2913 // version than the last one shown, and we are not running in 2914 // low-level factory test mode. 2915 final ContentResolver resolver = mContext.getContentResolver(); 2916 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2917 Settings.Global.getInt(resolver, 2918 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2919 mCheckedForSetup = true; 2920 2921 // See if we should be showing the platform update setup UI. 2922 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2923 List<ResolveInfo> ris = mContext.getPackageManager() 2924 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2925 2926 // We don't allow third party apps to replace this. 2927 ResolveInfo ri = null; 2928 for (int i=0; ris != null && i<ris.size(); i++) { 2929 if ((ris.get(i).activityInfo.applicationInfo.flags 2930 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2931 ri = ris.get(i); 2932 break; 2933 } 2934 } 2935 2936 if (ri != null) { 2937 String vers = ri.activityInfo.metaData != null 2938 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2939 : null; 2940 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2941 vers = ri.activityInfo.applicationInfo.metaData.getString( 2942 Intent.METADATA_SETUP_VERSION); 2943 } 2944 String lastVers = Settings.Secure.getString( 2945 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2946 if (vers != null && !vers.equals(lastVers)) { 2947 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2948 intent.setComponent(new ComponentName( 2949 ri.activityInfo.packageName, ri.activityInfo.name)); 2950 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2951 null, null, 0, 0, 0, null, 0, null, false, null, null); 2952 } 2953 } 2954 } 2955 } 2956 2957 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2958 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2959 } 2960 2961 void enforceNotIsolatedCaller(String caller) { 2962 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2963 throw new SecurityException("Isolated process not allowed to call " + caller); 2964 } 2965 } 2966 2967 @Override 2968 public int getFrontActivityScreenCompatMode() { 2969 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2970 synchronized (this) { 2971 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2972 } 2973 } 2974 2975 @Override 2976 public void setFrontActivityScreenCompatMode(int mode) { 2977 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2978 "setFrontActivityScreenCompatMode"); 2979 synchronized (this) { 2980 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2981 } 2982 } 2983 2984 @Override 2985 public int getPackageScreenCompatMode(String packageName) { 2986 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2987 synchronized (this) { 2988 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2989 } 2990 } 2991 2992 @Override 2993 public void setPackageScreenCompatMode(String packageName, int mode) { 2994 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2995 "setPackageScreenCompatMode"); 2996 synchronized (this) { 2997 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2998 } 2999 } 3000 3001 @Override 3002 public boolean getPackageAskScreenCompat(String packageName) { 3003 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3004 synchronized (this) { 3005 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3006 } 3007 } 3008 3009 @Override 3010 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3011 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3012 "setPackageAskScreenCompat"); 3013 synchronized (this) { 3014 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3015 } 3016 } 3017 3018 private void dispatchProcessesChanged() { 3019 int N; 3020 synchronized (this) { 3021 N = mPendingProcessChanges.size(); 3022 if (mActiveProcessChanges.length < N) { 3023 mActiveProcessChanges = new ProcessChangeItem[N]; 3024 } 3025 mPendingProcessChanges.toArray(mActiveProcessChanges); 3026 mAvailProcessChanges.addAll(mPendingProcessChanges); 3027 mPendingProcessChanges.clear(); 3028 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3029 } 3030 3031 int i = mProcessObservers.beginBroadcast(); 3032 while (i > 0) { 3033 i--; 3034 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3035 if (observer != null) { 3036 try { 3037 for (int j=0; j<N; j++) { 3038 ProcessChangeItem item = mActiveProcessChanges[j]; 3039 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3040 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3041 + item.pid + " uid=" + item.uid + ": " 3042 + item.foregroundActivities); 3043 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3044 item.foregroundActivities); 3045 } 3046 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3047 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3048 + item.pid + " uid=" + item.uid + ": " + item.importance); 3049 observer.onImportanceChanged(item.pid, item.uid, 3050 item.importance); 3051 } 3052 } 3053 } catch (RemoteException e) { 3054 } 3055 } 3056 } 3057 mProcessObservers.finishBroadcast(); 3058 } 3059 3060 private void dispatchProcessDied(int pid, int uid) { 3061 int i = mProcessObservers.beginBroadcast(); 3062 while (i > 0) { 3063 i--; 3064 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3065 if (observer != null) { 3066 try { 3067 observer.onProcessDied(pid, uid); 3068 } catch (RemoteException e) { 3069 } 3070 } 3071 } 3072 mProcessObservers.finishBroadcast(); 3073 } 3074 3075 final void doPendingActivityLaunchesLocked(boolean doResume) { 3076 final int N = mPendingActivityLaunches.size(); 3077 if (N <= 0) { 3078 return; 3079 } 3080 for (int i=0; i<N; i++) { 3081 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3082 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3083 doResume && i == (N-1), null); 3084 } 3085 mPendingActivityLaunches.clear(); 3086 } 3087 3088 @Override 3089 public final int startActivity(IApplicationThread caller, String callingPackage, 3090 Intent intent, String resolvedType, IBinder resultTo, 3091 String resultWho, int requestCode, int startFlags, 3092 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3093 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3094 resultWho, requestCode, 3095 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3096 } 3097 3098 @Override 3099 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3100 Intent intent, String resolvedType, IBinder resultTo, 3101 String resultWho, int requestCode, int startFlags, 3102 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3103 enforceNotIsolatedCaller("startActivity"); 3104 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3105 false, true, "startActivity", null); 3106 // TODO: Switch to user app stacks here. 3107 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3108 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3109 null, null, options, userId, null); 3110 } 3111 3112 @Override 3113 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3114 Intent intent, String resolvedType, IBinder resultTo, 3115 String resultWho, int requestCode, int startFlags, String profileFile, 3116 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3117 enforceNotIsolatedCaller("startActivityAndWait"); 3118 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3119 false, true, "startActivityAndWait", null); 3120 WaitResult res = new WaitResult(); 3121 // TODO: Switch to user app stacks here. 3122 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3123 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3124 res, null, options, UserHandle.getCallingUserId(), null); 3125 return res; 3126 } 3127 3128 @Override 3129 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3130 Intent intent, String resolvedType, IBinder resultTo, 3131 String resultWho, int requestCode, int startFlags, Configuration config, 3132 Bundle options, int userId) { 3133 enforceNotIsolatedCaller("startActivityWithConfig"); 3134 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3135 false, true, "startActivityWithConfig", null); 3136 // TODO: Switch to user app stacks here. 3137 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3138 resolvedType, resultTo, resultWho, requestCode, startFlags, 3139 null, null, null, config, options, userId, null); 3140 return ret; 3141 } 3142 3143 @Override 3144 public int startActivityIntentSender(IApplicationThread caller, 3145 IntentSender intent, Intent fillInIntent, String resolvedType, 3146 IBinder resultTo, String resultWho, int requestCode, 3147 int flagsMask, int flagsValues, Bundle options) { 3148 enforceNotIsolatedCaller("startActivityIntentSender"); 3149 // Refuse possible leaked file descriptors 3150 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3151 throw new IllegalArgumentException("File descriptors passed in Intent"); 3152 } 3153 3154 IIntentSender sender = intent.getTarget(); 3155 if (!(sender instanceof PendingIntentRecord)) { 3156 throw new IllegalArgumentException("Bad PendingIntent object"); 3157 } 3158 3159 PendingIntentRecord pir = (PendingIntentRecord)sender; 3160 3161 synchronized (this) { 3162 // If this is coming from the currently resumed activity, it is 3163 // effectively saying that app switches are allowed at this point. 3164 final ActivityStack stack = getFocusedStack(); 3165 if (stack.mResumedActivity != null && 3166 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3167 mAppSwitchesAllowedTime = 0; 3168 } 3169 } 3170 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3171 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3172 return ret; 3173 } 3174 3175 @Override 3176 public boolean startNextMatchingActivity(IBinder callingActivity, 3177 Intent intent, Bundle options) { 3178 // Refuse possible leaked file descriptors 3179 if (intent != null && intent.hasFileDescriptors() == true) { 3180 throw new IllegalArgumentException("File descriptors passed in Intent"); 3181 } 3182 3183 synchronized (this) { 3184 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3185 if (r == null) { 3186 ActivityOptions.abort(options); 3187 return false; 3188 } 3189 if (r.app == null || r.app.thread == null) { 3190 // The caller is not running... d'oh! 3191 ActivityOptions.abort(options); 3192 return false; 3193 } 3194 intent = new Intent(intent); 3195 // The caller is not allowed to change the data. 3196 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3197 // And we are resetting to find the next component... 3198 intent.setComponent(null); 3199 3200 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3201 3202 ActivityInfo aInfo = null; 3203 try { 3204 List<ResolveInfo> resolves = 3205 AppGlobals.getPackageManager().queryIntentActivities( 3206 intent, r.resolvedType, 3207 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3208 UserHandle.getCallingUserId()); 3209 3210 // Look for the original activity in the list... 3211 final int N = resolves != null ? resolves.size() : 0; 3212 for (int i=0; i<N; i++) { 3213 ResolveInfo rInfo = resolves.get(i); 3214 if (rInfo.activityInfo.packageName.equals(r.packageName) 3215 && rInfo.activityInfo.name.equals(r.info.name)) { 3216 // We found the current one... the next matching is 3217 // after it. 3218 i++; 3219 if (i<N) { 3220 aInfo = resolves.get(i).activityInfo; 3221 } 3222 if (debug) { 3223 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3224 + "/" + r.info.name); 3225 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3226 + "/" + aInfo.name); 3227 } 3228 break; 3229 } 3230 } 3231 } catch (RemoteException e) { 3232 } 3233 3234 if (aInfo == null) { 3235 // Nobody who is next! 3236 ActivityOptions.abort(options); 3237 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3238 return false; 3239 } 3240 3241 intent.setComponent(new ComponentName( 3242 aInfo.applicationInfo.packageName, aInfo.name)); 3243 intent.setFlags(intent.getFlags()&~( 3244 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3245 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3246 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3247 Intent.FLAG_ACTIVITY_NEW_TASK)); 3248 3249 // Okay now we need to start the new activity, replacing the 3250 // currently running activity. This is a little tricky because 3251 // we want to start the new one as if the current one is finished, 3252 // but not finish the current one first so that there is no flicker. 3253 // And thus... 3254 final boolean wasFinishing = r.finishing; 3255 r.finishing = true; 3256 3257 // Propagate reply information over to the new activity. 3258 final ActivityRecord resultTo = r.resultTo; 3259 final String resultWho = r.resultWho; 3260 final int requestCode = r.requestCode; 3261 r.resultTo = null; 3262 if (resultTo != null) { 3263 resultTo.removeResultsLocked(r, resultWho, requestCode); 3264 } 3265 3266 final long origId = Binder.clearCallingIdentity(); 3267 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3268 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3269 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3270 options, false, null, null); 3271 Binder.restoreCallingIdentity(origId); 3272 3273 r.finishing = wasFinishing; 3274 if (res != ActivityManager.START_SUCCESS) { 3275 return false; 3276 } 3277 return true; 3278 } 3279 } 3280 3281 final int startActivityInPackage(int uid, String callingPackage, 3282 Intent intent, String resolvedType, IBinder resultTo, 3283 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3284 IActivityContainer container) { 3285 3286 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3287 false, true, "startActivityInPackage", null); 3288 3289 // TODO: Switch to user app stacks here. 3290 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3291 resultTo, resultWho, requestCode, startFlags, 3292 null, null, null, null, options, userId, container); 3293 return ret; 3294 } 3295 3296 @Override 3297 public final int startActivities(IApplicationThread caller, String callingPackage, 3298 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3299 int userId) { 3300 enforceNotIsolatedCaller("startActivities"); 3301 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3302 false, true, "startActivity", null); 3303 // TODO: Switch to user app stacks here. 3304 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3305 resolvedTypes, resultTo, options, userId); 3306 return ret; 3307 } 3308 3309 final int startActivitiesInPackage(int uid, String callingPackage, 3310 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3311 Bundle options, int userId) { 3312 3313 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3314 false, true, "startActivityInPackage", null); 3315 // TODO: Switch to user app stacks here. 3316 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3317 resultTo, options, userId); 3318 return ret; 3319 } 3320 3321 final void addRecentTaskLocked(TaskRecord task) { 3322 int N = mRecentTasks.size(); 3323 // Quick case: check if the top-most recent task is the same. 3324 if (N > 0 && mRecentTasks.get(0) == task) { 3325 return; 3326 } 3327 // Remove any existing entries that are the same kind of task. 3328 final Intent intent = task.intent; 3329 final boolean document = intent != null && intent.isDocument(); 3330 for (int i=0; i<N; i++) { 3331 TaskRecord tr = mRecentTasks.get(i); 3332 if (task != tr) { 3333 if (task.userId != tr.userId) { 3334 continue; 3335 } 3336 final Intent trIntent = tr.intent; 3337 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3338 (intent == null || !intent.filterEquals(trIntent))) { 3339 continue; 3340 } 3341 if (document || trIntent != null && trIntent.isDocument()) { 3342 // Document tasks do not match other tasks. 3343 continue; 3344 } 3345 } 3346 3347 // Either task and tr are the same or, their affinities match or their intents match 3348 // and neither of them is a document. 3349 tr.disposeThumbnail(); 3350 mRecentTasks.remove(i); 3351 i--; 3352 N--; 3353 if (task.intent == null) { 3354 // If the new recent task we are adding is not fully 3355 // specified, then replace it with the existing recent task. 3356 task = tr; 3357 } 3358 } 3359 if (N >= MAX_RECENT_TASKS) { 3360 mRecentTasks.remove(N-1).disposeThumbnail(); 3361 } 3362 mRecentTasks.add(0, task); 3363 } 3364 3365 @Override 3366 public void reportActivityFullyDrawn(IBinder token) { 3367 synchronized (this) { 3368 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3369 if (r == null) { 3370 return; 3371 } 3372 r.reportFullyDrawnLocked(); 3373 } 3374 } 3375 3376 @Override 3377 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3378 synchronized (this) { 3379 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3380 if (r == null) { 3381 return; 3382 } 3383 final long origId = Binder.clearCallingIdentity(); 3384 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3385 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3386 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3387 if (config != null) { 3388 r.frozenBeforeDestroy = true; 3389 if (!updateConfigurationLocked(config, r, false, false)) { 3390 mStackSupervisor.resumeTopActivitiesLocked(); 3391 } 3392 } 3393 Binder.restoreCallingIdentity(origId); 3394 } 3395 } 3396 3397 @Override 3398 public int getRequestedOrientation(IBinder token) { 3399 synchronized (this) { 3400 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3401 if (r == null) { 3402 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3403 } 3404 return mWindowManager.getAppOrientation(r.appToken); 3405 } 3406 } 3407 3408 /** 3409 * This is the internal entry point for handling Activity.finish(). 3410 * 3411 * @param token The Binder token referencing the Activity we want to finish. 3412 * @param resultCode Result code, if any, from this Activity. 3413 * @param resultData Result data (Intent), if any, from this Activity. 3414 * 3415 * @return Returns true if the activity successfully finished, or false if it is still running. 3416 */ 3417 @Override 3418 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3419 // Refuse possible leaked file descriptors 3420 if (resultData != null && resultData.hasFileDescriptors() == true) { 3421 throw new IllegalArgumentException("File descriptors passed in Intent"); 3422 } 3423 3424 synchronized(this) { 3425 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3426 if (r == null) { 3427 return true; 3428 } 3429 if (mController != null) { 3430 // Find the first activity that is not finishing. 3431 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3432 if (next != null) { 3433 // ask watcher if this is allowed 3434 boolean resumeOK = true; 3435 try { 3436 resumeOK = mController.activityResuming(next.packageName); 3437 } catch (RemoteException e) { 3438 mController = null; 3439 Watchdog.getInstance().setActivityController(null); 3440 } 3441 3442 if (!resumeOK) { 3443 return false; 3444 } 3445 } 3446 } 3447 final long origId = Binder.clearCallingIdentity(); 3448 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3449 resultData, "app-request", true); 3450 Binder.restoreCallingIdentity(origId); 3451 return res; 3452 } 3453 } 3454 3455 @Override 3456 public final void finishHeavyWeightApp() { 3457 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3458 != PackageManager.PERMISSION_GRANTED) { 3459 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3460 + Binder.getCallingPid() 3461 + ", uid=" + Binder.getCallingUid() 3462 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3463 Slog.w(TAG, msg); 3464 throw new SecurityException(msg); 3465 } 3466 3467 synchronized(this) { 3468 if (mHeavyWeightProcess == null) { 3469 return; 3470 } 3471 3472 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3473 mHeavyWeightProcess.activities); 3474 for (int i=0; i<activities.size(); i++) { 3475 ActivityRecord r = activities.get(i); 3476 if (!r.finishing) { 3477 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3478 null, "finish-heavy", true); 3479 } 3480 } 3481 3482 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3483 mHeavyWeightProcess.userId, 0)); 3484 mHeavyWeightProcess = null; 3485 } 3486 } 3487 3488 @Override 3489 public void crashApplication(int uid, int initialPid, String packageName, 3490 String message) { 3491 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3492 != PackageManager.PERMISSION_GRANTED) { 3493 String msg = "Permission Denial: crashApplication() from pid=" 3494 + Binder.getCallingPid() 3495 + ", uid=" + Binder.getCallingUid() 3496 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3497 Slog.w(TAG, msg); 3498 throw new SecurityException(msg); 3499 } 3500 3501 synchronized(this) { 3502 ProcessRecord proc = null; 3503 3504 // Figure out which process to kill. We don't trust that initialPid 3505 // still has any relation to current pids, so must scan through the 3506 // list. 3507 synchronized (mPidsSelfLocked) { 3508 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3509 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3510 if (p.uid != uid) { 3511 continue; 3512 } 3513 if (p.pid == initialPid) { 3514 proc = p; 3515 break; 3516 } 3517 if (p.pkgList.containsKey(packageName)) { 3518 proc = p; 3519 } 3520 } 3521 } 3522 3523 if (proc == null) { 3524 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3525 + " initialPid=" + initialPid 3526 + " packageName=" + packageName); 3527 return; 3528 } 3529 3530 if (proc.thread != null) { 3531 if (proc.pid == Process.myPid()) { 3532 Log.w(TAG, "crashApplication: trying to crash self!"); 3533 return; 3534 } 3535 long ident = Binder.clearCallingIdentity(); 3536 try { 3537 proc.thread.scheduleCrash(message); 3538 } catch (RemoteException e) { 3539 } 3540 Binder.restoreCallingIdentity(ident); 3541 } 3542 } 3543 } 3544 3545 @Override 3546 public final void finishSubActivity(IBinder token, String resultWho, 3547 int requestCode) { 3548 synchronized(this) { 3549 final long origId = Binder.clearCallingIdentity(); 3550 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3551 if (r != null) { 3552 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3553 } 3554 Binder.restoreCallingIdentity(origId); 3555 } 3556 } 3557 3558 @Override 3559 public boolean finishActivityAffinity(IBinder token) { 3560 synchronized(this) { 3561 final long origId = Binder.clearCallingIdentity(); 3562 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3563 boolean res = false; 3564 if (r != null) { 3565 res = r.task.stack.finishActivityAffinityLocked(r); 3566 } 3567 Binder.restoreCallingIdentity(origId); 3568 return res; 3569 } 3570 } 3571 3572 @Override 3573 public boolean willActivityBeVisible(IBinder token) { 3574 synchronized(this) { 3575 ActivityStack stack = ActivityRecord.getStackLocked(token); 3576 if (stack != null) { 3577 return stack.willActivityBeVisibleLocked(token); 3578 } 3579 return false; 3580 } 3581 } 3582 3583 @Override 3584 public void overridePendingTransition(IBinder token, String packageName, 3585 int enterAnim, int exitAnim) { 3586 synchronized(this) { 3587 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3588 if (self == null) { 3589 return; 3590 } 3591 3592 final long origId = Binder.clearCallingIdentity(); 3593 3594 if (self.state == ActivityState.RESUMED 3595 || self.state == ActivityState.PAUSING) { 3596 mWindowManager.overridePendingAppTransition(packageName, 3597 enterAnim, exitAnim, null); 3598 } 3599 3600 Binder.restoreCallingIdentity(origId); 3601 } 3602 } 3603 3604 /** 3605 * Main function for removing an existing process from the activity manager 3606 * as a result of that process going away. Clears out all connections 3607 * to the process. 3608 */ 3609 private final void handleAppDiedLocked(ProcessRecord app, 3610 boolean restarting, boolean allowRestart) { 3611 int pid = app.pid; 3612 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3613 if (!restarting) { 3614 removeLruProcessLocked(app); 3615 if (pid > 0) { 3616 ProcessList.remove(pid); 3617 } 3618 } 3619 3620 if (mProfileProc == app) { 3621 clearProfilerLocked(); 3622 } 3623 3624 // Remove this application's activities from active lists. 3625 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3626 3627 app.activities.clear(); 3628 3629 if (app.instrumentationClass != null) { 3630 Slog.w(TAG, "Crash of app " + app.processName 3631 + " running instrumentation " + app.instrumentationClass); 3632 Bundle info = new Bundle(); 3633 info.putString("shortMsg", "Process crashed."); 3634 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3635 } 3636 3637 if (!restarting) { 3638 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3639 // If there was nothing to resume, and we are not already 3640 // restarting this process, but there is a visible activity that 3641 // is hosted by the process... then make sure all visible 3642 // activities are running, taking care of restarting this 3643 // process. 3644 if (hasVisibleActivities) { 3645 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3646 } 3647 } 3648 } 3649 } 3650 3651 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3652 IBinder threadBinder = thread.asBinder(); 3653 // Find the application record. 3654 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3655 ProcessRecord rec = mLruProcesses.get(i); 3656 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3657 return i; 3658 } 3659 } 3660 return -1; 3661 } 3662 3663 final ProcessRecord getRecordForAppLocked( 3664 IApplicationThread thread) { 3665 if (thread == null) { 3666 return null; 3667 } 3668 3669 int appIndex = getLRURecordIndexForAppLocked(thread); 3670 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3671 } 3672 3673 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3674 // If there are no longer any background processes running, 3675 // and the app that died was not running instrumentation, 3676 // then tell everyone we are now low on memory. 3677 boolean haveBg = false; 3678 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3679 ProcessRecord rec = mLruProcesses.get(i); 3680 if (rec.thread != null 3681 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3682 haveBg = true; 3683 break; 3684 } 3685 } 3686 3687 if (!haveBg) { 3688 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3689 if (doReport) { 3690 long now = SystemClock.uptimeMillis(); 3691 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3692 doReport = false; 3693 } else { 3694 mLastMemUsageReportTime = now; 3695 } 3696 } 3697 final ArrayList<ProcessMemInfo> memInfos 3698 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3699 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3700 long now = SystemClock.uptimeMillis(); 3701 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3702 ProcessRecord rec = mLruProcesses.get(i); 3703 if (rec == dyingProc || rec.thread == null) { 3704 continue; 3705 } 3706 if (doReport) { 3707 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3708 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3709 } 3710 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3711 // The low memory report is overriding any current 3712 // state for a GC request. Make sure to do 3713 // heavy/important/visible/foreground processes first. 3714 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3715 rec.lastRequestedGc = 0; 3716 } else { 3717 rec.lastRequestedGc = rec.lastLowMemory; 3718 } 3719 rec.reportLowMemory = true; 3720 rec.lastLowMemory = now; 3721 mProcessesToGc.remove(rec); 3722 addProcessToGcListLocked(rec); 3723 } 3724 } 3725 if (doReport) { 3726 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3727 mHandler.sendMessage(msg); 3728 } 3729 scheduleAppGcsLocked(); 3730 } 3731 } 3732 3733 final void appDiedLocked(ProcessRecord app, int pid, 3734 IApplicationThread thread) { 3735 3736 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3737 synchronized (stats) { 3738 stats.noteProcessDiedLocked(app.info.uid, pid); 3739 } 3740 3741 // Clean up already done if the process has been re-started. 3742 if (app.pid == pid && app.thread != null && 3743 app.thread.asBinder() == thread.asBinder()) { 3744 boolean doLowMem = app.instrumentationClass == null; 3745 boolean doOomAdj = doLowMem; 3746 if (!app.killedByAm) { 3747 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3748 + ") has died."); 3749 mAllowLowerMemLevel = true; 3750 } else { 3751 // Note that we always want to do oom adj to update our state with the 3752 // new number of procs. 3753 mAllowLowerMemLevel = false; 3754 doLowMem = false; 3755 } 3756 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3757 if (DEBUG_CLEANUP) Slog.v( 3758 TAG, "Dying app: " + app + ", pid: " + pid 3759 + ", thread: " + thread.asBinder()); 3760 handleAppDiedLocked(app, false, true); 3761 3762 if (doOomAdj) { 3763 updateOomAdjLocked(); 3764 } 3765 if (doLowMem) { 3766 doLowMemReportIfNeededLocked(app); 3767 } 3768 } else if (app.pid != pid) { 3769 // A new process has already been started. 3770 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3771 + ") has died and restarted (pid " + app.pid + ")."); 3772 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3773 } else if (DEBUG_PROCESSES) { 3774 Slog.d(TAG, "Received spurious death notification for thread " 3775 + thread.asBinder()); 3776 } 3777 } 3778 3779 /** 3780 * If a stack trace dump file is configured, dump process stack traces. 3781 * @param clearTraces causes the dump file to be erased prior to the new 3782 * traces being written, if true; when false, the new traces will be 3783 * appended to any existing file content. 3784 * @param firstPids of dalvik VM processes to dump stack traces for first 3785 * @param lastPids of dalvik VM processes to dump stack traces for last 3786 * @param nativeProcs optional list of native process names to dump stack crawls 3787 * @return file containing stack traces, or null if no dump file is configured 3788 */ 3789 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3790 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3791 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3792 if (tracesPath == null || tracesPath.length() == 0) { 3793 return null; 3794 } 3795 3796 File tracesFile = new File(tracesPath); 3797 try { 3798 File tracesDir = tracesFile.getParentFile(); 3799 if (!tracesDir.exists()) { 3800 tracesFile.mkdirs(); 3801 if (!SELinux.restorecon(tracesDir)) { 3802 return null; 3803 } 3804 } 3805 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3806 3807 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3808 tracesFile.createNewFile(); 3809 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3810 } catch (IOException e) { 3811 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3812 return null; 3813 } 3814 3815 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3816 return tracesFile; 3817 } 3818 3819 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3820 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3821 // Use a FileObserver to detect when traces finish writing. 3822 // The order of traces is considered important to maintain for legibility. 3823 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3824 @Override 3825 public synchronized void onEvent(int event, String path) { notify(); } 3826 }; 3827 3828 try { 3829 observer.startWatching(); 3830 3831 // First collect all of the stacks of the most important pids. 3832 if (firstPids != null) { 3833 try { 3834 int num = firstPids.size(); 3835 for (int i = 0; i < num; i++) { 3836 synchronized (observer) { 3837 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3838 observer.wait(200); // Wait for write-close, give up after 200msec 3839 } 3840 } 3841 } catch (InterruptedException e) { 3842 Log.wtf(TAG, e); 3843 } 3844 } 3845 3846 // Next collect the stacks of the native pids 3847 if (nativeProcs != null) { 3848 int[] pids = Process.getPidsForCommands(nativeProcs); 3849 if (pids != null) { 3850 for (int pid : pids) { 3851 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3852 } 3853 } 3854 } 3855 3856 // Lastly, measure CPU usage. 3857 if (processCpuTracker != null) { 3858 processCpuTracker.init(); 3859 System.gc(); 3860 processCpuTracker.update(); 3861 try { 3862 synchronized (processCpuTracker) { 3863 processCpuTracker.wait(500); // measure over 1/2 second. 3864 } 3865 } catch (InterruptedException e) { 3866 } 3867 processCpuTracker.update(); 3868 3869 // We'll take the stack crawls of just the top apps using CPU. 3870 final int N = processCpuTracker.countWorkingStats(); 3871 int numProcs = 0; 3872 for (int i=0; i<N && numProcs<5; i++) { 3873 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3874 if (lastPids.indexOfKey(stats.pid) >= 0) { 3875 numProcs++; 3876 try { 3877 synchronized (observer) { 3878 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3879 observer.wait(200); // Wait for write-close, give up after 200msec 3880 } 3881 } catch (InterruptedException e) { 3882 Log.wtf(TAG, e); 3883 } 3884 3885 } 3886 } 3887 } 3888 } finally { 3889 observer.stopWatching(); 3890 } 3891 } 3892 3893 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3894 if (true || IS_USER_BUILD) { 3895 return; 3896 } 3897 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3898 if (tracesPath == null || tracesPath.length() == 0) { 3899 return; 3900 } 3901 3902 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3903 StrictMode.allowThreadDiskWrites(); 3904 try { 3905 final File tracesFile = new File(tracesPath); 3906 final File tracesDir = tracesFile.getParentFile(); 3907 final File tracesTmp = new File(tracesDir, "__tmp__"); 3908 try { 3909 if (!tracesDir.exists()) { 3910 tracesFile.mkdirs(); 3911 if (!SELinux.restorecon(tracesDir.getPath())) { 3912 return; 3913 } 3914 } 3915 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3916 3917 if (tracesFile.exists()) { 3918 tracesTmp.delete(); 3919 tracesFile.renameTo(tracesTmp); 3920 } 3921 StringBuilder sb = new StringBuilder(); 3922 Time tobj = new Time(); 3923 tobj.set(System.currentTimeMillis()); 3924 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3925 sb.append(": "); 3926 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3927 sb.append(" since "); 3928 sb.append(msg); 3929 FileOutputStream fos = new FileOutputStream(tracesFile); 3930 fos.write(sb.toString().getBytes()); 3931 if (app == null) { 3932 fos.write("\n*** No application process!".getBytes()); 3933 } 3934 fos.close(); 3935 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3936 } catch (IOException e) { 3937 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3938 return; 3939 } 3940 3941 if (app != null) { 3942 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3943 firstPids.add(app.pid); 3944 dumpStackTraces(tracesPath, firstPids, null, null, null); 3945 } 3946 3947 File lastTracesFile = null; 3948 File curTracesFile = null; 3949 for (int i=9; i>=0; i--) { 3950 String name = String.format(Locale.US, "slow%02d.txt", i); 3951 curTracesFile = new File(tracesDir, name); 3952 if (curTracesFile.exists()) { 3953 if (lastTracesFile != null) { 3954 curTracesFile.renameTo(lastTracesFile); 3955 } else { 3956 curTracesFile.delete(); 3957 } 3958 } 3959 lastTracesFile = curTracesFile; 3960 } 3961 tracesFile.renameTo(curTracesFile); 3962 if (tracesTmp.exists()) { 3963 tracesTmp.renameTo(tracesFile); 3964 } 3965 } finally { 3966 StrictMode.setThreadPolicy(oldPolicy); 3967 } 3968 } 3969 3970 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3971 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3972 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3973 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3974 3975 if (mController != null) { 3976 try { 3977 // 0 == continue, -1 = kill process immediately 3978 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3979 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3980 } catch (RemoteException e) { 3981 mController = null; 3982 Watchdog.getInstance().setActivityController(null); 3983 } 3984 } 3985 3986 long anrTime = SystemClock.uptimeMillis(); 3987 if (MONITOR_CPU_USAGE) { 3988 updateCpuStatsNow(); 3989 } 3990 3991 synchronized (this) { 3992 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3993 if (mShuttingDown) { 3994 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3995 return; 3996 } else if (app.notResponding) { 3997 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3998 return; 3999 } else if (app.crashing) { 4000 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4001 return; 4002 } 4003 4004 // In case we come through here for the same app before completing 4005 // this one, mark as anring now so we will bail out. 4006 app.notResponding = true; 4007 4008 // Log the ANR to the event log. 4009 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4010 app.processName, app.info.flags, annotation); 4011 4012 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4013 firstPids.add(app.pid); 4014 4015 int parentPid = app.pid; 4016 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4017 if (parentPid != app.pid) firstPids.add(parentPid); 4018 4019 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4020 4021 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4022 ProcessRecord r = mLruProcesses.get(i); 4023 if (r != null && r.thread != null) { 4024 int pid = r.pid; 4025 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4026 if (r.persistent) { 4027 firstPids.add(pid); 4028 } else { 4029 lastPids.put(pid, Boolean.TRUE); 4030 } 4031 } 4032 } 4033 } 4034 } 4035 4036 // Log the ANR to the main log. 4037 StringBuilder info = new StringBuilder(); 4038 info.setLength(0); 4039 info.append("ANR in ").append(app.processName); 4040 if (activity != null && activity.shortComponentName != null) { 4041 info.append(" (").append(activity.shortComponentName).append(")"); 4042 } 4043 info.append("\n"); 4044 info.append("PID: ").append(app.pid).append("\n"); 4045 if (annotation != null) { 4046 info.append("Reason: ").append(annotation).append("\n"); 4047 } 4048 if (parent != null && parent != activity) { 4049 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4050 } 4051 4052 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4053 4054 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4055 NATIVE_STACKS_OF_INTEREST); 4056 4057 String cpuInfo = null; 4058 if (MONITOR_CPU_USAGE) { 4059 updateCpuStatsNow(); 4060 synchronized (mProcessCpuThread) { 4061 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4062 } 4063 info.append(processCpuTracker.printCurrentLoad()); 4064 info.append(cpuInfo); 4065 } 4066 4067 info.append(processCpuTracker.printCurrentState(anrTime)); 4068 4069 Slog.e(TAG, info.toString()); 4070 if (tracesFile == null) { 4071 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4072 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4073 } 4074 4075 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4076 cpuInfo, tracesFile, null); 4077 4078 if (mController != null) { 4079 try { 4080 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4081 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4082 if (res != 0) { 4083 if (res < 0 && app.pid != MY_PID) { 4084 Process.killProcess(app.pid); 4085 } else { 4086 synchronized (this) { 4087 mServices.scheduleServiceTimeoutLocked(app); 4088 } 4089 } 4090 return; 4091 } 4092 } catch (RemoteException e) { 4093 mController = null; 4094 Watchdog.getInstance().setActivityController(null); 4095 } 4096 } 4097 4098 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4099 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4100 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4101 4102 synchronized (this) { 4103 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4104 killUnneededProcessLocked(app, "background ANR"); 4105 return; 4106 } 4107 4108 // Set the app's notResponding state, and look up the errorReportReceiver 4109 makeAppNotRespondingLocked(app, 4110 activity != null ? activity.shortComponentName : null, 4111 annotation != null ? "ANR " + annotation : "ANR", 4112 info.toString()); 4113 4114 // Bring up the infamous App Not Responding dialog 4115 Message msg = Message.obtain(); 4116 HashMap<String, Object> map = new HashMap<String, Object>(); 4117 msg.what = SHOW_NOT_RESPONDING_MSG; 4118 msg.obj = map; 4119 msg.arg1 = aboveSystem ? 1 : 0; 4120 map.put("app", app); 4121 if (activity != null) { 4122 map.put("activity", activity); 4123 } 4124 4125 mHandler.sendMessage(msg); 4126 } 4127 } 4128 4129 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4130 if (!mLaunchWarningShown) { 4131 mLaunchWarningShown = true; 4132 mHandler.post(new Runnable() { 4133 @Override 4134 public void run() { 4135 synchronized (ActivityManagerService.this) { 4136 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4137 d.show(); 4138 mHandler.postDelayed(new Runnable() { 4139 @Override 4140 public void run() { 4141 synchronized (ActivityManagerService.this) { 4142 d.dismiss(); 4143 mLaunchWarningShown = false; 4144 } 4145 } 4146 }, 4000); 4147 } 4148 } 4149 }); 4150 } 4151 } 4152 4153 @Override 4154 public boolean clearApplicationUserData(final String packageName, 4155 final IPackageDataObserver observer, int userId) { 4156 enforceNotIsolatedCaller("clearApplicationUserData"); 4157 int uid = Binder.getCallingUid(); 4158 int pid = Binder.getCallingPid(); 4159 userId = handleIncomingUser(pid, uid, 4160 userId, false, true, "clearApplicationUserData", null); 4161 long callingId = Binder.clearCallingIdentity(); 4162 try { 4163 IPackageManager pm = AppGlobals.getPackageManager(); 4164 int pkgUid = -1; 4165 synchronized(this) { 4166 try { 4167 pkgUid = pm.getPackageUid(packageName, userId); 4168 } catch (RemoteException e) { 4169 } 4170 if (pkgUid == -1) { 4171 Slog.w(TAG, "Invalid packageName: " + packageName); 4172 if (observer != null) { 4173 try { 4174 observer.onRemoveCompleted(packageName, false); 4175 } catch (RemoteException e) { 4176 Slog.i(TAG, "Observer no longer exists."); 4177 } 4178 } 4179 return false; 4180 } 4181 if (uid == pkgUid || checkComponentPermission( 4182 android.Manifest.permission.CLEAR_APP_USER_DATA, 4183 pid, uid, -1, true) 4184 == PackageManager.PERMISSION_GRANTED) { 4185 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4186 } else { 4187 throw new SecurityException("PID " + pid + " does not have permission " 4188 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4189 + " of package " + packageName); 4190 } 4191 } 4192 4193 try { 4194 // Clear application user data 4195 pm.clearApplicationUserData(packageName, observer, userId); 4196 4197 // Remove all permissions granted from/to this package 4198 removeUriPermissionsForPackageLocked(packageName, userId, true); 4199 4200 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4201 Uri.fromParts("package", packageName, null)); 4202 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4203 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4204 null, null, 0, null, null, null, false, false, userId); 4205 } catch (RemoteException e) { 4206 } 4207 } finally { 4208 Binder.restoreCallingIdentity(callingId); 4209 } 4210 return true; 4211 } 4212 4213 @Override 4214 public void killBackgroundProcesses(final String packageName, int userId) { 4215 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4216 != PackageManager.PERMISSION_GRANTED && 4217 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4218 != PackageManager.PERMISSION_GRANTED) { 4219 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4220 + Binder.getCallingPid() 4221 + ", uid=" + Binder.getCallingUid() 4222 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4223 Slog.w(TAG, msg); 4224 throw new SecurityException(msg); 4225 } 4226 4227 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4228 userId, true, true, "killBackgroundProcesses", null); 4229 long callingId = Binder.clearCallingIdentity(); 4230 try { 4231 IPackageManager pm = AppGlobals.getPackageManager(); 4232 synchronized(this) { 4233 int appId = -1; 4234 try { 4235 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4236 } catch (RemoteException e) { 4237 } 4238 if (appId == -1) { 4239 Slog.w(TAG, "Invalid packageName: " + packageName); 4240 return; 4241 } 4242 killPackageProcessesLocked(packageName, appId, userId, 4243 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4244 } 4245 } finally { 4246 Binder.restoreCallingIdentity(callingId); 4247 } 4248 } 4249 4250 @Override 4251 public void killAllBackgroundProcesses() { 4252 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4253 != PackageManager.PERMISSION_GRANTED) { 4254 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4255 + Binder.getCallingPid() 4256 + ", uid=" + Binder.getCallingUid() 4257 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4258 Slog.w(TAG, msg); 4259 throw new SecurityException(msg); 4260 } 4261 4262 long callingId = Binder.clearCallingIdentity(); 4263 try { 4264 synchronized(this) { 4265 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4266 final int NP = mProcessNames.getMap().size(); 4267 for (int ip=0; ip<NP; ip++) { 4268 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4269 final int NA = apps.size(); 4270 for (int ia=0; ia<NA; ia++) { 4271 ProcessRecord app = apps.valueAt(ia); 4272 if (app.persistent) { 4273 // we don't kill persistent processes 4274 continue; 4275 } 4276 if (app.removed) { 4277 procs.add(app); 4278 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4279 app.removed = true; 4280 procs.add(app); 4281 } 4282 } 4283 } 4284 4285 int N = procs.size(); 4286 for (int i=0; i<N; i++) { 4287 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4288 } 4289 mAllowLowerMemLevel = true; 4290 updateOomAdjLocked(); 4291 doLowMemReportIfNeededLocked(null); 4292 } 4293 } finally { 4294 Binder.restoreCallingIdentity(callingId); 4295 } 4296 } 4297 4298 @Override 4299 public void forceStopPackage(final String packageName, int userId) { 4300 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4301 != PackageManager.PERMISSION_GRANTED) { 4302 String msg = "Permission Denial: forceStopPackage() from pid=" 4303 + Binder.getCallingPid() 4304 + ", uid=" + Binder.getCallingUid() 4305 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4306 Slog.w(TAG, msg); 4307 throw new SecurityException(msg); 4308 } 4309 final int callingPid = Binder.getCallingPid(); 4310 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4311 userId, true, true, "forceStopPackage", null); 4312 long callingId = Binder.clearCallingIdentity(); 4313 try { 4314 IPackageManager pm = AppGlobals.getPackageManager(); 4315 synchronized(this) { 4316 int[] users = userId == UserHandle.USER_ALL 4317 ? getUsersLocked() : new int[] { userId }; 4318 for (int user : users) { 4319 int pkgUid = -1; 4320 try { 4321 pkgUid = pm.getPackageUid(packageName, user); 4322 } catch (RemoteException e) { 4323 } 4324 if (pkgUid == -1) { 4325 Slog.w(TAG, "Invalid packageName: " + packageName); 4326 continue; 4327 } 4328 try { 4329 pm.setPackageStoppedState(packageName, true, user); 4330 } catch (RemoteException e) { 4331 } catch (IllegalArgumentException e) { 4332 Slog.w(TAG, "Failed trying to unstop package " 4333 + packageName + ": " + e); 4334 } 4335 if (isUserRunningLocked(user, false)) { 4336 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4337 } 4338 } 4339 } 4340 } finally { 4341 Binder.restoreCallingIdentity(callingId); 4342 } 4343 } 4344 4345 /* 4346 * The pkg name and app id have to be specified. 4347 */ 4348 @Override 4349 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4350 if (pkg == null) { 4351 return; 4352 } 4353 // Make sure the uid is valid. 4354 if (appid < 0) { 4355 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4356 return; 4357 } 4358 int callerUid = Binder.getCallingUid(); 4359 // Only the system server can kill an application 4360 if (callerUid == Process.SYSTEM_UID) { 4361 // Post an aysnc message to kill the application 4362 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4363 msg.arg1 = appid; 4364 msg.arg2 = 0; 4365 Bundle bundle = new Bundle(); 4366 bundle.putString("pkg", pkg); 4367 bundle.putString("reason", reason); 4368 msg.obj = bundle; 4369 mHandler.sendMessage(msg); 4370 } else { 4371 throw new SecurityException(callerUid + " cannot kill pkg: " + 4372 pkg); 4373 } 4374 } 4375 4376 @Override 4377 public void closeSystemDialogs(String reason) { 4378 enforceNotIsolatedCaller("closeSystemDialogs"); 4379 4380 final int pid = Binder.getCallingPid(); 4381 final int uid = Binder.getCallingUid(); 4382 final long origId = Binder.clearCallingIdentity(); 4383 try { 4384 synchronized (this) { 4385 // Only allow this from foreground processes, so that background 4386 // applications can't abuse it to prevent system UI from being shown. 4387 if (uid >= Process.FIRST_APPLICATION_UID) { 4388 ProcessRecord proc; 4389 synchronized (mPidsSelfLocked) { 4390 proc = mPidsSelfLocked.get(pid); 4391 } 4392 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4393 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4394 + " from background process " + proc); 4395 return; 4396 } 4397 } 4398 closeSystemDialogsLocked(reason); 4399 } 4400 } finally { 4401 Binder.restoreCallingIdentity(origId); 4402 } 4403 } 4404 4405 void closeSystemDialogsLocked(String reason) { 4406 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4407 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4408 | Intent.FLAG_RECEIVER_FOREGROUND); 4409 if (reason != null) { 4410 intent.putExtra("reason", reason); 4411 } 4412 mWindowManager.closeSystemDialogs(reason); 4413 4414 mStackSupervisor.closeSystemDialogsLocked(); 4415 4416 broadcastIntentLocked(null, null, intent, null, 4417 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4418 Process.SYSTEM_UID, UserHandle.USER_ALL); 4419 } 4420 4421 @Override 4422 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4423 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4424 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4425 for (int i=pids.length-1; i>=0; i--) { 4426 ProcessRecord proc; 4427 int oomAdj; 4428 synchronized (this) { 4429 synchronized (mPidsSelfLocked) { 4430 proc = mPidsSelfLocked.get(pids[i]); 4431 oomAdj = proc != null ? proc.setAdj : 0; 4432 } 4433 } 4434 infos[i] = new Debug.MemoryInfo(); 4435 Debug.getMemoryInfo(pids[i], infos[i]); 4436 if (proc != null) { 4437 synchronized (this) { 4438 if (proc.thread != null && proc.setAdj == oomAdj) { 4439 // Record this for posterity if the process has been stable. 4440 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4441 infos[i].getTotalUss(), false, proc.pkgList); 4442 } 4443 } 4444 } 4445 } 4446 return infos; 4447 } 4448 4449 @Override 4450 public long[] getProcessPss(int[] pids) { 4451 enforceNotIsolatedCaller("getProcessPss"); 4452 long[] pss = new long[pids.length]; 4453 for (int i=pids.length-1; i>=0; i--) { 4454 ProcessRecord proc; 4455 int oomAdj; 4456 synchronized (this) { 4457 synchronized (mPidsSelfLocked) { 4458 proc = mPidsSelfLocked.get(pids[i]); 4459 oomAdj = proc != null ? proc.setAdj : 0; 4460 } 4461 } 4462 long[] tmpUss = new long[1]; 4463 pss[i] = Debug.getPss(pids[i], tmpUss); 4464 if (proc != null) { 4465 synchronized (this) { 4466 if (proc.thread != null && proc.setAdj == oomAdj) { 4467 // Record this for posterity if the process has been stable. 4468 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4469 } 4470 } 4471 } 4472 } 4473 return pss; 4474 } 4475 4476 @Override 4477 public void killApplicationProcess(String processName, int uid) { 4478 if (processName == null) { 4479 return; 4480 } 4481 4482 int callerUid = Binder.getCallingUid(); 4483 // Only the system server can kill an application 4484 if (callerUid == Process.SYSTEM_UID) { 4485 synchronized (this) { 4486 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4487 if (app != null && app.thread != null) { 4488 try { 4489 app.thread.scheduleSuicide(); 4490 } catch (RemoteException e) { 4491 // If the other end already died, then our work here is done. 4492 } 4493 } else { 4494 Slog.w(TAG, "Process/uid not found attempting kill of " 4495 + processName + " / " + uid); 4496 } 4497 } 4498 } else { 4499 throw new SecurityException(callerUid + " cannot kill app process: " + 4500 processName); 4501 } 4502 } 4503 4504 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4505 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4506 false, true, false, false, UserHandle.getUserId(uid), reason); 4507 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4508 Uri.fromParts("package", packageName, null)); 4509 if (!mProcessesReady) { 4510 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4511 | Intent.FLAG_RECEIVER_FOREGROUND); 4512 } 4513 intent.putExtra(Intent.EXTRA_UID, uid); 4514 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4515 broadcastIntentLocked(null, null, intent, 4516 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4517 false, false, 4518 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4519 } 4520 4521 private void forceStopUserLocked(int userId, String reason) { 4522 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4523 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4524 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4525 | Intent.FLAG_RECEIVER_FOREGROUND); 4526 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4527 broadcastIntentLocked(null, null, intent, 4528 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4529 false, false, 4530 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4531 } 4532 4533 private final boolean killPackageProcessesLocked(String packageName, int appId, 4534 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4535 boolean doit, boolean evenPersistent, String reason) { 4536 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4537 4538 // Remove all processes this package may have touched: all with the 4539 // same UID (except for the system or root user), and all whose name 4540 // matches the package name. 4541 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4542 final int NP = mProcessNames.getMap().size(); 4543 for (int ip=0; ip<NP; ip++) { 4544 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4545 final int NA = apps.size(); 4546 for (int ia=0; ia<NA; ia++) { 4547 ProcessRecord app = apps.valueAt(ia); 4548 if (app.persistent && !evenPersistent) { 4549 // we don't kill persistent processes 4550 continue; 4551 } 4552 if (app.removed) { 4553 if (doit) { 4554 procs.add(app); 4555 } 4556 continue; 4557 } 4558 4559 // Skip process if it doesn't meet our oom adj requirement. 4560 if (app.setAdj < minOomAdj) { 4561 continue; 4562 } 4563 4564 // If no package is specified, we call all processes under the 4565 // give user id. 4566 if (packageName == null) { 4567 if (app.userId != userId) { 4568 continue; 4569 } 4570 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4571 continue; 4572 } 4573 // Package has been specified, we want to hit all processes 4574 // that match it. We need to qualify this by the processes 4575 // that are running under the specified app and user ID. 4576 } else { 4577 if (UserHandle.getAppId(app.uid) != appId) { 4578 continue; 4579 } 4580 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4581 continue; 4582 } 4583 if (!app.pkgList.containsKey(packageName)) { 4584 continue; 4585 } 4586 } 4587 4588 // Process has passed all conditions, kill it! 4589 if (!doit) { 4590 return true; 4591 } 4592 app.removed = true; 4593 procs.add(app); 4594 } 4595 } 4596 4597 int N = procs.size(); 4598 for (int i=0; i<N; i++) { 4599 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4600 } 4601 updateOomAdjLocked(); 4602 return N > 0; 4603 } 4604 4605 private final boolean forceStopPackageLocked(String name, int appId, 4606 boolean callerWillRestart, boolean purgeCache, boolean doit, 4607 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4608 int i; 4609 int N; 4610 4611 if (userId == UserHandle.USER_ALL && name == null) { 4612 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4613 } 4614 4615 if (appId < 0 && name != null) { 4616 try { 4617 appId = UserHandle.getAppId( 4618 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4619 } catch (RemoteException e) { 4620 } 4621 } 4622 4623 if (doit) { 4624 if (name != null) { 4625 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4626 + " user=" + userId + ": " + reason); 4627 } else { 4628 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4629 } 4630 4631 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4632 for (int ip=pmap.size()-1; ip>=0; ip--) { 4633 SparseArray<Long> ba = pmap.valueAt(ip); 4634 for (i=ba.size()-1; i>=0; i--) { 4635 boolean remove = false; 4636 final int entUid = ba.keyAt(i); 4637 if (name != null) { 4638 if (userId == UserHandle.USER_ALL) { 4639 if (UserHandle.getAppId(entUid) == appId) { 4640 remove = true; 4641 } 4642 } else { 4643 if (entUid == UserHandle.getUid(userId, appId)) { 4644 remove = true; 4645 } 4646 } 4647 } else if (UserHandle.getUserId(entUid) == userId) { 4648 remove = true; 4649 } 4650 if (remove) { 4651 ba.removeAt(i); 4652 } 4653 } 4654 if (ba.size() == 0) { 4655 pmap.removeAt(ip); 4656 } 4657 } 4658 } 4659 4660 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4661 -100, callerWillRestart, true, doit, evenPersistent, 4662 name == null ? ("stop user " + userId) : ("stop " + name)); 4663 4664 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4665 if (!doit) { 4666 return true; 4667 } 4668 didSomething = true; 4669 } 4670 4671 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4672 if (!doit) { 4673 return true; 4674 } 4675 didSomething = true; 4676 } 4677 4678 if (name == null) { 4679 // Remove all sticky broadcasts from this user. 4680 mStickyBroadcasts.remove(userId); 4681 } 4682 4683 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4684 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4685 userId, providers)) { 4686 if (!doit) { 4687 return true; 4688 } 4689 didSomething = true; 4690 } 4691 N = providers.size(); 4692 for (i=0; i<N; i++) { 4693 removeDyingProviderLocked(null, providers.get(i), true); 4694 } 4695 4696 // Remove transient permissions granted from/to this package/user 4697 removeUriPermissionsForPackageLocked(name, userId, false); 4698 4699 if (name == null || uninstalling) { 4700 // Remove pending intents. For now we only do this when force 4701 // stopping users, because we have some problems when doing this 4702 // for packages -- app widgets are not currently cleaned up for 4703 // such packages, so they can be left with bad pending intents. 4704 if (mIntentSenderRecords.size() > 0) { 4705 Iterator<WeakReference<PendingIntentRecord>> it 4706 = mIntentSenderRecords.values().iterator(); 4707 while (it.hasNext()) { 4708 WeakReference<PendingIntentRecord> wpir = it.next(); 4709 if (wpir == null) { 4710 it.remove(); 4711 continue; 4712 } 4713 PendingIntentRecord pir = wpir.get(); 4714 if (pir == null) { 4715 it.remove(); 4716 continue; 4717 } 4718 if (name == null) { 4719 // Stopping user, remove all objects for the user. 4720 if (pir.key.userId != userId) { 4721 // Not the same user, skip it. 4722 continue; 4723 } 4724 } else { 4725 if (UserHandle.getAppId(pir.uid) != appId) { 4726 // Different app id, skip it. 4727 continue; 4728 } 4729 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4730 // Different user, skip it. 4731 continue; 4732 } 4733 if (!pir.key.packageName.equals(name)) { 4734 // Different package, skip it. 4735 continue; 4736 } 4737 } 4738 if (!doit) { 4739 return true; 4740 } 4741 didSomething = true; 4742 it.remove(); 4743 pir.canceled = true; 4744 if (pir.key.activity != null) { 4745 pir.key.activity.pendingResults.remove(pir.ref); 4746 } 4747 } 4748 } 4749 } 4750 4751 if (doit) { 4752 if (purgeCache && name != null) { 4753 AttributeCache ac = AttributeCache.instance(); 4754 if (ac != null) { 4755 ac.removePackage(name); 4756 } 4757 } 4758 if (mBooted) { 4759 mStackSupervisor.resumeTopActivitiesLocked(); 4760 mStackSupervisor.scheduleIdleLocked(); 4761 } 4762 } 4763 4764 return didSomething; 4765 } 4766 4767 private final boolean removeProcessLocked(ProcessRecord app, 4768 boolean callerWillRestart, boolean allowRestart, String reason) { 4769 final String name = app.processName; 4770 final int uid = app.uid; 4771 if (DEBUG_PROCESSES) Slog.d( 4772 TAG, "Force removing proc " + app.toShortString() + " (" + name 4773 + "/" + uid + ")"); 4774 4775 mProcessNames.remove(name, uid); 4776 mIsolatedProcesses.remove(app.uid); 4777 if (mHeavyWeightProcess == app) { 4778 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4779 mHeavyWeightProcess.userId, 0)); 4780 mHeavyWeightProcess = null; 4781 } 4782 boolean needRestart = false; 4783 if (app.pid > 0 && app.pid != MY_PID) { 4784 int pid = app.pid; 4785 synchronized (mPidsSelfLocked) { 4786 mPidsSelfLocked.remove(pid); 4787 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4788 } 4789 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4790 app.processName, app.info.uid); 4791 if (app.isolated) { 4792 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4793 } 4794 killUnneededProcessLocked(app, reason); 4795 handleAppDiedLocked(app, true, allowRestart); 4796 removeLruProcessLocked(app); 4797 4798 if (app.persistent && !app.isolated) { 4799 if (!callerWillRestart) { 4800 addAppLocked(app.info, false); 4801 } else { 4802 needRestart = true; 4803 } 4804 } 4805 } else { 4806 mRemovedProcesses.add(app); 4807 } 4808 4809 return needRestart; 4810 } 4811 4812 private final void processStartTimedOutLocked(ProcessRecord app) { 4813 final int pid = app.pid; 4814 boolean gone = false; 4815 synchronized (mPidsSelfLocked) { 4816 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4817 if (knownApp != null && knownApp.thread == null) { 4818 mPidsSelfLocked.remove(pid); 4819 gone = true; 4820 } 4821 } 4822 4823 if (gone) { 4824 Slog.w(TAG, "Process " + app + " failed to attach"); 4825 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4826 pid, app.uid, app.processName); 4827 mProcessNames.remove(app.processName, app.uid); 4828 mIsolatedProcesses.remove(app.uid); 4829 if (mHeavyWeightProcess == app) { 4830 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4831 mHeavyWeightProcess.userId, 0)); 4832 mHeavyWeightProcess = null; 4833 } 4834 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4835 app.processName, app.info.uid); 4836 if (app.isolated) { 4837 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4838 } 4839 // Take care of any launching providers waiting for this process. 4840 checkAppInLaunchingProvidersLocked(app, true); 4841 // Take care of any services that are waiting for the process. 4842 mServices.processStartTimedOutLocked(app); 4843 killUnneededProcessLocked(app, "start timeout"); 4844 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4845 Slog.w(TAG, "Unattached app died before backup, skipping"); 4846 try { 4847 IBackupManager bm = IBackupManager.Stub.asInterface( 4848 ServiceManager.getService(Context.BACKUP_SERVICE)); 4849 bm.agentDisconnected(app.info.packageName); 4850 } catch (RemoteException e) { 4851 // Can't happen; the backup manager is local 4852 } 4853 } 4854 if (isPendingBroadcastProcessLocked(pid)) { 4855 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4856 skipPendingBroadcastLocked(pid); 4857 } 4858 } else { 4859 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4860 } 4861 } 4862 4863 private final boolean attachApplicationLocked(IApplicationThread thread, 4864 int pid) { 4865 4866 // Find the application record that is being attached... either via 4867 // the pid if we are running in multiple processes, or just pull the 4868 // next app record if we are emulating process with anonymous threads. 4869 ProcessRecord app; 4870 if (pid != MY_PID && pid >= 0) { 4871 synchronized (mPidsSelfLocked) { 4872 app = mPidsSelfLocked.get(pid); 4873 } 4874 } else { 4875 app = null; 4876 } 4877 4878 if (app == null) { 4879 Slog.w(TAG, "No pending application record for pid " + pid 4880 + " (IApplicationThread " + thread + "); dropping process"); 4881 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4882 if (pid > 0 && pid != MY_PID) { 4883 Process.killProcessQuiet(pid); 4884 } else { 4885 try { 4886 thread.scheduleExit(); 4887 } catch (Exception e) { 4888 // Ignore exceptions. 4889 } 4890 } 4891 return false; 4892 } 4893 4894 // If this application record is still attached to a previous 4895 // process, clean it up now. 4896 if (app.thread != null) { 4897 handleAppDiedLocked(app, true, true); 4898 } 4899 4900 // Tell the process all about itself. 4901 4902 if (localLOGV) Slog.v( 4903 TAG, "Binding process pid " + pid + " to record " + app); 4904 4905 final String processName = app.processName; 4906 try { 4907 AppDeathRecipient adr = new AppDeathRecipient( 4908 app, pid, thread); 4909 thread.asBinder().linkToDeath(adr, 0); 4910 app.deathRecipient = adr; 4911 } catch (RemoteException e) { 4912 app.resetPackageList(mProcessStats); 4913 startProcessLocked(app, "link fail", processName); 4914 return false; 4915 } 4916 4917 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4918 4919 app.makeActive(thread, mProcessStats); 4920 app.curAdj = app.setAdj = -100; 4921 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4922 app.forcingToForeground = null; 4923 updateProcessForegroundLocked(app, false, false); 4924 app.hasShownUi = false; 4925 app.debugging = false; 4926 app.cached = false; 4927 4928 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4929 4930 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4931 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4932 4933 if (!normalMode) { 4934 Slog.i(TAG, "Launching preboot mode app: " + app); 4935 } 4936 4937 if (localLOGV) Slog.v( 4938 TAG, "New app record " + app 4939 + " thread=" + thread.asBinder() + " pid=" + pid); 4940 try { 4941 int testMode = IApplicationThread.DEBUG_OFF; 4942 if (mDebugApp != null && mDebugApp.equals(processName)) { 4943 testMode = mWaitForDebugger 4944 ? IApplicationThread.DEBUG_WAIT 4945 : IApplicationThread.DEBUG_ON; 4946 app.debugging = true; 4947 if (mDebugTransient) { 4948 mDebugApp = mOrigDebugApp; 4949 mWaitForDebugger = mOrigWaitForDebugger; 4950 } 4951 } 4952 String profileFile = app.instrumentationProfileFile; 4953 ParcelFileDescriptor profileFd = null; 4954 boolean profileAutoStop = false; 4955 if (mProfileApp != null && mProfileApp.equals(processName)) { 4956 mProfileProc = app; 4957 profileFile = mProfileFile; 4958 profileFd = mProfileFd; 4959 profileAutoStop = mAutoStopProfiler; 4960 } 4961 boolean enableOpenGlTrace = false; 4962 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4963 enableOpenGlTrace = true; 4964 mOpenGlTraceApp = null; 4965 } 4966 4967 // If the app is being launched for restore or full backup, set it up specially 4968 boolean isRestrictedBackupMode = false; 4969 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4970 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4971 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4972 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4973 } 4974 4975 ensurePackageDexOpt(app.instrumentationInfo != null 4976 ? app.instrumentationInfo.packageName 4977 : app.info.packageName); 4978 if (app.instrumentationClass != null) { 4979 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4980 } 4981 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4982 + processName + " with config " + mConfiguration); 4983 ApplicationInfo appInfo = app.instrumentationInfo != null 4984 ? app.instrumentationInfo : app.info; 4985 app.compat = compatibilityInfoForPackageLocked(appInfo); 4986 if (profileFd != null) { 4987 profileFd = profileFd.dup(); 4988 } 4989 thread.bindApplication(processName, appInfo, providers, 4990 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4991 app.instrumentationArguments, app.instrumentationWatcher, 4992 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4993 isRestrictedBackupMode || !normalMode, app.persistent, 4994 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4995 mCoreSettingsObserver.getCoreSettingsLocked()); 4996 updateLruProcessLocked(app, false, null); 4997 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4998 } catch (Exception e) { 4999 // todo: Yikes! What should we do? For now we will try to 5000 // start another process, but that could easily get us in 5001 // an infinite loop of restarting processes... 5002 Slog.w(TAG, "Exception thrown during bind!", e); 5003 5004 app.resetPackageList(mProcessStats); 5005 app.unlinkDeathRecipient(); 5006 startProcessLocked(app, "bind fail", processName); 5007 return false; 5008 } 5009 5010 // Remove this record from the list of starting applications. 5011 mPersistentStartingProcesses.remove(app); 5012 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5013 "Attach application locked removing on hold: " + app); 5014 mProcessesOnHold.remove(app); 5015 5016 boolean badApp = false; 5017 boolean didSomething = false; 5018 5019 // See if the top visible activity is waiting to run in this process... 5020 if (normalMode) { 5021 try { 5022 if (mStackSupervisor.attachApplicationLocked(app)) { 5023 didSomething = true; 5024 } 5025 } catch (Exception e) { 5026 badApp = true; 5027 } 5028 } 5029 5030 // Find any services that should be running in this process... 5031 if (!badApp) { 5032 try { 5033 didSomething |= mServices.attachApplicationLocked(app, processName); 5034 } catch (Exception e) { 5035 badApp = true; 5036 } 5037 } 5038 5039 // Check if a next-broadcast receiver is in this process... 5040 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5041 try { 5042 didSomething |= sendPendingBroadcastsLocked(app); 5043 } catch (Exception e) { 5044 // If the app died trying to launch the receiver we declare it 'bad' 5045 badApp = true; 5046 } 5047 } 5048 5049 // Check whether the next backup agent is in this process... 5050 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5051 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5052 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5053 try { 5054 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5055 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5056 mBackupTarget.backupMode); 5057 } catch (Exception e) { 5058 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5059 e.printStackTrace(); 5060 } 5061 } 5062 5063 if (badApp) { 5064 // todo: Also need to kill application to deal with all 5065 // kinds of exceptions. 5066 handleAppDiedLocked(app, false, true); 5067 return false; 5068 } 5069 5070 if (!didSomething) { 5071 updateOomAdjLocked(); 5072 } 5073 5074 return true; 5075 } 5076 5077 @Override 5078 public final void attachApplication(IApplicationThread thread) { 5079 synchronized (this) { 5080 int callingPid = Binder.getCallingPid(); 5081 final long origId = Binder.clearCallingIdentity(); 5082 attachApplicationLocked(thread, callingPid); 5083 Binder.restoreCallingIdentity(origId); 5084 } 5085 } 5086 5087 @Override 5088 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5089 final long origId = Binder.clearCallingIdentity(); 5090 synchronized (this) { 5091 ActivityStack stack = ActivityRecord.getStackLocked(token); 5092 if (stack != null) { 5093 ActivityRecord r = 5094 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5095 if (stopProfiling) { 5096 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5097 try { 5098 mProfileFd.close(); 5099 } catch (IOException e) { 5100 } 5101 clearProfilerLocked(); 5102 } 5103 } 5104 } 5105 } 5106 Binder.restoreCallingIdentity(origId); 5107 } 5108 5109 void enableScreenAfterBoot() { 5110 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5111 SystemClock.uptimeMillis()); 5112 mWindowManager.enableScreenAfterBoot(); 5113 5114 synchronized (this) { 5115 updateEventDispatchingLocked(); 5116 } 5117 } 5118 5119 @Override 5120 public void showBootMessage(final CharSequence msg, final boolean always) { 5121 enforceNotIsolatedCaller("showBootMessage"); 5122 mWindowManager.showBootMessage(msg, always); 5123 } 5124 5125 @Override 5126 public void dismissKeyguardOnNextActivity() { 5127 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5128 final long token = Binder.clearCallingIdentity(); 5129 try { 5130 synchronized (this) { 5131 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5132 if (mLockScreenShown) { 5133 mLockScreenShown = false; 5134 comeOutOfSleepIfNeededLocked(); 5135 } 5136 mStackSupervisor.setDismissKeyguard(true); 5137 } 5138 } finally { 5139 Binder.restoreCallingIdentity(token); 5140 } 5141 } 5142 5143 final void finishBooting() { 5144 IntentFilter pkgFilter = new IntentFilter(); 5145 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5146 pkgFilter.addDataScheme("package"); 5147 mContext.registerReceiver(new BroadcastReceiver() { 5148 @Override 5149 public void onReceive(Context context, Intent intent) { 5150 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5151 if (pkgs != null) { 5152 for (String pkg : pkgs) { 5153 synchronized (ActivityManagerService.this) { 5154 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5155 "finished booting")) { 5156 setResultCode(Activity.RESULT_OK); 5157 return; 5158 } 5159 } 5160 } 5161 } 5162 } 5163 }, pkgFilter); 5164 5165 synchronized (this) { 5166 // Ensure that any processes we had put on hold are now started 5167 // up. 5168 final int NP = mProcessesOnHold.size(); 5169 if (NP > 0) { 5170 ArrayList<ProcessRecord> procs = 5171 new ArrayList<ProcessRecord>(mProcessesOnHold); 5172 for (int ip=0; ip<NP; ip++) { 5173 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5174 + procs.get(ip)); 5175 startProcessLocked(procs.get(ip), "on-hold", null); 5176 } 5177 } 5178 5179 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5180 // Start looking for apps that are abusing wake locks. 5181 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5182 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5183 // Tell anyone interested that we are done booting! 5184 SystemProperties.set("sys.boot_completed", "1"); 5185 SystemProperties.set("dev.bootcomplete", "1"); 5186 for (int i=0; i<mStartedUsers.size(); i++) { 5187 UserStartedState uss = mStartedUsers.valueAt(i); 5188 if (uss.mState == UserStartedState.STATE_BOOTING) { 5189 uss.mState = UserStartedState.STATE_RUNNING; 5190 final int userId = mStartedUsers.keyAt(i); 5191 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5192 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5193 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5194 broadcastIntentLocked(null, null, intent, null, 5195 new IIntentReceiver.Stub() { 5196 @Override 5197 public void performReceive(Intent intent, int resultCode, 5198 String data, Bundle extras, boolean ordered, 5199 boolean sticky, int sendingUser) { 5200 synchronized (ActivityManagerService.this) { 5201 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5202 true, false); 5203 } 5204 } 5205 }, 5206 0, null, null, 5207 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5208 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5209 userId); 5210 } 5211 } 5212 scheduleStartProfilesLocked(); 5213 } 5214 } 5215 } 5216 5217 final void ensureBootCompleted() { 5218 boolean booting; 5219 boolean enableScreen; 5220 synchronized (this) { 5221 booting = mBooting; 5222 mBooting = false; 5223 enableScreen = !mBooted; 5224 mBooted = true; 5225 } 5226 5227 if (booting) { 5228 finishBooting(); 5229 } 5230 5231 if (enableScreen) { 5232 enableScreenAfterBoot(); 5233 } 5234 } 5235 5236 @Override 5237 public final void activityResumed(IBinder token) { 5238 final long origId = Binder.clearCallingIdentity(); 5239 synchronized(this) { 5240 ActivityStack stack = ActivityRecord.getStackLocked(token); 5241 if (stack != null) { 5242 ActivityRecord.activityResumedLocked(token); 5243 } 5244 } 5245 Binder.restoreCallingIdentity(origId); 5246 } 5247 5248 @Override 5249 public final void activityPaused(IBinder token) { 5250 final long origId = Binder.clearCallingIdentity(); 5251 synchronized(this) { 5252 ActivityStack stack = ActivityRecord.getStackLocked(token); 5253 if (stack != null) { 5254 stack.activityPausedLocked(token, false); 5255 } 5256 } 5257 Binder.restoreCallingIdentity(origId); 5258 } 5259 5260 @Override 5261 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5262 CharSequence description) { 5263 if (localLOGV) Slog.v( 5264 TAG, "Activity stopped: token=" + token); 5265 5266 // Refuse possible leaked file descriptors 5267 if (icicle != null && icicle.hasFileDescriptors()) { 5268 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5269 } 5270 5271 ActivityRecord r = null; 5272 5273 final long origId = Binder.clearCallingIdentity(); 5274 5275 synchronized (this) { 5276 r = ActivityRecord.isInStackLocked(token); 5277 if (r != null) { 5278 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5279 } 5280 } 5281 5282 if (r != null) { 5283 sendPendingThumbnail(r, null, null, null, false); 5284 } 5285 5286 trimApplications(); 5287 5288 Binder.restoreCallingIdentity(origId); 5289 } 5290 5291 @Override 5292 public final void activityDestroyed(IBinder token) { 5293 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5294 synchronized (this) { 5295 ActivityStack stack = ActivityRecord.getStackLocked(token); 5296 if (stack != null) { 5297 stack.activityDestroyedLocked(token); 5298 } 5299 } 5300 } 5301 5302 @Override 5303 public String getCallingPackage(IBinder token) { 5304 synchronized (this) { 5305 ActivityRecord r = getCallingRecordLocked(token); 5306 return r != null ? r.info.packageName : null; 5307 } 5308 } 5309 5310 @Override 5311 public ComponentName getCallingActivity(IBinder token) { 5312 synchronized (this) { 5313 ActivityRecord r = getCallingRecordLocked(token); 5314 return r != null ? r.intent.getComponent() : null; 5315 } 5316 } 5317 5318 private ActivityRecord getCallingRecordLocked(IBinder token) { 5319 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5320 if (r == null) { 5321 return null; 5322 } 5323 return r.resultTo; 5324 } 5325 5326 @Override 5327 public ComponentName getActivityClassForToken(IBinder token) { 5328 synchronized(this) { 5329 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5330 if (r == null) { 5331 return null; 5332 } 5333 return r.intent.getComponent(); 5334 } 5335 } 5336 5337 @Override 5338 public String getPackageForToken(IBinder token) { 5339 synchronized(this) { 5340 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5341 if (r == null) { 5342 return null; 5343 } 5344 return r.packageName; 5345 } 5346 } 5347 5348 @Override 5349 public IIntentSender getIntentSender(int type, 5350 String packageName, IBinder token, String resultWho, 5351 int requestCode, Intent[] intents, String[] resolvedTypes, 5352 int flags, Bundle options, int userId) { 5353 enforceNotIsolatedCaller("getIntentSender"); 5354 // Refuse possible leaked file descriptors 5355 if (intents != null) { 5356 if (intents.length < 1) { 5357 throw new IllegalArgumentException("Intents array length must be >= 1"); 5358 } 5359 for (int i=0; i<intents.length; i++) { 5360 Intent intent = intents[i]; 5361 if (intent != null) { 5362 if (intent.hasFileDescriptors()) { 5363 throw new IllegalArgumentException("File descriptors passed in Intent"); 5364 } 5365 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5366 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5367 throw new IllegalArgumentException( 5368 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5369 } 5370 intents[i] = new Intent(intent); 5371 } 5372 } 5373 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5374 throw new IllegalArgumentException( 5375 "Intent array length does not match resolvedTypes length"); 5376 } 5377 } 5378 if (options != null) { 5379 if (options.hasFileDescriptors()) { 5380 throw new IllegalArgumentException("File descriptors passed in options"); 5381 } 5382 } 5383 5384 synchronized(this) { 5385 int callingUid = Binder.getCallingUid(); 5386 int origUserId = userId; 5387 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5388 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5389 "getIntentSender", null); 5390 if (origUserId == UserHandle.USER_CURRENT) { 5391 // We don't want to evaluate this until the pending intent is 5392 // actually executed. However, we do want to always do the 5393 // security checking for it above. 5394 userId = UserHandle.USER_CURRENT; 5395 } 5396 try { 5397 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5398 int uid = AppGlobals.getPackageManager() 5399 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5400 if (!UserHandle.isSameApp(callingUid, uid)) { 5401 String msg = "Permission Denial: getIntentSender() from pid=" 5402 + Binder.getCallingPid() 5403 + ", uid=" + Binder.getCallingUid() 5404 + ", (need uid=" + uid + ")" 5405 + " is not allowed to send as package " + packageName; 5406 Slog.w(TAG, msg); 5407 throw new SecurityException(msg); 5408 } 5409 } 5410 5411 return getIntentSenderLocked(type, packageName, callingUid, userId, 5412 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5413 5414 } catch (RemoteException e) { 5415 throw new SecurityException(e); 5416 } 5417 } 5418 } 5419 5420 IIntentSender getIntentSenderLocked(int type, String packageName, 5421 int callingUid, int userId, IBinder token, String resultWho, 5422 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5423 Bundle options) { 5424 if (DEBUG_MU) 5425 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5426 ActivityRecord activity = null; 5427 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5428 activity = ActivityRecord.isInStackLocked(token); 5429 if (activity == null) { 5430 return null; 5431 } 5432 if (activity.finishing) { 5433 return null; 5434 } 5435 } 5436 5437 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5438 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5439 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5440 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5441 |PendingIntent.FLAG_UPDATE_CURRENT); 5442 5443 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5444 type, packageName, activity, resultWho, 5445 requestCode, intents, resolvedTypes, flags, options, userId); 5446 WeakReference<PendingIntentRecord> ref; 5447 ref = mIntentSenderRecords.get(key); 5448 PendingIntentRecord rec = ref != null ? ref.get() : null; 5449 if (rec != null) { 5450 if (!cancelCurrent) { 5451 if (updateCurrent) { 5452 if (rec.key.requestIntent != null) { 5453 rec.key.requestIntent.replaceExtras(intents != null ? 5454 intents[intents.length - 1] : null); 5455 } 5456 if (intents != null) { 5457 intents[intents.length-1] = rec.key.requestIntent; 5458 rec.key.allIntents = intents; 5459 rec.key.allResolvedTypes = resolvedTypes; 5460 } else { 5461 rec.key.allIntents = null; 5462 rec.key.allResolvedTypes = null; 5463 } 5464 } 5465 return rec; 5466 } 5467 rec.canceled = true; 5468 mIntentSenderRecords.remove(key); 5469 } 5470 if (noCreate) { 5471 return rec; 5472 } 5473 rec = new PendingIntentRecord(this, key, callingUid); 5474 mIntentSenderRecords.put(key, rec.ref); 5475 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5476 if (activity.pendingResults == null) { 5477 activity.pendingResults 5478 = new HashSet<WeakReference<PendingIntentRecord>>(); 5479 } 5480 activity.pendingResults.add(rec.ref); 5481 } 5482 return rec; 5483 } 5484 5485 @Override 5486 public void cancelIntentSender(IIntentSender sender) { 5487 if (!(sender instanceof PendingIntentRecord)) { 5488 return; 5489 } 5490 synchronized(this) { 5491 PendingIntentRecord rec = (PendingIntentRecord)sender; 5492 try { 5493 int uid = AppGlobals.getPackageManager() 5494 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5495 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5496 String msg = "Permission Denial: cancelIntentSender() from pid=" 5497 + Binder.getCallingPid() 5498 + ", uid=" + Binder.getCallingUid() 5499 + " is not allowed to cancel packges " 5500 + rec.key.packageName; 5501 Slog.w(TAG, msg); 5502 throw new SecurityException(msg); 5503 } 5504 } catch (RemoteException e) { 5505 throw new SecurityException(e); 5506 } 5507 cancelIntentSenderLocked(rec, true); 5508 } 5509 } 5510 5511 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5512 rec.canceled = true; 5513 mIntentSenderRecords.remove(rec.key); 5514 if (cleanActivity && rec.key.activity != null) { 5515 rec.key.activity.pendingResults.remove(rec.ref); 5516 } 5517 } 5518 5519 @Override 5520 public String getPackageForIntentSender(IIntentSender pendingResult) { 5521 if (!(pendingResult instanceof PendingIntentRecord)) { 5522 return null; 5523 } 5524 try { 5525 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5526 return res.key.packageName; 5527 } catch (ClassCastException e) { 5528 } 5529 return null; 5530 } 5531 5532 @Override 5533 public int getUidForIntentSender(IIntentSender sender) { 5534 if (sender instanceof PendingIntentRecord) { 5535 try { 5536 PendingIntentRecord res = (PendingIntentRecord)sender; 5537 return res.uid; 5538 } catch (ClassCastException e) { 5539 } 5540 } 5541 return -1; 5542 } 5543 5544 @Override 5545 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5546 if (!(pendingResult instanceof PendingIntentRecord)) { 5547 return false; 5548 } 5549 try { 5550 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5551 if (res.key.allIntents == null) { 5552 return false; 5553 } 5554 for (int i=0; i<res.key.allIntents.length; i++) { 5555 Intent intent = res.key.allIntents[i]; 5556 if (intent.getPackage() != null && intent.getComponent() != null) { 5557 return false; 5558 } 5559 } 5560 return true; 5561 } catch (ClassCastException e) { 5562 } 5563 return false; 5564 } 5565 5566 @Override 5567 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5568 if (!(pendingResult instanceof PendingIntentRecord)) { 5569 return false; 5570 } 5571 try { 5572 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5573 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5574 return true; 5575 } 5576 return false; 5577 } catch (ClassCastException e) { 5578 } 5579 return false; 5580 } 5581 5582 @Override 5583 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5584 if (!(pendingResult instanceof PendingIntentRecord)) { 5585 return null; 5586 } 5587 try { 5588 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5589 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5590 } catch (ClassCastException e) { 5591 } 5592 return null; 5593 } 5594 5595 @Override 5596 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5597 if (!(pendingResult instanceof PendingIntentRecord)) { 5598 return null; 5599 } 5600 try { 5601 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5602 Intent intent = res.key.requestIntent; 5603 if (intent != null) { 5604 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5605 || res.lastTagPrefix.equals(prefix))) { 5606 return res.lastTag; 5607 } 5608 res.lastTagPrefix = prefix; 5609 StringBuilder sb = new StringBuilder(128); 5610 if (prefix != null) { 5611 sb.append(prefix); 5612 } 5613 if (intent.getAction() != null) { 5614 sb.append(intent.getAction()); 5615 } else if (intent.getComponent() != null) { 5616 intent.getComponent().appendShortString(sb); 5617 } else { 5618 sb.append("?"); 5619 } 5620 return res.lastTag = sb.toString(); 5621 } 5622 } catch (ClassCastException e) { 5623 } 5624 return null; 5625 } 5626 5627 @Override 5628 public void setProcessLimit(int max) { 5629 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5630 "setProcessLimit()"); 5631 synchronized (this) { 5632 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5633 mProcessLimitOverride = max; 5634 } 5635 trimApplications(); 5636 } 5637 5638 @Override 5639 public int getProcessLimit() { 5640 synchronized (this) { 5641 return mProcessLimitOverride; 5642 } 5643 } 5644 5645 void foregroundTokenDied(ForegroundToken token) { 5646 synchronized (ActivityManagerService.this) { 5647 synchronized (mPidsSelfLocked) { 5648 ForegroundToken cur 5649 = mForegroundProcesses.get(token.pid); 5650 if (cur != token) { 5651 return; 5652 } 5653 mForegroundProcesses.remove(token.pid); 5654 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5655 if (pr == null) { 5656 return; 5657 } 5658 pr.forcingToForeground = null; 5659 updateProcessForegroundLocked(pr, false, false); 5660 } 5661 updateOomAdjLocked(); 5662 } 5663 } 5664 5665 @Override 5666 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5667 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5668 "setProcessForeground()"); 5669 synchronized(this) { 5670 boolean changed = false; 5671 5672 synchronized (mPidsSelfLocked) { 5673 ProcessRecord pr = mPidsSelfLocked.get(pid); 5674 if (pr == null && isForeground) { 5675 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5676 return; 5677 } 5678 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5679 if (oldToken != null) { 5680 oldToken.token.unlinkToDeath(oldToken, 0); 5681 mForegroundProcesses.remove(pid); 5682 if (pr != null) { 5683 pr.forcingToForeground = null; 5684 } 5685 changed = true; 5686 } 5687 if (isForeground && token != null) { 5688 ForegroundToken newToken = new ForegroundToken() { 5689 @Override 5690 public void binderDied() { 5691 foregroundTokenDied(this); 5692 } 5693 }; 5694 newToken.pid = pid; 5695 newToken.token = token; 5696 try { 5697 token.linkToDeath(newToken, 0); 5698 mForegroundProcesses.put(pid, newToken); 5699 pr.forcingToForeground = token; 5700 changed = true; 5701 } catch (RemoteException e) { 5702 // If the process died while doing this, we will later 5703 // do the cleanup with the process death link. 5704 } 5705 } 5706 } 5707 5708 if (changed) { 5709 updateOomAdjLocked(); 5710 } 5711 } 5712 } 5713 5714 // ========================================================= 5715 // PERMISSIONS 5716 // ========================================================= 5717 5718 static class PermissionController extends IPermissionController.Stub { 5719 ActivityManagerService mActivityManagerService; 5720 PermissionController(ActivityManagerService activityManagerService) { 5721 mActivityManagerService = activityManagerService; 5722 } 5723 5724 @Override 5725 public boolean checkPermission(String permission, int pid, int uid) { 5726 return mActivityManagerService.checkPermission(permission, pid, 5727 uid) == PackageManager.PERMISSION_GRANTED; 5728 } 5729 } 5730 5731 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5732 @Override 5733 public int checkComponentPermission(String permission, int pid, int uid, 5734 int owningUid, boolean exported) { 5735 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5736 owningUid, exported); 5737 } 5738 5739 @Override 5740 public Object getAMSLock() { 5741 return ActivityManagerService.this; 5742 } 5743 } 5744 5745 /** 5746 * This can be called with or without the global lock held. 5747 */ 5748 int checkComponentPermission(String permission, int pid, int uid, 5749 int owningUid, boolean exported) { 5750 // We might be performing an operation on behalf of an indirect binder 5751 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5752 // client identity accordingly before proceeding. 5753 Identity tlsIdentity = sCallerIdentity.get(); 5754 if (tlsIdentity != null) { 5755 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5756 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5757 uid = tlsIdentity.uid; 5758 pid = tlsIdentity.pid; 5759 } 5760 5761 if (pid == MY_PID) { 5762 return PackageManager.PERMISSION_GRANTED; 5763 } 5764 5765 return ActivityManager.checkComponentPermission(permission, uid, 5766 owningUid, exported); 5767 } 5768 5769 /** 5770 * As the only public entry point for permissions checking, this method 5771 * can enforce the semantic that requesting a check on a null global 5772 * permission is automatically denied. (Internally a null permission 5773 * string is used when calling {@link #checkComponentPermission} in cases 5774 * when only uid-based security is needed.) 5775 * 5776 * This can be called with or without the global lock held. 5777 */ 5778 @Override 5779 public int checkPermission(String permission, int pid, int uid) { 5780 if (permission == null) { 5781 return PackageManager.PERMISSION_DENIED; 5782 } 5783 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5784 } 5785 5786 /** 5787 * Binder IPC calls go through the public entry point. 5788 * This can be called with or without the global lock held. 5789 */ 5790 int checkCallingPermission(String permission) { 5791 return checkPermission(permission, 5792 Binder.getCallingPid(), 5793 UserHandle.getAppId(Binder.getCallingUid())); 5794 } 5795 5796 /** 5797 * This can be called with or without the global lock held. 5798 */ 5799 void enforceCallingPermission(String permission, String func) { 5800 if (checkCallingPermission(permission) 5801 == PackageManager.PERMISSION_GRANTED) { 5802 return; 5803 } 5804 5805 String msg = "Permission Denial: " + func + " from pid=" 5806 + Binder.getCallingPid() 5807 + ", uid=" + Binder.getCallingUid() 5808 + " requires " + permission; 5809 Slog.w(TAG, msg); 5810 throw new SecurityException(msg); 5811 } 5812 5813 /** 5814 * Determine if UID is holding permissions required to access {@link Uri} in 5815 * the given {@link ProviderInfo}. Final permission checking is always done 5816 * in {@link ContentProvider}. 5817 */ 5818 private final boolean checkHoldingPermissionsLocked( 5819 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5820 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5821 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5822 5823 if (pi.applicationInfo.uid == uid) { 5824 return true; 5825 } else if (!pi.exported) { 5826 return false; 5827 } 5828 5829 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5830 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5831 try { 5832 // check if target holds top-level <provider> permissions 5833 if (!readMet && pi.readPermission != null 5834 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5835 readMet = true; 5836 } 5837 if (!writeMet && pi.writePermission != null 5838 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5839 writeMet = true; 5840 } 5841 5842 // track if unprotected read/write is allowed; any denied 5843 // <path-permission> below removes this ability 5844 boolean allowDefaultRead = pi.readPermission == null; 5845 boolean allowDefaultWrite = pi.writePermission == null; 5846 5847 // check if target holds any <path-permission> that match uri 5848 final PathPermission[] pps = pi.pathPermissions; 5849 if (pps != null) { 5850 final String path = uri.getPath(); 5851 int i = pps.length; 5852 while (i > 0 && (!readMet || !writeMet)) { 5853 i--; 5854 PathPermission pp = pps[i]; 5855 if (pp.match(path)) { 5856 if (!readMet) { 5857 final String pprperm = pp.getReadPermission(); 5858 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5859 + pprperm + " for " + pp.getPath() 5860 + ": match=" + pp.match(path) 5861 + " check=" + pm.checkUidPermission(pprperm, uid)); 5862 if (pprperm != null) { 5863 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5864 readMet = true; 5865 } else { 5866 allowDefaultRead = false; 5867 } 5868 } 5869 } 5870 if (!writeMet) { 5871 final String ppwperm = pp.getWritePermission(); 5872 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5873 + ppwperm + " for " + pp.getPath() 5874 + ": match=" + pp.match(path) 5875 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5876 if (ppwperm != null) { 5877 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5878 writeMet = true; 5879 } else { 5880 allowDefaultWrite = false; 5881 } 5882 } 5883 } 5884 } 5885 } 5886 } 5887 5888 // grant unprotected <provider> read/write, if not blocked by 5889 // <path-permission> above 5890 if (allowDefaultRead) readMet = true; 5891 if (allowDefaultWrite) writeMet = true; 5892 5893 } catch (RemoteException e) { 5894 return false; 5895 } 5896 5897 return readMet && writeMet; 5898 } 5899 5900 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5901 ProviderInfo pi = null; 5902 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5903 if (cpr != null) { 5904 pi = cpr.info; 5905 } else { 5906 try { 5907 pi = AppGlobals.getPackageManager().resolveContentProvider( 5908 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5909 } catch (RemoteException ex) { 5910 } 5911 } 5912 return pi; 5913 } 5914 5915 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5916 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5917 if (targetUris != null) { 5918 return targetUris.get(uri); 5919 } else { 5920 return null; 5921 } 5922 } 5923 5924 private UriPermission findOrCreateUriPermissionLocked( 5925 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5926 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5927 if (targetUris == null) { 5928 targetUris = Maps.newArrayMap(); 5929 mGrantedUriPermissions.put(targetUid, targetUris); 5930 } 5931 5932 UriPermission perm = targetUris.get(uri); 5933 if (perm == null) { 5934 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5935 targetUris.put(uri, perm); 5936 } 5937 5938 return perm; 5939 } 5940 5941 private final boolean checkUriPermissionLocked( 5942 Uri uri, int uid, int modeFlags, int minStrength) { 5943 // Root gets to do everything. 5944 if (uid == 0) { 5945 return true; 5946 } 5947 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5948 if (perms == null) return false; 5949 UriPermission perm = perms.get(uri); 5950 if (perm == null) return false; 5951 return perm.getStrength(modeFlags) >= minStrength; 5952 } 5953 5954 @Override 5955 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5956 enforceNotIsolatedCaller("checkUriPermission"); 5957 5958 // Another redirected-binder-call permissions check as in 5959 // {@link checkComponentPermission}. 5960 Identity tlsIdentity = sCallerIdentity.get(); 5961 if (tlsIdentity != null) { 5962 uid = tlsIdentity.uid; 5963 pid = tlsIdentity.pid; 5964 } 5965 5966 // Our own process gets to do everything. 5967 if (pid == MY_PID) { 5968 return PackageManager.PERMISSION_GRANTED; 5969 } 5970 synchronized(this) { 5971 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5972 ? PackageManager.PERMISSION_GRANTED 5973 : PackageManager.PERMISSION_DENIED; 5974 } 5975 } 5976 5977 /** 5978 * Check if the targetPkg can be granted permission to access uri by 5979 * the callingUid using the given modeFlags. Throws a security exception 5980 * if callingUid is not allowed to do this. Returns the uid of the target 5981 * if the URI permission grant should be performed; returns -1 if it is not 5982 * needed (for example targetPkg already has permission to access the URI). 5983 * If you already know the uid of the target, you can supply it in 5984 * lastTargetUid else set that to -1. 5985 */ 5986 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5987 Uri uri, int modeFlags, int lastTargetUid) { 5988 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5989 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5990 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5991 if (modeFlags == 0) { 5992 return -1; 5993 } 5994 5995 if (targetPkg != null) { 5996 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5997 "Checking grant " + targetPkg + " permission to " + uri); 5998 } 5999 6000 final IPackageManager pm = AppGlobals.getPackageManager(); 6001 6002 // If this is not a content: uri, we can't do anything with it. 6003 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6004 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6005 "Can't grant URI permission for non-content URI: " + uri); 6006 return -1; 6007 } 6008 6009 final String authority = uri.getAuthority(); 6010 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6011 if (pi == null) { 6012 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6013 return -1; 6014 } 6015 6016 int targetUid = lastTargetUid; 6017 if (targetUid < 0 && targetPkg != null) { 6018 try { 6019 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6020 if (targetUid < 0) { 6021 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6022 "Can't grant URI permission no uid for: " + targetPkg); 6023 return -1; 6024 } 6025 } catch (RemoteException ex) { 6026 return -1; 6027 } 6028 } 6029 6030 if (targetUid >= 0) { 6031 // First... does the target actually need this permission? 6032 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6033 // No need to grant the target this permission. 6034 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6035 "Target " + targetPkg + " already has full permission to " + uri); 6036 return -1; 6037 } 6038 } else { 6039 // First... there is no target package, so can anyone access it? 6040 boolean allowed = pi.exported; 6041 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6042 if (pi.readPermission != null) { 6043 allowed = false; 6044 } 6045 } 6046 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6047 if (pi.writePermission != null) { 6048 allowed = false; 6049 } 6050 } 6051 if (allowed) { 6052 return -1; 6053 } 6054 } 6055 6056 // Second... is the provider allowing granting of URI permissions? 6057 if (!pi.grantUriPermissions) { 6058 throw new SecurityException("Provider " + pi.packageName 6059 + "/" + pi.name 6060 + " does not allow granting of Uri permissions (uri " 6061 + uri + ")"); 6062 } 6063 if (pi.uriPermissionPatterns != null) { 6064 final int N = pi.uriPermissionPatterns.length; 6065 boolean allowed = false; 6066 for (int i=0; i<N; i++) { 6067 if (pi.uriPermissionPatterns[i] != null 6068 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6069 allowed = true; 6070 break; 6071 } 6072 } 6073 if (!allowed) { 6074 throw new SecurityException("Provider " + pi.packageName 6075 + "/" + pi.name 6076 + " does not allow granting of permission to path of Uri " 6077 + uri); 6078 } 6079 } 6080 6081 // Third... does the caller itself have permission to access 6082 // this uri? 6083 if (callingUid != Process.myUid()) { 6084 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6085 // Require they hold a strong enough Uri permission 6086 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6087 : UriPermission.STRENGTH_OWNED; 6088 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6089 throw new SecurityException("Uid " + callingUid 6090 + " does not have permission to uri " + uri); 6091 } 6092 } 6093 } 6094 6095 return targetUid; 6096 } 6097 6098 @Override 6099 public int checkGrantUriPermission(int callingUid, String targetPkg, 6100 Uri uri, int modeFlags) { 6101 enforceNotIsolatedCaller("checkGrantUriPermission"); 6102 synchronized(this) { 6103 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6104 } 6105 } 6106 6107 void grantUriPermissionUncheckedLocked( 6108 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6109 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6110 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6111 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6112 if (modeFlags == 0) { 6113 return; 6114 } 6115 6116 // So here we are: the caller has the assumed permission 6117 // to the uri, and the target doesn't. Let's now give this to 6118 // the target. 6119 6120 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6121 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6122 6123 final String authority = uri.getAuthority(); 6124 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6125 if (pi == null) { 6126 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6127 return; 6128 } 6129 6130 final UriPermission perm = findOrCreateUriPermissionLocked( 6131 pi.packageName, targetPkg, targetUid, uri); 6132 perm.grantModes(modeFlags, persistable, owner); 6133 } 6134 6135 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6136 int modeFlags, UriPermissionOwner owner) { 6137 if (targetPkg == null) { 6138 throw new NullPointerException("targetPkg"); 6139 } 6140 6141 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6142 if (targetUid < 0) { 6143 return; 6144 } 6145 6146 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6147 } 6148 6149 static class NeededUriGrants extends ArrayList<Uri> { 6150 final String targetPkg; 6151 final int targetUid; 6152 final int flags; 6153 6154 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6155 this.targetPkg = targetPkg; 6156 this.targetUid = targetUid; 6157 this.flags = flags; 6158 } 6159 } 6160 6161 /** 6162 * Like checkGrantUriPermissionLocked, but takes an Intent. 6163 */ 6164 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6165 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6166 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6167 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6168 + " clip=" + (intent != null ? intent.getClipData() : null) 6169 + " from " + intent + "; flags=0x" 6170 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6171 6172 if (targetPkg == null) { 6173 throw new NullPointerException("targetPkg"); 6174 } 6175 6176 if (intent == null) { 6177 return null; 6178 } 6179 Uri data = intent.getData(); 6180 ClipData clip = intent.getClipData(); 6181 if (data == null && clip == null) { 6182 return null; 6183 } 6184 6185 if (data != null) { 6186 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6187 mode, needed != null ? needed.targetUid : -1); 6188 if (targetUid > 0) { 6189 if (needed == null) { 6190 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6191 } 6192 needed.add(data); 6193 } 6194 } 6195 if (clip != null) { 6196 for (int i=0; i<clip.getItemCount(); i++) { 6197 Uri uri = clip.getItemAt(i).getUri(); 6198 if (uri != null) { 6199 int targetUid = -1; 6200 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6201 mode, needed != null ? needed.targetUid : -1); 6202 if (targetUid > 0) { 6203 if (needed == null) { 6204 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6205 } 6206 needed.add(uri); 6207 } 6208 } else { 6209 Intent clipIntent = clip.getItemAt(i).getIntent(); 6210 if (clipIntent != null) { 6211 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6212 callingUid, targetPkg, clipIntent, mode, needed); 6213 if (newNeeded != null) { 6214 needed = newNeeded; 6215 } 6216 } 6217 } 6218 } 6219 } 6220 6221 return needed; 6222 } 6223 6224 /** 6225 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6226 */ 6227 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6228 UriPermissionOwner owner) { 6229 if (needed != null) { 6230 for (int i=0; i<needed.size(); i++) { 6231 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6232 needed.get(i), needed.flags, owner); 6233 } 6234 } 6235 } 6236 6237 void grantUriPermissionFromIntentLocked(int callingUid, 6238 String targetPkg, Intent intent, UriPermissionOwner owner) { 6239 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6240 intent, intent != null ? intent.getFlags() : 0, null); 6241 if (needed == null) { 6242 return; 6243 } 6244 6245 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6246 } 6247 6248 @Override 6249 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6250 Uri uri, int modeFlags) { 6251 enforceNotIsolatedCaller("grantUriPermission"); 6252 synchronized(this) { 6253 final ProcessRecord r = getRecordForAppLocked(caller); 6254 if (r == null) { 6255 throw new SecurityException("Unable to find app for caller " 6256 + caller 6257 + " when granting permission to uri " + uri); 6258 } 6259 if (targetPkg == null) { 6260 throw new IllegalArgumentException("null target"); 6261 } 6262 if (uri == null) { 6263 throw new IllegalArgumentException("null uri"); 6264 } 6265 6266 // Persistable only supported through Intents 6267 Preconditions.checkFlagsArgument(modeFlags, 6268 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6269 6270 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6271 null); 6272 } 6273 } 6274 6275 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6276 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6277 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6278 ArrayMap<Uri, UriPermission> perms 6279 = mGrantedUriPermissions.get(perm.targetUid); 6280 if (perms != null) { 6281 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6282 "Removing " + perm.targetUid + " permission to " + perm.uri); 6283 perms.remove(perm.uri); 6284 if (perms.size() == 0) { 6285 mGrantedUriPermissions.remove(perm.targetUid); 6286 } 6287 } 6288 } 6289 } 6290 6291 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6292 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6293 6294 final IPackageManager pm = AppGlobals.getPackageManager(); 6295 final String authority = uri.getAuthority(); 6296 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6297 if (pi == null) { 6298 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6299 return; 6300 } 6301 6302 // Does the caller have this permission on the URI? 6303 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6304 // Right now, if you are not the original owner of the permission, 6305 // you are not allowed to revoke it. 6306 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6307 throw new SecurityException("Uid " + callingUid 6308 + " does not have permission to uri " + uri); 6309 //} 6310 } 6311 6312 boolean persistChanged = false; 6313 6314 // Go through all of the permissions and remove any that match. 6315 final List<String> SEGMENTS = uri.getPathSegments(); 6316 if (SEGMENTS != null) { 6317 final int NS = SEGMENTS.size(); 6318 int N = mGrantedUriPermissions.size(); 6319 for (int i=0; i<N; i++) { 6320 ArrayMap<Uri, UriPermission> perms 6321 = mGrantedUriPermissions.valueAt(i); 6322 Iterator<UriPermission> it = perms.values().iterator(); 6323 toploop: 6324 while (it.hasNext()) { 6325 UriPermission perm = it.next(); 6326 Uri targetUri = perm.uri; 6327 if (!authority.equals(targetUri.getAuthority())) { 6328 continue; 6329 } 6330 List<String> targetSegments = targetUri.getPathSegments(); 6331 if (targetSegments == null) { 6332 continue; 6333 } 6334 if (targetSegments.size() < NS) { 6335 continue; 6336 } 6337 for (int j=0; j<NS; j++) { 6338 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6339 continue toploop; 6340 } 6341 } 6342 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6343 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6344 persistChanged |= perm.clearModes(modeFlags, true); 6345 if (perm.modeFlags == 0) { 6346 it.remove(); 6347 } 6348 } 6349 if (perms.size() == 0) { 6350 mGrantedUriPermissions.remove( 6351 mGrantedUriPermissions.keyAt(i)); 6352 N--; 6353 i--; 6354 } 6355 } 6356 } 6357 6358 if (persistChanged) { 6359 schedulePersistUriGrants(); 6360 } 6361 } 6362 6363 @Override 6364 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6365 int modeFlags) { 6366 enforceNotIsolatedCaller("revokeUriPermission"); 6367 synchronized(this) { 6368 final ProcessRecord r = getRecordForAppLocked(caller); 6369 if (r == null) { 6370 throw new SecurityException("Unable to find app for caller " 6371 + caller 6372 + " when revoking permission to uri " + uri); 6373 } 6374 if (uri == null) { 6375 Slog.w(TAG, "revokeUriPermission: null uri"); 6376 return; 6377 } 6378 6379 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6380 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6381 if (modeFlags == 0) { 6382 return; 6383 } 6384 6385 final IPackageManager pm = AppGlobals.getPackageManager(); 6386 final String authority = uri.getAuthority(); 6387 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6388 if (pi == null) { 6389 Slog.w(TAG, "No content provider found for permission revoke: " 6390 + uri.toSafeString()); 6391 return; 6392 } 6393 6394 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6395 } 6396 } 6397 6398 /** 6399 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6400 * given package. 6401 * 6402 * @param packageName Package name to match, or {@code null} to apply to all 6403 * packages. 6404 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6405 * to all users. 6406 * @param persistable If persistable grants should be removed. 6407 */ 6408 private void removeUriPermissionsForPackageLocked( 6409 String packageName, int userHandle, boolean persistable) { 6410 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6411 throw new IllegalArgumentException("Must narrow by either package or user"); 6412 } 6413 6414 boolean persistChanged = false; 6415 6416 final int size = mGrantedUriPermissions.size(); 6417 for (int i = 0; i < size; i++) { 6418 // Only inspect grants matching user 6419 if (userHandle == UserHandle.USER_ALL 6420 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6421 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6422 .values().iterator(); 6423 while (it.hasNext()) { 6424 final UriPermission perm = it.next(); 6425 6426 // Only inspect grants matching package 6427 if (packageName == null || perm.sourcePkg.equals(packageName) 6428 || perm.targetPkg.equals(packageName)) { 6429 persistChanged |= perm.clearModes(~0, persistable); 6430 6431 // Only remove when no modes remain; any persisted grants 6432 // will keep this alive. 6433 if (perm.modeFlags == 0) { 6434 it.remove(); 6435 } 6436 } 6437 } 6438 } 6439 } 6440 6441 if (persistChanged) { 6442 schedulePersistUriGrants(); 6443 } 6444 } 6445 6446 @Override 6447 public IBinder newUriPermissionOwner(String name) { 6448 enforceNotIsolatedCaller("newUriPermissionOwner"); 6449 synchronized(this) { 6450 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6451 return owner.getExternalTokenLocked(); 6452 } 6453 } 6454 6455 @Override 6456 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6457 Uri uri, int modeFlags) { 6458 synchronized(this) { 6459 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6460 if (owner == null) { 6461 throw new IllegalArgumentException("Unknown owner: " + token); 6462 } 6463 if (fromUid != Binder.getCallingUid()) { 6464 if (Binder.getCallingUid() != Process.myUid()) { 6465 // Only system code can grant URI permissions on behalf 6466 // of other users. 6467 throw new SecurityException("nice try"); 6468 } 6469 } 6470 if (targetPkg == null) { 6471 throw new IllegalArgumentException("null target"); 6472 } 6473 if (uri == null) { 6474 throw new IllegalArgumentException("null uri"); 6475 } 6476 6477 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6478 } 6479 } 6480 6481 @Override 6482 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6483 synchronized(this) { 6484 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6485 if (owner == null) { 6486 throw new IllegalArgumentException("Unknown owner: " + token); 6487 } 6488 6489 if (uri == null) { 6490 owner.removeUriPermissionsLocked(mode); 6491 } else { 6492 owner.removeUriPermissionLocked(uri, mode); 6493 } 6494 } 6495 } 6496 6497 private void schedulePersistUriGrants() { 6498 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6499 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6500 10 * DateUtils.SECOND_IN_MILLIS); 6501 } 6502 } 6503 6504 private void writeGrantedUriPermissions() { 6505 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6506 6507 // Snapshot permissions so we can persist without lock 6508 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6509 synchronized (this) { 6510 final int size = mGrantedUriPermissions.size(); 6511 for (int i = 0 ; i < size; i++) { 6512 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6513 if (perm.persistedModeFlags != 0) { 6514 persist.add(perm.snapshot()); 6515 } 6516 } 6517 } 6518 } 6519 6520 FileOutputStream fos = null; 6521 try { 6522 fos = mGrantFile.startWrite(); 6523 6524 XmlSerializer out = new FastXmlSerializer(); 6525 out.setOutput(fos, "utf-8"); 6526 out.startDocument(null, true); 6527 out.startTag(null, TAG_URI_GRANTS); 6528 for (UriPermission.Snapshot perm : persist) { 6529 out.startTag(null, TAG_URI_GRANT); 6530 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6531 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6532 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6533 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6534 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6535 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6536 out.endTag(null, TAG_URI_GRANT); 6537 } 6538 out.endTag(null, TAG_URI_GRANTS); 6539 out.endDocument(); 6540 6541 mGrantFile.finishWrite(fos); 6542 } catch (IOException e) { 6543 if (fos != null) { 6544 mGrantFile.failWrite(fos); 6545 } 6546 } 6547 } 6548 6549 private void readGrantedUriPermissionsLocked() { 6550 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6551 6552 final long now = System.currentTimeMillis(); 6553 6554 FileInputStream fis = null; 6555 try { 6556 fis = mGrantFile.openRead(); 6557 final XmlPullParser in = Xml.newPullParser(); 6558 in.setInput(fis, null); 6559 6560 int type; 6561 while ((type = in.next()) != END_DOCUMENT) { 6562 final String tag = in.getName(); 6563 if (type == START_TAG) { 6564 if (TAG_URI_GRANT.equals(tag)) { 6565 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6566 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6567 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6568 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6569 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6570 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6571 6572 // Sanity check that provider still belongs to source package 6573 final ProviderInfo pi = getProviderInfoLocked( 6574 uri.getAuthority(), userHandle); 6575 if (pi != null && sourcePkg.equals(pi.packageName)) { 6576 int targetUid = -1; 6577 try { 6578 targetUid = AppGlobals.getPackageManager() 6579 .getPackageUid(targetPkg, userHandle); 6580 } catch (RemoteException e) { 6581 } 6582 if (targetUid != -1) { 6583 final UriPermission perm = findOrCreateUriPermissionLocked( 6584 sourcePkg, targetPkg, targetUid, uri); 6585 perm.initPersistedModes(modeFlags, createdTime); 6586 } 6587 } else { 6588 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6589 + " but instead found " + pi); 6590 } 6591 } 6592 } 6593 } 6594 } catch (FileNotFoundException e) { 6595 // Missing grants is okay 6596 } catch (IOException e) { 6597 Log.wtf(TAG, "Failed reading Uri grants", e); 6598 } catch (XmlPullParserException e) { 6599 Log.wtf(TAG, "Failed reading Uri grants", e); 6600 } finally { 6601 IoUtils.closeQuietly(fis); 6602 } 6603 } 6604 6605 @Override 6606 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6607 enforceNotIsolatedCaller("takePersistableUriPermission"); 6608 6609 Preconditions.checkFlagsArgument(modeFlags, 6610 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6611 6612 synchronized (this) { 6613 final int callingUid = Binder.getCallingUid(); 6614 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6615 if (perm == null) { 6616 throw new SecurityException("No permission grant found for UID " + callingUid 6617 + " and Uri " + uri.toSafeString()); 6618 } 6619 6620 boolean persistChanged = perm.takePersistableModes(modeFlags); 6621 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6622 6623 if (persistChanged) { 6624 schedulePersistUriGrants(); 6625 } 6626 } 6627 } 6628 6629 @Override 6630 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6631 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6632 6633 Preconditions.checkFlagsArgument(modeFlags, 6634 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6635 6636 synchronized (this) { 6637 final int callingUid = Binder.getCallingUid(); 6638 6639 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6640 if (perm == null) { 6641 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6642 + uri.toSafeString()); 6643 return; 6644 } 6645 6646 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6647 removeUriPermissionIfNeededLocked(perm); 6648 if (persistChanged) { 6649 schedulePersistUriGrants(); 6650 } 6651 } 6652 } 6653 6654 /** 6655 * Prune any older {@link UriPermission} for the given UID until outstanding 6656 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6657 * 6658 * @return if any mutations occured that require persisting. 6659 */ 6660 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6661 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6662 if (perms == null) return false; 6663 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6664 6665 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6666 for (UriPermission perm : perms.values()) { 6667 if (perm.persistedModeFlags != 0) { 6668 persisted.add(perm); 6669 } 6670 } 6671 6672 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6673 if (trimCount <= 0) return false; 6674 6675 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6676 for (int i = 0; i < trimCount; i++) { 6677 final UriPermission perm = persisted.get(i); 6678 6679 if (DEBUG_URI_PERMISSION) { 6680 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6681 } 6682 6683 perm.releasePersistableModes(~0); 6684 removeUriPermissionIfNeededLocked(perm); 6685 } 6686 6687 return true; 6688 } 6689 6690 @Override 6691 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6692 String packageName, boolean incoming) { 6693 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6694 Preconditions.checkNotNull(packageName, "packageName"); 6695 6696 final int callingUid = Binder.getCallingUid(); 6697 final IPackageManager pm = AppGlobals.getPackageManager(); 6698 try { 6699 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6700 if (packageUid != callingUid) { 6701 throw new SecurityException( 6702 "Package " + packageName + " does not belong to calling UID " + callingUid); 6703 } 6704 } catch (RemoteException e) { 6705 throw new SecurityException("Failed to verify package name ownership"); 6706 } 6707 6708 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6709 synchronized (this) { 6710 if (incoming) { 6711 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6712 if (perms == null) { 6713 Slog.w(TAG, "No permission grants found for " + packageName); 6714 } else { 6715 final int size = perms.size(); 6716 for (int i = 0; i < size; i++) { 6717 final UriPermission perm = perms.valueAt(i); 6718 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6719 result.add(perm.buildPersistedPublicApiObject()); 6720 } 6721 } 6722 } 6723 } else { 6724 final int size = mGrantedUriPermissions.size(); 6725 for (int i = 0; i < size; i++) { 6726 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6727 final int permsSize = perms.size(); 6728 for (int j = 0; j < permsSize; j++) { 6729 final UriPermission perm = perms.valueAt(j); 6730 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6731 result.add(perm.buildPersistedPublicApiObject()); 6732 } 6733 } 6734 } 6735 } 6736 } 6737 return new ParceledListSlice<android.content.UriPermission>(result); 6738 } 6739 6740 @Override 6741 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6742 synchronized (this) { 6743 ProcessRecord app = 6744 who != null ? getRecordForAppLocked(who) : null; 6745 if (app == null) return; 6746 6747 Message msg = Message.obtain(); 6748 msg.what = WAIT_FOR_DEBUGGER_MSG; 6749 msg.obj = app; 6750 msg.arg1 = waiting ? 1 : 0; 6751 mHandler.sendMessage(msg); 6752 } 6753 } 6754 6755 @Override 6756 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6757 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6758 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6759 outInfo.availMem = Process.getFreeMemory(); 6760 outInfo.totalMem = Process.getTotalMemory(); 6761 outInfo.threshold = homeAppMem; 6762 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6763 outInfo.hiddenAppThreshold = cachedAppMem; 6764 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6765 ProcessList.SERVICE_ADJ); 6766 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6767 ProcessList.VISIBLE_APP_ADJ); 6768 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6769 ProcessList.FOREGROUND_APP_ADJ); 6770 } 6771 6772 // ========================================================= 6773 // TASK MANAGEMENT 6774 // ========================================================= 6775 6776 @Override 6777 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6778 IThumbnailReceiver receiver) { 6779 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6780 6781 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6782 ActivityRecord topRecord = null; 6783 6784 synchronized(this) { 6785 if (localLOGV) Slog.v( 6786 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6787 + ", receiver=" + receiver); 6788 6789 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6790 != PackageManager.PERMISSION_GRANTED) { 6791 if (receiver != null) { 6792 // If the caller wants to wait for pending thumbnails, 6793 // it ain't gonna get them. 6794 try { 6795 receiver.finished(); 6796 } catch (RemoteException ex) { 6797 } 6798 } 6799 String msg = "Permission Denial: getTasks() from pid=" 6800 + Binder.getCallingPid() 6801 + ", uid=" + Binder.getCallingUid() 6802 + " requires " + android.Manifest.permission.GET_TASKS; 6803 Slog.w(TAG, msg); 6804 throw new SecurityException(msg); 6805 } 6806 6807 // TODO: Improve with MRU list from all ActivityStacks. 6808 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6809 6810 if (!pending.pendingRecords.isEmpty()) { 6811 mPendingThumbnails.add(pending); 6812 } 6813 } 6814 6815 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6816 6817 if (topRecord != null) { 6818 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6819 try { 6820 IApplicationThread topThumbnail = topRecord.app.thread; 6821 topThumbnail.requestThumbnail(topRecord.appToken); 6822 } catch (Exception e) { 6823 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6824 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6825 } 6826 } 6827 6828 if (pending.pendingRecords.isEmpty() && receiver != null) { 6829 // In this case all thumbnails were available and the client 6830 // is being asked to be told when the remaining ones come in... 6831 // which is unusually, since the top-most currently running 6832 // activity should never have a canned thumbnail! Oh well. 6833 try { 6834 receiver.finished(); 6835 } catch (RemoteException ex) { 6836 } 6837 } 6838 6839 return list; 6840 } 6841 6842 TaskRecord getMostRecentTask() { 6843 return mRecentTasks.get(0); 6844 } 6845 6846 @Override 6847 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6848 int flags, int userId) { 6849 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6850 false, true, "getRecentTasks", null); 6851 6852 synchronized (this) { 6853 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6854 "getRecentTasks()"); 6855 final boolean detailed = checkCallingPermission( 6856 android.Manifest.permission.GET_DETAILED_TASKS) 6857 == PackageManager.PERMISSION_GRANTED; 6858 6859 IPackageManager pm = AppGlobals.getPackageManager(); 6860 6861 final int N = mRecentTasks.size(); 6862 ArrayList<ActivityManager.RecentTaskInfo> res 6863 = new ArrayList<ActivityManager.RecentTaskInfo>( 6864 maxNum < N ? maxNum : N); 6865 6866 final Set<Integer> includedUsers; 6867 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 6868 includedUsers = getProfileIdsLocked(userId); 6869 } else { 6870 includedUsers = new HashSet<Integer>(); 6871 } 6872 includedUsers.add(Integer.valueOf(userId)); 6873 for (int i=0; i<N && maxNum > 0; i++) { 6874 TaskRecord tr = mRecentTasks.get(i); 6875 // Only add calling user or related users recent tasks 6876 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 6877 6878 // Return the entry if desired by the caller. We always return 6879 // the first entry, because callers always expect this to be the 6880 // foreground app. We may filter others if the caller has 6881 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6882 // we should exclude the entry. 6883 6884 if (i == 0 6885 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6886 || (tr.intent == null) 6887 || ((tr.intent.getFlags() 6888 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6889 ActivityManager.RecentTaskInfo rti 6890 = new ActivityManager.RecentTaskInfo(); 6891 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6892 rti.persistentId = tr.taskId; 6893 rti.baseIntent = new Intent( 6894 tr.intent != null ? tr.intent : tr.affinityIntent); 6895 if (!detailed) { 6896 rti.baseIntent.replaceExtras((Bundle)null); 6897 } 6898 rti.origActivity = tr.origActivity; 6899 rti.description = tr.lastDescription; 6900 rti.stackId = tr.stack.mStackId; 6901 rti.userId = tr.userId; 6902 6903 final ArrayList<ActivityRecord> activities = tr.mActivities; 6904 int numSet = 0; 6905 for (int activityNdx = activities.size() - 1; activityNdx >= 0 && numSet < 2; 6906 --activityNdx) { 6907 final ActivityRecord r = activities.get(activityNdx); 6908 if (rti.activityLabel == null && r.recentsLabel != null) { 6909 rti.activityLabel = r.recentsLabel; 6910 ++numSet; 6911 } 6912 if (rti.activityIcon == null && r.recentsIcon != null) { 6913 rti.activityIcon = r.recentsIcon; 6914 ++numSet; 6915 } 6916 } 6917 6918 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6919 // Check whether this activity is currently available. 6920 try { 6921 if (rti.origActivity != null) { 6922 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6923 == null) { 6924 continue; 6925 } 6926 } else if (rti.baseIntent != null) { 6927 if (pm.queryIntentActivities(rti.baseIntent, 6928 null, 0, userId) == null) { 6929 continue; 6930 } 6931 } 6932 } catch (RemoteException e) { 6933 // Will never happen. 6934 } 6935 } 6936 6937 res.add(rti); 6938 maxNum--; 6939 } 6940 } 6941 return res; 6942 } 6943 } 6944 6945 private TaskRecord recentTaskForIdLocked(int id) { 6946 final int N = mRecentTasks.size(); 6947 for (int i=0; i<N; i++) { 6948 TaskRecord tr = mRecentTasks.get(i); 6949 if (tr.taskId == id) { 6950 return tr; 6951 } 6952 } 6953 return null; 6954 } 6955 6956 @Override 6957 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6958 synchronized (this) { 6959 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6960 "getTaskThumbnails()"); 6961 TaskRecord tr = recentTaskForIdLocked(id); 6962 if (tr != null) { 6963 return tr.getTaskThumbnailsLocked(); 6964 } 6965 } 6966 return null; 6967 } 6968 6969 @Override 6970 public Bitmap getTaskTopThumbnail(int id) { 6971 synchronized (this) { 6972 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6973 "getTaskTopThumbnail()"); 6974 TaskRecord tr = recentTaskForIdLocked(id); 6975 if (tr != null) { 6976 return tr.getTaskTopThumbnailLocked(); 6977 } 6978 } 6979 return null; 6980 } 6981 6982 @Override 6983 public void setRecentsLabel(IBinder token, CharSequence recentsLabel) { 6984 synchronized (this) { 6985 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6986 if (r != null) { 6987 r.recentsLabel = recentsLabel.toString(); 6988 } 6989 } 6990 } 6991 6992 @Override 6993 public void setRecentsIcon(IBinder token, Bitmap recentsIcon) { 6994 synchronized (this) { 6995 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6996 if (r != null) { 6997 r.recentsIcon = recentsIcon; 6998 } 6999 } 7000 } 7001 7002 @Override 7003 public boolean removeSubTask(int taskId, int subTaskIndex) { 7004 synchronized (this) { 7005 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7006 "removeSubTask()"); 7007 long ident = Binder.clearCallingIdentity(); 7008 try { 7009 TaskRecord tr = recentTaskForIdLocked(taskId); 7010 if (tr != null) { 7011 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7012 } 7013 return false; 7014 } finally { 7015 Binder.restoreCallingIdentity(ident); 7016 } 7017 } 7018 } 7019 7020 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7021 if (!pr.killedByAm) { 7022 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7023 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7024 pr.processName, pr.setAdj, reason); 7025 pr.killedByAm = true; 7026 Process.killProcessQuiet(pr.pid); 7027 } 7028 } 7029 7030 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7031 tr.disposeThumbnail(); 7032 mRecentTasks.remove(tr); 7033 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7034 Intent baseIntent = new Intent( 7035 tr.intent != null ? tr.intent : tr.affinityIntent); 7036 ComponentName component = baseIntent.getComponent(); 7037 if (component == null) { 7038 Slog.w(TAG, "Now component for base intent of task: " + tr); 7039 return; 7040 } 7041 7042 // Find any running services associated with this app. 7043 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7044 7045 if (killProcesses) { 7046 // Find any running processes associated with this app. 7047 final String pkg = component.getPackageName(); 7048 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7049 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7050 for (int i=0; i<pmap.size(); i++) { 7051 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7052 for (int j=0; j<uids.size(); j++) { 7053 ProcessRecord proc = uids.valueAt(j); 7054 if (proc.userId != tr.userId) { 7055 continue; 7056 } 7057 if (!proc.pkgList.containsKey(pkg)) { 7058 continue; 7059 } 7060 procs.add(proc); 7061 } 7062 } 7063 7064 // Kill the running processes. 7065 for (int i=0; i<procs.size(); i++) { 7066 ProcessRecord pr = procs.get(i); 7067 if (pr == mHomeProcess) { 7068 // Don't kill the home process along with tasks from the same package. 7069 continue; 7070 } 7071 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7072 killUnneededProcessLocked(pr, "remove task"); 7073 } else { 7074 pr.waitingToKill = "remove task"; 7075 } 7076 } 7077 } 7078 } 7079 7080 @Override 7081 public boolean removeTask(int taskId, int flags) { 7082 synchronized (this) { 7083 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7084 "removeTask()"); 7085 long ident = Binder.clearCallingIdentity(); 7086 try { 7087 TaskRecord tr = recentTaskForIdLocked(taskId); 7088 if (tr != null) { 7089 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7090 if (r != null) { 7091 cleanUpRemovedTaskLocked(tr, flags); 7092 return true; 7093 } 7094 if (tr.mActivities.size() == 0) { 7095 // Caller is just removing a recent task that is 7096 // not actively running. That is easy! 7097 cleanUpRemovedTaskLocked(tr, flags); 7098 return true; 7099 } 7100 Slog.w(TAG, "removeTask: task " + taskId 7101 + " does not have activities to remove, " 7102 + " but numActivities=" + tr.numActivities 7103 + ": " + tr); 7104 } 7105 } finally { 7106 Binder.restoreCallingIdentity(ident); 7107 } 7108 } 7109 return false; 7110 } 7111 7112 /** 7113 * TODO: Add mController hook 7114 */ 7115 @Override 7116 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7117 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7118 "moveTaskToFront()"); 7119 7120 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7121 synchronized(this) { 7122 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7123 Binder.getCallingUid(), "Task to front")) { 7124 ActivityOptions.abort(options); 7125 return; 7126 } 7127 final long origId = Binder.clearCallingIdentity(); 7128 try { 7129 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7130 if (task == null) { 7131 return; 7132 } 7133 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7134 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7135 return; 7136 } 7137 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7138 } finally { 7139 Binder.restoreCallingIdentity(origId); 7140 } 7141 ActivityOptions.abort(options); 7142 } 7143 } 7144 7145 @Override 7146 public void moveTaskToBack(int taskId) { 7147 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7148 "moveTaskToBack()"); 7149 7150 synchronized(this) { 7151 TaskRecord tr = recentTaskForIdLocked(taskId); 7152 if (tr != null) { 7153 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7154 ActivityStack stack = tr.stack; 7155 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7156 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7157 Binder.getCallingUid(), "Task to back")) { 7158 return; 7159 } 7160 } 7161 final long origId = Binder.clearCallingIdentity(); 7162 try { 7163 stack.moveTaskToBackLocked(taskId, null); 7164 } finally { 7165 Binder.restoreCallingIdentity(origId); 7166 } 7167 } 7168 } 7169 } 7170 7171 /** 7172 * Moves an activity, and all of the other activities within the same task, to the bottom 7173 * of the history stack. The activity's order within the task is unchanged. 7174 * 7175 * @param token A reference to the activity we wish to move 7176 * @param nonRoot If false then this only works if the activity is the root 7177 * of a task; if true it will work for any activity in a task. 7178 * @return Returns true if the move completed, false if not. 7179 */ 7180 @Override 7181 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7182 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7183 synchronized(this) { 7184 final long origId = Binder.clearCallingIdentity(); 7185 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7186 if (taskId >= 0) { 7187 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7188 } 7189 Binder.restoreCallingIdentity(origId); 7190 } 7191 return false; 7192 } 7193 7194 @Override 7195 public void moveTaskBackwards(int task) { 7196 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7197 "moveTaskBackwards()"); 7198 7199 synchronized(this) { 7200 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7201 Binder.getCallingUid(), "Task backwards")) { 7202 return; 7203 } 7204 final long origId = Binder.clearCallingIdentity(); 7205 moveTaskBackwardsLocked(task); 7206 Binder.restoreCallingIdentity(origId); 7207 } 7208 } 7209 7210 private final void moveTaskBackwardsLocked(int task) { 7211 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7212 } 7213 7214 @Override 7215 public IBinder getHomeActivityToken() throws RemoteException { 7216 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7217 "getHomeActivityToken()"); 7218 synchronized (this) { 7219 return mStackSupervisor.getHomeActivityToken(); 7220 } 7221 } 7222 7223 @Override 7224 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7225 IActivityContainerCallback callback) throws RemoteException { 7226 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7227 "createActivityContainer()"); 7228 synchronized (this) { 7229 if (parentActivityToken == null) { 7230 throw new IllegalArgumentException("parent token must not be null"); 7231 } 7232 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7233 if (r == null) { 7234 return null; 7235 } 7236 return mStackSupervisor.createActivityContainer(r, callback); 7237 } 7238 } 7239 7240 @Override 7241 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7242 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7243 "deleteActivityContainer()"); 7244 synchronized (this) { 7245 mStackSupervisor.deleteActivityContainer(container); 7246 } 7247 } 7248 7249 @Override 7250 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7251 throws RemoteException { 7252 synchronized (this) { 7253 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7254 if (stack != null) { 7255 return stack.mActivityContainer; 7256 } 7257 return null; 7258 } 7259 } 7260 7261 @Override 7262 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7263 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7264 "moveTaskToStack()"); 7265 if (stackId == HOME_STACK_ID) { 7266 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7267 new RuntimeException("here").fillInStackTrace()); 7268 } 7269 synchronized (this) { 7270 long ident = Binder.clearCallingIdentity(); 7271 try { 7272 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7273 + stackId + " toTop=" + toTop); 7274 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7275 } finally { 7276 Binder.restoreCallingIdentity(ident); 7277 } 7278 } 7279 } 7280 7281 @Override 7282 public void resizeStack(int stackBoxId, Rect bounds) { 7283 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7284 "resizeStackBox()"); 7285 long ident = Binder.clearCallingIdentity(); 7286 try { 7287 mWindowManager.resizeStack(stackBoxId, bounds); 7288 } finally { 7289 Binder.restoreCallingIdentity(ident); 7290 } 7291 } 7292 7293 @Override 7294 public List<StackInfo> getAllStackInfos() { 7295 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7296 "getAllStackInfos()"); 7297 long ident = Binder.clearCallingIdentity(); 7298 try { 7299 synchronized (this) { 7300 return mStackSupervisor.getAllStackInfosLocked(); 7301 } 7302 } finally { 7303 Binder.restoreCallingIdentity(ident); 7304 } 7305 } 7306 7307 @Override 7308 public StackInfo getStackInfo(int stackId) { 7309 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7310 "getStackInfo()"); 7311 long ident = Binder.clearCallingIdentity(); 7312 try { 7313 synchronized (this) { 7314 return mStackSupervisor.getStackInfoLocked(stackId); 7315 } 7316 } finally { 7317 Binder.restoreCallingIdentity(ident); 7318 } 7319 } 7320 7321 @Override 7322 public boolean isInHomeStack(int taskId) { 7323 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7324 "getStackInfo()"); 7325 long ident = Binder.clearCallingIdentity(); 7326 try { 7327 synchronized (this) { 7328 TaskRecord tr = recentTaskForIdLocked(taskId); 7329 if (tr != null) { 7330 return tr.stack.isHomeStack(); 7331 } 7332 } 7333 } finally { 7334 Binder.restoreCallingIdentity(ident); 7335 } 7336 return false; 7337 } 7338 7339 @Override 7340 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7341 synchronized(this) { 7342 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7343 } 7344 } 7345 7346 private boolean isLockTaskAuthorized(ComponentName name) { 7347// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7348// "startLockTaskMode()"); 7349// DevicePolicyManager dpm = (DevicePolicyManager) 7350// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7351// return dpm != null && dpm.isLockTaskPermitted(name); 7352 return true; 7353 } 7354 7355 private void startLockTaskMode(TaskRecord task) { 7356 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7357 return; 7358 } 7359 long ident = Binder.clearCallingIdentity(); 7360 try { 7361 synchronized (this) { 7362 // Since we lost lock on task, make sure it is still there. 7363 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7364 if (task != null) { 7365 mStackSupervisor.setLockTaskModeLocked(task); 7366 } 7367 } 7368 } finally { 7369 Binder.restoreCallingIdentity(ident); 7370 } 7371 } 7372 7373 @Override 7374 public void startLockTaskMode(int taskId) { 7375 long ident = Binder.clearCallingIdentity(); 7376 try { 7377 final TaskRecord task; 7378 synchronized (this) { 7379 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7380 } 7381 if (task != null) { 7382 startLockTaskMode(task); 7383 } 7384 } finally { 7385 Binder.restoreCallingIdentity(ident); 7386 } 7387 } 7388 7389 @Override 7390 public void startLockTaskMode(IBinder token) { 7391 long ident = Binder.clearCallingIdentity(); 7392 try { 7393 final TaskRecord task; 7394 synchronized (this) { 7395 final ActivityRecord r = ActivityRecord.forToken(token); 7396 if (r == null) { 7397 return; 7398 } 7399 task = r.task; 7400 } 7401 if (task != null) { 7402 startLockTaskMode(task); 7403 } 7404 } finally { 7405 Binder.restoreCallingIdentity(ident); 7406 } 7407 } 7408 7409 @Override 7410 public void stopLockTaskMode() { 7411// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7412// "stopLockTaskMode()"); 7413 synchronized (this) { 7414 mStackSupervisor.setLockTaskModeLocked(null); 7415 } 7416 } 7417 7418 @Override 7419 public boolean isInLockTaskMode() { 7420 synchronized (this) { 7421 return mStackSupervisor.isInLockTaskMode(); 7422 } 7423 } 7424 7425 // ========================================================= 7426 // THUMBNAILS 7427 // ========================================================= 7428 7429 public void reportThumbnail(IBinder token, 7430 Bitmap thumbnail, CharSequence description) { 7431 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7432 final long origId = Binder.clearCallingIdentity(); 7433 sendPendingThumbnail(null, token, thumbnail, description, true); 7434 Binder.restoreCallingIdentity(origId); 7435 } 7436 7437 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7438 Bitmap thumbnail, CharSequence description, boolean always) { 7439 TaskRecord task; 7440 ArrayList<PendingThumbnailsRecord> receivers = null; 7441 7442 //System.out.println("Send pending thumbnail: " + r); 7443 7444 synchronized(this) { 7445 if (r == null) { 7446 r = ActivityRecord.isInStackLocked(token); 7447 if (r == null) { 7448 return; 7449 } 7450 } 7451 if (thumbnail == null && r.thumbHolder != null) { 7452 thumbnail = r.thumbHolder.lastThumbnail; 7453 description = r.thumbHolder.lastDescription; 7454 } 7455 if (thumbnail == null && !always) { 7456 // If there is no thumbnail, and this entry is not actually 7457 // going away, then abort for now and pick up the next 7458 // thumbnail we get. 7459 return; 7460 } 7461 task = r.task; 7462 7463 int N = mPendingThumbnails.size(); 7464 int i=0; 7465 while (i<N) { 7466 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7467 //System.out.println("Looking in " + pr.pendingRecords); 7468 if (pr.pendingRecords.remove(r)) { 7469 if (receivers == null) { 7470 receivers = new ArrayList<PendingThumbnailsRecord>(); 7471 } 7472 receivers.add(pr); 7473 if (pr.pendingRecords.size() == 0) { 7474 pr.finished = true; 7475 mPendingThumbnails.remove(i); 7476 N--; 7477 continue; 7478 } 7479 } 7480 i++; 7481 } 7482 } 7483 7484 if (receivers != null) { 7485 final int N = receivers.size(); 7486 for (int i=0; i<N; i++) { 7487 try { 7488 PendingThumbnailsRecord pr = receivers.get(i); 7489 pr.receiver.newThumbnail( 7490 task != null ? task.taskId : -1, thumbnail, description); 7491 if (pr.finished) { 7492 pr.receiver.finished(); 7493 } 7494 } catch (Exception e) { 7495 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7496 } 7497 } 7498 } 7499 } 7500 7501 // ========================================================= 7502 // CONTENT PROVIDERS 7503 // ========================================================= 7504 7505 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7506 List<ProviderInfo> providers = null; 7507 try { 7508 providers = AppGlobals.getPackageManager(). 7509 queryContentProviders(app.processName, app.uid, 7510 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7511 } catch (RemoteException ex) { 7512 } 7513 if (DEBUG_MU) 7514 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7515 int userId = app.userId; 7516 if (providers != null) { 7517 int N = providers.size(); 7518 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7519 for (int i=0; i<N; i++) { 7520 ProviderInfo cpi = 7521 (ProviderInfo)providers.get(i); 7522 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7523 cpi.name, cpi.flags); 7524 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7525 // This is a singleton provider, but a user besides the 7526 // default user is asking to initialize a process it runs 7527 // in... well, no, it doesn't actually run in this process, 7528 // it runs in the process of the default user. Get rid of it. 7529 providers.remove(i); 7530 N--; 7531 i--; 7532 continue; 7533 } 7534 7535 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7536 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7537 if (cpr == null) { 7538 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7539 mProviderMap.putProviderByClass(comp, cpr); 7540 } 7541 if (DEBUG_MU) 7542 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7543 app.pubProviders.put(cpi.name, cpr); 7544 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7545 // Don't add this if it is a platform component that is marked 7546 // to run in multiple processes, because this is actually 7547 // part of the framework so doesn't make sense to track as a 7548 // separate apk in the process. 7549 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7550 } 7551 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7552 } 7553 } 7554 return providers; 7555 } 7556 7557 /** 7558 * Check if {@link ProcessRecord} has a possible chance at accessing the 7559 * given {@link ProviderInfo}. Final permission checking is always done 7560 * in {@link ContentProvider}. 7561 */ 7562 private final String checkContentProviderPermissionLocked( 7563 ProviderInfo cpi, ProcessRecord r) { 7564 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7565 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7566 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7567 cpi.applicationInfo.uid, cpi.exported) 7568 == PackageManager.PERMISSION_GRANTED) { 7569 return null; 7570 } 7571 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7572 cpi.applicationInfo.uid, cpi.exported) 7573 == PackageManager.PERMISSION_GRANTED) { 7574 return null; 7575 } 7576 7577 PathPermission[] pps = cpi.pathPermissions; 7578 if (pps != null) { 7579 int i = pps.length; 7580 while (i > 0) { 7581 i--; 7582 PathPermission pp = pps[i]; 7583 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7584 cpi.applicationInfo.uid, cpi.exported) 7585 == PackageManager.PERMISSION_GRANTED) { 7586 return null; 7587 } 7588 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7589 cpi.applicationInfo.uid, cpi.exported) 7590 == PackageManager.PERMISSION_GRANTED) { 7591 return null; 7592 } 7593 } 7594 } 7595 7596 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7597 if (perms != null) { 7598 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7599 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7600 return null; 7601 } 7602 } 7603 } 7604 7605 String msg; 7606 if (!cpi.exported) { 7607 msg = "Permission Denial: opening provider " + cpi.name 7608 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7609 + ", uid=" + callingUid + ") that is not exported from uid " 7610 + cpi.applicationInfo.uid; 7611 } else { 7612 msg = "Permission Denial: opening provider " + cpi.name 7613 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7614 + ", uid=" + callingUid + ") requires " 7615 + cpi.readPermission + " or " + cpi.writePermission; 7616 } 7617 Slog.w(TAG, msg); 7618 return msg; 7619 } 7620 7621 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7622 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7623 if (r != null) { 7624 for (int i=0; i<r.conProviders.size(); i++) { 7625 ContentProviderConnection conn = r.conProviders.get(i); 7626 if (conn.provider == cpr) { 7627 if (DEBUG_PROVIDER) Slog.v(TAG, 7628 "Adding provider requested by " 7629 + r.processName + " from process " 7630 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7631 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7632 if (stable) { 7633 conn.stableCount++; 7634 conn.numStableIncs++; 7635 } else { 7636 conn.unstableCount++; 7637 conn.numUnstableIncs++; 7638 } 7639 return conn; 7640 } 7641 } 7642 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7643 if (stable) { 7644 conn.stableCount = 1; 7645 conn.numStableIncs = 1; 7646 } else { 7647 conn.unstableCount = 1; 7648 conn.numUnstableIncs = 1; 7649 } 7650 cpr.connections.add(conn); 7651 r.conProviders.add(conn); 7652 return conn; 7653 } 7654 cpr.addExternalProcessHandleLocked(externalProcessToken); 7655 return null; 7656 } 7657 7658 boolean decProviderCountLocked(ContentProviderConnection conn, 7659 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7660 if (conn != null) { 7661 cpr = conn.provider; 7662 if (DEBUG_PROVIDER) Slog.v(TAG, 7663 "Removing provider requested by " 7664 + conn.client.processName + " from process " 7665 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7666 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7667 if (stable) { 7668 conn.stableCount--; 7669 } else { 7670 conn.unstableCount--; 7671 } 7672 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7673 cpr.connections.remove(conn); 7674 conn.client.conProviders.remove(conn); 7675 return true; 7676 } 7677 return false; 7678 } 7679 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7680 return false; 7681 } 7682 7683 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7684 String name, IBinder token, boolean stable, int userId) { 7685 ContentProviderRecord cpr; 7686 ContentProviderConnection conn = null; 7687 ProviderInfo cpi = null; 7688 7689 synchronized(this) { 7690 ProcessRecord r = null; 7691 if (caller != null) { 7692 r = getRecordForAppLocked(caller); 7693 if (r == null) { 7694 throw new SecurityException( 7695 "Unable to find app for caller " + caller 7696 + " (pid=" + Binder.getCallingPid() 7697 + ") when getting content provider " + name); 7698 } 7699 } 7700 7701 // First check if this content provider has been published... 7702 cpr = mProviderMap.getProviderByName(name, userId); 7703 boolean providerRunning = cpr != null; 7704 if (providerRunning) { 7705 cpi = cpr.info; 7706 String msg; 7707 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7708 throw new SecurityException(msg); 7709 } 7710 7711 if (r != null && cpr.canRunHere(r)) { 7712 // This provider has been published or is in the process 7713 // of being published... but it is also allowed to run 7714 // in the caller's process, so don't make a connection 7715 // and just let the caller instantiate its own instance. 7716 ContentProviderHolder holder = cpr.newHolder(null); 7717 // don't give caller the provider object, it needs 7718 // to make its own. 7719 holder.provider = null; 7720 return holder; 7721 } 7722 7723 final long origId = Binder.clearCallingIdentity(); 7724 7725 // In this case the provider instance already exists, so we can 7726 // return it right away. 7727 conn = incProviderCountLocked(r, cpr, token, stable); 7728 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7729 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7730 // If this is a perceptible app accessing the provider, 7731 // make sure to count it as being accessed and thus 7732 // back up on the LRU list. This is good because 7733 // content providers are often expensive to start. 7734 updateLruProcessLocked(cpr.proc, false, null); 7735 } 7736 } 7737 7738 if (cpr.proc != null) { 7739 if (false) { 7740 if (cpr.name.flattenToShortString().equals( 7741 "com.android.providers.calendar/.CalendarProvider2")) { 7742 Slog.v(TAG, "****************** KILLING " 7743 + cpr.name.flattenToShortString()); 7744 Process.killProcess(cpr.proc.pid); 7745 } 7746 } 7747 boolean success = updateOomAdjLocked(cpr.proc); 7748 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7749 // NOTE: there is still a race here where a signal could be 7750 // pending on the process even though we managed to update its 7751 // adj level. Not sure what to do about this, but at least 7752 // the race is now smaller. 7753 if (!success) { 7754 // Uh oh... it looks like the provider's process 7755 // has been killed on us. We need to wait for a new 7756 // process to be started, and make sure its death 7757 // doesn't kill our process. 7758 Slog.i(TAG, 7759 "Existing provider " + cpr.name.flattenToShortString() 7760 + " is crashing; detaching " + r); 7761 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7762 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7763 if (!lastRef) { 7764 // This wasn't the last ref our process had on 7765 // the provider... we have now been killed, bail. 7766 return null; 7767 } 7768 providerRunning = false; 7769 conn = null; 7770 } 7771 } 7772 7773 Binder.restoreCallingIdentity(origId); 7774 } 7775 7776 boolean singleton; 7777 if (!providerRunning) { 7778 try { 7779 cpi = AppGlobals.getPackageManager(). 7780 resolveContentProvider(name, 7781 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7782 } catch (RemoteException ex) { 7783 } 7784 if (cpi == null) { 7785 return null; 7786 } 7787 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7788 cpi.name, cpi.flags); 7789 if (singleton) { 7790 userId = 0; 7791 } 7792 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7793 7794 String msg; 7795 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7796 throw new SecurityException(msg); 7797 } 7798 7799 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7800 && !cpi.processName.equals("system")) { 7801 // If this content provider does not run in the system 7802 // process, and the system is not yet ready to run other 7803 // processes, then fail fast instead of hanging. 7804 throw new IllegalArgumentException( 7805 "Attempt to launch content provider before system ready"); 7806 } 7807 7808 // Make sure that the user who owns this provider is started. If not, 7809 // we don't want to allow it to run. 7810 if (mStartedUsers.get(userId) == null) { 7811 Slog.w(TAG, "Unable to launch app " 7812 + cpi.applicationInfo.packageName + "/" 7813 + cpi.applicationInfo.uid + " for provider " 7814 + name + ": user " + userId + " is stopped"); 7815 return null; 7816 } 7817 7818 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7819 cpr = mProviderMap.getProviderByClass(comp, userId); 7820 final boolean firstClass = cpr == null; 7821 if (firstClass) { 7822 try { 7823 ApplicationInfo ai = 7824 AppGlobals.getPackageManager(). 7825 getApplicationInfo( 7826 cpi.applicationInfo.packageName, 7827 STOCK_PM_FLAGS, userId); 7828 if (ai == null) { 7829 Slog.w(TAG, "No package info for content provider " 7830 + cpi.name); 7831 return null; 7832 } 7833 ai = getAppInfoForUser(ai, userId); 7834 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7835 } catch (RemoteException ex) { 7836 // pm is in same process, this will never happen. 7837 } 7838 } 7839 7840 if (r != null && cpr.canRunHere(r)) { 7841 // If this is a multiprocess provider, then just return its 7842 // info and allow the caller to instantiate it. Only do 7843 // this if the provider is the same user as the caller's 7844 // process, or can run as root (so can be in any process). 7845 return cpr.newHolder(null); 7846 } 7847 7848 if (DEBUG_PROVIDER) { 7849 RuntimeException e = new RuntimeException("here"); 7850 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7851 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7852 } 7853 7854 // This is single process, and our app is now connecting to it. 7855 // See if we are already in the process of launching this 7856 // provider. 7857 final int N = mLaunchingProviders.size(); 7858 int i; 7859 for (i=0; i<N; i++) { 7860 if (mLaunchingProviders.get(i) == cpr) { 7861 break; 7862 } 7863 } 7864 7865 // If the provider is not already being launched, then get it 7866 // started. 7867 if (i >= N) { 7868 final long origId = Binder.clearCallingIdentity(); 7869 7870 try { 7871 // Content provider is now in use, its package can't be stopped. 7872 try { 7873 AppGlobals.getPackageManager().setPackageStoppedState( 7874 cpr.appInfo.packageName, false, userId); 7875 } catch (RemoteException e) { 7876 } catch (IllegalArgumentException e) { 7877 Slog.w(TAG, "Failed trying to unstop package " 7878 + cpr.appInfo.packageName + ": " + e); 7879 } 7880 7881 // Use existing process if already started 7882 ProcessRecord proc = getProcessRecordLocked( 7883 cpi.processName, cpr.appInfo.uid, false); 7884 if (proc != null && proc.thread != null) { 7885 if (DEBUG_PROVIDER) { 7886 Slog.d(TAG, "Installing in existing process " + proc); 7887 } 7888 proc.pubProviders.put(cpi.name, cpr); 7889 try { 7890 proc.thread.scheduleInstallProvider(cpi); 7891 } catch (RemoteException e) { 7892 } 7893 } else { 7894 proc = startProcessLocked(cpi.processName, 7895 cpr.appInfo, false, 0, "content provider", 7896 new ComponentName(cpi.applicationInfo.packageName, 7897 cpi.name), false, false, false); 7898 if (proc == null) { 7899 Slog.w(TAG, "Unable to launch app " 7900 + cpi.applicationInfo.packageName + "/" 7901 + cpi.applicationInfo.uid + " for provider " 7902 + name + ": process is bad"); 7903 return null; 7904 } 7905 } 7906 cpr.launchingApp = proc; 7907 mLaunchingProviders.add(cpr); 7908 } finally { 7909 Binder.restoreCallingIdentity(origId); 7910 } 7911 } 7912 7913 // Make sure the provider is published (the same provider class 7914 // may be published under multiple names). 7915 if (firstClass) { 7916 mProviderMap.putProviderByClass(comp, cpr); 7917 } 7918 7919 mProviderMap.putProviderByName(name, cpr); 7920 conn = incProviderCountLocked(r, cpr, token, stable); 7921 if (conn != null) { 7922 conn.waiting = true; 7923 } 7924 } 7925 } 7926 7927 // Wait for the provider to be published... 7928 synchronized (cpr) { 7929 while (cpr.provider == null) { 7930 if (cpr.launchingApp == null) { 7931 Slog.w(TAG, "Unable to launch app " 7932 + cpi.applicationInfo.packageName + "/" 7933 + cpi.applicationInfo.uid + " for provider " 7934 + name + ": launching app became null"); 7935 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7936 UserHandle.getUserId(cpi.applicationInfo.uid), 7937 cpi.applicationInfo.packageName, 7938 cpi.applicationInfo.uid, name); 7939 return null; 7940 } 7941 try { 7942 if (DEBUG_MU) { 7943 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7944 + cpr.launchingApp); 7945 } 7946 if (conn != null) { 7947 conn.waiting = true; 7948 } 7949 cpr.wait(); 7950 } catch (InterruptedException ex) { 7951 } finally { 7952 if (conn != null) { 7953 conn.waiting = false; 7954 } 7955 } 7956 } 7957 } 7958 return cpr != null ? cpr.newHolder(conn) : null; 7959 } 7960 7961 public final ContentProviderHolder getContentProvider( 7962 IApplicationThread caller, String name, int userId, boolean stable) { 7963 enforceNotIsolatedCaller("getContentProvider"); 7964 if (caller == null) { 7965 String msg = "null IApplicationThread when getting content provider " 7966 + name; 7967 Slog.w(TAG, msg); 7968 throw new SecurityException(msg); 7969 } 7970 7971 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7972 false, true, "getContentProvider", null); 7973 return getContentProviderImpl(caller, name, null, stable, userId); 7974 } 7975 7976 public ContentProviderHolder getContentProviderExternal( 7977 String name, int userId, IBinder token) { 7978 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7979 "Do not have permission in call getContentProviderExternal()"); 7980 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7981 false, true, "getContentProvider", null); 7982 return getContentProviderExternalUnchecked(name, token, userId); 7983 } 7984 7985 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7986 IBinder token, int userId) { 7987 return getContentProviderImpl(null, name, token, true, userId); 7988 } 7989 7990 /** 7991 * Drop a content provider from a ProcessRecord's bookkeeping 7992 */ 7993 public void removeContentProvider(IBinder connection, boolean stable) { 7994 enforceNotIsolatedCaller("removeContentProvider"); 7995 long ident = Binder.clearCallingIdentity(); 7996 try { 7997 synchronized (this) { 7998 ContentProviderConnection conn; 7999 try { 8000 conn = (ContentProviderConnection)connection; 8001 } catch (ClassCastException e) { 8002 String msg ="removeContentProvider: " + connection 8003 + " not a ContentProviderConnection"; 8004 Slog.w(TAG, msg); 8005 throw new IllegalArgumentException(msg); 8006 } 8007 if (conn == null) { 8008 throw new NullPointerException("connection is null"); 8009 } 8010 if (decProviderCountLocked(conn, null, null, stable)) { 8011 updateOomAdjLocked(); 8012 } 8013 } 8014 } finally { 8015 Binder.restoreCallingIdentity(ident); 8016 } 8017 } 8018 8019 public void removeContentProviderExternal(String name, IBinder token) { 8020 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8021 "Do not have permission in call removeContentProviderExternal()"); 8022 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8023 } 8024 8025 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8026 synchronized (this) { 8027 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8028 if(cpr == null) { 8029 //remove from mProvidersByClass 8030 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8031 return; 8032 } 8033 8034 //update content provider record entry info 8035 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8036 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8037 if (localCpr.hasExternalProcessHandles()) { 8038 if (localCpr.removeExternalProcessHandleLocked(token)) { 8039 updateOomAdjLocked(); 8040 } else { 8041 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8042 + " with no external reference for token: " 8043 + token + "."); 8044 } 8045 } else { 8046 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8047 + " with no external references."); 8048 } 8049 } 8050 } 8051 8052 public final void publishContentProviders(IApplicationThread caller, 8053 List<ContentProviderHolder> providers) { 8054 if (providers == null) { 8055 return; 8056 } 8057 8058 enforceNotIsolatedCaller("publishContentProviders"); 8059 synchronized (this) { 8060 final ProcessRecord r = getRecordForAppLocked(caller); 8061 if (DEBUG_MU) 8062 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8063 if (r == null) { 8064 throw new SecurityException( 8065 "Unable to find app for caller " + caller 8066 + " (pid=" + Binder.getCallingPid() 8067 + ") when publishing content providers"); 8068 } 8069 8070 final long origId = Binder.clearCallingIdentity(); 8071 8072 final int N = providers.size(); 8073 for (int i=0; i<N; i++) { 8074 ContentProviderHolder src = providers.get(i); 8075 if (src == null || src.info == null || src.provider == null) { 8076 continue; 8077 } 8078 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8079 if (DEBUG_MU) 8080 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8081 if (dst != null) { 8082 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8083 mProviderMap.putProviderByClass(comp, dst); 8084 String names[] = dst.info.authority.split(";"); 8085 for (int j = 0; j < names.length; j++) { 8086 mProviderMap.putProviderByName(names[j], dst); 8087 } 8088 8089 int NL = mLaunchingProviders.size(); 8090 int j; 8091 for (j=0; j<NL; j++) { 8092 if (mLaunchingProviders.get(j) == dst) { 8093 mLaunchingProviders.remove(j); 8094 j--; 8095 NL--; 8096 } 8097 } 8098 synchronized (dst) { 8099 dst.provider = src.provider; 8100 dst.proc = r; 8101 dst.notifyAll(); 8102 } 8103 updateOomAdjLocked(r); 8104 } 8105 } 8106 8107 Binder.restoreCallingIdentity(origId); 8108 } 8109 } 8110 8111 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8112 ContentProviderConnection conn; 8113 try { 8114 conn = (ContentProviderConnection)connection; 8115 } catch (ClassCastException e) { 8116 String msg ="refContentProvider: " + connection 8117 + " not a ContentProviderConnection"; 8118 Slog.w(TAG, msg); 8119 throw new IllegalArgumentException(msg); 8120 } 8121 if (conn == null) { 8122 throw new NullPointerException("connection is null"); 8123 } 8124 8125 synchronized (this) { 8126 if (stable > 0) { 8127 conn.numStableIncs += stable; 8128 } 8129 stable = conn.stableCount + stable; 8130 if (stable < 0) { 8131 throw new IllegalStateException("stableCount < 0: " + stable); 8132 } 8133 8134 if (unstable > 0) { 8135 conn.numUnstableIncs += unstable; 8136 } 8137 unstable = conn.unstableCount + unstable; 8138 if (unstable < 0) { 8139 throw new IllegalStateException("unstableCount < 0: " + unstable); 8140 } 8141 8142 if ((stable+unstable) <= 0) { 8143 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8144 + stable + " unstable=" + unstable); 8145 } 8146 conn.stableCount = stable; 8147 conn.unstableCount = unstable; 8148 return !conn.dead; 8149 } 8150 } 8151 8152 public void unstableProviderDied(IBinder connection) { 8153 ContentProviderConnection conn; 8154 try { 8155 conn = (ContentProviderConnection)connection; 8156 } catch (ClassCastException e) { 8157 String msg ="refContentProvider: " + connection 8158 + " not a ContentProviderConnection"; 8159 Slog.w(TAG, msg); 8160 throw new IllegalArgumentException(msg); 8161 } 8162 if (conn == null) { 8163 throw new NullPointerException("connection is null"); 8164 } 8165 8166 // Safely retrieve the content provider associated with the connection. 8167 IContentProvider provider; 8168 synchronized (this) { 8169 provider = conn.provider.provider; 8170 } 8171 8172 if (provider == null) { 8173 // Um, yeah, we're way ahead of you. 8174 return; 8175 } 8176 8177 // Make sure the caller is being honest with us. 8178 if (provider.asBinder().pingBinder()) { 8179 // Er, no, still looks good to us. 8180 synchronized (this) { 8181 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8182 + " says " + conn + " died, but we don't agree"); 8183 return; 8184 } 8185 } 8186 8187 // Well look at that! It's dead! 8188 synchronized (this) { 8189 if (conn.provider.provider != provider) { 8190 // But something changed... good enough. 8191 return; 8192 } 8193 8194 ProcessRecord proc = conn.provider.proc; 8195 if (proc == null || proc.thread == null) { 8196 // Seems like the process is already cleaned up. 8197 return; 8198 } 8199 8200 // As far as we're concerned, this is just like receiving a 8201 // death notification... just a bit prematurely. 8202 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8203 + ") early provider death"); 8204 final long ident = Binder.clearCallingIdentity(); 8205 try { 8206 appDiedLocked(proc, proc.pid, proc.thread); 8207 } finally { 8208 Binder.restoreCallingIdentity(ident); 8209 } 8210 } 8211 } 8212 8213 @Override 8214 public void appNotRespondingViaProvider(IBinder connection) { 8215 enforceCallingPermission( 8216 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8217 8218 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8219 if (conn == null) { 8220 Slog.w(TAG, "ContentProviderConnection is null"); 8221 return; 8222 } 8223 8224 final ProcessRecord host = conn.provider.proc; 8225 if (host == null) { 8226 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8227 return; 8228 } 8229 8230 final long token = Binder.clearCallingIdentity(); 8231 try { 8232 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8233 } finally { 8234 Binder.restoreCallingIdentity(token); 8235 } 8236 } 8237 8238 public final void installSystemProviders() { 8239 List<ProviderInfo> providers; 8240 synchronized (this) { 8241 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8242 providers = generateApplicationProvidersLocked(app); 8243 if (providers != null) { 8244 for (int i=providers.size()-1; i>=0; i--) { 8245 ProviderInfo pi = (ProviderInfo)providers.get(i); 8246 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8247 Slog.w(TAG, "Not installing system proc provider " + pi.name 8248 + ": not system .apk"); 8249 providers.remove(i); 8250 } 8251 } 8252 } 8253 } 8254 if (providers != null) { 8255 mSystemThread.installSystemProviders(providers); 8256 } 8257 8258 mCoreSettingsObserver = new CoreSettingsObserver(this); 8259 8260 mUsageStatsService.monitorPackages(); 8261 } 8262 8263 /** 8264 * Allows app to retrieve the MIME type of a URI without having permission 8265 * to access its content provider. 8266 * 8267 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8268 * 8269 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8270 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8271 */ 8272 public String getProviderMimeType(Uri uri, int userId) { 8273 enforceNotIsolatedCaller("getProviderMimeType"); 8274 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8275 userId, false, true, "getProviderMimeType", null); 8276 final String name = uri.getAuthority(); 8277 final long ident = Binder.clearCallingIdentity(); 8278 ContentProviderHolder holder = null; 8279 8280 try { 8281 holder = getContentProviderExternalUnchecked(name, null, userId); 8282 if (holder != null) { 8283 return holder.provider.getType(uri); 8284 } 8285 } catch (RemoteException e) { 8286 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8287 return null; 8288 } finally { 8289 if (holder != null) { 8290 removeContentProviderExternalUnchecked(name, null, userId); 8291 } 8292 Binder.restoreCallingIdentity(ident); 8293 } 8294 8295 return null; 8296 } 8297 8298 // ========================================================= 8299 // GLOBAL MANAGEMENT 8300 // ========================================================= 8301 8302 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8303 boolean isolated) { 8304 String proc = customProcess != null ? customProcess : info.processName; 8305 BatteryStatsImpl.Uid.Proc ps = null; 8306 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8307 int uid = info.uid; 8308 if (isolated) { 8309 int userId = UserHandle.getUserId(uid); 8310 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8311 while (true) { 8312 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8313 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8314 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8315 } 8316 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8317 mNextIsolatedProcessUid++; 8318 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8319 // No process for this uid, use it. 8320 break; 8321 } 8322 stepsLeft--; 8323 if (stepsLeft <= 0) { 8324 return null; 8325 } 8326 } 8327 } 8328 return new ProcessRecord(stats, info, proc, uid); 8329 } 8330 8331 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8332 ProcessRecord app; 8333 if (!isolated) { 8334 app = getProcessRecordLocked(info.processName, info.uid, true); 8335 } else { 8336 app = null; 8337 } 8338 8339 if (app == null) { 8340 app = newProcessRecordLocked(info, null, isolated); 8341 mProcessNames.put(info.processName, app.uid, app); 8342 if (isolated) { 8343 mIsolatedProcesses.put(app.uid, app); 8344 } 8345 updateLruProcessLocked(app, false, null); 8346 updateOomAdjLocked(); 8347 } 8348 8349 // This package really, really can not be stopped. 8350 try { 8351 AppGlobals.getPackageManager().setPackageStoppedState( 8352 info.packageName, false, UserHandle.getUserId(app.uid)); 8353 } catch (RemoteException e) { 8354 } catch (IllegalArgumentException e) { 8355 Slog.w(TAG, "Failed trying to unstop package " 8356 + info.packageName + ": " + e); 8357 } 8358 8359 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8360 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8361 app.persistent = true; 8362 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8363 } 8364 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8365 mPersistentStartingProcesses.add(app); 8366 startProcessLocked(app, "added application", app.processName); 8367 } 8368 8369 return app; 8370 } 8371 8372 public void unhandledBack() { 8373 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8374 "unhandledBack()"); 8375 8376 synchronized(this) { 8377 final long origId = Binder.clearCallingIdentity(); 8378 try { 8379 getFocusedStack().unhandledBackLocked(); 8380 } finally { 8381 Binder.restoreCallingIdentity(origId); 8382 } 8383 } 8384 } 8385 8386 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8387 enforceNotIsolatedCaller("openContentUri"); 8388 final int userId = UserHandle.getCallingUserId(); 8389 String name = uri.getAuthority(); 8390 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8391 ParcelFileDescriptor pfd = null; 8392 if (cph != null) { 8393 // We record the binder invoker's uid in thread-local storage before 8394 // going to the content provider to open the file. Later, in the code 8395 // that handles all permissions checks, we look for this uid and use 8396 // that rather than the Activity Manager's own uid. The effect is that 8397 // we do the check against the caller's permissions even though it looks 8398 // to the content provider like the Activity Manager itself is making 8399 // the request. 8400 sCallerIdentity.set(new Identity( 8401 Binder.getCallingPid(), Binder.getCallingUid())); 8402 try { 8403 pfd = cph.provider.openFile(null, uri, "r", null); 8404 } catch (FileNotFoundException e) { 8405 // do nothing; pfd will be returned null 8406 } finally { 8407 // Ensure that whatever happens, we clean up the identity state 8408 sCallerIdentity.remove(); 8409 } 8410 8411 // We've got the fd now, so we're done with the provider. 8412 removeContentProviderExternalUnchecked(name, null, userId); 8413 } else { 8414 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8415 } 8416 return pfd; 8417 } 8418 8419 // Actually is sleeping or shutting down or whatever else in the future 8420 // is an inactive state. 8421 public boolean isSleepingOrShuttingDown() { 8422 return mSleeping || mShuttingDown; 8423 } 8424 8425 public void goingToSleep() { 8426 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8427 != PackageManager.PERMISSION_GRANTED) { 8428 throw new SecurityException("Requires permission " 8429 + android.Manifest.permission.DEVICE_POWER); 8430 } 8431 8432 synchronized(this) { 8433 mWentToSleep = true; 8434 updateEventDispatchingLocked(); 8435 8436 if (!mSleeping) { 8437 mSleeping = true; 8438 mStackSupervisor.goingToSleepLocked(); 8439 8440 // Initialize the wake times of all processes. 8441 checkExcessivePowerUsageLocked(false); 8442 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8443 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8444 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8445 } 8446 } 8447 } 8448 8449 @Override 8450 public boolean shutdown(int timeout) { 8451 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8452 != PackageManager.PERMISSION_GRANTED) { 8453 throw new SecurityException("Requires permission " 8454 + android.Manifest.permission.SHUTDOWN); 8455 } 8456 8457 boolean timedout = false; 8458 8459 synchronized(this) { 8460 mShuttingDown = true; 8461 updateEventDispatchingLocked(); 8462 timedout = mStackSupervisor.shutdownLocked(timeout); 8463 } 8464 8465 mAppOpsService.shutdown(); 8466 mUsageStatsService.shutdown(); 8467 mBatteryStatsService.shutdown(); 8468 synchronized (this) { 8469 mProcessStats.shutdownLocked(); 8470 } 8471 8472 return timedout; 8473 } 8474 8475 public final void activitySlept(IBinder token) { 8476 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8477 8478 final long origId = Binder.clearCallingIdentity(); 8479 8480 synchronized (this) { 8481 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8482 if (r != null) { 8483 mStackSupervisor.activitySleptLocked(r); 8484 } 8485 } 8486 8487 Binder.restoreCallingIdentity(origId); 8488 } 8489 8490 void logLockScreen(String msg) { 8491 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8492 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8493 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8494 mStackSupervisor.mDismissKeyguardOnNextActivity); 8495 } 8496 8497 private void comeOutOfSleepIfNeededLocked() { 8498 if (!mWentToSleep && !mLockScreenShown) { 8499 if (mSleeping) { 8500 mSleeping = false; 8501 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8502 } 8503 } 8504 } 8505 8506 public void wakingUp() { 8507 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8508 != PackageManager.PERMISSION_GRANTED) { 8509 throw new SecurityException("Requires permission " 8510 + android.Manifest.permission.DEVICE_POWER); 8511 } 8512 8513 synchronized(this) { 8514 mWentToSleep = false; 8515 updateEventDispatchingLocked(); 8516 comeOutOfSleepIfNeededLocked(); 8517 } 8518 } 8519 8520 private void updateEventDispatchingLocked() { 8521 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8522 } 8523 8524 public void setLockScreenShown(boolean shown) { 8525 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8526 != PackageManager.PERMISSION_GRANTED) { 8527 throw new SecurityException("Requires permission " 8528 + android.Manifest.permission.DEVICE_POWER); 8529 } 8530 8531 synchronized(this) { 8532 long ident = Binder.clearCallingIdentity(); 8533 try { 8534 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8535 mLockScreenShown = shown; 8536 comeOutOfSleepIfNeededLocked(); 8537 } finally { 8538 Binder.restoreCallingIdentity(ident); 8539 } 8540 } 8541 } 8542 8543 public void stopAppSwitches() { 8544 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8545 != PackageManager.PERMISSION_GRANTED) { 8546 throw new SecurityException("Requires permission " 8547 + android.Manifest.permission.STOP_APP_SWITCHES); 8548 } 8549 8550 synchronized(this) { 8551 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8552 + APP_SWITCH_DELAY_TIME; 8553 mDidAppSwitch = false; 8554 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8555 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8556 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8557 } 8558 } 8559 8560 public void resumeAppSwitches() { 8561 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8562 != PackageManager.PERMISSION_GRANTED) { 8563 throw new SecurityException("Requires permission " 8564 + android.Manifest.permission.STOP_APP_SWITCHES); 8565 } 8566 8567 synchronized(this) { 8568 // Note that we don't execute any pending app switches... we will 8569 // let those wait until either the timeout, or the next start 8570 // activity request. 8571 mAppSwitchesAllowedTime = 0; 8572 } 8573 } 8574 8575 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8576 String name) { 8577 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8578 return true; 8579 } 8580 8581 final int perm = checkComponentPermission( 8582 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8583 callingUid, -1, true); 8584 if (perm == PackageManager.PERMISSION_GRANTED) { 8585 return true; 8586 } 8587 8588 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8589 return false; 8590 } 8591 8592 public void setDebugApp(String packageName, boolean waitForDebugger, 8593 boolean persistent) { 8594 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8595 "setDebugApp()"); 8596 8597 long ident = Binder.clearCallingIdentity(); 8598 try { 8599 // Note that this is not really thread safe if there are multiple 8600 // callers into it at the same time, but that's not a situation we 8601 // care about. 8602 if (persistent) { 8603 final ContentResolver resolver = mContext.getContentResolver(); 8604 Settings.Global.putString( 8605 resolver, Settings.Global.DEBUG_APP, 8606 packageName); 8607 Settings.Global.putInt( 8608 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8609 waitForDebugger ? 1 : 0); 8610 } 8611 8612 synchronized (this) { 8613 if (!persistent) { 8614 mOrigDebugApp = mDebugApp; 8615 mOrigWaitForDebugger = mWaitForDebugger; 8616 } 8617 mDebugApp = packageName; 8618 mWaitForDebugger = waitForDebugger; 8619 mDebugTransient = !persistent; 8620 if (packageName != null) { 8621 forceStopPackageLocked(packageName, -1, false, false, true, true, 8622 false, UserHandle.USER_ALL, "set debug app"); 8623 } 8624 } 8625 } finally { 8626 Binder.restoreCallingIdentity(ident); 8627 } 8628 } 8629 8630 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8631 synchronized (this) { 8632 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8633 if (!isDebuggable) { 8634 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8635 throw new SecurityException("Process not debuggable: " + app.packageName); 8636 } 8637 } 8638 8639 mOpenGlTraceApp = processName; 8640 } 8641 } 8642 8643 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8644 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8645 synchronized (this) { 8646 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8647 if (!isDebuggable) { 8648 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8649 throw new SecurityException("Process not debuggable: " + app.packageName); 8650 } 8651 } 8652 mProfileApp = processName; 8653 mProfileFile = profileFile; 8654 if (mProfileFd != null) { 8655 try { 8656 mProfileFd.close(); 8657 } catch (IOException e) { 8658 } 8659 mProfileFd = null; 8660 } 8661 mProfileFd = profileFd; 8662 mProfileType = 0; 8663 mAutoStopProfiler = autoStopProfiler; 8664 } 8665 } 8666 8667 @Override 8668 public void setAlwaysFinish(boolean enabled) { 8669 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8670 "setAlwaysFinish()"); 8671 8672 Settings.Global.putInt( 8673 mContext.getContentResolver(), 8674 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8675 8676 synchronized (this) { 8677 mAlwaysFinishActivities = enabled; 8678 } 8679 } 8680 8681 @Override 8682 public void setActivityController(IActivityController controller) { 8683 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8684 "setActivityController()"); 8685 synchronized (this) { 8686 mController = controller; 8687 Watchdog.getInstance().setActivityController(controller); 8688 } 8689 } 8690 8691 @Override 8692 public void setUserIsMonkey(boolean userIsMonkey) { 8693 synchronized (this) { 8694 synchronized (mPidsSelfLocked) { 8695 final int callingPid = Binder.getCallingPid(); 8696 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8697 if (precessRecord == null) { 8698 throw new SecurityException("Unknown process: " + callingPid); 8699 } 8700 if (precessRecord.instrumentationUiAutomationConnection == null) { 8701 throw new SecurityException("Only an instrumentation process " 8702 + "with a UiAutomation can call setUserIsMonkey"); 8703 } 8704 } 8705 mUserIsMonkey = userIsMonkey; 8706 } 8707 } 8708 8709 @Override 8710 public boolean isUserAMonkey() { 8711 synchronized (this) { 8712 // If there is a controller also implies the user is a monkey. 8713 return (mUserIsMonkey || mController != null); 8714 } 8715 } 8716 8717 public void requestBugReport() { 8718 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8719 SystemProperties.set("ctl.start", "bugreport"); 8720 } 8721 8722 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8723 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8724 } 8725 8726 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8727 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8728 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8729 } 8730 return KEY_DISPATCHING_TIMEOUT; 8731 } 8732 8733 @Override 8734 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8735 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8736 != PackageManager.PERMISSION_GRANTED) { 8737 throw new SecurityException("Requires permission " 8738 + android.Manifest.permission.FILTER_EVENTS); 8739 } 8740 ProcessRecord proc; 8741 long timeout; 8742 synchronized (this) { 8743 synchronized (mPidsSelfLocked) { 8744 proc = mPidsSelfLocked.get(pid); 8745 } 8746 timeout = getInputDispatchingTimeoutLocked(proc); 8747 } 8748 8749 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8750 return -1; 8751 } 8752 8753 return timeout; 8754 } 8755 8756 /** 8757 * Handle input dispatching timeouts. 8758 * Returns whether input dispatching should be aborted or not. 8759 */ 8760 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8761 final ActivityRecord activity, final ActivityRecord parent, 8762 final boolean aboveSystem, String reason) { 8763 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8764 != PackageManager.PERMISSION_GRANTED) { 8765 throw new SecurityException("Requires permission " 8766 + android.Manifest.permission.FILTER_EVENTS); 8767 } 8768 8769 final String annotation; 8770 if (reason == null) { 8771 annotation = "Input dispatching timed out"; 8772 } else { 8773 annotation = "Input dispatching timed out (" + reason + ")"; 8774 } 8775 8776 if (proc != null) { 8777 synchronized (this) { 8778 if (proc.debugging) { 8779 return false; 8780 } 8781 8782 if (mDidDexOpt) { 8783 // Give more time since we were dexopting. 8784 mDidDexOpt = false; 8785 return false; 8786 } 8787 8788 if (proc.instrumentationClass != null) { 8789 Bundle info = new Bundle(); 8790 info.putString("shortMsg", "keyDispatchingTimedOut"); 8791 info.putString("longMsg", annotation); 8792 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8793 return true; 8794 } 8795 } 8796 mHandler.post(new Runnable() { 8797 @Override 8798 public void run() { 8799 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8800 } 8801 }); 8802 } 8803 8804 return true; 8805 } 8806 8807 public Bundle getAssistContextExtras(int requestType) { 8808 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8809 "getAssistContextExtras()"); 8810 PendingAssistExtras pae; 8811 Bundle extras = new Bundle(); 8812 synchronized (this) { 8813 ActivityRecord activity = getFocusedStack().mResumedActivity; 8814 if (activity == null) { 8815 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8816 return null; 8817 } 8818 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8819 if (activity.app == null || activity.app.thread == null) { 8820 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8821 return extras; 8822 } 8823 if (activity.app.pid == Binder.getCallingPid()) { 8824 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8825 return extras; 8826 } 8827 pae = new PendingAssistExtras(activity); 8828 try { 8829 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8830 requestType); 8831 mPendingAssistExtras.add(pae); 8832 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8833 } catch (RemoteException e) { 8834 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8835 return extras; 8836 } 8837 } 8838 synchronized (pae) { 8839 while (!pae.haveResult) { 8840 try { 8841 pae.wait(); 8842 } catch (InterruptedException e) { 8843 } 8844 } 8845 if (pae.result != null) { 8846 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8847 } 8848 } 8849 synchronized (this) { 8850 mPendingAssistExtras.remove(pae); 8851 mHandler.removeCallbacks(pae); 8852 } 8853 return extras; 8854 } 8855 8856 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8857 PendingAssistExtras pae = (PendingAssistExtras)token; 8858 synchronized (pae) { 8859 pae.result = extras; 8860 pae.haveResult = true; 8861 pae.notifyAll(); 8862 } 8863 } 8864 8865 public void registerProcessObserver(IProcessObserver observer) { 8866 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8867 "registerProcessObserver()"); 8868 synchronized (this) { 8869 mProcessObservers.register(observer); 8870 } 8871 } 8872 8873 @Override 8874 public void unregisterProcessObserver(IProcessObserver observer) { 8875 synchronized (this) { 8876 mProcessObservers.unregister(observer); 8877 } 8878 } 8879 8880 @Override 8881 public boolean convertFromTranslucent(IBinder token) { 8882 final long origId = Binder.clearCallingIdentity(); 8883 try { 8884 synchronized (this) { 8885 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8886 if (r == null) { 8887 return false; 8888 } 8889 if (r.changeWindowTranslucency(true)) { 8890 mWindowManager.setAppFullscreen(token, true); 8891 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8892 return true; 8893 } 8894 return false; 8895 } 8896 } finally { 8897 Binder.restoreCallingIdentity(origId); 8898 } 8899 } 8900 8901 @Override 8902 public boolean convertToTranslucent(IBinder token) { 8903 final long origId = Binder.clearCallingIdentity(); 8904 try { 8905 synchronized (this) { 8906 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8907 if (r == null) { 8908 return false; 8909 } 8910 if (r.changeWindowTranslucency(false)) { 8911 r.task.stack.convertToTranslucent(r); 8912 mWindowManager.setAppFullscreen(token, false); 8913 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8914 return true; 8915 } 8916 return false; 8917 } 8918 } finally { 8919 Binder.restoreCallingIdentity(origId); 8920 } 8921 } 8922 8923 @Override 8924 public void setImmersive(IBinder token, boolean immersive) { 8925 synchronized(this) { 8926 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8927 if (r == null) { 8928 throw new IllegalArgumentException(); 8929 } 8930 r.immersive = immersive; 8931 8932 // update associated state if we're frontmost 8933 if (r == mFocusedActivity) { 8934 if (DEBUG_IMMERSIVE) { 8935 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8936 } 8937 applyUpdateLockStateLocked(r); 8938 } 8939 } 8940 } 8941 8942 @Override 8943 public boolean isImmersive(IBinder token) { 8944 synchronized (this) { 8945 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8946 if (r == null) { 8947 throw new IllegalArgumentException(); 8948 } 8949 return r.immersive; 8950 } 8951 } 8952 8953 public boolean isTopActivityImmersive() { 8954 enforceNotIsolatedCaller("startActivity"); 8955 synchronized (this) { 8956 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8957 return (r != null) ? r.immersive : false; 8958 } 8959 } 8960 8961 public final void enterSafeMode() { 8962 synchronized(this) { 8963 // It only makes sense to do this before the system is ready 8964 // and started launching other packages. 8965 if (!mSystemReady) { 8966 try { 8967 AppGlobals.getPackageManager().enterSafeMode(); 8968 } catch (RemoteException e) { 8969 } 8970 } 8971 8972 mSafeMode = true; 8973 } 8974 } 8975 8976 public final void showSafeModeOverlay() { 8977 View v = LayoutInflater.from(mContext).inflate( 8978 com.android.internal.R.layout.safe_mode, null); 8979 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8980 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8981 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8982 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8983 lp.gravity = Gravity.BOTTOM | Gravity.START; 8984 lp.format = v.getBackground().getOpacity(); 8985 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8986 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8987 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8988 ((WindowManager)mContext.getSystemService( 8989 Context.WINDOW_SERVICE)).addView(v, lp); 8990 } 8991 8992 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8993 if (!(sender instanceof PendingIntentRecord)) { 8994 return; 8995 } 8996 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8997 synchronized (stats) { 8998 if (mBatteryStatsService.isOnBattery()) { 8999 mBatteryStatsService.enforceCallingPermission(); 9000 PendingIntentRecord rec = (PendingIntentRecord)sender; 9001 int MY_UID = Binder.getCallingUid(); 9002 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9003 BatteryStatsImpl.Uid.Pkg pkg = 9004 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9005 sourcePkg != null ? sourcePkg : rec.key.packageName); 9006 pkg.incWakeupsLocked(); 9007 } 9008 } 9009 } 9010 9011 public boolean killPids(int[] pids, String pReason, boolean secure) { 9012 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9013 throw new SecurityException("killPids only available to the system"); 9014 } 9015 String reason = (pReason == null) ? "Unknown" : pReason; 9016 // XXX Note: don't acquire main activity lock here, because the window 9017 // manager calls in with its locks held. 9018 9019 boolean killed = false; 9020 synchronized (mPidsSelfLocked) { 9021 int[] types = new int[pids.length]; 9022 int worstType = 0; 9023 for (int i=0; i<pids.length; i++) { 9024 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9025 if (proc != null) { 9026 int type = proc.setAdj; 9027 types[i] = type; 9028 if (type > worstType) { 9029 worstType = type; 9030 } 9031 } 9032 } 9033 9034 // If the worst oom_adj is somewhere in the cached proc LRU range, 9035 // then constrain it so we will kill all cached procs. 9036 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9037 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9038 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9039 } 9040 9041 // If this is not a secure call, don't let it kill processes that 9042 // are important. 9043 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9044 worstType = ProcessList.SERVICE_ADJ; 9045 } 9046 9047 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9048 for (int i=0; i<pids.length; i++) { 9049 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9050 if (proc == null) { 9051 continue; 9052 } 9053 int adj = proc.setAdj; 9054 if (adj >= worstType && !proc.killedByAm) { 9055 killUnneededProcessLocked(proc, reason); 9056 killed = true; 9057 } 9058 } 9059 } 9060 return killed; 9061 } 9062 9063 @Override 9064 public void killUid(int uid, String reason) { 9065 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9066 throw new SecurityException("killUid only available to the system"); 9067 } 9068 synchronized (this) { 9069 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9070 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9071 reason != null ? reason : "kill uid"); 9072 } 9073 } 9074 9075 @Override 9076 public boolean killProcessesBelowForeground(String reason) { 9077 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9078 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9079 } 9080 9081 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9082 } 9083 9084 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9085 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9086 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9087 } 9088 9089 boolean killed = false; 9090 synchronized (mPidsSelfLocked) { 9091 final int size = mPidsSelfLocked.size(); 9092 for (int i = 0; i < size; i++) { 9093 final int pid = mPidsSelfLocked.keyAt(i); 9094 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9095 if (proc == null) continue; 9096 9097 final int adj = proc.setAdj; 9098 if (adj > belowAdj && !proc.killedByAm) { 9099 killUnneededProcessLocked(proc, reason); 9100 killed = true; 9101 } 9102 } 9103 } 9104 return killed; 9105 } 9106 9107 @Override 9108 public void hang(final IBinder who, boolean allowRestart) { 9109 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9110 != PackageManager.PERMISSION_GRANTED) { 9111 throw new SecurityException("Requires permission " 9112 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9113 } 9114 9115 final IBinder.DeathRecipient death = new DeathRecipient() { 9116 @Override 9117 public void binderDied() { 9118 synchronized (this) { 9119 notifyAll(); 9120 } 9121 } 9122 }; 9123 9124 try { 9125 who.linkToDeath(death, 0); 9126 } catch (RemoteException e) { 9127 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9128 return; 9129 } 9130 9131 synchronized (this) { 9132 Watchdog.getInstance().setAllowRestart(allowRestart); 9133 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9134 synchronized (death) { 9135 while (who.isBinderAlive()) { 9136 try { 9137 death.wait(); 9138 } catch (InterruptedException e) { 9139 } 9140 } 9141 } 9142 Watchdog.getInstance().setAllowRestart(true); 9143 } 9144 } 9145 9146 @Override 9147 public void restart() { 9148 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9149 != PackageManager.PERMISSION_GRANTED) { 9150 throw new SecurityException("Requires permission " 9151 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9152 } 9153 9154 Log.i(TAG, "Sending shutdown broadcast..."); 9155 9156 BroadcastReceiver br = new BroadcastReceiver() { 9157 @Override public void onReceive(Context context, Intent intent) { 9158 // Now the broadcast is done, finish up the low-level shutdown. 9159 Log.i(TAG, "Shutting down activity manager..."); 9160 shutdown(10000); 9161 Log.i(TAG, "Shutdown complete, restarting!"); 9162 Process.killProcess(Process.myPid()); 9163 System.exit(10); 9164 } 9165 }; 9166 9167 // First send the high-level shut down broadcast. 9168 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9169 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9170 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9171 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9172 mContext.sendOrderedBroadcastAsUser(intent, 9173 UserHandle.ALL, null, br, mHandler, 0, null, null); 9174 */ 9175 br.onReceive(mContext, intent); 9176 } 9177 9178 private long getLowRamTimeSinceIdle(long now) { 9179 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9180 } 9181 9182 @Override 9183 public void performIdleMaintenance() { 9184 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9185 != PackageManager.PERMISSION_GRANTED) { 9186 throw new SecurityException("Requires permission " 9187 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9188 } 9189 9190 synchronized (this) { 9191 final long now = SystemClock.uptimeMillis(); 9192 final long timeSinceLastIdle = now - mLastIdleTime; 9193 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9194 mLastIdleTime = now; 9195 mLowRamTimeSinceLastIdle = 0; 9196 if (mLowRamStartTime != 0) { 9197 mLowRamStartTime = now; 9198 } 9199 9200 StringBuilder sb = new StringBuilder(128); 9201 sb.append("Idle maintenance over "); 9202 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9203 sb.append(" low RAM for "); 9204 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9205 Slog.i(TAG, sb.toString()); 9206 9207 // If at least 1/3 of our time since the last idle period has been spent 9208 // with RAM low, then we want to kill processes. 9209 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9210 9211 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9212 ProcessRecord proc = mLruProcesses.get(i); 9213 if (proc.notCachedSinceIdle) { 9214 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9215 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9216 if (doKilling && proc.initialIdlePss != 0 9217 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9218 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9219 + " from " + proc.initialIdlePss + ")"); 9220 } 9221 } 9222 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9223 proc.notCachedSinceIdle = true; 9224 proc.initialIdlePss = 0; 9225 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9226 mSleeping, now); 9227 } 9228 } 9229 9230 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9231 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9232 } 9233 } 9234 9235 public final void startRunning(String pkg, String cls, String action, 9236 String data) { 9237 synchronized(this) { 9238 if (mStartRunning) { 9239 return; 9240 } 9241 mStartRunning = true; 9242 mTopComponent = pkg != null && cls != null 9243 ? new ComponentName(pkg, cls) : null; 9244 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9245 mTopData = data; 9246 if (!mSystemReady) { 9247 return; 9248 } 9249 } 9250 9251 systemReady(null); 9252 } 9253 9254 private void retrieveSettings() { 9255 final ContentResolver resolver = mContext.getContentResolver(); 9256 String debugApp = Settings.Global.getString( 9257 resolver, Settings.Global.DEBUG_APP); 9258 boolean waitForDebugger = Settings.Global.getInt( 9259 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9260 boolean alwaysFinishActivities = Settings.Global.getInt( 9261 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9262 boolean forceRtl = Settings.Global.getInt( 9263 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9264 // Transfer any global setting for forcing RTL layout, into a System Property 9265 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9266 9267 Configuration configuration = new Configuration(); 9268 Settings.System.getConfiguration(resolver, configuration); 9269 if (forceRtl) { 9270 // This will take care of setting the correct layout direction flags 9271 configuration.setLayoutDirection(configuration.locale); 9272 } 9273 9274 synchronized (this) { 9275 mDebugApp = mOrigDebugApp = debugApp; 9276 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9277 mAlwaysFinishActivities = alwaysFinishActivities; 9278 // This happens before any activities are started, so we can 9279 // change mConfiguration in-place. 9280 updateConfigurationLocked(configuration, null, false, true); 9281 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9282 } 9283 } 9284 9285 public boolean testIsSystemReady() { 9286 // no need to synchronize(this) just to read & return the value 9287 return mSystemReady; 9288 } 9289 9290 private static File getCalledPreBootReceiversFile() { 9291 File dataDir = Environment.getDataDirectory(); 9292 File systemDir = new File(dataDir, "system"); 9293 File fname = new File(systemDir, "called_pre_boots.dat"); 9294 return fname; 9295 } 9296 9297 static final int LAST_DONE_VERSION = 10000; 9298 9299 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9300 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9301 File file = getCalledPreBootReceiversFile(); 9302 FileInputStream fis = null; 9303 try { 9304 fis = new FileInputStream(file); 9305 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9306 int fvers = dis.readInt(); 9307 if (fvers == LAST_DONE_VERSION) { 9308 String vers = dis.readUTF(); 9309 String codename = dis.readUTF(); 9310 String build = dis.readUTF(); 9311 if (android.os.Build.VERSION.RELEASE.equals(vers) 9312 && android.os.Build.VERSION.CODENAME.equals(codename) 9313 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9314 int num = dis.readInt(); 9315 while (num > 0) { 9316 num--; 9317 String pkg = dis.readUTF(); 9318 String cls = dis.readUTF(); 9319 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9320 } 9321 } 9322 } 9323 } catch (FileNotFoundException e) { 9324 } catch (IOException e) { 9325 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9326 } finally { 9327 if (fis != null) { 9328 try { 9329 fis.close(); 9330 } catch (IOException e) { 9331 } 9332 } 9333 } 9334 return lastDoneReceivers; 9335 } 9336 9337 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9338 File file = getCalledPreBootReceiversFile(); 9339 FileOutputStream fos = null; 9340 DataOutputStream dos = null; 9341 try { 9342 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9343 fos = new FileOutputStream(file); 9344 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9345 dos.writeInt(LAST_DONE_VERSION); 9346 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9347 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9348 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9349 dos.writeInt(list.size()); 9350 for (int i=0; i<list.size(); i++) { 9351 dos.writeUTF(list.get(i).getPackageName()); 9352 dos.writeUTF(list.get(i).getClassName()); 9353 } 9354 } catch (IOException e) { 9355 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9356 file.delete(); 9357 } finally { 9358 FileUtils.sync(fos); 9359 if (dos != null) { 9360 try { 9361 dos.close(); 9362 } catch (IOException e) { 9363 // TODO Auto-generated catch block 9364 e.printStackTrace(); 9365 } 9366 } 9367 } 9368 } 9369 9370 public void systemReady(final Runnable goingCallback) { 9371 synchronized(this) { 9372 if (mSystemReady) { 9373 if (goingCallback != null) goingCallback.run(); 9374 return; 9375 } 9376 9377 // Check to see if there are any update receivers to run. 9378 if (!mDidUpdate) { 9379 if (mWaitingUpdate) { 9380 return; 9381 } 9382 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9383 List<ResolveInfo> ris = null; 9384 try { 9385 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9386 intent, null, 0, 0); 9387 } catch (RemoteException e) { 9388 } 9389 if (ris != null) { 9390 for (int i=ris.size()-1; i>=0; i--) { 9391 if ((ris.get(i).activityInfo.applicationInfo.flags 9392 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9393 ris.remove(i); 9394 } 9395 } 9396 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9397 9398 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9399 9400 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9401 for (int i=0; i<ris.size(); i++) { 9402 ActivityInfo ai = ris.get(i).activityInfo; 9403 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9404 if (lastDoneReceivers.contains(comp)) { 9405 // We already did the pre boot receiver for this app with the current 9406 // platform version, so don't do it again... 9407 ris.remove(i); 9408 i--; 9409 // ...however, do keep it as one that has been done, so we don't 9410 // forget about it when rewriting the file of last done receivers. 9411 doneReceivers.add(comp); 9412 } 9413 } 9414 9415 final int[] users = getUsersLocked(); 9416 for (int i=0; i<ris.size(); i++) { 9417 ActivityInfo ai = ris.get(i).activityInfo; 9418 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9419 doneReceivers.add(comp); 9420 intent.setComponent(comp); 9421 for (int j=0; j<users.length; j++) { 9422 IIntentReceiver finisher = null; 9423 if (i == ris.size()-1 && j == users.length-1) { 9424 finisher = new IIntentReceiver.Stub() { 9425 public void performReceive(Intent intent, int resultCode, 9426 String data, Bundle extras, boolean ordered, 9427 boolean sticky, int sendingUser) { 9428 // The raw IIntentReceiver interface is called 9429 // with the AM lock held, so redispatch to 9430 // execute our code without the lock. 9431 mHandler.post(new Runnable() { 9432 public void run() { 9433 synchronized (ActivityManagerService.this) { 9434 mDidUpdate = true; 9435 } 9436 writeLastDonePreBootReceivers(doneReceivers); 9437 showBootMessage(mContext.getText( 9438 R.string.android_upgrading_complete), 9439 false); 9440 systemReady(goingCallback); 9441 } 9442 }); 9443 } 9444 }; 9445 } 9446 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9447 + " for user " + users[j]); 9448 broadcastIntentLocked(null, null, intent, null, finisher, 9449 0, null, null, null, AppOpsManager.OP_NONE, 9450 true, false, MY_PID, Process.SYSTEM_UID, 9451 users[j]); 9452 if (finisher != null) { 9453 mWaitingUpdate = true; 9454 } 9455 } 9456 } 9457 } 9458 if (mWaitingUpdate) { 9459 return; 9460 } 9461 mDidUpdate = true; 9462 } 9463 9464 mAppOpsService.systemReady(); 9465 mSystemReady = true; 9466 if (!mStartRunning) { 9467 return; 9468 } 9469 } 9470 9471 ArrayList<ProcessRecord> procsToKill = null; 9472 synchronized(mPidsSelfLocked) { 9473 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9474 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9475 if (!isAllowedWhileBooting(proc.info)){ 9476 if (procsToKill == null) { 9477 procsToKill = new ArrayList<ProcessRecord>(); 9478 } 9479 procsToKill.add(proc); 9480 } 9481 } 9482 } 9483 9484 synchronized(this) { 9485 if (procsToKill != null) { 9486 for (int i=procsToKill.size()-1; i>=0; i--) { 9487 ProcessRecord proc = procsToKill.get(i); 9488 Slog.i(TAG, "Removing system update proc: " + proc); 9489 removeProcessLocked(proc, true, false, "system update done"); 9490 } 9491 } 9492 9493 // Now that we have cleaned up any update processes, we 9494 // are ready to start launching real processes and know that 9495 // we won't trample on them any more. 9496 mProcessesReady = true; 9497 } 9498 9499 Slog.i(TAG, "System now ready"); 9500 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9501 SystemClock.uptimeMillis()); 9502 9503 synchronized(this) { 9504 // Make sure we have no pre-ready processes sitting around. 9505 9506 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9507 ResolveInfo ri = mContext.getPackageManager() 9508 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9509 STOCK_PM_FLAGS); 9510 CharSequence errorMsg = null; 9511 if (ri != null) { 9512 ActivityInfo ai = ri.activityInfo; 9513 ApplicationInfo app = ai.applicationInfo; 9514 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9515 mTopAction = Intent.ACTION_FACTORY_TEST; 9516 mTopData = null; 9517 mTopComponent = new ComponentName(app.packageName, 9518 ai.name); 9519 } else { 9520 errorMsg = mContext.getResources().getText( 9521 com.android.internal.R.string.factorytest_not_system); 9522 } 9523 } else { 9524 errorMsg = mContext.getResources().getText( 9525 com.android.internal.R.string.factorytest_no_action); 9526 } 9527 if (errorMsg != null) { 9528 mTopAction = null; 9529 mTopData = null; 9530 mTopComponent = null; 9531 Message msg = Message.obtain(); 9532 msg.what = SHOW_FACTORY_ERROR_MSG; 9533 msg.getData().putCharSequence("msg", errorMsg); 9534 mHandler.sendMessage(msg); 9535 } 9536 } 9537 } 9538 9539 retrieveSettings(); 9540 9541 synchronized (this) { 9542 readGrantedUriPermissionsLocked(); 9543 } 9544 9545 if (goingCallback != null) goingCallback.run(); 9546 9547 synchronized (this) { 9548 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9549 try { 9550 List apps = AppGlobals.getPackageManager(). 9551 getPersistentApplications(STOCK_PM_FLAGS); 9552 if (apps != null) { 9553 int N = apps.size(); 9554 int i; 9555 for (i=0; i<N; i++) { 9556 ApplicationInfo info 9557 = (ApplicationInfo)apps.get(i); 9558 if (info != null && 9559 !info.packageName.equals("android")) { 9560 addAppLocked(info, false); 9561 } 9562 } 9563 } 9564 } catch (RemoteException ex) { 9565 // pm is in same process, this will never happen. 9566 } 9567 } 9568 9569 // Start up initial activity. 9570 mBooting = true; 9571 9572 try { 9573 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9574 Message msg = Message.obtain(); 9575 msg.what = SHOW_UID_ERROR_MSG; 9576 mHandler.sendMessage(msg); 9577 } 9578 } catch (RemoteException e) { 9579 } 9580 9581 long ident = Binder.clearCallingIdentity(); 9582 try { 9583 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9584 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9585 | Intent.FLAG_RECEIVER_FOREGROUND); 9586 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9587 broadcastIntentLocked(null, null, intent, 9588 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9589 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9590 intent = new Intent(Intent.ACTION_USER_STARTING); 9591 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9592 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9593 broadcastIntentLocked(null, null, intent, 9594 null, new IIntentReceiver.Stub() { 9595 @Override 9596 public void performReceive(Intent intent, int resultCode, String data, 9597 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9598 throws RemoteException { 9599 } 9600 }, 0, null, null, 9601 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9602 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9603 } finally { 9604 Binder.restoreCallingIdentity(ident); 9605 } 9606 mStackSupervisor.resumeTopActivitiesLocked(); 9607 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9608 } 9609 } 9610 9611 private boolean makeAppCrashingLocked(ProcessRecord app, 9612 String shortMsg, String longMsg, String stackTrace) { 9613 app.crashing = true; 9614 app.crashingReport = generateProcessError(app, 9615 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9616 startAppProblemLocked(app); 9617 app.stopFreezingAllLocked(); 9618 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9619 } 9620 9621 private void makeAppNotRespondingLocked(ProcessRecord app, 9622 String activity, String shortMsg, String longMsg) { 9623 app.notResponding = true; 9624 app.notRespondingReport = generateProcessError(app, 9625 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9626 activity, shortMsg, longMsg, null); 9627 startAppProblemLocked(app); 9628 app.stopFreezingAllLocked(); 9629 } 9630 9631 /** 9632 * Generate a process error record, suitable for attachment to a ProcessRecord. 9633 * 9634 * @param app The ProcessRecord in which the error occurred. 9635 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9636 * ActivityManager.AppErrorStateInfo 9637 * @param activity The activity associated with the crash, if known. 9638 * @param shortMsg Short message describing the crash. 9639 * @param longMsg Long message describing the crash. 9640 * @param stackTrace Full crash stack trace, may be null. 9641 * 9642 * @return Returns a fully-formed AppErrorStateInfo record. 9643 */ 9644 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9645 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9646 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9647 9648 report.condition = condition; 9649 report.processName = app.processName; 9650 report.pid = app.pid; 9651 report.uid = app.info.uid; 9652 report.tag = activity; 9653 report.shortMsg = shortMsg; 9654 report.longMsg = longMsg; 9655 report.stackTrace = stackTrace; 9656 9657 return report; 9658 } 9659 9660 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9661 synchronized (this) { 9662 app.crashing = false; 9663 app.crashingReport = null; 9664 app.notResponding = false; 9665 app.notRespondingReport = null; 9666 if (app.anrDialog == fromDialog) { 9667 app.anrDialog = null; 9668 } 9669 if (app.waitDialog == fromDialog) { 9670 app.waitDialog = null; 9671 } 9672 if (app.pid > 0 && app.pid != MY_PID) { 9673 handleAppCrashLocked(app, null, null, null); 9674 killUnneededProcessLocked(app, "user request after error"); 9675 } 9676 } 9677 } 9678 9679 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9680 String stackTrace) { 9681 long now = SystemClock.uptimeMillis(); 9682 9683 Long crashTime; 9684 if (!app.isolated) { 9685 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9686 } else { 9687 crashTime = null; 9688 } 9689 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9690 // This process loses! 9691 Slog.w(TAG, "Process " + app.info.processName 9692 + " has crashed too many times: killing!"); 9693 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9694 app.userId, app.info.processName, app.uid); 9695 mStackSupervisor.handleAppCrashLocked(app); 9696 if (!app.persistent) { 9697 // We don't want to start this process again until the user 9698 // explicitly does so... but for persistent process, we really 9699 // need to keep it running. If a persistent process is actually 9700 // repeatedly crashing, then badness for everyone. 9701 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9702 app.info.processName); 9703 if (!app.isolated) { 9704 // XXX We don't have a way to mark isolated processes 9705 // as bad, since they don't have a peristent identity. 9706 mBadProcesses.put(app.info.processName, app.uid, 9707 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9708 mProcessCrashTimes.remove(app.info.processName, app.uid); 9709 } 9710 app.bad = true; 9711 app.removed = true; 9712 // Don't let services in this process be restarted and potentially 9713 // annoy the user repeatedly. Unless it is persistent, since those 9714 // processes run critical code. 9715 removeProcessLocked(app, false, false, "crash"); 9716 mStackSupervisor.resumeTopActivitiesLocked(); 9717 return false; 9718 } 9719 mStackSupervisor.resumeTopActivitiesLocked(); 9720 } else { 9721 mStackSupervisor.finishTopRunningActivityLocked(app); 9722 } 9723 9724 // Bump up the crash count of any services currently running in the proc. 9725 for (int i=app.services.size()-1; i>=0; i--) { 9726 // Any services running in the application need to be placed 9727 // back in the pending list. 9728 ServiceRecord sr = app.services.valueAt(i); 9729 sr.crashCount++; 9730 } 9731 9732 // If the crashing process is what we consider to be the "home process" and it has been 9733 // replaced by a third-party app, clear the package preferred activities from packages 9734 // with a home activity running in the process to prevent a repeatedly crashing app 9735 // from blocking the user to manually clear the list. 9736 final ArrayList<ActivityRecord> activities = app.activities; 9737 if (app == mHomeProcess && activities.size() > 0 9738 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9739 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9740 final ActivityRecord r = activities.get(activityNdx); 9741 if (r.isHomeActivity()) { 9742 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9743 try { 9744 ActivityThread.getPackageManager() 9745 .clearPackagePreferredActivities(r.packageName); 9746 } catch (RemoteException c) { 9747 // pm is in same process, this will never happen. 9748 } 9749 } 9750 } 9751 } 9752 9753 if (!app.isolated) { 9754 // XXX Can't keep track of crash times for isolated processes, 9755 // because they don't have a perisistent identity. 9756 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9757 } 9758 9759 return true; 9760 } 9761 9762 void startAppProblemLocked(ProcessRecord app) { 9763 if (app.userId == mCurrentUserId) { 9764 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9765 mContext, app.info.packageName, app.info.flags); 9766 } else { 9767 // If this app is not running under the current user, then we 9768 // can't give it a report button because that would require 9769 // launching the report UI under a different user. 9770 app.errorReportReceiver = null; 9771 } 9772 skipCurrentReceiverLocked(app); 9773 } 9774 9775 void skipCurrentReceiverLocked(ProcessRecord app) { 9776 for (BroadcastQueue queue : mBroadcastQueues) { 9777 queue.skipCurrentReceiverLocked(app); 9778 } 9779 } 9780 9781 /** 9782 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9783 * The application process will exit immediately after this call returns. 9784 * @param app object of the crashing app, null for the system server 9785 * @param crashInfo describing the exception 9786 */ 9787 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9788 ProcessRecord r = findAppProcess(app, "Crash"); 9789 final String processName = app == null ? "system_server" 9790 : (r == null ? "unknown" : r.processName); 9791 9792 handleApplicationCrashInner("crash", r, processName, crashInfo); 9793 } 9794 9795 /* Native crash reporting uses this inner version because it needs to be somewhat 9796 * decoupled from the AM-managed cleanup lifecycle 9797 */ 9798 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9799 ApplicationErrorReport.CrashInfo crashInfo) { 9800 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9801 UserHandle.getUserId(Binder.getCallingUid()), processName, 9802 r == null ? -1 : r.info.flags, 9803 crashInfo.exceptionClassName, 9804 crashInfo.exceptionMessage, 9805 crashInfo.throwFileName, 9806 crashInfo.throwLineNumber); 9807 9808 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9809 9810 crashApplication(r, crashInfo); 9811 } 9812 9813 public void handleApplicationStrictModeViolation( 9814 IBinder app, 9815 int violationMask, 9816 StrictMode.ViolationInfo info) { 9817 ProcessRecord r = findAppProcess(app, "StrictMode"); 9818 if (r == null) { 9819 return; 9820 } 9821 9822 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9823 Integer stackFingerprint = info.hashCode(); 9824 boolean logIt = true; 9825 synchronized (mAlreadyLoggedViolatedStacks) { 9826 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9827 logIt = false; 9828 // TODO: sub-sample into EventLog for these, with 9829 // the info.durationMillis? Then we'd get 9830 // the relative pain numbers, without logging all 9831 // the stack traces repeatedly. We'd want to do 9832 // likewise in the client code, which also does 9833 // dup suppression, before the Binder call. 9834 } else { 9835 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9836 mAlreadyLoggedViolatedStacks.clear(); 9837 } 9838 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9839 } 9840 } 9841 if (logIt) { 9842 logStrictModeViolationToDropBox(r, info); 9843 } 9844 } 9845 9846 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9847 AppErrorResult result = new AppErrorResult(); 9848 synchronized (this) { 9849 final long origId = Binder.clearCallingIdentity(); 9850 9851 Message msg = Message.obtain(); 9852 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9853 HashMap<String, Object> data = new HashMap<String, Object>(); 9854 data.put("result", result); 9855 data.put("app", r); 9856 data.put("violationMask", violationMask); 9857 data.put("info", info); 9858 msg.obj = data; 9859 mHandler.sendMessage(msg); 9860 9861 Binder.restoreCallingIdentity(origId); 9862 } 9863 int res = result.get(); 9864 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9865 } 9866 } 9867 9868 // Depending on the policy in effect, there could be a bunch of 9869 // these in quick succession so we try to batch these together to 9870 // minimize disk writes, number of dropbox entries, and maximize 9871 // compression, by having more fewer, larger records. 9872 private void logStrictModeViolationToDropBox( 9873 ProcessRecord process, 9874 StrictMode.ViolationInfo info) { 9875 if (info == null) { 9876 return; 9877 } 9878 final boolean isSystemApp = process == null || 9879 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9880 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9881 final String processName = process == null ? "unknown" : process.processName; 9882 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9883 final DropBoxManager dbox = (DropBoxManager) 9884 mContext.getSystemService(Context.DROPBOX_SERVICE); 9885 9886 // Exit early if the dropbox isn't configured to accept this report type. 9887 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9888 9889 boolean bufferWasEmpty; 9890 boolean needsFlush; 9891 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9892 synchronized (sb) { 9893 bufferWasEmpty = sb.length() == 0; 9894 appendDropBoxProcessHeaders(process, processName, sb); 9895 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9896 sb.append("System-App: ").append(isSystemApp).append("\n"); 9897 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9898 if (info.violationNumThisLoop != 0) { 9899 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9900 } 9901 if (info.numAnimationsRunning != 0) { 9902 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9903 } 9904 if (info.broadcastIntentAction != null) { 9905 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9906 } 9907 if (info.durationMillis != -1) { 9908 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9909 } 9910 if (info.numInstances != -1) { 9911 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9912 } 9913 if (info.tags != null) { 9914 for (String tag : info.tags) { 9915 sb.append("Span-Tag: ").append(tag).append("\n"); 9916 } 9917 } 9918 sb.append("\n"); 9919 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9920 sb.append(info.crashInfo.stackTrace); 9921 } 9922 sb.append("\n"); 9923 9924 // Only buffer up to ~64k. Various logging bits truncate 9925 // things at 128k. 9926 needsFlush = (sb.length() > 64 * 1024); 9927 } 9928 9929 // Flush immediately if the buffer's grown too large, or this 9930 // is a non-system app. Non-system apps are isolated with a 9931 // different tag & policy and not batched. 9932 // 9933 // Batching is useful during internal testing with 9934 // StrictMode settings turned up high. Without batching, 9935 // thousands of separate files could be created on boot. 9936 if (!isSystemApp || needsFlush) { 9937 new Thread("Error dump: " + dropboxTag) { 9938 @Override 9939 public void run() { 9940 String report; 9941 synchronized (sb) { 9942 report = sb.toString(); 9943 sb.delete(0, sb.length()); 9944 sb.trimToSize(); 9945 } 9946 if (report.length() != 0) { 9947 dbox.addText(dropboxTag, report); 9948 } 9949 } 9950 }.start(); 9951 return; 9952 } 9953 9954 // System app batching: 9955 if (!bufferWasEmpty) { 9956 // An existing dropbox-writing thread is outstanding, so 9957 // we don't need to start it up. The existing thread will 9958 // catch the buffer appends we just did. 9959 return; 9960 } 9961 9962 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9963 // (After this point, we shouldn't access AMS internal data structures.) 9964 new Thread("Error dump: " + dropboxTag) { 9965 @Override 9966 public void run() { 9967 // 5 second sleep to let stacks arrive and be batched together 9968 try { 9969 Thread.sleep(5000); // 5 seconds 9970 } catch (InterruptedException e) {} 9971 9972 String errorReport; 9973 synchronized (mStrictModeBuffer) { 9974 errorReport = mStrictModeBuffer.toString(); 9975 if (errorReport.length() == 0) { 9976 return; 9977 } 9978 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9979 mStrictModeBuffer.trimToSize(); 9980 } 9981 dbox.addText(dropboxTag, errorReport); 9982 } 9983 }.start(); 9984 } 9985 9986 /** 9987 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9988 * @param app object of the crashing app, null for the system server 9989 * @param tag reported by the caller 9990 * @param crashInfo describing the context of the error 9991 * @return true if the process should exit immediately (WTF is fatal) 9992 */ 9993 public boolean handleApplicationWtf(IBinder app, String tag, 9994 ApplicationErrorReport.CrashInfo crashInfo) { 9995 ProcessRecord r = findAppProcess(app, "WTF"); 9996 final String processName = app == null ? "system_server" 9997 : (r == null ? "unknown" : r.processName); 9998 9999 EventLog.writeEvent(EventLogTags.AM_WTF, 10000 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10001 processName, 10002 r == null ? -1 : r.info.flags, 10003 tag, crashInfo.exceptionMessage); 10004 10005 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10006 10007 if (r != null && r.pid != Process.myPid() && 10008 Settings.Global.getInt(mContext.getContentResolver(), 10009 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10010 crashApplication(r, crashInfo); 10011 return true; 10012 } else { 10013 return false; 10014 } 10015 } 10016 10017 /** 10018 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10019 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10020 */ 10021 private ProcessRecord findAppProcess(IBinder app, String reason) { 10022 if (app == null) { 10023 return null; 10024 } 10025 10026 synchronized (this) { 10027 final int NP = mProcessNames.getMap().size(); 10028 for (int ip=0; ip<NP; ip++) { 10029 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10030 final int NA = apps.size(); 10031 for (int ia=0; ia<NA; ia++) { 10032 ProcessRecord p = apps.valueAt(ia); 10033 if (p.thread != null && p.thread.asBinder() == app) { 10034 return p; 10035 } 10036 } 10037 } 10038 10039 Slog.w(TAG, "Can't find mystery application for " + reason 10040 + " from pid=" + Binder.getCallingPid() 10041 + " uid=" + Binder.getCallingUid() + ": " + app); 10042 return null; 10043 } 10044 } 10045 10046 /** 10047 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10048 * to append various headers to the dropbox log text. 10049 */ 10050 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10051 StringBuilder sb) { 10052 // Watchdog thread ends up invoking this function (with 10053 // a null ProcessRecord) to add the stack file to dropbox. 10054 // Do not acquire a lock on this (am) in such cases, as it 10055 // could cause a potential deadlock, if and when watchdog 10056 // is invoked due to unavailability of lock on am and it 10057 // would prevent watchdog from killing system_server. 10058 if (process == null) { 10059 sb.append("Process: ").append(processName).append("\n"); 10060 return; 10061 } 10062 // Note: ProcessRecord 'process' is guarded by the service 10063 // instance. (notably process.pkgList, which could otherwise change 10064 // concurrently during execution of this method) 10065 synchronized (this) { 10066 sb.append("Process: ").append(processName).append("\n"); 10067 int flags = process.info.flags; 10068 IPackageManager pm = AppGlobals.getPackageManager(); 10069 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10070 for (int ip=0; ip<process.pkgList.size(); ip++) { 10071 String pkg = process.pkgList.keyAt(ip); 10072 sb.append("Package: ").append(pkg); 10073 try { 10074 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10075 if (pi != null) { 10076 sb.append(" v").append(pi.versionCode); 10077 if (pi.versionName != null) { 10078 sb.append(" (").append(pi.versionName).append(")"); 10079 } 10080 } 10081 } catch (RemoteException e) { 10082 Slog.e(TAG, "Error getting package info: " + pkg, e); 10083 } 10084 sb.append("\n"); 10085 } 10086 } 10087 } 10088 10089 private static String processClass(ProcessRecord process) { 10090 if (process == null || process.pid == MY_PID) { 10091 return "system_server"; 10092 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10093 return "system_app"; 10094 } else { 10095 return "data_app"; 10096 } 10097 } 10098 10099 /** 10100 * Write a description of an error (crash, WTF, ANR) to the drop box. 10101 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10102 * @param process which caused the error, null means the system server 10103 * @param activity which triggered the error, null if unknown 10104 * @param parent activity related to the error, null if unknown 10105 * @param subject line related to the error, null if absent 10106 * @param report in long form describing the error, null if absent 10107 * @param logFile to include in the report, null if none 10108 * @param crashInfo giving an application stack trace, null if absent 10109 */ 10110 public void addErrorToDropBox(String eventType, 10111 ProcessRecord process, String processName, ActivityRecord activity, 10112 ActivityRecord parent, String subject, 10113 final String report, final File logFile, 10114 final ApplicationErrorReport.CrashInfo crashInfo) { 10115 // NOTE -- this must never acquire the ActivityManagerService lock, 10116 // otherwise the watchdog may be prevented from resetting the system. 10117 10118 final String dropboxTag = processClass(process) + "_" + eventType; 10119 final DropBoxManager dbox = (DropBoxManager) 10120 mContext.getSystemService(Context.DROPBOX_SERVICE); 10121 10122 // Exit early if the dropbox isn't configured to accept this report type. 10123 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10124 10125 final StringBuilder sb = new StringBuilder(1024); 10126 appendDropBoxProcessHeaders(process, processName, sb); 10127 if (activity != null) { 10128 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10129 } 10130 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10131 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10132 } 10133 if (parent != null && parent != activity) { 10134 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10135 } 10136 if (subject != null) { 10137 sb.append("Subject: ").append(subject).append("\n"); 10138 } 10139 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10140 if (Debug.isDebuggerConnected()) { 10141 sb.append("Debugger: Connected\n"); 10142 } 10143 sb.append("\n"); 10144 10145 // Do the rest in a worker thread to avoid blocking the caller on I/O 10146 // (After this point, we shouldn't access AMS internal data structures.) 10147 Thread worker = new Thread("Error dump: " + dropboxTag) { 10148 @Override 10149 public void run() { 10150 if (report != null) { 10151 sb.append(report); 10152 } 10153 if (logFile != null) { 10154 try { 10155 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10156 "\n\n[[TRUNCATED]]")); 10157 } catch (IOException e) { 10158 Slog.e(TAG, "Error reading " + logFile, e); 10159 } 10160 } 10161 if (crashInfo != null && crashInfo.stackTrace != null) { 10162 sb.append(crashInfo.stackTrace); 10163 } 10164 10165 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10166 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10167 if (lines > 0) { 10168 sb.append("\n"); 10169 10170 // Merge several logcat streams, and take the last N lines 10171 InputStreamReader input = null; 10172 try { 10173 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10174 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10175 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10176 10177 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10178 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10179 input = new InputStreamReader(logcat.getInputStream()); 10180 10181 int num; 10182 char[] buf = new char[8192]; 10183 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10184 } catch (IOException e) { 10185 Slog.e(TAG, "Error running logcat", e); 10186 } finally { 10187 if (input != null) try { input.close(); } catch (IOException e) {} 10188 } 10189 } 10190 10191 dbox.addText(dropboxTag, sb.toString()); 10192 } 10193 }; 10194 10195 if (process == null) { 10196 // If process is null, we are being called from some internal code 10197 // and may be about to die -- run this synchronously. 10198 worker.run(); 10199 } else { 10200 worker.start(); 10201 } 10202 } 10203 10204 /** 10205 * Bring up the "unexpected error" dialog box for a crashing app. 10206 * Deal with edge cases (intercepts from instrumented applications, 10207 * ActivityController, error intent receivers, that sort of thing). 10208 * @param r the application crashing 10209 * @param crashInfo describing the failure 10210 */ 10211 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10212 long timeMillis = System.currentTimeMillis(); 10213 String shortMsg = crashInfo.exceptionClassName; 10214 String longMsg = crashInfo.exceptionMessage; 10215 String stackTrace = crashInfo.stackTrace; 10216 if (shortMsg != null && longMsg != null) { 10217 longMsg = shortMsg + ": " + longMsg; 10218 } else if (shortMsg != null) { 10219 longMsg = shortMsg; 10220 } 10221 10222 AppErrorResult result = new AppErrorResult(); 10223 synchronized (this) { 10224 if (mController != null) { 10225 try { 10226 String name = r != null ? r.processName : null; 10227 int pid = r != null ? r.pid : Binder.getCallingPid(); 10228 if (!mController.appCrashed(name, pid, 10229 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10230 Slog.w(TAG, "Force-killing crashed app " + name 10231 + " at watcher's request"); 10232 Process.killProcess(pid); 10233 return; 10234 } 10235 } catch (RemoteException e) { 10236 mController = null; 10237 Watchdog.getInstance().setActivityController(null); 10238 } 10239 } 10240 10241 final long origId = Binder.clearCallingIdentity(); 10242 10243 // If this process is running instrumentation, finish it. 10244 if (r != null && r.instrumentationClass != null) { 10245 Slog.w(TAG, "Error in app " + r.processName 10246 + " running instrumentation " + r.instrumentationClass + ":"); 10247 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10248 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10249 Bundle info = new Bundle(); 10250 info.putString("shortMsg", shortMsg); 10251 info.putString("longMsg", longMsg); 10252 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10253 Binder.restoreCallingIdentity(origId); 10254 return; 10255 } 10256 10257 // If we can't identify the process or it's already exceeded its crash quota, 10258 // quit right away without showing a crash dialog. 10259 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10260 Binder.restoreCallingIdentity(origId); 10261 return; 10262 } 10263 10264 Message msg = Message.obtain(); 10265 msg.what = SHOW_ERROR_MSG; 10266 HashMap data = new HashMap(); 10267 data.put("result", result); 10268 data.put("app", r); 10269 msg.obj = data; 10270 mHandler.sendMessage(msg); 10271 10272 Binder.restoreCallingIdentity(origId); 10273 } 10274 10275 int res = result.get(); 10276 10277 Intent appErrorIntent = null; 10278 synchronized (this) { 10279 if (r != null && !r.isolated) { 10280 // XXX Can't keep track of crash time for isolated processes, 10281 // since they don't have a persistent identity. 10282 mProcessCrashTimes.put(r.info.processName, r.uid, 10283 SystemClock.uptimeMillis()); 10284 } 10285 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10286 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10287 } 10288 } 10289 10290 if (appErrorIntent != null) { 10291 try { 10292 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10293 } catch (ActivityNotFoundException e) { 10294 Slog.w(TAG, "bug report receiver dissappeared", e); 10295 } 10296 } 10297 } 10298 10299 Intent createAppErrorIntentLocked(ProcessRecord r, 10300 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10301 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10302 if (report == null) { 10303 return null; 10304 } 10305 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10306 result.setComponent(r.errorReportReceiver); 10307 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10308 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10309 return result; 10310 } 10311 10312 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10313 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10314 if (r.errorReportReceiver == null) { 10315 return null; 10316 } 10317 10318 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10319 return null; 10320 } 10321 10322 ApplicationErrorReport report = new ApplicationErrorReport(); 10323 report.packageName = r.info.packageName; 10324 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10325 report.processName = r.processName; 10326 report.time = timeMillis; 10327 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10328 10329 if (r.crashing || r.forceCrashReport) { 10330 report.type = ApplicationErrorReport.TYPE_CRASH; 10331 report.crashInfo = crashInfo; 10332 } else if (r.notResponding) { 10333 report.type = ApplicationErrorReport.TYPE_ANR; 10334 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10335 10336 report.anrInfo.activity = r.notRespondingReport.tag; 10337 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10338 report.anrInfo.info = r.notRespondingReport.longMsg; 10339 } 10340 10341 return report; 10342 } 10343 10344 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10345 enforceNotIsolatedCaller("getProcessesInErrorState"); 10346 // assume our apps are happy - lazy create the list 10347 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10348 10349 final boolean allUsers = ActivityManager.checkUidPermission( 10350 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10351 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10352 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10353 10354 synchronized (this) { 10355 10356 // iterate across all processes 10357 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10358 ProcessRecord app = mLruProcesses.get(i); 10359 if (!allUsers && app.userId != userId) { 10360 continue; 10361 } 10362 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10363 // This one's in trouble, so we'll generate a report for it 10364 // crashes are higher priority (in case there's a crash *and* an anr) 10365 ActivityManager.ProcessErrorStateInfo report = null; 10366 if (app.crashing) { 10367 report = app.crashingReport; 10368 } else if (app.notResponding) { 10369 report = app.notRespondingReport; 10370 } 10371 10372 if (report != null) { 10373 if (errList == null) { 10374 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10375 } 10376 errList.add(report); 10377 } else { 10378 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10379 " crashing = " + app.crashing + 10380 " notResponding = " + app.notResponding); 10381 } 10382 } 10383 } 10384 } 10385 10386 return errList; 10387 } 10388 10389 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10390 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10391 if (currApp != null) { 10392 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10393 } 10394 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10395 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10396 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10397 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10398 if (currApp != null) { 10399 currApp.lru = 0; 10400 } 10401 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10402 } else if (adj >= ProcessList.SERVICE_ADJ) { 10403 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10404 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10405 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10406 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10407 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10408 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10409 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10410 } else { 10411 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10412 } 10413 } 10414 10415 private void fillInProcMemInfo(ProcessRecord app, 10416 ActivityManager.RunningAppProcessInfo outInfo) { 10417 outInfo.pid = app.pid; 10418 outInfo.uid = app.info.uid; 10419 if (mHeavyWeightProcess == app) { 10420 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10421 } 10422 if (app.persistent) { 10423 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10424 } 10425 if (app.activities.size() > 0) { 10426 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10427 } 10428 outInfo.lastTrimLevel = app.trimMemoryLevel; 10429 int adj = app.curAdj; 10430 outInfo.importance = oomAdjToImportance(adj, outInfo); 10431 outInfo.importanceReasonCode = app.adjTypeCode; 10432 } 10433 10434 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10435 enforceNotIsolatedCaller("getRunningAppProcesses"); 10436 // Lazy instantiation of list 10437 List<ActivityManager.RunningAppProcessInfo> runList = null; 10438 final boolean allUsers = ActivityManager.checkUidPermission( 10439 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10440 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10441 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10442 synchronized (this) { 10443 // Iterate across all processes 10444 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10445 ProcessRecord app = mLruProcesses.get(i); 10446 if (!allUsers && app.userId != userId) { 10447 continue; 10448 } 10449 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10450 // Generate process state info for running application 10451 ActivityManager.RunningAppProcessInfo currApp = 10452 new ActivityManager.RunningAppProcessInfo(app.processName, 10453 app.pid, app.getPackageList()); 10454 fillInProcMemInfo(app, currApp); 10455 if (app.adjSource instanceof ProcessRecord) { 10456 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10457 currApp.importanceReasonImportance = oomAdjToImportance( 10458 app.adjSourceOom, null); 10459 } else if (app.adjSource instanceof ActivityRecord) { 10460 ActivityRecord r = (ActivityRecord)app.adjSource; 10461 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10462 } 10463 if (app.adjTarget instanceof ComponentName) { 10464 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10465 } 10466 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10467 // + " lru=" + currApp.lru); 10468 if (runList == null) { 10469 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10470 } 10471 runList.add(currApp); 10472 } 10473 } 10474 } 10475 return runList; 10476 } 10477 10478 public List<ApplicationInfo> getRunningExternalApplications() { 10479 enforceNotIsolatedCaller("getRunningExternalApplications"); 10480 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10481 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10482 if (runningApps != null && runningApps.size() > 0) { 10483 Set<String> extList = new HashSet<String>(); 10484 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10485 if (app.pkgList != null) { 10486 for (String pkg : app.pkgList) { 10487 extList.add(pkg); 10488 } 10489 } 10490 } 10491 IPackageManager pm = AppGlobals.getPackageManager(); 10492 for (String pkg : extList) { 10493 try { 10494 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10495 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10496 retList.add(info); 10497 } 10498 } catch (RemoteException e) { 10499 } 10500 } 10501 } 10502 return retList; 10503 } 10504 10505 @Override 10506 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10507 enforceNotIsolatedCaller("getMyMemoryState"); 10508 synchronized (this) { 10509 ProcessRecord proc; 10510 synchronized (mPidsSelfLocked) { 10511 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10512 } 10513 fillInProcMemInfo(proc, outInfo); 10514 } 10515 } 10516 10517 @Override 10518 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10519 if (checkCallingPermission(android.Manifest.permission.DUMP) 10520 != PackageManager.PERMISSION_GRANTED) { 10521 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10522 + Binder.getCallingPid() 10523 + ", uid=" + Binder.getCallingUid() 10524 + " without permission " 10525 + android.Manifest.permission.DUMP); 10526 return; 10527 } 10528 10529 boolean dumpAll = false; 10530 boolean dumpClient = false; 10531 String dumpPackage = null; 10532 10533 int opti = 0; 10534 while (opti < args.length) { 10535 String opt = args[opti]; 10536 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10537 break; 10538 } 10539 opti++; 10540 if ("-a".equals(opt)) { 10541 dumpAll = true; 10542 } else if ("-c".equals(opt)) { 10543 dumpClient = true; 10544 } else if ("-h".equals(opt)) { 10545 pw.println("Activity manager dump options:"); 10546 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10547 pw.println(" cmd may be one of:"); 10548 pw.println(" a[ctivities]: activity stack state"); 10549 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10550 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10551 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10552 pw.println(" o[om]: out of memory management"); 10553 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10554 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10555 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10556 pw.println(" service [COMP_SPEC]: service client-side state"); 10557 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10558 pw.println(" all: dump all activities"); 10559 pw.println(" top: dump the top activity"); 10560 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10561 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10562 pw.println(" a partial substring in a component name, a"); 10563 pw.println(" hex object identifier."); 10564 pw.println(" -a: include all available server state."); 10565 pw.println(" -c: include client state."); 10566 return; 10567 } else { 10568 pw.println("Unknown argument: " + opt + "; use -h for help"); 10569 } 10570 } 10571 10572 long origId = Binder.clearCallingIdentity(); 10573 boolean more = false; 10574 // Is the caller requesting to dump a particular piece of data? 10575 if (opti < args.length) { 10576 String cmd = args[opti]; 10577 opti++; 10578 if ("activities".equals(cmd) || "a".equals(cmd)) { 10579 synchronized (this) { 10580 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10581 } 10582 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10583 String[] newArgs; 10584 String name; 10585 if (opti >= args.length) { 10586 name = null; 10587 newArgs = EMPTY_STRING_ARRAY; 10588 } else { 10589 name = args[opti]; 10590 opti++; 10591 newArgs = new String[args.length - opti]; 10592 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10593 args.length - opti); 10594 } 10595 synchronized (this) { 10596 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10597 } 10598 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10599 String[] newArgs; 10600 String name; 10601 if (opti >= args.length) { 10602 name = null; 10603 newArgs = EMPTY_STRING_ARRAY; 10604 } else { 10605 name = args[opti]; 10606 opti++; 10607 newArgs = new String[args.length - opti]; 10608 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10609 args.length - opti); 10610 } 10611 synchronized (this) { 10612 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10613 } 10614 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10615 String[] newArgs; 10616 String name; 10617 if (opti >= args.length) { 10618 name = null; 10619 newArgs = EMPTY_STRING_ARRAY; 10620 } else { 10621 name = args[opti]; 10622 opti++; 10623 newArgs = new String[args.length - opti]; 10624 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10625 args.length - opti); 10626 } 10627 synchronized (this) { 10628 dumpProcessesLocked(fd, pw, args, opti, true, name); 10629 } 10630 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10631 synchronized (this) { 10632 dumpOomLocked(fd, pw, args, opti, true); 10633 } 10634 } else if ("provider".equals(cmd)) { 10635 String[] newArgs; 10636 String name; 10637 if (opti >= args.length) { 10638 name = null; 10639 newArgs = EMPTY_STRING_ARRAY; 10640 } else { 10641 name = args[opti]; 10642 opti++; 10643 newArgs = new String[args.length - opti]; 10644 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10645 } 10646 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10647 pw.println("No providers match: " + name); 10648 pw.println("Use -h for help."); 10649 } 10650 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10651 synchronized (this) { 10652 dumpProvidersLocked(fd, pw, args, opti, true, null); 10653 } 10654 } else if ("service".equals(cmd)) { 10655 String[] newArgs; 10656 String name; 10657 if (opti >= args.length) { 10658 name = null; 10659 newArgs = EMPTY_STRING_ARRAY; 10660 } else { 10661 name = args[opti]; 10662 opti++; 10663 newArgs = new String[args.length - opti]; 10664 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10665 args.length - opti); 10666 } 10667 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10668 pw.println("No services match: " + name); 10669 pw.println("Use -h for help."); 10670 } 10671 } else if ("package".equals(cmd)) { 10672 String[] newArgs; 10673 if (opti >= args.length) { 10674 pw.println("package: no package name specified"); 10675 pw.println("Use -h for help."); 10676 } else { 10677 dumpPackage = args[opti]; 10678 opti++; 10679 newArgs = new String[args.length - opti]; 10680 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10681 args.length - opti); 10682 args = newArgs; 10683 opti = 0; 10684 more = true; 10685 } 10686 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10687 synchronized (this) { 10688 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10689 } 10690 } else { 10691 // Dumping a single activity? 10692 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10693 pw.println("Bad activity command, or no activities match: " + cmd); 10694 pw.println("Use -h for help."); 10695 } 10696 } 10697 if (!more) { 10698 Binder.restoreCallingIdentity(origId); 10699 return; 10700 } 10701 } 10702 10703 // No piece of data specified, dump everything. 10704 synchronized (this) { 10705 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10706 pw.println(); 10707 if (dumpAll) { 10708 pw.println("-------------------------------------------------------------------------------"); 10709 } 10710 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10711 pw.println(); 10712 if (dumpAll) { 10713 pw.println("-------------------------------------------------------------------------------"); 10714 } 10715 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10716 pw.println(); 10717 if (dumpAll) { 10718 pw.println("-------------------------------------------------------------------------------"); 10719 } 10720 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10721 pw.println(); 10722 if (dumpAll) { 10723 pw.println("-------------------------------------------------------------------------------"); 10724 } 10725 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10726 pw.println(); 10727 if (dumpAll) { 10728 pw.println("-------------------------------------------------------------------------------"); 10729 } 10730 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10731 } 10732 Binder.restoreCallingIdentity(origId); 10733 } 10734 10735 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10736 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10737 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10738 10739 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10740 dumpPackage); 10741 boolean needSep = printedAnything; 10742 10743 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10744 dumpPackage, needSep, " mFocusedActivity: "); 10745 if (printed) { 10746 printedAnything = true; 10747 needSep = false; 10748 } 10749 10750 if (dumpPackage == null) { 10751 if (needSep) { 10752 pw.println(); 10753 } 10754 needSep = true; 10755 printedAnything = true; 10756 mStackSupervisor.dump(pw, " "); 10757 } 10758 10759 if (mRecentTasks.size() > 0) { 10760 boolean printedHeader = false; 10761 10762 final int N = mRecentTasks.size(); 10763 for (int i=0; i<N; i++) { 10764 TaskRecord tr = mRecentTasks.get(i); 10765 if (dumpPackage != null) { 10766 if (tr.realActivity == null || 10767 !dumpPackage.equals(tr.realActivity)) { 10768 continue; 10769 } 10770 } 10771 if (!printedHeader) { 10772 if (needSep) { 10773 pw.println(); 10774 } 10775 pw.println(" Recent tasks:"); 10776 printedHeader = true; 10777 printedAnything = true; 10778 } 10779 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10780 pw.println(tr); 10781 if (dumpAll) { 10782 mRecentTasks.get(i).dump(pw, " "); 10783 } 10784 } 10785 } 10786 10787 if (!printedAnything) { 10788 pw.println(" (nothing)"); 10789 } 10790 } 10791 10792 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10793 int opti, boolean dumpAll, String dumpPackage) { 10794 boolean needSep = false; 10795 boolean printedAnything = false; 10796 int numPers = 0; 10797 10798 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10799 10800 if (dumpAll) { 10801 final int NP = mProcessNames.getMap().size(); 10802 for (int ip=0; ip<NP; ip++) { 10803 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10804 final int NA = procs.size(); 10805 for (int ia=0; ia<NA; ia++) { 10806 ProcessRecord r = procs.valueAt(ia); 10807 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10808 continue; 10809 } 10810 if (!needSep) { 10811 pw.println(" All known processes:"); 10812 needSep = true; 10813 printedAnything = true; 10814 } 10815 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10816 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10817 pw.print(" "); pw.println(r); 10818 r.dump(pw, " "); 10819 if (r.persistent) { 10820 numPers++; 10821 } 10822 } 10823 } 10824 } 10825 10826 if (mIsolatedProcesses.size() > 0) { 10827 boolean printed = false; 10828 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10829 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10830 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10831 continue; 10832 } 10833 if (!printed) { 10834 if (needSep) { 10835 pw.println(); 10836 } 10837 pw.println(" Isolated process list (sorted by uid):"); 10838 printedAnything = true; 10839 printed = true; 10840 needSep = true; 10841 } 10842 pw.println(String.format("%sIsolated #%2d: %s", 10843 " ", i, r.toString())); 10844 } 10845 } 10846 10847 if (mLruProcesses.size() > 0) { 10848 if (needSep) { 10849 pw.println(); 10850 } 10851 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10852 pw.print(" total, non-act at "); 10853 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10854 pw.print(", non-svc at "); 10855 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10856 pw.println("):"); 10857 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10858 needSep = true; 10859 printedAnything = true; 10860 } 10861 10862 if (dumpAll || dumpPackage != null) { 10863 synchronized (mPidsSelfLocked) { 10864 boolean printed = false; 10865 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10866 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10867 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10868 continue; 10869 } 10870 if (!printed) { 10871 if (needSep) pw.println(); 10872 needSep = true; 10873 pw.println(" PID mappings:"); 10874 printed = true; 10875 printedAnything = true; 10876 } 10877 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10878 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10879 } 10880 } 10881 } 10882 10883 if (mForegroundProcesses.size() > 0) { 10884 synchronized (mPidsSelfLocked) { 10885 boolean printed = false; 10886 for (int i=0; i<mForegroundProcesses.size(); i++) { 10887 ProcessRecord r = mPidsSelfLocked.get( 10888 mForegroundProcesses.valueAt(i).pid); 10889 if (dumpPackage != null && (r == null 10890 || !r.pkgList.containsKey(dumpPackage))) { 10891 continue; 10892 } 10893 if (!printed) { 10894 if (needSep) pw.println(); 10895 needSep = true; 10896 pw.println(" Foreground Processes:"); 10897 printed = true; 10898 printedAnything = true; 10899 } 10900 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10901 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10902 } 10903 } 10904 } 10905 10906 if (mPersistentStartingProcesses.size() > 0) { 10907 if (needSep) pw.println(); 10908 needSep = true; 10909 printedAnything = true; 10910 pw.println(" Persisent processes that are starting:"); 10911 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10912 "Starting Norm", "Restarting PERS", dumpPackage); 10913 } 10914 10915 if (mRemovedProcesses.size() > 0) { 10916 if (needSep) pw.println(); 10917 needSep = true; 10918 printedAnything = true; 10919 pw.println(" Processes that are being removed:"); 10920 dumpProcessList(pw, this, mRemovedProcesses, " ", 10921 "Removed Norm", "Removed PERS", dumpPackage); 10922 } 10923 10924 if (mProcessesOnHold.size() > 0) { 10925 if (needSep) pw.println(); 10926 needSep = true; 10927 printedAnything = true; 10928 pw.println(" Processes that are on old until the system is ready:"); 10929 dumpProcessList(pw, this, mProcessesOnHold, " ", 10930 "OnHold Norm", "OnHold PERS", dumpPackage); 10931 } 10932 10933 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10934 10935 if (mProcessCrashTimes.getMap().size() > 0) { 10936 boolean printed = false; 10937 long now = SystemClock.uptimeMillis(); 10938 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10939 final int NP = pmap.size(); 10940 for (int ip=0; ip<NP; ip++) { 10941 String pname = pmap.keyAt(ip); 10942 SparseArray<Long> uids = pmap.valueAt(ip); 10943 final int N = uids.size(); 10944 for (int i=0; i<N; i++) { 10945 int puid = uids.keyAt(i); 10946 ProcessRecord r = mProcessNames.get(pname, puid); 10947 if (dumpPackage != null && (r == null 10948 || !r.pkgList.containsKey(dumpPackage))) { 10949 continue; 10950 } 10951 if (!printed) { 10952 if (needSep) pw.println(); 10953 needSep = true; 10954 pw.println(" Time since processes crashed:"); 10955 printed = true; 10956 printedAnything = true; 10957 } 10958 pw.print(" Process "); pw.print(pname); 10959 pw.print(" uid "); pw.print(puid); 10960 pw.print(": last crashed "); 10961 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10962 pw.println(" ago"); 10963 } 10964 } 10965 } 10966 10967 if (mBadProcesses.getMap().size() > 0) { 10968 boolean printed = false; 10969 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10970 final int NP = pmap.size(); 10971 for (int ip=0; ip<NP; ip++) { 10972 String pname = pmap.keyAt(ip); 10973 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10974 final int N = uids.size(); 10975 for (int i=0; i<N; i++) { 10976 int puid = uids.keyAt(i); 10977 ProcessRecord r = mProcessNames.get(pname, puid); 10978 if (dumpPackage != null && (r == null 10979 || !r.pkgList.containsKey(dumpPackage))) { 10980 continue; 10981 } 10982 if (!printed) { 10983 if (needSep) pw.println(); 10984 needSep = true; 10985 pw.println(" Bad processes:"); 10986 printedAnything = true; 10987 } 10988 BadProcessInfo info = uids.valueAt(i); 10989 pw.print(" Bad process "); pw.print(pname); 10990 pw.print(" uid "); pw.print(puid); 10991 pw.print(": crashed at time "); pw.println(info.time); 10992 if (info.shortMsg != null) { 10993 pw.print(" Short msg: "); pw.println(info.shortMsg); 10994 } 10995 if (info.longMsg != null) { 10996 pw.print(" Long msg: "); pw.println(info.longMsg); 10997 } 10998 if (info.stack != null) { 10999 pw.println(" Stack:"); 11000 int lastPos = 0; 11001 for (int pos=0; pos<info.stack.length(); pos++) { 11002 if (info.stack.charAt(pos) == '\n') { 11003 pw.print(" "); 11004 pw.write(info.stack, lastPos, pos-lastPos); 11005 pw.println(); 11006 lastPos = pos+1; 11007 } 11008 } 11009 if (lastPos < info.stack.length()) { 11010 pw.print(" "); 11011 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11012 pw.println(); 11013 } 11014 } 11015 } 11016 } 11017 } 11018 11019 if (dumpPackage == null) { 11020 pw.println(); 11021 needSep = false; 11022 pw.println(" mStartedUsers:"); 11023 for (int i=0; i<mStartedUsers.size(); i++) { 11024 UserStartedState uss = mStartedUsers.valueAt(i); 11025 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11026 pw.print(": "); uss.dump("", pw); 11027 } 11028 pw.print(" mStartedUserArray: ["); 11029 for (int i=0; i<mStartedUserArray.length; i++) { 11030 if (i > 0) pw.print(", "); 11031 pw.print(mStartedUserArray[i]); 11032 } 11033 pw.println("]"); 11034 pw.print(" mUserLru: ["); 11035 for (int i=0; i<mUserLru.size(); i++) { 11036 if (i > 0) pw.print(", "); 11037 pw.print(mUserLru.get(i)); 11038 } 11039 pw.println("]"); 11040 if (dumpAll) { 11041 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11042 } 11043 } 11044 if (mHomeProcess != null && (dumpPackage == null 11045 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11046 if (needSep) { 11047 pw.println(); 11048 needSep = false; 11049 } 11050 pw.println(" mHomeProcess: " + mHomeProcess); 11051 } 11052 if (mPreviousProcess != null && (dumpPackage == null 11053 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11054 if (needSep) { 11055 pw.println(); 11056 needSep = false; 11057 } 11058 pw.println(" mPreviousProcess: " + mPreviousProcess); 11059 } 11060 if (dumpAll) { 11061 StringBuilder sb = new StringBuilder(128); 11062 sb.append(" mPreviousProcessVisibleTime: "); 11063 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11064 pw.println(sb); 11065 } 11066 if (mHeavyWeightProcess != null && (dumpPackage == null 11067 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11068 if (needSep) { 11069 pw.println(); 11070 needSep = false; 11071 } 11072 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11073 } 11074 if (dumpPackage == null) { 11075 pw.println(" mConfiguration: " + mConfiguration); 11076 } 11077 if (dumpAll) { 11078 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11079 if (mCompatModePackages.getPackages().size() > 0) { 11080 boolean printed = false; 11081 for (Map.Entry<String, Integer> entry 11082 : mCompatModePackages.getPackages().entrySet()) { 11083 String pkg = entry.getKey(); 11084 int mode = entry.getValue(); 11085 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11086 continue; 11087 } 11088 if (!printed) { 11089 pw.println(" mScreenCompatPackages:"); 11090 printed = true; 11091 } 11092 pw.print(" "); pw.print(pkg); pw.print(": "); 11093 pw.print(mode); pw.println(); 11094 } 11095 } 11096 } 11097 if (dumpPackage == null) { 11098 if (mSleeping || mWentToSleep || mLockScreenShown) { 11099 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11100 + " mLockScreenShown " + mLockScreenShown); 11101 } 11102 if (mShuttingDown) { 11103 pw.println(" mShuttingDown=" + mShuttingDown); 11104 } 11105 } 11106 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11107 || mOrigWaitForDebugger) { 11108 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11109 || dumpPackage.equals(mOrigDebugApp)) { 11110 if (needSep) { 11111 pw.println(); 11112 needSep = false; 11113 } 11114 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11115 + " mDebugTransient=" + mDebugTransient 11116 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11117 } 11118 } 11119 if (mOpenGlTraceApp != null) { 11120 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11121 if (needSep) { 11122 pw.println(); 11123 needSep = false; 11124 } 11125 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11126 } 11127 } 11128 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11129 || mProfileFd != null) { 11130 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11131 if (needSep) { 11132 pw.println(); 11133 needSep = false; 11134 } 11135 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11136 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11137 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11138 + mAutoStopProfiler); 11139 } 11140 } 11141 if (dumpPackage == null) { 11142 if (mAlwaysFinishActivities || mController != null) { 11143 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11144 + " mController=" + mController); 11145 } 11146 if (dumpAll) { 11147 pw.println(" Total persistent processes: " + numPers); 11148 pw.println(" mStartRunning=" + mStartRunning 11149 + " mProcessesReady=" + mProcessesReady 11150 + " mSystemReady=" + mSystemReady); 11151 pw.println(" mBooting=" + mBooting 11152 + " mBooted=" + mBooted 11153 + " mFactoryTest=" + mFactoryTest); 11154 pw.print(" mLastPowerCheckRealtime="); 11155 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11156 pw.println(""); 11157 pw.print(" mLastPowerCheckUptime="); 11158 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11159 pw.println(""); 11160 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11161 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11162 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11163 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11164 + " (" + mLruProcesses.size() + " total)" 11165 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11166 + " mNumServiceProcs=" + mNumServiceProcs 11167 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11168 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11169 + " mLastMemoryLevel" + mLastMemoryLevel 11170 + " mLastNumProcesses" + mLastNumProcesses); 11171 long now = SystemClock.uptimeMillis(); 11172 pw.print(" mLastIdleTime="); 11173 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11174 pw.print(" mLowRamSinceLastIdle="); 11175 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11176 pw.println(); 11177 } 11178 } 11179 11180 if (!printedAnything) { 11181 pw.println(" (nothing)"); 11182 } 11183 } 11184 11185 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11186 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11187 if (mProcessesToGc.size() > 0) { 11188 boolean printed = false; 11189 long now = SystemClock.uptimeMillis(); 11190 for (int i=0; i<mProcessesToGc.size(); i++) { 11191 ProcessRecord proc = mProcessesToGc.get(i); 11192 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11193 continue; 11194 } 11195 if (!printed) { 11196 if (needSep) pw.println(); 11197 needSep = true; 11198 pw.println(" Processes that are waiting to GC:"); 11199 printed = true; 11200 } 11201 pw.print(" Process "); pw.println(proc); 11202 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11203 pw.print(", last gced="); 11204 pw.print(now-proc.lastRequestedGc); 11205 pw.print(" ms ago, last lowMem="); 11206 pw.print(now-proc.lastLowMemory); 11207 pw.println(" ms ago"); 11208 11209 } 11210 } 11211 return needSep; 11212 } 11213 11214 void printOomLevel(PrintWriter pw, String name, int adj) { 11215 pw.print(" "); 11216 if (adj >= 0) { 11217 pw.print(' '); 11218 if (adj < 10) pw.print(' '); 11219 } else { 11220 if (adj > -10) pw.print(' '); 11221 } 11222 pw.print(adj); 11223 pw.print(": "); 11224 pw.print(name); 11225 pw.print(" ("); 11226 pw.print(mProcessList.getMemLevel(adj)/1024); 11227 pw.println(" kB)"); 11228 } 11229 11230 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11231 int opti, boolean dumpAll) { 11232 boolean needSep = false; 11233 11234 if (mLruProcesses.size() > 0) { 11235 if (needSep) pw.println(); 11236 needSep = true; 11237 pw.println(" OOM levels:"); 11238 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11239 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11240 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11241 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11242 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11243 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11244 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11245 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11246 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11247 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11248 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11249 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11250 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11251 11252 if (needSep) pw.println(); 11253 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11254 pw.print(" total, non-act at "); 11255 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11256 pw.print(", non-svc at "); 11257 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11258 pw.println("):"); 11259 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11260 needSep = true; 11261 } 11262 11263 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11264 11265 pw.println(); 11266 pw.println(" mHomeProcess: " + mHomeProcess); 11267 pw.println(" mPreviousProcess: " + mPreviousProcess); 11268 if (mHeavyWeightProcess != null) { 11269 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11270 } 11271 11272 return true; 11273 } 11274 11275 /** 11276 * There are three ways to call this: 11277 * - no provider specified: dump all the providers 11278 * - a flattened component name that matched an existing provider was specified as the 11279 * first arg: dump that one provider 11280 * - the first arg isn't the flattened component name of an existing provider: 11281 * dump all providers whose component contains the first arg as a substring 11282 */ 11283 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11284 int opti, boolean dumpAll) { 11285 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11286 } 11287 11288 static class ItemMatcher { 11289 ArrayList<ComponentName> components; 11290 ArrayList<String> strings; 11291 ArrayList<Integer> objects; 11292 boolean all; 11293 11294 ItemMatcher() { 11295 all = true; 11296 } 11297 11298 void build(String name) { 11299 ComponentName componentName = ComponentName.unflattenFromString(name); 11300 if (componentName != null) { 11301 if (components == null) { 11302 components = new ArrayList<ComponentName>(); 11303 } 11304 components.add(componentName); 11305 all = false; 11306 } else { 11307 int objectId = 0; 11308 // Not a '/' separated full component name; maybe an object ID? 11309 try { 11310 objectId = Integer.parseInt(name, 16); 11311 if (objects == null) { 11312 objects = new ArrayList<Integer>(); 11313 } 11314 objects.add(objectId); 11315 all = false; 11316 } catch (RuntimeException e) { 11317 // Not an integer; just do string match. 11318 if (strings == null) { 11319 strings = new ArrayList<String>(); 11320 } 11321 strings.add(name); 11322 all = false; 11323 } 11324 } 11325 } 11326 11327 int build(String[] args, int opti) { 11328 for (; opti<args.length; opti++) { 11329 String name = args[opti]; 11330 if ("--".equals(name)) { 11331 return opti+1; 11332 } 11333 build(name); 11334 } 11335 return opti; 11336 } 11337 11338 boolean match(Object object, ComponentName comp) { 11339 if (all) { 11340 return true; 11341 } 11342 if (components != null) { 11343 for (int i=0; i<components.size(); i++) { 11344 if (components.get(i).equals(comp)) { 11345 return true; 11346 } 11347 } 11348 } 11349 if (objects != null) { 11350 for (int i=0; i<objects.size(); i++) { 11351 if (System.identityHashCode(object) == objects.get(i)) { 11352 return true; 11353 } 11354 } 11355 } 11356 if (strings != null) { 11357 String flat = comp.flattenToString(); 11358 for (int i=0; i<strings.size(); i++) { 11359 if (flat.contains(strings.get(i))) { 11360 return true; 11361 } 11362 } 11363 } 11364 return false; 11365 } 11366 } 11367 11368 /** 11369 * There are three things that cmd can be: 11370 * - a flattened component name that matches an existing activity 11371 * - the cmd arg isn't the flattened component name of an existing activity: 11372 * dump all activity whose component contains the cmd as a substring 11373 * - A hex number of the ActivityRecord object instance. 11374 */ 11375 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11376 int opti, boolean dumpAll) { 11377 ArrayList<ActivityRecord> activities; 11378 11379 synchronized (this) { 11380 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11381 } 11382 11383 if (activities.size() <= 0) { 11384 return false; 11385 } 11386 11387 String[] newArgs = new String[args.length - opti]; 11388 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11389 11390 TaskRecord lastTask = null; 11391 boolean needSep = false; 11392 for (int i=activities.size()-1; i>=0; i--) { 11393 ActivityRecord r = activities.get(i); 11394 if (needSep) { 11395 pw.println(); 11396 } 11397 needSep = true; 11398 synchronized (this) { 11399 if (lastTask != r.task) { 11400 lastTask = r.task; 11401 pw.print("TASK "); pw.print(lastTask.affinity); 11402 pw.print(" id="); pw.println(lastTask.taskId); 11403 if (dumpAll) { 11404 lastTask.dump(pw, " "); 11405 } 11406 } 11407 } 11408 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11409 } 11410 return true; 11411 } 11412 11413 /** 11414 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11415 * there is a thread associated with the activity. 11416 */ 11417 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11418 final ActivityRecord r, String[] args, boolean dumpAll) { 11419 String innerPrefix = prefix + " "; 11420 synchronized (this) { 11421 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11422 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11423 pw.print(" pid="); 11424 if (r.app != null) pw.println(r.app.pid); 11425 else pw.println("(not running)"); 11426 if (dumpAll) { 11427 r.dump(pw, innerPrefix); 11428 } 11429 } 11430 if (r.app != null && r.app.thread != null) { 11431 // flush anything that is already in the PrintWriter since the thread is going 11432 // to write to the file descriptor directly 11433 pw.flush(); 11434 try { 11435 TransferPipe tp = new TransferPipe(); 11436 try { 11437 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11438 r.appToken, innerPrefix, args); 11439 tp.go(fd); 11440 } finally { 11441 tp.kill(); 11442 } 11443 } catch (IOException e) { 11444 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11445 } catch (RemoteException e) { 11446 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11447 } 11448 } 11449 } 11450 11451 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11452 int opti, boolean dumpAll, String dumpPackage) { 11453 boolean needSep = false; 11454 boolean onlyHistory = false; 11455 boolean printedAnything = false; 11456 11457 if ("history".equals(dumpPackage)) { 11458 if (opti < args.length && "-s".equals(args[opti])) { 11459 dumpAll = false; 11460 } 11461 onlyHistory = true; 11462 dumpPackage = null; 11463 } 11464 11465 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11466 if (!onlyHistory && dumpAll) { 11467 if (mRegisteredReceivers.size() > 0) { 11468 boolean printed = false; 11469 Iterator it = mRegisteredReceivers.values().iterator(); 11470 while (it.hasNext()) { 11471 ReceiverList r = (ReceiverList)it.next(); 11472 if (dumpPackage != null && (r.app == null || 11473 !dumpPackage.equals(r.app.info.packageName))) { 11474 continue; 11475 } 11476 if (!printed) { 11477 pw.println(" Registered Receivers:"); 11478 needSep = true; 11479 printed = true; 11480 printedAnything = true; 11481 } 11482 pw.print(" * "); pw.println(r); 11483 r.dump(pw, " "); 11484 } 11485 } 11486 11487 if (mReceiverResolver.dump(pw, needSep ? 11488 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11489 " ", dumpPackage, false)) { 11490 needSep = true; 11491 printedAnything = true; 11492 } 11493 } 11494 11495 for (BroadcastQueue q : mBroadcastQueues) { 11496 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11497 printedAnything |= needSep; 11498 } 11499 11500 needSep = true; 11501 11502 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11503 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11504 if (needSep) { 11505 pw.println(); 11506 } 11507 needSep = true; 11508 printedAnything = true; 11509 pw.print(" Sticky broadcasts for user "); 11510 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11511 StringBuilder sb = new StringBuilder(128); 11512 for (Map.Entry<String, ArrayList<Intent>> ent 11513 : mStickyBroadcasts.valueAt(user).entrySet()) { 11514 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11515 if (dumpAll) { 11516 pw.println(":"); 11517 ArrayList<Intent> intents = ent.getValue(); 11518 final int N = intents.size(); 11519 for (int i=0; i<N; i++) { 11520 sb.setLength(0); 11521 sb.append(" Intent: "); 11522 intents.get(i).toShortString(sb, false, true, false, false); 11523 pw.println(sb.toString()); 11524 Bundle bundle = intents.get(i).getExtras(); 11525 if (bundle != null) { 11526 pw.print(" "); 11527 pw.println(bundle.toString()); 11528 } 11529 } 11530 } else { 11531 pw.println(""); 11532 } 11533 } 11534 } 11535 } 11536 11537 if (!onlyHistory && dumpAll) { 11538 pw.println(); 11539 for (BroadcastQueue queue : mBroadcastQueues) { 11540 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11541 + queue.mBroadcastsScheduled); 11542 } 11543 pw.println(" mHandler:"); 11544 mHandler.dump(new PrintWriterPrinter(pw), " "); 11545 needSep = true; 11546 printedAnything = true; 11547 } 11548 11549 if (!printedAnything) { 11550 pw.println(" (nothing)"); 11551 } 11552 } 11553 11554 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11555 int opti, boolean dumpAll, String dumpPackage) { 11556 boolean needSep; 11557 boolean printedAnything = false; 11558 11559 ItemMatcher matcher = new ItemMatcher(); 11560 matcher.build(args, opti); 11561 11562 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11563 11564 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11565 printedAnything |= needSep; 11566 11567 if (mLaunchingProviders.size() > 0) { 11568 boolean printed = false; 11569 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11570 ContentProviderRecord r = mLaunchingProviders.get(i); 11571 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11572 continue; 11573 } 11574 if (!printed) { 11575 if (needSep) pw.println(); 11576 needSep = true; 11577 pw.println(" Launching content providers:"); 11578 printed = true; 11579 printedAnything = true; 11580 } 11581 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11582 pw.println(r); 11583 } 11584 } 11585 11586 if (mGrantedUriPermissions.size() > 0) { 11587 boolean printed = false; 11588 int dumpUid = -2; 11589 if (dumpPackage != null) { 11590 try { 11591 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11592 } catch (NameNotFoundException e) { 11593 dumpUid = -1; 11594 } 11595 } 11596 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11597 int uid = mGrantedUriPermissions.keyAt(i); 11598 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11599 continue; 11600 } 11601 ArrayMap<Uri, UriPermission> perms 11602 = mGrantedUriPermissions.valueAt(i); 11603 if (!printed) { 11604 if (needSep) pw.println(); 11605 needSep = true; 11606 pw.println(" Granted Uri Permissions:"); 11607 printed = true; 11608 printedAnything = true; 11609 } 11610 pw.print(" * UID "); pw.print(uid); 11611 pw.println(" holds:"); 11612 for (UriPermission perm : perms.values()) { 11613 pw.print(" "); pw.println(perm); 11614 if (dumpAll) { 11615 perm.dump(pw, " "); 11616 } 11617 } 11618 } 11619 } 11620 11621 if (!printedAnything) { 11622 pw.println(" (nothing)"); 11623 } 11624 } 11625 11626 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11627 int opti, boolean dumpAll, String dumpPackage) { 11628 boolean printed = false; 11629 11630 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11631 11632 if (mIntentSenderRecords.size() > 0) { 11633 Iterator<WeakReference<PendingIntentRecord>> it 11634 = mIntentSenderRecords.values().iterator(); 11635 while (it.hasNext()) { 11636 WeakReference<PendingIntentRecord> ref = it.next(); 11637 PendingIntentRecord rec = ref != null ? ref.get(): null; 11638 if (dumpPackage != null && (rec == null 11639 || !dumpPackage.equals(rec.key.packageName))) { 11640 continue; 11641 } 11642 printed = true; 11643 if (rec != null) { 11644 pw.print(" * "); pw.println(rec); 11645 if (dumpAll) { 11646 rec.dump(pw, " "); 11647 } 11648 } else { 11649 pw.print(" * "); pw.println(ref); 11650 } 11651 } 11652 } 11653 11654 if (!printed) { 11655 pw.println(" (nothing)"); 11656 } 11657 } 11658 11659 private static final int dumpProcessList(PrintWriter pw, 11660 ActivityManagerService service, List list, 11661 String prefix, String normalLabel, String persistentLabel, 11662 String dumpPackage) { 11663 int numPers = 0; 11664 final int N = list.size()-1; 11665 for (int i=N; i>=0; i--) { 11666 ProcessRecord r = (ProcessRecord)list.get(i); 11667 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11668 continue; 11669 } 11670 pw.println(String.format("%s%s #%2d: %s", 11671 prefix, (r.persistent ? persistentLabel : normalLabel), 11672 i, r.toString())); 11673 if (r.persistent) { 11674 numPers++; 11675 } 11676 } 11677 return numPers; 11678 } 11679 11680 private static final boolean dumpProcessOomList(PrintWriter pw, 11681 ActivityManagerService service, List<ProcessRecord> origList, 11682 String prefix, String normalLabel, String persistentLabel, 11683 boolean inclDetails, String dumpPackage) { 11684 11685 ArrayList<Pair<ProcessRecord, Integer>> list 11686 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11687 for (int i=0; i<origList.size(); i++) { 11688 ProcessRecord r = origList.get(i); 11689 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11690 continue; 11691 } 11692 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11693 } 11694 11695 if (list.size() <= 0) { 11696 return false; 11697 } 11698 11699 Comparator<Pair<ProcessRecord, Integer>> comparator 11700 = new Comparator<Pair<ProcessRecord, Integer>>() { 11701 @Override 11702 public int compare(Pair<ProcessRecord, Integer> object1, 11703 Pair<ProcessRecord, Integer> object2) { 11704 if (object1.first.setAdj != object2.first.setAdj) { 11705 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11706 } 11707 if (object1.second.intValue() != object2.second.intValue()) { 11708 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11709 } 11710 return 0; 11711 } 11712 }; 11713 11714 Collections.sort(list, comparator); 11715 11716 final long curRealtime = SystemClock.elapsedRealtime(); 11717 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11718 final long curUptime = SystemClock.uptimeMillis(); 11719 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11720 11721 for (int i=list.size()-1; i>=0; i--) { 11722 ProcessRecord r = list.get(i).first; 11723 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11724 char schedGroup; 11725 switch (r.setSchedGroup) { 11726 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11727 schedGroup = 'B'; 11728 break; 11729 case Process.THREAD_GROUP_DEFAULT: 11730 schedGroup = 'F'; 11731 break; 11732 default: 11733 schedGroup = '?'; 11734 break; 11735 } 11736 char foreground; 11737 if (r.foregroundActivities) { 11738 foreground = 'A'; 11739 } else if (r.foregroundServices) { 11740 foreground = 'S'; 11741 } else { 11742 foreground = ' '; 11743 } 11744 String procState = ProcessList.makeProcStateString(r.curProcState); 11745 pw.print(prefix); 11746 pw.print(r.persistent ? persistentLabel : normalLabel); 11747 pw.print(" #"); 11748 int num = (origList.size()-1)-list.get(i).second; 11749 if (num < 10) pw.print(' '); 11750 pw.print(num); 11751 pw.print(": "); 11752 pw.print(oomAdj); 11753 pw.print(' '); 11754 pw.print(schedGroup); 11755 pw.print('/'); 11756 pw.print(foreground); 11757 pw.print('/'); 11758 pw.print(procState); 11759 pw.print(" trm:"); 11760 if (r.trimMemoryLevel < 10) pw.print(' '); 11761 pw.print(r.trimMemoryLevel); 11762 pw.print(' '); 11763 pw.print(r.toShortString()); 11764 pw.print(" ("); 11765 pw.print(r.adjType); 11766 pw.println(')'); 11767 if (r.adjSource != null || r.adjTarget != null) { 11768 pw.print(prefix); 11769 pw.print(" "); 11770 if (r.adjTarget instanceof ComponentName) { 11771 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11772 } else if (r.adjTarget != null) { 11773 pw.print(r.adjTarget.toString()); 11774 } else { 11775 pw.print("{null}"); 11776 } 11777 pw.print("<="); 11778 if (r.adjSource instanceof ProcessRecord) { 11779 pw.print("Proc{"); 11780 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11781 pw.println("}"); 11782 } else if (r.adjSource != null) { 11783 pw.println(r.adjSource.toString()); 11784 } else { 11785 pw.println("{null}"); 11786 } 11787 } 11788 if (inclDetails) { 11789 pw.print(prefix); 11790 pw.print(" "); 11791 pw.print("oom: max="); pw.print(r.maxAdj); 11792 pw.print(" curRaw="); pw.print(r.curRawAdj); 11793 pw.print(" setRaw="); pw.print(r.setRawAdj); 11794 pw.print(" cur="); pw.print(r.curAdj); 11795 pw.print(" set="); pw.println(r.setAdj); 11796 pw.print(prefix); 11797 pw.print(" "); 11798 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11799 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11800 pw.print(" lastPss="); pw.print(r.lastPss); 11801 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11802 pw.print(prefix); 11803 pw.print(" "); 11804 pw.print("keeping="); pw.print(r.keeping); 11805 pw.print(" cached="); pw.print(r.cached); 11806 pw.print(" empty="); pw.print(r.empty); 11807 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11808 11809 if (!r.keeping) { 11810 if (r.lastWakeTime != 0) { 11811 long wtime; 11812 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11813 synchronized (stats) { 11814 wtime = stats.getProcessWakeTime(r.info.uid, 11815 r.pid, curRealtime); 11816 } 11817 long timeUsed = wtime - r.lastWakeTime; 11818 pw.print(prefix); 11819 pw.print(" "); 11820 pw.print("keep awake over "); 11821 TimeUtils.formatDuration(realtimeSince, pw); 11822 pw.print(" used "); 11823 TimeUtils.formatDuration(timeUsed, pw); 11824 pw.print(" ("); 11825 pw.print((timeUsed*100)/realtimeSince); 11826 pw.println("%)"); 11827 } 11828 if (r.lastCpuTime != 0) { 11829 long timeUsed = r.curCpuTime - r.lastCpuTime; 11830 pw.print(prefix); 11831 pw.print(" "); 11832 pw.print("run cpu over "); 11833 TimeUtils.formatDuration(uptimeSince, pw); 11834 pw.print(" used "); 11835 TimeUtils.formatDuration(timeUsed, pw); 11836 pw.print(" ("); 11837 pw.print((timeUsed*100)/uptimeSince); 11838 pw.println("%)"); 11839 } 11840 } 11841 } 11842 } 11843 return true; 11844 } 11845 11846 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11847 ArrayList<ProcessRecord> procs; 11848 synchronized (this) { 11849 if (args != null && args.length > start 11850 && args[start].charAt(0) != '-') { 11851 procs = new ArrayList<ProcessRecord>(); 11852 int pid = -1; 11853 try { 11854 pid = Integer.parseInt(args[start]); 11855 } catch (NumberFormatException e) { 11856 } 11857 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11858 ProcessRecord proc = mLruProcesses.get(i); 11859 if (proc.pid == pid) { 11860 procs.add(proc); 11861 } else if (proc.processName.equals(args[start])) { 11862 procs.add(proc); 11863 } 11864 } 11865 if (procs.size() <= 0) { 11866 return null; 11867 } 11868 } else { 11869 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11870 } 11871 } 11872 return procs; 11873 } 11874 11875 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11876 PrintWriter pw, String[] args) { 11877 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11878 if (procs == null) { 11879 pw.println("No process found for: " + args[0]); 11880 return; 11881 } 11882 11883 long uptime = SystemClock.uptimeMillis(); 11884 long realtime = SystemClock.elapsedRealtime(); 11885 pw.println("Applications Graphics Acceleration Info:"); 11886 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11887 11888 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11889 ProcessRecord r = procs.get(i); 11890 if (r.thread != null) { 11891 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11892 pw.flush(); 11893 try { 11894 TransferPipe tp = new TransferPipe(); 11895 try { 11896 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11897 tp.go(fd); 11898 } finally { 11899 tp.kill(); 11900 } 11901 } catch (IOException e) { 11902 pw.println("Failure while dumping the app: " + r); 11903 pw.flush(); 11904 } catch (RemoteException e) { 11905 pw.println("Got a RemoteException while dumping the app " + r); 11906 pw.flush(); 11907 } 11908 } 11909 } 11910 } 11911 11912 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11913 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11914 if (procs == null) { 11915 pw.println("No process found for: " + args[0]); 11916 return; 11917 } 11918 11919 pw.println("Applications Database Info:"); 11920 11921 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11922 ProcessRecord r = procs.get(i); 11923 if (r.thread != null) { 11924 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11925 pw.flush(); 11926 try { 11927 TransferPipe tp = new TransferPipe(); 11928 try { 11929 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11930 tp.go(fd); 11931 } finally { 11932 tp.kill(); 11933 } 11934 } catch (IOException e) { 11935 pw.println("Failure while dumping the app: " + r); 11936 pw.flush(); 11937 } catch (RemoteException e) { 11938 pw.println("Got a RemoteException while dumping the app " + r); 11939 pw.flush(); 11940 } 11941 } 11942 } 11943 } 11944 11945 final static class MemItem { 11946 final boolean isProc; 11947 final String label; 11948 final String shortLabel; 11949 final long pss; 11950 final int id; 11951 final boolean hasActivities; 11952 ArrayList<MemItem> subitems; 11953 11954 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11955 boolean _hasActivities) { 11956 isProc = true; 11957 label = _label; 11958 shortLabel = _shortLabel; 11959 pss = _pss; 11960 id = _id; 11961 hasActivities = _hasActivities; 11962 } 11963 11964 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11965 isProc = false; 11966 label = _label; 11967 shortLabel = _shortLabel; 11968 pss = _pss; 11969 id = _id; 11970 hasActivities = false; 11971 } 11972 } 11973 11974 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11975 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11976 if (sort && !isCompact) { 11977 Collections.sort(items, new Comparator<MemItem>() { 11978 @Override 11979 public int compare(MemItem lhs, MemItem rhs) { 11980 if (lhs.pss < rhs.pss) { 11981 return 1; 11982 } else if (lhs.pss > rhs.pss) { 11983 return -1; 11984 } 11985 return 0; 11986 } 11987 }); 11988 } 11989 11990 for (int i=0; i<items.size(); i++) { 11991 MemItem mi = items.get(i); 11992 if (!isCompact) { 11993 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11994 } else if (mi.isProc) { 11995 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11996 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11997 pw.println(mi.hasActivities ? ",a" : ",e"); 11998 } else { 11999 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12000 pw.println(mi.pss); 12001 } 12002 if (mi.subitems != null) { 12003 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12004 true, isCompact); 12005 } 12006 } 12007 } 12008 12009 // These are in KB. 12010 static final long[] DUMP_MEM_BUCKETS = new long[] { 12011 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12012 120*1024, 160*1024, 200*1024, 12013 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12014 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12015 }; 12016 12017 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12018 boolean stackLike) { 12019 int start = label.lastIndexOf('.'); 12020 if (start >= 0) start++; 12021 else start = 0; 12022 int end = label.length(); 12023 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12024 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12025 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12026 out.append(bucket); 12027 out.append(stackLike ? "MB." : "MB "); 12028 out.append(label, start, end); 12029 return; 12030 } 12031 } 12032 out.append(memKB/1024); 12033 out.append(stackLike ? "MB." : "MB "); 12034 out.append(label, start, end); 12035 } 12036 12037 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12038 ProcessList.NATIVE_ADJ, 12039 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12040 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12041 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12042 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12043 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12044 }; 12045 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12046 "Native", 12047 "System", "Persistent", "Foreground", 12048 "Visible", "Perceptible", 12049 "Heavy Weight", "Backup", 12050 "A Services", "Home", 12051 "Previous", "B Services", "Cached" 12052 }; 12053 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12054 "native", 12055 "sys", "pers", "fore", 12056 "vis", "percept", 12057 "heavy", "backup", 12058 "servicea", "home", 12059 "prev", "serviceb", "cached" 12060 }; 12061 12062 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12063 long realtime, boolean isCheckinRequest, boolean isCompact) { 12064 if (isCheckinRequest || isCompact) { 12065 // short checkin version 12066 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12067 } else { 12068 pw.println("Applications Memory Usage (kB):"); 12069 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12070 } 12071 } 12072 12073 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12074 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12075 boolean dumpDetails = false; 12076 boolean dumpFullDetails = false; 12077 boolean dumpDalvik = false; 12078 boolean oomOnly = false; 12079 boolean isCompact = false; 12080 boolean localOnly = false; 12081 12082 int opti = 0; 12083 while (opti < args.length) { 12084 String opt = args[opti]; 12085 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12086 break; 12087 } 12088 opti++; 12089 if ("-a".equals(opt)) { 12090 dumpDetails = true; 12091 dumpFullDetails = true; 12092 dumpDalvik = true; 12093 } else if ("-d".equals(opt)) { 12094 dumpDalvik = true; 12095 } else if ("-c".equals(opt)) { 12096 isCompact = true; 12097 } else if ("--oom".equals(opt)) { 12098 oomOnly = true; 12099 } else if ("--local".equals(opt)) { 12100 localOnly = true; 12101 } else if ("-h".equals(opt)) { 12102 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12103 pw.println(" -a: include all available information for each process."); 12104 pw.println(" -d: include dalvik details when dumping process details."); 12105 pw.println(" -c: dump in a compact machine-parseable representation."); 12106 pw.println(" --oom: only show processes organized by oom adj."); 12107 pw.println(" --local: only collect details locally, don't call process."); 12108 pw.println("If [process] is specified it can be the name or "); 12109 pw.println("pid of a specific process to dump."); 12110 return; 12111 } else { 12112 pw.println("Unknown argument: " + opt + "; use -h for help"); 12113 } 12114 } 12115 12116 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12117 long uptime = SystemClock.uptimeMillis(); 12118 long realtime = SystemClock.elapsedRealtime(); 12119 final long[] tmpLong = new long[1]; 12120 12121 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12122 if (procs == null) { 12123 // No Java processes. Maybe they want to print a native process. 12124 if (args != null && args.length > opti 12125 && args[opti].charAt(0) != '-') { 12126 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12127 = new ArrayList<ProcessCpuTracker.Stats>(); 12128 updateCpuStatsNow(); 12129 int findPid = -1; 12130 try { 12131 findPid = Integer.parseInt(args[opti]); 12132 } catch (NumberFormatException e) { 12133 } 12134 synchronized (mProcessCpuThread) { 12135 final int N = mProcessCpuTracker.countStats(); 12136 for (int i=0; i<N; i++) { 12137 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12138 if (st.pid == findPid || (st.baseName != null 12139 && st.baseName.equals(args[opti]))) { 12140 nativeProcs.add(st); 12141 } 12142 } 12143 } 12144 if (nativeProcs.size() > 0) { 12145 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12146 isCompact); 12147 Debug.MemoryInfo mi = null; 12148 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12149 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12150 final int pid = r.pid; 12151 if (!isCheckinRequest && dumpDetails) { 12152 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12153 } 12154 if (mi == null) { 12155 mi = new Debug.MemoryInfo(); 12156 } 12157 if (dumpDetails || (!brief && !oomOnly)) { 12158 Debug.getMemoryInfo(pid, mi); 12159 } else { 12160 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12161 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12162 } 12163 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12164 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12165 if (isCheckinRequest) { 12166 pw.println(); 12167 } 12168 } 12169 return; 12170 } 12171 } 12172 pw.println("No process found for: " + args[opti]); 12173 return; 12174 } 12175 12176 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12177 dumpDetails = true; 12178 } 12179 12180 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12181 12182 String[] innerArgs = new String[args.length-opti]; 12183 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12184 12185 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12186 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12187 long nativePss=0, dalvikPss=0, otherPss=0; 12188 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12189 12190 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12191 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12192 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12193 12194 long totalPss = 0; 12195 long cachedPss = 0; 12196 12197 Debug.MemoryInfo mi = null; 12198 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12199 final ProcessRecord r = procs.get(i); 12200 final IApplicationThread thread; 12201 final int pid; 12202 final int oomAdj; 12203 final boolean hasActivities; 12204 synchronized (this) { 12205 thread = r.thread; 12206 pid = r.pid; 12207 oomAdj = r.getSetAdjWithServices(); 12208 hasActivities = r.activities.size() > 0; 12209 } 12210 if (thread != null) { 12211 if (!isCheckinRequest && dumpDetails) { 12212 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12213 } 12214 if (mi == null) { 12215 mi = new Debug.MemoryInfo(); 12216 } 12217 if (dumpDetails || (!brief && !oomOnly)) { 12218 Debug.getMemoryInfo(pid, mi); 12219 } else { 12220 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12221 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12222 } 12223 if (dumpDetails) { 12224 if (localOnly) { 12225 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12226 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12227 if (isCheckinRequest) { 12228 pw.println(); 12229 } 12230 } else { 12231 try { 12232 pw.flush(); 12233 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12234 dumpDalvik, innerArgs); 12235 } catch (RemoteException e) { 12236 if (!isCheckinRequest) { 12237 pw.println("Got RemoteException!"); 12238 pw.flush(); 12239 } 12240 } 12241 } 12242 } 12243 12244 final long myTotalPss = mi.getTotalPss(); 12245 final long myTotalUss = mi.getTotalUss(); 12246 12247 synchronized (this) { 12248 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12249 // Record this for posterity if the process has been stable. 12250 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12251 } 12252 } 12253 12254 if (!isCheckinRequest && mi != null) { 12255 totalPss += myTotalPss; 12256 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12257 (hasActivities ? " / activities)" : ")"), 12258 r.processName, myTotalPss, pid, hasActivities); 12259 procMems.add(pssItem); 12260 procMemsMap.put(pid, pssItem); 12261 12262 nativePss += mi.nativePss; 12263 dalvikPss += mi.dalvikPss; 12264 otherPss += mi.otherPss; 12265 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12266 long mem = mi.getOtherPss(j); 12267 miscPss[j] += mem; 12268 otherPss -= mem; 12269 } 12270 12271 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12272 cachedPss += myTotalPss; 12273 } 12274 12275 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12276 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12277 || oomIndex == (oomPss.length-1)) { 12278 oomPss[oomIndex] += myTotalPss; 12279 if (oomProcs[oomIndex] == null) { 12280 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12281 } 12282 oomProcs[oomIndex].add(pssItem); 12283 break; 12284 } 12285 } 12286 } 12287 } 12288 } 12289 12290 if (!isCheckinRequest && procs.size() > 1) { 12291 // If we are showing aggregations, also look for native processes to 12292 // include so that our aggregations are more accurate. 12293 updateCpuStatsNow(); 12294 synchronized (mProcessCpuThread) { 12295 final int N = mProcessCpuTracker.countStats(); 12296 for (int i=0; i<N; i++) { 12297 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12298 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12299 if (mi == null) { 12300 mi = new Debug.MemoryInfo(); 12301 } 12302 if (!brief && !oomOnly) { 12303 Debug.getMemoryInfo(st.pid, mi); 12304 } else { 12305 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12306 mi.nativePrivateDirty = (int)tmpLong[0]; 12307 } 12308 12309 final long myTotalPss = mi.getTotalPss(); 12310 totalPss += myTotalPss; 12311 12312 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12313 st.name, myTotalPss, st.pid, false); 12314 procMems.add(pssItem); 12315 12316 nativePss += mi.nativePss; 12317 dalvikPss += mi.dalvikPss; 12318 otherPss += mi.otherPss; 12319 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12320 long mem = mi.getOtherPss(j); 12321 miscPss[j] += mem; 12322 otherPss -= mem; 12323 } 12324 oomPss[0] += myTotalPss; 12325 if (oomProcs[0] == null) { 12326 oomProcs[0] = new ArrayList<MemItem>(); 12327 } 12328 oomProcs[0].add(pssItem); 12329 } 12330 } 12331 } 12332 12333 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12334 12335 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12336 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12337 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12338 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12339 String label = Debug.MemoryInfo.getOtherLabel(j); 12340 catMems.add(new MemItem(label, label, miscPss[j], j)); 12341 } 12342 12343 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12344 for (int j=0; j<oomPss.length; j++) { 12345 if (oomPss[j] != 0) { 12346 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12347 : DUMP_MEM_OOM_LABEL[j]; 12348 MemItem item = new MemItem(label, label, oomPss[j], 12349 DUMP_MEM_OOM_ADJ[j]); 12350 item.subitems = oomProcs[j]; 12351 oomMems.add(item); 12352 } 12353 } 12354 12355 if (!brief && !oomOnly && !isCompact) { 12356 pw.println(); 12357 pw.println("Total PSS by process:"); 12358 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12359 pw.println(); 12360 } 12361 if (!isCompact) { 12362 pw.println("Total PSS by OOM adjustment:"); 12363 } 12364 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12365 if (!brief && !oomOnly) { 12366 PrintWriter out = categoryPw != null ? categoryPw : pw; 12367 if (!isCompact) { 12368 out.println(); 12369 out.println("Total PSS by category:"); 12370 } 12371 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12372 } 12373 if (!isCompact) { 12374 pw.println(); 12375 } 12376 MemInfoReader memInfo = new MemInfoReader(); 12377 memInfo.readMemInfo(); 12378 if (!brief) { 12379 if (!isCompact) { 12380 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12381 pw.print(" kB (status "); 12382 switch (mLastMemoryLevel) { 12383 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12384 pw.println("normal)"); 12385 break; 12386 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12387 pw.println("moderate)"); 12388 break; 12389 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12390 pw.println("low)"); 12391 break; 12392 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12393 pw.println("critical)"); 12394 break; 12395 default: 12396 pw.print(mLastMemoryLevel); 12397 pw.println(")"); 12398 break; 12399 } 12400 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12401 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12402 pw.print(cachedPss); pw.print(" cached pss + "); 12403 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12404 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12405 } else { 12406 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12407 pw.print(cachedPss + memInfo.getCachedSizeKb() 12408 + memInfo.getFreeSizeKb()); pw.print(","); 12409 pw.println(totalPss - cachedPss); 12410 } 12411 } 12412 if (!isCompact) { 12413 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12414 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12415 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12416 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12417 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12418 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12419 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12420 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12421 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12422 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12423 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12424 } 12425 if (!brief) { 12426 if (memInfo.getZramTotalSizeKb() != 0) { 12427 if (!isCompact) { 12428 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12429 pw.print(" kB physical used for "); 12430 pw.print(memInfo.getSwapTotalSizeKb() 12431 - memInfo.getSwapFreeSizeKb()); 12432 pw.print(" kB in swap ("); 12433 pw.print(memInfo.getSwapTotalSizeKb()); 12434 pw.println(" kB total swap)"); 12435 } else { 12436 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12437 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12438 pw.println(memInfo.getSwapFreeSizeKb()); 12439 } 12440 } 12441 final int[] SINGLE_LONG_FORMAT = new int[] { 12442 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12443 }; 12444 long[] longOut = new long[1]; 12445 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12446 SINGLE_LONG_FORMAT, null, longOut, null); 12447 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12448 longOut[0] = 0; 12449 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12450 SINGLE_LONG_FORMAT, null, longOut, null); 12451 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12452 longOut[0] = 0; 12453 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12454 SINGLE_LONG_FORMAT, null, longOut, null); 12455 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12456 longOut[0] = 0; 12457 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12458 SINGLE_LONG_FORMAT, null, longOut, null); 12459 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12460 if (!isCompact) { 12461 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12462 pw.print(" KSM: "); pw.print(sharing); 12463 pw.print(" kB saved from shared "); 12464 pw.print(shared); pw.println(" kB"); 12465 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12466 pw.print(voltile); pw.println(" kB volatile"); 12467 } 12468 pw.print(" Tuning: "); 12469 pw.print(ActivityManager.staticGetMemoryClass()); 12470 pw.print(" (large "); 12471 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12472 pw.print("), oom "); 12473 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12474 pw.print(" kB"); 12475 pw.print(", restore limit "); 12476 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12477 pw.print(" kB"); 12478 if (ActivityManager.isLowRamDeviceStatic()) { 12479 pw.print(" (low-ram)"); 12480 } 12481 if (ActivityManager.isHighEndGfx()) { 12482 pw.print(" (high-end-gfx)"); 12483 } 12484 pw.println(); 12485 } else { 12486 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12487 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12488 pw.println(voltile); 12489 pw.print("tuning,"); 12490 pw.print(ActivityManager.staticGetMemoryClass()); 12491 pw.print(','); 12492 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12493 pw.print(','); 12494 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12495 if (ActivityManager.isLowRamDeviceStatic()) { 12496 pw.print(",low-ram"); 12497 } 12498 if (ActivityManager.isHighEndGfx()) { 12499 pw.print(",high-end-gfx"); 12500 } 12501 pw.println(); 12502 } 12503 } 12504 } 12505 } 12506 12507 /** 12508 * Searches array of arguments for the specified string 12509 * @param args array of argument strings 12510 * @param value value to search for 12511 * @return true if the value is contained in the array 12512 */ 12513 private static boolean scanArgs(String[] args, String value) { 12514 if (args != null) { 12515 for (String arg : args) { 12516 if (value.equals(arg)) { 12517 return true; 12518 } 12519 } 12520 } 12521 return false; 12522 } 12523 12524 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12525 ContentProviderRecord cpr, boolean always) { 12526 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12527 12528 if (!inLaunching || always) { 12529 synchronized (cpr) { 12530 cpr.launchingApp = null; 12531 cpr.notifyAll(); 12532 } 12533 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12534 String names[] = cpr.info.authority.split(";"); 12535 for (int j = 0; j < names.length; j++) { 12536 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12537 } 12538 } 12539 12540 for (int i=0; i<cpr.connections.size(); i++) { 12541 ContentProviderConnection conn = cpr.connections.get(i); 12542 if (conn.waiting) { 12543 // If this connection is waiting for the provider, then we don't 12544 // need to mess with its process unless we are always removing 12545 // or for some reason the provider is not currently launching. 12546 if (inLaunching && !always) { 12547 continue; 12548 } 12549 } 12550 ProcessRecord capp = conn.client; 12551 conn.dead = true; 12552 if (conn.stableCount > 0) { 12553 if (!capp.persistent && capp.thread != null 12554 && capp.pid != 0 12555 && capp.pid != MY_PID) { 12556 killUnneededProcessLocked(capp, "depends on provider " 12557 + cpr.name.flattenToShortString() 12558 + " in dying proc " + (proc != null ? proc.processName : "??")); 12559 } 12560 } else if (capp.thread != null && conn.provider.provider != null) { 12561 try { 12562 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12563 } catch (RemoteException e) { 12564 } 12565 // In the protocol here, we don't expect the client to correctly 12566 // clean up this connection, we'll just remove it. 12567 cpr.connections.remove(i); 12568 conn.client.conProviders.remove(conn); 12569 } 12570 } 12571 12572 if (inLaunching && always) { 12573 mLaunchingProviders.remove(cpr); 12574 } 12575 return inLaunching; 12576 } 12577 12578 /** 12579 * Main code for cleaning up a process when it has gone away. This is 12580 * called both as a result of the process dying, or directly when stopping 12581 * a process when running in single process mode. 12582 */ 12583 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12584 boolean restarting, boolean allowRestart, int index) { 12585 if (index >= 0) { 12586 removeLruProcessLocked(app); 12587 ProcessList.remove(app.pid); 12588 } 12589 12590 mProcessesToGc.remove(app); 12591 mPendingPssProcesses.remove(app); 12592 12593 // Dismiss any open dialogs. 12594 if (app.crashDialog != null && !app.forceCrashReport) { 12595 app.crashDialog.dismiss(); 12596 app.crashDialog = null; 12597 } 12598 if (app.anrDialog != null) { 12599 app.anrDialog.dismiss(); 12600 app.anrDialog = null; 12601 } 12602 if (app.waitDialog != null) { 12603 app.waitDialog.dismiss(); 12604 app.waitDialog = null; 12605 } 12606 12607 app.crashing = false; 12608 app.notResponding = false; 12609 12610 app.resetPackageList(mProcessStats); 12611 app.unlinkDeathRecipient(); 12612 app.makeInactive(mProcessStats); 12613 app.forcingToForeground = null; 12614 updateProcessForegroundLocked(app, false, false); 12615 app.foregroundActivities = false; 12616 app.hasShownUi = false; 12617 app.treatLikeActivity = false; 12618 app.hasAboveClient = false; 12619 app.hasClientActivities = false; 12620 12621 mServices.killServicesLocked(app, allowRestart); 12622 12623 boolean restart = false; 12624 12625 // Remove published content providers. 12626 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12627 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12628 final boolean always = app.bad || !allowRestart; 12629 if (removeDyingProviderLocked(app, cpr, always) || always) { 12630 // We left the provider in the launching list, need to 12631 // restart it. 12632 restart = true; 12633 } 12634 12635 cpr.provider = null; 12636 cpr.proc = null; 12637 } 12638 app.pubProviders.clear(); 12639 12640 // Take care of any launching providers waiting for this process. 12641 if (checkAppInLaunchingProvidersLocked(app, false)) { 12642 restart = true; 12643 } 12644 12645 // Unregister from connected content providers. 12646 if (!app.conProviders.isEmpty()) { 12647 for (int i=0; i<app.conProviders.size(); i++) { 12648 ContentProviderConnection conn = app.conProviders.get(i); 12649 conn.provider.connections.remove(conn); 12650 } 12651 app.conProviders.clear(); 12652 } 12653 12654 // At this point there may be remaining entries in mLaunchingProviders 12655 // where we were the only one waiting, so they are no longer of use. 12656 // Look for these and clean up if found. 12657 // XXX Commented out for now. Trying to figure out a way to reproduce 12658 // the actual situation to identify what is actually going on. 12659 if (false) { 12660 for (int i=0; i<mLaunchingProviders.size(); i++) { 12661 ContentProviderRecord cpr = (ContentProviderRecord) 12662 mLaunchingProviders.get(i); 12663 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12664 synchronized (cpr) { 12665 cpr.launchingApp = null; 12666 cpr.notifyAll(); 12667 } 12668 } 12669 } 12670 } 12671 12672 skipCurrentReceiverLocked(app); 12673 12674 // Unregister any receivers. 12675 for (int i=app.receivers.size()-1; i>=0; i--) { 12676 removeReceiverLocked(app.receivers.valueAt(i)); 12677 } 12678 app.receivers.clear(); 12679 12680 // If the app is undergoing backup, tell the backup manager about it 12681 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12682 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12683 + mBackupTarget.appInfo + " died during backup"); 12684 try { 12685 IBackupManager bm = IBackupManager.Stub.asInterface( 12686 ServiceManager.getService(Context.BACKUP_SERVICE)); 12687 bm.agentDisconnected(app.info.packageName); 12688 } catch (RemoteException e) { 12689 // can't happen; backup manager is local 12690 } 12691 } 12692 12693 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12694 ProcessChangeItem item = mPendingProcessChanges.get(i); 12695 if (item.pid == app.pid) { 12696 mPendingProcessChanges.remove(i); 12697 mAvailProcessChanges.add(item); 12698 } 12699 } 12700 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12701 12702 // If the caller is restarting this app, then leave it in its 12703 // current lists and let the caller take care of it. 12704 if (restarting) { 12705 return; 12706 } 12707 12708 if (!app.persistent || app.isolated) { 12709 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12710 "Removing non-persistent process during cleanup: " + app); 12711 mProcessNames.remove(app.processName, app.uid); 12712 mIsolatedProcesses.remove(app.uid); 12713 if (mHeavyWeightProcess == app) { 12714 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12715 mHeavyWeightProcess.userId, 0)); 12716 mHeavyWeightProcess = null; 12717 } 12718 } else if (!app.removed) { 12719 // This app is persistent, so we need to keep its record around. 12720 // If it is not already on the pending app list, add it there 12721 // and start a new process for it. 12722 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12723 mPersistentStartingProcesses.add(app); 12724 restart = true; 12725 } 12726 } 12727 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12728 "Clean-up removing on hold: " + app); 12729 mProcessesOnHold.remove(app); 12730 12731 if (app == mHomeProcess) { 12732 mHomeProcess = null; 12733 } 12734 if (app == mPreviousProcess) { 12735 mPreviousProcess = null; 12736 } 12737 12738 if (restart && !app.isolated) { 12739 // We have components that still need to be running in the 12740 // process, so re-launch it. 12741 mProcessNames.put(app.processName, app.uid, app); 12742 startProcessLocked(app, "restart", app.processName); 12743 } else if (app.pid > 0 && app.pid != MY_PID) { 12744 // Goodbye! 12745 boolean removed; 12746 synchronized (mPidsSelfLocked) { 12747 mPidsSelfLocked.remove(app.pid); 12748 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12749 } 12750 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12751 app.processName, app.info.uid); 12752 if (app.isolated) { 12753 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12754 } 12755 app.setPid(0); 12756 } 12757 } 12758 12759 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12760 // Look through the content providers we are waiting to have launched, 12761 // and if any run in this process then either schedule a restart of 12762 // the process or kill the client waiting for it if this process has 12763 // gone bad. 12764 int NL = mLaunchingProviders.size(); 12765 boolean restart = false; 12766 for (int i=0; i<NL; i++) { 12767 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12768 if (cpr.launchingApp == app) { 12769 if (!alwaysBad && !app.bad) { 12770 restart = true; 12771 } else { 12772 removeDyingProviderLocked(app, cpr, true); 12773 // cpr should have been removed from mLaunchingProviders 12774 NL = mLaunchingProviders.size(); 12775 i--; 12776 } 12777 } 12778 } 12779 return restart; 12780 } 12781 12782 // ========================================================= 12783 // SERVICES 12784 // ========================================================= 12785 12786 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12787 int flags) { 12788 enforceNotIsolatedCaller("getServices"); 12789 synchronized (this) { 12790 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12791 } 12792 } 12793 12794 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12795 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12796 synchronized (this) { 12797 return mServices.getRunningServiceControlPanelLocked(name); 12798 } 12799 } 12800 12801 public ComponentName startService(IApplicationThread caller, Intent service, 12802 String resolvedType, int userId) { 12803 enforceNotIsolatedCaller("startService"); 12804 // Refuse possible leaked file descriptors 12805 if (service != null && service.hasFileDescriptors() == true) { 12806 throw new IllegalArgumentException("File descriptors passed in Intent"); 12807 } 12808 12809 if (DEBUG_SERVICE) 12810 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12811 synchronized(this) { 12812 final int callingPid = Binder.getCallingPid(); 12813 final int callingUid = Binder.getCallingUid(); 12814 final long origId = Binder.clearCallingIdentity(); 12815 ComponentName res = mServices.startServiceLocked(caller, service, 12816 resolvedType, callingPid, callingUid, userId); 12817 Binder.restoreCallingIdentity(origId); 12818 return res; 12819 } 12820 } 12821 12822 ComponentName startServiceInPackage(int uid, 12823 Intent service, String resolvedType, int userId) { 12824 synchronized(this) { 12825 if (DEBUG_SERVICE) 12826 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12827 final long origId = Binder.clearCallingIdentity(); 12828 ComponentName res = mServices.startServiceLocked(null, service, 12829 resolvedType, -1, uid, userId); 12830 Binder.restoreCallingIdentity(origId); 12831 return res; 12832 } 12833 } 12834 12835 public int stopService(IApplicationThread caller, Intent service, 12836 String resolvedType, int userId) { 12837 enforceNotIsolatedCaller("stopService"); 12838 // Refuse possible leaked file descriptors 12839 if (service != null && service.hasFileDescriptors() == true) { 12840 throw new IllegalArgumentException("File descriptors passed in Intent"); 12841 } 12842 12843 synchronized(this) { 12844 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12845 } 12846 } 12847 12848 public IBinder peekService(Intent service, String resolvedType) { 12849 enforceNotIsolatedCaller("peekService"); 12850 // Refuse possible leaked file descriptors 12851 if (service != null && service.hasFileDescriptors() == true) { 12852 throw new IllegalArgumentException("File descriptors passed in Intent"); 12853 } 12854 synchronized(this) { 12855 return mServices.peekServiceLocked(service, resolvedType); 12856 } 12857 } 12858 12859 public boolean stopServiceToken(ComponentName className, IBinder token, 12860 int startId) { 12861 synchronized(this) { 12862 return mServices.stopServiceTokenLocked(className, token, startId); 12863 } 12864 } 12865 12866 public void setServiceForeground(ComponentName className, IBinder token, 12867 int id, Notification notification, boolean removeNotification) { 12868 synchronized(this) { 12869 mServices.setServiceForegroundLocked(className, token, id, notification, 12870 removeNotification); 12871 } 12872 } 12873 12874 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12875 boolean requireFull, String name, String callerPackage) { 12876 final int callingUserId = UserHandle.getUserId(callingUid); 12877 if (callingUserId != userId) { 12878 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12879 if ((requireFull || checkComponentPermission( 12880 android.Manifest.permission.INTERACT_ACROSS_USERS, 12881 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12882 && checkComponentPermission( 12883 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12884 callingPid, callingUid, -1, true) 12885 != PackageManager.PERMISSION_GRANTED) { 12886 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12887 // In this case, they would like to just execute as their 12888 // owner user instead of failing. 12889 userId = callingUserId; 12890 } else { 12891 StringBuilder builder = new StringBuilder(128); 12892 builder.append("Permission Denial: "); 12893 builder.append(name); 12894 if (callerPackage != null) { 12895 builder.append(" from "); 12896 builder.append(callerPackage); 12897 } 12898 builder.append(" asks to run as user "); 12899 builder.append(userId); 12900 builder.append(" but is calling from user "); 12901 builder.append(UserHandle.getUserId(callingUid)); 12902 builder.append("; this requires "); 12903 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12904 if (!requireFull) { 12905 builder.append(" or "); 12906 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12907 } 12908 String msg = builder.toString(); 12909 Slog.w(TAG, msg); 12910 throw new SecurityException(msg); 12911 } 12912 } 12913 } 12914 if (userId == UserHandle.USER_CURRENT 12915 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12916 // Note that we may be accessing this outside of a lock... 12917 // shouldn't be a big deal, if this is being called outside 12918 // of a locked context there is intrinsically a race with 12919 // the value the caller will receive and someone else changing it. 12920 userId = mCurrentUserId; 12921 } 12922 if (!allowAll && userId < 0) { 12923 throw new IllegalArgumentException( 12924 "Call does not support special user #" + userId); 12925 } 12926 } 12927 return userId; 12928 } 12929 12930 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12931 String className, int flags) { 12932 boolean result = false; 12933 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12934 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12935 if (ActivityManager.checkUidPermission( 12936 android.Manifest.permission.INTERACT_ACROSS_USERS, 12937 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12938 ComponentName comp = new ComponentName(aInfo.packageName, className); 12939 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12940 + " requests FLAG_SINGLE_USER, but app does not hold " 12941 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12942 Slog.w(TAG, msg); 12943 throw new SecurityException(msg); 12944 } 12945 result = true; 12946 } 12947 } else if (componentProcessName == aInfo.packageName) { 12948 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12949 } else if ("system".equals(componentProcessName)) { 12950 result = true; 12951 } 12952 if (DEBUG_MU) { 12953 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12954 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12955 } 12956 return result; 12957 } 12958 12959 public int bindService(IApplicationThread caller, IBinder token, 12960 Intent service, String resolvedType, 12961 IServiceConnection connection, int flags, int userId) { 12962 enforceNotIsolatedCaller("bindService"); 12963 // Refuse possible leaked file descriptors 12964 if (service != null && service.hasFileDescriptors() == true) { 12965 throw new IllegalArgumentException("File descriptors passed in Intent"); 12966 } 12967 12968 synchronized(this) { 12969 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12970 connection, flags, userId); 12971 } 12972 } 12973 12974 public boolean unbindService(IServiceConnection connection) { 12975 synchronized (this) { 12976 return mServices.unbindServiceLocked(connection); 12977 } 12978 } 12979 12980 public void publishService(IBinder token, Intent intent, IBinder service) { 12981 // Refuse possible leaked file descriptors 12982 if (intent != null && intent.hasFileDescriptors() == true) { 12983 throw new IllegalArgumentException("File descriptors passed in Intent"); 12984 } 12985 12986 synchronized(this) { 12987 if (!(token instanceof ServiceRecord)) { 12988 throw new IllegalArgumentException("Invalid service token"); 12989 } 12990 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12991 } 12992 } 12993 12994 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12995 // Refuse possible leaked file descriptors 12996 if (intent != null && intent.hasFileDescriptors() == true) { 12997 throw new IllegalArgumentException("File descriptors passed in Intent"); 12998 } 12999 13000 synchronized(this) { 13001 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13002 } 13003 } 13004 13005 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13006 synchronized(this) { 13007 if (!(token instanceof ServiceRecord)) { 13008 throw new IllegalArgumentException("Invalid service token"); 13009 } 13010 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13011 } 13012 } 13013 13014 // ========================================================= 13015 // BACKUP AND RESTORE 13016 // ========================================================= 13017 13018 // Cause the target app to be launched if necessary and its backup agent 13019 // instantiated. The backup agent will invoke backupAgentCreated() on the 13020 // activity manager to announce its creation. 13021 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13022 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13023 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13024 13025 synchronized(this) { 13026 // !!! TODO: currently no check here that we're already bound 13027 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13028 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13029 synchronized (stats) { 13030 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13031 } 13032 13033 // Backup agent is now in use, its package can't be stopped. 13034 try { 13035 AppGlobals.getPackageManager().setPackageStoppedState( 13036 app.packageName, false, UserHandle.getUserId(app.uid)); 13037 } catch (RemoteException e) { 13038 } catch (IllegalArgumentException e) { 13039 Slog.w(TAG, "Failed trying to unstop package " 13040 + app.packageName + ": " + e); 13041 } 13042 13043 BackupRecord r = new BackupRecord(ss, app, backupMode); 13044 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13045 ? new ComponentName(app.packageName, app.backupAgentName) 13046 : new ComponentName("android", "FullBackupAgent"); 13047 // startProcessLocked() returns existing proc's record if it's already running 13048 ProcessRecord proc = startProcessLocked(app.processName, app, 13049 false, 0, "backup", hostingName, false, false, false); 13050 if (proc == null) { 13051 Slog.e(TAG, "Unable to start backup agent process " + r); 13052 return false; 13053 } 13054 13055 r.app = proc; 13056 mBackupTarget = r; 13057 mBackupAppName = app.packageName; 13058 13059 // Try not to kill the process during backup 13060 updateOomAdjLocked(proc); 13061 13062 // If the process is already attached, schedule the creation of the backup agent now. 13063 // If it is not yet live, this will be done when it attaches to the framework. 13064 if (proc.thread != null) { 13065 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13066 try { 13067 proc.thread.scheduleCreateBackupAgent(app, 13068 compatibilityInfoForPackageLocked(app), backupMode); 13069 } catch (RemoteException e) { 13070 // Will time out on the backup manager side 13071 } 13072 } else { 13073 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13074 } 13075 // Invariants: at this point, the target app process exists and the application 13076 // is either already running or in the process of coming up. mBackupTarget and 13077 // mBackupAppName describe the app, so that when it binds back to the AM we 13078 // know that it's scheduled for a backup-agent operation. 13079 } 13080 13081 return true; 13082 } 13083 13084 @Override 13085 public void clearPendingBackup() { 13086 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13087 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13088 13089 synchronized (this) { 13090 mBackupTarget = null; 13091 mBackupAppName = null; 13092 } 13093 } 13094 13095 // A backup agent has just come up 13096 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13097 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13098 + " = " + agent); 13099 13100 synchronized(this) { 13101 if (!agentPackageName.equals(mBackupAppName)) { 13102 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13103 return; 13104 } 13105 } 13106 13107 long oldIdent = Binder.clearCallingIdentity(); 13108 try { 13109 IBackupManager bm = IBackupManager.Stub.asInterface( 13110 ServiceManager.getService(Context.BACKUP_SERVICE)); 13111 bm.agentConnected(agentPackageName, agent); 13112 } catch (RemoteException e) { 13113 // can't happen; the backup manager service is local 13114 } catch (Exception e) { 13115 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13116 e.printStackTrace(); 13117 } finally { 13118 Binder.restoreCallingIdentity(oldIdent); 13119 } 13120 } 13121 13122 // done with this agent 13123 public void unbindBackupAgent(ApplicationInfo appInfo) { 13124 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13125 if (appInfo == null) { 13126 Slog.w(TAG, "unbind backup agent for null app"); 13127 return; 13128 } 13129 13130 synchronized(this) { 13131 try { 13132 if (mBackupAppName == null) { 13133 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13134 return; 13135 } 13136 13137 if (!mBackupAppName.equals(appInfo.packageName)) { 13138 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13139 return; 13140 } 13141 13142 // Not backing this app up any more; reset its OOM adjustment 13143 final ProcessRecord proc = mBackupTarget.app; 13144 updateOomAdjLocked(proc); 13145 13146 // If the app crashed during backup, 'thread' will be null here 13147 if (proc.thread != null) { 13148 try { 13149 proc.thread.scheduleDestroyBackupAgent(appInfo, 13150 compatibilityInfoForPackageLocked(appInfo)); 13151 } catch (Exception e) { 13152 Slog.e(TAG, "Exception when unbinding backup agent:"); 13153 e.printStackTrace(); 13154 } 13155 } 13156 } finally { 13157 mBackupTarget = null; 13158 mBackupAppName = null; 13159 } 13160 } 13161 } 13162 // ========================================================= 13163 // BROADCASTS 13164 // ========================================================= 13165 13166 private final List getStickiesLocked(String action, IntentFilter filter, 13167 List cur, int userId) { 13168 final ContentResolver resolver = mContext.getContentResolver(); 13169 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13170 if (stickies == null) { 13171 return cur; 13172 } 13173 final ArrayList<Intent> list = stickies.get(action); 13174 if (list == null) { 13175 return cur; 13176 } 13177 int N = list.size(); 13178 for (int i=0; i<N; i++) { 13179 Intent intent = list.get(i); 13180 if (filter.match(resolver, intent, true, TAG) >= 0) { 13181 if (cur == null) { 13182 cur = new ArrayList<Intent>(); 13183 } 13184 cur.add(intent); 13185 } 13186 } 13187 return cur; 13188 } 13189 13190 boolean isPendingBroadcastProcessLocked(int pid) { 13191 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13192 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13193 } 13194 13195 void skipPendingBroadcastLocked(int pid) { 13196 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13197 for (BroadcastQueue queue : mBroadcastQueues) { 13198 queue.skipPendingBroadcastLocked(pid); 13199 } 13200 } 13201 13202 // The app just attached; send any pending broadcasts that it should receive 13203 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13204 boolean didSomething = false; 13205 for (BroadcastQueue queue : mBroadcastQueues) { 13206 didSomething |= queue.sendPendingBroadcastsLocked(app); 13207 } 13208 return didSomething; 13209 } 13210 13211 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13212 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13213 enforceNotIsolatedCaller("registerReceiver"); 13214 int callingUid; 13215 int callingPid; 13216 synchronized(this) { 13217 ProcessRecord callerApp = null; 13218 if (caller != null) { 13219 callerApp = getRecordForAppLocked(caller); 13220 if (callerApp == null) { 13221 throw new SecurityException( 13222 "Unable to find app for caller " + caller 13223 + " (pid=" + Binder.getCallingPid() 13224 + ") when registering receiver " + receiver); 13225 } 13226 if (callerApp.info.uid != Process.SYSTEM_UID && 13227 !callerApp.pkgList.containsKey(callerPackage) && 13228 !"android".equals(callerPackage)) { 13229 throw new SecurityException("Given caller package " + callerPackage 13230 + " is not running in process " + callerApp); 13231 } 13232 callingUid = callerApp.info.uid; 13233 callingPid = callerApp.pid; 13234 } else { 13235 callerPackage = null; 13236 callingUid = Binder.getCallingUid(); 13237 callingPid = Binder.getCallingPid(); 13238 } 13239 13240 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13241 true, true, "registerReceiver", callerPackage); 13242 13243 List allSticky = null; 13244 13245 // Look for any matching sticky broadcasts... 13246 Iterator actions = filter.actionsIterator(); 13247 if (actions != null) { 13248 while (actions.hasNext()) { 13249 String action = (String)actions.next(); 13250 allSticky = getStickiesLocked(action, filter, allSticky, 13251 UserHandle.USER_ALL); 13252 allSticky = getStickiesLocked(action, filter, allSticky, 13253 UserHandle.getUserId(callingUid)); 13254 } 13255 } else { 13256 allSticky = getStickiesLocked(null, filter, allSticky, 13257 UserHandle.USER_ALL); 13258 allSticky = getStickiesLocked(null, filter, allSticky, 13259 UserHandle.getUserId(callingUid)); 13260 } 13261 13262 // The first sticky in the list is returned directly back to 13263 // the client. 13264 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13265 13266 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13267 + ": " + sticky); 13268 13269 if (receiver == null) { 13270 return sticky; 13271 } 13272 13273 ReceiverList rl 13274 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13275 if (rl == null) { 13276 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13277 userId, receiver); 13278 if (rl.app != null) { 13279 rl.app.receivers.add(rl); 13280 } else { 13281 try { 13282 receiver.asBinder().linkToDeath(rl, 0); 13283 } catch (RemoteException e) { 13284 return sticky; 13285 } 13286 rl.linkedToDeath = true; 13287 } 13288 mRegisteredReceivers.put(receiver.asBinder(), rl); 13289 } else if (rl.uid != callingUid) { 13290 throw new IllegalArgumentException( 13291 "Receiver requested to register for uid " + callingUid 13292 + " was previously registered for uid " + rl.uid); 13293 } else if (rl.pid != callingPid) { 13294 throw new IllegalArgumentException( 13295 "Receiver requested to register for pid " + callingPid 13296 + " was previously registered for pid " + rl.pid); 13297 } else if (rl.userId != userId) { 13298 throw new IllegalArgumentException( 13299 "Receiver requested to register for user " + userId 13300 + " was previously registered for user " + rl.userId); 13301 } 13302 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13303 permission, callingUid, userId); 13304 rl.add(bf); 13305 if (!bf.debugCheck()) { 13306 Slog.w(TAG, "==> For Dynamic broadast"); 13307 } 13308 mReceiverResolver.addFilter(bf); 13309 13310 // Enqueue broadcasts for all existing stickies that match 13311 // this filter. 13312 if (allSticky != null) { 13313 ArrayList receivers = new ArrayList(); 13314 receivers.add(bf); 13315 13316 int N = allSticky.size(); 13317 for (int i=0; i<N; i++) { 13318 Intent intent = (Intent)allSticky.get(i); 13319 BroadcastQueue queue = broadcastQueueForIntent(intent); 13320 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13321 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13322 null, null, false, true, true, -1); 13323 queue.enqueueParallelBroadcastLocked(r); 13324 queue.scheduleBroadcastsLocked(); 13325 } 13326 } 13327 13328 return sticky; 13329 } 13330 } 13331 13332 public void unregisterReceiver(IIntentReceiver receiver) { 13333 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13334 13335 final long origId = Binder.clearCallingIdentity(); 13336 try { 13337 boolean doTrim = false; 13338 13339 synchronized(this) { 13340 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13341 if (rl != null) { 13342 if (rl.curBroadcast != null) { 13343 BroadcastRecord r = rl.curBroadcast; 13344 final boolean doNext = finishReceiverLocked( 13345 receiver.asBinder(), r.resultCode, r.resultData, 13346 r.resultExtras, r.resultAbort); 13347 if (doNext) { 13348 doTrim = true; 13349 r.queue.processNextBroadcast(false); 13350 } 13351 } 13352 13353 if (rl.app != null) { 13354 rl.app.receivers.remove(rl); 13355 } 13356 removeReceiverLocked(rl); 13357 if (rl.linkedToDeath) { 13358 rl.linkedToDeath = false; 13359 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13360 } 13361 } 13362 } 13363 13364 // If we actually concluded any broadcasts, we might now be able 13365 // to trim the recipients' apps from our working set 13366 if (doTrim) { 13367 trimApplications(); 13368 return; 13369 } 13370 13371 } finally { 13372 Binder.restoreCallingIdentity(origId); 13373 } 13374 } 13375 13376 void removeReceiverLocked(ReceiverList rl) { 13377 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13378 int N = rl.size(); 13379 for (int i=0; i<N; i++) { 13380 mReceiverResolver.removeFilter(rl.get(i)); 13381 } 13382 } 13383 13384 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13385 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13386 ProcessRecord r = mLruProcesses.get(i); 13387 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13388 try { 13389 r.thread.dispatchPackageBroadcast(cmd, packages); 13390 } catch (RemoteException ex) { 13391 } 13392 } 13393 } 13394 } 13395 13396 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13397 int[] users) { 13398 List<ResolveInfo> receivers = null; 13399 try { 13400 HashSet<ComponentName> singleUserReceivers = null; 13401 boolean scannedFirstReceivers = false; 13402 for (int user : users) { 13403 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13404 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13405 if (user != 0 && newReceivers != null) { 13406 // If this is not the primary user, we need to check for 13407 // any receivers that should be filtered out. 13408 for (int i=0; i<newReceivers.size(); i++) { 13409 ResolveInfo ri = newReceivers.get(i); 13410 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13411 newReceivers.remove(i); 13412 i--; 13413 } 13414 } 13415 } 13416 if (newReceivers != null && newReceivers.size() == 0) { 13417 newReceivers = null; 13418 } 13419 if (receivers == null) { 13420 receivers = newReceivers; 13421 } else if (newReceivers != null) { 13422 // We need to concatenate the additional receivers 13423 // found with what we have do far. This would be easy, 13424 // but we also need to de-dup any receivers that are 13425 // singleUser. 13426 if (!scannedFirstReceivers) { 13427 // Collect any single user receivers we had already retrieved. 13428 scannedFirstReceivers = true; 13429 for (int i=0; i<receivers.size(); i++) { 13430 ResolveInfo ri = receivers.get(i); 13431 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13432 ComponentName cn = new ComponentName( 13433 ri.activityInfo.packageName, ri.activityInfo.name); 13434 if (singleUserReceivers == null) { 13435 singleUserReceivers = new HashSet<ComponentName>(); 13436 } 13437 singleUserReceivers.add(cn); 13438 } 13439 } 13440 } 13441 // Add the new results to the existing results, tracking 13442 // and de-dupping single user receivers. 13443 for (int i=0; i<newReceivers.size(); i++) { 13444 ResolveInfo ri = newReceivers.get(i); 13445 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13446 ComponentName cn = new ComponentName( 13447 ri.activityInfo.packageName, ri.activityInfo.name); 13448 if (singleUserReceivers == null) { 13449 singleUserReceivers = new HashSet<ComponentName>(); 13450 } 13451 if (!singleUserReceivers.contains(cn)) { 13452 singleUserReceivers.add(cn); 13453 receivers.add(ri); 13454 } 13455 } else { 13456 receivers.add(ri); 13457 } 13458 } 13459 } 13460 } 13461 } catch (RemoteException ex) { 13462 // pm is in same process, this will never happen. 13463 } 13464 return receivers; 13465 } 13466 13467 private final int broadcastIntentLocked(ProcessRecord callerApp, 13468 String callerPackage, Intent intent, String resolvedType, 13469 IIntentReceiver resultTo, int resultCode, String resultData, 13470 Bundle map, String requiredPermission, int appOp, 13471 boolean ordered, boolean sticky, int callingPid, int callingUid, 13472 int userId) { 13473 intent = new Intent(intent); 13474 13475 // By default broadcasts do not go to stopped apps. 13476 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13477 13478 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13479 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13480 + " ordered=" + ordered + " userid=" + userId); 13481 if ((resultTo != null) && !ordered) { 13482 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13483 } 13484 13485 userId = handleIncomingUser(callingPid, callingUid, userId, 13486 true, false, "broadcast", callerPackage); 13487 13488 // Make sure that the user who is receiving this broadcast is started. 13489 // If not, we will just skip it. 13490 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13491 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13492 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13493 Slog.w(TAG, "Skipping broadcast of " + intent 13494 + ": user " + userId + " is stopped"); 13495 return ActivityManager.BROADCAST_SUCCESS; 13496 } 13497 } 13498 13499 /* 13500 * Prevent non-system code (defined here to be non-persistent 13501 * processes) from sending protected broadcasts. 13502 */ 13503 int callingAppId = UserHandle.getAppId(callingUid); 13504 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13505 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13506 callingUid == 0) { 13507 // Always okay. 13508 } else if (callerApp == null || !callerApp.persistent) { 13509 try { 13510 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13511 intent.getAction())) { 13512 String msg = "Permission Denial: not allowed to send broadcast " 13513 + intent.getAction() + " from pid=" 13514 + callingPid + ", uid=" + callingUid; 13515 Slog.w(TAG, msg); 13516 throw new SecurityException(msg); 13517 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13518 // Special case for compatibility: we don't want apps to send this, 13519 // but historically it has not been protected and apps may be using it 13520 // to poke their own app widget. So, instead of making it protected, 13521 // just limit it to the caller. 13522 if (callerApp == null) { 13523 String msg = "Permission Denial: not allowed to send broadcast " 13524 + intent.getAction() + " from unknown caller."; 13525 Slog.w(TAG, msg); 13526 throw new SecurityException(msg); 13527 } else if (intent.getComponent() != null) { 13528 // They are good enough to send to an explicit component... verify 13529 // it is being sent to the calling app. 13530 if (!intent.getComponent().getPackageName().equals( 13531 callerApp.info.packageName)) { 13532 String msg = "Permission Denial: not allowed to send broadcast " 13533 + intent.getAction() + " to " 13534 + intent.getComponent().getPackageName() + " from " 13535 + callerApp.info.packageName; 13536 Slog.w(TAG, msg); 13537 throw new SecurityException(msg); 13538 } 13539 } else { 13540 // Limit broadcast to their own package. 13541 intent.setPackage(callerApp.info.packageName); 13542 } 13543 } 13544 } catch (RemoteException e) { 13545 Slog.w(TAG, "Remote exception", e); 13546 return ActivityManager.BROADCAST_SUCCESS; 13547 } 13548 } 13549 13550 // Handle special intents: if this broadcast is from the package 13551 // manager about a package being removed, we need to remove all of 13552 // its activities from the history stack. 13553 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13554 intent.getAction()); 13555 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13556 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13557 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13558 || uidRemoved) { 13559 if (checkComponentPermission( 13560 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13561 callingPid, callingUid, -1, true) 13562 == PackageManager.PERMISSION_GRANTED) { 13563 if (uidRemoved) { 13564 final Bundle intentExtras = intent.getExtras(); 13565 final int uid = intentExtras != null 13566 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13567 if (uid >= 0) { 13568 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13569 synchronized (bs) { 13570 bs.removeUidStatsLocked(uid); 13571 } 13572 mAppOpsService.uidRemoved(uid); 13573 } 13574 } else { 13575 // If resources are unavailable just force stop all 13576 // those packages and flush the attribute cache as well. 13577 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13578 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13579 if (list != null && (list.length > 0)) { 13580 for (String pkg : list) { 13581 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13582 "storage unmount"); 13583 } 13584 sendPackageBroadcastLocked( 13585 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13586 } 13587 } else { 13588 Uri data = intent.getData(); 13589 String ssp; 13590 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13591 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13592 intent.getAction()); 13593 boolean fullUninstall = removed && 13594 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13595 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13596 forceStopPackageLocked(ssp, UserHandle.getAppId( 13597 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13598 false, fullUninstall, userId, 13599 removed ? "pkg removed" : "pkg changed"); 13600 } 13601 if (removed) { 13602 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13603 new String[] {ssp}, userId); 13604 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13605 mAppOpsService.packageRemoved( 13606 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13607 13608 // Remove all permissions granted from/to this package 13609 removeUriPermissionsForPackageLocked(ssp, userId, true); 13610 } 13611 } 13612 } 13613 } 13614 } 13615 } else { 13616 String msg = "Permission Denial: " + intent.getAction() 13617 + " broadcast from " + callerPackage + " (pid=" + callingPid 13618 + ", uid=" + callingUid + ")" 13619 + " requires " 13620 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13621 Slog.w(TAG, msg); 13622 throw new SecurityException(msg); 13623 } 13624 13625 // Special case for adding a package: by default turn on compatibility 13626 // mode. 13627 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13628 Uri data = intent.getData(); 13629 String ssp; 13630 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13631 mCompatModePackages.handlePackageAddedLocked(ssp, 13632 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13633 } 13634 } 13635 13636 /* 13637 * If this is the time zone changed action, queue up a message that will reset the timezone 13638 * of all currently running processes. This message will get queued up before the broadcast 13639 * happens. 13640 */ 13641 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13642 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13643 } 13644 13645 /* 13646 * If the user set the time, let all running processes know. 13647 */ 13648 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13649 final int is24Hour = intent.getBooleanExtra( 13650 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13651 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13652 } 13653 13654 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13655 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13656 } 13657 13658 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13659 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13660 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13661 } 13662 13663 // Add to the sticky list if requested. 13664 if (sticky) { 13665 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13666 callingPid, callingUid) 13667 != PackageManager.PERMISSION_GRANTED) { 13668 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13669 + callingPid + ", uid=" + callingUid 13670 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13671 Slog.w(TAG, msg); 13672 throw new SecurityException(msg); 13673 } 13674 if (requiredPermission != null) { 13675 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13676 + " and enforce permission " + requiredPermission); 13677 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13678 } 13679 if (intent.getComponent() != null) { 13680 throw new SecurityException( 13681 "Sticky broadcasts can't target a specific component"); 13682 } 13683 // We use userId directly here, since the "all" target is maintained 13684 // as a separate set of sticky broadcasts. 13685 if (userId != UserHandle.USER_ALL) { 13686 // But first, if this is not a broadcast to all users, then 13687 // make sure it doesn't conflict with an existing broadcast to 13688 // all users. 13689 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13690 UserHandle.USER_ALL); 13691 if (stickies != null) { 13692 ArrayList<Intent> list = stickies.get(intent.getAction()); 13693 if (list != null) { 13694 int N = list.size(); 13695 int i; 13696 for (i=0; i<N; i++) { 13697 if (intent.filterEquals(list.get(i))) { 13698 throw new IllegalArgumentException( 13699 "Sticky broadcast " + intent + " for user " 13700 + userId + " conflicts with existing global broadcast"); 13701 } 13702 } 13703 } 13704 } 13705 } 13706 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13707 if (stickies == null) { 13708 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13709 mStickyBroadcasts.put(userId, stickies); 13710 } 13711 ArrayList<Intent> list = stickies.get(intent.getAction()); 13712 if (list == null) { 13713 list = new ArrayList<Intent>(); 13714 stickies.put(intent.getAction(), list); 13715 } 13716 int N = list.size(); 13717 int i; 13718 for (i=0; i<N; i++) { 13719 if (intent.filterEquals(list.get(i))) { 13720 // This sticky already exists, replace it. 13721 list.set(i, new Intent(intent)); 13722 break; 13723 } 13724 } 13725 if (i >= N) { 13726 list.add(new Intent(intent)); 13727 } 13728 } 13729 13730 int[] users; 13731 if (userId == UserHandle.USER_ALL) { 13732 // Caller wants broadcast to go to all started users. 13733 users = mStartedUserArray; 13734 } else { 13735 // Caller wants broadcast to go to one specific user. 13736 users = new int[] {userId}; 13737 } 13738 13739 // Figure out who all will receive this broadcast. 13740 List receivers = null; 13741 List<BroadcastFilter> registeredReceivers = null; 13742 // Need to resolve the intent to interested receivers... 13743 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13744 == 0) { 13745 receivers = collectReceiverComponents(intent, resolvedType, users); 13746 } 13747 if (intent.getComponent() == null) { 13748 registeredReceivers = mReceiverResolver.queryIntent(intent, 13749 resolvedType, false, userId); 13750 } 13751 13752 final boolean replacePending = 13753 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13754 13755 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13756 + " replacePending=" + replacePending); 13757 13758 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13759 if (!ordered && NR > 0) { 13760 // If we are not serializing this broadcast, then send the 13761 // registered receivers separately so they don't wait for the 13762 // components to be launched. 13763 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13764 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13765 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13766 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13767 ordered, sticky, false, userId); 13768 if (DEBUG_BROADCAST) Slog.v( 13769 TAG, "Enqueueing parallel broadcast " + r); 13770 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13771 if (!replaced) { 13772 queue.enqueueParallelBroadcastLocked(r); 13773 queue.scheduleBroadcastsLocked(); 13774 } 13775 registeredReceivers = null; 13776 NR = 0; 13777 } 13778 13779 // Merge into one list. 13780 int ir = 0; 13781 if (receivers != null) { 13782 // A special case for PACKAGE_ADDED: do not allow the package 13783 // being added to see this broadcast. This prevents them from 13784 // using this as a back door to get run as soon as they are 13785 // installed. Maybe in the future we want to have a special install 13786 // broadcast or such for apps, but we'd like to deliberately make 13787 // this decision. 13788 String skipPackages[] = null; 13789 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13790 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13791 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13792 Uri data = intent.getData(); 13793 if (data != null) { 13794 String pkgName = data.getSchemeSpecificPart(); 13795 if (pkgName != null) { 13796 skipPackages = new String[] { pkgName }; 13797 } 13798 } 13799 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13800 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13801 } 13802 if (skipPackages != null && (skipPackages.length > 0)) { 13803 for (String skipPackage : skipPackages) { 13804 if (skipPackage != null) { 13805 int NT = receivers.size(); 13806 for (int it=0; it<NT; it++) { 13807 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13808 if (curt.activityInfo.packageName.equals(skipPackage)) { 13809 receivers.remove(it); 13810 it--; 13811 NT--; 13812 } 13813 } 13814 } 13815 } 13816 } 13817 13818 int NT = receivers != null ? receivers.size() : 0; 13819 int it = 0; 13820 ResolveInfo curt = null; 13821 BroadcastFilter curr = null; 13822 while (it < NT && ir < NR) { 13823 if (curt == null) { 13824 curt = (ResolveInfo)receivers.get(it); 13825 } 13826 if (curr == null) { 13827 curr = registeredReceivers.get(ir); 13828 } 13829 if (curr.getPriority() >= curt.priority) { 13830 // Insert this broadcast record into the final list. 13831 receivers.add(it, curr); 13832 ir++; 13833 curr = null; 13834 it++; 13835 NT++; 13836 } else { 13837 // Skip to the next ResolveInfo in the final list. 13838 it++; 13839 curt = null; 13840 } 13841 } 13842 } 13843 while (ir < NR) { 13844 if (receivers == null) { 13845 receivers = new ArrayList(); 13846 } 13847 receivers.add(registeredReceivers.get(ir)); 13848 ir++; 13849 } 13850 13851 if ((receivers != null && receivers.size() > 0) 13852 || resultTo != null) { 13853 BroadcastQueue queue = broadcastQueueForIntent(intent); 13854 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13855 callerPackage, callingPid, callingUid, resolvedType, 13856 requiredPermission, appOp, receivers, resultTo, resultCode, 13857 resultData, map, ordered, sticky, false, userId); 13858 if (DEBUG_BROADCAST) Slog.v( 13859 TAG, "Enqueueing ordered broadcast " + r 13860 + ": prev had " + queue.mOrderedBroadcasts.size()); 13861 if (DEBUG_BROADCAST) { 13862 int seq = r.intent.getIntExtra("seq", -1); 13863 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13864 } 13865 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13866 if (!replaced) { 13867 queue.enqueueOrderedBroadcastLocked(r); 13868 queue.scheduleBroadcastsLocked(); 13869 } 13870 } 13871 13872 return ActivityManager.BROADCAST_SUCCESS; 13873 } 13874 13875 final Intent verifyBroadcastLocked(Intent intent) { 13876 // Refuse possible leaked file descriptors 13877 if (intent != null && intent.hasFileDescriptors() == true) { 13878 throw new IllegalArgumentException("File descriptors passed in Intent"); 13879 } 13880 13881 int flags = intent.getFlags(); 13882 13883 if (!mProcessesReady) { 13884 // if the caller really truly claims to know what they're doing, go 13885 // ahead and allow the broadcast without launching any receivers 13886 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13887 intent = new Intent(intent); 13888 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13889 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13890 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13891 + " before boot completion"); 13892 throw new IllegalStateException("Cannot broadcast before boot completed"); 13893 } 13894 } 13895 13896 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13897 throw new IllegalArgumentException( 13898 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13899 } 13900 13901 return intent; 13902 } 13903 13904 public final int broadcastIntent(IApplicationThread caller, 13905 Intent intent, String resolvedType, IIntentReceiver resultTo, 13906 int resultCode, String resultData, Bundle map, 13907 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13908 enforceNotIsolatedCaller("broadcastIntent"); 13909 synchronized(this) { 13910 intent = verifyBroadcastLocked(intent); 13911 13912 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13913 final int callingPid = Binder.getCallingPid(); 13914 final int callingUid = Binder.getCallingUid(); 13915 final long origId = Binder.clearCallingIdentity(); 13916 int res = broadcastIntentLocked(callerApp, 13917 callerApp != null ? callerApp.info.packageName : null, 13918 intent, resolvedType, resultTo, 13919 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13920 callingPid, callingUid, userId); 13921 Binder.restoreCallingIdentity(origId); 13922 return res; 13923 } 13924 } 13925 13926 int broadcastIntentInPackage(String packageName, int uid, 13927 Intent intent, String resolvedType, IIntentReceiver resultTo, 13928 int resultCode, String resultData, Bundle map, 13929 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13930 synchronized(this) { 13931 intent = verifyBroadcastLocked(intent); 13932 13933 final long origId = Binder.clearCallingIdentity(); 13934 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13935 resultTo, resultCode, resultData, map, requiredPermission, 13936 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13937 Binder.restoreCallingIdentity(origId); 13938 return res; 13939 } 13940 } 13941 13942 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13943 // Refuse possible leaked file descriptors 13944 if (intent != null && intent.hasFileDescriptors() == true) { 13945 throw new IllegalArgumentException("File descriptors passed in Intent"); 13946 } 13947 13948 userId = handleIncomingUser(Binder.getCallingPid(), 13949 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13950 13951 synchronized(this) { 13952 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13953 != PackageManager.PERMISSION_GRANTED) { 13954 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13955 + Binder.getCallingPid() 13956 + ", uid=" + Binder.getCallingUid() 13957 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13958 Slog.w(TAG, msg); 13959 throw new SecurityException(msg); 13960 } 13961 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13962 if (stickies != null) { 13963 ArrayList<Intent> list = stickies.get(intent.getAction()); 13964 if (list != null) { 13965 int N = list.size(); 13966 int i; 13967 for (i=0; i<N; i++) { 13968 if (intent.filterEquals(list.get(i))) { 13969 list.remove(i); 13970 break; 13971 } 13972 } 13973 if (list.size() <= 0) { 13974 stickies.remove(intent.getAction()); 13975 } 13976 } 13977 if (stickies.size() <= 0) { 13978 mStickyBroadcasts.remove(userId); 13979 } 13980 } 13981 } 13982 } 13983 13984 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13985 String resultData, Bundle resultExtras, boolean resultAbort) { 13986 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13987 if (r == null) { 13988 Slog.w(TAG, "finishReceiver called but not found on queue"); 13989 return false; 13990 } 13991 13992 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13993 } 13994 13995 void backgroundServicesFinishedLocked(int userId) { 13996 for (BroadcastQueue queue : mBroadcastQueues) { 13997 queue.backgroundServicesFinishedLocked(userId); 13998 } 13999 } 14000 14001 public void finishReceiver(IBinder who, int resultCode, String resultData, 14002 Bundle resultExtras, boolean resultAbort) { 14003 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14004 14005 // Refuse possible leaked file descriptors 14006 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14007 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14008 } 14009 14010 final long origId = Binder.clearCallingIdentity(); 14011 try { 14012 boolean doNext = false; 14013 BroadcastRecord r; 14014 14015 synchronized(this) { 14016 r = broadcastRecordForReceiverLocked(who); 14017 if (r != null) { 14018 doNext = r.queue.finishReceiverLocked(r, resultCode, 14019 resultData, resultExtras, resultAbort, true); 14020 } 14021 } 14022 14023 if (doNext) { 14024 r.queue.processNextBroadcast(false); 14025 } 14026 trimApplications(); 14027 } finally { 14028 Binder.restoreCallingIdentity(origId); 14029 } 14030 } 14031 14032 // ========================================================= 14033 // INSTRUMENTATION 14034 // ========================================================= 14035 14036 public boolean startInstrumentation(ComponentName className, 14037 String profileFile, int flags, Bundle arguments, 14038 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14039 int userId) { 14040 enforceNotIsolatedCaller("startInstrumentation"); 14041 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14042 userId, false, true, "startInstrumentation", null); 14043 // Refuse possible leaked file descriptors 14044 if (arguments != null && arguments.hasFileDescriptors()) { 14045 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14046 } 14047 14048 synchronized(this) { 14049 InstrumentationInfo ii = null; 14050 ApplicationInfo ai = null; 14051 try { 14052 ii = mContext.getPackageManager().getInstrumentationInfo( 14053 className, STOCK_PM_FLAGS); 14054 ai = AppGlobals.getPackageManager().getApplicationInfo( 14055 ii.targetPackage, STOCK_PM_FLAGS, userId); 14056 } catch (PackageManager.NameNotFoundException e) { 14057 } catch (RemoteException e) { 14058 } 14059 if (ii == null) { 14060 reportStartInstrumentationFailure(watcher, className, 14061 "Unable to find instrumentation info for: " + className); 14062 return false; 14063 } 14064 if (ai == null) { 14065 reportStartInstrumentationFailure(watcher, className, 14066 "Unable to find instrumentation target package: " + ii.targetPackage); 14067 return false; 14068 } 14069 14070 int match = mContext.getPackageManager().checkSignatures( 14071 ii.targetPackage, ii.packageName); 14072 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14073 String msg = "Permission Denial: starting instrumentation " 14074 + className + " from pid=" 14075 + Binder.getCallingPid() 14076 + ", uid=" + Binder.getCallingPid() 14077 + " not allowed because package " + ii.packageName 14078 + " does not have a signature matching the target " 14079 + ii.targetPackage; 14080 reportStartInstrumentationFailure(watcher, className, msg); 14081 throw new SecurityException(msg); 14082 } 14083 14084 final long origId = Binder.clearCallingIdentity(); 14085 // Instrumentation can kill and relaunch even persistent processes 14086 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14087 "start instr"); 14088 ProcessRecord app = addAppLocked(ai, false); 14089 app.instrumentationClass = className; 14090 app.instrumentationInfo = ai; 14091 app.instrumentationProfileFile = profileFile; 14092 app.instrumentationArguments = arguments; 14093 app.instrumentationWatcher = watcher; 14094 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14095 app.instrumentationResultClass = className; 14096 Binder.restoreCallingIdentity(origId); 14097 } 14098 14099 return true; 14100 } 14101 14102 /** 14103 * Report errors that occur while attempting to start Instrumentation. Always writes the 14104 * error to the logs, but if somebody is watching, send the report there too. This enables 14105 * the "am" command to report errors with more information. 14106 * 14107 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14108 * @param cn The component name of the instrumentation. 14109 * @param report The error report. 14110 */ 14111 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14112 ComponentName cn, String report) { 14113 Slog.w(TAG, report); 14114 try { 14115 if (watcher != null) { 14116 Bundle results = new Bundle(); 14117 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14118 results.putString("Error", report); 14119 watcher.instrumentationStatus(cn, -1, results); 14120 } 14121 } catch (RemoteException e) { 14122 Slog.w(TAG, e); 14123 } 14124 } 14125 14126 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14127 if (app.instrumentationWatcher != null) { 14128 try { 14129 // NOTE: IInstrumentationWatcher *must* be oneway here 14130 app.instrumentationWatcher.instrumentationFinished( 14131 app.instrumentationClass, 14132 resultCode, 14133 results); 14134 } catch (RemoteException e) { 14135 } 14136 } 14137 if (app.instrumentationUiAutomationConnection != null) { 14138 try { 14139 app.instrumentationUiAutomationConnection.shutdown(); 14140 } catch (RemoteException re) { 14141 /* ignore */ 14142 } 14143 // Only a UiAutomation can set this flag and now that 14144 // it is finished we make sure it is reset to its default. 14145 mUserIsMonkey = false; 14146 } 14147 app.instrumentationWatcher = null; 14148 app.instrumentationUiAutomationConnection = null; 14149 app.instrumentationClass = null; 14150 app.instrumentationInfo = null; 14151 app.instrumentationProfileFile = null; 14152 app.instrumentationArguments = null; 14153 14154 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14155 "finished inst"); 14156 } 14157 14158 public void finishInstrumentation(IApplicationThread target, 14159 int resultCode, Bundle results) { 14160 int userId = UserHandle.getCallingUserId(); 14161 // Refuse possible leaked file descriptors 14162 if (results != null && results.hasFileDescriptors()) { 14163 throw new IllegalArgumentException("File descriptors passed in Intent"); 14164 } 14165 14166 synchronized(this) { 14167 ProcessRecord app = getRecordForAppLocked(target); 14168 if (app == null) { 14169 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14170 return; 14171 } 14172 final long origId = Binder.clearCallingIdentity(); 14173 finishInstrumentationLocked(app, resultCode, results); 14174 Binder.restoreCallingIdentity(origId); 14175 } 14176 } 14177 14178 // ========================================================= 14179 // CONFIGURATION 14180 // ========================================================= 14181 14182 public ConfigurationInfo getDeviceConfigurationInfo() { 14183 ConfigurationInfo config = new ConfigurationInfo(); 14184 synchronized (this) { 14185 config.reqTouchScreen = mConfiguration.touchscreen; 14186 config.reqKeyboardType = mConfiguration.keyboard; 14187 config.reqNavigation = mConfiguration.navigation; 14188 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14189 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14190 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14191 } 14192 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14193 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14194 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14195 } 14196 config.reqGlEsVersion = GL_ES_VERSION; 14197 } 14198 return config; 14199 } 14200 14201 ActivityStack getFocusedStack() { 14202 return mStackSupervisor.getFocusedStack(); 14203 } 14204 14205 public Configuration getConfiguration() { 14206 Configuration ci; 14207 synchronized(this) { 14208 ci = new Configuration(mConfiguration); 14209 } 14210 return ci; 14211 } 14212 14213 public void updatePersistentConfiguration(Configuration values) { 14214 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14215 "updateConfiguration()"); 14216 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14217 "updateConfiguration()"); 14218 if (values == null) { 14219 throw new NullPointerException("Configuration must not be null"); 14220 } 14221 14222 synchronized(this) { 14223 final long origId = Binder.clearCallingIdentity(); 14224 updateConfigurationLocked(values, null, true, false); 14225 Binder.restoreCallingIdentity(origId); 14226 } 14227 } 14228 14229 public void updateConfiguration(Configuration values) { 14230 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14231 "updateConfiguration()"); 14232 14233 synchronized(this) { 14234 if (values == null && mWindowManager != null) { 14235 // sentinel: fetch the current configuration from the window manager 14236 values = mWindowManager.computeNewConfiguration(); 14237 } 14238 14239 if (mWindowManager != null) { 14240 mProcessList.applyDisplaySize(mWindowManager); 14241 } 14242 14243 final long origId = Binder.clearCallingIdentity(); 14244 if (values != null) { 14245 Settings.System.clearConfiguration(values); 14246 } 14247 updateConfigurationLocked(values, null, false, false); 14248 Binder.restoreCallingIdentity(origId); 14249 } 14250 } 14251 14252 /** 14253 * Do either or both things: (1) change the current configuration, and (2) 14254 * make sure the given activity is running with the (now) current 14255 * configuration. Returns true if the activity has been left running, or 14256 * false if <var>starting</var> is being destroyed to match the new 14257 * configuration. 14258 * @param persistent TODO 14259 */ 14260 boolean updateConfigurationLocked(Configuration values, 14261 ActivityRecord starting, boolean persistent, boolean initLocale) { 14262 int changes = 0; 14263 14264 if (values != null) { 14265 Configuration newConfig = new Configuration(mConfiguration); 14266 changes = newConfig.updateFrom(values); 14267 if (changes != 0) { 14268 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14269 Slog.i(TAG, "Updating configuration to: " + values); 14270 } 14271 14272 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14273 14274 if (values.locale != null && !initLocale) { 14275 saveLocaleLocked(values.locale, 14276 !values.locale.equals(mConfiguration.locale), 14277 values.userSetLocale); 14278 } 14279 14280 mConfigurationSeq++; 14281 if (mConfigurationSeq <= 0) { 14282 mConfigurationSeq = 1; 14283 } 14284 newConfig.seq = mConfigurationSeq; 14285 mConfiguration = newConfig; 14286 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14287 14288 final Configuration configCopy = new Configuration(mConfiguration); 14289 14290 // TODO: If our config changes, should we auto dismiss any currently 14291 // showing dialogs? 14292 mShowDialogs = shouldShowDialogs(newConfig); 14293 14294 AttributeCache ac = AttributeCache.instance(); 14295 if (ac != null) { 14296 ac.updateConfiguration(configCopy); 14297 } 14298 14299 // Make sure all resources in our process are updated 14300 // right now, so that anyone who is going to retrieve 14301 // resource values after we return will be sure to get 14302 // the new ones. This is especially important during 14303 // boot, where the first config change needs to guarantee 14304 // all resources have that config before following boot 14305 // code is executed. 14306 mSystemThread.applyConfigurationToResources(configCopy); 14307 14308 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14309 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14310 msg.obj = new Configuration(configCopy); 14311 mHandler.sendMessage(msg); 14312 } 14313 14314 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14315 ProcessRecord app = mLruProcesses.get(i); 14316 try { 14317 if (app.thread != null) { 14318 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14319 + app.processName + " new config " + mConfiguration); 14320 app.thread.scheduleConfigurationChanged(configCopy); 14321 } 14322 } catch (Exception e) { 14323 } 14324 } 14325 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14326 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14327 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14328 | Intent.FLAG_RECEIVER_FOREGROUND); 14329 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14330 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14331 Process.SYSTEM_UID, UserHandle.USER_ALL); 14332 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14333 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14334 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14335 broadcastIntentLocked(null, null, intent, 14336 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14337 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14338 } 14339 } 14340 } 14341 14342 boolean kept = true; 14343 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14344 // mainStack is null during startup. 14345 if (mainStack != null) { 14346 if (changes != 0 && starting == null) { 14347 // If the configuration changed, and the caller is not already 14348 // in the process of starting an activity, then find the top 14349 // activity to check if its configuration needs to change. 14350 starting = mainStack.topRunningActivityLocked(null); 14351 } 14352 14353 if (starting != null) { 14354 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14355 // And we need to make sure at this point that all other activities 14356 // are made visible with the correct configuration. 14357 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14358 } 14359 } 14360 14361 if (values != null && mWindowManager != null) { 14362 mWindowManager.setNewConfiguration(mConfiguration); 14363 } 14364 14365 return kept; 14366 } 14367 14368 /** 14369 * Decide based on the configuration whether we should shouw the ANR, 14370 * crash, etc dialogs. The idea is that if there is no affordnace to 14371 * press the on-screen buttons, we shouldn't show the dialog. 14372 * 14373 * A thought: SystemUI might also want to get told about this, the Power 14374 * dialog / global actions also might want different behaviors. 14375 */ 14376 private static final boolean shouldShowDialogs(Configuration config) { 14377 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14378 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14379 } 14380 14381 /** 14382 * Save the locale. You must be inside a synchronized (this) block. 14383 */ 14384 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14385 if(isDiff) { 14386 SystemProperties.set("user.language", l.getLanguage()); 14387 SystemProperties.set("user.region", l.getCountry()); 14388 } 14389 14390 if(isPersist) { 14391 SystemProperties.set("persist.sys.language", l.getLanguage()); 14392 SystemProperties.set("persist.sys.country", l.getCountry()); 14393 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14394 } 14395 } 14396 14397 @Override 14398 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14399 ActivityRecord srec = ActivityRecord.forToken(token); 14400 return srec != null && srec.task.affinity != null && 14401 srec.task.affinity.equals(destAffinity); 14402 } 14403 14404 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14405 Intent resultData) { 14406 14407 synchronized (this) { 14408 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14409 if (stack != null) { 14410 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14411 } 14412 return false; 14413 } 14414 } 14415 14416 public int getLaunchedFromUid(IBinder activityToken) { 14417 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14418 if (srec == null) { 14419 return -1; 14420 } 14421 return srec.launchedFromUid; 14422 } 14423 14424 public String getLaunchedFromPackage(IBinder activityToken) { 14425 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14426 if (srec == null) { 14427 return null; 14428 } 14429 return srec.launchedFromPackage; 14430 } 14431 14432 // ========================================================= 14433 // LIFETIME MANAGEMENT 14434 // ========================================================= 14435 14436 // Returns which broadcast queue the app is the current [or imminent] receiver 14437 // on, or 'null' if the app is not an active broadcast recipient. 14438 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14439 BroadcastRecord r = app.curReceiver; 14440 if (r != null) { 14441 return r.queue; 14442 } 14443 14444 // It's not the current receiver, but it might be starting up to become one 14445 synchronized (this) { 14446 for (BroadcastQueue queue : mBroadcastQueues) { 14447 r = queue.mPendingBroadcast; 14448 if (r != null && r.curApp == app) { 14449 // found it; report which queue it's in 14450 return queue; 14451 } 14452 } 14453 } 14454 14455 return null; 14456 } 14457 14458 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14459 boolean doingAll, long now) { 14460 if (mAdjSeq == app.adjSeq) { 14461 // This adjustment has already been computed. 14462 return app.curRawAdj; 14463 } 14464 14465 if (app.thread == null) { 14466 app.adjSeq = mAdjSeq; 14467 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14468 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14469 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14470 } 14471 14472 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14473 app.adjSource = null; 14474 app.adjTarget = null; 14475 app.empty = false; 14476 app.cached = false; 14477 14478 final int activitiesSize = app.activities.size(); 14479 14480 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14481 // The max adjustment doesn't allow this app to be anything 14482 // below foreground, so it is not worth doing work for it. 14483 app.adjType = "fixed"; 14484 app.adjSeq = mAdjSeq; 14485 app.curRawAdj = app.maxAdj; 14486 app.foregroundActivities = false; 14487 app.keeping = true; 14488 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14489 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14490 // System process can do UI, and when they do we want to have 14491 // them trim their memory after the user leaves the UI. To 14492 // facilitate this, here we need to determine whether or not it 14493 // is currently showing UI. 14494 app.systemNoUi = true; 14495 if (app == TOP_APP) { 14496 app.systemNoUi = false; 14497 } else if (activitiesSize > 0) { 14498 for (int j = 0; j < activitiesSize; j++) { 14499 final ActivityRecord r = app.activities.get(j); 14500 if (r.visible) { 14501 app.systemNoUi = false; 14502 } 14503 } 14504 } 14505 if (!app.systemNoUi) { 14506 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14507 } 14508 return (app.curAdj=app.maxAdj); 14509 } 14510 14511 app.keeping = false; 14512 app.systemNoUi = false; 14513 14514 // Determine the importance of the process, starting with most 14515 // important to least, and assign an appropriate OOM adjustment. 14516 int adj; 14517 int schedGroup; 14518 int procState; 14519 boolean foregroundActivities = false; 14520 boolean interesting = false; 14521 BroadcastQueue queue; 14522 if (app == TOP_APP) { 14523 // The last app on the list is the foreground app. 14524 adj = ProcessList.FOREGROUND_APP_ADJ; 14525 schedGroup = Process.THREAD_GROUP_DEFAULT; 14526 app.adjType = "top-activity"; 14527 foregroundActivities = true; 14528 interesting = true; 14529 procState = ActivityManager.PROCESS_STATE_TOP; 14530 } else if (app.instrumentationClass != null) { 14531 // Don't want to kill running instrumentation. 14532 adj = ProcessList.FOREGROUND_APP_ADJ; 14533 schedGroup = Process.THREAD_GROUP_DEFAULT; 14534 app.adjType = "instrumentation"; 14535 interesting = true; 14536 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14537 } else if ((queue = isReceivingBroadcast(app)) != null) { 14538 // An app that is currently receiving a broadcast also 14539 // counts as being in the foreground for OOM killer purposes. 14540 // It's placed in a sched group based on the nature of the 14541 // broadcast as reflected by which queue it's active in. 14542 adj = ProcessList.FOREGROUND_APP_ADJ; 14543 schedGroup = (queue == mFgBroadcastQueue) 14544 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14545 app.adjType = "broadcast"; 14546 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14547 } else if (app.executingServices.size() > 0) { 14548 // An app that is currently executing a service callback also 14549 // counts as being in the foreground. 14550 adj = ProcessList.FOREGROUND_APP_ADJ; 14551 schedGroup = app.execServicesFg ? 14552 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14553 app.adjType = "exec-service"; 14554 procState = ActivityManager.PROCESS_STATE_SERVICE; 14555 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14556 } else { 14557 // As far as we know the process is empty. We may change our mind later. 14558 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14559 // At this point we don't actually know the adjustment. Use the cached adj 14560 // value that the caller wants us to. 14561 adj = cachedAdj; 14562 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14563 app.cached = true; 14564 app.empty = true; 14565 app.adjType = "cch-empty"; 14566 } 14567 14568 // Examine all activities if not already foreground. 14569 if (!foregroundActivities && activitiesSize > 0) { 14570 for (int j = 0; j < activitiesSize; j++) { 14571 final ActivityRecord r = app.activities.get(j); 14572 if (r.app != app) { 14573 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14574 + app + "?!?"); 14575 continue; 14576 } 14577 if (r.visible) { 14578 // App has a visible activity; only upgrade adjustment. 14579 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14580 adj = ProcessList.VISIBLE_APP_ADJ; 14581 app.adjType = "visible"; 14582 } 14583 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14584 procState = ActivityManager.PROCESS_STATE_TOP; 14585 } 14586 schedGroup = Process.THREAD_GROUP_DEFAULT; 14587 app.cached = false; 14588 app.empty = false; 14589 foregroundActivities = true; 14590 break; 14591 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14592 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14593 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14594 app.adjType = "pausing"; 14595 } 14596 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14597 procState = ActivityManager.PROCESS_STATE_TOP; 14598 } 14599 schedGroup = Process.THREAD_GROUP_DEFAULT; 14600 app.cached = false; 14601 app.empty = false; 14602 foregroundActivities = true; 14603 } else if (r.state == ActivityState.STOPPING) { 14604 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14605 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14606 app.adjType = "stopping"; 14607 } 14608 // For the process state, we will at this point consider the 14609 // process to be cached. It will be cached either as an activity 14610 // or empty depending on whether the activity is finishing. We do 14611 // this so that we can treat the process as cached for purposes of 14612 // memory trimming (determing current memory level, trim command to 14613 // send to process) since there can be an arbitrary number of stopping 14614 // processes and they should soon all go into the cached state. 14615 if (!r.finishing) { 14616 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14617 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14618 } 14619 } 14620 app.cached = false; 14621 app.empty = false; 14622 foregroundActivities = true; 14623 } else { 14624 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14625 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14626 app.adjType = "cch-act"; 14627 } 14628 } 14629 } 14630 } 14631 14632 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14633 if (app.foregroundServices) { 14634 // The user is aware of this app, so make it visible. 14635 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14636 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14637 app.cached = false; 14638 app.adjType = "fg-service"; 14639 schedGroup = Process.THREAD_GROUP_DEFAULT; 14640 } else if (app.forcingToForeground != null) { 14641 // The user is aware of this app, so make it visible. 14642 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14643 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14644 app.cached = false; 14645 app.adjType = "force-fg"; 14646 app.adjSource = app.forcingToForeground; 14647 schedGroup = Process.THREAD_GROUP_DEFAULT; 14648 } 14649 } 14650 14651 if (app.foregroundServices) { 14652 interesting = true; 14653 } 14654 14655 if (app == mHeavyWeightProcess) { 14656 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14657 // We don't want to kill the current heavy-weight process. 14658 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14659 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14660 app.cached = false; 14661 app.adjType = "heavy"; 14662 } 14663 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14664 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14665 } 14666 } 14667 14668 if (app == mHomeProcess) { 14669 if (adj > ProcessList.HOME_APP_ADJ) { 14670 // This process is hosting what we currently consider to be the 14671 // home app, so we don't want to let it go into the background. 14672 adj = ProcessList.HOME_APP_ADJ; 14673 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14674 app.cached = false; 14675 app.adjType = "home"; 14676 } 14677 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14678 procState = ActivityManager.PROCESS_STATE_HOME; 14679 } 14680 } 14681 14682 if (app == mPreviousProcess && app.activities.size() > 0) { 14683 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14684 // This was the previous process that showed UI to the user. 14685 // We want to try to keep it around more aggressively, to give 14686 // a good experience around switching between two apps. 14687 adj = ProcessList.PREVIOUS_APP_ADJ; 14688 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14689 app.cached = false; 14690 app.adjType = "previous"; 14691 } 14692 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14693 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14694 } 14695 } 14696 14697 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14698 + " reason=" + app.adjType); 14699 14700 // By default, we use the computed adjustment. It may be changed if 14701 // there are applications dependent on our services or providers, but 14702 // this gives us a baseline and makes sure we don't get into an 14703 // infinite recursion. 14704 app.adjSeq = mAdjSeq; 14705 app.curRawAdj = adj; 14706 app.hasStartedServices = false; 14707 14708 if (mBackupTarget != null && app == mBackupTarget.app) { 14709 // If possible we want to avoid killing apps while they're being backed up 14710 if (adj > ProcessList.BACKUP_APP_ADJ) { 14711 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14712 adj = ProcessList.BACKUP_APP_ADJ; 14713 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14714 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14715 } 14716 app.adjType = "backup"; 14717 app.cached = false; 14718 } 14719 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14720 procState = ActivityManager.PROCESS_STATE_BACKUP; 14721 } 14722 } 14723 14724 boolean mayBeTop = false; 14725 14726 for (int is = app.services.size()-1; 14727 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14728 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14729 || procState > ActivityManager.PROCESS_STATE_TOP); 14730 is--) { 14731 ServiceRecord s = app.services.valueAt(is); 14732 if (s.startRequested) { 14733 app.hasStartedServices = true; 14734 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14735 procState = ActivityManager.PROCESS_STATE_SERVICE; 14736 } 14737 if (app.hasShownUi && app != mHomeProcess) { 14738 // If this process has shown some UI, let it immediately 14739 // go to the LRU list because it may be pretty heavy with 14740 // UI stuff. We'll tag it with a label just to help 14741 // debug and understand what is going on. 14742 if (adj > ProcessList.SERVICE_ADJ) { 14743 app.adjType = "cch-started-ui-services"; 14744 } 14745 } else { 14746 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14747 // This service has seen some activity within 14748 // recent memory, so we will keep its process ahead 14749 // of the background processes. 14750 if (adj > ProcessList.SERVICE_ADJ) { 14751 adj = ProcessList.SERVICE_ADJ; 14752 app.adjType = "started-services"; 14753 app.cached = false; 14754 } 14755 } 14756 // If we have let the service slide into the background 14757 // state, still have some text describing what it is doing 14758 // even though the service no longer has an impact. 14759 if (adj > ProcessList.SERVICE_ADJ) { 14760 app.adjType = "cch-started-services"; 14761 } 14762 } 14763 // Don't kill this process because it is doing work; it 14764 // has said it is doing work. 14765 app.keeping = true; 14766 } 14767 for (int conni = s.connections.size()-1; 14768 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14769 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14770 || procState > ActivityManager.PROCESS_STATE_TOP); 14771 conni--) { 14772 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14773 for (int i = 0; 14774 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14775 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14776 || procState > ActivityManager.PROCESS_STATE_TOP); 14777 i++) { 14778 // XXX should compute this based on the max of 14779 // all connected clients. 14780 ConnectionRecord cr = clist.get(i); 14781 if (cr.binding.client == app) { 14782 // Binding to ourself is not interesting. 14783 continue; 14784 } 14785 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14786 ProcessRecord client = cr.binding.client; 14787 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14788 TOP_APP, doingAll, now); 14789 int clientProcState = client.curProcState; 14790 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14791 // If the other app is cached for any reason, for purposes here 14792 // we are going to consider it empty. The specific cached state 14793 // doesn't propagate except under certain conditions. 14794 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14795 } 14796 String adjType = null; 14797 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14798 // Not doing bind OOM management, so treat 14799 // this guy more like a started service. 14800 if (app.hasShownUi && app != mHomeProcess) { 14801 // If this process has shown some UI, let it immediately 14802 // go to the LRU list because it may be pretty heavy with 14803 // UI stuff. We'll tag it with a label just to help 14804 // debug and understand what is going on. 14805 if (adj > clientAdj) { 14806 adjType = "cch-bound-ui-services"; 14807 } 14808 app.cached = false; 14809 clientAdj = adj; 14810 clientProcState = procState; 14811 } else { 14812 if (now >= (s.lastActivity 14813 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14814 // This service has not seen activity within 14815 // recent memory, so allow it to drop to the 14816 // LRU list if there is no other reason to keep 14817 // it around. We'll also tag it with a label just 14818 // to help debug and undertand what is going on. 14819 if (adj > clientAdj) { 14820 adjType = "cch-bound-services"; 14821 } 14822 clientAdj = adj; 14823 } 14824 } 14825 } 14826 if (adj > clientAdj) { 14827 // If this process has recently shown UI, and 14828 // the process that is binding to it is less 14829 // important than being visible, then we don't 14830 // care about the binding as much as we care 14831 // about letting this process get into the LRU 14832 // list to be killed and restarted if needed for 14833 // memory. 14834 if (app.hasShownUi && app != mHomeProcess 14835 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14836 adjType = "cch-bound-ui-services"; 14837 } else { 14838 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14839 |Context.BIND_IMPORTANT)) != 0) { 14840 adj = clientAdj; 14841 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14842 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14843 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14844 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14845 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14846 adj = clientAdj; 14847 } else { 14848 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14849 adj = ProcessList.VISIBLE_APP_ADJ; 14850 } 14851 } 14852 if (!client.cached) { 14853 app.cached = false; 14854 } 14855 if (client.keeping) { 14856 app.keeping = true; 14857 } 14858 adjType = "service"; 14859 } 14860 } 14861 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14862 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14863 schedGroup = Process.THREAD_GROUP_DEFAULT; 14864 } 14865 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14866 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14867 // Special handling of clients who are in the top state. 14868 // We *may* want to consider this process to be in the 14869 // top state as well, but only if there is not another 14870 // reason for it to be running. Being on the top is a 14871 // special state, meaning you are specifically running 14872 // for the current top app. If the process is already 14873 // running in the background for some other reason, it 14874 // is more important to continue considering it to be 14875 // in the background state. 14876 mayBeTop = true; 14877 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14878 } else { 14879 // Special handling for above-top states (persistent 14880 // processes). These should not bring the current process 14881 // into the top state, since they are not on top. Instead 14882 // give them the best state after that. 14883 clientProcState = 14884 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14885 } 14886 } 14887 } else { 14888 if (clientProcState < 14889 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14890 clientProcState = 14891 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14892 } 14893 } 14894 if (procState > clientProcState) { 14895 procState = clientProcState; 14896 } 14897 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14898 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14899 app.pendingUiClean = true; 14900 } 14901 if (adjType != null) { 14902 app.adjType = adjType; 14903 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14904 .REASON_SERVICE_IN_USE; 14905 app.adjSource = cr.binding.client; 14906 app.adjSourceOom = clientAdj; 14907 app.adjTarget = s.name; 14908 } 14909 } 14910 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 14911 app.treatLikeActivity = true; 14912 } 14913 final ActivityRecord a = cr.activity; 14914 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14915 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14916 (a.visible || a.state == ActivityState.RESUMED 14917 || a.state == ActivityState.PAUSING)) { 14918 adj = ProcessList.FOREGROUND_APP_ADJ; 14919 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14920 schedGroup = Process.THREAD_GROUP_DEFAULT; 14921 } 14922 app.cached = false; 14923 app.adjType = "service"; 14924 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14925 .REASON_SERVICE_IN_USE; 14926 app.adjSource = a; 14927 app.adjSourceOom = adj; 14928 app.adjTarget = s.name; 14929 } 14930 } 14931 } 14932 } 14933 } 14934 14935 for (int provi = app.pubProviders.size()-1; 14936 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14937 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14938 || procState > ActivityManager.PROCESS_STATE_TOP); 14939 provi--) { 14940 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14941 for (int i = cpr.connections.size()-1; 14942 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14943 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14944 || procState > ActivityManager.PROCESS_STATE_TOP); 14945 i--) { 14946 ContentProviderConnection conn = cpr.connections.get(i); 14947 ProcessRecord client = conn.client; 14948 if (client == app) { 14949 // Being our own client is not interesting. 14950 continue; 14951 } 14952 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14953 int clientProcState = client.curProcState; 14954 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14955 // If the other app is cached for any reason, for purposes here 14956 // we are going to consider it empty. 14957 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14958 } 14959 if (adj > clientAdj) { 14960 if (app.hasShownUi && app != mHomeProcess 14961 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14962 app.adjType = "cch-ui-provider"; 14963 } else { 14964 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14965 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14966 app.adjType = "provider"; 14967 } 14968 app.cached &= client.cached; 14969 app.keeping |= client.keeping; 14970 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14971 .REASON_PROVIDER_IN_USE; 14972 app.adjSource = client; 14973 app.adjSourceOom = clientAdj; 14974 app.adjTarget = cpr.name; 14975 } 14976 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14977 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14978 // Special handling of clients who are in the top state. 14979 // We *may* want to consider this process to be in the 14980 // top state as well, but only if there is not another 14981 // reason for it to be running. Being on the top is a 14982 // special state, meaning you are specifically running 14983 // for the current top app. If the process is already 14984 // running in the background for some other reason, it 14985 // is more important to continue considering it to be 14986 // in the background state. 14987 mayBeTop = true; 14988 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14989 } else { 14990 // Special handling for above-top states (persistent 14991 // processes). These should not bring the current process 14992 // into the top state, since they are not on top. Instead 14993 // give them the best state after that. 14994 clientProcState = 14995 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14996 } 14997 } 14998 if (procState > clientProcState) { 14999 procState = clientProcState; 15000 } 15001 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15002 schedGroup = Process.THREAD_GROUP_DEFAULT; 15003 } 15004 } 15005 // If the provider has external (non-framework) process 15006 // dependencies, ensure that its adjustment is at least 15007 // FOREGROUND_APP_ADJ. 15008 if (cpr.hasExternalProcessHandles()) { 15009 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15010 adj = ProcessList.FOREGROUND_APP_ADJ; 15011 schedGroup = Process.THREAD_GROUP_DEFAULT; 15012 app.cached = false; 15013 app.keeping = true; 15014 app.adjType = "provider"; 15015 app.adjTarget = cpr.name; 15016 } 15017 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15018 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15019 } 15020 } 15021 } 15022 15023 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15024 // A client of one of our services or providers is in the top state. We 15025 // *may* want to be in the top state, but not if we are already running in 15026 // the background for some other reason. For the decision here, we are going 15027 // to pick out a few specific states that we want to remain in when a client 15028 // is top (states that tend to be longer-term) and otherwise allow it to go 15029 // to the top state. 15030 switch (procState) { 15031 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15032 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15033 case ActivityManager.PROCESS_STATE_SERVICE: 15034 // These all are longer-term states, so pull them up to the top 15035 // of the background states, but not all the way to the top state. 15036 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15037 break; 15038 default: 15039 // Otherwise, top is a better choice, so take it. 15040 procState = ActivityManager.PROCESS_STATE_TOP; 15041 break; 15042 } 15043 } 15044 15045 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15046 if (app.hasClientActivities) { 15047 // This is a cached process, but with client activities. Mark it so. 15048 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15049 app.adjType = "cch-client-act"; 15050 } else if (app.treatLikeActivity) { 15051 // This is a cached process, but somebody wants us to treat it like it has 15052 // an activity, okay! 15053 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15054 app.adjType = "cch-as-act"; 15055 } 15056 } 15057 15058 if (adj == ProcessList.SERVICE_ADJ) { 15059 if (doingAll) { 15060 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15061 mNewNumServiceProcs++; 15062 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15063 if (!app.serviceb) { 15064 // This service isn't far enough down on the LRU list to 15065 // normally be a B service, but if we are low on RAM and it 15066 // is large we want to force it down since we would prefer to 15067 // keep launcher over it. 15068 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15069 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15070 app.serviceHighRam = true; 15071 app.serviceb = true; 15072 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15073 } else { 15074 mNewNumAServiceProcs++; 15075 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15076 } 15077 } else { 15078 app.serviceHighRam = false; 15079 } 15080 } 15081 if (app.serviceb) { 15082 adj = ProcessList.SERVICE_B_ADJ; 15083 } 15084 } 15085 15086 app.curRawAdj = adj; 15087 15088 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15089 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15090 if (adj > app.maxAdj) { 15091 adj = app.maxAdj; 15092 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15093 schedGroup = Process.THREAD_GROUP_DEFAULT; 15094 } 15095 } 15096 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15097 app.keeping = true; 15098 } 15099 15100 // Do final modification to adj. Everything we do between here and applying 15101 // the final setAdj must be done in this function, because we will also use 15102 // it when computing the final cached adj later. Note that we don't need to 15103 // worry about this for max adj above, since max adj will always be used to 15104 // keep it out of the cached vaues. 15105 adj = app.modifyRawOomAdj(adj); 15106 15107 app.curProcState = procState; 15108 15109 int importance = app.memImportance; 15110 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15111 app.curAdj = adj; 15112 app.curSchedGroup = schedGroup; 15113 if (!interesting) { 15114 // For this reporting, if there is not something explicitly 15115 // interesting in this process then we will push it to the 15116 // background importance. 15117 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15118 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15119 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15120 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15121 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15122 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15123 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15124 } else if (adj >= ProcessList.SERVICE_ADJ) { 15125 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15126 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15127 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15128 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15129 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15130 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15131 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15132 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15133 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15134 } else { 15135 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15136 } 15137 } 15138 15139 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15140 if (foregroundActivities != app.foregroundActivities) { 15141 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15142 } 15143 if (changes != 0) { 15144 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15145 app.memImportance = importance; 15146 app.foregroundActivities = foregroundActivities; 15147 int i = mPendingProcessChanges.size()-1; 15148 ProcessChangeItem item = null; 15149 while (i >= 0) { 15150 item = mPendingProcessChanges.get(i); 15151 if (item.pid == app.pid) { 15152 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15153 break; 15154 } 15155 i--; 15156 } 15157 if (i < 0) { 15158 // No existing item in pending changes; need a new one. 15159 final int NA = mAvailProcessChanges.size(); 15160 if (NA > 0) { 15161 item = mAvailProcessChanges.remove(NA-1); 15162 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15163 } else { 15164 item = new ProcessChangeItem(); 15165 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15166 } 15167 item.changes = 0; 15168 item.pid = app.pid; 15169 item.uid = app.info.uid; 15170 if (mPendingProcessChanges.size() == 0) { 15171 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15172 "*** Enqueueing dispatch processes changed!"); 15173 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15174 } 15175 mPendingProcessChanges.add(item); 15176 } 15177 item.changes |= changes; 15178 item.importance = importance; 15179 item.foregroundActivities = foregroundActivities; 15180 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15181 + Integer.toHexString(System.identityHashCode(item)) 15182 + " " + app.toShortString() + ": changes=" + item.changes 15183 + " importance=" + item.importance 15184 + " foreground=" + item.foregroundActivities 15185 + " type=" + app.adjType + " source=" + app.adjSource 15186 + " target=" + app.adjTarget); 15187 } 15188 15189 return app.curRawAdj; 15190 } 15191 15192 /** 15193 * Schedule PSS collection of a process. 15194 */ 15195 void requestPssLocked(ProcessRecord proc, int procState) { 15196 if (mPendingPssProcesses.contains(proc)) { 15197 return; 15198 } 15199 if (mPendingPssProcesses.size() == 0) { 15200 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15201 } 15202 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15203 proc.pssProcState = procState; 15204 mPendingPssProcesses.add(proc); 15205 } 15206 15207 /** 15208 * Schedule PSS collection of all processes. 15209 */ 15210 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15211 if (!always) { 15212 if (now < (mLastFullPssTime + 15213 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15214 return; 15215 } 15216 } 15217 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15218 mLastFullPssTime = now; 15219 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15220 mPendingPssProcesses.clear(); 15221 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15222 ProcessRecord app = mLruProcesses.get(i); 15223 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15224 app.pssProcState = app.setProcState; 15225 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15226 mSleeping, now); 15227 mPendingPssProcesses.add(app); 15228 } 15229 } 15230 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15231 } 15232 15233 /** 15234 * Ask a given process to GC right now. 15235 */ 15236 final void performAppGcLocked(ProcessRecord app) { 15237 try { 15238 app.lastRequestedGc = SystemClock.uptimeMillis(); 15239 if (app.thread != null) { 15240 if (app.reportLowMemory) { 15241 app.reportLowMemory = false; 15242 app.thread.scheduleLowMemory(); 15243 } else { 15244 app.thread.processInBackground(); 15245 } 15246 } 15247 } catch (Exception e) { 15248 // whatever. 15249 } 15250 } 15251 15252 /** 15253 * Returns true if things are idle enough to perform GCs. 15254 */ 15255 private final boolean canGcNowLocked() { 15256 boolean processingBroadcasts = false; 15257 for (BroadcastQueue q : mBroadcastQueues) { 15258 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15259 processingBroadcasts = true; 15260 } 15261 } 15262 return !processingBroadcasts 15263 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15264 } 15265 15266 /** 15267 * Perform GCs on all processes that are waiting for it, but only 15268 * if things are idle. 15269 */ 15270 final void performAppGcsLocked() { 15271 final int N = mProcessesToGc.size(); 15272 if (N <= 0) { 15273 return; 15274 } 15275 if (canGcNowLocked()) { 15276 while (mProcessesToGc.size() > 0) { 15277 ProcessRecord proc = mProcessesToGc.remove(0); 15278 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15279 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15280 <= SystemClock.uptimeMillis()) { 15281 // To avoid spamming the system, we will GC processes one 15282 // at a time, waiting a few seconds between each. 15283 performAppGcLocked(proc); 15284 scheduleAppGcsLocked(); 15285 return; 15286 } else { 15287 // It hasn't been long enough since we last GCed this 15288 // process... put it in the list to wait for its time. 15289 addProcessToGcListLocked(proc); 15290 break; 15291 } 15292 } 15293 } 15294 15295 scheduleAppGcsLocked(); 15296 } 15297 } 15298 15299 /** 15300 * If all looks good, perform GCs on all processes waiting for them. 15301 */ 15302 final void performAppGcsIfAppropriateLocked() { 15303 if (canGcNowLocked()) { 15304 performAppGcsLocked(); 15305 return; 15306 } 15307 // Still not idle, wait some more. 15308 scheduleAppGcsLocked(); 15309 } 15310 15311 /** 15312 * Schedule the execution of all pending app GCs. 15313 */ 15314 final void scheduleAppGcsLocked() { 15315 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15316 15317 if (mProcessesToGc.size() > 0) { 15318 // Schedule a GC for the time to the next process. 15319 ProcessRecord proc = mProcessesToGc.get(0); 15320 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15321 15322 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15323 long now = SystemClock.uptimeMillis(); 15324 if (when < (now+GC_TIMEOUT)) { 15325 when = now + GC_TIMEOUT; 15326 } 15327 mHandler.sendMessageAtTime(msg, when); 15328 } 15329 } 15330 15331 /** 15332 * Add a process to the array of processes waiting to be GCed. Keeps the 15333 * list in sorted order by the last GC time. The process can't already be 15334 * on the list. 15335 */ 15336 final void addProcessToGcListLocked(ProcessRecord proc) { 15337 boolean added = false; 15338 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15339 if (mProcessesToGc.get(i).lastRequestedGc < 15340 proc.lastRequestedGc) { 15341 added = true; 15342 mProcessesToGc.add(i+1, proc); 15343 break; 15344 } 15345 } 15346 if (!added) { 15347 mProcessesToGc.add(0, proc); 15348 } 15349 } 15350 15351 /** 15352 * Set up to ask a process to GC itself. This will either do it 15353 * immediately, or put it on the list of processes to gc the next 15354 * time things are idle. 15355 */ 15356 final void scheduleAppGcLocked(ProcessRecord app) { 15357 long now = SystemClock.uptimeMillis(); 15358 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15359 return; 15360 } 15361 if (!mProcessesToGc.contains(app)) { 15362 addProcessToGcListLocked(app); 15363 scheduleAppGcsLocked(); 15364 } 15365 } 15366 15367 final void checkExcessivePowerUsageLocked(boolean doKills) { 15368 updateCpuStatsNow(); 15369 15370 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15371 boolean doWakeKills = doKills; 15372 boolean doCpuKills = doKills; 15373 if (mLastPowerCheckRealtime == 0) { 15374 doWakeKills = false; 15375 } 15376 if (mLastPowerCheckUptime == 0) { 15377 doCpuKills = false; 15378 } 15379 if (stats.isScreenOn()) { 15380 doWakeKills = false; 15381 } 15382 final long curRealtime = SystemClock.elapsedRealtime(); 15383 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15384 final long curUptime = SystemClock.uptimeMillis(); 15385 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15386 mLastPowerCheckRealtime = curRealtime; 15387 mLastPowerCheckUptime = curUptime; 15388 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15389 doWakeKills = false; 15390 } 15391 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15392 doCpuKills = false; 15393 } 15394 int i = mLruProcesses.size(); 15395 while (i > 0) { 15396 i--; 15397 ProcessRecord app = mLruProcesses.get(i); 15398 if (!app.keeping) { 15399 long wtime; 15400 synchronized (stats) { 15401 wtime = stats.getProcessWakeTime(app.info.uid, 15402 app.pid, curRealtime); 15403 } 15404 long wtimeUsed = wtime - app.lastWakeTime; 15405 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15406 if (DEBUG_POWER) { 15407 StringBuilder sb = new StringBuilder(128); 15408 sb.append("Wake for "); 15409 app.toShortString(sb); 15410 sb.append(": over "); 15411 TimeUtils.formatDuration(realtimeSince, sb); 15412 sb.append(" used "); 15413 TimeUtils.formatDuration(wtimeUsed, sb); 15414 sb.append(" ("); 15415 sb.append((wtimeUsed*100)/realtimeSince); 15416 sb.append("%)"); 15417 Slog.i(TAG, sb.toString()); 15418 sb.setLength(0); 15419 sb.append("CPU for "); 15420 app.toShortString(sb); 15421 sb.append(": over "); 15422 TimeUtils.formatDuration(uptimeSince, sb); 15423 sb.append(" used "); 15424 TimeUtils.formatDuration(cputimeUsed, sb); 15425 sb.append(" ("); 15426 sb.append((cputimeUsed*100)/uptimeSince); 15427 sb.append("%)"); 15428 Slog.i(TAG, sb.toString()); 15429 } 15430 // If a process has held a wake lock for more 15431 // than 50% of the time during this period, 15432 // that sounds bad. Kill! 15433 if (doWakeKills && realtimeSince > 0 15434 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15435 synchronized (stats) { 15436 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15437 realtimeSince, wtimeUsed); 15438 } 15439 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15440 + " during " + realtimeSince); 15441 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15442 } else if (doCpuKills && uptimeSince > 0 15443 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15444 synchronized (stats) { 15445 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15446 uptimeSince, cputimeUsed); 15447 } 15448 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15449 + " during " + uptimeSince); 15450 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15451 } else { 15452 app.lastWakeTime = wtime; 15453 app.lastCpuTime = app.curCpuTime; 15454 } 15455 } 15456 } 15457 } 15458 15459 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15460 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15461 boolean success = true; 15462 15463 if (app.curRawAdj != app.setRawAdj) { 15464 if (wasKeeping && !app.keeping) { 15465 // This app is no longer something we want to keep. Note 15466 // its current wake lock time to later know to kill it if 15467 // it is not behaving well. 15468 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15469 synchronized (stats) { 15470 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15471 app.pid, SystemClock.elapsedRealtime()); 15472 } 15473 app.lastCpuTime = app.curCpuTime; 15474 } 15475 15476 app.setRawAdj = app.curRawAdj; 15477 } 15478 15479 if (app.curAdj != app.setAdj) { 15480 ProcessList.setOomAdj(app.pid, app.curAdj); 15481 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15482 TAG, "Set " + app.pid + " " + app.processName + 15483 " adj " + app.curAdj + ": " + app.adjType); 15484 app.setAdj = app.curAdj; 15485 } 15486 15487 if (app.setSchedGroup != app.curSchedGroup) { 15488 app.setSchedGroup = app.curSchedGroup; 15489 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15490 "Setting process group of " + app.processName 15491 + " to " + app.curSchedGroup); 15492 if (app.waitingToKill != null && 15493 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15494 killUnneededProcessLocked(app, app.waitingToKill); 15495 success = false; 15496 } else { 15497 if (true) { 15498 long oldId = Binder.clearCallingIdentity(); 15499 try { 15500 Process.setProcessGroup(app.pid, app.curSchedGroup); 15501 } catch (Exception e) { 15502 Slog.w(TAG, "Failed setting process group of " + app.pid 15503 + " to " + app.curSchedGroup); 15504 e.printStackTrace(); 15505 } finally { 15506 Binder.restoreCallingIdentity(oldId); 15507 } 15508 } else { 15509 if (app.thread != null) { 15510 try { 15511 app.thread.setSchedulingGroup(app.curSchedGroup); 15512 } catch (RemoteException e) { 15513 } 15514 } 15515 } 15516 Process.setSwappiness(app.pid, 15517 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15518 } 15519 } 15520 if (app.repProcState != app.curProcState) { 15521 app.repProcState = app.curProcState; 15522 if (!reportingProcessState && app.thread != null) { 15523 try { 15524 if (false) { 15525 //RuntimeException h = new RuntimeException("here"); 15526 Slog.i(TAG, "Sending new process state " + app.repProcState 15527 + " to " + app /*, h*/); 15528 } 15529 app.thread.setProcessState(app.repProcState); 15530 } catch (RemoteException e) { 15531 } 15532 } 15533 } 15534 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15535 app.setProcState)) { 15536 app.lastStateTime = now; 15537 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15538 mSleeping, now); 15539 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15540 + ProcessList.makeProcStateString(app.setProcState) + " to " 15541 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15542 + (app.nextPssTime-now) + ": " + app); 15543 } else { 15544 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15545 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15546 requestPssLocked(app, app.setProcState); 15547 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15548 mSleeping, now); 15549 } else if (false && DEBUG_PSS) { 15550 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15551 } 15552 } 15553 if (app.setProcState != app.curProcState) { 15554 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15555 "Proc state change of " + app.processName 15556 + " to " + app.curProcState); 15557 app.setProcState = app.curProcState; 15558 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15559 app.notCachedSinceIdle = false; 15560 } 15561 if (!doingAll) { 15562 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15563 } else { 15564 app.procStateChanged = true; 15565 } 15566 } 15567 return success; 15568 } 15569 15570 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15571 if (proc.thread != null && proc.baseProcessTracker != null) { 15572 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15573 } 15574 } 15575 15576 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15577 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15578 if (app.thread == null) { 15579 return false; 15580 } 15581 15582 final boolean wasKeeping = app.keeping; 15583 15584 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15585 15586 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15587 reportingProcessState, now); 15588 } 15589 15590 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15591 boolean oomAdj) { 15592 if (isForeground != proc.foregroundServices) { 15593 proc.foregroundServices = isForeground; 15594 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15595 proc.info.uid); 15596 if (isForeground) { 15597 if (curProcs == null) { 15598 curProcs = new ArrayList<ProcessRecord>(); 15599 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15600 } 15601 if (!curProcs.contains(proc)) { 15602 curProcs.add(proc); 15603 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15604 proc.info.packageName, proc.info.uid); 15605 } 15606 } else { 15607 if (curProcs != null) { 15608 if (curProcs.remove(proc)) { 15609 mBatteryStatsService.noteEvent( 15610 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15611 proc.info.packageName, proc.info.uid); 15612 if (curProcs.size() <= 0) { 15613 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15614 } 15615 } 15616 } 15617 } 15618 if (oomAdj) { 15619 updateOomAdjLocked(); 15620 } 15621 } 15622 } 15623 15624 private final ActivityRecord resumedAppLocked() { 15625 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15626 String pkg; 15627 int uid; 15628 if (act != null && !act.sleeping) { 15629 pkg = act.packageName; 15630 uid = act.info.applicationInfo.uid; 15631 } else { 15632 pkg = null; 15633 uid = -1; 15634 } 15635 // Has the UID or resumed package name changed? 15636 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15637 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15638 if (mCurResumedPackage != null) { 15639 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15640 mCurResumedPackage, mCurResumedUid); 15641 } 15642 mCurResumedPackage = pkg; 15643 mCurResumedUid = uid; 15644 if (mCurResumedPackage != null) { 15645 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15646 mCurResumedPackage, mCurResumedUid); 15647 } 15648 } 15649 return act; 15650 } 15651 15652 final boolean updateOomAdjLocked(ProcessRecord app) { 15653 return updateOomAdjLocked(app, false); 15654 } 15655 15656 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15657 final ActivityRecord TOP_ACT = resumedAppLocked(); 15658 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15659 final boolean wasCached = app.cached; 15660 15661 mAdjSeq++; 15662 15663 // This is the desired cached adjusment we want to tell it to use. 15664 // If our app is currently cached, we know it, and that is it. Otherwise, 15665 // we don't know it yet, and it needs to now be cached we will then 15666 // need to do a complete oom adj. 15667 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15668 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15669 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15670 SystemClock.uptimeMillis()); 15671 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15672 // Changed to/from cached state, so apps after it in the LRU 15673 // list may also be changed. 15674 updateOomAdjLocked(); 15675 } 15676 return success; 15677 } 15678 15679 final void updateOomAdjLocked() { 15680 final ActivityRecord TOP_ACT = resumedAppLocked(); 15681 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15682 final long now = SystemClock.uptimeMillis(); 15683 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15684 final int N = mLruProcesses.size(); 15685 15686 if (false) { 15687 RuntimeException e = new RuntimeException(); 15688 e.fillInStackTrace(); 15689 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15690 } 15691 15692 mAdjSeq++; 15693 mNewNumServiceProcs = 0; 15694 mNewNumAServiceProcs = 0; 15695 15696 final int emptyProcessLimit; 15697 final int cachedProcessLimit; 15698 if (mProcessLimit <= 0) { 15699 emptyProcessLimit = cachedProcessLimit = 0; 15700 } else if (mProcessLimit == 1) { 15701 emptyProcessLimit = 1; 15702 cachedProcessLimit = 0; 15703 } else { 15704 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15705 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15706 } 15707 15708 // Let's determine how many processes we have running vs. 15709 // how many slots we have for background processes; we may want 15710 // to put multiple processes in a slot of there are enough of 15711 // them. 15712 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15713 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15714 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15715 if (numEmptyProcs > cachedProcessLimit) { 15716 // If there are more empty processes than our limit on cached 15717 // processes, then use the cached process limit for the factor. 15718 // This ensures that the really old empty processes get pushed 15719 // down to the bottom, so if we are running low on memory we will 15720 // have a better chance at keeping around more cached processes 15721 // instead of a gazillion empty processes. 15722 numEmptyProcs = cachedProcessLimit; 15723 } 15724 int emptyFactor = numEmptyProcs/numSlots; 15725 if (emptyFactor < 1) emptyFactor = 1; 15726 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15727 if (cachedFactor < 1) cachedFactor = 1; 15728 int stepCached = 0; 15729 int stepEmpty = 0; 15730 int numCached = 0; 15731 int numEmpty = 0; 15732 int numTrimming = 0; 15733 15734 mNumNonCachedProcs = 0; 15735 mNumCachedHiddenProcs = 0; 15736 15737 // First update the OOM adjustment for each of the 15738 // application processes based on their current state. 15739 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15740 int nextCachedAdj = curCachedAdj+1; 15741 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15742 int nextEmptyAdj = curEmptyAdj+2; 15743 for (int i=N-1; i>=0; i--) { 15744 ProcessRecord app = mLruProcesses.get(i); 15745 if (!app.killedByAm && app.thread != null) { 15746 app.procStateChanged = false; 15747 final boolean wasKeeping = app.keeping; 15748 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15749 15750 // If we haven't yet assigned the final cached adj 15751 // to the process, do that now. 15752 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15753 switch (app.curProcState) { 15754 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15755 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15756 // This process is a cached process holding activities... 15757 // assign it the next cached value for that type, and then 15758 // step that cached level. 15759 app.curRawAdj = curCachedAdj; 15760 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15761 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15762 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15763 + ")"); 15764 if (curCachedAdj != nextCachedAdj) { 15765 stepCached++; 15766 if (stepCached >= cachedFactor) { 15767 stepCached = 0; 15768 curCachedAdj = nextCachedAdj; 15769 nextCachedAdj += 2; 15770 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15771 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15772 } 15773 } 15774 } 15775 break; 15776 default: 15777 // For everything else, assign next empty cached process 15778 // level and bump that up. Note that this means that 15779 // long-running services that have dropped down to the 15780 // cached level will be treated as empty (since their process 15781 // state is still as a service), which is what we want. 15782 app.curRawAdj = curEmptyAdj; 15783 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15784 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15785 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15786 + ")"); 15787 if (curEmptyAdj != nextEmptyAdj) { 15788 stepEmpty++; 15789 if (stepEmpty >= emptyFactor) { 15790 stepEmpty = 0; 15791 curEmptyAdj = nextEmptyAdj; 15792 nextEmptyAdj += 2; 15793 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15794 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15795 } 15796 } 15797 } 15798 break; 15799 } 15800 } 15801 15802 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15803 15804 // Count the number of process types. 15805 switch (app.curProcState) { 15806 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15807 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15808 mNumCachedHiddenProcs++; 15809 numCached++; 15810 if (numCached > cachedProcessLimit) { 15811 killUnneededProcessLocked(app, "cached #" + numCached); 15812 } 15813 break; 15814 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15815 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15816 && app.lastActivityTime < oldTime) { 15817 killUnneededProcessLocked(app, "empty for " 15818 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15819 / 1000) + "s"); 15820 } else { 15821 numEmpty++; 15822 if (numEmpty > emptyProcessLimit) { 15823 killUnneededProcessLocked(app, "empty #" + numEmpty); 15824 } 15825 } 15826 break; 15827 default: 15828 mNumNonCachedProcs++; 15829 break; 15830 } 15831 15832 if (app.isolated && app.services.size() <= 0) { 15833 // If this is an isolated process, and there are no 15834 // services running in it, then the process is no longer 15835 // needed. We agressively kill these because we can by 15836 // definition not re-use the same process again, and it is 15837 // good to avoid having whatever code was running in them 15838 // left sitting around after no longer needed. 15839 killUnneededProcessLocked(app, "isolated not needed"); 15840 } 15841 15842 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15843 && !app.killedByAm) { 15844 numTrimming++; 15845 } 15846 } 15847 } 15848 15849 mNumServiceProcs = mNewNumServiceProcs; 15850 15851 // Now determine the memory trimming level of background processes. 15852 // Unfortunately we need to start at the back of the list to do this 15853 // properly. We only do this if the number of background apps we 15854 // are managing to keep around is less than half the maximum we desire; 15855 // if we are keeping a good number around, we'll let them use whatever 15856 // memory they want. 15857 final int numCachedAndEmpty = numCached + numEmpty; 15858 int memFactor; 15859 if (numCached <= ProcessList.TRIM_CACHED_APPS 15860 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15861 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15862 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15863 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15864 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15865 } else { 15866 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15867 } 15868 } else { 15869 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15870 } 15871 // We always allow the memory level to go up (better). We only allow it to go 15872 // down if we are in a state where that is allowed, *and* the total number of processes 15873 // has gone down since last time. 15874 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15875 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15876 + " last=" + mLastNumProcesses); 15877 if (memFactor > mLastMemoryLevel) { 15878 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15879 memFactor = mLastMemoryLevel; 15880 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15881 } 15882 } 15883 mLastMemoryLevel = memFactor; 15884 mLastNumProcesses = mLruProcesses.size(); 15885 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15886 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15887 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15888 if (mLowRamStartTime == 0) { 15889 mLowRamStartTime = now; 15890 } 15891 int step = 0; 15892 int fgTrimLevel; 15893 switch (memFactor) { 15894 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15895 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15896 break; 15897 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15898 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15899 break; 15900 default: 15901 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15902 break; 15903 } 15904 int factor = numTrimming/3; 15905 int minFactor = 2; 15906 if (mHomeProcess != null) minFactor++; 15907 if (mPreviousProcess != null) minFactor++; 15908 if (factor < minFactor) factor = minFactor; 15909 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15910 for (int i=N-1; i>=0; i--) { 15911 ProcessRecord app = mLruProcesses.get(i); 15912 if (allChanged || app.procStateChanged) { 15913 setProcessTrackerState(app, trackerMemFactor, now); 15914 app.procStateChanged = false; 15915 } 15916 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15917 && !app.killedByAm) { 15918 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15919 try { 15920 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15921 "Trimming memory of " + app.processName 15922 + " to " + curLevel); 15923 app.thread.scheduleTrimMemory(curLevel); 15924 } catch (RemoteException e) { 15925 } 15926 if (false) { 15927 // For now we won't do this; our memory trimming seems 15928 // to be good enough at this point that destroying 15929 // activities causes more harm than good. 15930 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15931 && app != mHomeProcess && app != mPreviousProcess) { 15932 // Need to do this on its own message because the stack may not 15933 // be in a consistent state at this point. 15934 // For these apps we will also finish their activities 15935 // to help them free memory. 15936 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15937 } 15938 } 15939 } 15940 app.trimMemoryLevel = curLevel; 15941 step++; 15942 if (step >= factor) { 15943 step = 0; 15944 switch (curLevel) { 15945 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15946 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15947 break; 15948 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15949 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15950 break; 15951 } 15952 } 15953 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15954 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15955 && app.thread != null) { 15956 try { 15957 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15958 "Trimming memory of heavy-weight " + app.processName 15959 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15960 app.thread.scheduleTrimMemory( 15961 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15962 } catch (RemoteException e) { 15963 } 15964 } 15965 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15966 } else { 15967 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15968 || app.systemNoUi) && app.pendingUiClean) { 15969 // If this application is now in the background and it 15970 // had done UI, then give it the special trim level to 15971 // have it free UI resources. 15972 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15973 if (app.trimMemoryLevel < level && app.thread != null) { 15974 try { 15975 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15976 "Trimming memory of bg-ui " + app.processName 15977 + " to " + level); 15978 app.thread.scheduleTrimMemory(level); 15979 } catch (RemoteException e) { 15980 } 15981 } 15982 app.pendingUiClean = false; 15983 } 15984 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15985 try { 15986 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15987 "Trimming memory of fg " + app.processName 15988 + " to " + fgTrimLevel); 15989 app.thread.scheduleTrimMemory(fgTrimLevel); 15990 } catch (RemoteException e) { 15991 } 15992 } 15993 app.trimMemoryLevel = fgTrimLevel; 15994 } 15995 } 15996 } else { 15997 if (mLowRamStartTime != 0) { 15998 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15999 mLowRamStartTime = 0; 16000 } 16001 for (int i=N-1; i>=0; i--) { 16002 ProcessRecord app = mLruProcesses.get(i); 16003 if (allChanged || app.procStateChanged) { 16004 setProcessTrackerState(app, trackerMemFactor, now); 16005 app.procStateChanged = false; 16006 } 16007 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16008 || app.systemNoUi) && app.pendingUiClean) { 16009 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16010 && app.thread != null) { 16011 try { 16012 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16013 "Trimming memory of ui hidden " + app.processName 16014 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16015 app.thread.scheduleTrimMemory( 16016 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16017 } catch (RemoteException e) { 16018 } 16019 } 16020 app.pendingUiClean = false; 16021 } 16022 app.trimMemoryLevel = 0; 16023 } 16024 } 16025 16026 if (mAlwaysFinishActivities) { 16027 // Need to do this on its own message because the stack may not 16028 // be in a consistent state at this point. 16029 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16030 } 16031 16032 if (allChanged) { 16033 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16034 } 16035 16036 if (mProcessStats.shouldWriteNowLocked(now)) { 16037 mHandler.post(new Runnable() { 16038 @Override public void run() { 16039 synchronized (ActivityManagerService.this) { 16040 mProcessStats.writeStateAsyncLocked(); 16041 } 16042 } 16043 }); 16044 } 16045 16046 if (DEBUG_OOM_ADJ) { 16047 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16048 } 16049 } 16050 16051 final void trimApplications() { 16052 synchronized (this) { 16053 int i; 16054 16055 // First remove any unused application processes whose package 16056 // has been removed. 16057 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16058 final ProcessRecord app = mRemovedProcesses.get(i); 16059 if (app.activities.size() == 0 16060 && app.curReceiver == null && app.services.size() == 0) { 16061 Slog.i( 16062 TAG, "Exiting empty application process " 16063 + app.processName + " (" 16064 + (app.thread != null ? app.thread.asBinder() : null) 16065 + ")\n"); 16066 if (app.pid > 0 && app.pid != MY_PID) { 16067 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16068 app.processName, app.setAdj, "empty"); 16069 app.killedByAm = true; 16070 Process.killProcessQuiet(app.pid); 16071 } else { 16072 try { 16073 app.thread.scheduleExit(); 16074 } catch (Exception e) { 16075 // Ignore exceptions. 16076 } 16077 } 16078 cleanUpApplicationRecordLocked(app, false, true, -1); 16079 mRemovedProcesses.remove(i); 16080 16081 if (app.persistent) { 16082 if (app.persistent) { 16083 addAppLocked(app.info, false); 16084 } 16085 } 16086 } 16087 } 16088 16089 // Now update the oom adj for all processes. 16090 updateOomAdjLocked(); 16091 } 16092 } 16093 16094 /** This method sends the specified signal to each of the persistent apps */ 16095 public void signalPersistentProcesses(int sig) throws RemoteException { 16096 if (sig != Process.SIGNAL_USR1) { 16097 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16098 } 16099 16100 synchronized (this) { 16101 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16102 != PackageManager.PERMISSION_GRANTED) { 16103 throw new SecurityException("Requires permission " 16104 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16105 } 16106 16107 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16108 ProcessRecord r = mLruProcesses.get(i); 16109 if (r.thread != null && r.persistent) { 16110 Process.sendSignal(r.pid, sig); 16111 } 16112 } 16113 } 16114 } 16115 16116 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16117 if (proc == null || proc == mProfileProc) { 16118 proc = mProfileProc; 16119 path = mProfileFile; 16120 profileType = mProfileType; 16121 clearProfilerLocked(); 16122 } 16123 if (proc == null) { 16124 return; 16125 } 16126 try { 16127 proc.thread.profilerControl(false, path, null, profileType); 16128 } catch (RemoteException e) { 16129 throw new IllegalStateException("Process disappeared"); 16130 } 16131 } 16132 16133 private void clearProfilerLocked() { 16134 if (mProfileFd != null) { 16135 try { 16136 mProfileFd.close(); 16137 } catch (IOException e) { 16138 } 16139 } 16140 mProfileApp = null; 16141 mProfileProc = null; 16142 mProfileFile = null; 16143 mProfileType = 0; 16144 mAutoStopProfiler = false; 16145 } 16146 16147 public boolean profileControl(String process, int userId, boolean start, 16148 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16149 16150 try { 16151 synchronized (this) { 16152 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16153 // its own permission. 16154 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16155 != PackageManager.PERMISSION_GRANTED) { 16156 throw new SecurityException("Requires permission " 16157 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16158 } 16159 16160 if (start && fd == null) { 16161 throw new IllegalArgumentException("null fd"); 16162 } 16163 16164 ProcessRecord proc = null; 16165 if (process != null) { 16166 proc = findProcessLocked(process, userId, "profileControl"); 16167 } 16168 16169 if (start && (proc == null || proc.thread == null)) { 16170 throw new IllegalArgumentException("Unknown process: " + process); 16171 } 16172 16173 if (start) { 16174 stopProfilerLocked(null, null, 0); 16175 setProfileApp(proc.info, proc.processName, path, fd, false); 16176 mProfileProc = proc; 16177 mProfileType = profileType; 16178 try { 16179 fd = fd.dup(); 16180 } catch (IOException e) { 16181 fd = null; 16182 } 16183 proc.thread.profilerControl(start, path, fd, profileType); 16184 fd = null; 16185 mProfileFd = null; 16186 } else { 16187 stopProfilerLocked(proc, path, profileType); 16188 if (fd != null) { 16189 try { 16190 fd.close(); 16191 } catch (IOException e) { 16192 } 16193 } 16194 } 16195 16196 return true; 16197 } 16198 } catch (RemoteException e) { 16199 throw new IllegalStateException("Process disappeared"); 16200 } finally { 16201 if (fd != null) { 16202 try { 16203 fd.close(); 16204 } catch (IOException e) { 16205 } 16206 } 16207 } 16208 } 16209 16210 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16211 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16212 userId, true, true, callName, null); 16213 ProcessRecord proc = null; 16214 try { 16215 int pid = Integer.parseInt(process); 16216 synchronized (mPidsSelfLocked) { 16217 proc = mPidsSelfLocked.get(pid); 16218 } 16219 } catch (NumberFormatException e) { 16220 } 16221 16222 if (proc == null) { 16223 ArrayMap<String, SparseArray<ProcessRecord>> all 16224 = mProcessNames.getMap(); 16225 SparseArray<ProcessRecord> procs = all.get(process); 16226 if (procs != null && procs.size() > 0) { 16227 proc = procs.valueAt(0); 16228 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16229 for (int i=1; i<procs.size(); i++) { 16230 ProcessRecord thisProc = procs.valueAt(i); 16231 if (thisProc.userId == userId) { 16232 proc = thisProc; 16233 break; 16234 } 16235 } 16236 } 16237 } 16238 } 16239 16240 return proc; 16241 } 16242 16243 public boolean dumpHeap(String process, int userId, boolean managed, 16244 String path, ParcelFileDescriptor fd) throws RemoteException { 16245 16246 try { 16247 synchronized (this) { 16248 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16249 // its own permission (same as profileControl). 16250 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16251 != PackageManager.PERMISSION_GRANTED) { 16252 throw new SecurityException("Requires permission " 16253 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16254 } 16255 16256 if (fd == null) { 16257 throw new IllegalArgumentException("null fd"); 16258 } 16259 16260 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16261 if (proc == null || proc.thread == null) { 16262 throw new IllegalArgumentException("Unknown process: " + process); 16263 } 16264 16265 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16266 if (!isDebuggable) { 16267 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16268 throw new SecurityException("Process not debuggable: " + proc); 16269 } 16270 } 16271 16272 proc.thread.dumpHeap(managed, path, fd); 16273 fd = null; 16274 return true; 16275 } 16276 } catch (RemoteException e) { 16277 throw new IllegalStateException("Process disappeared"); 16278 } finally { 16279 if (fd != null) { 16280 try { 16281 fd.close(); 16282 } catch (IOException e) { 16283 } 16284 } 16285 } 16286 } 16287 16288 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16289 public void monitor() { 16290 synchronized (this) { } 16291 } 16292 16293 void onCoreSettingsChange(Bundle settings) { 16294 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16295 ProcessRecord processRecord = mLruProcesses.get(i); 16296 try { 16297 if (processRecord.thread != null) { 16298 processRecord.thread.setCoreSettings(settings); 16299 } 16300 } catch (RemoteException re) { 16301 /* ignore */ 16302 } 16303 } 16304 } 16305 16306 // Multi-user methods 16307 16308 /** 16309 * Start user, if its not already running, but don't bring it to foreground. 16310 */ 16311 @Override 16312 public boolean startUserInBackground(final int userId) { 16313 return startUser(userId, /* foreground */ false); 16314 } 16315 16316 /** 16317 * Refreshes the list of users related to the current user when either a 16318 * user switch happens or when a new related user is started in the 16319 * background. 16320 */ 16321 private void updateCurrentProfileIdsLocked() { 16322 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId); 16323 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16324 for (int i = 0; i < currentProfileIds.length; i++) { 16325 currentProfileIds[i] = profiles.get(i).id; 16326 } 16327 mCurrentProfileIds = currentProfileIds; 16328 } 16329 16330 private Set getProfileIdsLocked(int userId) { 16331 Set userIds = new HashSet<Integer>(); 16332 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(userId); 16333 for (UserInfo user : profiles) { 16334 userIds.add(Integer.valueOf(user.id)); 16335 } 16336 return userIds; 16337 } 16338 16339 @Override 16340 public boolean switchUser(final int userId) { 16341 return startUser(userId, /* foregound */ true); 16342 } 16343 16344 private boolean startUser(final int userId, boolean foreground) { 16345 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16346 != PackageManager.PERMISSION_GRANTED) { 16347 String msg = "Permission Denial: switchUser() from pid=" 16348 + Binder.getCallingPid() 16349 + ", uid=" + Binder.getCallingUid() 16350 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16351 Slog.w(TAG, msg); 16352 throw new SecurityException(msg); 16353 } 16354 16355 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16356 16357 final long ident = Binder.clearCallingIdentity(); 16358 try { 16359 synchronized (this) { 16360 final int oldUserId = mCurrentUserId; 16361 if (oldUserId == userId) { 16362 return true; 16363 } 16364 16365 mStackSupervisor.setLockTaskModeLocked(null); 16366 16367 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16368 if (userInfo == null) { 16369 Slog.w(TAG, "No user info for user #" + userId); 16370 return false; 16371 } 16372 16373 if (foreground) { 16374 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16375 R.anim.screen_user_enter); 16376 } 16377 16378 boolean needStart = false; 16379 16380 // If the user we are switching to is not currently started, then 16381 // we need to start it now. 16382 if (mStartedUsers.get(userId) == null) { 16383 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16384 updateStartedUserArrayLocked(); 16385 needStart = true; 16386 } 16387 16388 final Integer userIdInt = Integer.valueOf(userId); 16389 mUserLru.remove(userIdInt); 16390 mUserLru.add(userIdInt); 16391 16392 if (foreground) { 16393 mCurrentUserId = userId; 16394 updateCurrentProfileIdsLocked(); 16395 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16396 // Once the internal notion of the active user has switched, we lock the device 16397 // with the option to show the user switcher on the keyguard. 16398 mWindowManager.lockNow(null); 16399 } else { 16400 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16401 updateCurrentProfileIdsLocked(); 16402 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16403 mUserLru.remove(currentUserIdInt); 16404 mUserLru.add(currentUserIdInt); 16405 } 16406 16407 final UserStartedState uss = mStartedUsers.get(userId); 16408 16409 // Make sure user is in the started state. If it is currently 16410 // stopping, we need to knock that off. 16411 if (uss.mState == UserStartedState.STATE_STOPPING) { 16412 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16413 // so we can just fairly silently bring the user back from 16414 // the almost-dead. 16415 uss.mState = UserStartedState.STATE_RUNNING; 16416 updateStartedUserArrayLocked(); 16417 needStart = true; 16418 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16419 // This means ACTION_SHUTDOWN has been sent, so we will 16420 // need to treat this as a new boot of the user. 16421 uss.mState = UserStartedState.STATE_BOOTING; 16422 updateStartedUserArrayLocked(); 16423 needStart = true; 16424 } 16425 16426 if (foreground) { 16427 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16428 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16429 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16430 oldUserId, userId, uss)); 16431 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16432 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16433 } 16434 16435 if (needStart) { 16436 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16437 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16438 | Intent.FLAG_RECEIVER_FOREGROUND); 16439 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16440 broadcastIntentLocked(null, null, intent, 16441 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16442 false, false, MY_PID, Process.SYSTEM_UID, userId); 16443 } 16444 16445 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16446 if (userId != 0) { 16447 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16448 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16449 broadcastIntentLocked(null, null, intent, null, 16450 new IIntentReceiver.Stub() { 16451 public void performReceive(Intent intent, int resultCode, 16452 String data, Bundle extras, boolean ordered, 16453 boolean sticky, int sendingUser) { 16454 userInitialized(uss, userId); 16455 } 16456 }, 0, null, null, null, AppOpsManager.OP_NONE, 16457 true, false, MY_PID, Process.SYSTEM_UID, 16458 userId); 16459 uss.initializing = true; 16460 } else { 16461 getUserManagerLocked().makeInitialized(userInfo.id); 16462 } 16463 } 16464 16465 if (foreground) { 16466 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16467 if (homeInFront) { 16468 startHomeActivityLocked(userId); 16469 } else { 16470 mStackSupervisor.resumeTopActivitiesLocked(); 16471 } 16472 EventLogTags.writeAmSwitchUser(userId); 16473 getUserManagerLocked().userForeground(userId); 16474 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16475 } 16476 16477 if (needStart) { 16478 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16479 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16480 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16481 broadcastIntentLocked(null, null, intent, 16482 null, new IIntentReceiver.Stub() { 16483 @Override 16484 public void performReceive(Intent intent, int resultCode, String data, 16485 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16486 throws RemoteException { 16487 } 16488 }, 0, null, null, 16489 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16490 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16491 } 16492 } 16493 } finally { 16494 Binder.restoreCallingIdentity(ident); 16495 } 16496 16497 return true; 16498 } 16499 16500 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16501 long ident = Binder.clearCallingIdentity(); 16502 try { 16503 Intent intent; 16504 if (oldUserId >= 0) { 16505 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16506 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16507 | Intent.FLAG_RECEIVER_FOREGROUND); 16508 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16509 broadcastIntentLocked(null, null, intent, 16510 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16511 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16512 } 16513 if (newUserId >= 0) { 16514 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16515 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16516 | Intent.FLAG_RECEIVER_FOREGROUND); 16517 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16518 broadcastIntentLocked(null, null, intent, 16519 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16520 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16521 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16522 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16523 | Intent.FLAG_RECEIVER_FOREGROUND); 16524 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16525 broadcastIntentLocked(null, null, intent, 16526 null, null, 0, null, null, 16527 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16528 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16529 } 16530 } finally { 16531 Binder.restoreCallingIdentity(ident); 16532 } 16533 } 16534 16535 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16536 final int newUserId) { 16537 final int N = mUserSwitchObservers.beginBroadcast(); 16538 if (N > 0) { 16539 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16540 int mCount = 0; 16541 @Override 16542 public void sendResult(Bundle data) throws RemoteException { 16543 synchronized (ActivityManagerService.this) { 16544 if (mCurUserSwitchCallback == this) { 16545 mCount++; 16546 if (mCount == N) { 16547 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16548 } 16549 } 16550 } 16551 } 16552 }; 16553 synchronized (this) { 16554 uss.switching = true; 16555 mCurUserSwitchCallback = callback; 16556 } 16557 for (int i=0; i<N; i++) { 16558 try { 16559 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16560 newUserId, callback); 16561 } catch (RemoteException e) { 16562 } 16563 } 16564 } else { 16565 synchronized (this) { 16566 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16567 } 16568 } 16569 mUserSwitchObservers.finishBroadcast(); 16570 } 16571 16572 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16573 synchronized (this) { 16574 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16575 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16576 } 16577 } 16578 16579 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16580 mCurUserSwitchCallback = null; 16581 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16582 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16583 oldUserId, newUserId, uss)); 16584 } 16585 16586 void userInitialized(UserStartedState uss, int newUserId) { 16587 completeSwitchAndInitalize(uss, newUserId, true, false); 16588 } 16589 16590 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16591 completeSwitchAndInitalize(uss, newUserId, false, true); 16592 } 16593 16594 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16595 boolean clearInitializing, boolean clearSwitching) { 16596 boolean unfrozen = false; 16597 synchronized (this) { 16598 if (clearInitializing) { 16599 uss.initializing = false; 16600 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16601 } 16602 if (clearSwitching) { 16603 uss.switching = false; 16604 } 16605 if (!uss.switching && !uss.initializing) { 16606 mWindowManager.stopFreezingScreen(); 16607 unfrozen = true; 16608 } 16609 } 16610 if (unfrozen) { 16611 final int N = mUserSwitchObservers.beginBroadcast(); 16612 for (int i=0; i<N; i++) { 16613 try { 16614 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16615 } catch (RemoteException e) { 16616 } 16617 } 16618 mUserSwitchObservers.finishBroadcast(); 16619 } 16620 } 16621 16622 void scheduleStartProfilesLocked() { 16623 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16624 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16625 DateUtils.SECOND_IN_MILLIS); 16626 } 16627 } 16628 16629 void startProfilesLocked() { 16630 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16631 List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId); 16632 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16633 for (UserInfo user : profiles) { 16634 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16635 && user.id != mCurrentUserId) { 16636 toStart.add(user); 16637 } 16638 } 16639 final int n = toStart.size(); 16640 int i = 0; 16641 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16642 startUserInBackground(toStart.get(i).id); 16643 } 16644 if (i < n) { 16645 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16646 } 16647 } 16648 16649 void finishUserSwitch(UserStartedState uss) { 16650 synchronized (this) { 16651 if (uss.mState == UserStartedState.STATE_BOOTING 16652 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16653 uss.mState = UserStartedState.STATE_RUNNING; 16654 final int userId = uss.mHandle.getIdentifier(); 16655 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16656 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16657 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16658 broadcastIntentLocked(null, null, intent, 16659 null, null, 0, null, null, 16660 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16661 true, false, MY_PID, Process.SYSTEM_UID, userId); 16662 } 16663 16664 startProfilesLocked(); 16665 16666 int num = mUserLru.size(); 16667 int i = 0; 16668 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16669 Integer oldUserId = mUserLru.get(i); 16670 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16671 if (oldUss == null) { 16672 // Shouldn't happen, but be sane if it does. 16673 mUserLru.remove(i); 16674 num--; 16675 continue; 16676 } 16677 if (oldUss.mState == UserStartedState.STATE_STOPPING 16678 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16679 // This user is already stopping, doesn't count. 16680 num--; 16681 i++; 16682 continue; 16683 } 16684 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16685 // Owner and current can't be stopped, but count as running. 16686 i++; 16687 continue; 16688 } 16689 // This is a user to be stopped. 16690 stopUserLocked(oldUserId, null); 16691 num--; 16692 i++; 16693 } 16694 } 16695 } 16696 16697 @Override 16698 public int stopUser(final int userId, final IStopUserCallback callback) { 16699 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16700 != PackageManager.PERMISSION_GRANTED) { 16701 String msg = "Permission Denial: switchUser() from pid=" 16702 + Binder.getCallingPid() 16703 + ", uid=" + Binder.getCallingUid() 16704 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16705 Slog.w(TAG, msg); 16706 throw new SecurityException(msg); 16707 } 16708 if (userId <= 0) { 16709 throw new IllegalArgumentException("Can't stop primary user " + userId); 16710 } 16711 synchronized (this) { 16712 return stopUserLocked(userId, callback); 16713 } 16714 } 16715 16716 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16717 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16718 if (mCurrentUserId == userId) { 16719 return ActivityManager.USER_OP_IS_CURRENT; 16720 } 16721 16722 final UserStartedState uss = mStartedUsers.get(userId); 16723 if (uss == null) { 16724 // User is not started, nothing to do... but we do need to 16725 // callback if requested. 16726 if (callback != null) { 16727 mHandler.post(new Runnable() { 16728 @Override 16729 public void run() { 16730 try { 16731 callback.userStopped(userId); 16732 } catch (RemoteException e) { 16733 } 16734 } 16735 }); 16736 } 16737 return ActivityManager.USER_OP_SUCCESS; 16738 } 16739 16740 if (callback != null) { 16741 uss.mStopCallbacks.add(callback); 16742 } 16743 16744 if (uss.mState != UserStartedState.STATE_STOPPING 16745 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16746 uss.mState = UserStartedState.STATE_STOPPING; 16747 updateStartedUserArrayLocked(); 16748 16749 long ident = Binder.clearCallingIdentity(); 16750 try { 16751 // We are going to broadcast ACTION_USER_STOPPING and then 16752 // once that is done send a final ACTION_SHUTDOWN and then 16753 // stop the user. 16754 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16755 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16756 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16757 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16758 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16759 // This is the result receiver for the final shutdown broadcast. 16760 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16761 @Override 16762 public void performReceive(Intent intent, int resultCode, String data, 16763 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16764 finishUserStop(uss); 16765 } 16766 }; 16767 // This is the result receiver for the initial stopping broadcast. 16768 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16769 @Override 16770 public void performReceive(Intent intent, int resultCode, String data, 16771 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16772 // On to the next. 16773 synchronized (ActivityManagerService.this) { 16774 if (uss.mState != UserStartedState.STATE_STOPPING) { 16775 // Whoops, we are being started back up. Abort, abort! 16776 return; 16777 } 16778 uss.mState = UserStartedState.STATE_SHUTDOWN; 16779 } 16780 broadcastIntentLocked(null, null, shutdownIntent, 16781 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16782 true, false, MY_PID, Process.SYSTEM_UID, userId); 16783 } 16784 }; 16785 // Kick things off. 16786 broadcastIntentLocked(null, null, stoppingIntent, 16787 null, stoppingReceiver, 0, null, null, 16788 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16789 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16790 } finally { 16791 Binder.restoreCallingIdentity(ident); 16792 } 16793 } 16794 16795 return ActivityManager.USER_OP_SUCCESS; 16796 } 16797 16798 void finishUserStop(UserStartedState uss) { 16799 final int userId = uss.mHandle.getIdentifier(); 16800 boolean stopped; 16801 ArrayList<IStopUserCallback> callbacks; 16802 synchronized (this) { 16803 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16804 if (mStartedUsers.get(userId) != uss) { 16805 stopped = false; 16806 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16807 stopped = false; 16808 } else { 16809 stopped = true; 16810 // User can no longer run. 16811 mStartedUsers.remove(userId); 16812 mUserLru.remove(Integer.valueOf(userId)); 16813 updateStartedUserArrayLocked(); 16814 16815 // Clean up all state and processes associated with the user. 16816 // Kill all the processes for the user. 16817 forceStopUserLocked(userId, "finish user"); 16818 } 16819 } 16820 16821 for (int i=0; i<callbacks.size(); i++) { 16822 try { 16823 if (stopped) callbacks.get(i).userStopped(userId); 16824 else callbacks.get(i).userStopAborted(userId); 16825 } catch (RemoteException e) { 16826 } 16827 } 16828 16829 mStackSupervisor.removeUserLocked(userId); 16830 } 16831 16832 @Override 16833 public UserInfo getCurrentUser() { 16834 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16835 != PackageManager.PERMISSION_GRANTED) && ( 16836 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16837 != PackageManager.PERMISSION_GRANTED)) { 16838 String msg = "Permission Denial: getCurrentUser() from pid=" 16839 + Binder.getCallingPid() 16840 + ", uid=" + Binder.getCallingUid() 16841 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16842 Slog.w(TAG, msg); 16843 throw new SecurityException(msg); 16844 } 16845 synchronized (this) { 16846 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16847 } 16848 } 16849 16850 int getCurrentUserIdLocked() { 16851 return mCurrentUserId; 16852 } 16853 16854 @Override 16855 public boolean isUserRunning(int userId, boolean orStopped) { 16856 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16857 != PackageManager.PERMISSION_GRANTED) { 16858 String msg = "Permission Denial: isUserRunning() from pid=" 16859 + Binder.getCallingPid() 16860 + ", uid=" + Binder.getCallingUid() 16861 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16862 Slog.w(TAG, msg); 16863 throw new SecurityException(msg); 16864 } 16865 synchronized (this) { 16866 return isUserRunningLocked(userId, orStopped); 16867 } 16868 } 16869 16870 boolean isUserRunningLocked(int userId, boolean orStopped) { 16871 UserStartedState state = mStartedUsers.get(userId); 16872 if (state == null) { 16873 return false; 16874 } 16875 if (orStopped) { 16876 return true; 16877 } 16878 return state.mState != UserStartedState.STATE_STOPPING 16879 && state.mState != UserStartedState.STATE_SHUTDOWN; 16880 } 16881 16882 @Override 16883 public int[] getRunningUserIds() { 16884 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16885 != PackageManager.PERMISSION_GRANTED) { 16886 String msg = "Permission Denial: isUserRunning() from pid=" 16887 + Binder.getCallingPid() 16888 + ", uid=" + Binder.getCallingUid() 16889 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16890 Slog.w(TAG, msg); 16891 throw new SecurityException(msg); 16892 } 16893 synchronized (this) { 16894 return mStartedUserArray; 16895 } 16896 } 16897 16898 private void updateStartedUserArrayLocked() { 16899 int num = 0; 16900 for (int i=0; i<mStartedUsers.size(); i++) { 16901 UserStartedState uss = mStartedUsers.valueAt(i); 16902 // This list does not include stopping users. 16903 if (uss.mState != UserStartedState.STATE_STOPPING 16904 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16905 num++; 16906 } 16907 } 16908 mStartedUserArray = new int[num]; 16909 num = 0; 16910 for (int i=0; i<mStartedUsers.size(); i++) { 16911 UserStartedState uss = mStartedUsers.valueAt(i); 16912 if (uss.mState != UserStartedState.STATE_STOPPING 16913 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16914 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16915 num++; 16916 } 16917 } 16918 } 16919 16920 @Override 16921 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16922 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16923 != PackageManager.PERMISSION_GRANTED) { 16924 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16925 + Binder.getCallingPid() 16926 + ", uid=" + Binder.getCallingUid() 16927 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16928 Slog.w(TAG, msg); 16929 throw new SecurityException(msg); 16930 } 16931 16932 mUserSwitchObservers.register(observer); 16933 } 16934 16935 @Override 16936 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16937 mUserSwitchObservers.unregister(observer); 16938 } 16939 16940 private boolean userExists(int userId) { 16941 if (userId == 0) { 16942 return true; 16943 } 16944 UserManagerService ums = getUserManagerLocked(); 16945 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16946 } 16947 16948 int[] getUsersLocked() { 16949 UserManagerService ums = getUserManagerLocked(); 16950 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16951 } 16952 16953 UserManagerService getUserManagerLocked() { 16954 if (mUserManager == null) { 16955 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16956 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16957 } 16958 return mUserManager; 16959 } 16960 16961 private int applyUserId(int uid, int userId) { 16962 return UserHandle.getUid(userId, uid); 16963 } 16964 16965 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16966 if (info == null) return null; 16967 ApplicationInfo newInfo = new ApplicationInfo(info); 16968 newInfo.uid = applyUserId(info.uid, userId); 16969 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16970 + info.packageName; 16971 return newInfo; 16972 } 16973 16974 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16975 if (aInfo == null 16976 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16977 return aInfo; 16978 } 16979 16980 ActivityInfo info = new ActivityInfo(aInfo); 16981 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16982 return info; 16983 } 16984} 16985