ActivityManagerService.java revision 2fbd7541804f816171849413b095fcfc70e06c1e
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 String mDebugApp = null; 949 boolean mWaitForDebugger = false; 950 boolean mDebugTransient = false; 951 String mOrigDebugApp = null; 952 boolean mOrigWaitForDebugger = false; 953 boolean mAlwaysFinishActivities = false; 954 IActivityController mController = null; 955 String mProfileApp = null; 956 ProcessRecord mProfileProc = null; 957 String mProfileFile; 958 ParcelFileDescriptor mProfileFd; 959 int mProfileType = 0; 960 boolean mAutoStopProfiler = false; 961 String mOpenGlTraceApp = null; 962 963 static class ProcessChangeItem { 964 static final int CHANGE_ACTIVITIES = 1<<0; 965 static final int CHANGE_IMPORTANCE= 1<<1; 966 int changes; 967 int uid; 968 int pid; 969 int importance; 970 boolean foregroundActivities; 971 } 972 973 final RemoteCallbackList<IProcessObserver> mProcessObservers 974 = new RemoteCallbackList<IProcessObserver>(); 975 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 976 977 final ArrayList<ProcessChangeItem> mPendingProcessChanges 978 = new ArrayList<ProcessChangeItem>(); 979 final ArrayList<ProcessChangeItem> mAvailProcessChanges 980 = new ArrayList<ProcessChangeItem>(); 981 982 /** 983 * Runtime CPU use collection thread. This object's lock is used to 984 * protect all related state. 985 */ 986 final Thread mProcessCpuThread; 987 988 /** 989 * Used to collect process stats when showing not responding dialog. 990 * Protected by mProcessCpuThread. 991 */ 992 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 993 MONITOR_THREAD_CPU_USAGE); 994 final AtomicLong mLastCpuTime = new AtomicLong(0); 995 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 996 997 long mLastWriteTime = 0; 998 999 /** 1000 * Used to retain an update lock when the foreground activity is in 1001 * immersive mode. 1002 */ 1003 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1004 1005 /** 1006 * Set to true after the system has finished booting. 1007 */ 1008 boolean mBooted = false; 1009 1010 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1011 int mProcessLimitOverride = -1; 1012 1013 WindowManagerService mWindowManager; 1014 1015 final ActivityThread mSystemThread; 1016 1017 int mCurrentUserId = 0; 1018 int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack 1019 private UserManagerService mUserManager; 1020 1021 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1022 final ProcessRecord mApp; 1023 final int mPid; 1024 final IApplicationThread mAppThread; 1025 1026 AppDeathRecipient(ProcessRecord app, int pid, 1027 IApplicationThread thread) { 1028 if (localLOGV) Slog.v( 1029 TAG, "New death recipient " + this 1030 + " for thread " + thread.asBinder()); 1031 mApp = app; 1032 mPid = pid; 1033 mAppThread = thread; 1034 } 1035 1036 @Override 1037 public void binderDied() { 1038 if (localLOGV) Slog.v( 1039 TAG, "Death received in " + this 1040 + " for thread " + mAppThread.asBinder()); 1041 synchronized(ActivityManagerService.this) { 1042 appDiedLocked(mApp, mPid, mAppThread); 1043 } 1044 } 1045 } 1046 1047 static final int SHOW_ERROR_MSG = 1; 1048 static final int SHOW_NOT_RESPONDING_MSG = 2; 1049 static final int SHOW_FACTORY_ERROR_MSG = 3; 1050 static final int UPDATE_CONFIGURATION_MSG = 4; 1051 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1052 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1053 static final int SERVICE_TIMEOUT_MSG = 12; 1054 static final int UPDATE_TIME_ZONE = 13; 1055 static final int SHOW_UID_ERROR_MSG = 14; 1056 static final int IM_FEELING_LUCKY_MSG = 15; 1057 static final int PROC_START_TIMEOUT_MSG = 20; 1058 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1059 static final int KILL_APPLICATION_MSG = 22; 1060 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1061 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1062 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1063 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1064 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1065 static final int CLEAR_DNS_CACHE_MSG = 28; 1066 static final int UPDATE_HTTP_PROXY_MSG = 29; 1067 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1068 static final int DISPATCH_PROCESSES_CHANGED = 31; 1069 static final int DISPATCH_PROCESS_DIED = 32; 1070 static final int REPORT_MEM_USAGE_MSG = 33; 1071 static final int REPORT_USER_SWITCH_MSG = 34; 1072 static final int CONTINUE_USER_SWITCH_MSG = 35; 1073 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1074 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1075 static final int PERSIST_URI_GRANTS_MSG = 38; 1076 static final int REQUEST_ALL_PSS_MSG = 39; 1077 static final int START_RELATED_USERS_MSG = 40; 1078 static final int UPDATE_TIME = 41; 1079 1080 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1081 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1082 static final int FIRST_COMPAT_MODE_MSG = 300; 1083 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1084 1085 AlertDialog mUidAlert; 1086 CompatModeDialog mCompatModeDialog; 1087 long mLastMemUsageReportTime = 0; 1088 1089 /** 1090 * Flag whether the current user is a "monkey", i.e. whether 1091 * the UI is driven by a UI automation tool. 1092 */ 1093 private boolean mUserIsMonkey; 1094 1095 final ServiceThread mHandlerThread; 1096 final MainHandler mHandler; 1097 1098 final class MainHandler extends Handler { 1099 public MainHandler(Looper looper) { 1100 super(looper, null, true); 1101 } 1102 1103 @Override 1104 public void handleMessage(Message msg) { 1105 switch (msg.what) { 1106 case SHOW_ERROR_MSG: { 1107 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1108 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1109 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1110 synchronized (ActivityManagerService.this) { 1111 ProcessRecord proc = (ProcessRecord)data.get("app"); 1112 AppErrorResult res = (AppErrorResult) data.get("result"); 1113 if (proc != null && proc.crashDialog != null) { 1114 Slog.e(TAG, "App already has crash dialog: " + proc); 1115 if (res != null) { 1116 res.set(0); 1117 } 1118 return; 1119 } 1120 if (!showBackground && UserHandle.getAppId(proc.uid) 1121 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1122 && proc.pid != MY_PID) { 1123 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1124 if (res != null) { 1125 res.set(0); 1126 } 1127 return; 1128 } 1129 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1130 Dialog d = new AppErrorDialog(mContext, 1131 ActivityManagerService.this, res, proc); 1132 d.show(); 1133 proc.crashDialog = d; 1134 } else { 1135 // The device is asleep, so just pretend that the user 1136 // saw a crash dialog and hit "force quit". 1137 if (res != null) { 1138 res.set(0); 1139 } 1140 } 1141 } 1142 1143 ensureBootCompleted(); 1144 } break; 1145 case SHOW_NOT_RESPONDING_MSG: { 1146 synchronized (ActivityManagerService.this) { 1147 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1148 ProcessRecord proc = (ProcessRecord)data.get("app"); 1149 if (proc != null && proc.anrDialog != null) { 1150 Slog.e(TAG, "App already has anr dialog: " + proc); 1151 return; 1152 } 1153 1154 Intent intent = new Intent("android.intent.action.ANR"); 1155 if (!mProcessesReady) { 1156 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1157 | Intent.FLAG_RECEIVER_FOREGROUND); 1158 } 1159 broadcastIntentLocked(null, null, intent, 1160 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1161 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1162 1163 if (mShowDialogs) { 1164 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1165 mContext, proc, (ActivityRecord)data.get("activity"), 1166 msg.arg1 != 0); 1167 d.show(); 1168 proc.anrDialog = d; 1169 } else { 1170 // Just kill the app if there is no dialog to be shown. 1171 killAppAtUsersRequest(proc, null); 1172 } 1173 } 1174 1175 ensureBootCompleted(); 1176 } break; 1177 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1178 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1179 synchronized (ActivityManagerService.this) { 1180 ProcessRecord proc = (ProcessRecord) data.get("app"); 1181 if (proc == null) { 1182 Slog.e(TAG, "App not found when showing strict mode dialog."); 1183 break; 1184 } 1185 if (proc.crashDialog != null) { 1186 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1187 return; 1188 } 1189 AppErrorResult res = (AppErrorResult) data.get("result"); 1190 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1191 Dialog d = new StrictModeViolationDialog(mContext, 1192 ActivityManagerService.this, res, proc); 1193 d.show(); 1194 proc.crashDialog = d; 1195 } else { 1196 // The device is asleep, so just pretend that the user 1197 // saw a crash dialog and hit "force quit". 1198 res.set(0); 1199 } 1200 } 1201 ensureBootCompleted(); 1202 } break; 1203 case SHOW_FACTORY_ERROR_MSG: { 1204 Dialog d = new FactoryErrorDialog( 1205 mContext, msg.getData().getCharSequence("msg")); 1206 d.show(); 1207 ensureBootCompleted(); 1208 } break; 1209 case UPDATE_CONFIGURATION_MSG: { 1210 final ContentResolver resolver = mContext.getContentResolver(); 1211 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1212 } break; 1213 case GC_BACKGROUND_PROCESSES_MSG: { 1214 synchronized (ActivityManagerService.this) { 1215 performAppGcsIfAppropriateLocked(); 1216 } 1217 } break; 1218 case WAIT_FOR_DEBUGGER_MSG: { 1219 synchronized (ActivityManagerService.this) { 1220 ProcessRecord app = (ProcessRecord)msg.obj; 1221 if (msg.arg1 != 0) { 1222 if (!app.waitedForDebugger) { 1223 Dialog d = new AppWaitingForDebuggerDialog( 1224 ActivityManagerService.this, 1225 mContext, app); 1226 app.waitDialog = d; 1227 app.waitedForDebugger = true; 1228 d.show(); 1229 } 1230 } else { 1231 if (app.waitDialog != null) { 1232 app.waitDialog.dismiss(); 1233 app.waitDialog = null; 1234 } 1235 } 1236 } 1237 } break; 1238 case SERVICE_TIMEOUT_MSG: { 1239 if (mDidDexOpt) { 1240 mDidDexOpt = false; 1241 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1242 nmsg.obj = msg.obj; 1243 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1244 return; 1245 } 1246 mServices.serviceTimeout((ProcessRecord)msg.obj); 1247 } break; 1248 case UPDATE_TIME_ZONE: { 1249 synchronized (ActivityManagerService.this) { 1250 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1251 ProcessRecord r = mLruProcesses.get(i); 1252 if (r.thread != null) { 1253 try { 1254 r.thread.updateTimeZone(); 1255 } catch (RemoteException ex) { 1256 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1257 } 1258 } 1259 } 1260 } 1261 } break; 1262 case CLEAR_DNS_CACHE_MSG: { 1263 synchronized (ActivityManagerService.this) { 1264 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1265 ProcessRecord r = mLruProcesses.get(i); 1266 if (r.thread != null) { 1267 try { 1268 r.thread.clearDnsCache(); 1269 } catch (RemoteException ex) { 1270 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1271 } 1272 } 1273 } 1274 } 1275 } break; 1276 case UPDATE_HTTP_PROXY_MSG: { 1277 ProxyProperties proxy = (ProxyProperties)msg.obj; 1278 String host = ""; 1279 String port = ""; 1280 String exclList = ""; 1281 String pacFileUrl = null; 1282 if (proxy != null) { 1283 host = proxy.getHost(); 1284 port = Integer.toString(proxy.getPort()); 1285 exclList = proxy.getExclusionList(); 1286 pacFileUrl = proxy.getPacFileUrl(); 1287 } 1288 synchronized (ActivityManagerService.this) { 1289 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1290 ProcessRecord r = mLruProcesses.get(i); 1291 if (r.thread != null) { 1292 try { 1293 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1294 } catch (RemoteException ex) { 1295 Slog.w(TAG, "Failed to update http proxy for: " + 1296 r.info.processName); 1297 } 1298 } 1299 } 1300 } 1301 } break; 1302 case SHOW_UID_ERROR_MSG: { 1303 String title = "System UIDs Inconsistent"; 1304 String text = "UIDs on the system are inconsistent, you need to wipe your" 1305 + " data partition or your device will be unstable."; 1306 Log.e(TAG, title + ": " + text); 1307 if (mShowDialogs) { 1308 // XXX This is a temporary dialog, no need to localize. 1309 AlertDialog d = new BaseErrorDialog(mContext); 1310 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1311 d.setCancelable(false); 1312 d.setTitle(title); 1313 d.setMessage(text); 1314 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1315 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1316 mUidAlert = d; 1317 d.show(); 1318 } 1319 } break; 1320 case IM_FEELING_LUCKY_MSG: { 1321 if (mUidAlert != null) { 1322 mUidAlert.dismiss(); 1323 mUidAlert = null; 1324 } 1325 } break; 1326 case PROC_START_TIMEOUT_MSG: { 1327 if (mDidDexOpt) { 1328 mDidDexOpt = false; 1329 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1330 nmsg.obj = msg.obj; 1331 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1332 return; 1333 } 1334 ProcessRecord app = (ProcessRecord)msg.obj; 1335 synchronized (ActivityManagerService.this) { 1336 processStartTimedOutLocked(app); 1337 } 1338 } break; 1339 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1340 synchronized (ActivityManagerService.this) { 1341 doPendingActivityLaunchesLocked(true); 1342 } 1343 } break; 1344 case KILL_APPLICATION_MSG: { 1345 synchronized (ActivityManagerService.this) { 1346 int appid = msg.arg1; 1347 boolean restart = (msg.arg2 == 1); 1348 Bundle bundle = (Bundle)msg.obj; 1349 String pkg = bundle.getString("pkg"); 1350 String reason = bundle.getString("reason"); 1351 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1352 false, UserHandle.USER_ALL, reason); 1353 } 1354 } break; 1355 case FINALIZE_PENDING_INTENT_MSG: { 1356 ((PendingIntentRecord)msg.obj).completeFinalize(); 1357 } break; 1358 case POST_HEAVY_NOTIFICATION_MSG: { 1359 INotificationManager inm = NotificationManager.getService(); 1360 if (inm == null) { 1361 return; 1362 } 1363 1364 ActivityRecord root = (ActivityRecord)msg.obj; 1365 ProcessRecord process = root.app; 1366 if (process == null) { 1367 return; 1368 } 1369 1370 try { 1371 Context context = mContext.createPackageContext(process.info.packageName, 0); 1372 String text = mContext.getString(R.string.heavy_weight_notification, 1373 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1374 Notification notification = new Notification(); 1375 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1376 notification.when = 0; 1377 notification.flags = Notification.FLAG_ONGOING_EVENT; 1378 notification.tickerText = text; 1379 notification.defaults = 0; // please be quiet 1380 notification.sound = null; 1381 notification.vibrate = null; 1382 notification.setLatestEventInfo(context, text, 1383 mContext.getText(R.string.heavy_weight_notification_detail), 1384 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1385 PendingIntent.FLAG_CANCEL_CURRENT, null, 1386 new UserHandle(root.userId))); 1387 1388 try { 1389 int[] outId = new int[1]; 1390 inm.enqueueNotificationWithTag("android", "android", null, 1391 R.string.heavy_weight_notification, 1392 notification, outId, root.userId); 1393 } catch (RuntimeException e) { 1394 Slog.w(ActivityManagerService.TAG, 1395 "Error showing notification for heavy-weight app", e); 1396 } catch (RemoteException e) { 1397 } 1398 } catch (NameNotFoundException e) { 1399 Slog.w(TAG, "Unable to create context for heavy notification", e); 1400 } 1401 } break; 1402 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1403 INotificationManager inm = NotificationManager.getService(); 1404 if (inm == null) { 1405 return; 1406 } 1407 try { 1408 inm.cancelNotificationWithTag("android", null, 1409 R.string.heavy_weight_notification, msg.arg1); 1410 } catch (RuntimeException e) { 1411 Slog.w(ActivityManagerService.TAG, 1412 "Error canceling notification for service", e); 1413 } catch (RemoteException e) { 1414 } 1415 } break; 1416 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1417 synchronized (ActivityManagerService.this) { 1418 checkExcessivePowerUsageLocked(true); 1419 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1420 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1421 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1422 } 1423 } break; 1424 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1425 synchronized (ActivityManagerService.this) { 1426 ActivityRecord ar = (ActivityRecord)msg.obj; 1427 if (mCompatModeDialog != null) { 1428 if (mCompatModeDialog.mAppInfo.packageName.equals( 1429 ar.info.applicationInfo.packageName)) { 1430 return; 1431 } 1432 mCompatModeDialog.dismiss(); 1433 mCompatModeDialog = null; 1434 } 1435 if (ar != null && false) { 1436 if (mCompatModePackages.getPackageAskCompatModeLocked( 1437 ar.packageName)) { 1438 int mode = mCompatModePackages.computeCompatModeLocked( 1439 ar.info.applicationInfo); 1440 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1441 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1442 mCompatModeDialog = new CompatModeDialog( 1443 ActivityManagerService.this, mContext, 1444 ar.info.applicationInfo); 1445 mCompatModeDialog.show(); 1446 } 1447 } 1448 } 1449 } 1450 break; 1451 } 1452 case DISPATCH_PROCESSES_CHANGED: { 1453 dispatchProcessesChanged(); 1454 break; 1455 } 1456 case DISPATCH_PROCESS_DIED: { 1457 final int pid = msg.arg1; 1458 final int uid = msg.arg2; 1459 dispatchProcessDied(pid, uid); 1460 break; 1461 } 1462 case REPORT_MEM_USAGE_MSG: { 1463 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1464 Thread thread = new Thread() { 1465 @Override public void run() { 1466 final SparseArray<ProcessMemInfo> infoMap 1467 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1468 for (int i=0, N=memInfos.size(); i<N; i++) { 1469 ProcessMemInfo mi = memInfos.get(i); 1470 infoMap.put(mi.pid, mi); 1471 } 1472 updateCpuStatsNow(); 1473 synchronized (mProcessCpuThread) { 1474 final int N = mProcessCpuTracker.countStats(); 1475 for (int i=0; i<N; i++) { 1476 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1477 if (st.vsize > 0) { 1478 long pss = Debug.getPss(st.pid, null); 1479 if (pss > 0) { 1480 if (infoMap.indexOfKey(st.pid) < 0) { 1481 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1482 ProcessList.NATIVE_ADJ, -1, "native", null); 1483 mi.pss = pss; 1484 memInfos.add(mi); 1485 } 1486 } 1487 } 1488 } 1489 } 1490 1491 long totalPss = 0; 1492 for (int i=0, N=memInfos.size(); i<N; i++) { 1493 ProcessMemInfo mi = memInfos.get(i); 1494 if (mi.pss == 0) { 1495 mi.pss = Debug.getPss(mi.pid, null); 1496 } 1497 totalPss += mi.pss; 1498 } 1499 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1500 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1501 if (lhs.oomAdj != rhs.oomAdj) { 1502 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1503 } 1504 if (lhs.pss != rhs.pss) { 1505 return lhs.pss < rhs.pss ? 1 : -1; 1506 } 1507 return 0; 1508 } 1509 }); 1510 1511 StringBuilder tag = new StringBuilder(128); 1512 StringBuilder stack = new StringBuilder(128); 1513 tag.append("Low on memory -- "); 1514 appendMemBucket(tag, totalPss, "total", false); 1515 appendMemBucket(stack, totalPss, "total", true); 1516 1517 StringBuilder logBuilder = new StringBuilder(1024); 1518 logBuilder.append("Low on memory:\n"); 1519 1520 boolean firstLine = true; 1521 int lastOomAdj = Integer.MIN_VALUE; 1522 for (int i=0, N=memInfos.size(); i<N; i++) { 1523 ProcessMemInfo mi = memInfos.get(i); 1524 1525 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1526 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1527 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1528 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1529 if (lastOomAdj != mi.oomAdj) { 1530 lastOomAdj = mi.oomAdj; 1531 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1532 tag.append(" / "); 1533 } 1534 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1535 if (firstLine) { 1536 stack.append(":"); 1537 firstLine = false; 1538 } 1539 stack.append("\n\t at "); 1540 } else { 1541 stack.append("$"); 1542 } 1543 } else { 1544 tag.append(" "); 1545 stack.append("$"); 1546 } 1547 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1548 appendMemBucket(tag, mi.pss, mi.name, false); 1549 } 1550 appendMemBucket(stack, mi.pss, mi.name, true); 1551 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1552 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1553 stack.append("("); 1554 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1555 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1556 stack.append(DUMP_MEM_OOM_LABEL[k]); 1557 stack.append(":"); 1558 stack.append(DUMP_MEM_OOM_ADJ[k]); 1559 } 1560 } 1561 stack.append(")"); 1562 } 1563 } 1564 1565 logBuilder.append(" "); 1566 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1567 logBuilder.append(' '); 1568 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1569 logBuilder.append(' '); 1570 ProcessList.appendRamKb(logBuilder, mi.pss); 1571 logBuilder.append(" kB: "); 1572 logBuilder.append(mi.name); 1573 logBuilder.append(" ("); 1574 logBuilder.append(mi.pid); 1575 logBuilder.append(") "); 1576 logBuilder.append(mi.adjType); 1577 logBuilder.append('\n'); 1578 if (mi.adjReason != null) { 1579 logBuilder.append(" "); 1580 logBuilder.append(mi.adjReason); 1581 logBuilder.append('\n'); 1582 } 1583 } 1584 1585 logBuilder.append(" "); 1586 ProcessList.appendRamKb(logBuilder, totalPss); 1587 logBuilder.append(" kB: TOTAL\n"); 1588 1589 long[] infos = new long[Debug.MEMINFO_COUNT]; 1590 Debug.getMemInfo(infos); 1591 logBuilder.append(" MemInfo: "); 1592 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1593 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1594 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1595 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1596 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1597 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1598 logBuilder.append(" ZRAM: "); 1599 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1600 logBuilder.append(" kB RAM, "); 1601 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1602 logBuilder.append(" kB swap total, "); 1603 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1604 logBuilder.append(" kB swap free\n"); 1605 } 1606 Slog.i(TAG, logBuilder.toString()); 1607 1608 StringBuilder dropBuilder = new StringBuilder(1024); 1609 /* 1610 StringWriter oomSw = new StringWriter(); 1611 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1612 StringWriter catSw = new StringWriter(); 1613 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1614 String[] emptyArgs = new String[] { }; 1615 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1616 oomPw.flush(); 1617 String oomString = oomSw.toString(); 1618 */ 1619 dropBuilder.append(stack); 1620 dropBuilder.append('\n'); 1621 dropBuilder.append('\n'); 1622 dropBuilder.append(logBuilder); 1623 dropBuilder.append('\n'); 1624 /* 1625 dropBuilder.append(oomString); 1626 dropBuilder.append('\n'); 1627 */ 1628 StringWriter catSw = new StringWriter(); 1629 synchronized (ActivityManagerService.this) { 1630 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1631 String[] emptyArgs = new String[] { }; 1632 catPw.println(); 1633 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1634 catPw.println(); 1635 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1636 false, false, null); 1637 catPw.println(); 1638 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1639 catPw.flush(); 1640 } 1641 dropBuilder.append(catSw.toString()); 1642 addErrorToDropBox("lowmem", null, "system_server", null, 1643 null, tag.toString(), dropBuilder.toString(), null, null); 1644 //Slog.i(TAG, "Sent to dropbox:"); 1645 //Slog.i(TAG, dropBuilder.toString()); 1646 synchronized (ActivityManagerService.this) { 1647 long now = SystemClock.uptimeMillis(); 1648 if (mLastMemUsageReportTime < now) { 1649 mLastMemUsageReportTime = now; 1650 } 1651 } 1652 } 1653 }; 1654 thread.start(); 1655 break; 1656 } 1657 case REPORT_USER_SWITCH_MSG: { 1658 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1659 break; 1660 } 1661 case CONTINUE_USER_SWITCH_MSG: { 1662 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1663 break; 1664 } 1665 case USER_SWITCH_TIMEOUT_MSG: { 1666 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1667 break; 1668 } 1669 case IMMERSIVE_MODE_LOCK_MSG: { 1670 final boolean nextState = (msg.arg1 != 0); 1671 if (mUpdateLock.isHeld() != nextState) { 1672 if (DEBUG_IMMERSIVE) { 1673 final ActivityRecord r = (ActivityRecord) msg.obj; 1674 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1675 } 1676 if (nextState) { 1677 mUpdateLock.acquire(); 1678 } else { 1679 mUpdateLock.release(); 1680 } 1681 } 1682 break; 1683 } 1684 case PERSIST_URI_GRANTS_MSG: { 1685 writeGrantedUriPermissions(); 1686 break; 1687 } 1688 case REQUEST_ALL_PSS_MSG: { 1689 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1690 break; 1691 } 1692 case START_RELATED_USERS_MSG: { 1693 synchronized (ActivityManagerService.this) { 1694 startRelatedUsersLocked(); 1695 } 1696 break; 1697 } 1698 case UPDATE_TIME: { 1699 synchronized (ActivityManagerService.this) { 1700 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1701 ProcessRecord r = mLruProcesses.get(i); 1702 if (r.thread != null) { 1703 try { 1704 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1705 } catch (RemoteException ex) { 1706 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1707 } 1708 } 1709 } 1710 } 1711 break; 1712 } 1713 } 1714 } 1715 }; 1716 1717 static final int COLLECT_PSS_BG_MSG = 1; 1718 1719 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1720 @Override 1721 public void handleMessage(Message msg) { 1722 switch (msg.what) { 1723 case COLLECT_PSS_BG_MSG: { 1724 int i=0, num=0; 1725 long start = SystemClock.uptimeMillis(); 1726 long[] tmp = new long[1]; 1727 do { 1728 ProcessRecord proc; 1729 int procState; 1730 int pid; 1731 synchronized (ActivityManagerService.this) { 1732 if (i >= mPendingPssProcesses.size()) { 1733 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1734 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1735 mPendingPssProcesses.clear(); 1736 return; 1737 } 1738 proc = mPendingPssProcesses.get(i); 1739 procState = proc.pssProcState; 1740 if (proc.thread != null && procState == proc.setProcState) { 1741 pid = proc.pid; 1742 } else { 1743 proc = null; 1744 pid = 0; 1745 } 1746 i++; 1747 } 1748 if (proc != null) { 1749 long pss = Debug.getPss(pid, tmp); 1750 synchronized (ActivityManagerService.this) { 1751 if (proc.thread != null && proc.setProcState == procState 1752 && proc.pid == pid) { 1753 num++; 1754 proc.lastPssTime = SystemClock.uptimeMillis(); 1755 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1756 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1757 + ": " + pss + " lastPss=" + proc.lastPss 1758 + " state=" + ProcessList.makeProcStateString(procState)); 1759 if (proc.initialIdlePss == 0) { 1760 proc.initialIdlePss = pss; 1761 } 1762 proc.lastPss = pss; 1763 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1764 proc.lastCachedPss = pss; 1765 } 1766 } 1767 } 1768 } 1769 } while (true); 1770 } 1771 } 1772 } 1773 }; 1774 1775 public void setSystemProcess() { 1776 try { 1777 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1778 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1779 ServiceManager.addService("meminfo", new MemBinder(this)); 1780 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1781 ServiceManager.addService("dbinfo", new DbBinder(this)); 1782 if (MONITOR_CPU_USAGE) { 1783 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1784 } 1785 ServiceManager.addService("permission", new PermissionController(this)); 1786 1787 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1788 "android", STOCK_PM_FLAGS); 1789 mSystemThread.installSystemApplicationInfo(info); 1790 1791 synchronized (this) { 1792 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1793 app.persistent = true; 1794 app.pid = MY_PID; 1795 app.maxAdj = ProcessList.SYSTEM_ADJ; 1796 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1797 mProcessNames.put(app.processName, app.uid, app); 1798 synchronized (mPidsSelfLocked) { 1799 mPidsSelfLocked.put(app.pid, app); 1800 } 1801 updateLruProcessLocked(app, false, null); 1802 updateOomAdjLocked(); 1803 } 1804 } catch (PackageManager.NameNotFoundException e) { 1805 throw new RuntimeException( 1806 "Unable to find android system package", e); 1807 } 1808 } 1809 1810 public void setWindowManager(WindowManagerService wm) { 1811 mWindowManager = wm; 1812 mStackSupervisor.setWindowManager(wm); 1813 } 1814 1815 public void startObservingNativeCrashes() { 1816 final NativeCrashListener ncl = new NativeCrashListener(this); 1817 ncl.start(); 1818 } 1819 1820 public IAppOpsService getAppOpsService() { 1821 return mAppOpsService; 1822 } 1823 1824 static class MemBinder extends Binder { 1825 ActivityManagerService mActivityManagerService; 1826 MemBinder(ActivityManagerService activityManagerService) { 1827 mActivityManagerService = activityManagerService; 1828 } 1829 1830 @Override 1831 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1832 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1833 != PackageManager.PERMISSION_GRANTED) { 1834 pw.println("Permission Denial: can't dump meminfo from from pid=" 1835 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1836 + " without permission " + android.Manifest.permission.DUMP); 1837 return; 1838 } 1839 1840 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1841 } 1842 } 1843 1844 static class GraphicsBinder extends Binder { 1845 ActivityManagerService mActivityManagerService; 1846 GraphicsBinder(ActivityManagerService activityManagerService) { 1847 mActivityManagerService = activityManagerService; 1848 } 1849 1850 @Override 1851 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1852 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1853 != PackageManager.PERMISSION_GRANTED) { 1854 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1855 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1856 + " without permission " + android.Manifest.permission.DUMP); 1857 return; 1858 } 1859 1860 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1861 } 1862 } 1863 1864 static class DbBinder extends Binder { 1865 ActivityManagerService mActivityManagerService; 1866 DbBinder(ActivityManagerService activityManagerService) { 1867 mActivityManagerService = activityManagerService; 1868 } 1869 1870 @Override 1871 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1872 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1873 != PackageManager.PERMISSION_GRANTED) { 1874 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1875 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1876 + " without permission " + android.Manifest.permission.DUMP); 1877 return; 1878 } 1879 1880 mActivityManagerService.dumpDbInfo(fd, pw, args); 1881 } 1882 } 1883 1884 static class CpuBinder extends Binder { 1885 ActivityManagerService mActivityManagerService; 1886 CpuBinder(ActivityManagerService activityManagerService) { 1887 mActivityManagerService = activityManagerService; 1888 } 1889 1890 @Override 1891 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1892 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1893 != PackageManager.PERMISSION_GRANTED) { 1894 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1895 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1896 + " without permission " + android.Manifest.permission.DUMP); 1897 return; 1898 } 1899 1900 synchronized (mActivityManagerService.mProcessCpuThread) { 1901 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1902 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1903 SystemClock.uptimeMillis())); 1904 } 1905 } 1906 } 1907 1908 public static final class Lifecycle extends SystemService { 1909 private final ActivityManagerService mService; 1910 1911 public Lifecycle(Context context) { 1912 super(context); 1913 mService = new ActivityManagerService(context); 1914 } 1915 1916 @Override 1917 public void onStart() { 1918 mService.start(); 1919 } 1920 1921 public ActivityManagerService getService() { 1922 return mService; 1923 } 1924 } 1925 1926 // Note: This method is invoked on the main thread but may need to attach various 1927 // handlers to other threads. So take care to be explicit about the looper. 1928 public ActivityManagerService(Context systemContext) { 1929 mContext = systemContext; 1930 mFactoryTest = FactoryTest.getMode(); 1931 mSystemThread = ActivityThread.currentActivityThread(); 1932 1933 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1934 1935 mHandlerThread = new ServiceThread(TAG, 1936 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1937 mHandlerThread.start(); 1938 mHandler = new MainHandler(mHandlerThread.getLooper()); 1939 1940 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1941 "foreground", BROADCAST_FG_TIMEOUT, false); 1942 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1943 "background", BROADCAST_BG_TIMEOUT, true); 1944 mBroadcastQueues[0] = mFgBroadcastQueue; 1945 mBroadcastQueues[1] = mBgBroadcastQueue; 1946 1947 mServices = new ActiveServices(this); 1948 mProviderMap = new ProviderMap(this); 1949 1950 // TODO: Move creation of battery stats service outside of activity manager service. 1951 File dataDir = Environment.getDataDirectory(); 1952 File systemDir = new File(dataDir, "system"); 1953 systemDir.mkdirs(); 1954 mBatteryStatsService = new BatteryStatsService(new File( 1955 systemDir, "batterystats.bin").toString(), mHandler); 1956 mBatteryStatsService.getActiveStatistics().readLocked(); 1957 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1958 mOnBattery = DEBUG_POWER ? true 1959 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1960 mBatteryStatsService.getActiveStatistics().setCallback(this); 1961 1962 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1963 1964 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1965 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1966 1967 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1968 1969 // User 0 is the first and only user that runs at boot. 1970 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1971 mUserLru.add(Integer.valueOf(0)); 1972 updateStartedUserArrayLocked(); 1973 1974 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1975 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1976 1977 mConfiguration.setToDefaults(); 1978 mConfiguration.setLocale(Locale.getDefault()); 1979 1980 mConfigurationSeq = mConfiguration.seq = 1; 1981 mProcessCpuTracker.init(); 1982 1983 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1984 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1985 mStackSupervisor = new ActivityStackSupervisor(this); 1986 1987 mProcessCpuThread = new Thread("CpuTracker") { 1988 @Override 1989 public void run() { 1990 while (true) { 1991 try { 1992 try { 1993 synchronized(this) { 1994 final long now = SystemClock.uptimeMillis(); 1995 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1996 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1997 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1998 // + ", write delay=" + nextWriteDelay); 1999 if (nextWriteDelay < nextCpuDelay) { 2000 nextCpuDelay = nextWriteDelay; 2001 } 2002 if (nextCpuDelay > 0) { 2003 mProcessCpuMutexFree.set(true); 2004 this.wait(nextCpuDelay); 2005 } 2006 } 2007 } catch (InterruptedException e) { 2008 } 2009 updateCpuStatsNow(); 2010 } catch (Exception e) { 2011 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2012 } 2013 } 2014 } 2015 }; 2016 2017 Watchdog.getInstance().addMonitor(this); 2018 Watchdog.getInstance().addThread(mHandler); 2019 } 2020 2021 private void start() { 2022 mProcessCpuThread.start(); 2023 2024 mBatteryStatsService.publish(mContext); 2025 mUsageStatsService.publish(mContext); 2026 mAppOpsService.publish(mContext); 2027 startRunning(null, null, null, null); 2028 } 2029 2030 @Override 2031 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2032 throws RemoteException { 2033 if (code == SYSPROPS_TRANSACTION) { 2034 // We need to tell all apps about the system property change. 2035 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2036 synchronized(this) { 2037 final int NP = mProcessNames.getMap().size(); 2038 for (int ip=0; ip<NP; ip++) { 2039 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2040 final int NA = apps.size(); 2041 for (int ia=0; ia<NA; ia++) { 2042 ProcessRecord app = apps.valueAt(ia); 2043 if (app.thread != null) { 2044 procs.add(app.thread.asBinder()); 2045 } 2046 } 2047 } 2048 } 2049 2050 int N = procs.size(); 2051 for (int i=0; i<N; i++) { 2052 Parcel data2 = Parcel.obtain(); 2053 try { 2054 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2055 } catch (RemoteException e) { 2056 } 2057 data2.recycle(); 2058 } 2059 } 2060 try { 2061 return super.onTransact(code, data, reply, flags); 2062 } catch (RuntimeException e) { 2063 // The activity manager only throws security exceptions, so let's 2064 // log all others. 2065 if (!(e instanceof SecurityException)) { 2066 Slog.wtf(TAG, "Activity Manager Crash", e); 2067 } 2068 throw e; 2069 } 2070 } 2071 2072 void updateCpuStats() { 2073 final long now = SystemClock.uptimeMillis(); 2074 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2075 return; 2076 } 2077 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2078 synchronized (mProcessCpuThread) { 2079 mProcessCpuThread.notify(); 2080 } 2081 } 2082 } 2083 2084 void updateCpuStatsNow() { 2085 synchronized (mProcessCpuThread) { 2086 mProcessCpuMutexFree.set(false); 2087 final long now = SystemClock.uptimeMillis(); 2088 boolean haveNewCpuStats = false; 2089 2090 if (MONITOR_CPU_USAGE && 2091 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2092 mLastCpuTime.set(now); 2093 haveNewCpuStats = true; 2094 mProcessCpuTracker.update(); 2095 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2096 //Slog.i(TAG, "Total CPU usage: " 2097 // + mProcessCpu.getTotalCpuPercent() + "%"); 2098 2099 // Slog the cpu usage if the property is set. 2100 if ("true".equals(SystemProperties.get("events.cpu"))) { 2101 int user = mProcessCpuTracker.getLastUserTime(); 2102 int system = mProcessCpuTracker.getLastSystemTime(); 2103 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2104 int irq = mProcessCpuTracker.getLastIrqTime(); 2105 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2106 int idle = mProcessCpuTracker.getLastIdleTime(); 2107 2108 int total = user + system + iowait + irq + softIrq + idle; 2109 if (total == 0) total = 1; 2110 2111 EventLog.writeEvent(EventLogTags.CPU, 2112 ((user+system+iowait+irq+softIrq) * 100) / total, 2113 (user * 100) / total, 2114 (system * 100) / total, 2115 (iowait * 100) / total, 2116 (irq * 100) / total, 2117 (softIrq * 100) / total); 2118 } 2119 } 2120 2121 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2122 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2123 synchronized(bstats) { 2124 synchronized(mPidsSelfLocked) { 2125 if (haveNewCpuStats) { 2126 if (mOnBattery) { 2127 int perc = bstats.startAddingCpuLocked(); 2128 int totalUTime = 0; 2129 int totalSTime = 0; 2130 final int N = mProcessCpuTracker.countStats(); 2131 for (int i=0; i<N; i++) { 2132 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2133 if (!st.working) { 2134 continue; 2135 } 2136 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2137 int otherUTime = (st.rel_utime*perc)/100; 2138 int otherSTime = (st.rel_stime*perc)/100; 2139 totalUTime += otherUTime; 2140 totalSTime += otherSTime; 2141 if (pr != null) { 2142 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2143 if (ps == null || !ps.isActive()) { 2144 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2145 pr.info.uid, pr.processName); 2146 } 2147 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2148 st.rel_stime-otherSTime); 2149 ps.addSpeedStepTimes(cpuSpeedTimes); 2150 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2151 } else { 2152 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2153 if (ps == null || !ps.isActive()) { 2154 st.batteryStats = ps = bstats.getProcessStatsLocked( 2155 bstats.mapUid(st.uid), st.name); 2156 } 2157 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2158 st.rel_stime-otherSTime); 2159 ps.addSpeedStepTimes(cpuSpeedTimes); 2160 } 2161 } 2162 bstats.finishAddingCpuLocked(perc, totalUTime, 2163 totalSTime, cpuSpeedTimes); 2164 } 2165 } 2166 } 2167 2168 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2169 mLastWriteTime = now; 2170 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2171 } 2172 } 2173 } 2174 } 2175 2176 @Override 2177 public void batteryNeedsCpuUpdate() { 2178 updateCpuStatsNow(); 2179 } 2180 2181 @Override 2182 public void batteryPowerChanged(boolean onBattery) { 2183 // When plugging in, update the CPU stats first before changing 2184 // the plug state. 2185 updateCpuStatsNow(); 2186 synchronized (this) { 2187 synchronized(mPidsSelfLocked) { 2188 mOnBattery = DEBUG_POWER ? true : onBattery; 2189 } 2190 } 2191 } 2192 2193 /** 2194 * Initialize the application bind args. These are passed to each 2195 * process when the bindApplication() IPC is sent to the process. They're 2196 * lazily setup to make sure the services are running when they're asked for. 2197 */ 2198 private HashMap<String, IBinder> getCommonServicesLocked() { 2199 if (mAppBindArgs == null) { 2200 mAppBindArgs = new HashMap<String, IBinder>(); 2201 2202 // Setup the application init args 2203 mAppBindArgs.put("package", ServiceManager.getService("package")); 2204 mAppBindArgs.put("window", ServiceManager.getService("window")); 2205 mAppBindArgs.put(Context.ALARM_SERVICE, 2206 ServiceManager.getService(Context.ALARM_SERVICE)); 2207 } 2208 return mAppBindArgs; 2209 } 2210 2211 final void setFocusedActivityLocked(ActivityRecord r) { 2212 if (mFocusedActivity != r) { 2213 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2214 mFocusedActivity = r; 2215 mStackSupervisor.setFocusedStack(r); 2216 if (r != null) { 2217 mWindowManager.setFocusedApp(r.appToken, true); 2218 } 2219 applyUpdateLockStateLocked(r); 2220 } 2221 } 2222 2223 @Override 2224 public void setFocusedStack(int stackId) { 2225 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2226 synchronized (ActivityManagerService.this) { 2227 ActivityStack stack = mStackSupervisor.getStack(stackId); 2228 if (stack != null) { 2229 ActivityRecord r = stack.topRunningActivityLocked(null); 2230 if (r != null) { 2231 setFocusedActivityLocked(r); 2232 } 2233 } 2234 } 2235 } 2236 2237 @Override 2238 public void notifyActivityDrawn(IBinder token) { 2239 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2240 synchronized (this) { 2241 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2242 if (r != null) { 2243 r.task.stack.notifyActivityDrawnLocked(r); 2244 } 2245 } 2246 } 2247 2248 final void applyUpdateLockStateLocked(ActivityRecord r) { 2249 // Modifications to the UpdateLock state are done on our handler, outside 2250 // the activity manager's locks. The new state is determined based on the 2251 // state *now* of the relevant activity record. The object is passed to 2252 // the handler solely for logging detail, not to be consulted/modified. 2253 final boolean nextState = r != null && r.immersive; 2254 mHandler.sendMessage( 2255 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2256 } 2257 2258 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2259 Message msg = Message.obtain(); 2260 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2261 msg.obj = r.task.askedCompatMode ? null : r; 2262 mHandler.sendMessage(msg); 2263 } 2264 2265 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2266 String what, Object obj, ProcessRecord srcApp) { 2267 app.lastActivityTime = now; 2268 2269 if (app.activities.size() > 0) { 2270 // Don't want to touch dependent processes that are hosting activities. 2271 return index; 2272 } 2273 2274 int lrui = mLruProcesses.lastIndexOf(app); 2275 if (lrui < 0) { 2276 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2277 + what + " " + obj + " from " + srcApp); 2278 return index; 2279 } 2280 2281 if (lrui >= index) { 2282 // Don't want to cause this to move dependent processes *back* in the 2283 // list as if they were less frequently used. 2284 return index; 2285 } 2286 2287 if (lrui >= mLruProcessActivityStart) { 2288 // Don't want to touch dependent processes that are hosting activities. 2289 return index; 2290 } 2291 2292 mLruProcesses.remove(lrui); 2293 if (index > 0) { 2294 index--; 2295 } 2296 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2297 + " in LRU list: " + app); 2298 mLruProcesses.add(index, app); 2299 return index; 2300 } 2301 2302 final void removeLruProcessLocked(ProcessRecord app) { 2303 int lrui = mLruProcesses.lastIndexOf(app); 2304 if (lrui >= 0) { 2305 if (lrui <= mLruProcessActivityStart) { 2306 mLruProcessActivityStart--; 2307 } 2308 if (lrui <= mLruProcessServiceStart) { 2309 mLruProcessServiceStart--; 2310 } 2311 mLruProcesses.remove(lrui); 2312 } 2313 } 2314 2315 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2316 ProcessRecord client) { 2317 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2318 || app.treatLikeActivity; 2319 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2320 if (!activityChange && hasActivity) { 2321 // The process has activities, so we are only allowing activity-based adjustments 2322 // to move it. It should be kept in the front of the list with other 2323 // processes that have activities, and we don't want those to change their 2324 // order except due to activity operations. 2325 return; 2326 } 2327 2328 mLruSeq++; 2329 final long now = SystemClock.uptimeMillis(); 2330 app.lastActivityTime = now; 2331 2332 // First a quick reject: if the app is already at the position we will 2333 // put it, then there is nothing to do. 2334 if (hasActivity) { 2335 final int N = mLruProcesses.size(); 2336 if (N > 0 && mLruProcesses.get(N-1) == app) { 2337 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2338 return; 2339 } 2340 } else { 2341 if (mLruProcessServiceStart > 0 2342 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2343 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2344 return; 2345 } 2346 } 2347 2348 int lrui = mLruProcesses.lastIndexOf(app); 2349 2350 if (app.persistent && lrui >= 0) { 2351 // We don't care about the position of persistent processes, as long as 2352 // they are in the list. 2353 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2354 return; 2355 } 2356 2357 /* In progress: compute new position first, so we can avoid doing work 2358 if the process is not actually going to move. Not yet working. 2359 int addIndex; 2360 int nextIndex; 2361 boolean inActivity = false, inService = false; 2362 if (hasActivity) { 2363 // Process has activities, put it at the very tipsy-top. 2364 addIndex = mLruProcesses.size(); 2365 nextIndex = mLruProcessServiceStart; 2366 inActivity = true; 2367 } else if (hasService) { 2368 // Process has services, put it at the top of the service list. 2369 addIndex = mLruProcessActivityStart; 2370 nextIndex = mLruProcessServiceStart; 2371 inActivity = true; 2372 inService = true; 2373 } else { 2374 // Process not otherwise of interest, it goes to the top of the non-service area. 2375 addIndex = mLruProcessServiceStart; 2376 if (client != null) { 2377 int clientIndex = mLruProcesses.lastIndexOf(client); 2378 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2379 + app); 2380 if (clientIndex >= 0 && addIndex > clientIndex) { 2381 addIndex = clientIndex; 2382 } 2383 } 2384 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2385 } 2386 2387 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2388 + mLruProcessActivityStart + "): " + app); 2389 */ 2390 2391 if (lrui >= 0) { 2392 if (lrui < mLruProcessActivityStart) { 2393 mLruProcessActivityStart--; 2394 } 2395 if (lrui < mLruProcessServiceStart) { 2396 mLruProcessServiceStart--; 2397 } 2398 /* 2399 if (addIndex > lrui) { 2400 addIndex--; 2401 } 2402 if (nextIndex > lrui) { 2403 nextIndex--; 2404 } 2405 */ 2406 mLruProcesses.remove(lrui); 2407 } 2408 2409 /* 2410 mLruProcesses.add(addIndex, app); 2411 if (inActivity) { 2412 mLruProcessActivityStart++; 2413 } 2414 if (inService) { 2415 mLruProcessActivityStart++; 2416 } 2417 */ 2418 2419 int nextIndex; 2420 if (hasActivity) { 2421 final int N = mLruProcesses.size(); 2422 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2423 // Process doesn't have activities, but has clients with 2424 // activities... move it up, but one below the top (the top 2425 // should always have a real activity). 2426 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2427 mLruProcesses.add(N-1, app); 2428 // To keep it from spamming the LRU list (by making a bunch of clients), 2429 // we will push down any other entries owned by the app. 2430 final int uid = app.info.uid; 2431 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2432 ProcessRecord subProc = mLruProcesses.get(i); 2433 if (subProc.info.uid == uid) { 2434 // We want to push this one down the list. If the process after 2435 // it is for the same uid, however, don't do so, because we don't 2436 // want them internally to be re-ordered. 2437 if (mLruProcesses.get(i-1).info.uid != uid) { 2438 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2439 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2440 ProcessRecord tmp = mLruProcesses.get(i); 2441 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2442 mLruProcesses.set(i-1, tmp); 2443 i--; 2444 } 2445 } else { 2446 // A gap, we can stop here. 2447 break; 2448 } 2449 } 2450 } else { 2451 // Process has activities, put it at the very tipsy-top. 2452 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2453 mLruProcesses.add(app); 2454 } 2455 nextIndex = mLruProcessServiceStart; 2456 } else if (hasService) { 2457 // Process has services, put it at the top of the service list. 2458 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2459 mLruProcesses.add(mLruProcessActivityStart, app); 2460 nextIndex = mLruProcessServiceStart; 2461 mLruProcessActivityStart++; 2462 } else { 2463 // Process not otherwise of interest, it goes to the top of the non-service area. 2464 int index = mLruProcessServiceStart; 2465 if (client != null) { 2466 // If there is a client, don't allow the process to be moved up higher 2467 // in the list than that client. 2468 int clientIndex = mLruProcesses.lastIndexOf(client); 2469 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2470 + " when updating " + app); 2471 if (clientIndex <= lrui) { 2472 // Don't allow the client index restriction to push it down farther in the 2473 // list than it already is. 2474 clientIndex = lrui; 2475 } 2476 if (clientIndex >= 0 && index > clientIndex) { 2477 index = clientIndex; 2478 } 2479 } 2480 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2481 mLruProcesses.add(index, app); 2482 nextIndex = index-1; 2483 mLruProcessActivityStart++; 2484 mLruProcessServiceStart++; 2485 } 2486 2487 // If the app is currently using a content provider or service, 2488 // bump those processes as well. 2489 for (int j=app.connections.size()-1; j>=0; j--) { 2490 ConnectionRecord cr = app.connections.valueAt(j); 2491 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2492 && cr.binding.service.app != null 2493 && cr.binding.service.app.lruSeq != mLruSeq 2494 && !cr.binding.service.app.persistent) { 2495 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2496 "service connection", cr, app); 2497 } 2498 } 2499 for (int j=app.conProviders.size()-1; j>=0; j--) { 2500 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2501 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2502 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2503 "provider reference", cpr, app); 2504 } 2505 } 2506 } 2507 2508 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2509 if (uid == Process.SYSTEM_UID) { 2510 // The system gets to run in any process. If there are multiple 2511 // processes with the same uid, just pick the first (this 2512 // should never happen). 2513 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2514 if (procs == null) return null; 2515 final int N = procs.size(); 2516 for (int i = 0; i < N; i++) { 2517 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2518 } 2519 } 2520 ProcessRecord proc = mProcessNames.get(processName, uid); 2521 if (false && proc != null && !keepIfLarge 2522 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2523 && proc.lastCachedPss >= 4000) { 2524 // Turn this condition on to cause killing to happen regularly, for testing. 2525 if (proc.baseProcessTracker != null) { 2526 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2527 } 2528 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2529 + "k from cached"); 2530 } else if (proc != null && !keepIfLarge 2531 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2532 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2533 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2534 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2535 if (proc.baseProcessTracker != null) { 2536 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2537 } 2538 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2539 + "k from cached"); 2540 } 2541 } 2542 return proc; 2543 } 2544 2545 void ensurePackageDexOpt(String packageName) { 2546 IPackageManager pm = AppGlobals.getPackageManager(); 2547 try { 2548 if (pm.performDexOpt(packageName)) { 2549 mDidDexOpt = true; 2550 } 2551 } catch (RemoteException e) { 2552 } 2553 } 2554 2555 boolean isNextTransitionForward() { 2556 int transit = mWindowManager.getPendingAppTransition(); 2557 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2558 || transit == AppTransition.TRANSIT_TASK_OPEN 2559 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2560 } 2561 2562 final ProcessRecord startProcessLocked(String processName, 2563 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2564 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2565 boolean isolated, boolean keepIfLarge) { 2566 ProcessRecord app; 2567 if (!isolated) { 2568 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2569 } else { 2570 // If this is an isolated process, it can't re-use an existing process. 2571 app = null; 2572 } 2573 // We don't have to do anything more if: 2574 // (1) There is an existing application record; and 2575 // (2) The caller doesn't think it is dead, OR there is no thread 2576 // object attached to it so we know it couldn't have crashed; and 2577 // (3) There is a pid assigned to it, so it is either starting or 2578 // already running. 2579 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2580 + " app=" + app + " knownToBeDead=" + knownToBeDead 2581 + " thread=" + (app != null ? app.thread : null) 2582 + " pid=" + (app != null ? app.pid : -1)); 2583 if (app != null && app.pid > 0) { 2584 if (!knownToBeDead || app.thread == null) { 2585 // We already have the app running, or are waiting for it to 2586 // come up (we have a pid but not yet its thread), so keep it. 2587 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2588 // If this is a new package in the process, add the package to the list 2589 app.addPackage(info.packageName, mProcessStats); 2590 return app; 2591 } 2592 2593 // An application record is attached to a previous process, 2594 // clean it up now. 2595 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2596 handleAppDiedLocked(app, true, true); 2597 } 2598 2599 String hostingNameStr = hostingName != null 2600 ? hostingName.flattenToShortString() : null; 2601 2602 if (!isolated) { 2603 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2604 // If we are in the background, then check to see if this process 2605 // is bad. If so, we will just silently fail. 2606 if (mBadProcesses.get(info.processName, info.uid) != null) { 2607 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2608 + "/" + info.processName); 2609 return null; 2610 } 2611 } else { 2612 // When the user is explicitly starting a process, then clear its 2613 // crash count so that we won't make it bad until they see at 2614 // least one crash dialog again, and make the process good again 2615 // if it had been bad. 2616 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2617 + "/" + info.processName); 2618 mProcessCrashTimes.remove(info.processName, info.uid); 2619 if (mBadProcesses.get(info.processName, info.uid) != null) { 2620 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2621 UserHandle.getUserId(info.uid), info.uid, 2622 info.processName); 2623 mBadProcesses.remove(info.processName, info.uid); 2624 if (app != null) { 2625 app.bad = false; 2626 } 2627 } 2628 } 2629 } 2630 2631 if (app == null) { 2632 app = newProcessRecordLocked(info, processName, isolated); 2633 if (app == null) { 2634 Slog.w(TAG, "Failed making new process record for " 2635 + processName + "/" + info.uid + " isolated=" + isolated); 2636 return null; 2637 } 2638 mProcessNames.put(processName, app.uid, app); 2639 if (isolated) { 2640 mIsolatedProcesses.put(app.uid, app); 2641 } 2642 } else { 2643 // If this is a new package in the process, add the package to the list 2644 app.addPackage(info.packageName, mProcessStats); 2645 } 2646 2647 // If the system is not ready yet, then hold off on starting this 2648 // process until it is. 2649 if (!mProcessesReady 2650 && !isAllowedWhileBooting(info) 2651 && !allowWhileBooting) { 2652 if (!mProcessesOnHold.contains(app)) { 2653 mProcessesOnHold.add(app); 2654 } 2655 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2656 return app; 2657 } 2658 2659 startProcessLocked(app, hostingType, hostingNameStr); 2660 return (app.pid != 0) ? app : null; 2661 } 2662 2663 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2664 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2665 } 2666 2667 private final void startProcessLocked(ProcessRecord app, 2668 String hostingType, String hostingNameStr) { 2669 if (app.pid > 0 && app.pid != MY_PID) { 2670 synchronized (mPidsSelfLocked) { 2671 mPidsSelfLocked.remove(app.pid); 2672 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2673 } 2674 app.setPid(0); 2675 } 2676 2677 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2678 "startProcessLocked removing on hold: " + app); 2679 mProcessesOnHold.remove(app); 2680 2681 updateCpuStats(); 2682 2683 try { 2684 int uid = app.uid; 2685 2686 int[] gids = null; 2687 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2688 if (!app.isolated) { 2689 int[] permGids = null; 2690 try { 2691 final PackageManager pm = mContext.getPackageManager(); 2692 permGids = pm.getPackageGids(app.info.packageName); 2693 2694 if (Environment.isExternalStorageEmulated()) { 2695 if (pm.checkPermission( 2696 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2697 app.info.packageName) == PERMISSION_GRANTED) { 2698 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2699 } else { 2700 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2701 } 2702 } 2703 } catch (PackageManager.NameNotFoundException e) { 2704 Slog.w(TAG, "Unable to retrieve gids", e); 2705 } 2706 2707 /* 2708 * Add shared application GID so applications can share some 2709 * resources like shared libraries 2710 */ 2711 if (permGids == null) { 2712 gids = new int[1]; 2713 } else { 2714 gids = new int[permGids.length + 1]; 2715 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2716 } 2717 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2718 } 2719 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2720 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2721 && mTopComponent != null 2722 && app.processName.equals(mTopComponent.getPackageName())) { 2723 uid = 0; 2724 } 2725 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2726 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2727 uid = 0; 2728 } 2729 } 2730 int debugFlags = 0; 2731 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2732 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2733 // Also turn on CheckJNI for debuggable apps. It's quite 2734 // awkward to turn on otherwise. 2735 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2736 } 2737 // Run the app in safe mode if its manifest requests so or the 2738 // system is booted in safe mode. 2739 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2740 Zygote.systemInSafeMode == true) { 2741 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2742 } 2743 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2744 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2745 } 2746 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2747 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2748 } 2749 if ("1".equals(SystemProperties.get("debug.assert"))) { 2750 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2751 } 2752 2753 // Start the process. It will either succeed and return a result containing 2754 // the PID of the new process, or else throw a RuntimeException. 2755 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2756 app.processName, uid, uid, gids, debugFlags, mountExternal, 2757 app.info.targetSdkVersion, app.info.seinfo, null); 2758 2759 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2760 synchronized (bs) { 2761 if (bs.isOnBattery()) { 2762 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2763 } 2764 } 2765 2766 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2767 UserHandle.getUserId(uid), startResult.pid, uid, 2768 app.processName, hostingType, 2769 hostingNameStr != null ? hostingNameStr : ""); 2770 2771 if (app.persistent) { 2772 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2773 } 2774 2775 StringBuilder buf = mStringBuilder; 2776 buf.setLength(0); 2777 buf.append("Start proc "); 2778 buf.append(app.processName); 2779 buf.append(" for "); 2780 buf.append(hostingType); 2781 if (hostingNameStr != null) { 2782 buf.append(" "); 2783 buf.append(hostingNameStr); 2784 } 2785 buf.append(": pid="); 2786 buf.append(startResult.pid); 2787 buf.append(" uid="); 2788 buf.append(uid); 2789 buf.append(" gids={"); 2790 if (gids != null) { 2791 for (int gi=0; gi<gids.length; gi++) { 2792 if (gi != 0) buf.append(", "); 2793 buf.append(gids[gi]); 2794 2795 } 2796 } 2797 buf.append("}"); 2798 Slog.i(TAG, buf.toString()); 2799 app.setPid(startResult.pid); 2800 app.usingWrapper = startResult.usingWrapper; 2801 app.removed = false; 2802 synchronized (mPidsSelfLocked) { 2803 this.mPidsSelfLocked.put(startResult.pid, app); 2804 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2805 msg.obj = app; 2806 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2807 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2808 } 2809 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2810 app.processName, app.info.uid); 2811 if (app.isolated) { 2812 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2813 } 2814 } catch (RuntimeException e) { 2815 // XXX do better error recovery. 2816 app.setPid(0); 2817 Slog.e(TAG, "Failure starting process " + app.processName, e); 2818 } 2819 } 2820 2821 void updateUsageStats(ActivityRecord component, boolean resumed) { 2822 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2823 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2824 if (resumed) { 2825 mUsageStatsService.noteResumeComponent(component.realActivity); 2826 synchronized (stats) { 2827 stats.noteActivityResumedLocked(component.app.uid); 2828 } 2829 } else { 2830 mUsageStatsService.notePauseComponent(component.realActivity); 2831 synchronized (stats) { 2832 stats.noteActivityPausedLocked(component.app.uid); 2833 } 2834 } 2835 } 2836 2837 Intent getHomeIntent() { 2838 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2839 intent.setComponent(mTopComponent); 2840 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2841 intent.addCategory(Intent.CATEGORY_HOME); 2842 } 2843 return intent; 2844 } 2845 2846 boolean startHomeActivityLocked(int userId) { 2847 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2848 && mTopAction == null) { 2849 // We are running in factory test mode, but unable to find 2850 // the factory test app, so just sit around displaying the 2851 // error message and don't try to start anything. 2852 return false; 2853 } 2854 Intent intent = getHomeIntent(); 2855 ActivityInfo aInfo = 2856 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2857 if (aInfo != null) { 2858 intent.setComponent(new ComponentName( 2859 aInfo.applicationInfo.packageName, aInfo.name)); 2860 // Don't do this if the home app is currently being 2861 // instrumented. 2862 aInfo = new ActivityInfo(aInfo); 2863 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2864 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2865 aInfo.applicationInfo.uid, true); 2866 if (app == null || app.instrumentationClass == null) { 2867 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2868 mStackSupervisor.startHomeActivity(intent, aInfo); 2869 } 2870 } 2871 2872 return true; 2873 } 2874 2875 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2876 ActivityInfo ai = null; 2877 ComponentName comp = intent.getComponent(); 2878 try { 2879 if (comp != null) { 2880 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2881 } else { 2882 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2883 intent, 2884 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2885 flags, userId); 2886 2887 if (info != null) { 2888 ai = info.activityInfo; 2889 } 2890 } 2891 } catch (RemoteException e) { 2892 // ignore 2893 } 2894 2895 return ai; 2896 } 2897 2898 /** 2899 * Starts the "new version setup screen" if appropriate. 2900 */ 2901 void startSetupActivityLocked() { 2902 // Only do this once per boot. 2903 if (mCheckedForSetup) { 2904 return; 2905 } 2906 2907 // We will show this screen if the current one is a different 2908 // version than the last one shown, and we are not running in 2909 // low-level factory test mode. 2910 final ContentResolver resolver = mContext.getContentResolver(); 2911 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2912 Settings.Global.getInt(resolver, 2913 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2914 mCheckedForSetup = true; 2915 2916 // See if we should be showing the platform update setup UI. 2917 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2918 List<ResolveInfo> ris = mContext.getPackageManager() 2919 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2920 2921 // We don't allow third party apps to replace this. 2922 ResolveInfo ri = null; 2923 for (int i=0; ris != null && i<ris.size(); i++) { 2924 if ((ris.get(i).activityInfo.applicationInfo.flags 2925 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2926 ri = ris.get(i); 2927 break; 2928 } 2929 } 2930 2931 if (ri != null) { 2932 String vers = ri.activityInfo.metaData != null 2933 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2934 : null; 2935 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2936 vers = ri.activityInfo.applicationInfo.metaData.getString( 2937 Intent.METADATA_SETUP_VERSION); 2938 } 2939 String lastVers = Settings.Secure.getString( 2940 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2941 if (vers != null && !vers.equals(lastVers)) { 2942 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2943 intent.setComponent(new ComponentName( 2944 ri.activityInfo.packageName, ri.activityInfo.name)); 2945 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2946 null, null, 0, 0, 0, null, 0, null, false, null, null); 2947 } 2948 } 2949 } 2950 } 2951 2952 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2953 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2954 } 2955 2956 void enforceNotIsolatedCaller(String caller) { 2957 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2958 throw new SecurityException("Isolated process not allowed to call " + caller); 2959 } 2960 } 2961 2962 @Override 2963 public int getFrontActivityScreenCompatMode() { 2964 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2965 synchronized (this) { 2966 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2967 } 2968 } 2969 2970 @Override 2971 public void setFrontActivityScreenCompatMode(int mode) { 2972 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2973 "setFrontActivityScreenCompatMode"); 2974 synchronized (this) { 2975 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2976 } 2977 } 2978 2979 @Override 2980 public int getPackageScreenCompatMode(String packageName) { 2981 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2982 synchronized (this) { 2983 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2984 } 2985 } 2986 2987 @Override 2988 public void setPackageScreenCompatMode(String packageName, int mode) { 2989 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2990 "setPackageScreenCompatMode"); 2991 synchronized (this) { 2992 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2993 } 2994 } 2995 2996 @Override 2997 public boolean getPackageAskScreenCompat(String packageName) { 2998 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2999 synchronized (this) { 3000 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3001 } 3002 } 3003 3004 @Override 3005 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3006 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3007 "setPackageAskScreenCompat"); 3008 synchronized (this) { 3009 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3010 } 3011 } 3012 3013 private void dispatchProcessesChanged() { 3014 int N; 3015 synchronized (this) { 3016 N = mPendingProcessChanges.size(); 3017 if (mActiveProcessChanges.length < N) { 3018 mActiveProcessChanges = new ProcessChangeItem[N]; 3019 } 3020 mPendingProcessChanges.toArray(mActiveProcessChanges); 3021 mAvailProcessChanges.addAll(mPendingProcessChanges); 3022 mPendingProcessChanges.clear(); 3023 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3024 } 3025 3026 int i = mProcessObservers.beginBroadcast(); 3027 while (i > 0) { 3028 i--; 3029 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3030 if (observer != null) { 3031 try { 3032 for (int j=0; j<N; j++) { 3033 ProcessChangeItem item = mActiveProcessChanges[j]; 3034 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3035 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3036 + item.pid + " uid=" + item.uid + ": " 3037 + item.foregroundActivities); 3038 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3039 item.foregroundActivities); 3040 } 3041 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3042 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3043 + item.pid + " uid=" + item.uid + ": " + item.importance); 3044 observer.onImportanceChanged(item.pid, item.uid, 3045 item.importance); 3046 } 3047 } 3048 } catch (RemoteException e) { 3049 } 3050 } 3051 } 3052 mProcessObservers.finishBroadcast(); 3053 } 3054 3055 private void dispatchProcessDied(int pid, int uid) { 3056 int i = mProcessObservers.beginBroadcast(); 3057 while (i > 0) { 3058 i--; 3059 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3060 if (observer != null) { 3061 try { 3062 observer.onProcessDied(pid, uid); 3063 } catch (RemoteException e) { 3064 } 3065 } 3066 } 3067 mProcessObservers.finishBroadcast(); 3068 } 3069 3070 final void doPendingActivityLaunchesLocked(boolean doResume) { 3071 final int N = mPendingActivityLaunches.size(); 3072 if (N <= 0) { 3073 return; 3074 } 3075 for (int i=0; i<N; i++) { 3076 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3077 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3078 doResume && i == (N-1), null); 3079 } 3080 mPendingActivityLaunches.clear(); 3081 } 3082 3083 @Override 3084 public final int startActivity(IApplicationThread caller, String callingPackage, 3085 Intent intent, String resolvedType, IBinder resultTo, 3086 String resultWho, int requestCode, int startFlags, 3087 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3088 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3089 resultWho, requestCode, 3090 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3091 } 3092 3093 @Override 3094 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3095 Intent intent, String resolvedType, IBinder resultTo, 3096 String resultWho, int requestCode, int startFlags, 3097 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3098 enforceNotIsolatedCaller("startActivity"); 3099 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3100 false, true, "startActivity", null); 3101 // TODO: Switch to user app stacks here. 3102 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3103 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3104 null, null, options, userId, null); 3105 } 3106 3107 @Override 3108 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3109 Intent intent, String resolvedType, IBinder resultTo, 3110 String resultWho, int requestCode, int startFlags, String profileFile, 3111 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3112 enforceNotIsolatedCaller("startActivityAndWait"); 3113 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3114 false, true, "startActivityAndWait", null); 3115 WaitResult res = new WaitResult(); 3116 // TODO: Switch to user app stacks here. 3117 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3118 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3119 res, null, options, UserHandle.getCallingUserId(), null); 3120 return res; 3121 } 3122 3123 @Override 3124 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3125 Intent intent, String resolvedType, IBinder resultTo, 3126 String resultWho, int requestCode, int startFlags, Configuration config, 3127 Bundle options, int userId) { 3128 enforceNotIsolatedCaller("startActivityWithConfig"); 3129 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3130 false, true, "startActivityWithConfig", null); 3131 // TODO: Switch to user app stacks here. 3132 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3133 resolvedType, resultTo, resultWho, requestCode, startFlags, 3134 null, null, null, config, options, userId, null); 3135 return ret; 3136 } 3137 3138 @Override 3139 public int startActivityIntentSender(IApplicationThread caller, 3140 IntentSender intent, Intent fillInIntent, String resolvedType, 3141 IBinder resultTo, String resultWho, int requestCode, 3142 int flagsMask, int flagsValues, Bundle options) { 3143 enforceNotIsolatedCaller("startActivityIntentSender"); 3144 // Refuse possible leaked file descriptors 3145 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3146 throw new IllegalArgumentException("File descriptors passed in Intent"); 3147 } 3148 3149 IIntentSender sender = intent.getTarget(); 3150 if (!(sender instanceof PendingIntentRecord)) { 3151 throw new IllegalArgumentException("Bad PendingIntent object"); 3152 } 3153 3154 PendingIntentRecord pir = (PendingIntentRecord)sender; 3155 3156 synchronized (this) { 3157 // If this is coming from the currently resumed activity, it is 3158 // effectively saying that app switches are allowed at this point. 3159 final ActivityStack stack = getFocusedStack(); 3160 if (stack.mResumedActivity != null && 3161 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3162 mAppSwitchesAllowedTime = 0; 3163 } 3164 } 3165 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3166 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3167 return ret; 3168 } 3169 3170 @Override 3171 public boolean startNextMatchingActivity(IBinder callingActivity, 3172 Intent intent, Bundle options) { 3173 // Refuse possible leaked file descriptors 3174 if (intent != null && intent.hasFileDescriptors() == true) { 3175 throw new IllegalArgumentException("File descriptors passed in Intent"); 3176 } 3177 3178 synchronized (this) { 3179 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3180 if (r == null) { 3181 ActivityOptions.abort(options); 3182 return false; 3183 } 3184 if (r.app == null || r.app.thread == null) { 3185 // The caller is not running... d'oh! 3186 ActivityOptions.abort(options); 3187 return false; 3188 } 3189 intent = new Intent(intent); 3190 // The caller is not allowed to change the data. 3191 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3192 // And we are resetting to find the next component... 3193 intent.setComponent(null); 3194 3195 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3196 3197 ActivityInfo aInfo = null; 3198 try { 3199 List<ResolveInfo> resolves = 3200 AppGlobals.getPackageManager().queryIntentActivities( 3201 intent, r.resolvedType, 3202 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3203 UserHandle.getCallingUserId()); 3204 3205 // Look for the original activity in the list... 3206 final int N = resolves != null ? resolves.size() : 0; 3207 for (int i=0; i<N; i++) { 3208 ResolveInfo rInfo = resolves.get(i); 3209 if (rInfo.activityInfo.packageName.equals(r.packageName) 3210 && rInfo.activityInfo.name.equals(r.info.name)) { 3211 // We found the current one... the next matching is 3212 // after it. 3213 i++; 3214 if (i<N) { 3215 aInfo = resolves.get(i).activityInfo; 3216 } 3217 if (debug) { 3218 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3219 + "/" + r.info.name); 3220 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3221 + "/" + aInfo.name); 3222 } 3223 break; 3224 } 3225 } 3226 } catch (RemoteException e) { 3227 } 3228 3229 if (aInfo == null) { 3230 // Nobody who is next! 3231 ActivityOptions.abort(options); 3232 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3233 return false; 3234 } 3235 3236 intent.setComponent(new ComponentName( 3237 aInfo.applicationInfo.packageName, aInfo.name)); 3238 intent.setFlags(intent.getFlags()&~( 3239 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3240 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3241 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3242 Intent.FLAG_ACTIVITY_NEW_TASK)); 3243 3244 // Okay now we need to start the new activity, replacing the 3245 // currently running activity. This is a little tricky because 3246 // we want to start the new one as if the current one is finished, 3247 // but not finish the current one first so that there is no flicker. 3248 // And thus... 3249 final boolean wasFinishing = r.finishing; 3250 r.finishing = true; 3251 3252 // Propagate reply information over to the new activity. 3253 final ActivityRecord resultTo = r.resultTo; 3254 final String resultWho = r.resultWho; 3255 final int requestCode = r.requestCode; 3256 r.resultTo = null; 3257 if (resultTo != null) { 3258 resultTo.removeResultsLocked(r, resultWho, requestCode); 3259 } 3260 3261 final long origId = Binder.clearCallingIdentity(); 3262 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3263 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3264 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3265 options, false, null, null); 3266 Binder.restoreCallingIdentity(origId); 3267 3268 r.finishing = wasFinishing; 3269 if (res != ActivityManager.START_SUCCESS) { 3270 return false; 3271 } 3272 return true; 3273 } 3274 } 3275 3276 final int startActivityInPackage(int uid, String callingPackage, 3277 Intent intent, String resolvedType, IBinder resultTo, 3278 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3279 IActivityContainer container) { 3280 3281 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3282 false, true, "startActivityInPackage", null); 3283 3284 // TODO: Switch to user app stacks here. 3285 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3286 resultTo, resultWho, requestCode, startFlags, 3287 null, null, null, null, options, userId, container); 3288 return ret; 3289 } 3290 3291 @Override 3292 public final int startActivities(IApplicationThread caller, String callingPackage, 3293 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3294 int userId) { 3295 enforceNotIsolatedCaller("startActivities"); 3296 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3297 false, true, "startActivity", null); 3298 // TODO: Switch to user app stacks here. 3299 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3300 resolvedTypes, resultTo, options, userId); 3301 return ret; 3302 } 3303 3304 final int startActivitiesInPackage(int uid, String callingPackage, 3305 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3306 Bundle options, int userId) { 3307 3308 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3309 false, true, "startActivityInPackage", null); 3310 // TODO: Switch to user app stacks here. 3311 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3312 resultTo, options, userId); 3313 return ret; 3314 } 3315 3316 final void addRecentTaskLocked(TaskRecord task) { 3317 int N = mRecentTasks.size(); 3318 // Quick case: check if the top-most recent task is the same. 3319 if (N > 0 && mRecentTasks.get(0) == task) { 3320 return; 3321 } 3322 // Remove any existing entries that are the same kind of task. 3323 final Intent intent = task.intent; 3324 final boolean document = intent != null && intent.isDocument(); 3325 for (int i=0; i<N; i++) { 3326 TaskRecord tr = mRecentTasks.get(i); 3327 if (task != tr) { 3328 if (task.userId != tr.userId) { 3329 continue; 3330 } 3331 final Intent trIntent = tr.intent; 3332 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3333 (intent == null || !intent.filterEquals(trIntent))) { 3334 continue; 3335 } 3336 if (document || trIntent != null && trIntent.isDocument()) { 3337 // Document tasks do not match other tasks. 3338 continue; 3339 } 3340 } 3341 3342 // Either task and tr are the same or, their affinities match or their intents match 3343 // and neither of them is a document. 3344 tr.disposeThumbnail(); 3345 mRecentTasks.remove(i); 3346 i--; 3347 N--; 3348 if (task.intent == null) { 3349 // If the new recent task we are adding is not fully 3350 // specified, then replace it with the existing recent task. 3351 task = tr; 3352 } 3353 } 3354 if (N >= MAX_RECENT_TASKS) { 3355 mRecentTasks.remove(N-1).disposeThumbnail(); 3356 } 3357 mRecentTasks.add(0, task); 3358 } 3359 3360 @Override 3361 public void reportActivityFullyDrawn(IBinder token) { 3362 synchronized (this) { 3363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3364 if (r == null) { 3365 return; 3366 } 3367 r.reportFullyDrawnLocked(); 3368 } 3369 } 3370 3371 @Override 3372 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3373 synchronized (this) { 3374 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3375 if (r == null) { 3376 return; 3377 } 3378 final long origId = Binder.clearCallingIdentity(); 3379 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3380 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3381 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3382 if (config != null) { 3383 r.frozenBeforeDestroy = true; 3384 if (!updateConfigurationLocked(config, r, false, false)) { 3385 mStackSupervisor.resumeTopActivitiesLocked(); 3386 } 3387 } 3388 Binder.restoreCallingIdentity(origId); 3389 } 3390 } 3391 3392 @Override 3393 public int getRequestedOrientation(IBinder token) { 3394 synchronized (this) { 3395 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3396 if (r == null) { 3397 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3398 } 3399 return mWindowManager.getAppOrientation(r.appToken); 3400 } 3401 } 3402 3403 /** 3404 * This is the internal entry point for handling Activity.finish(). 3405 * 3406 * @param token The Binder token referencing the Activity we want to finish. 3407 * @param resultCode Result code, if any, from this Activity. 3408 * @param resultData Result data (Intent), if any, from this Activity. 3409 * 3410 * @return Returns true if the activity successfully finished, or false if it is still running. 3411 */ 3412 @Override 3413 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3414 // Refuse possible leaked file descriptors 3415 if (resultData != null && resultData.hasFileDescriptors() == true) { 3416 throw new IllegalArgumentException("File descriptors passed in Intent"); 3417 } 3418 3419 synchronized(this) { 3420 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3421 if (r == null) { 3422 return true; 3423 } 3424 if (mController != null) { 3425 // Find the first activity that is not finishing. 3426 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3427 if (next != null) { 3428 // ask watcher if this is allowed 3429 boolean resumeOK = true; 3430 try { 3431 resumeOK = mController.activityResuming(next.packageName); 3432 } catch (RemoteException e) { 3433 mController = null; 3434 Watchdog.getInstance().setActivityController(null); 3435 } 3436 3437 if (!resumeOK) { 3438 return false; 3439 } 3440 } 3441 } 3442 final long origId = Binder.clearCallingIdentity(); 3443 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3444 resultData, "app-request", true); 3445 Binder.restoreCallingIdentity(origId); 3446 return res; 3447 } 3448 } 3449 3450 @Override 3451 public final void finishHeavyWeightApp() { 3452 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3453 != PackageManager.PERMISSION_GRANTED) { 3454 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3455 + Binder.getCallingPid() 3456 + ", uid=" + Binder.getCallingUid() 3457 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3458 Slog.w(TAG, msg); 3459 throw new SecurityException(msg); 3460 } 3461 3462 synchronized(this) { 3463 if (mHeavyWeightProcess == null) { 3464 return; 3465 } 3466 3467 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3468 mHeavyWeightProcess.activities); 3469 for (int i=0; i<activities.size(); i++) { 3470 ActivityRecord r = activities.get(i); 3471 if (!r.finishing) { 3472 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3473 null, "finish-heavy", true); 3474 } 3475 } 3476 3477 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3478 mHeavyWeightProcess.userId, 0)); 3479 mHeavyWeightProcess = null; 3480 } 3481 } 3482 3483 @Override 3484 public void crashApplication(int uid, int initialPid, String packageName, 3485 String message) { 3486 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3487 != PackageManager.PERMISSION_GRANTED) { 3488 String msg = "Permission Denial: crashApplication() from pid=" 3489 + Binder.getCallingPid() 3490 + ", uid=" + Binder.getCallingUid() 3491 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3492 Slog.w(TAG, msg); 3493 throw new SecurityException(msg); 3494 } 3495 3496 synchronized(this) { 3497 ProcessRecord proc = null; 3498 3499 // Figure out which process to kill. We don't trust that initialPid 3500 // still has any relation to current pids, so must scan through the 3501 // list. 3502 synchronized (mPidsSelfLocked) { 3503 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3504 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3505 if (p.uid != uid) { 3506 continue; 3507 } 3508 if (p.pid == initialPid) { 3509 proc = p; 3510 break; 3511 } 3512 if (p.pkgList.containsKey(packageName)) { 3513 proc = p; 3514 } 3515 } 3516 } 3517 3518 if (proc == null) { 3519 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3520 + " initialPid=" + initialPid 3521 + " packageName=" + packageName); 3522 return; 3523 } 3524 3525 if (proc.thread != null) { 3526 if (proc.pid == Process.myPid()) { 3527 Log.w(TAG, "crashApplication: trying to crash self!"); 3528 return; 3529 } 3530 long ident = Binder.clearCallingIdentity(); 3531 try { 3532 proc.thread.scheduleCrash(message); 3533 } catch (RemoteException e) { 3534 } 3535 Binder.restoreCallingIdentity(ident); 3536 } 3537 } 3538 } 3539 3540 @Override 3541 public final void finishSubActivity(IBinder token, String resultWho, 3542 int requestCode) { 3543 synchronized(this) { 3544 final long origId = Binder.clearCallingIdentity(); 3545 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3546 if (r != null) { 3547 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3548 } 3549 Binder.restoreCallingIdentity(origId); 3550 } 3551 } 3552 3553 @Override 3554 public boolean finishActivityAffinity(IBinder token) { 3555 synchronized(this) { 3556 final long origId = Binder.clearCallingIdentity(); 3557 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3558 boolean res = false; 3559 if (r != null) { 3560 res = r.task.stack.finishActivityAffinityLocked(r); 3561 } 3562 Binder.restoreCallingIdentity(origId); 3563 return res; 3564 } 3565 } 3566 3567 @Override 3568 public boolean willActivityBeVisible(IBinder token) { 3569 synchronized(this) { 3570 ActivityStack stack = ActivityRecord.getStackLocked(token); 3571 if (stack != null) { 3572 return stack.willActivityBeVisibleLocked(token); 3573 } 3574 return false; 3575 } 3576 } 3577 3578 @Override 3579 public void overridePendingTransition(IBinder token, String packageName, 3580 int enterAnim, int exitAnim) { 3581 synchronized(this) { 3582 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3583 if (self == null) { 3584 return; 3585 } 3586 3587 final long origId = Binder.clearCallingIdentity(); 3588 3589 if (self.state == ActivityState.RESUMED 3590 || self.state == ActivityState.PAUSING) { 3591 mWindowManager.overridePendingAppTransition(packageName, 3592 enterAnim, exitAnim, null); 3593 } 3594 3595 Binder.restoreCallingIdentity(origId); 3596 } 3597 } 3598 3599 /** 3600 * Main function for removing an existing process from the activity manager 3601 * as a result of that process going away. Clears out all connections 3602 * to the process. 3603 */ 3604 private final void handleAppDiedLocked(ProcessRecord app, 3605 boolean restarting, boolean allowRestart) { 3606 int pid = app.pid; 3607 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3608 if (!restarting) { 3609 removeLruProcessLocked(app); 3610 if (pid > 0) { 3611 ProcessList.remove(pid); 3612 } 3613 } 3614 3615 if (mProfileProc == app) { 3616 clearProfilerLocked(); 3617 } 3618 3619 // Remove this application's activities from active lists. 3620 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3621 3622 app.activities.clear(); 3623 3624 if (app.instrumentationClass != null) { 3625 Slog.w(TAG, "Crash of app " + app.processName 3626 + " running instrumentation " + app.instrumentationClass); 3627 Bundle info = new Bundle(); 3628 info.putString("shortMsg", "Process crashed."); 3629 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3630 } 3631 3632 if (!restarting) { 3633 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3634 // If there was nothing to resume, and we are not already 3635 // restarting this process, but there is a visible activity that 3636 // is hosted by the process... then make sure all visible 3637 // activities are running, taking care of restarting this 3638 // process. 3639 if (hasVisibleActivities) { 3640 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3641 } 3642 } 3643 } 3644 } 3645 3646 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3647 IBinder threadBinder = thread.asBinder(); 3648 // Find the application record. 3649 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3650 ProcessRecord rec = mLruProcesses.get(i); 3651 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3652 return i; 3653 } 3654 } 3655 return -1; 3656 } 3657 3658 final ProcessRecord getRecordForAppLocked( 3659 IApplicationThread thread) { 3660 if (thread == null) { 3661 return null; 3662 } 3663 3664 int appIndex = getLRURecordIndexForAppLocked(thread); 3665 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3666 } 3667 3668 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3669 // If there are no longer any background processes running, 3670 // and the app that died was not running instrumentation, 3671 // then tell everyone we are now low on memory. 3672 boolean haveBg = false; 3673 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3674 ProcessRecord rec = mLruProcesses.get(i); 3675 if (rec.thread != null 3676 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3677 haveBg = true; 3678 break; 3679 } 3680 } 3681 3682 if (!haveBg) { 3683 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3684 if (doReport) { 3685 long now = SystemClock.uptimeMillis(); 3686 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3687 doReport = false; 3688 } else { 3689 mLastMemUsageReportTime = now; 3690 } 3691 } 3692 final ArrayList<ProcessMemInfo> memInfos 3693 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3694 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3695 long now = SystemClock.uptimeMillis(); 3696 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3697 ProcessRecord rec = mLruProcesses.get(i); 3698 if (rec == dyingProc || rec.thread == null) { 3699 continue; 3700 } 3701 if (doReport) { 3702 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3703 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3704 } 3705 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3706 // The low memory report is overriding any current 3707 // state for a GC request. Make sure to do 3708 // heavy/important/visible/foreground processes first. 3709 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3710 rec.lastRequestedGc = 0; 3711 } else { 3712 rec.lastRequestedGc = rec.lastLowMemory; 3713 } 3714 rec.reportLowMemory = true; 3715 rec.lastLowMemory = now; 3716 mProcessesToGc.remove(rec); 3717 addProcessToGcListLocked(rec); 3718 } 3719 } 3720 if (doReport) { 3721 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3722 mHandler.sendMessage(msg); 3723 } 3724 scheduleAppGcsLocked(); 3725 } 3726 } 3727 3728 final void appDiedLocked(ProcessRecord app, int pid, 3729 IApplicationThread thread) { 3730 3731 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3732 synchronized (stats) { 3733 stats.noteProcessDiedLocked(app.info.uid, pid); 3734 } 3735 3736 // Clean up already done if the process has been re-started. 3737 if (app.pid == pid && app.thread != null && 3738 app.thread.asBinder() == thread.asBinder()) { 3739 boolean doLowMem = app.instrumentationClass == null; 3740 boolean doOomAdj = doLowMem; 3741 if (!app.killedByAm) { 3742 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3743 + ") has died."); 3744 mAllowLowerMemLevel = true; 3745 } else { 3746 // Note that we always want to do oom adj to update our state with the 3747 // new number of procs. 3748 mAllowLowerMemLevel = false; 3749 doLowMem = false; 3750 } 3751 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3752 if (DEBUG_CLEANUP) Slog.v( 3753 TAG, "Dying app: " + app + ", pid: " + pid 3754 + ", thread: " + thread.asBinder()); 3755 handleAppDiedLocked(app, false, true); 3756 3757 if (doOomAdj) { 3758 updateOomAdjLocked(); 3759 } 3760 if (doLowMem) { 3761 doLowMemReportIfNeededLocked(app); 3762 } 3763 } else if (app.pid != pid) { 3764 // A new process has already been started. 3765 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3766 + ") has died and restarted (pid " + app.pid + ")."); 3767 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3768 } else if (DEBUG_PROCESSES) { 3769 Slog.d(TAG, "Received spurious death notification for thread " 3770 + thread.asBinder()); 3771 } 3772 } 3773 3774 /** 3775 * If a stack trace dump file is configured, dump process stack traces. 3776 * @param clearTraces causes the dump file to be erased prior to the new 3777 * traces being written, if true; when false, the new traces will be 3778 * appended to any existing file content. 3779 * @param firstPids of dalvik VM processes to dump stack traces for first 3780 * @param lastPids of dalvik VM processes to dump stack traces for last 3781 * @param nativeProcs optional list of native process names to dump stack crawls 3782 * @return file containing stack traces, or null if no dump file is configured 3783 */ 3784 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3785 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3786 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3787 if (tracesPath == null || tracesPath.length() == 0) { 3788 return null; 3789 } 3790 3791 File tracesFile = new File(tracesPath); 3792 try { 3793 File tracesDir = tracesFile.getParentFile(); 3794 if (!tracesDir.exists()) { 3795 tracesFile.mkdirs(); 3796 if (!SELinux.restorecon(tracesDir)) { 3797 return null; 3798 } 3799 } 3800 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3801 3802 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3803 tracesFile.createNewFile(); 3804 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3805 } catch (IOException e) { 3806 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3807 return null; 3808 } 3809 3810 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3811 return tracesFile; 3812 } 3813 3814 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3815 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3816 // Use a FileObserver to detect when traces finish writing. 3817 // The order of traces is considered important to maintain for legibility. 3818 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3819 @Override 3820 public synchronized void onEvent(int event, String path) { notify(); } 3821 }; 3822 3823 try { 3824 observer.startWatching(); 3825 3826 // First collect all of the stacks of the most important pids. 3827 if (firstPids != null) { 3828 try { 3829 int num = firstPids.size(); 3830 for (int i = 0; i < num; i++) { 3831 synchronized (observer) { 3832 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3833 observer.wait(200); // Wait for write-close, give up after 200msec 3834 } 3835 } 3836 } catch (InterruptedException e) { 3837 Log.wtf(TAG, e); 3838 } 3839 } 3840 3841 // Next collect the stacks of the native pids 3842 if (nativeProcs != null) { 3843 int[] pids = Process.getPidsForCommands(nativeProcs); 3844 if (pids != null) { 3845 for (int pid : pids) { 3846 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3847 } 3848 } 3849 } 3850 3851 // Lastly, measure CPU usage. 3852 if (processCpuTracker != null) { 3853 processCpuTracker.init(); 3854 System.gc(); 3855 processCpuTracker.update(); 3856 try { 3857 synchronized (processCpuTracker) { 3858 processCpuTracker.wait(500); // measure over 1/2 second. 3859 } 3860 } catch (InterruptedException e) { 3861 } 3862 processCpuTracker.update(); 3863 3864 // We'll take the stack crawls of just the top apps using CPU. 3865 final int N = processCpuTracker.countWorkingStats(); 3866 int numProcs = 0; 3867 for (int i=0; i<N && numProcs<5; i++) { 3868 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3869 if (lastPids.indexOfKey(stats.pid) >= 0) { 3870 numProcs++; 3871 try { 3872 synchronized (observer) { 3873 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3874 observer.wait(200); // Wait for write-close, give up after 200msec 3875 } 3876 } catch (InterruptedException e) { 3877 Log.wtf(TAG, e); 3878 } 3879 3880 } 3881 } 3882 } 3883 } finally { 3884 observer.stopWatching(); 3885 } 3886 } 3887 3888 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3889 if (true || IS_USER_BUILD) { 3890 return; 3891 } 3892 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3893 if (tracesPath == null || tracesPath.length() == 0) { 3894 return; 3895 } 3896 3897 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3898 StrictMode.allowThreadDiskWrites(); 3899 try { 3900 final File tracesFile = new File(tracesPath); 3901 final File tracesDir = tracesFile.getParentFile(); 3902 final File tracesTmp = new File(tracesDir, "__tmp__"); 3903 try { 3904 if (!tracesDir.exists()) { 3905 tracesFile.mkdirs(); 3906 if (!SELinux.restorecon(tracesDir.getPath())) { 3907 return; 3908 } 3909 } 3910 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3911 3912 if (tracesFile.exists()) { 3913 tracesTmp.delete(); 3914 tracesFile.renameTo(tracesTmp); 3915 } 3916 StringBuilder sb = new StringBuilder(); 3917 Time tobj = new Time(); 3918 tobj.set(System.currentTimeMillis()); 3919 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3920 sb.append(": "); 3921 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3922 sb.append(" since "); 3923 sb.append(msg); 3924 FileOutputStream fos = new FileOutputStream(tracesFile); 3925 fos.write(sb.toString().getBytes()); 3926 if (app == null) { 3927 fos.write("\n*** No application process!".getBytes()); 3928 } 3929 fos.close(); 3930 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3931 } catch (IOException e) { 3932 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3933 return; 3934 } 3935 3936 if (app != null) { 3937 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3938 firstPids.add(app.pid); 3939 dumpStackTraces(tracesPath, firstPids, null, null, null); 3940 } 3941 3942 File lastTracesFile = null; 3943 File curTracesFile = null; 3944 for (int i=9; i>=0; i--) { 3945 String name = String.format(Locale.US, "slow%02d.txt", i); 3946 curTracesFile = new File(tracesDir, name); 3947 if (curTracesFile.exists()) { 3948 if (lastTracesFile != null) { 3949 curTracesFile.renameTo(lastTracesFile); 3950 } else { 3951 curTracesFile.delete(); 3952 } 3953 } 3954 lastTracesFile = curTracesFile; 3955 } 3956 tracesFile.renameTo(curTracesFile); 3957 if (tracesTmp.exists()) { 3958 tracesTmp.renameTo(tracesFile); 3959 } 3960 } finally { 3961 StrictMode.setThreadPolicy(oldPolicy); 3962 } 3963 } 3964 3965 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3966 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3967 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3968 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3969 3970 if (mController != null) { 3971 try { 3972 // 0 == continue, -1 = kill process immediately 3973 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3974 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3975 } catch (RemoteException e) { 3976 mController = null; 3977 Watchdog.getInstance().setActivityController(null); 3978 } 3979 } 3980 3981 long anrTime = SystemClock.uptimeMillis(); 3982 if (MONITOR_CPU_USAGE) { 3983 updateCpuStatsNow(); 3984 } 3985 3986 synchronized (this) { 3987 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3988 if (mShuttingDown) { 3989 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3990 return; 3991 } else if (app.notResponding) { 3992 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3993 return; 3994 } else if (app.crashing) { 3995 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3996 return; 3997 } 3998 3999 // In case we come through here for the same app before completing 4000 // this one, mark as anring now so we will bail out. 4001 app.notResponding = true; 4002 4003 // Log the ANR to the event log. 4004 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4005 app.processName, app.info.flags, annotation); 4006 4007 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4008 firstPids.add(app.pid); 4009 4010 int parentPid = app.pid; 4011 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4012 if (parentPid != app.pid) firstPids.add(parentPid); 4013 4014 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4015 4016 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4017 ProcessRecord r = mLruProcesses.get(i); 4018 if (r != null && r.thread != null) { 4019 int pid = r.pid; 4020 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4021 if (r.persistent) { 4022 firstPids.add(pid); 4023 } else { 4024 lastPids.put(pid, Boolean.TRUE); 4025 } 4026 } 4027 } 4028 } 4029 } 4030 4031 // Log the ANR to the main log. 4032 StringBuilder info = new StringBuilder(); 4033 info.setLength(0); 4034 info.append("ANR in ").append(app.processName); 4035 if (activity != null && activity.shortComponentName != null) { 4036 info.append(" (").append(activity.shortComponentName).append(")"); 4037 } 4038 info.append("\n"); 4039 info.append("PID: ").append(app.pid).append("\n"); 4040 if (annotation != null) { 4041 info.append("Reason: ").append(annotation).append("\n"); 4042 } 4043 if (parent != null && parent != activity) { 4044 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4045 } 4046 4047 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4048 4049 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4050 NATIVE_STACKS_OF_INTEREST); 4051 4052 String cpuInfo = null; 4053 if (MONITOR_CPU_USAGE) { 4054 updateCpuStatsNow(); 4055 synchronized (mProcessCpuThread) { 4056 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4057 } 4058 info.append(processCpuTracker.printCurrentLoad()); 4059 info.append(cpuInfo); 4060 } 4061 4062 info.append(processCpuTracker.printCurrentState(anrTime)); 4063 4064 Slog.e(TAG, info.toString()); 4065 if (tracesFile == null) { 4066 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4067 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4068 } 4069 4070 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4071 cpuInfo, tracesFile, null); 4072 4073 if (mController != null) { 4074 try { 4075 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4076 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4077 if (res != 0) { 4078 if (res < 0 && app.pid != MY_PID) { 4079 Process.killProcess(app.pid); 4080 } else { 4081 synchronized (this) { 4082 mServices.scheduleServiceTimeoutLocked(app); 4083 } 4084 } 4085 return; 4086 } 4087 } catch (RemoteException e) { 4088 mController = null; 4089 Watchdog.getInstance().setActivityController(null); 4090 } 4091 } 4092 4093 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4094 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4095 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4096 4097 synchronized (this) { 4098 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4099 killUnneededProcessLocked(app, "background ANR"); 4100 return; 4101 } 4102 4103 // Set the app's notResponding state, and look up the errorReportReceiver 4104 makeAppNotRespondingLocked(app, 4105 activity != null ? activity.shortComponentName : null, 4106 annotation != null ? "ANR " + annotation : "ANR", 4107 info.toString()); 4108 4109 // Bring up the infamous App Not Responding dialog 4110 Message msg = Message.obtain(); 4111 HashMap<String, Object> map = new HashMap<String, Object>(); 4112 msg.what = SHOW_NOT_RESPONDING_MSG; 4113 msg.obj = map; 4114 msg.arg1 = aboveSystem ? 1 : 0; 4115 map.put("app", app); 4116 if (activity != null) { 4117 map.put("activity", activity); 4118 } 4119 4120 mHandler.sendMessage(msg); 4121 } 4122 } 4123 4124 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4125 if (!mLaunchWarningShown) { 4126 mLaunchWarningShown = true; 4127 mHandler.post(new Runnable() { 4128 @Override 4129 public void run() { 4130 synchronized (ActivityManagerService.this) { 4131 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4132 d.show(); 4133 mHandler.postDelayed(new Runnable() { 4134 @Override 4135 public void run() { 4136 synchronized (ActivityManagerService.this) { 4137 d.dismiss(); 4138 mLaunchWarningShown = false; 4139 } 4140 } 4141 }, 4000); 4142 } 4143 } 4144 }); 4145 } 4146 } 4147 4148 @Override 4149 public boolean clearApplicationUserData(final String packageName, 4150 final IPackageDataObserver observer, int userId) { 4151 enforceNotIsolatedCaller("clearApplicationUserData"); 4152 int uid = Binder.getCallingUid(); 4153 int pid = Binder.getCallingPid(); 4154 userId = handleIncomingUser(pid, uid, 4155 userId, false, true, "clearApplicationUserData", null); 4156 long callingId = Binder.clearCallingIdentity(); 4157 try { 4158 IPackageManager pm = AppGlobals.getPackageManager(); 4159 int pkgUid = -1; 4160 synchronized(this) { 4161 try { 4162 pkgUid = pm.getPackageUid(packageName, userId); 4163 } catch (RemoteException e) { 4164 } 4165 if (pkgUid == -1) { 4166 Slog.w(TAG, "Invalid packageName: " + packageName); 4167 if (observer != null) { 4168 try { 4169 observer.onRemoveCompleted(packageName, false); 4170 } catch (RemoteException e) { 4171 Slog.i(TAG, "Observer no longer exists."); 4172 } 4173 } 4174 return false; 4175 } 4176 if (uid == pkgUid || checkComponentPermission( 4177 android.Manifest.permission.CLEAR_APP_USER_DATA, 4178 pid, uid, -1, true) 4179 == PackageManager.PERMISSION_GRANTED) { 4180 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4181 } else { 4182 throw new SecurityException("PID " + pid + " does not have permission " 4183 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4184 + " of package " + packageName); 4185 } 4186 } 4187 4188 try { 4189 // Clear application user data 4190 pm.clearApplicationUserData(packageName, observer, userId); 4191 4192 // Remove all permissions granted from/to this package 4193 removeUriPermissionsForPackageLocked(packageName, userId, true); 4194 4195 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4196 Uri.fromParts("package", packageName, null)); 4197 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4198 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4199 null, null, 0, null, null, null, false, false, userId); 4200 } catch (RemoteException e) { 4201 } 4202 } finally { 4203 Binder.restoreCallingIdentity(callingId); 4204 } 4205 return true; 4206 } 4207 4208 @Override 4209 public void killBackgroundProcesses(final String packageName, int userId) { 4210 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4211 != PackageManager.PERMISSION_GRANTED && 4212 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4213 != PackageManager.PERMISSION_GRANTED) { 4214 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4215 + Binder.getCallingPid() 4216 + ", uid=" + Binder.getCallingUid() 4217 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4218 Slog.w(TAG, msg); 4219 throw new SecurityException(msg); 4220 } 4221 4222 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4223 userId, true, true, "killBackgroundProcesses", null); 4224 long callingId = Binder.clearCallingIdentity(); 4225 try { 4226 IPackageManager pm = AppGlobals.getPackageManager(); 4227 synchronized(this) { 4228 int appId = -1; 4229 try { 4230 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4231 } catch (RemoteException e) { 4232 } 4233 if (appId == -1) { 4234 Slog.w(TAG, "Invalid packageName: " + packageName); 4235 return; 4236 } 4237 killPackageProcessesLocked(packageName, appId, userId, 4238 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4239 } 4240 } finally { 4241 Binder.restoreCallingIdentity(callingId); 4242 } 4243 } 4244 4245 @Override 4246 public void killAllBackgroundProcesses() { 4247 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4248 != PackageManager.PERMISSION_GRANTED) { 4249 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4250 + Binder.getCallingPid() 4251 + ", uid=" + Binder.getCallingUid() 4252 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4253 Slog.w(TAG, msg); 4254 throw new SecurityException(msg); 4255 } 4256 4257 long callingId = Binder.clearCallingIdentity(); 4258 try { 4259 synchronized(this) { 4260 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4261 final int NP = mProcessNames.getMap().size(); 4262 for (int ip=0; ip<NP; ip++) { 4263 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4264 final int NA = apps.size(); 4265 for (int ia=0; ia<NA; ia++) { 4266 ProcessRecord app = apps.valueAt(ia); 4267 if (app.persistent) { 4268 // we don't kill persistent processes 4269 continue; 4270 } 4271 if (app.removed) { 4272 procs.add(app); 4273 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4274 app.removed = true; 4275 procs.add(app); 4276 } 4277 } 4278 } 4279 4280 int N = procs.size(); 4281 for (int i=0; i<N; i++) { 4282 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4283 } 4284 mAllowLowerMemLevel = true; 4285 updateOomAdjLocked(); 4286 doLowMemReportIfNeededLocked(null); 4287 } 4288 } finally { 4289 Binder.restoreCallingIdentity(callingId); 4290 } 4291 } 4292 4293 @Override 4294 public void forceStopPackage(final String packageName, int userId) { 4295 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4296 != PackageManager.PERMISSION_GRANTED) { 4297 String msg = "Permission Denial: forceStopPackage() from pid=" 4298 + Binder.getCallingPid() 4299 + ", uid=" + Binder.getCallingUid() 4300 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4301 Slog.w(TAG, msg); 4302 throw new SecurityException(msg); 4303 } 4304 final int callingPid = Binder.getCallingPid(); 4305 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4306 userId, true, true, "forceStopPackage", null); 4307 long callingId = Binder.clearCallingIdentity(); 4308 try { 4309 IPackageManager pm = AppGlobals.getPackageManager(); 4310 synchronized(this) { 4311 int[] users = userId == UserHandle.USER_ALL 4312 ? getUsersLocked() : new int[] { userId }; 4313 for (int user : users) { 4314 int pkgUid = -1; 4315 try { 4316 pkgUid = pm.getPackageUid(packageName, user); 4317 } catch (RemoteException e) { 4318 } 4319 if (pkgUid == -1) { 4320 Slog.w(TAG, "Invalid packageName: " + packageName); 4321 continue; 4322 } 4323 try { 4324 pm.setPackageStoppedState(packageName, true, user); 4325 } catch (RemoteException e) { 4326 } catch (IllegalArgumentException e) { 4327 Slog.w(TAG, "Failed trying to unstop package " 4328 + packageName + ": " + e); 4329 } 4330 if (isUserRunningLocked(user, false)) { 4331 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4332 } 4333 } 4334 } 4335 } finally { 4336 Binder.restoreCallingIdentity(callingId); 4337 } 4338 } 4339 4340 /* 4341 * The pkg name and app id have to be specified. 4342 */ 4343 @Override 4344 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4345 if (pkg == null) { 4346 return; 4347 } 4348 // Make sure the uid is valid. 4349 if (appid < 0) { 4350 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4351 return; 4352 } 4353 int callerUid = Binder.getCallingUid(); 4354 // Only the system server can kill an application 4355 if (callerUid == Process.SYSTEM_UID) { 4356 // Post an aysnc message to kill the application 4357 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4358 msg.arg1 = appid; 4359 msg.arg2 = 0; 4360 Bundle bundle = new Bundle(); 4361 bundle.putString("pkg", pkg); 4362 bundle.putString("reason", reason); 4363 msg.obj = bundle; 4364 mHandler.sendMessage(msg); 4365 } else { 4366 throw new SecurityException(callerUid + " cannot kill pkg: " + 4367 pkg); 4368 } 4369 } 4370 4371 @Override 4372 public void closeSystemDialogs(String reason) { 4373 enforceNotIsolatedCaller("closeSystemDialogs"); 4374 4375 final int pid = Binder.getCallingPid(); 4376 final int uid = Binder.getCallingUid(); 4377 final long origId = Binder.clearCallingIdentity(); 4378 try { 4379 synchronized (this) { 4380 // Only allow this from foreground processes, so that background 4381 // applications can't abuse it to prevent system UI from being shown. 4382 if (uid >= Process.FIRST_APPLICATION_UID) { 4383 ProcessRecord proc; 4384 synchronized (mPidsSelfLocked) { 4385 proc = mPidsSelfLocked.get(pid); 4386 } 4387 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4388 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4389 + " from background process " + proc); 4390 return; 4391 } 4392 } 4393 closeSystemDialogsLocked(reason); 4394 } 4395 } finally { 4396 Binder.restoreCallingIdentity(origId); 4397 } 4398 } 4399 4400 void closeSystemDialogsLocked(String reason) { 4401 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4402 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4403 | Intent.FLAG_RECEIVER_FOREGROUND); 4404 if (reason != null) { 4405 intent.putExtra("reason", reason); 4406 } 4407 mWindowManager.closeSystemDialogs(reason); 4408 4409 mStackSupervisor.closeSystemDialogsLocked(); 4410 4411 broadcastIntentLocked(null, null, intent, null, 4412 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4413 Process.SYSTEM_UID, UserHandle.USER_ALL); 4414 } 4415 4416 @Override 4417 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4418 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4419 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4420 for (int i=pids.length-1; i>=0; i--) { 4421 ProcessRecord proc; 4422 int oomAdj; 4423 synchronized (this) { 4424 synchronized (mPidsSelfLocked) { 4425 proc = mPidsSelfLocked.get(pids[i]); 4426 oomAdj = proc != null ? proc.setAdj : 0; 4427 } 4428 } 4429 infos[i] = new Debug.MemoryInfo(); 4430 Debug.getMemoryInfo(pids[i], infos[i]); 4431 if (proc != null) { 4432 synchronized (this) { 4433 if (proc.thread != null && proc.setAdj == oomAdj) { 4434 // Record this for posterity if the process has been stable. 4435 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4436 infos[i].getTotalUss(), false, proc.pkgList); 4437 } 4438 } 4439 } 4440 } 4441 return infos; 4442 } 4443 4444 @Override 4445 public long[] getProcessPss(int[] pids) { 4446 enforceNotIsolatedCaller("getProcessPss"); 4447 long[] pss = new long[pids.length]; 4448 for (int i=pids.length-1; i>=0; i--) { 4449 ProcessRecord proc; 4450 int oomAdj; 4451 synchronized (this) { 4452 synchronized (mPidsSelfLocked) { 4453 proc = mPidsSelfLocked.get(pids[i]); 4454 oomAdj = proc != null ? proc.setAdj : 0; 4455 } 4456 } 4457 long[] tmpUss = new long[1]; 4458 pss[i] = Debug.getPss(pids[i], tmpUss); 4459 if (proc != null) { 4460 synchronized (this) { 4461 if (proc.thread != null && proc.setAdj == oomAdj) { 4462 // Record this for posterity if the process has been stable. 4463 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4464 } 4465 } 4466 } 4467 } 4468 return pss; 4469 } 4470 4471 @Override 4472 public void killApplicationProcess(String processName, int uid) { 4473 if (processName == null) { 4474 return; 4475 } 4476 4477 int callerUid = Binder.getCallingUid(); 4478 // Only the system server can kill an application 4479 if (callerUid == Process.SYSTEM_UID) { 4480 synchronized (this) { 4481 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4482 if (app != null && app.thread != null) { 4483 try { 4484 app.thread.scheduleSuicide(); 4485 } catch (RemoteException e) { 4486 // If the other end already died, then our work here is done. 4487 } 4488 } else { 4489 Slog.w(TAG, "Process/uid not found attempting kill of " 4490 + processName + " / " + uid); 4491 } 4492 } 4493 } else { 4494 throw new SecurityException(callerUid + " cannot kill app process: " + 4495 processName); 4496 } 4497 } 4498 4499 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4500 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4501 false, true, false, false, UserHandle.getUserId(uid), reason); 4502 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4503 Uri.fromParts("package", packageName, null)); 4504 if (!mProcessesReady) { 4505 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4506 | Intent.FLAG_RECEIVER_FOREGROUND); 4507 } 4508 intent.putExtra(Intent.EXTRA_UID, uid); 4509 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4510 broadcastIntentLocked(null, null, intent, 4511 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4512 false, false, 4513 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4514 } 4515 4516 private void forceStopUserLocked(int userId, String reason) { 4517 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4518 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4519 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4520 | Intent.FLAG_RECEIVER_FOREGROUND); 4521 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4522 broadcastIntentLocked(null, null, intent, 4523 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4524 false, false, 4525 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4526 } 4527 4528 private final boolean killPackageProcessesLocked(String packageName, int appId, 4529 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4530 boolean doit, boolean evenPersistent, String reason) { 4531 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4532 4533 // Remove all processes this package may have touched: all with the 4534 // same UID (except for the system or root user), and all whose name 4535 // matches the package name. 4536 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4537 final int NP = mProcessNames.getMap().size(); 4538 for (int ip=0; ip<NP; ip++) { 4539 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4540 final int NA = apps.size(); 4541 for (int ia=0; ia<NA; ia++) { 4542 ProcessRecord app = apps.valueAt(ia); 4543 if (app.persistent && !evenPersistent) { 4544 // we don't kill persistent processes 4545 continue; 4546 } 4547 if (app.removed) { 4548 if (doit) { 4549 procs.add(app); 4550 } 4551 continue; 4552 } 4553 4554 // Skip process if it doesn't meet our oom adj requirement. 4555 if (app.setAdj < minOomAdj) { 4556 continue; 4557 } 4558 4559 // If no package is specified, we call all processes under the 4560 // give user id. 4561 if (packageName == null) { 4562 if (app.userId != userId) { 4563 continue; 4564 } 4565 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4566 continue; 4567 } 4568 // Package has been specified, we want to hit all processes 4569 // that match it. We need to qualify this by the processes 4570 // that are running under the specified app and user ID. 4571 } else { 4572 if (UserHandle.getAppId(app.uid) != appId) { 4573 continue; 4574 } 4575 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4576 continue; 4577 } 4578 if (!app.pkgList.containsKey(packageName)) { 4579 continue; 4580 } 4581 } 4582 4583 // Process has passed all conditions, kill it! 4584 if (!doit) { 4585 return true; 4586 } 4587 app.removed = true; 4588 procs.add(app); 4589 } 4590 } 4591 4592 int N = procs.size(); 4593 for (int i=0; i<N; i++) { 4594 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4595 } 4596 updateOomAdjLocked(); 4597 return N > 0; 4598 } 4599 4600 private final boolean forceStopPackageLocked(String name, int appId, 4601 boolean callerWillRestart, boolean purgeCache, boolean doit, 4602 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4603 int i; 4604 int N; 4605 4606 if (userId == UserHandle.USER_ALL && name == null) { 4607 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4608 } 4609 4610 if (appId < 0 && name != null) { 4611 try { 4612 appId = UserHandle.getAppId( 4613 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4614 } catch (RemoteException e) { 4615 } 4616 } 4617 4618 if (doit) { 4619 if (name != null) { 4620 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4621 + " user=" + userId + ": " + reason); 4622 } else { 4623 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4624 } 4625 4626 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4627 for (int ip=pmap.size()-1; ip>=0; ip--) { 4628 SparseArray<Long> ba = pmap.valueAt(ip); 4629 for (i=ba.size()-1; i>=0; i--) { 4630 boolean remove = false; 4631 final int entUid = ba.keyAt(i); 4632 if (name != null) { 4633 if (userId == UserHandle.USER_ALL) { 4634 if (UserHandle.getAppId(entUid) == appId) { 4635 remove = true; 4636 } 4637 } else { 4638 if (entUid == UserHandle.getUid(userId, appId)) { 4639 remove = true; 4640 } 4641 } 4642 } else if (UserHandle.getUserId(entUid) == userId) { 4643 remove = true; 4644 } 4645 if (remove) { 4646 ba.removeAt(i); 4647 } 4648 } 4649 if (ba.size() == 0) { 4650 pmap.removeAt(ip); 4651 } 4652 } 4653 } 4654 4655 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4656 -100, callerWillRestart, true, doit, evenPersistent, 4657 name == null ? ("stop user " + userId) : ("stop " + name)); 4658 4659 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4660 if (!doit) { 4661 return true; 4662 } 4663 didSomething = true; 4664 } 4665 4666 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4667 if (!doit) { 4668 return true; 4669 } 4670 didSomething = true; 4671 } 4672 4673 if (name == null) { 4674 // Remove all sticky broadcasts from this user. 4675 mStickyBroadcasts.remove(userId); 4676 } 4677 4678 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4679 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4680 userId, providers)) { 4681 if (!doit) { 4682 return true; 4683 } 4684 didSomething = true; 4685 } 4686 N = providers.size(); 4687 for (i=0; i<N; i++) { 4688 removeDyingProviderLocked(null, providers.get(i), true); 4689 } 4690 4691 // Remove transient permissions granted from/to this package/user 4692 removeUriPermissionsForPackageLocked(name, userId, false); 4693 4694 if (name == null || uninstalling) { 4695 // Remove pending intents. For now we only do this when force 4696 // stopping users, because we have some problems when doing this 4697 // for packages -- app widgets are not currently cleaned up for 4698 // such packages, so they can be left with bad pending intents. 4699 if (mIntentSenderRecords.size() > 0) { 4700 Iterator<WeakReference<PendingIntentRecord>> it 4701 = mIntentSenderRecords.values().iterator(); 4702 while (it.hasNext()) { 4703 WeakReference<PendingIntentRecord> wpir = it.next(); 4704 if (wpir == null) { 4705 it.remove(); 4706 continue; 4707 } 4708 PendingIntentRecord pir = wpir.get(); 4709 if (pir == null) { 4710 it.remove(); 4711 continue; 4712 } 4713 if (name == null) { 4714 // Stopping user, remove all objects for the user. 4715 if (pir.key.userId != userId) { 4716 // Not the same user, skip it. 4717 continue; 4718 } 4719 } else { 4720 if (UserHandle.getAppId(pir.uid) != appId) { 4721 // Different app id, skip it. 4722 continue; 4723 } 4724 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4725 // Different user, skip it. 4726 continue; 4727 } 4728 if (!pir.key.packageName.equals(name)) { 4729 // Different package, skip it. 4730 continue; 4731 } 4732 } 4733 if (!doit) { 4734 return true; 4735 } 4736 didSomething = true; 4737 it.remove(); 4738 pir.canceled = true; 4739 if (pir.key.activity != null) { 4740 pir.key.activity.pendingResults.remove(pir.ref); 4741 } 4742 } 4743 } 4744 } 4745 4746 if (doit) { 4747 if (purgeCache && name != null) { 4748 AttributeCache ac = AttributeCache.instance(); 4749 if (ac != null) { 4750 ac.removePackage(name); 4751 } 4752 } 4753 if (mBooted) { 4754 mStackSupervisor.resumeTopActivitiesLocked(); 4755 mStackSupervisor.scheduleIdleLocked(); 4756 } 4757 } 4758 4759 return didSomething; 4760 } 4761 4762 private final boolean removeProcessLocked(ProcessRecord app, 4763 boolean callerWillRestart, boolean allowRestart, String reason) { 4764 final String name = app.processName; 4765 final int uid = app.uid; 4766 if (DEBUG_PROCESSES) Slog.d( 4767 TAG, "Force removing proc " + app.toShortString() + " (" + name 4768 + "/" + uid + ")"); 4769 4770 mProcessNames.remove(name, uid); 4771 mIsolatedProcesses.remove(app.uid); 4772 if (mHeavyWeightProcess == app) { 4773 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4774 mHeavyWeightProcess.userId, 0)); 4775 mHeavyWeightProcess = null; 4776 } 4777 boolean needRestart = false; 4778 if (app.pid > 0 && app.pid != MY_PID) { 4779 int pid = app.pid; 4780 synchronized (mPidsSelfLocked) { 4781 mPidsSelfLocked.remove(pid); 4782 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4783 } 4784 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4785 app.processName, app.info.uid); 4786 if (app.isolated) { 4787 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4788 } 4789 killUnneededProcessLocked(app, reason); 4790 handleAppDiedLocked(app, true, allowRestart); 4791 removeLruProcessLocked(app); 4792 4793 if (app.persistent && !app.isolated) { 4794 if (!callerWillRestart) { 4795 addAppLocked(app.info, false); 4796 } else { 4797 needRestart = true; 4798 } 4799 } 4800 } else { 4801 mRemovedProcesses.add(app); 4802 } 4803 4804 return needRestart; 4805 } 4806 4807 private final void processStartTimedOutLocked(ProcessRecord app) { 4808 final int pid = app.pid; 4809 boolean gone = false; 4810 synchronized (mPidsSelfLocked) { 4811 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4812 if (knownApp != null && knownApp.thread == null) { 4813 mPidsSelfLocked.remove(pid); 4814 gone = true; 4815 } 4816 } 4817 4818 if (gone) { 4819 Slog.w(TAG, "Process " + app + " failed to attach"); 4820 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4821 pid, app.uid, app.processName); 4822 mProcessNames.remove(app.processName, app.uid); 4823 mIsolatedProcesses.remove(app.uid); 4824 if (mHeavyWeightProcess == app) { 4825 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4826 mHeavyWeightProcess.userId, 0)); 4827 mHeavyWeightProcess = null; 4828 } 4829 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4830 app.processName, app.info.uid); 4831 if (app.isolated) { 4832 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4833 } 4834 // Take care of any launching providers waiting for this process. 4835 checkAppInLaunchingProvidersLocked(app, true); 4836 // Take care of any services that are waiting for the process. 4837 mServices.processStartTimedOutLocked(app); 4838 killUnneededProcessLocked(app, "start timeout"); 4839 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4840 Slog.w(TAG, "Unattached app died before backup, skipping"); 4841 try { 4842 IBackupManager bm = IBackupManager.Stub.asInterface( 4843 ServiceManager.getService(Context.BACKUP_SERVICE)); 4844 bm.agentDisconnected(app.info.packageName); 4845 } catch (RemoteException e) { 4846 // Can't happen; the backup manager is local 4847 } 4848 } 4849 if (isPendingBroadcastProcessLocked(pid)) { 4850 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4851 skipPendingBroadcastLocked(pid); 4852 } 4853 } else { 4854 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4855 } 4856 } 4857 4858 private final boolean attachApplicationLocked(IApplicationThread thread, 4859 int pid) { 4860 4861 // Find the application record that is being attached... either via 4862 // the pid if we are running in multiple processes, or just pull the 4863 // next app record if we are emulating process with anonymous threads. 4864 ProcessRecord app; 4865 if (pid != MY_PID && pid >= 0) { 4866 synchronized (mPidsSelfLocked) { 4867 app = mPidsSelfLocked.get(pid); 4868 } 4869 } else { 4870 app = null; 4871 } 4872 4873 if (app == null) { 4874 Slog.w(TAG, "No pending application record for pid " + pid 4875 + " (IApplicationThread " + thread + "); dropping process"); 4876 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4877 if (pid > 0 && pid != MY_PID) { 4878 Process.killProcessQuiet(pid); 4879 } else { 4880 try { 4881 thread.scheduleExit(); 4882 } catch (Exception e) { 4883 // Ignore exceptions. 4884 } 4885 } 4886 return false; 4887 } 4888 4889 // If this application record is still attached to a previous 4890 // process, clean it up now. 4891 if (app.thread != null) { 4892 handleAppDiedLocked(app, true, true); 4893 } 4894 4895 // Tell the process all about itself. 4896 4897 if (localLOGV) Slog.v( 4898 TAG, "Binding process pid " + pid + " to record " + app); 4899 4900 final String processName = app.processName; 4901 try { 4902 AppDeathRecipient adr = new AppDeathRecipient( 4903 app, pid, thread); 4904 thread.asBinder().linkToDeath(adr, 0); 4905 app.deathRecipient = adr; 4906 } catch (RemoteException e) { 4907 app.resetPackageList(mProcessStats); 4908 startProcessLocked(app, "link fail", processName); 4909 return false; 4910 } 4911 4912 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4913 4914 app.makeActive(thread, mProcessStats); 4915 app.curAdj = app.setAdj = -100; 4916 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4917 app.forcingToForeground = null; 4918 updateProcessForegroundLocked(app, false, false); 4919 app.hasShownUi = false; 4920 app.debugging = false; 4921 app.cached = false; 4922 4923 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4924 4925 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4926 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4927 4928 if (!normalMode) { 4929 Slog.i(TAG, "Launching preboot mode app: " + app); 4930 } 4931 4932 if (localLOGV) Slog.v( 4933 TAG, "New app record " + app 4934 + " thread=" + thread.asBinder() + " pid=" + pid); 4935 try { 4936 int testMode = IApplicationThread.DEBUG_OFF; 4937 if (mDebugApp != null && mDebugApp.equals(processName)) { 4938 testMode = mWaitForDebugger 4939 ? IApplicationThread.DEBUG_WAIT 4940 : IApplicationThread.DEBUG_ON; 4941 app.debugging = true; 4942 if (mDebugTransient) { 4943 mDebugApp = mOrigDebugApp; 4944 mWaitForDebugger = mOrigWaitForDebugger; 4945 } 4946 } 4947 String profileFile = app.instrumentationProfileFile; 4948 ParcelFileDescriptor profileFd = null; 4949 boolean profileAutoStop = false; 4950 if (mProfileApp != null && mProfileApp.equals(processName)) { 4951 mProfileProc = app; 4952 profileFile = mProfileFile; 4953 profileFd = mProfileFd; 4954 profileAutoStop = mAutoStopProfiler; 4955 } 4956 boolean enableOpenGlTrace = false; 4957 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4958 enableOpenGlTrace = true; 4959 mOpenGlTraceApp = null; 4960 } 4961 4962 // If the app is being launched for restore or full backup, set it up specially 4963 boolean isRestrictedBackupMode = false; 4964 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4965 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4966 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4967 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4968 } 4969 4970 ensurePackageDexOpt(app.instrumentationInfo != null 4971 ? app.instrumentationInfo.packageName 4972 : app.info.packageName); 4973 if (app.instrumentationClass != null) { 4974 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4975 } 4976 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4977 + processName + " with config " + mConfiguration); 4978 ApplicationInfo appInfo = app.instrumentationInfo != null 4979 ? app.instrumentationInfo : app.info; 4980 app.compat = compatibilityInfoForPackageLocked(appInfo); 4981 if (profileFd != null) { 4982 profileFd = profileFd.dup(); 4983 } 4984 thread.bindApplication(processName, appInfo, providers, 4985 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4986 app.instrumentationArguments, app.instrumentationWatcher, 4987 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4988 isRestrictedBackupMode || !normalMode, app.persistent, 4989 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4990 mCoreSettingsObserver.getCoreSettingsLocked()); 4991 updateLruProcessLocked(app, false, null); 4992 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4993 } catch (Exception e) { 4994 // todo: Yikes! What should we do? For now we will try to 4995 // start another process, but that could easily get us in 4996 // an infinite loop of restarting processes... 4997 Slog.w(TAG, "Exception thrown during bind!", e); 4998 4999 app.resetPackageList(mProcessStats); 5000 app.unlinkDeathRecipient(); 5001 startProcessLocked(app, "bind fail", processName); 5002 return false; 5003 } 5004 5005 // Remove this record from the list of starting applications. 5006 mPersistentStartingProcesses.remove(app); 5007 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5008 "Attach application locked removing on hold: " + app); 5009 mProcessesOnHold.remove(app); 5010 5011 boolean badApp = false; 5012 boolean didSomething = false; 5013 5014 // See if the top visible activity is waiting to run in this process... 5015 if (normalMode) { 5016 try { 5017 if (mStackSupervisor.attachApplicationLocked(app)) { 5018 didSomething = true; 5019 } 5020 } catch (Exception e) { 5021 badApp = true; 5022 } 5023 } 5024 5025 // Find any services that should be running in this process... 5026 if (!badApp) { 5027 try { 5028 didSomething |= mServices.attachApplicationLocked(app, processName); 5029 } catch (Exception e) { 5030 badApp = true; 5031 } 5032 } 5033 5034 // Check if a next-broadcast receiver is in this process... 5035 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5036 try { 5037 didSomething |= sendPendingBroadcastsLocked(app); 5038 } catch (Exception e) { 5039 // If the app died trying to launch the receiver we declare it 'bad' 5040 badApp = true; 5041 } 5042 } 5043 5044 // Check whether the next backup agent is in this process... 5045 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5046 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5047 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5048 try { 5049 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5050 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5051 mBackupTarget.backupMode); 5052 } catch (Exception e) { 5053 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5054 e.printStackTrace(); 5055 } 5056 } 5057 5058 if (badApp) { 5059 // todo: Also need to kill application to deal with all 5060 // kinds of exceptions. 5061 handleAppDiedLocked(app, false, true); 5062 return false; 5063 } 5064 5065 if (!didSomething) { 5066 updateOomAdjLocked(); 5067 } 5068 5069 return true; 5070 } 5071 5072 @Override 5073 public final void attachApplication(IApplicationThread thread) { 5074 synchronized (this) { 5075 int callingPid = Binder.getCallingPid(); 5076 final long origId = Binder.clearCallingIdentity(); 5077 attachApplicationLocked(thread, callingPid); 5078 Binder.restoreCallingIdentity(origId); 5079 } 5080 } 5081 5082 @Override 5083 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5084 final long origId = Binder.clearCallingIdentity(); 5085 synchronized (this) { 5086 ActivityStack stack = ActivityRecord.getStackLocked(token); 5087 if (stack != null) { 5088 ActivityRecord r = 5089 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5090 if (stopProfiling) { 5091 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5092 try { 5093 mProfileFd.close(); 5094 } catch (IOException e) { 5095 } 5096 clearProfilerLocked(); 5097 } 5098 } 5099 } 5100 } 5101 Binder.restoreCallingIdentity(origId); 5102 } 5103 5104 void enableScreenAfterBoot() { 5105 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5106 SystemClock.uptimeMillis()); 5107 mWindowManager.enableScreenAfterBoot(); 5108 5109 synchronized (this) { 5110 updateEventDispatchingLocked(); 5111 } 5112 } 5113 5114 @Override 5115 public void showBootMessage(final CharSequence msg, final boolean always) { 5116 enforceNotIsolatedCaller("showBootMessage"); 5117 mWindowManager.showBootMessage(msg, always); 5118 } 5119 5120 @Override 5121 public void dismissKeyguardOnNextActivity() { 5122 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5123 final long token = Binder.clearCallingIdentity(); 5124 try { 5125 synchronized (this) { 5126 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5127 if (mLockScreenShown) { 5128 mLockScreenShown = false; 5129 comeOutOfSleepIfNeededLocked(); 5130 } 5131 mStackSupervisor.setDismissKeyguard(true); 5132 } 5133 } finally { 5134 Binder.restoreCallingIdentity(token); 5135 } 5136 } 5137 5138 final void finishBooting() { 5139 IntentFilter pkgFilter = new IntentFilter(); 5140 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5141 pkgFilter.addDataScheme("package"); 5142 mContext.registerReceiver(new BroadcastReceiver() { 5143 @Override 5144 public void onReceive(Context context, Intent intent) { 5145 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5146 if (pkgs != null) { 5147 for (String pkg : pkgs) { 5148 synchronized (ActivityManagerService.this) { 5149 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5150 "finished booting")) { 5151 setResultCode(Activity.RESULT_OK); 5152 return; 5153 } 5154 } 5155 } 5156 } 5157 } 5158 }, pkgFilter); 5159 5160 synchronized (this) { 5161 // Ensure that any processes we had put on hold are now started 5162 // up. 5163 final int NP = mProcessesOnHold.size(); 5164 if (NP > 0) { 5165 ArrayList<ProcessRecord> procs = 5166 new ArrayList<ProcessRecord>(mProcessesOnHold); 5167 for (int ip=0; ip<NP; ip++) { 5168 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5169 + procs.get(ip)); 5170 startProcessLocked(procs.get(ip), "on-hold", null); 5171 } 5172 } 5173 5174 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5175 // Start looking for apps that are abusing wake locks. 5176 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5177 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5178 // Tell anyone interested that we are done booting! 5179 SystemProperties.set("sys.boot_completed", "1"); 5180 SystemProperties.set("dev.bootcomplete", "1"); 5181 for (int i=0; i<mStartedUsers.size(); i++) { 5182 UserStartedState uss = mStartedUsers.valueAt(i); 5183 if (uss.mState == UserStartedState.STATE_BOOTING) { 5184 uss.mState = UserStartedState.STATE_RUNNING; 5185 final int userId = mStartedUsers.keyAt(i); 5186 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5187 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5188 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5189 broadcastIntentLocked(null, null, intent, null, 5190 new IIntentReceiver.Stub() { 5191 @Override 5192 public void performReceive(Intent intent, int resultCode, 5193 String data, Bundle extras, boolean ordered, 5194 boolean sticky, int sendingUser) { 5195 synchronized (ActivityManagerService.this) { 5196 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5197 true, false); 5198 } 5199 } 5200 }, 5201 0, null, null, 5202 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5203 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5204 userId); 5205 } 5206 } 5207 scheduleStartRelatedUsersLocked(); 5208 } 5209 } 5210 } 5211 5212 final void ensureBootCompleted() { 5213 boolean booting; 5214 boolean enableScreen; 5215 synchronized (this) { 5216 booting = mBooting; 5217 mBooting = false; 5218 enableScreen = !mBooted; 5219 mBooted = true; 5220 } 5221 5222 if (booting) { 5223 finishBooting(); 5224 } 5225 5226 if (enableScreen) { 5227 enableScreenAfterBoot(); 5228 } 5229 } 5230 5231 @Override 5232 public final void activityResumed(IBinder token) { 5233 final long origId = Binder.clearCallingIdentity(); 5234 synchronized(this) { 5235 ActivityStack stack = ActivityRecord.getStackLocked(token); 5236 if (stack != null) { 5237 ActivityRecord.activityResumedLocked(token); 5238 } 5239 } 5240 Binder.restoreCallingIdentity(origId); 5241 } 5242 5243 @Override 5244 public final void activityPaused(IBinder token) { 5245 final long origId = Binder.clearCallingIdentity(); 5246 synchronized(this) { 5247 ActivityStack stack = ActivityRecord.getStackLocked(token); 5248 if (stack != null) { 5249 stack.activityPausedLocked(token, false); 5250 } 5251 } 5252 Binder.restoreCallingIdentity(origId); 5253 } 5254 5255 @Override 5256 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5257 CharSequence description) { 5258 if (localLOGV) Slog.v( 5259 TAG, "Activity stopped: token=" + token); 5260 5261 // Refuse possible leaked file descriptors 5262 if (icicle != null && icicle.hasFileDescriptors()) { 5263 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5264 } 5265 5266 ActivityRecord r = null; 5267 5268 final long origId = Binder.clearCallingIdentity(); 5269 5270 synchronized (this) { 5271 r = ActivityRecord.isInStackLocked(token); 5272 if (r != null) { 5273 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5274 } 5275 } 5276 5277 if (r != null) { 5278 sendPendingThumbnail(r, null, null, null, false); 5279 } 5280 5281 trimApplications(); 5282 5283 Binder.restoreCallingIdentity(origId); 5284 } 5285 5286 @Override 5287 public final void activityDestroyed(IBinder token) { 5288 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5289 synchronized (this) { 5290 ActivityStack stack = ActivityRecord.getStackLocked(token); 5291 if (stack != null) { 5292 stack.activityDestroyedLocked(token); 5293 } 5294 } 5295 } 5296 5297 @Override 5298 public String getCallingPackage(IBinder token) { 5299 synchronized (this) { 5300 ActivityRecord r = getCallingRecordLocked(token); 5301 return r != null ? r.info.packageName : null; 5302 } 5303 } 5304 5305 @Override 5306 public ComponentName getCallingActivity(IBinder token) { 5307 synchronized (this) { 5308 ActivityRecord r = getCallingRecordLocked(token); 5309 return r != null ? r.intent.getComponent() : null; 5310 } 5311 } 5312 5313 private ActivityRecord getCallingRecordLocked(IBinder token) { 5314 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5315 if (r == null) { 5316 return null; 5317 } 5318 return r.resultTo; 5319 } 5320 5321 @Override 5322 public ComponentName getActivityClassForToken(IBinder token) { 5323 synchronized(this) { 5324 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5325 if (r == null) { 5326 return null; 5327 } 5328 return r.intent.getComponent(); 5329 } 5330 } 5331 5332 @Override 5333 public String getPackageForToken(IBinder token) { 5334 synchronized(this) { 5335 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5336 if (r == null) { 5337 return null; 5338 } 5339 return r.packageName; 5340 } 5341 } 5342 5343 @Override 5344 public IIntentSender getIntentSender(int type, 5345 String packageName, IBinder token, String resultWho, 5346 int requestCode, Intent[] intents, String[] resolvedTypes, 5347 int flags, Bundle options, int userId) { 5348 enforceNotIsolatedCaller("getIntentSender"); 5349 // Refuse possible leaked file descriptors 5350 if (intents != null) { 5351 if (intents.length < 1) { 5352 throw new IllegalArgumentException("Intents array length must be >= 1"); 5353 } 5354 for (int i=0; i<intents.length; i++) { 5355 Intent intent = intents[i]; 5356 if (intent != null) { 5357 if (intent.hasFileDescriptors()) { 5358 throw new IllegalArgumentException("File descriptors passed in Intent"); 5359 } 5360 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5361 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5362 throw new IllegalArgumentException( 5363 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5364 } 5365 intents[i] = new Intent(intent); 5366 } 5367 } 5368 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5369 throw new IllegalArgumentException( 5370 "Intent array length does not match resolvedTypes length"); 5371 } 5372 } 5373 if (options != null) { 5374 if (options.hasFileDescriptors()) { 5375 throw new IllegalArgumentException("File descriptors passed in options"); 5376 } 5377 } 5378 5379 synchronized(this) { 5380 int callingUid = Binder.getCallingUid(); 5381 int origUserId = userId; 5382 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5383 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5384 "getIntentSender", null); 5385 if (origUserId == UserHandle.USER_CURRENT) { 5386 // We don't want to evaluate this until the pending intent is 5387 // actually executed. However, we do want to always do the 5388 // security checking for it above. 5389 userId = UserHandle.USER_CURRENT; 5390 } 5391 try { 5392 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5393 int uid = AppGlobals.getPackageManager() 5394 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5395 if (!UserHandle.isSameApp(callingUid, uid)) { 5396 String msg = "Permission Denial: getIntentSender() from pid=" 5397 + Binder.getCallingPid() 5398 + ", uid=" + Binder.getCallingUid() 5399 + ", (need uid=" + uid + ")" 5400 + " is not allowed to send as package " + packageName; 5401 Slog.w(TAG, msg); 5402 throw new SecurityException(msg); 5403 } 5404 } 5405 5406 return getIntentSenderLocked(type, packageName, callingUid, userId, 5407 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5408 5409 } catch (RemoteException e) { 5410 throw new SecurityException(e); 5411 } 5412 } 5413 } 5414 5415 IIntentSender getIntentSenderLocked(int type, String packageName, 5416 int callingUid, int userId, IBinder token, String resultWho, 5417 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5418 Bundle options) { 5419 if (DEBUG_MU) 5420 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5421 ActivityRecord activity = null; 5422 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5423 activity = ActivityRecord.isInStackLocked(token); 5424 if (activity == null) { 5425 return null; 5426 } 5427 if (activity.finishing) { 5428 return null; 5429 } 5430 } 5431 5432 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5433 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5434 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5435 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5436 |PendingIntent.FLAG_UPDATE_CURRENT); 5437 5438 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5439 type, packageName, activity, resultWho, 5440 requestCode, intents, resolvedTypes, flags, options, userId); 5441 WeakReference<PendingIntentRecord> ref; 5442 ref = mIntentSenderRecords.get(key); 5443 PendingIntentRecord rec = ref != null ? ref.get() : null; 5444 if (rec != null) { 5445 if (!cancelCurrent) { 5446 if (updateCurrent) { 5447 if (rec.key.requestIntent != null) { 5448 rec.key.requestIntent.replaceExtras(intents != null ? 5449 intents[intents.length - 1] : null); 5450 } 5451 if (intents != null) { 5452 intents[intents.length-1] = rec.key.requestIntent; 5453 rec.key.allIntents = intents; 5454 rec.key.allResolvedTypes = resolvedTypes; 5455 } else { 5456 rec.key.allIntents = null; 5457 rec.key.allResolvedTypes = null; 5458 } 5459 } 5460 return rec; 5461 } 5462 rec.canceled = true; 5463 mIntentSenderRecords.remove(key); 5464 } 5465 if (noCreate) { 5466 return rec; 5467 } 5468 rec = new PendingIntentRecord(this, key, callingUid); 5469 mIntentSenderRecords.put(key, rec.ref); 5470 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5471 if (activity.pendingResults == null) { 5472 activity.pendingResults 5473 = new HashSet<WeakReference<PendingIntentRecord>>(); 5474 } 5475 activity.pendingResults.add(rec.ref); 5476 } 5477 return rec; 5478 } 5479 5480 @Override 5481 public void cancelIntentSender(IIntentSender sender) { 5482 if (!(sender instanceof PendingIntentRecord)) { 5483 return; 5484 } 5485 synchronized(this) { 5486 PendingIntentRecord rec = (PendingIntentRecord)sender; 5487 try { 5488 int uid = AppGlobals.getPackageManager() 5489 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5490 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5491 String msg = "Permission Denial: cancelIntentSender() from pid=" 5492 + Binder.getCallingPid() 5493 + ", uid=" + Binder.getCallingUid() 5494 + " is not allowed to cancel packges " 5495 + rec.key.packageName; 5496 Slog.w(TAG, msg); 5497 throw new SecurityException(msg); 5498 } 5499 } catch (RemoteException e) { 5500 throw new SecurityException(e); 5501 } 5502 cancelIntentSenderLocked(rec, true); 5503 } 5504 } 5505 5506 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5507 rec.canceled = true; 5508 mIntentSenderRecords.remove(rec.key); 5509 if (cleanActivity && rec.key.activity != null) { 5510 rec.key.activity.pendingResults.remove(rec.ref); 5511 } 5512 } 5513 5514 @Override 5515 public String getPackageForIntentSender(IIntentSender pendingResult) { 5516 if (!(pendingResult instanceof PendingIntentRecord)) { 5517 return null; 5518 } 5519 try { 5520 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5521 return res.key.packageName; 5522 } catch (ClassCastException e) { 5523 } 5524 return null; 5525 } 5526 5527 @Override 5528 public int getUidForIntentSender(IIntentSender sender) { 5529 if (sender instanceof PendingIntentRecord) { 5530 try { 5531 PendingIntentRecord res = (PendingIntentRecord)sender; 5532 return res.uid; 5533 } catch (ClassCastException e) { 5534 } 5535 } 5536 return -1; 5537 } 5538 5539 @Override 5540 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5541 if (!(pendingResult instanceof PendingIntentRecord)) { 5542 return false; 5543 } 5544 try { 5545 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5546 if (res.key.allIntents == null) { 5547 return false; 5548 } 5549 for (int i=0; i<res.key.allIntents.length; i++) { 5550 Intent intent = res.key.allIntents[i]; 5551 if (intent.getPackage() != null && intent.getComponent() != null) { 5552 return false; 5553 } 5554 } 5555 return true; 5556 } catch (ClassCastException e) { 5557 } 5558 return false; 5559 } 5560 5561 @Override 5562 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5563 if (!(pendingResult instanceof PendingIntentRecord)) { 5564 return false; 5565 } 5566 try { 5567 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5568 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5569 return true; 5570 } 5571 return false; 5572 } catch (ClassCastException e) { 5573 } 5574 return false; 5575 } 5576 5577 @Override 5578 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5579 if (!(pendingResult instanceof PendingIntentRecord)) { 5580 return null; 5581 } 5582 try { 5583 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5584 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5585 } catch (ClassCastException e) { 5586 } 5587 return null; 5588 } 5589 5590 @Override 5591 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5592 if (!(pendingResult instanceof PendingIntentRecord)) { 5593 return null; 5594 } 5595 try { 5596 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5597 Intent intent = res.key.requestIntent; 5598 if (intent != null) { 5599 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5600 || res.lastTagPrefix.equals(prefix))) { 5601 return res.lastTag; 5602 } 5603 res.lastTagPrefix = prefix; 5604 StringBuilder sb = new StringBuilder(128); 5605 if (prefix != null) { 5606 sb.append(prefix); 5607 } 5608 if (intent.getAction() != null) { 5609 sb.append(intent.getAction()); 5610 } else if (intent.getComponent() != null) { 5611 intent.getComponent().appendShortString(sb); 5612 } else { 5613 sb.append("?"); 5614 } 5615 return res.lastTag = sb.toString(); 5616 } 5617 } catch (ClassCastException e) { 5618 } 5619 return null; 5620 } 5621 5622 @Override 5623 public void setProcessLimit(int max) { 5624 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5625 "setProcessLimit()"); 5626 synchronized (this) { 5627 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5628 mProcessLimitOverride = max; 5629 } 5630 trimApplications(); 5631 } 5632 5633 @Override 5634 public int getProcessLimit() { 5635 synchronized (this) { 5636 return mProcessLimitOverride; 5637 } 5638 } 5639 5640 void foregroundTokenDied(ForegroundToken token) { 5641 synchronized (ActivityManagerService.this) { 5642 synchronized (mPidsSelfLocked) { 5643 ForegroundToken cur 5644 = mForegroundProcesses.get(token.pid); 5645 if (cur != token) { 5646 return; 5647 } 5648 mForegroundProcesses.remove(token.pid); 5649 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5650 if (pr == null) { 5651 return; 5652 } 5653 pr.forcingToForeground = null; 5654 updateProcessForegroundLocked(pr, false, false); 5655 } 5656 updateOomAdjLocked(); 5657 } 5658 } 5659 5660 @Override 5661 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5662 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5663 "setProcessForeground()"); 5664 synchronized(this) { 5665 boolean changed = false; 5666 5667 synchronized (mPidsSelfLocked) { 5668 ProcessRecord pr = mPidsSelfLocked.get(pid); 5669 if (pr == null && isForeground) { 5670 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5671 return; 5672 } 5673 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5674 if (oldToken != null) { 5675 oldToken.token.unlinkToDeath(oldToken, 0); 5676 mForegroundProcesses.remove(pid); 5677 if (pr != null) { 5678 pr.forcingToForeground = null; 5679 } 5680 changed = true; 5681 } 5682 if (isForeground && token != null) { 5683 ForegroundToken newToken = new ForegroundToken() { 5684 @Override 5685 public void binderDied() { 5686 foregroundTokenDied(this); 5687 } 5688 }; 5689 newToken.pid = pid; 5690 newToken.token = token; 5691 try { 5692 token.linkToDeath(newToken, 0); 5693 mForegroundProcesses.put(pid, newToken); 5694 pr.forcingToForeground = token; 5695 changed = true; 5696 } catch (RemoteException e) { 5697 // If the process died while doing this, we will later 5698 // do the cleanup with the process death link. 5699 } 5700 } 5701 } 5702 5703 if (changed) { 5704 updateOomAdjLocked(); 5705 } 5706 } 5707 } 5708 5709 // ========================================================= 5710 // PERMISSIONS 5711 // ========================================================= 5712 5713 static class PermissionController extends IPermissionController.Stub { 5714 ActivityManagerService mActivityManagerService; 5715 PermissionController(ActivityManagerService activityManagerService) { 5716 mActivityManagerService = activityManagerService; 5717 } 5718 5719 @Override 5720 public boolean checkPermission(String permission, int pid, int uid) { 5721 return mActivityManagerService.checkPermission(permission, pid, 5722 uid) == PackageManager.PERMISSION_GRANTED; 5723 } 5724 } 5725 5726 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5727 @Override 5728 public int checkComponentPermission(String permission, int pid, int uid, 5729 int owningUid, boolean exported) { 5730 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5731 owningUid, exported); 5732 } 5733 5734 @Override 5735 public Object getAMSLock() { 5736 return ActivityManagerService.this; 5737 } 5738 } 5739 5740 /** 5741 * This can be called with or without the global lock held. 5742 */ 5743 int checkComponentPermission(String permission, int pid, int uid, 5744 int owningUid, boolean exported) { 5745 // We might be performing an operation on behalf of an indirect binder 5746 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5747 // client identity accordingly before proceeding. 5748 Identity tlsIdentity = sCallerIdentity.get(); 5749 if (tlsIdentity != null) { 5750 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5751 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5752 uid = tlsIdentity.uid; 5753 pid = tlsIdentity.pid; 5754 } 5755 5756 if (pid == MY_PID) { 5757 return PackageManager.PERMISSION_GRANTED; 5758 } 5759 5760 return ActivityManager.checkComponentPermission(permission, uid, 5761 owningUid, exported); 5762 } 5763 5764 /** 5765 * As the only public entry point for permissions checking, this method 5766 * can enforce the semantic that requesting a check on a null global 5767 * permission is automatically denied. (Internally a null permission 5768 * string is used when calling {@link #checkComponentPermission} in cases 5769 * when only uid-based security is needed.) 5770 * 5771 * This can be called with or without the global lock held. 5772 */ 5773 @Override 5774 public int checkPermission(String permission, int pid, int uid) { 5775 if (permission == null) { 5776 return PackageManager.PERMISSION_DENIED; 5777 } 5778 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5779 } 5780 5781 /** 5782 * Binder IPC calls go through the public entry point. 5783 * This can be called with or without the global lock held. 5784 */ 5785 int checkCallingPermission(String permission) { 5786 return checkPermission(permission, 5787 Binder.getCallingPid(), 5788 UserHandle.getAppId(Binder.getCallingUid())); 5789 } 5790 5791 /** 5792 * This can be called with or without the global lock held. 5793 */ 5794 void enforceCallingPermission(String permission, String func) { 5795 if (checkCallingPermission(permission) 5796 == PackageManager.PERMISSION_GRANTED) { 5797 return; 5798 } 5799 5800 String msg = "Permission Denial: " + func + " from pid=" 5801 + Binder.getCallingPid() 5802 + ", uid=" + Binder.getCallingUid() 5803 + " requires " + permission; 5804 Slog.w(TAG, msg); 5805 throw new SecurityException(msg); 5806 } 5807 5808 /** 5809 * Determine if UID is holding permissions required to access {@link Uri} in 5810 * the given {@link ProviderInfo}. Final permission checking is always done 5811 * in {@link ContentProvider}. 5812 */ 5813 private final boolean checkHoldingPermissionsLocked( 5814 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5815 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5816 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5817 5818 if (pi.applicationInfo.uid == uid) { 5819 return true; 5820 } else if (!pi.exported) { 5821 return false; 5822 } 5823 5824 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5825 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5826 try { 5827 // check if target holds top-level <provider> permissions 5828 if (!readMet && pi.readPermission != null 5829 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5830 readMet = true; 5831 } 5832 if (!writeMet && pi.writePermission != null 5833 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5834 writeMet = true; 5835 } 5836 5837 // track if unprotected read/write is allowed; any denied 5838 // <path-permission> below removes this ability 5839 boolean allowDefaultRead = pi.readPermission == null; 5840 boolean allowDefaultWrite = pi.writePermission == null; 5841 5842 // check if target holds any <path-permission> that match uri 5843 final PathPermission[] pps = pi.pathPermissions; 5844 if (pps != null) { 5845 final String path = uri.getPath(); 5846 int i = pps.length; 5847 while (i > 0 && (!readMet || !writeMet)) { 5848 i--; 5849 PathPermission pp = pps[i]; 5850 if (pp.match(path)) { 5851 if (!readMet) { 5852 final String pprperm = pp.getReadPermission(); 5853 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5854 + pprperm + " for " + pp.getPath() 5855 + ": match=" + pp.match(path) 5856 + " check=" + pm.checkUidPermission(pprperm, uid)); 5857 if (pprperm != null) { 5858 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5859 readMet = true; 5860 } else { 5861 allowDefaultRead = false; 5862 } 5863 } 5864 } 5865 if (!writeMet) { 5866 final String ppwperm = pp.getWritePermission(); 5867 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5868 + ppwperm + " for " + pp.getPath() 5869 + ": match=" + pp.match(path) 5870 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5871 if (ppwperm != null) { 5872 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5873 writeMet = true; 5874 } else { 5875 allowDefaultWrite = false; 5876 } 5877 } 5878 } 5879 } 5880 } 5881 } 5882 5883 // grant unprotected <provider> read/write, if not blocked by 5884 // <path-permission> above 5885 if (allowDefaultRead) readMet = true; 5886 if (allowDefaultWrite) writeMet = true; 5887 5888 } catch (RemoteException e) { 5889 return false; 5890 } 5891 5892 return readMet && writeMet; 5893 } 5894 5895 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5896 ProviderInfo pi = null; 5897 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5898 if (cpr != null) { 5899 pi = cpr.info; 5900 } else { 5901 try { 5902 pi = AppGlobals.getPackageManager().resolveContentProvider( 5903 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5904 } catch (RemoteException ex) { 5905 } 5906 } 5907 return pi; 5908 } 5909 5910 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5911 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5912 if (targetUris != null) { 5913 return targetUris.get(uri); 5914 } else { 5915 return null; 5916 } 5917 } 5918 5919 private UriPermission findOrCreateUriPermissionLocked( 5920 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5921 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5922 if (targetUris == null) { 5923 targetUris = Maps.newArrayMap(); 5924 mGrantedUriPermissions.put(targetUid, targetUris); 5925 } 5926 5927 UriPermission perm = targetUris.get(uri); 5928 if (perm == null) { 5929 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5930 targetUris.put(uri, perm); 5931 } 5932 5933 return perm; 5934 } 5935 5936 private final boolean checkUriPermissionLocked( 5937 Uri uri, int uid, int modeFlags, int minStrength) { 5938 // Root gets to do everything. 5939 if (uid == 0) { 5940 return true; 5941 } 5942 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5943 if (perms == null) return false; 5944 UriPermission perm = perms.get(uri); 5945 if (perm == null) return false; 5946 return perm.getStrength(modeFlags) >= minStrength; 5947 } 5948 5949 @Override 5950 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5951 enforceNotIsolatedCaller("checkUriPermission"); 5952 5953 // Another redirected-binder-call permissions check as in 5954 // {@link checkComponentPermission}. 5955 Identity tlsIdentity = sCallerIdentity.get(); 5956 if (tlsIdentity != null) { 5957 uid = tlsIdentity.uid; 5958 pid = tlsIdentity.pid; 5959 } 5960 5961 // Our own process gets to do everything. 5962 if (pid == MY_PID) { 5963 return PackageManager.PERMISSION_GRANTED; 5964 } 5965 synchronized(this) { 5966 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5967 ? PackageManager.PERMISSION_GRANTED 5968 : PackageManager.PERMISSION_DENIED; 5969 } 5970 } 5971 5972 /** 5973 * Check if the targetPkg can be granted permission to access uri by 5974 * the callingUid using the given modeFlags. Throws a security exception 5975 * if callingUid is not allowed to do this. Returns the uid of the target 5976 * if the URI permission grant should be performed; returns -1 if it is not 5977 * needed (for example targetPkg already has permission to access the URI). 5978 * If you already know the uid of the target, you can supply it in 5979 * lastTargetUid else set that to -1. 5980 */ 5981 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5982 Uri uri, int modeFlags, int lastTargetUid) { 5983 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5984 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5985 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5986 if (modeFlags == 0) { 5987 return -1; 5988 } 5989 5990 if (targetPkg != null) { 5991 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5992 "Checking grant " + targetPkg + " permission to " + uri); 5993 } 5994 5995 final IPackageManager pm = AppGlobals.getPackageManager(); 5996 5997 // If this is not a content: uri, we can't do anything with it. 5998 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5999 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6000 "Can't grant URI permission for non-content URI: " + uri); 6001 return -1; 6002 } 6003 6004 final String authority = uri.getAuthority(); 6005 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6006 if (pi == null) { 6007 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6008 return -1; 6009 } 6010 6011 int targetUid = lastTargetUid; 6012 if (targetUid < 0 && targetPkg != null) { 6013 try { 6014 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6015 if (targetUid < 0) { 6016 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6017 "Can't grant URI permission no uid for: " + targetPkg); 6018 return -1; 6019 } 6020 } catch (RemoteException ex) { 6021 return -1; 6022 } 6023 } 6024 6025 if (targetUid >= 0) { 6026 // First... does the target actually need this permission? 6027 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6028 // No need to grant the target this permission. 6029 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6030 "Target " + targetPkg + " already has full permission to " + uri); 6031 return -1; 6032 } 6033 } else { 6034 // First... there is no target package, so can anyone access it? 6035 boolean allowed = pi.exported; 6036 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6037 if (pi.readPermission != null) { 6038 allowed = false; 6039 } 6040 } 6041 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6042 if (pi.writePermission != null) { 6043 allowed = false; 6044 } 6045 } 6046 if (allowed) { 6047 return -1; 6048 } 6049 } 6050 6051 // Second... is the provider allowing granting of URI permissions? 6052 if (!pi.grantUriPermissions) { 6053 throw new SecurityException("Provider " + pi.packageName 6054 + "/" + pi.name 6055 + " does not allow granting of Uri permissions (uri " 6056 + uri + ")"); 6057 } 6058 if (pi.uriPermissionPatterns != null) { 6059 final int N = pi.uriPermissionPatterns.length; 6060 boolean allowed = false; 6061 for (int i=0; i<N; i++) { 6062 if (pi.uriPermissionPatterns[i] != null 6063 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6064 allowed = true; 6065 break; 6066 } 6067 } 6068 if (!allowed) { 6069 throw new SecurityException("Provider " + pi.packageName 6070 + "/" + pi.name 6071 + " does not allow granting of permission to path of Uri " 6072 + uri); 6073 } 6074 } 6075 6076 // Third... does the caller itself have permission to access 6077 // this uri? 6078 if (callingUid != Process.myUid()) { 6079 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6080 // Require they hold a strong enough Uri permission 6081 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6082 : UriPermission.STRENGTH_OWNED; 6083 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6084 throw new SecurityException("Uid " + callingUid 6085 + " does not have permission to uri " + uri); 6086 } 6087 } 6088 } 6089 6090 return targetUid; 6091 } 6092 6093 @Override 6094 public int checkGrantUriPermission(int callingUid, String targetPkg, 6095 Uri uri, int modeFlags) { 6096 enforceNotIsolatedCaller("checkGrantUriPermission"); 6097 synchronized(this) { 6098 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6099 } 6100 } 6101 6102 void grantUriPermissionUncheckedLocked( 6103 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6104 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6105 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6106 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6107 if (modeFlags == 0) { 6108 return; 6109 } 6110 6111 // So here we are: the caller has the assumed permission 6112 // to the uri, and the target doesn't. Let's now give this to 6113 // the target. 6114 6115 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6116 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6117 6118 final String authority = uri.getAuthority(); 6119 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6120 if (pi == null) { 6121 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6122 return; 6123 } 6124 6125 final UriPermission perm = findOrCreateUriPermissionLocked( 6126 pi.packageName, targetPkg, targetUid, uri); 6127 perm.grantModes(modeFlags, persistable, owner); 6128 } 6129 6130 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6131 int modeFlags, UriPermissionOwner owner) { 6132 if (targetPkg == null) { 6133 throw new NullPointerException("targetPkg"); 6134 } 6135 6136 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6137 if (targetUid < 0) { 6138 return; 6139 } 6140 6141 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6142 } 6143 6144 static class NeededUriGrants extends ArrayList<Uri> { 6145 final String targetPkg; 6146 final int targetUid; 6147 final int flags; 6148 6149 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6150 this.targetPkg = targetPkg; 6151 this.targetUid = targetUid; 6152 this.flags = flags; 6153 } 6154 } 6155 6156 /** 6157 * Like checkGrantUriPermissionLocked, but takes an Intent. 6158 */ 6159 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6160 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6161 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6162 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6163 + " clip=" + (intent != null ? intent.getClipData() : null) 6164 + " from " + intent + "; flags=0x" 6165 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6166 6167 if (targetPkg == null) { 6168 throw new NullPointerException("targetPkg"); 6169 } 6170 6171 if (intent == null) { 6172 return null; 6173 } 6174 Uri data = intent.getData(); 6175 ClipData clip = intent.getClipData(); 6176 if (data == null && clip == null) { 6177 return null; 6178 } 6179 6180 if (data != null) { 6181 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6182 mode, needed != null ? needed.targetUid : -1); 6183 if (targetUid > 0) { 6184 if (needed == null) { 6185 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6186 } 6187 needed.add(data); 6188 } 6189 } 6190 if (clip != null) { 6191 for (int i=0; i<clip.getItemCount(); i++) { 6192 Uri uri = clip.getItemAt(i).getUri(); 6193 if (uri != null) { 6194 int targetUid = -1; 6195 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6196 mode, needed != null ? needed.targetUid : -1); 6197 if (targetUid > 0) { 6198 if (needed == null) { 6199 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6200 } 6201 needed.add(uri); 6202 } 6203 } else { 6204 Intent clipIntent = clip.getItemAt(i).getIntent(); 6205 if (clipIntent != null) { 6206 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6207 callingUid, targetPkg, clipIntent, mode, needed); 6208 if (newNeeded != null) { 6209 needed = newNeeded; 6210 } 6211 } 6212 } 6213 } 6214 } 6215 6216 return needed; 6217 } 6218 6219 /** 6220 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6221 */ 6222 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6223 UriPermissionOwner owner) { 6224 if (needed != null) { 6225 for (int i=0; i<needed.size(); i++) { 6226 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6227 needed.get(i), needed.flags, owner); 6228 } 6229 } 6230 } 6231 6232 void grantUriPermissionFromIntentLocked(int callingUid, 6233 String targetPkg, Intent intent, UriPermissionOwner owner) { 6234 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6235 intent, intent != null ? intent.getFlags() : 0, null); 6236 if (needed == null) { 6237 return; 6238 } 6239 6240 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6241 } 6242 6243 @Override 6244 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6245 Uri uri, int modeFlags) { 6246 enforceNotIsolatedCaller("grantUriPermission"); 6247 synchronized(this) { 6248 final ProcessRecord r = getRecordForAppLocked(caller); 6249 if (r == null) { 6250 throw new SecurityException("Unable to find app for caller " 6251 + caller 6252 + " when granting permission to uri " + uri); 6253 } 6254 if (targetPkg == null) { 6255 throw new IllegalArgumentException("null target"); 6256 } 6257 if (uri == null) { 6258 throw new IllegalArgumentException("null uri"); 6259 } 6260 6261 // Persistable only supported through Intents 6262 Preconditions.checkFlagsArgument(modeFlags, 6263 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6264 6265 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6266 null); 6267 } 6268 } 6269 6270 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6271 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6272 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6273 ArrayMap<Uri, UriPermission> perms 6274 = mGrantedUriPermissions.get(perm.targetUid); 6275 if (perms != null) { 6276 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6277 "Removing " + perm.targetUid + " permission to " + perm.uri); 6278 perms.remove(perm.uri); 6279 if (perms.size() == 0) { 6280 mGrantedUriPermissions.remove(perm.targetUid); 6281 } 6282 } 6283 } 6284 } 6285 6286 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6287 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6288 6289 final IPackageManager pm = AppGlobals.getPackageManager(); 6290 final String authority = uri.getAuthority(); 6291 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6292 if (pi == null) { 6293 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6294 return; 6295 } 6296 6297 // Does the caller have this permission on the URI? 6298 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6299 // Right now, if you are not the original owner of the permission, 6300 // you are not allowed to revoke it. 6301 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6302 throw new SecurityException("Uid " + callingUid 6303 + " does not have permission to uri " + uri); 6304 //} 6305 } 6306 6307 boolean persistChanged = false; 6308 6309 // Go through all of the permissions and remove any that match. 6310 final List<String> SEGMENTS = uri.getPathSegments(); 6311 if (SEGMENTS != null) { 6312 final int NS = SEGMENTS.size(); 6313 int N = mGrantedUriPermissions.size(); 6314 for (int i=0; i<N; i++) { 6315 ArrayMap<Uri, UriPermission> perms 6316 = mGrantedUriPermissions.valueAt(i); 6317 Iterator<UriPermission> it = perms.values().iterator(); 6318 toploop: 6319 while (it.hasNext()) { 6320 UriPermission perm = it.next(); 6321 Uri targetUri = perm.uri; 6322 if (!authority.equals(targetUri.getAuthority())) { 6323 continue; 6324 } 6325 List<String> targetSegments = targetUri.getPathSegments(); 6326 if (targetSegments == null) { 6327 continue; 6328 } 6329 if (targetSegments.size() < NS) { 6330 continue; 6331 } 6332 for (int j=0; j<NS; j++) { 6333 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6334 continue toploop; 6335 } 6336 } 6337 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6338 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6339 persistChanged |= perm.clearModes(modeFlags, true); 6340 if (perm.modeFlags == 0) { 6341 it.remove(); 6342 } 6343 } 6344 if (perms.size() == 0) { 6345 mGrantedUriPermissions.remove( 6346 mGrantedUriPermissions.keyAt(i)); 6347 N--; 6348 i--; 6349 } 6350 } 6351 } 6352 6353 if (persistChanged) { 6354 schedulePersistUriGrants(); 6355 } 6356 } 6357 6358 @Override 6359 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6360 int modeFlags) { 6361 enforceNotIsolatedCaller("revokeUriPermission"); 6362 synchronized(this) { 6363 final ProcessRecord r = getRecordForAppLocked(caller); 6364 if (r == null) { 6365 throw new SecurityException("Unable to find app for caller " 6366 + caller 6367 + " when revoking permission to uri " + uri); 6368 } 6369 if (uri == null) { 6370 Slog.w(TAG, "revokeUriPermission: null uri"); 6371 return; 6372 } 6373 6374 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6375 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6376 if (modeFlags == 0) { 6377 return; 6378 } 6379 6380 final IPackageManager pm = AppGlobals.getPackageManager(); 6381 final String authority = uri.getAuthority(); 6382 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6383 if (pi == null) { 6384 Slog.w(TAG, "No content provider found for permission revoke: " 6385 + uri.toSafeString()); 6386 return; 6387 } 6388 6389 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6390 } 6391 } 6392 6393 /** 6394 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6395 * given package. 6396 * 6397 * @param packageName Package name to match, or {@code null} to apply to all 6398 * packages. 6399 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6400 * to all users. 6401 * @param persistable If persistable grants should be removed. 6402 */ 6403 private void removeUriPermissionsForPackageLocked( 6404 String packageName, int userHandle, boolean persistable) { 6405 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6406 throw new IllegalArgumentException("Must narrow by either package or user"); 6407 } 6408 6409 boolean persistChanged = false; 6410 6411 final int size = mGrantedUriPermissions.size(); 6412 for (int i = 0; i < size; i++) { 6413 // Only inspect grants matching user 6414 if (userHandle == UserHandle.USER_ALL 6415 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6416 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6417 .values().iterator(); 6418 while (it.hasNext()) { 6419 final UriPermission perm = it.next(); 6420 6421 // Only inspect grants matching package 6422 if (packageName == null || perm.sourcePkg.equals(packageName) 6423 || perm.targetPkg.equals(packageName)) { 6424 persistChanged |= perm.clearModes(~0, persistable); 6425 6426 // Only remove when no modes remain; any persisted grants 6427 // will keep this alive. 6428 if (perm.modeFlags == 0) { 6429 it.remove(); 6430 } 6431 } 6432 } 6433 } 6434 } 6435 6436 if (persistChanged) { 6437 schedulePersistUriGrants(); 6438 } 6439 } 6440 6441 @Override 6442 public IBinder newUriPermissionOwner(String name) { 6443 enforceNotIsolatedCaller("newUriPermissionOwner"); 6444 synchronized(this) { 6445 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6446 return owner.getExternalTokenLocked(); 6447 } 6448 } 6449 6450 @Override 6451 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6452 Uri uri, int modeFlags) { 6453 synchronized(this) { 6454 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6455 if (owner == null) { 6456 throw new IllegalArgumentException("Unknown owner: " + token); 6457 } 6458 if (fromUid != Binder.getCallingUid()) { 6459 if (Binder.getCallingUid() != Process.myUid()) { 6460 // Only system code can grant URI permissions on behalf 6461 // of other users. 6462 throw new SecurityException("nice try"); 6463 } 6464 } 6465 if (targetPkg == null) { 6466 throw new IllegalArgumentException("null target"); 6467 } 6468 if (uri == null) { 6469 throw new IllegalArgumentException("null uri"); 6470 } 6471 6472 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6473 } 6474 } 6475 6476 @Override 6477 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6478 synchronized(this) { 6479 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6480 if (owner == null) { 6481 throw new IllegalArgumentException("Unknown owner: " + token); 6482 } 6483 6484 if (uri == null) { 6485 owner.removeUriPermissionsLocked(mode); 6486 } else { 6487 owner.removeUriPermissionLocked(uri, mode); 6488 } 6489 } 6490 } 6491 6492 private void schedulePersistUriGrants() { 6493 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6494 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6495 10 * DateUtils.SECOND_IN_MILLIS); 6496 } 6497 } 6498 6499 private void writeGrantedUriPermissions() { 6500 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6501 6502 // Snapshot permissions so we can persist without lock 6503 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6504 synchronized (this) { 6505 final int size = mGrantedUriPermissions.size(); 6506 for (int i = 0 ; i < size; i++) { 6507 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6508 if (perm.persistedModeFlags != 0) { 6509 persist.add(perm.snapshot()); 6510 } 6511 } 6512 } 6513 } 6514 6515 FileOutputStream fos = null; 6516 try { 6517 fos = mGrantFile.startWrite(); 6518 6519 XmlSerializer out = new FastXmlSerializer(); 6520 out.setOutput(fos, "utf-8"); 6521 out.startDocument(null, true); 6522 out.startTag(null, TAG_URI_GRANTS); 6523 for (UriPermission.Snapshot perm : persist) { 6524 out.startTag(null, TAG_URI_GRANT); 6525 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6526 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6527 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6528 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6529 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6530 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6531 out.endTag(null, TAG_URI_GRANT); 6532 } 6533 out.endTag(null, TAG_URI_GRANTS); 6534 out.endDocument(); 6535 6536 mGrantFile.finishWrite(fos); 6537 } catch (IOException e) { 6538 if (fos != null) { 6539 mGrantFile.failWrite(fos); 6540 } 6541 } 6542 } 6543 6544 private void readGrantedUriPermissionsLocked() { 6545 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6546 6547 final long now = System.currentTimeMillis(); 6548 6549 FileInputStream fis = null; 6550 try { 6551 fis = mGrantFile.openRead(); 6552 final XmlPullParser in = Xml.newPullParser(); 6553 in.setInput(fis, null); 6554 6555 int type; 6556 while ((type = in.next()) != END_DOCUMENT) { 6557 final String tag = in.getName(); 6558 if (type == START_TAG) { 6559 if (TAG_URI_GRANT.equals(tag)) { 6560 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6561 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6562 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6563 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6564 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6565 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6566 6567 // Sanity check that provider still belongs to source package 6568 final ProviderInfo pi = getProviderInfoLocked( 6569 uri.getAuthority(), userHandle); 6570 if (pi != null && sourcePkg.equals(pi.packageName)) { 6571 int targetUid = -1; 6572 try { 6573 targetUid = AppGlobals.getPackageManager() 6574 .getPackageUid(targetPkg, userHandle); 6575 } catch (RemoteException e) { 6576 } 6577 if (targetUid != -1) { 6578 final UriPermission perm = findOrCreateUriPermissionLocked( 6579 sourcePkg, targetPkg, targetUid, uri); 6580 perm.initPersistedModes(modeFlags, createdTime); 6581 } 6582 } else { 6583 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6584 + " but instead found " + pi); 6585 } 6586 } 6587 } 6588 } 6589 } catch (FileNotFoundException e) { 6590 // Missing grants is okay 6591 } catch (IOException e) { 6592 Log.wtf(TAG, "Failed reading Uri grants", e); 6593 } catch (XmlPullParserException e) { 6594 Log.wtf(TAG, "Failed reading Uri grants", e); 6595 } finally { 6596 IoUtils.closeQuietly(fis); 6597 } 6598 } 6599 6600 @Override 6601 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6602 enforceNotIsolatedCaller("takePersistableUriPermission"); 6603 6604 Preconditions.checkFlagsArgument(modeFlags, 6605 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6606 6607 synchronized (this) { 6608 final int callingUid = Binder.getCallingUid(); 6609 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6610 if (perm == null) { 6611 throw new SecurityException("No permission grant found for UID " + callingUid 6612 + " and Uri " + uri.toSafeString()); 6613 } 6614 6615 boolean persistChanged = perm.takePersistableModes(modeFlags); 6616 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6617 6618 if (persistChanged) { 6619 schedulePersistUriGrants(); 6620 } 6621 } 6622 } 6623 6624 @Override 6625 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6626 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6627 6628 Preconditions.checkFlagsArgument(modeFlags, 6629 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6630 6631 synchronized (this) { 6632 final int callingUid = Binder.getCallingUid(); 6633 6634 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6635 if (perm == null) { 6636 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6637 + uri.toSafeString()); 6638 return; 6639 } 6640 6641 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6642 removeUriPermissionIfNeededLocked(perm); 6643 if (persistChanged) { 6644 schedulePersistUriGrants(); 6645 } 6646 } 6647 } 6648 6649 /** 6650 * Prune any older {@link UriPermission} for the given UID until outstanding 6651 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6652 * 6653 * @return if any mutations occured that require persisting. 6654 */ 6655 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6656 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6657 if (perms == null) return false; 6658 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6659 6660 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6661 for (UriPermission perm : perms.values()) { 6662 if (perm.persistedModeFlags != 0) { 6663 persisted.add(perm); 6664 } 6665 } 6666 6667 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6668 if (trimCount <= 0) return false; 6669 6670 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6671 for (int i = 0; i < trimCount; i++) { 6672 final UriPermission perm = persisted.get(i); 6673 6674 if (DEBUG_URI_PERMISSION) { 6675 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6676 } 6677 6678 perm.releasePersistableModes(~0); 6679 removeUriPermissionIfNeededLocked(perm); 6680 } 6681 6682 return true; 6683 } 6684 6685 @Override 6686 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6687 String packageName, boolean incoming) { 6688 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6689 Preconditions.checkNotNull(packageName, "packageName"); 6690 6691 final int callingUid = Binder.getCallingUid(); 6692 final IPackageManager pm = AppGlobals.getPackageManager(); 6693 try { 6694 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6695 if (packageUid != callingUid) { 6696 throw new SecurityException( 6697 "Package " + packageName + " does not belong to calling UID " + callingUid); 6698 } 6699 } catch (RemoteException e) { 6700 throw new SecurityException("Failed to verify package name ownership"); 6701 } 6702 6703 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6704 synchronized (this) { 6705 if (incoming) { 6706 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6707 if (perms == null) { 6708 Slog.w(TAG, "No permission grants found for " + packageName); 6709 } else { 6710 final int size = perms.size(); 6711 for (int i = 0; i < size; i++) { 6712 final UriPermission perm = perms.valueAt(i); 6713 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6714 result.add(perm.buildPersistedPublicApiObject()); 6715 } 6716 } 6717 } 6718 } else { 6719 final int size = mGrantedUriPermissions.size(); 6720 for (int i = 0; i < size; i++) { 6721 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6722 final int permsSize = perms.size(); 6723 for (int j = 0; j < permsSize; j++) { 6724 final UriPermission perm = perms.valueAt(j); 6725 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6726 result.add(perm.buildPersistedPublicApiObject()); 6727 } 6728 } 6729 } 6730 } 6731 } 6732 return new ParceledListSlice<android.content.UriPermission>(result); 6733 } 6734 6735 @Override 6736 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6737 synchronized (this) { 6738 ProcessRecord app = 6739 who != null ? getRecordForAppLocked(who) : null; 6740 if (app == null) return; 6741 6742 Message msg = Message.obtain(); 6743 msg.what = WAIT_FOR_DEBUGGER_MSG; 6744 msg.obj = app; 6745 msg.arg1 = waiting ? 1 : 0; 6746 mHandler.sendMessage(msg); 6747 } 6748 } 6749 6750 @Override 6751 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6752 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6753 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6754 outInfo.availMem = Process.getFreeMemory(); 6755 outInfo.totalMem = Process.getTotalMemory(); 6756 outInfo.threshold = homeAppMem; 6757 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6758 outInfo.hiddenAppThreshold = cachedAppMem; 6759 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6760 ProcessList.SERVICE_ADJ); 6761 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6762 ProcessList.VISIBLE_APP_ADJ); 6763 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6764 ProcessList.FOREGROUND_APP_ADJ); 6765 } 6766 6767 // ========================================================= 6768 // TASK MANAGEMENT 6769 // ========================================================= 6770 6771 @Override 6772 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6773 IThumbnailReceiver receiver) { 6774 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6775 6776 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6777 ActivityRecord topRecord = null; 6778 6779 synchronized(this) { 6780 if (localLOGV) Slog.v( 6781 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6782 + ", receiver=" + receiver); 6783 6784 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6785 != PackageManager.PERMISSION_GRANTED) { 6786 if (receiver != null) { 6787 // If the caller wants to wait for pending thumbnails, 6788 // it ain't gonna get them. 6789 try { 6790 receiver.finished(); 6791 } catch (RemoteException ex) { 6792 } 6793 } 6794 String msg = "Permission Denial: getTasks() from pid=" 6795 + Binder.getCallingPid() 6796 + ", uid=" + Binder.getCallingUid() 6797 + " requires " + android.Manifest.permission.GET_TASKS; 6798 Slog.w(TAG, msg); 6799 throw new SecurityException(msg); 6800 } 6801 6802 // TODO: Improve with MRU list from all ActivityStacks. 6803 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6804 6805 if (!pending.pendingRecords.isEmpty()) { 6806 mPendingThumbnails.add(pending); 6807 } 6808 } 6809 6810 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6811 6812 if (topRecord != null) { 6813 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6814 try { 6815 IApplicationThread topThumbnail = topRecord.app.thread; 6816 topThumbnail.requestThumbnail(topRecord.appToken); 6817 } catch (Exception e) { 6818 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6819 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6820 } 6821 } 6822 6823 if (pending.pendingRecords.isEmpty() && receiver != null) { 6824 // In this case all thumbnails were available and the client 6825 // is being asked to be told when the remaining ones come in... 6826 // which is unusually, since the top-most currently running 6827 // activity should never have a canned thumbnail! Oh well. 6828 try { 6829 receiver.finished(); 6830 } catch (RemoteException ex) { 6831 } 6832 } 6833 6834 return list; 6835 } 6836 6837 TaskRecord getMostRecentTask() { 6838 return mRecentTasks.get(0); 6839 } 6840 6841 @Override 6842 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6843 int flags, int userId) { 6844 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6845 false, true, "getRecentTasks", null); 6846 6847 synchronized (this) { 6848 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6849 "getRecentTasks()"); 6850 final boolean detailed = checkCallingPermission( 6851 android.Manifest.permission.GET_DETAILED_TASKS) 6852 == PackageManager.PERMISSION_GRANTED; 6853 6854 IPackageManager pm = AppGlobals.getPackageManager(); 6855 6856 final int N = mRecentTasks.size(); 6857 ArrayList<ActivityManager.RecentTaskInfo> res 6858 = new ArrayList<ActivityManager.RecentTaskInfo>( 6859 maxNum < N ? maxNum : N); 6860 6861 final Set<Integer> includedUsers; 6862 if ((flags & ActivityManager.RECENT_INCLUDE_RELATED) != 0) { 6863 includedUsers = getRelatedUsersLocked(userId); 6864 } else { 6865 includedUsers = new HashSet<Integer>(); 6866 } 6867 includedUsers.add(Integer.valueOf(userId)); 6868 for (int i=0; i<N && maxNum > 0; i++) { 6869 TaskRecord tr = mRecentTasks.get(i); 6870 // Only add calling user or related users recent tasks 6871 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 6872 6873 // Return the entry if desired by the caller. We always return 6874 // the first entry, because callers always expect this to be the 6875 // foreground app. We may filter others if the caller has 6876 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6877 // we should exclude the entry. 6878 6879 if (i == 0 6880 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6881 || (tr.intent == null) 6882 || ((tr.intent.getFlags() 6883 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6884 ActivityManager.RecentTaskInfo rti 6885 = new ActivityManager.RecentTaskInfo(); 6886 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6887 rti.persistentId = tr.taskId; 6888 rti.baseIntent = new Intent( 6889 tr.intent != null ? tr.intent : tr.affinityIntent); 6890 if (!detailed) { 6891 rti.baseIntent.replaceExtras((Bundle)null); 6892 } 6893 rti.origActivity = tr.origActivity; 6894 rti.description = tr.lastDescription; 6895 rti.stackId = tr.stack.mStackId; 6896 rti.userId = tr.userId; 6897 6898 final ArrayList<ActivityRecord> activities = tr.mActivities; 6899 int numSet = 0; 6900 for (int activityNdx = activities.size() - 1; activityNdx >= 0 && numSet < 2; 6901 --activityNdx) { 6902 final ActivityRecord r = activities.get(activityNdx); 6903 if (rti.activityLabel == null && r.recentsLabel != null) { 6904 rti.activityLabel = r.recentsLabel; 6905 ++numSet; 6906 } 6907 if (rti.activityIcon == null && r.recentsIcon != null) { 6908 rti.activityIcon = r.recentsIcon; 6909 ++numSet; 6910 } 6911 } 6912 6913 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6914 // Check whether this activity is currently available. 6915 try { 6916 if (rti.origActivity != null) { 6917 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6918 == null) { 6919 continue; 6920 } 6921 } else if (rti.baseIntent != null) { 6922 if (pm.queryIntentActivities(rti.baseIntent, 6923 null, 0, userId) == null) { 6924 continue; 6925 } 6926 } 6927 } catch (RemoteException e) { 6928 // Will never happen. 6929 } 6930 } 6931 6932 res.add(rti); 6933 maxNum--; 6934 } 6935 } 6936 return res; 6937 } 6938 } 6939 6940 private TaskRecord recentTaskForIdLocked(int id) { 6941 final int N = mRecentTasks.size(); 6942 for (int i=0; i<N; i++) { 6943 TaskRecord tr = mRecentTasks.get(i); 6944 if (tr.taskId == id) { 6945 return tr; 6946 } 6947 } 6948 return null; 6949 } 6950 6951 @Override 6952 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6953 synchronized (this) { 6954 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6955 "getTaskThumbnails()"); 6956 TaskRecord tr = recentTaskForIdLocked(id); 6957 if (tr != null) { 6958 return tr.getTaskThumbnailsLocked(); 6959 } 6960 } 6961 return null; 6962 } 6963 6964 @Override 6965 public Bitmap getTaskTopThumbnail(int id) { 6966 synchronized (this) { 6967 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6968 "getTaskTopThumbnail()"); 6969 TaskRecord tr = recentTaskForIdLocked(id); 6970 if (tr != null) { 6971 return tr.getTaskTopThumbnailLocked(); 6972 } 6973 } 6974 return null; 6975 } 6976 6977 @Override 6978 public void setRecentsLabel(IBinder token, CharSequence recentsLabel) { 6979 synchronized (this) { 6980 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6981 if (r != null) { 6982 r.recentsLabel = recentsLabel.toString(); 6983 } 6984 } 6985 } 6986 6987 @Override 6988 public void setRecentsIcon(IBinder token, Bitmap recentsIcon) { 6989 synchronized (this) { 6990 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6991 if (r != null) { 6992 r.recentsIcon = recentsIcon; 6993 } 6994 } 6995 } 6996 6997 @Override 6998 public boolean removeSubTask(int taskId, int subTaskIndex) { 6999 synchronized (this) { 7000 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7001 "removeSubTask()"); 7002 long ident = Binder.clearCallingIdentity(); 7003 try { 7004 TaskRecord tr = recentTaskForIdLocked(taskId); 7005 if (tr != null) { 7006 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7007 } 7008 return false; 7009 } finally { 7010 Binder.restoreCallingIdentity(ident); 7011 } 7012 } 7013 } 7014 7015 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7016 if (!pr.killedByAm) { 7017 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7018 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7019 pr.processName, pr.setAdj, reason); 7020 pr.killedByAm = true; 7021 Process.killProcessQuiet(pr.pid); 7022 } 7023 } 7024 7025 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7026 tr.disposeThumbnail(); 7027 mRecentTasks.remove(tr); 7028 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7029 Intent baseIntent = new Intent( 7030 tr.intent != null ? tr.intent : tr.affinityIntent); 7031 ComponentName component = baseIntent.getComponent(); 7032 if (component == null) { 7033 Slog.w(TAG, "Now component for base intent of task: " + tr); 7034 return; 7035 } 7036 7037 // Find any running services associated with this app. 7038 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7039 7040 if (killProcesses) { 7041 // Find any running processes associated with this app. 7042 final String pkg = component.getPackageName(); 7043 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7044 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7045 for (int i=0; i<pmap.size(); i++) { 7046 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7047 for (int j=0; j<uids.size(); j++) { 7048 ProcessRecord proc = uids.valueAt(j); 7049 if (proc.userId != tr.userId) { 7050 continue; 7051 } 7052 if (!proc.pkgList.containsKey(pkg)) { 7053 continue; 7054 } 7055 procs.add(proc); 7056 } 7057 } 7058 7059 // Kill the running processes. 7060 for (int i=0; i<procs.size(); i++) { 7061 ProcessRecord pr = procs.get(i); 7062 if (pr == mHomeProcess) { 7063 // Don't kill the home process along with tasks from the same package. 7064 continue; 7065 } 7066 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7067 killUnneededProcessLocked(pr, "remove task"); 7068 } else { 7069 pr.waitingToKill = "remove task"; 7070 } 7071 } 7072 } 7073 } 7074 7075 @Override 7076 public boolean removeTask(int taskId, int flags) { 7077 synchronized (this) { 7078 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7079 "removeTask()"); 7080 long ident = Binder.clearCallingIdentity(); 7081 try { 7082 TaskRecord tr = recentTaskForIdLocked(taskId); 7083 if (tr != null) { 7084 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7085 if (r != null) { 7086 cleanUpRemovedTaskLocked(tr, flags); 7087 return true; 7088 } 7089 if (tr.mActivities.size() == 0) { 7090 // Caller is just removing a recent task that is 7091 // not actively running. That is easy! 7092 cleanUpRemovedTaskLocked(tr, flags); 7093 return true; 7094 } 7095 Slog.w(TAG, "removeTask: task " + taskId 7096 + " does not have activities to remove, " 7097 + " but numActivities=" + tr.numActivities 7098 + ": " + tr); 7099 } 7100 } finally { 7101 Binder.restoreCallingIdentity(ident); 7102 } 7103 } 7104 return false; 7105 } 7106 7107 /** 7108 * TODO: Add mController hook 7109 */ 7110 @Override 7111 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7112 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7113 "moveTaskToFront()"); 7114 7115 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7116 synchronized(this) { 7117 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7118 Binder.getCallingUid(), "Task to front")) { 7119 ActivityOptions.abort(options); 7120 return; 7121 } 7122 final long origId = Binder.clearCallingIdentity(); 7123 try { 7124 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7125 if (task == null) { 7126 return; 7127 } 7128 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7129 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7130 return; 7131 } 7132 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7133 } finally { 7134 Binder.restoreCallingIdentity(origId); 7135 } 7136 ActivityOptions.abort(options); 7137 } 7138 } 7139 7140 @Override 7141 public void moveTaskToBack(int taskId) { 7142 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7143 "moveTaskToBack()"); 7144 7145 synchronized(this) { 7146 TaskRecord tr = recentTaskForIdLocked(taskId); 7147 if (tr != null) { 7148 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7149 ActivityStack stack = tr.stack; 7150 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7151 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7152 Binder.getCallingUid(), "Task to back")) { 7153 return; 7154 } 7155 } 7156 final long origId = Binder.clearCallingIdentity(); 7157 try { 7158 stack.moveTaskToBackLocked(taskId, null); 7159 } finally { 7160 Binder.restoreCallingIdentity(origId); 7161 } 7162 } 7163 } 7164 } 7165 7166 /** 7167 * Moves an activity, and all of the other activities within the same task, to the bottom 7168 * of the history stack. The activity's order within the task is unchanged. 7169 * 7170 * @param token A reference to the activity we wish to move 7171 * @param nonRoot If false then this only works if the activity is the root 7172 * of a task; if true it will work for any activity in a task. 7173 * @return Returns true if the move completed, false if not. 7174 */ 7175 @Override 7176 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7177 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7178 synchronized(this) { 7179 final long origId = Binder.clearCallingIdentity(); 7180 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7181 if (taskId >= 0) { 7182 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7183 } 7184 Binder.restoreCallingIdentity(origId); 7185 } 7186 return false; 7187 } 7188 7189 @Override 7190 public void moveTaskBackwards(int task) { 7191 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7192 "moveTaskBackwards()"); 7193 7194 synchronized(this) { 7195 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7196 Binder.getCallingUid(), "Task backwards")) { 7197 return; 7198 } 7199 final long origId = Binder.clearCallingIdentity(); 7200 moveTaskBackwardsLocked(task); 7201 Binder.restoreCallingIdentity(origId); 7202 } 7203 } 7204 7205 private final void moveTaskBackwardsLocked(int task) { 7206 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7207 } 7208 7209 @Override 7210 public IBinder getHomeActivityToken() throws RemoteException { 7211 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7212 "getHomeActivityToken()"); 7213 synchronized (this) { 7214 return mStackSupervisor.getHomeActivityToken(); 7215 } 7216 } 7217 7218 @Override 7219 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7220 IActivityContainerCallback callback) throws RemoteException { 7221 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7222 "createActivityContainer()"); 7223 synchronized (this) { 7224 if (parentActivityToken == null) { 7225 throw new IllegalArgumentException("parent token must not be null"); 7226 } 7227 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7228 if (r == null) { 7229 return null; 7230 } 7231 return mStackSupervisor.createActivityContainer(r, callback); 7232 } 7233 } 7234 7235 @Override 7236 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7237 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7238 "deleteActivityContainer()"); 7239 synchronized (this) { 7240 mStackSupervisor.deleteActivityContainer(container); 7241 } 7242 } 7243 7244 @Override 7245 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7246 throws RemoteException { 7247 synchronized (this) { 7248 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7249 if (stack != null) { 7250 return stack.mActivityContainer; 7251 } 7252 return null; 7253 } 7254 } 7255 7256 @Override 7257 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7258 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7259 "moveTaskToStack()"); 7260 if (stackId == HOME_STACK_ID) { 7261 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7262 new RuntimeException("here").fillInStackTrace()); 7263 } 7264 synchronized (this) { 7265 long ident = Binder.clearCallingIdentity(); 7266 try { 7267 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7268 + stackId + " toTop=" + toTop); 7269 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7270 } finally { 7271 Binder.restoreCallingIdentity(ident); 7272 } 7273 } 7274 } 7275 7276 @Override 7277 public void resizeStack(int stackBoxId, Rect bounds) { 7278 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7279 "resizeStackBox()"); 7280 long ident = Binder.clearCallingIdentity(); 7281 try { 7282 mWindowManager.resizeStack(stackBoxId, bounds); 7283 } finally { 7284 Binder.restoreCallingIdentity(ident); 7285 } 7286 } 7287 7288 @Override 7289 public List<StackInfo> getAllStackInfos() { 7290 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7291 "getAllStackInfos()"); 7292 long ident = Binder.clearCallingIdentity(); 7293 try { 7294 synchronized (this) { 7295 return mStackSupervisor.getAllStackInfosLocked(); 7296 } 7297 } finally { 7298 Binder.restoreCallingIdentity(ident); 7299 } 7300 } 7301 7302 @Override 7303 public StackInfo getStackInfo(int stackId) { 7304 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7305 "getStackInfo()"); 7306 long ident = Binder.clearCallingIdentity(); 7307 try { 7308 synchronized (this) { 7309 return mStackSupervisor.getStackInfoLocked(stackId); 7310 } 7311 } finally { 7312 Binder.restoreCallingIdentity(ident); 7313 } 7314 } 7315 7316 @Override 7317 public boolean isInHomeStack(int taskId) { 7318 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7319 "getStackInfo()"); 7320 long ident = Binder.clearCallingIdentity(); 7321 try { 7322 synchronized (this) { 7323 TaskRecord tr = recentTaskForIdLocked(taskId); 7324 if (tr != null) { 7325 return tr.stack.isHomeStack(); 7326 } 7327 } 7328 } finally { 7329 Binder.restoreCallingIdentity(ident); 7330 } 7331 return false; 7332 } 7333 7334 @Override 7335 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7336 synchronized(this) { 7337 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7338 } 7339 } 7340 7341 private boolean isLockTaskAuthorized(ComponentName name) { 7342// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7343// "startLockTaskMode()"); 7344// DevicePolicyManager dpm = (DevicePolicyManager) 7345// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7346// return dpm != null && dpm.isLockTaskPermitted(name); 7347 return true; 7348 } 7349 7350 private void startLockTaskMode(TaskRecord task) { 7351 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7352 return; 7353 } 7354 long ident = Binder.clearCallingIdentity(); 7355 try { 7356 synchronized (this) { 7357 // Since we lost lock on task, make sure it is still there. 7358 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7359 if (task != null) { 7360 mStackSupervisor.setLockTaskModeLocked(task); 7361 } 7362 } 7363 } finally { 7364 Binder.restoreCallingIdentity(ident); 7365 } 7366 } 7367 7368 @Override 7369 public void startLockTaskMode(int taskId) { 7370 long ident = Binder.clearCallingIdentity(); 7371 try { 7372 final TaskRecord task; 7373 synchronized (this) { 7374 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7375 } 7376 if (task != null) { 7377 startLockTaskMode(task); 7378 } 7379 } finally { 7380 Binder.restoreCallingIdentity(ident); 7381 } 7382 } 7383 7384 @Override 7385 public void startLockTaskMode(IBinder token) { 7386 long ident = Binder.clearCallingIdentity(); 7387 try { 7388 final TaskRecord task; 7389 synchronized (this) { 7390 final ActivityRecord r = ActivityRecord.forToken(token); 7391 if (r == null) { 7392 return; 7393 } 7394 task = r.task; 7395 } 7396 if (task != null) { 7397 startLockTaskMode(task); 7398 } 7399 } finally { 7400 Binder.restoreCallingIdentity(ident); 7401 } 7402 } 7403 7404 @Override 7405 public void stopLockTaskMode() { 7406// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7407// "stopLockTaskMode()"); 7408 synchronized (this) { 7409 mStackSupervisor.setLockTaskModeLocked(null); 7410 } 7411 } 7412 7413 @Override 7414 public boolean isInLockTaskMode() { 7415 synchronized (this) { 7416 return mStackSupervisor.isInLockTaskMode(); 7417 } 7418 } 7419 7420 // ========================================================= 7421 // THUMBNAILS 7422 // ========================================================= 7423 7424 public void reportThumbnail(IBinder token, 7425 Bitmap thumbnail, CharSequence description) { 7426 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7427 final long origId = Binder.clearCallingIdentity(); 7428 sendPendingThumbnail(null, token, thumbnail, description, true); 7429 Binder.restoreCallingIdentity(origId); 7430 } 7431 7432 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7433 Bitmap thumbnail, CharSequence description, boolean always) { 7434 TaskRecord task; 7435 ArrayList<PendingThumbnailsRecord> receivers = null; 7436 7437 //System.out.println("Send pending thumbnail: " + r); 7438 7439 synchronized(this) { 7440 if (r == null) { 7441 r = ActivityRecord.isInStackLocked(token); 7442 if (r == null) { 7443 return; 7444 } 7445 } 7446 if (thumbnail == null && r.thumbHolder != null) { 7447 thumbnail = r.thumbHolder.lastThumbnail; 7448 description = r.thumbHolder.lastDescription; 7449 } 7450 if (thumbnail == null && !always) { 7451 // If there is no thumbnail, and this entry is not actually 7452 // going away, then abort for now and pick up the next 7453 // thumbnail we get. 7454 return; 7455 } 7456 task = r.task; 7457 7458 int N = mPendingThumbnails.size(); 7459 int i=0; 7460 while (i<N) { 7461 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7462 //System.out.println("Looking in " + pr.pendingRecords); 7463 if (pr.pendingRecords.remove(r)) { 7464 if (receivers == null) { 7465 receivers = new ArrayList<PendingThumbnailsRecord>(); 7466 } 7467 receivers.add(pr); 7468 if (pr.pendingRecords.size() == 0) { 7469 pr.finished = true; 7470 mPendingThumbnails.remove(i); 7471 N--; 7472 continue; 7473 } 7474 } 7475 i++; 7476 } 7477 } 7478 7479 if (receivers != null) { 7480 final int N = receivers.size(); 7481 for (int i=0; i<N; i++) { 7482 try { 7483 PendingThumbnailsRecord pr = receivers.get(i); 7484 pr.receiver.newThumbnail( 7485 task != null ? task.taskId : -1, thumbnail, description); 7486 if (pr.finished) { 7487 pr.receiver.finished(); 7488 } 7489 } catch (Exception e) { 7490 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7491 } 7492 } 7493 } 7494 } 7495 7496 // ========================================================= 7497 // CONTENT PROVIDERS 7498 // ========================================================= 7499 7500 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7501 List<ProviderInfo> providers = null; 7502 try { 7503 providers = AppGlobals.getPackageManager(). 7504 queryContentProviders(app.processName, app.uid, 7505 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7506 } catch (RemoteException ex) { 7507 } 7508 if (DEBUG_MU) 7509 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7510 int userId = app.userId; 7511 if (providers != null) { 7512 int N = providers.size(); 7513 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7514 for (int i=0; i<N; i++) { 7515 ProviderInfo cpi = 7516 (ProviderInfo)providers.get(i); 7517 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7518 cpi.name, cpi.flags); 7519 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7520 // This is a singleton provider, but a user besides the 7521 // default user is asking to initialize a process it runs 7522 // in... well, no, it doesn't actually run in this process, 7523 // it runs in the process of the default user. Get rid of it. 7524 providers.remove(i); 7525 N--; 7526 i--; 7527 continue; 7528 } 7529 7530 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7531 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7532 if (cpr == null) { 7533 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7534 mProviderMap.putProviderByClass(comp, cpr); 7535 } 7536 if (DEBUG_MU) 7537 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7538 app.pubProviders.put(cpi.name, cpr); 7539 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7540 // Don't add this if it is a platform component that is marked 7541 // to run in multiple processes, because this is actually 7542 // part of the framework so doesn't make sense to track as a 7543 // separate apk in the process. 7544 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7545 } 7546 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7547 } 7548 } 7549 return providers; 7550 } 7551 7552 /** 7553 * Check if {@link ProcessRecord} has a possible chance at accessing the 7554 * given {@link ProviderInfo}. Final permission checking is always done 7555 * in {@link ContentProvider}. 7556 */ 7557 private final String checkContentProviderPermissionLocked( 7558 ProviderInfo cpi, ProcessRecord r) { 7559 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7560 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7561 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7562 cpi.applicationInfo.uid, cpi.exported) 7563 == PackageManager.PERMISSION_GRANTED) { 7564 return null; 7565 } 7566 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7567 cpi.applicationInfo.uid, cpi.exported) 7568 == PackageManager.PERMISSION_GRANTED) { 7569 return null; 7570 } 7571 7572 PathPermission[] pps = cpi.pathPermissions; 7573 if (pps != null) { 7574 int i = pps.length; 7575 while (i > 0) { 7576 i--; 7577 PathPermission pp = pps[i]; 7578 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7579 cpi.applicationInfo.uid, cpi.exported) 7580 == PackageManager.PERMISSION_GRANTED) { 7581 return null; 7582 } 7583 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7584 cpi.applicationInfo.uid, cpi.exported) 7585 == PackageManager.PERMISSION_GRANTED) { 7586 return null; 7587 } 7588 } 7589 } 7590 7591 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7592 if (perms != null) { 7593 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7594 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7595 return null; 7596 } 7597 } 7598 } 7599 7600 String msg; 7601 if (!cpi.exported) { 7602 msg = "Permission Denial: opening provider " + cpi.name 7603 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7604 + ", uid=" + callingUid + ") that is not exported from uid " 7605 + cpi.applicationInfo.uid; 7606 } else { 7607 msg = "Permission Denial: opening provider " + cpi.name 7608 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7609 + ", uid=" + callingUid + ") requires " 7610 + cpi.readPermission + " or " + cpi.writePermission; 7611 } 7612 Slog.w(TAG, msg); 7613 return msg; 7614 } 7615 7616 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7617 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7618 if (r != null) { 7619 for (int i=0; i<r.conProviders.size(); i++) { 7620 ContentProviderConnection conn = r.conProviders.get(i); 7621 if (conn.provider == cpr) { 7622 if (DEBUG_PROVIDER) Slog.v(TAG, 7623 "Adding provider requested by " 7624 + r.processName + " from process " 7625 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7626 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7627 if (stable) { 7628 conn.stableCount++; 7629 conn.numStableIncs++; 7630 } else { 7631 conn.unstableCount++; 7632 conn.numUnstableIncs++; 7633 } 7634 return conn; 7635 } 7636 } 7637 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7638 if (stable) { 7639 conn.stableCount = 1; 7640 conn.numStableIncs = 1; 7641 } else { 7642 conn.unstableCount = 1; 7643 conn.numUnstableIncs = 1; 7644 } 7645 cpr.connections.add(conn); 7646 r.conProviders.add(conn); 7647 return conn; 7648 } 7649 cpr.addExternalProcessHandleLocked(externalProcessToken); 7650 return null; 7651 } 7652 7653 boolean decProviderCountLocked(ContentProviderConnection conn, 7654 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7655 if (conn != null) { 7656 cpr = conn.provider; 7657 if (DEBUG_PROVIDER) Slog.v(TAG, 7658 "Removing provider requested by " 7659 + conn.client.processName + " from process " 7660 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7661 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7662 if (stable) { 7663 conn.stableCount--; 7664 } else { 7665 conn.unstableCount--; 7666 } 7667 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7668 cpr.connections.remove(conn); 7669 conn.client.conProviders.remove(conn); 7670 return true; 7671 } 7672 return false; 7673 } 7674 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7675 return false; 7676 } 7677 7678 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7679 String name, IBinder token, boolean stable, int userId) { 7680 ContentProviderRecord cpr; 7681 ContentProviderConnection conn = null; 7682 ProviderInfo cpi = null; 7683 7684 synchronized(this) { 7685 ProcessRecord r = null; 7686 if (caller != null) { 7687 r = getRecordForAppLocked(caller); 7688 if (r == null) { 7689 throw new SecurityException( 7690 "Unable to find app for caller " + caller 7691 + " (pid=" + Binder.getCallingPid() 7692 + ") when getting content provider " + name); 7693 } 7694 } 7695 7696 // First check if this content provider has been published... 7697 cpr = mProviderMap.getProviderByName(name, userId); 7698 boolean providerRunning = cpr != null; 7699 if (providerRunning) { 7700 cpi = cpr.info; 7701 String msg; 7702 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7703 throw new SecurityException(msg); 7704 } 7705 7706 if (r != null && cpr.canRunHere(r)) { 7707 // This provider has been published or is in the process 7708 // of being published... but it is also allowed to run 7709 // in the caller's process, so don't make a connection 7710 // and just let the caller instantiate its own instance. 7711 ContentProviderHolder holder = cpr.newHolder(null); 7712 // don't give caller the provider object, it needs 7713 // to make its own. 7714 holder.provider = null; 7715 return holder; 7716 } 7717 7718 final long origId = Binder.clearCallingIdentity(); 7719 7720 // In this case the provider instance already exists, so we can 7721 // return it right away. 7722 conn = incProviderCountLocked(r, cpr, token, stable); 7723 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7724 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7725 // If this is a perceptible app accessing the provider, 7726 // make sure to count it as being accessed and thus 7727 // back up on the LRU list. This is good because 7728 // content providers are often expensive to start. 7729 updateLruProcessLocked(cpr.proc, false, null); 7730 } 7731 } 7732 7733 if (cpr.proc != null) { 7734 if (false) { 7735 if (cpr.name.flattenToShortString().equals( 7736 "com.android.providers.calendar/.CalendarProvider2")) { 7737 Slog.v(TAG, "****************** KILLING " 7738 + cpr.name.flattenToShortString()); 7739 Process.killProcess(cpr.proc.pid); 7740 } 7741 } 7742 boolean success = updateOomAdjLocked(cpr.proc); 7743 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7744 // NOTE: there is still a race here where a signal could be 7745 // pending on the process even though we managed to update its 7746 // adj level. Not sure what to do about this, but at least 7747 // the race is now smaller. 7748 if (!success) { 7749 // Uh oh... it looks like the provider's process 7750 // has been killed on us. We need to wait for a new 7751 // process to be started, and make sure its death 7752 // doesn't kill our process. 7753 Slog.i(TAG, 7754 "Existing provider " + cpr.name.flattenToShortString() 7755 + " is crashing; detaching " + r); 7756 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7757 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7758 if (!lastRef) { 7759 // This wasn't the last ref our process had on 7760 // the provider... we have now been killed, bail. 7761 return null; 7762 } 7763 providerRunning = false; 7764 conn = null; 7765 } 7766 } 7767 7768 Binder.restoreCallingIdentity(origId); 7769 } 7770 7771 boolean singleton; 7772 if (!providerRunning) { 7773 try { 7774 cpi = AppGlobals.getPackageManager(). 7775 resolveContentProvider(name, 7776 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7777 } catch (RemoteException ex) { 7778 } 7779 if (cpi == null) { 7780 return null; 7781 } 7782 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7783 cpi.name, cpi.flags); 7784 if (singleton) { 7785 userId = 0; 7786 } 7787 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7788 7789 String msg; 7790 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7791 throw new SecurityException(msg); 7792 } 7793 7794 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7795 && !cpi.processName.equals("system")) { 7796 // If this content provider does not run in the system 7797 // process, and the system is not yet ready to run other 7798 // processes, then fail fast instead of hanging. 7799 throw new IllegalArgumentException( 7800 "Attempt to launch content provider before system ready"); 7801 } 7802 7803 // Make sure that the user who owns this provider is started. If not, 7804 // we don't want to allow it to run. 7805 if (mStartedUsers.get(userId) == null) { 7806 Slog.w(TAG, "Unable to launch app " 7807 + cpi.applicationInfo.packageName + "/" 7808 + cpi.applicationInfo.uid + " for provider " 7809 + name + ": user " + userId + " is stopped"); 7810 return null; 7811 } 7812 7813 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7814 cpr = mProviderMap.getProviderByClass(comp, userId); 7815 final boolean firstClass = cpr == null; 7816 if (firstClass) { 7817 try { 7818 ApplicationInfo ai = 7819 AppGlobals.getPackageManager(). 7820 getApplicationInfo( 7821 cpi.applicationInfo.packageName, 7822 STOCK_PM_FLAGS, userId); 7823 if (ai == null) { 7824 Slog.w(TAG, "No package info for content provider " 7825 + cpi.name); 7826 return null; 7827 } 7828 ai = getAppInfoForUser(ai, userId); 7829 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7830 } catch (RemoteException ex) { 7831 // pm is in same process, this will never happen. 7832 } 7833 } 7834 7835 if (r != null && cpr.canRunHere(r)) { 7836 // If this is a multiprocess provider, then just return its 7837 // info and allow the caller to instantiate it. Only do 7838 // this if the provider is the same user as the caller's 7839 // process, or can run as root (so can be in any process). 7840 return cpr.newHolder(null); 7841 } 7842 7843 if (DEBUG_PROVIDER) { 7844 RuntimeException e = new RuntimeException("here"); 7845 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7846 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7847 } 7848 7849 // This is single process, and our app is now connecting to it. 7850 // See if we are already in the process of launching this 7851 // provider. 7852 final int N = mLaunchingProviders.size(); 7853 int i; 7854 for (i=0; i<N; i++) { 7855 if (mLaunchingProviders.get(i) == cpr) { 7856 break; 7857 } 7858 } 7859 7860 // If the provider is not already being launched, then get it 7861 // started. 7862 if (i >= N) { 7863 final long origId = Binder.clearCallingIdentity(); 7864 7865 try { 7866 // Content provider is now in use, its package can't be stopped. 7867 try { 7868 AppGlobals.getPackageManager().setPackageStoppedState( 7869 cpr.appInfo.packageName, false, userId); 7870 } catch (RemoteException e) { 7871 } catch (IllegalArgumentException e) { 7872 Slog.w(TAG, "Failed trying to unstop package " 7873 + cpr.appInfo.packageName + ": " + e); 7874 } 7875 7876 // Use existing process if already started 7877 ProcessRecord proc = getProcessRecordLocked( 7878 cpi.processName, cpr.appInfo.uid, false); 7879 if (proc != null && proc.thread != null) { 7880 if (DEBUG_PROVIDER) { 7881 Slog.d(TAG, "Installing in existing process " + proc); 7882 } 7883 proc.pubProviders.put(cpi.name, cpr); 7884 try { 7885 proc.thread.scheduleInstallProvider(cpi); 7886 } catch (RemoteException e) { 7887 } 7888 } else { 7889 proc = startProcessLocked(cpi.processName, 7890 cpr.appInfo, false, 0, "content provider", 7891 new ComponentName(cpi.applicationInfo.packageName, 7892 cpi.name), false, false, false); 7893 if (proc == null) { 7894 Slog.w(TAG, "Unable to launch app " 7895 + cpi.applicationInfo.packageName + "/" 7896 + cpi.applicationInfo.uid + " for provider " 7897 + name + ": process is bad"); 7898 return null; 7899 } 7900 } 7901 cpr.launchingApp = proc; 7902 mLaunchingProviders.add(cpr); 7903 } finally { 7904 Binder.restoreCallingIdentity(origId); 7905 } 7906 } 7907 7908 // Make sure the provider is published (the same provider class 7909 // may be published under multiple names). 7910 if (firstClass) { 7911 mProviderMap.putProviderByClass(comp, cpr); 7912 } 7913 7914 mProviderMap.putProviderByName(name, cpr); 7915 conn = incProviderCountLocked(r, cpr, token, stable); 7916 if (conn != null) { 7917 conn.waiting = true; 7918 } 7919 } 7920 } 7921 7922 // Wait for the provider to be published... 7923 synchronized (cpr) { 7924 while (cpr.provider == null) { 7925 if (cpr.launchingApp == null) { 7926 Slog.w(TAG, "Unable to launch app " 7927 + cpi.applicationInfo.packageName + "/" 7928 + cpi.applicationInfo.uid + " for provider " 7929 + name + ": launching app became null"); 7930 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7931 UserHandle.getUserId(cpi.applicationInfo.uid), 7932 cpi.applicationInfo.packageName, 7933 cpi.applicationInfo.uid, name); 7934 return null; 7935 } 7936 try { 7937 if (DEBUG_MU) { 7938 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7939 + cpr.launchingApp); 7940 } 7941 if (conn != null) { 7942 conn.waiting = true; 7943 } 7944 cpr.wait(); 7945 } catch (InterruptedException ex) { 7946 } finally { 7947 if (conn != null) { 7948 conn.waiting = false; 7949 } 7950 } 7951 } 7952 } 7953 return cpr != null ? cpr.newHolder(conn) : null; 7954 } 7955 7956 public final ContentProviderHolder getContentProvider( 7957 IApplicationThread caller, String name, int userId, boolean stable) { 7958 enforceNotIsolatedCaller("getContentProvider"); 7959 if (caller == null) { 7960 String msg = "null IApplicationThread when getting content provider " 7961 + name; 7962 Slog.w(TAG, msg); 7963 throw new SecurityException(msg); 7964 } 7965 7966 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7967 false, true, "getContentProvider", null); 7968 return getContentProviderImpl(caller, name, null, stable, userId); 7969 } 7970 7971 public ContentProviderHolder getContentProviderExternal( 7972 String name, int userId, IBinder token) { 7973 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7974 "Do not have permission in call getContentProviderExternal()"); 7975 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7976 false, true, "getContentProvider", null); 7977 return getContentProviderExternalUnchecked(name, token, userId); 7978 } 7979 7980 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7981 IBinder token, int userId) { 7982 return getContentProviderImpl(null, name, token, true, userId); 7983 } 7984 7985 /** 7986 * Drop a content provider from a ProcessRecord's bookkeeping 7987 */ 7988 public void removeContentProvider(IBinder connection, boolean stable) { 7989 enforceNotIsolatedCaller("removeContentProvider"); 7990 long ident = Binder.clearCallingIdentity(); 7991 try { 7992 synchronized (this) { 7993 ContentProviderConnection conn; 7994 try { 7995 conn = (ContentProviderConnection)connection; 7996 } catch (ClassCastException e) { 7997 String msg ="removeContentProvider: " + connection 7998 + " not a ContentProviderConnection"; 7999 Slog.w(TAG, msg); 8000 throw new IllegalArgumentException(msg); 8001 } 8002 if (conn == null) { 8003 throw new NullPointerException("connection is null"); 8004 } 8005 if (decProviderCountLocked(conn, null, null, stable)) { 8006 updateOomAdjLocked(); 8007 } 8008 } 8009 } finally { 8010 Binder.restoreCallingIdentity(ident); 8011 } 8012 } 8013 8014 public void removeContentProviderExternal(String name, IBinder token) { 8015 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8016 "Do not have permission in call removeContentProviderExternal()"); 8017 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8018 } 8019 8020 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8021 synchronized (this) { 8022 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8023 if(cpr == null) { 8024 //remove from mProvidersByClass 8025 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8026 return; 8027 } 8028 8029 //update content provider record entry info 8030 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8031 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8032 if (localCpr.hasExternalProcessHandles()) { 8033 if (localCpr.removeExternalProcessHandleLocked(token)) { 8034 updateOomAdjLocked(); 8035 } else { 8036 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8037 + " with no external reference for token: " 8038 + token + "."); 8039 } 8040 } else { 8041 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8042 + " with no external references."); 8043 } 8044 } 8045 } 8046 8047 public final void publishContentProviders(IApplicationThread caller, 8048 List<ContentProviderHolder> providers) { 8049 if (providers == null) { 8050 return; 8051 } 8052 8053 enforceNotIsolatedCaller("publishContentProviders"); 8054 synchronized (this) { 8055 final ProcessRecord r = getRecordForAppLocked(caller); 8056 if (DEBUG_MU) 8057 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8058 if (r == null) { 8059 throw new SecurityException( 8060 "Unable to find app for caller " + caller 8061 + " (pid=" + Binder.getCallingPid() 8062 + ") when publishing content providers"); 8063 } 8064 8065 final long origId = Binder.clearCallingIdentity(); 8066 8067 final int N = providers.size(); 8068 for (int i=0; i<N; i++) { 8069 ContentProviderHolder src = providers.get(i); 8070 if (src == null || src.info == null || src.provider == null) { 8071 continue; 8072 } 8073 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8074 if (DEBUG_MU) 8075 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8076 if (dst != null) { 8077 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8078 mProviderMap.putProviderByClass(comp, dst); 8079 String names[] = dst.info.authority.split(";"); 8080 for (int j = 0; j < names.length; j++) { 8081 mProviderMap.putProviderByName(names[j], dst); 8082 } 8083 8084 int NL = mLaunchingProviders.size(); 8085 int j; 8086 for (j=0; j<NL; j++) { 8087 if (mLaunchingProviders.get(j) == dst) { 8088 mLaunchingProviders.remove(j); 8089 j--; 8090 NL--; 8091 } 8092 } 8093 synchronized (dst) { 8094 dst.provider = src.provider; 8095 dst.proc = r; 8096 dst.notifyAll(); 8097 } 8098 updateOomAdjLocked(r); 8099 } 8100 } 8101 8102 Binder.restoreCallingIdentity(origId); 8103 } 8104 } 8105 8106 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8107 ContentProviderConnection conn; 8108 try { 8109 conn = (ContentProviderConnection)connection; 8110 } catch (ClassCastException e) { 8111 String msg ="refContentProvider: " + connection 8112 + " not a ContentProviderConnection"; 8113 Slog.w(TAG, msg); 8114 throw new IllegalArgumentException(msg); 8115 } 8116 if (conn == null) { 8117 throw new NullPointerException("connection is null"); 8118 } 8119 8120 synchronized (this) { 8121 if (stable > 0) { 8122 conn.numStableIncs += stable; 8123 } 8124 stable = conn.stableCount + stable; 8125 if (stable < 0) { 8126 throw new IllegalStateException("stableCount < 0: " + stable); 8127 } 8128 8129 if (unstable > 0) { 8130 conn.numUnstableIncs += unstable; 8131 } 8132 unstable = conn.unstableCount + unstable; 8133 if (unstable < 0) { 8134 throw new IllegalStateException("unstableCount < 0: " + unstable); 8135 } 8136 8137 if ((stable+unstable) <= 0) { 8138 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8139 + stable + " unstable=" + unstable); 8140 } 8141 conn.stableCount = stable; 8142 conn.unstableCount = unstable; 8143 return !conn.dead; 8144 } 8145 } 8146 8147 public void unstableProviderDied(IBinder connection) { 8148 ContentProviderConnection conn; 8149 try { 8150 conn = (ContentProviderConnection)connection; 8151 } catch (ClassCastException e) { 8152 String msg ="refContentProvider: " + connection 8153 + " not a ContentProviderConnection"; 8154 Slog.w(TAG, msg); 8155 throw new IllegalArgumentException(msg); 8156 } 8157 if (conn == null) { 8158 throw new NullPointerException("connection is null"); 8159 } 8160 8161 // Safely retrieve the content provider associated with the connection. 8162 IContentProvider provider; 8163 synchronized (this) { 8164 provider = conn.provider.provider; 8165 } 8166 8167 if (provider == null) { 8168 // Um, yeah, we're way ahead of you. 8169 return; 8170 } 8171 8172 // Make sure the caller is being honest with us. 8173 if (provider.asBinder().pingBinder()) { 8174 // Er, no, still looks good to us. 8175 synchronized (this) { 8176 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8177 + " says " + conn + " died, but we don't agree"); 8178 return; 8179 } 8180 } 8181 8182 // Well look at that! It's dead! 8183 synchronized (this) { 8184 if (conn.provider.provider != provider) { 8185 // But something changed... good enough. 8186 return; 8187 } 8188 8189 ProcessRecord proc = conn.provider.proc; 8190 if (proc == null || proc.thread == null) { 8191 // Seems like the process is already cleaned up. 8192 return; 8193 } 8194 8195 // As far as we're concerned, this is just like receiving a 8196 // death notification... just a bit prematurely. 8197 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8198 + ") early provider death"); 8199 final long ident = Binder.clearCallingIdentity(); 8200 try { 8201 appDiedLocked(proc, proc.pid, proc.thread); 8202 } finally { 8203 Binder.restoreCallingIdentity(ident); 8204 } 8205 } 8206 } 8207 8208 @Override 8209 public void appNotRespondingViaProvider(IBinder connection) { 8210 enforceCallingPermission( 8211 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8212 8213 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8214 if (conn == null) { 8215 Slog.w(TAG, "ContentProviderConnection is null"); 8216 return; 8217 } 8218 8219 final ProcessRecord host = conn.provider.proc; 8220 if (host == null) { 8221 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8222 return; 8223 } 8224 8225 final long token = Binder.clearCallingIdentity(); 8226 try { 8227 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8228 } finally { 8229 Binder.restoreCallingIdentity(token); 8230 } 8231 } 8232 8233 public final void installSystemProviders() { 8234 List<ProviderInfo> providers; 8235 synchronized (this) { 8236 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8237 providers = generateApplicationProvidersLocked(app); 8238 if (providers != null) { 8239 for (int i=providers.size()-1; i>=0; i--) { 8240 ProviderInfo pi = (ProviderInfo)providers.get(i); 8241 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8242 Slog.w(TAG, "Not installing system proc provider " + pi.name 8243 + ": not system .apk"); 8244 providers.remove(i); 8245 } 8246 } 8247 } 8248 } 8249 if (providers != null) { 8250 mSystemThread.installSystemProviders(providers); 8251 } 8252 8253 mCoreSettingsObserver = new CoreSettingsObserver(this); 8254 8255 mUsageStatsService.monitorPackages(); 8256 } 8257 8258 /** 8259 * Allows app to retrieve the MIME type of a URI without having permission 8260 * to access its content provider. 8261 * 8262 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8263 * 8264 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8265 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8266 */ 8267 public String getProviderMimeType(Uri uri, int userId) { 8268 enforceNotIsolatedCaller("getProviderMimeType"); 8269 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8270 userId, false, true, "getProviderMimeType", null); 8271 final String name = uri.getAuthority(); 8272 final long ident = Binder.clearCallingIdentity(); 8273 ContentProviderHolder holder = null; 8274 8275 try { 8276 holder = getContentProviderExternalUnchecked(name, null, userId); 8277 if (holder != null) { 8278 return holder.provider.getType(uri); 8279 } 8280 } catch (RemoteException e) { 8281 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8282 return null; 8283 } finally { 8284 if (holder != null) { 8285 removeContentProviderExternalUnchecked(name, null, userId); 8286 } 8287 Binder.restoreCallingIdentity(ident); 8288 } 8289 8290 return null; 8291 } 8292 8293 // ========================================================= 8294 // GLOBAL MANAGEMENT 8295 // ========================================================= 8296 8297 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8298 boolean isolated) { 8299 String proc = customProcess != null ? customProcess : info.processName; 8300 BatteryStatsImpl.Uid.Proc ps = null; 8301 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8302 int uid = info.uid; 8303 if (isolated) { 8304 int userId = UserHandle.getUserId(uid); 8305 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8306 while (true) { 8307 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8308 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8309 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8310 } 8311 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8312 mNextIsolatedProcessUid++; 8313 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8314 // No process for this uid, use it. 8315 break; 8316 } 8317 stepsLeft--; 8318 if (stepsLeft <= 0) { 8319 return null; 8320 } 8321 } 8322 } 8323 return new ProcessRecord(stats, info, proc, uid); 8324 } 8325 8326 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8327 ProcessRecord app; 8328 if (!isolated) { 8329 app = getProcessRecordLocked(info.processName, info.uid, true); 8330 } else { 8331 app = null; 8332 } 8333 8334 if (app == null) { 8335 app = newProcessRecordLocked(info, null, isolated); 8336 mProcessNames.put(info.processName, app.uid, app); 8337 if (isolated) { 8338 mIsolatedProcesses.put(app.uid, app); 8339 } 8340 updateLruProcessLocked(app, false, null); 8341 updateOomAdjLocked(); 8342 } 8343 8344 // This package really, really can not be stopped. 8345 try { 8346 AppGlobals.getPackageManager().setPackageStoppedState( 8347 info.packageName, false, UserHandle.getUserId(app.uid)); 8348 } catch (RemoteException e) { 8349 } catch (IllegalArgumentException e) { 8350 Slog.w(TAG, "Failed trying to unstop package " 8351 + info.packageName + ": " + e); 8352 } 8353 8354 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8355 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8356 app.persistent = true; 8357 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8358 } 8359 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8360 mPersistentStartingProcesses.add(app); 8361 startProcessLocked(app, "added application", app.processName); 8362 } 8363 8364 return app; 8365 } 8366 8367 public void unhandledBack() { 8368 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8369 "unhandledBack()"); 8370 8371 synchronized(this) { 8372 final long origId = Binder.clearCallingIdentity(); 8373 try { 8374 getFocusedStack().unhandledBackLocked(); 8375 } finally { 8376 Binder.restoreCallingIdentity(origId); 8377 } 8378 } 8379 } 8380 8381 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8382 enforceNotIsolatedCaller("openContentUri"); 8383 final int userId = UserHandle.getCallingUserId(); 8384 String name = uri.getAuthority(); 8385 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8386 ParcelFileDescriptor pfd = null; 8387 if (cph != null) { 8388 // We record the binder invoker's uid in thread-local storage before 8389 // going to the content provider to open the file. Later, in the code 8390 // that handles all permissions checks, we look for this uid and use 8391 // that rather than the Activity Manager's own uid. The effect is that 8392 // we do the check against the caller's permissions even though it looks 8393 // to the content provider like the Activity Manager itself is making 8394 // the request. 8395 sCallerIdentity.set(new Identity( 8396 Binder.getCallingPid(), Binder.getCallingUid())); 8397 try { 8398 pfd = cph.provider.openFile(null, uri, "r", null); 8399 } catch (FileNotFoundException e) { 8400 // do nothing; pfd will be returned null 8401 } finally { 8402 // Ensure that whatever happens, we clean up the identity state 8403 sCallerIdentity.remove(); 8404 } 8405 8406 // We've got the fd now, so we're done with the provider. 8407 removeContentProviderExternalUnchecked(name, null, userId); 8408 } else { 8409 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8410 } 8411 return pfd; 8412 } 8413 8414 // Actually is sleeping or shutting down or whatever else in the future 8415 // is an inactive state. 8416 public boolean isSleepingOrShuttingDown() { 8417 return mSleeping || mShuttingDown; 8418 } 8419 8420 public void goingToSleep() { 8421 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8422 != PackageManager.PERMISSION_GRANTED) { 8423 throw new SecurityException("Requires permission " 8424 + android.Manifest.permission.DEVICE_POWER); 8425 } 8426 8427 synchronized(this) { 8428 mWentToSleep = true; 8429 updateEventDispatchingLocked(); 8430 8431 if (!mSleeping) { 8432 mSleeping = true; 8433 mStackSupervisor.goingToSleepLocked(); 8434 8435 // Initialize the wake times of all processes. 8436 checkExcessivePowerUsageLocked(false); 8437 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8438 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8439 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8440 } 8441 } 8442 } 8443 8444 @Override 8445 public boolean shutdown(int timeout) { 8446 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8447 != PackageManager.PERMISSION_GRANTED) { 8448 throw new SecurityException("Requires permission " 8449 + android.Manifest.permission.SHUTDOWN); 8450 } 8451 8452 boolean timedout = false; 8453 8454 synchronized(this) { 8455 mShuttingDown = true; 8456 updateEventDispatchingLocked(); 8457 timedout = mStackSupervisor.shutdownLocked(timeout); 8458 } 8459 8460 mAppOpsService.shutdown(); 8461 mUsageStatsService.shutdown(); 8462 mBatteryStatsService.shutdown(); 8463 synchronized (this) { 8464 mProcessStats.shutdownLocked(); 8465 } 8466 8467 return timedout; 8468 } 8469 8470 public final void activitySlept(IBinder token) { 8471 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8472 8473 final long origId = Binder.clearCallingIdentity(); 8474 8475 synchronized (this) { 8476 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8477 if (r != null) { 8478 mStackSupervisor.activitySleptLocked(r); 8479 } 8480 } 8481 8482 Binder.restoreCallingIdentity(origId); 8483 } 8484 8485 void logLockScreen(String msg) { 8486 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8487 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8488 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8489 mStackSupervisor.mDismissKeyguardOnNextActivity); 8490 } 8491 8492 private void comeOutOfSleepIfNeededLocked() { 8493 if (!mWentToSleep && !mLockScreenShown) { 8494 if (mSleeping) { 8495 mSleeping = false; 8496 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8497 } 8498 } 8499 } 8500 8501 public void wakingUp() { 8502 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8503 != PackageManager.PERMISSION_GRANTED) { 8504 throw new SecurityException("Requires permission " 8505 + android.Manifest.permission.DEVICE_POWER); 8506 } 8507 8508 synchronized(this) { 8509 mWentToSleep = false; 8510 updateEventDispatchingLocked(); 8511 comeOutOfSleepIfNeededLocked(); 8512 } 8513 } 8514 8515 private void updateEventDispatchingLocked() { 8516 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8517 } 8518 8519 public void setLockScreenShown(boolean shown) { 8520 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8521 != PackageManager.PERMISSION_GRANTED) { 8522 throw new SecurityException("Requires permission " 8523 + android.Manifest.permission.DEVICE_POWER); 8524 } 8525 8526 synchronized(this) { 8527 long ident = Binder.clearCallingIdentity(); 8528 try { 8529 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8530 mLockScreenShown = shown; 8531 comeOutOfSleepIfNeededLocked(); 8532 } finally { 8533 Binder.restoreCallingIdentity(ident); 8534 } 8535 } 8536 } 8537 8538 public void stopAppSwitches() { 8539 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8540 != PackageManager.PERMISSION_GRANTED) { 8541 throw new SecurityException("Requires permission " 8542 + android.Manifest.permission.STOP_APP_SWITCHES); 8543 } 8544 8545 synchronized(this) { 8546 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8547 + APP_SWITCH_DELAY_TIME; 8548 mDidAppSwitch = false; 8549 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8550 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8551 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8552 } 8553 } 8554 8555 public void resumeAppSwitches() { 8556 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8557 != PackageManager.PERMISSION_GRANTED) { 8558 throw new SecurityException("Requires permission " 8559 + android.Manifest.permission.STOP_APP_SWITCHES); 8560 } 8561 8562 synchronized(this) { 8563 // Note that we don't execute any pending app switches... we will 8564 // let those wait until either the timeout, or the next start 8565 // activity request. 8566 mAppSwitchesAllowedTime = 0; 8567 } 8568 } 8569 8570 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8571 String name) { 8572 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8573 return true; 8574 } 8575 8576 final int perm = checkComponentPermission( 8577 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8578 callingUid, -1, true); 8579 if (perm == PackageManager.PERMISSION_GRANTED) { 8580 return true; 8581 } 8582 8583 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8584 return false; 8585 } 8586 8587 public void setDebugApp(String packageName, boolean waitForDebugger, 8588 boolean persistent) { 8589 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8590 "setDebugApp()"); 8591 8592 long ident = Binder.clearCallingIdentity(); 8593 try { 8594 // Note that this is not really thread safe if there are multiple 8595 // callers into it at the same time, but that's not a situation we 8596 // care about. 8597 if (persistent) { 8598 final ContentResolver resolver = mContext.getContentResolver(); 8599 Settings.Global.putString( 8600 resolver, Settings.Global.DEBUG_APP, 8601 packageName); 8602 Settings.Global.putInt( 8603 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8604 waitForDebugger ? 1 : 0); 8605 } 8606 8607 synchronized (this) { 8608 if (!persistent) { 8609 mOrigDebugApp = mDebugApp; 8610 mOrigWaitForDebugger = mWaitForDebugger; 8611 } 8612 mDebugApp = packageName; 8613 mWaitForDebugger = waitForDebugger; 8614 mDebugTransient = !persistent; 8615 if (packageName != null) { 8616 forceStopPackageLocked(packageName, -1, false, false, true, true, 8617 false, UserHandle.USER_ALL, "set debug app"); 8618 } 8619 } 8620 } finally { 8621 Binder.restoreCallingIdentity(ident); 8622 } 8623 } 8624 8625 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8626 synchronized (this) { 8627 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8628 if (!isDebuggable) { 8629 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8630 throw new SecurityException("Process not debuggable: " + app.packageName); 8631 } 8632 } 8633 8634 mOpenGlTraceApp = processName; 8635 } 8636 } 8637 8638 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8639 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8640 synchronized (this) { 8641 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8642 if (!isDebuggable) { 8643 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8644 throw new SecurityException("Process not debuggable: " + app.packageName); 8645 } 8646 } 8647 mProfileApp = processName; 8648 mProfileFile = profileFile; 8649 if (mProfileFd != null) { 8650 try { 8651 mProfileFd.close(); 8652 } catch (IOException e) { 8653 } 8654 mProfileFd = null; 8655 } 8656 mProfileFd = profileFd; 8657 mProfileType = 0; 8658 mAutoStopProfiler = autoStopProfiler; 8659 } 8660 } 8661 8662 @Override 8663 public void setAlwaysFinish(boolean enabled) { 8664 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8665 "setAlwaysFinish()"); 8666 8667 Settings.Global.putInt( 8668 mContext.getContentResolver(), 8669 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8670 8671 synchronized (this) { 8672 mAlwaysFinishActivities = enabled; 8673 } 8674 } 8675 8676 @Override 8677 public void setActivityController(IActivityController controller) { 8678 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8679 "setActivityController()"); 8680 synchronized (this) { 8681 mController = controller; 8682 Watchdog.getInstance().setActivityController(controller); 8683 } 8684 } 8685 8686 @Override 8687 public void setUserIsMonkey(boolean userIsMonkey) { 8688 synchronized (this) { 8689 synchronized (mPidsSelfLocked) { 8690 final int callingPid = Binder.getCallingPid(); 8691 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8692 if (precessRecord == null) { 8693 throw new SecurityException("Unknown process: " + callingPid); 8694 } 8695 if (precessRecord.instrumentationUiAutomationConnection == null) { 8696 throw new SecurityException("Only an instrumentation process " 8697 + "with a UiAutomation can call setUserIsMonkey"); 8698 } 8699 } 8700 mUserIsMonkey = userIsMonkey; 8701 } 8702 } 8703 8704 @Override 8705 public boolean isUserAMonkey() { 8706 synchronized (this) { 8707 // If there is a controller also implies the user is a monkey. 8708 return (mUserIsMonkey || mController != null); 8709 } 8710 } 8711 8712 public void requestBugReport() { 8713 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8714 SystemProperties.set("ctl.start", "bugreport"); 8715 } 8716 8717 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8718 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8719 } 8720 8721 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8722 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8723 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8724 } 8725 return KEY_DISPATCHING_TIMEOUT; 8726 } 8727 8728 @Override 8729 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8730 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8731 != PackageManager.PERMISSION_GRANTED) { 8732 throw new SecurityException("Requires permission " 8733 + android.Manifest.permission.FILTER_EVENTS); 8734 } 8735 ProcessRecord proc; 8736 long timeout; 8737 synchronized (this) { 8738 synchronized (mPidsSelfLocked) { 8739 proc = mPidsSelfLocked.get(pid); 8740 } 8741 timeout = getInputDispatchingTimeoutLocked(proc); 8742 } 8743 8744 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8745 return -1; 8746 } 8747 8748 return timeout; 8749 } 8750 8751 /** 8752 * Handle input dispatching timeouts. 8753 * Returns whether input dispatching should be aborted or not. 8754 */ 8755 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8756 final ActivityRecord activity, final ActivityRecord parent, 8757 final boolean aboveSystem, String reason) { 8758 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8759 != PackageManager.PERMISSION_GRANTED) { 8760 throw new SecurityException("Requires permission " 8761 + android.Manifest.permission.FILTER_EVENTS); 8762 } 8763 8764 final String annotation; 8765 if (reason == null) { 8766 annotation = "Input dispatching timed out"; 8767 } else { 8768 annotation = "Input dispatching timed out (" + reason + ")"; 8769 } 8770 8771 if (proc != null) { 8772 synchronized (this) { 8773 if (proc.debugging) { 8774 return false; 8775 } 8776 8777 if (mDidDexOpt) { 8778 // Give more time since we were dexopting. 8779 mDidDexOpt = false; 8780 return false; 8781 } 8782 8783 if (proc.instrumentationClass != null) { 8784 Bundle info = new Bundle(); 8785 info.putString("shortMsg", "keyDispatchingTimedOut"); 8786 info.putString("longMsg", annotation); 8787 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8788 return true; 8789 } 8790 } 8791 mHandler.post(new Runnable() { 8792 @Override 8793 public void run() { 8794 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8795 } 8796 }); 8797 } 8798 8799 return true; 8800 } 8801 8802 public Bundle getAssistContextExtras(int requestType) { 8803 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8804 "getAssistContextExtras()"); 8805 PendingAssistExtras pae; 8806 Bundle extras = new Bundle(); 8807 synchronized (this) { 8808 ActivityRecord activity = getFocusedStack().mResumedActivity; 8809 if (activity == null) { 8810 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8811 return null; 8812 } 8813 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8814 if (activity.app == null || activity.app.thread == null) { 8815 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8816 return extras; 8817 } 8818 if (activity.app.pid == Binder.getCallingPid()) { 8819 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8820 return extras; 8821 } 8822 pae = new PendingAssistExtras(activity); 8823 try { 8824 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8825 requestType); 8826 mPendingAssistExtras.add(pae); 8827 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8828 } catch (RemoteException e) { 8829 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8830 return extras; 8831 } 8832 } 8833 synchronized (pae) { 8834 while (!pae.haveResult) { 8835 try { 8836 pae.wait(); 8837 } catch (InterruptedException e) { 8838 } 8839 } 8840 if (pae.result != null) { 8841 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8842 } 8843 } 8844 synchronized (this) { 8845 mPendingAssistExtras.remove(pae); 8846 mHandler.removeCallbacks(pae); 8847 } 8848 return extras; 8849 } 8850 8851 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8852 PendingAssistExtras pae = (PendingAssistExtras)token; 8853 synchronized (pae) { 8854 pae.result = extras; 8855 pae.haveResult = true; 8856 pae.notifyAll(); 8857 } 8858 } 8859 8860 public void registerProcessObserver(IProcessObserver observer) { 8861 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8862 "registerProcessObserver()"); 8863 synchronized (this) { 8864 mProcessObservers.register(observer); 8865 } 8866 } 8867 8868 @Override 8869 public void unregisterProcessObserver(IProcessObserver observer) { 8870 synchronized (this) { 8871 mProcessObservers.unregister(observer); 8872 } 8873 } 8874 8875 @Override 8876 public boolean convertFromTranslucent(IBinder token) { 8877 final long origId = Binder.clearCallingIdentity(); 8878 try { 8879 synchronized (this) { 8880 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8881 if (r == null) { 8882 return false; 8883 } 8884 if (r.changeWindowTranslucency(true)) { 8885 mWindowManager.setAppFullscreen(token, true); 8886 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8887 return true; 8888 } 8889 return false; 8890 } 8891 } finally { 8892 Binder.restoreCallingIdentity(origId); 8893 } 8894 } 8895 8896 @Override 8897 public boolean convertToTranslucent(IBinder token) { 8898 final long origId = Binder.clearCallingIdentity(); 8899 try { 8900 synchronized (this) { 8901 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8902 if (r == null) { 8903 return false; 8904 } 8905 if (r.changeWindowTranslucency(false)) { 8906 r.task.stack.convertToTranslucent(r); 8907 mWindowManager.setAppFullscreen(token, false); 8908 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8909 return true; 8910 } 8911 return false; 8912 } 8913 } finally { 8914 Binder.restoreCallingIdentity(origId); 8915 } 8916 } 8917 8918 @Override 8919 public void setImmersive(IBinder token, boolean immersive) { 8920 synchronized(this) { 8921 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8922 if (r == null) { 8923 throw new IllegalArgumentException(); 8924 } 8925 r.immersive = immersive; 8926 8927 // update associated state if we're frontmost 8928 if (r == mFocusedActivity) { 8929 if (DEBUG_IMMERSIVE) { 8930 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8931 } 8932 applyUpdateLockStateLocked(r); 8933 } 8934 } 8935 } 8936 8937 @Override 8938 public boolean isImmersive(IBinder token) { 8939 synchronized (this) { 8940 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8941 if (r == null) { 8942 throw new IllegalArgumentException(); 8943 } 8944 return r.immersive; 8945 } 8946 } 8947 8948 public boolean isTopActivityImmersive() { 8949 enforceNotIsolatedCaller("startActivity"); 8950 synchronized (this) { 8951 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8952 return (r != null) ? r.immersive : false; 8953 } 8954 } 8955 8956 public final void enterSafeMode() { 8957 synchronized(this) { 8958 // It only makes sense to do this before the system is ready 8959 // and started launching other packages. 8960 if (!mSystemReady) { 8961 try { 8962 AppGlobals.getPackageManager().enterSafeMode(); 8963 } catch (RemoteException e) { 8964 } 8965 } 8966 } 8967 } 8968 8969 public final void showSafeModeOverlay() { 8970 View v = LayoutInflater.from(mContext).inflate( 8971 com.android.internal.R.layout.safe_mode, null); 8972 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8973 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8974 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8975 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8976 lp.gravity = Gravity.BOTTOM | Gravity.START; 8977 lp.format = v.getBackground().getOpacity(); 8978 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8979 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8980 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8981 ((WindowManager)mContext.getSystemService( 8982 Context.WINDOW_SERVICE)).addView(v, lp); 8983 } 8984 8985 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8986 if (!(sender instanceof PendingIntentRecord)) { 8987 return; 8988 } 8989 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8990 synchronized (stats) { 8991 if (mBatteryStatsService.isOnBattery()) { 8992 mBatteryStatsService.enforceCallingPermission(); 8993 PendingIntentRecord rec = (PendingIntentRecord)sender; 8994 int MY_UID = Binder.getCallingUid(); 8995 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8996 BatteryStatsImpl.Uid.Pkg pkg = 8997 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8998 sourcePkg != null ? sourcePkg : rec.key.packageName); 8999 pkg.incWakeupsLocked(); 9000 } 9001 } 9002 } 9003 9004 public boolean killPids(int[] pids, String pReason, boolean secure) { 9005 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9006 throw new SecurityException("killPids only available to the system"); 9007 } 9008 String reason = (pReason == null) ? "Unknown" : pReason; 9009 // XXX Note: don't acquire main activity lock here, because the window 9010 // manager calls in with its locks held. 9011 9012 boolean killed = false; 9013 synchronized (mPidsSelfLocked) { 9014 int[] types = new int[pids.length]; 9015 int worstType = 0; 9016 for (int i=0; i<pids.length; i++) { 9017 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9018 if (proc != null) { 9019 int type = proc.setAdj; 9020 types[i] = type; 9021 if (type > worstType) { 9022 worstType = type; 9023 } 9024 } 9025 } 9026 9027 // If the worst oom_adj is somewhere in the cached proc LRU range, 9028 // then constrain it so we will kill all cached procs. 9029 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9030 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9031 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9032 } 9033 9034 // If this is not a secure call, don't let it kill processes that 9035 // are important. 9036 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9037 worstType = ProcessList.SERVICE_ADJ; 9038 } 9039 9040 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9041 for (int i=0; i<pids.length; i++) { 9042 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9043 if (proc == null) { 9044 continue; 9045 } 9046 int adj = proc.setAdj; 9047 if (adj >= worstType && !proc.killedByAm) { 9048 killUnneededProcessLocked(proc, reason); 9049 killed = true; 9050 } 9051 } 9052 } 9053 return killed; 9054 } 9055 9056 @Override 9057 public void killUid(int uid, String reason) { 9058 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9059 throw new SecurityException("killUid only available to the system"); 9060 } 9061 synchronized (this) { 9062 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9063 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9064 reason != null ? reason : "kill uid"); 9065 } 9066 } 9067 9068 @Override 9069 public boolean killProcessesBelowForeground(String reason) { 9070 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9071 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9072 } 9073 9074 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9075 } 9076 9077 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9078 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9079 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9080 } 9081 9082 boolean killed = false; 9083 synchronized (mPidsSelfLocked) { 9084 final int size = mPidsSelfLocked.size(); 9085 for (int i = 0; i < size; i++) { 9086 final int pid = mPidsSelfLocked.keyAt(i); 9087 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9088 if (proc == null) continue; 9089 9090 final int adj = proc.setAdj; 9091 if (adj > belowAdj && !proc.killedByAm) { 9092 killUnneededProcessLocked(proc, reason); 9093 killed = true; 9094 } 9095 } 9096 } 9097 return killed; 9098 } 9099 9100 @Override 9101 public void hang(final IBinder who, boolean allowRestart) { 9102 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9103 != PackageManager.PERMISSION_GRANTED) { 9104 throw new SecurityException("Requires permission " 9105 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9106 } 9107 9108 final IBinder.DeathRecipient death = new DeathRecipient() { 9109 @Override 9110 public void binderDied() { 9111 synchronized (this) { 9112 notifyAll(); 9113 } 9114 } 9115 }; 9116 9117 try { 9118 who.linkToDeath(death, 0); 9119 } catch (RemoteException e) { 9120 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9121 return; 9122 } 9123 9124 synchronized (this) { 9125 Watchdog.getInstance().setAllowRestart(allowRestart); 9126 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9127 synchronized (death) { 9128 while (who.isBinderAlive()) { 9129 try { 9130 death.wait(); 9131 } catch (InterruptedException e) { 9132 } 9133 } 9134 } 9135 Watchdog.getInstance().setAllowRestart(true); 9136 } 9137 } 9138 9139 @Override 9140 public void restart() { 9141 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9142 != PackageManager.PERMISSION_GRANTED) { 9143 throw new SecurityException("Requires permission " 9144 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9145 } 9146 9147 Log.i(TAG, "Sending shutdown broadcast..."); 9148 9149 BroadcastReceiver br = new BroadcastReceiver() { 9150 @Override public void onReceive(Context context, Intent intent) { 9151 // Now the broadcast is done, finish up the low-level shutdown. 9152 Log.i(TAG, "Shutting down activity manager..."); 9153 shutdown(10000); 9154 Log.i(TAG, "Shutdown complete, restarting!"); 9155 Process.killProcess(Process.myPid()); 9156 System.exit(10); 9157 } 9158 }; 9159 9160 // First send the high-level shut down broadcast. 9161 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9162 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9163 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9164 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9165 mContext.sendOrderedBroadcastAsUser(intent, 9166 UserHandle.ALL, null, br, mHandler, 0, null, null); 9167 */ 9168 br.onReceive(mContext, intent); 9169 } 9170 9171 private long getLowRamTimeSinceIdle(long now) { 9172 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9173 } 9174 9175 @Override 9176 public void performIdleMaintenance() { 9177 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9178 != PackageManager.PERMISSION_GRANTED) { 9179 throw new SecurityException("Requires permission " 9180 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9181 } 9182 9183 synchronized (this) { 9184 final long now = SystemClock.uptimeMillis(); 9185 final long timeSinceLastIdle = now - mLastIdleTime; 9186 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9187 mLastIdleTime = now; 9188 mLowRamTimeSinceLastIdle = 0; 9189 if (mLowRamStartTime != 0) { 9190 mLowRamStartTime = now; 9191 } 9192 9193 StringBuilder sb = new StringBuilder(128); 9194 sb.append("Idle maintenance over "); 9195 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9196 sb.append(" low RAM for "); 9197 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9198 Slog.i(TAG, sb.toString()); 9199 9200 // If at least 1/3 of our time since the last idle period has been spent 9201 // with RAM low, then we want to kill processes. 9202 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9203 9204 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9205 ProcessRecord proc = mLruProcesses.get(i); 9206 if (proc.notCachedSinceIdle) { 9207 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9208 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9209 if (doKilling && proc.initialIdlePss != 0 9210 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9211 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9212 + " from " + proc.initialIdlePss + ")"); 9213 } 9214 } 9215 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9216 proc.notCachedSinceIdle = true; 9217 proc.initialIdlePss = 0; 9218 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9219 mSleeping, now); 9220 } 9221 } 9222 9223 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9224 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9225 } 9226 } 9227 9228 public final void startRunning(String pkg, String cls, String action, 9229 String data) { 9230 synchronized(this) { 9231 if (mStartRunning) { 9232 return; 9233 } 9234 mStartRunning = true; 9235 mTopComponent = pkg != null && cls != null 9236 ? new ComponentName(pkg, cls) : null; 9237 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9238 mTopData = data; 9239 if (!mSystemReady) { 9240 return; 9241 } 9242 } 9243 9244 systemReady(null); 9245 } 9246 9247 private void retrieveSettings() { 9248 final ContentResolver resolver = mContext.getContentResolver(); 9249 String debugApp = Settings.Global.getString( 9250 resolver, Settings.Global.DEBUG_APP); 9251 boolean waitForDebugger = Settings.Global.getInt( 9252 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9253 boolean alwaysFinishActivities = Settings.Global.getInt( 9254 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9255 boolean forceRtl = Settings.Global.getInt( 9256 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9257 // Transfer any global setting for forcing RTL layout, into a System Property 9258 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9259 9260 Configuration configuration = new Configuration(); 9261 Settings.System.getConfiguration(resolver, configuration); 9262 if (forceRtl) { 9263 // This will take care of setting the correct layout direction flags 9264 configuration.setLayoutDirection(configuration.locale); 9265 } 9266 9267 synchronized (this) { 9268 mDebugApp = mOrigDebugApp = debugApp; 9269 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9270 mAlwaysFinishActivities = alwaysFinishActivities; 9271 // This happens before any activities are started, so we can 9272 // change mConfiguration in-place. 9273 updateConfigurationLocked(configuration, null, false, true); 9274 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9275 } 9276 } 9277 9278 public boolean testIsSystemReady() { 9279 // no need to synchronize(this) just to read & return the value 9280 return mSystemReady; 9281 } 9282 9283 private static File getCalledPreBootReceiversFile() { 9284 File dataDir = Environment.getDataDirectory(); 9285 File systemDir = new File(dataDir, "system"); 9286 File fname = new File(systemDir, "called_pre_boots.dat"); 9287 return fname; 9288 } 9289 9290 static final int LAST_DONE_VERSION = 10000; 9291 9292 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9293 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9294 File file = getCalledPreBootReceiversFile(); 9295 FileInputStream fis = null; 9296 try { 9297 fis = new FileInputStream(file); 9298 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9299 int fvers = dis.readInt(); 9300 if (fvers == LAST_DONE_VERSION) { 9301 String vers = dis.readUTF(); 9302 String codename = dis.readUTF(); 9303 String build = dis.readUTF(); 9304 if (android.os.Build.VERSION.RELEASE.equals(vers) 9305 && android.os.Build.VERSION.CODENAME.equals(codename) 9306 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9307 int num = dis.readInt(); 9308 while (num > 0) { 9309 num--; 9310 String pkg = dis.readUTF(); 9311 String cls = dis.readUTF(); 9312 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9313 } 9314 } 9315 } 9316 } catch (FileNotFoundException e) { 9317 } catch (IOException e) { 9318 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9319 } finally { 9320 if (fis != null) { 9321 try { 9322 fis.close(); 9323 } catch (IOException e) { 9324 } 9325 } 9326 } 9327 return lastDoneReceivers; 9328 } 9329 9330 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9331 File file = getCalledPreBootReceiversFile(); 9332 FileOutputStream fos = null; 9333 DataOutputStream dos = null; 9334 try { 9335 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9336 fos = new FileOutputStream(file); 9337 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9338 dos.writeInt(LAST_DONE_VERSION); 9339 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9340 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9341 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9342 dos.writeInt(list.size()); 9343 for (int i=0; i<list.size(); i++) { 9344 dos.writeUTF(list.get(i).getPackageName()); 9345 dos.writeUTF(list.get(i).getClassName()); 9346 } 9347 } catch (IOException e) { 9348 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9349 file.delete(); 9350 } finally { 9351 FileUtils.sync(fos); 9352 if (dos != null) { 9353 try { 9354 dos.close(); 9355 } catch (IOException e) { 9356 // TODO Auto-generated catch block 9357 e.printStackTrace(); 9358 } 9359 } 9360 } 9361 } 9362 9363 public void systemReady(final Runnable goingCallback) { 9364 synchronized(this) { 9365 if (mSystemReady) { 9366 if (goingCallback != null) goingCallback.run(); 9367 return; 9368 } 9369 9370 // Check to see if there are any update receivers to run. 9371 if (!mDidUpdate) { 9372 if (mWaitingUpdate) { 9373 return; 9374 } 9375 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9376 List<ResolveInfo> ris = null; 9377 try { 9378 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9379 intent, null, 0, 0); 9380 } catch (RemoteException e) { 9381 } 9382 if (ris != null) { 9383 for (int i=ris.size()-1; i>=0; i--) { 9384 if ((ris.get(i).activityInfo.applicationInfo.flags 9385 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9386 ris.remove(i); 9387 } 9388 } 9389 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9390 9391 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9392 9393 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9394 for (int i=0; i<ris.size(); i++) { 9395 ActivityInfo ai = ris.get(i).activityInfo; 9396 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9397 if (lastDoneReceivers.contains(comp)) { 9398 // We already did the pre boot receiver for this app with the current 9399 // platform version, so don't do it again... 9400 ris.remove(i); 9401 i--; 9402 // ...however, do keep it as one that has been done, so we don't 9403 // forget about it when rewriting the file of last done receivers. 9404 doneReceivers.add(comp); 9405 } 9406 } 9407 9408 final int[] users = getUsersLocked(); 9409 for (int i=0; i<ris.size(); i++) { 9410 ActivityInfo ai = ris.get(i).activityInfo; 9411 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9412 doneReceivers.add(comp); 9413 intent.setComponent(comp); 9414 for (int j=0; j<users.length; j++) { 9415 IIntentReceiver finisher = null; 9416 if (i == ris.size()-1 && j == users.length-1) { 9417 finisher = new IIntentReceiver.Stub() { 9418 public void performReceive(Intent intent, int resultCode, 9419 String data, Bundle extras, boolean ordered, 9420 boolean sticky, int sendingUser) { 9421 // The raw IIntentReceiver interface is called 9422 // with the AM lock held, so redispatch to 9423 // execute our code without the lock. 9424 mHandler.post(new Runnable() { 9425 public void run() { 9426 synchronized (ActivityManagerService.this) { 9427 mDidUpdate = true; 9428 } 9429 writeLastDonePreBootReceivers(doneReceivers); 9430 showBootMessage(mContext.getText( 9431 R.string.android_upgrading_complete), 9432 false); 9433 systemReady(goingCallback); 9434 } 9435 }); 9436 } 9437 }; 9438 } 9439 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9440 + " for user " + users[j]); 9441 broadcastIntentLocked(null, null, intent, null, finisher, 9442 0, null, null, null, AppOpsManager.OP_NONE, 9443 true, false, MY_PID, Process.SYSTEM_UID, 9444 users[j]); 9445 if (finisher != null) { 9446 mWaitingUpdate = true; 9447 } 9448 } 9449 } 9450 } 9451 if (mWaitingUpdate) { 9452 return; 9453 } 9454 mDidUpdate = true; 9455 } 9456 9457 mAppOpsService.systemReady(); 9458 mSystemReady = true; 9459 if (!mStartRunning) { 9460 return; 9461 } 9462 } 9463 9464 ArrayList<ProcessRecord> procsToKill = null; 9465 synchronized(mPidsSelfLocked) { 9466 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9467 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9468 if (!isAllowedWhileBooting(proc.info)){ 9469 if (procsToKill == null) { 9470 procsToKill = new ArrayList<ProcessRecord>(); 9471 } 9472 procsToKill.add(proc); 9473 } 9474 } 9475 } 9476 9477 synchronized(this) { 9478 if (procsToKill != null) { 9479 for (int i=procsToKill.size()-1; i>=0; i--) { 9480 ProcessRecord proc = procsToKill.get(i); 9481 Slog.i(TAG, "Removing system update proc: " + proc); 9482 removeProcessLocked(proc, true, false, "system update done"); 9483 } 9484 } 9485 9486 // Now that we have cleaned up any update processes, we 9487 // are ready to start launching real processes and know that 9488 // we won't trample on them any more. 9489 mProcessesReady = true; 9490 } 9491 9492 Slog.i(TAG, "System now ready"); 9493 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9494 SystemClock.uptimeMillis()); 9495 9496 synchronized(this) { 9497 // Make sure we have no pre-ready processes sitting around. 9498 9499 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9500 ResolveInfo ri = mContext.getPackageManager() 9501 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9502 STOCK_PM_FLAGS); 9503 CharSequence errorMsg = null; 9504 if (ri != null) { 9505 ActivityInfo ai = ri.activityInfo; 9506 ApplicationInfo app = ai.applicationInfo; 9507 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9508 mTopAction = Intent.ACTION_FACTORY_TEST; 9509 mTopData = null; 9510 mTopComponent = new ComponentName(app.packageName, 9511 ai.name); 9512 } else { 9513 errorMsg = mContext.getResources().getText( 9514 com.android.internal.R.string.factorytest_not_system); 9515 } 9516 } else { 9517 errorMsg = mContext.getResources().getText( 9518 com.android.internal.R.string.factorytest_no_action); 9519 } 9520 if (errorMsg != null) { 9521 mTopAction = null; 9522 mTopData = null; 9523 mTopComponent = null; 9524 Message msg = Message.obtain(); 9525 msg.what = SHOW_FACTORY_ERROR_MSG; 9526 msg.getData().putCharSequence("msg", errorMsg); 9527 mHandler.sendMessage(msg); 9528 } 9529 } 9530 } 9531 9532 retrieveSettings(); 9533 9534 synchronized (this) { 9535 readGrantedUriPermissionsLocked(); 9536 } 9537 9538 if (goingCallback != null) goingCallback.run(); 9539 9540 synchronized (this) { 9541 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9542 try { 9543 List apps = AppGlobals.getPackageManager(). 9544 getPersistentApplications(STOCK_PM_FLAGS); 9545 if (apps != null) { 9546 int N = apps.size(); 9547 int i; 9548 for (i=0; i<N; i++) { 9549 ApplicationInfo info 9550 = (ApplicationInfo)apps.get(i); 9551 if (info != null && 9552 !info.packageName.equals("android")) { 9553 addAppLocked(info, false); 9554 } 9555 } 9556 } 9557 } catch (RemoteException ex) { 9558 // pm is in same process, this will never happen. 9559 } 9560 } 9561 9562 // Start up initial activity. 9563 mBooting = true; 9564 9565 try { 9566 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9567 Message msg = Message.obtain(); 9568 msg.what = SHOW_UID_ERROR_MSG; 9569 mHandler.sendMessage(msg); 9570 } 9571 } catch (RemoteException e) { 9572 } 9573 9574 long ident = Binder.clearCallingIdentity(); 9575 try { 9576 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9577 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9578 | Intent.FLAG_RECEIVER_FOREGROUND); 9579 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9580 broadcastIntentLocked(null, null, intent, 9581 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9582 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9583 intent = new Intent(Intent.ACTION_USER_STARTING); 9584 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9585 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9586 broadcastIntentLocked(null, null, intent, 9587 null, new IIntentReceiver.Stub() { 9588 @Override 9589 public void performReceive(Intent intent, int resultCode, String data, 9590 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9591 throws RemoteException { 9592 } 9593 }, 0, null, null, 9594 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9595 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9596 } finally { 9597 Binder.restoreCallingIdentity(ident); 9598 } 9599 mStackSupervisor.resumeTopActivitiesLocked(); 9600 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9601 } 9602 } 9603 9604 private boolean makeAppCrashingLocked(ProcessRecord app, 9605 String shortMsg, String longMsg, String stackTrace) { 9606 app.crashing = true; 9607 app.crashingReport = generateProcessError(app, 9608 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9609 startAppProblemLocked(app); 9610 app.stopFreezingAllLocked(); 9611 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9612 } 9613 9614 private void makeAppNotRespondingLocked(ProcessRecord app, 9615 String activity, String shortMsg, String longMsg) { 9616 app.notResponding = true; 9617 app.notRespondingReport = generateProcessError(app, 9618 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9619 activity, shortMsg, longMsg, null); 9620 startAppProblemLocked(app); 9621 app.stopFreezingAllLocked(); 9622 } 9623 9624 /** 9625 * Generate a process error record, suitable for attachment to a ProcessRecord. 9626 * 9627 * @param app The ProcessRecord in which the error occurred. 9628 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9629 * ActivityManager.AppErrorStateInfo 9630 * @param activity The activity associated with the crash, if known. 9631 * @param shortMsg Short message describing the crash. 9632 * @param longMsg Long message describing the crash. 9633 * @param stackTrace Full crash stack trace, may be null. 9634 * 9635 * @return Returns a fully-formed AppErrorStateInfo record. 9636 */ 9637 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9638 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9639 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9640 9641 report.condition = condition; 9642 report.processName = app.processName; 9643 report.pid = app.pid; 9644 report.uid = app.info.uid; 9645 report.tag = activity; 9646 report.shortMsg = shortMsg; 9647 report.longMsg = longMsg; 9648 report.stackTrace = stackTrace; 9649 9650 return report; 9651 } 9652 9653 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9654 synchronized (this) { 9655 app.crashing = false; 9656 app.crashingReport = null; 9657 app.notResponding = false; 9658 app.notRespondingReport = null; 9659 if (app.anrDialog == fromDialog) { 9660 app.anrDialog = null; 9661 } 9662 if (app.waitDialog == fromDialog) { 9663 app.waitDialog = null; 9664 } 9665 if (app.pid > 0 && app.pid != MY_PID) { 9666 handleAppCrashLocked(app, null, null, null); 9667 killUnneededProcessLocked(app, "user request after error"); 9668 } 9669 } 9670 } 9671 9672 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9673 String stackTrace) { 9674 long now = SystemClock.uptimeMillis(); 9675 9676 Long crashTime; 9677 if (!app.isolated) { 9678 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9679 } else { 9680 crashTime = null; 9681 } 9682 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9683 // This process loses! 9684 Slog.w(TAG, "Process " + app.info.processName 9685 + " has crashed too many times: killing!"); 9686 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9687 app.userId, app.info.processName, app.uid); 9688 mStackSupervisor.handleAppCrashLocked(app); 9689 if (!app.persistent) { 9690 // We don't want to start this process again until the user 9691 // explicitly does so... but for persistent process, we really 9692 // need to keep it running. If a persistent process is actually 9693 // repeatedly crashing, then badness for everyone. 9694 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9695 app.info.processName); 9696 if (!app.isolated) { 9697 // XXX We don't have a way to mark isolated processes 9698 // as bad, since they don't have a peristent identity. 9699 mBadProcesses.put(app.info.processName, app.uid, 9700 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9701 mProcessCrashTimes.remove(app.info.processName, app.uid); 9702 } 9703 app.bad = true; 9704 app.removed = true; 9705 // Don't let services in this process be restarted and potentially 9706 // annoy the user repeatedly. Unless it is persistent, since those 9707 // processes run critical code. 9708 removeProcessLocked(app, false, false, "crash"); 9709 mStackSupervisor.resumeTopActivitiesLocked(); 9710 return false; 9711 } 9712 mStackSupervisor.resumeTopActivitiesLocked(); 9713 } else { 9714 mStackSupervisor.finishTopRunningActivityLocked(app); 9715 } 9716 9717 // Bump up the crash count of any services currently running in the proc. 9718 for (int i=app.services.size()-1; i>=0; i--) { 9719 // Any services running in the application need to be placed 9720 // back in the pending list. 9721 ServiceRecord sr = app.services.valueAt(i); 9722 sr.crashCount++; 9723 } 9724 9725 // If the crashing process is what we consider to be the "home process" and it has been 9726 // replaced by a third-party app, clear the package preferred activities from packages 9727 // with a home activity running in the process to prevent a repeatedly crashing app 9728 // from blocking the user to manually clear the list. 9729 final ArrayList<ActivityRecord> activities = app.activities; 9730 if (app == mHomeProcess && activities.size() > 0 9731 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9732 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9733 final ActivityRecord r = activities.get(activityNdx); 9734 if (r.isHomeActivity()) { 9735 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9736 try { 9737 ActivityThread.getPackageManager() 9738 .clearPackagePreferredActivities(r.packageName); 9739 } catch (RemoteException c) { 9740 // pm is in same process, this will never happen. 9741 } 9742 } 9743 } 9744 } 9745 9746 if (!app.isolated) { 9747 // XXX Can't keep track of crash times for isolated processes, 9748 // because they don't have a perisistent identity. 9749 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9750 } 9751 9752 return true; 9753 } 9754 9755 void startAppProblemLocked(ProcessRecord app) { 9756 if (app.userId == mCurrentUserId) { 9757 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9758 mContext, app.info.packageName, app.info.flags); 9759 } else { 9760 // If this app is not running under the current user, then we 9761 // can't give it a report button because that would require 9762 // launching the report UI under a different user. 9763 app.errorReportReceiver = null; 9764 } 9765 skipCurrentReceiverLocked(app); 9766 } 9767 9768 void skipCurrentReceiverLocked(ProcessRecord app) { 9769 for (BroadcastQueue queue : mBroadcastQueues) { 9770 queue.skipCurrentReceiverLocked(app); 9771 } 9772 } 9773 9774 /** 9775 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9776 * The application process will exit immediately after this call returns. 9777 * @param app object of the crashing app, null for the system server 9778 * @param crashInfo describing the exception 9779 */ 9780 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9781 ProcessRecord r = findAppProcess(app, "Crash"); 9782 final String processName = app == null ? "system_server" 9783 : (r == null ? "unknown" : r.processName); 9784 9785 handleApplicationCrashInner("crash", r, processName, crashInfo); 9786 } 9787 9788 /* Native crash reporting uses this inner version because it needs to be somewhat 9789 * decoupled from the AM-managed cleanup lifecycle 9790 */ 9791 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9792 ApplicationErrorReport.CrashInfo crashInfo) { 9793 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9794 UserHandle.getUserId(Binder.getCallingUid()), processName, 9795 r == null ? -1 : r.info.flags, 9796 crashInfo.exceptionClassName, 9797 crashInfo.exceptionMessage, 9798 crashInfo.throwFileName, 9799 crashInfo.throwLineNumber); 9800 9801 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9802 9803 crashApplication(r, crashInfo); 9804 } 9805 9806 public void handleApplicationStrictModeViolation( 9807 IBinder app, 9808 int violationMask, 9809 StrictMode.ViolationInfo info) { 9810 ProcessRecord r = findAppProcess(app, "StrictMode"); 9811 if (r == null) { 9812 return; 9813 } 9814 9815 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9816 Integer stackFingerprint = info.hashCode(); 9817 boolean logIt = true; 9818 synchronized (mAlreadyLoggedViolatedStacks) { 9819 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9820 logIt = false; 9821 // TODO: sub-sample into EventLog for these, with 9822 // the info.durationMillis? Then we'd get 9823 // the relative pain numbers, without logging all 9824 // the stack traces repeatedly. We'd want to do 9825 // likewise in the client code, which also does 9826 // dup suppression, before the Binder call. 9827 } else { 9828 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9829 mAlreadyLoggedViolatedStacks.clear(); 9830 } 9831 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9832 } 9833 } 9834 if (logIt) { 9835 logStrictModeViolationToDropBox(r, info); 9836 } 9837 } 9838 9839 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9840 AppErrorResult result = new AppErrorResult(); 9841 synchronized (this) { 9842 final long origId = Binder.clearCallingIdentity(); 9843 9844 Message msg = Message.obtain(); 9845 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9846 HashMap<String, Object> data = new HashMap<String, Object>(); 9847 data.put("result", result); 9848 data.put("app", r); 9849 data.put("violationMask", violationMask); 9850 data.put("info", info); 9851 msg.obj = data; 9852 mHandler.sendMessage(msg); 9853 9854 Binder.restoreCallingIdentity(origId); 9855 } 9856 int res = result.get(); 9857 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9858 } 9859 } 9860 9861 // Depending on the policy in effect, there could be a bunch of 9862 // these in quick succession so we try to batch these together to 9863 // minimize disk writes, number of dropbox entries, and maximize 9864 // compression, by having more fewer, larger records. 9865 private void logStrictModeViolationToDropBox( 9866 ProcessRecord process, 9867 StrictMode.ViolationInfo info) { 9868 if (info == null) { 9869 return; 9870 } 9871 final boolean isSystemApp = process == null || 9872 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9873 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9874 final String processName = process == null ? "unknown" : process.processName; 9875 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9876 final DropBoxManager dbox = (DropBoxManager) 9877 mContext.getSystemService(Context.DROPBOX_SERVICE); 9878 9879 // Exit early if the dropbox isn't configured to accept this report type. 9880 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9881 9882 boolean bufferWasEmpty; 9883 boolean needsFlush; 9884 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9885 synchronized (sb) { 9886 bufferWasEmpty = sb.length() == 0; 9887 appendDropBoxProcessHeaders(process, processName, sb); 9888 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9889 sb.append("System-App: ").append(isSystemApp).append("\n"); 9890 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9891 if (info.violationNumThisLoop != 0) { 9892 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9893 } 9894 if (info.numAnimationsRunning != 0) { 9895 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9896 } 9897 if (info.broadcastIntentAction != null) { 9898 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9899 } 9900 if (info.durationMillis != -1) { 9901 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9902 } 9903 if (info.numInstances != -1) { 9904 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9905 } 9906 if (info.tags != null) { 9907 for (String tag : info.tags) { 9908 sb.append("Span-Tag: ").append(tag).append("\n"); 9909 } 9910 } 9911 sb.append("\n"); 9912 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9913 sb.append(info.crashInfo.stackTrace); 9914 } 9915 sb.append("\n"); 9916 9917 // Only buffer up to ~64k. Various logging bits truncate 9918 // things at 128k. 9919 needsFlush = (sb.length() > 64 * 1024); 9920 } 9921 9922 // Flush immediately if the buffer's grown too large, or this 9923 // is a non-system app. Non-system apps are isolated with a 9924 // different tag & policy and not batched. 9925 // 9926 // Batching is useful during internal testing with 9927 // StrictMode settings turned up high. Without batching, 9928 // thousands of separate files could be created on boot. 9929 if (!isSystemApp || needsFlush) { 9930 new Thread("Error dump: " + dropboxTag) { 9931 @Override 9932 public void run() { 9933 String report; 9934 synchronized (sb) { 9935 report = sb.toString(); 9936 sb.delete(0, sb.length()); 9937 sb.trimToSize(); 9938 } 9939 if (report.length() != 0) { 9940 dbox.addText(dropboxTag, report); 9941 } 9942 } 9943 }.start(); 9944 return; 9945 } 9946 9947 // System app batching: 9948 if (!bufferWasEmpty) { 9949 // An existing dropbox-writing thread is outstanding, so 9950 // we don't need to start it up. The existing thread will 9951 // catch the buffer appends we just did. 9952 return; 9953 } 9954 9955 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9956 // (After this point, we shouldn't access AMS internal data structures.) 9957 new Thread("Error dump: " + dropboxTag) { 9958 @Override 9959 public void run() { 9960 // 5 second sleep to let stacks arrive and be batched together 9961 try { 9962 Thread.sleep(5000); // 5 seconds 9963 } catch (InterruptedException e) {} 9964 9965 String errorReport; 9966 synchronized (mStrictModeBuffer) { 9967 errorReport = mStrictModeBuffer.toString(); 9968 if (errorReport.length() == 0) { 9969 return; 9970 } 9971 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9972 mStrictModeBuffer.trimToSize(); 9973 } 9974 dbox.addText(dropboxTag, errorReport); 9975 } 9976 }.start(); 9977 } 9978 9979 /** 9980 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9981 * @param app object of the crashing app, null for the system server 9982 * @param tag reported by the caller 9983 * @param crashInfo describing the context of the error 9984 * @return true if the process should exit immediately (WTF is fatal) 9985 */ 9986 public boolean handleApplicationWtf(IBinder app, String tag, 9987 ApplicationErrorReport.CrashInfo crashInfo) { 9988 ProcessRecord r = findAppProcess(app, "WTF"); 9989 final String processName = app == null ? "system_server" 9990 : (r == null ? "unknown" : r.processName); 9991 9992 EventLog.writeEvent(EventLogTags.AM_WTF, 9993 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9994 processName, 9995 r == null ? -1 : r.info.flags, 9996 tag, crashInfo.exceptionMessage); 9997 9998 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9999 10000 if (r != null && r.pid != Process.myPid() && 10001 Settings.Global.getInt(mContext.getContentResolver(), 10002 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10003 crashApplication(r, crashInfo); 10004 return true; 10005 } else { 10006 return false; 10007 } 10008 } 10009 10010 /** 10011 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10012 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10013 */ 10014 private ProcessRecord findAppProcess(IBinder app, String reason) { 10015 if (app == null) { 10016 return null; 10017 } 10018 10019 synchronized (this) { 10020 final int NP = mProcessNames.getMap().size(); 10021 for (int ip=0; ip<NP; ip++) { 10022 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10023 final int NA = apps.size(); 10024 for (int ia=0; ia<NA; ia++) { 10025 ProcessRecord p = apps.valueAt(ia); 10026 if (p.thread != null && p.thread.asBinder() == app) { 10027 return p; 10028 } 10029 } 10030 } 10031 10032 Slog.w(TAG, "Can't find mystery application for " + reason 10033 + " from pid=" + Binder.getCallingPid() 10034 + " uid=" + Binder.getCallingUid() + ": " + app); 10035 return null; 10036 } 10037 } 10038 10039 /** 10040 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10041 * to append various headers to the dropbox log text. 10042 */ 10043 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10044 StringBuilder sb) { 10045 // Watchdog thread ends up invoking this function (with 10046 // a null ProcessRecord) to add the stack file to dropbox. 10047 // Do not acquire a lock on this (am) in such cases, as it 10048 // could cause a potential deadlock, if and when watchdog 10049 // is invoked due to unavailability of lock on am and it 10050 // would prevent watchdog from killing system_server. 10051 if (process == null) { 10052 sb.append("Process: ").append(processName).append("\n"); 10053 return; 10054 } 10055 // Note: ProcessRecord 'process' is guarded by the service 10056 // instance. (notably process.pkgList, which could otherwise change 10057 // concurrently during execution of this method) 10058 synchronized (this) { 10059 sb.append("Process: ").append(processName).append("\n"); 10060 int flags = process.info.flags; 10061 IPackageManager pm = AppGlobals.getPackageManager(); 10062 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10063 for (int ip=0; ip<process.pkgList.size(); ip++) { 10064 String pkg = process.pkgList.keyAt(ip); 10065 sb.append("Package: ").append(pkg); 10066 try { 10067 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10068 if (pi != null) { 10069 sb.append(" v").append(pi.versionCode); 10070 if (pi.versionName != null) { 10071 sb.append(" (").append(pi.versionName).append(")"); 10072 } 10073 } 10074 } catch (RemoteException e) { 10075 Slog.e(TAG, "Error getting package info: " + pkg, e); 10076 } 10077 sb.append("\n"); 10078 } 10079 } 10080 } 10081 10082 private static String processClass(ProcessRecord process) { 10083 if (process == null || process.pid == MY_PID) { 10084 return "system_server"; 10085 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10086 return "system_app"; 10087 } else { 10088 return "data_app"; 10089 } 10090 } 10091 10092 /** 10093 * Write a description of an error (crash, WTF, ANR) to the drop box. 10094 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10095 * @param process which caused the error, null means the system server 10096 * @param activity which triggered the error, null if unknown 10097 * @param parent activity related to the error, null if unknown 10098 * @param subject line related to the error, null if absent 10099 * @param report in long form describing the error, null if absent 10100 * @param logFile to include in the report, null if none 10101 * @param crashInfo giving an application stack trace, null if absent 10102 */ 10103 public void addErrorToDropBox(String eventType, 10104 ProcessRecord process, String processName, ActivityRecord activity, 10105 ActivityRecord parent, String subject, 10106 final String report, final File logFile, 10107 final ApplicationErrorReport.CrashInfo crashInfo) { 10108 // NOTE -- this must never acquire the ActivityManagerService lock, 10109 // otherwise the watchdog may be prevented from resetting the system. 10110 10111 final String dropboxTag = processClass(process) + "_" + eventType; 10112 final DropBoxManager dbox = (DropBoxManager) 10113 mContext.getSystemService(Context.DROPBOX_SERVICE); 10114 10115 // Exit early if the dropbox isn't configured to accept this report type. 10116 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10117 10118 final StringBuilder sb = new StringBuilder(1024); 10119 appendDropBoxProcessHeaders(process, processName, sb); 10120 if (activity != null) { 10121 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10122 } 10123 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10124 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10125 } 10126 if (parent != null && parent != activity) { 10127 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10128 } 10129 if (subject != null) { 10130 sb.append("Subject: ").append(subject).append("\n"); 10131 } 10132 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10133 if (Debug.isDebuggerConnected()) { 10134 sb.append("Debugger: Connected\n"); 10135 } 10136 sb.append("\n"); 10137 10138 // Do the rest in a worker thread to avoid blocking the caller on I/O 10139 // (After this point, we shouldn't access AMS internal data structures.) 10140 Thread worker = new Thread("Error dump: " + dropboxTag) { 10141 @Override 10142 public void run() { 10143 if (report != null) { 10144 sb.append(report); 10145 } 10146 if (logFile != null) { 10147 try { 10148 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10149 "\n\n[[TRUNCATED]]")); 10150 } catch (IOException e) { 10151 Slog.e(TAG, "Error reading " + logFile, e); 10152 } 10153 } 10154 if (crashInfo != null && crashInfo.stackTrace != null) { 10155 sb.append(crashInfo.stackTrace); 10156 } 10157 10158 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10159 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10160 if (lines > 0) { 10161 sb.append("\n"); 10162 10163 // Merge several logcat streams, and take the last N lines 10164 InputStreamReader input = null; 10165 try { 10166 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10167 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10168 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10169 10170 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10171 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10172 input = new InputStreamReader(logcat.getInputStream()); 10173 10174 int num; 10175 char[] buf = new char[8192]; 10176 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10177 } catch (IOException e) { 10178 Slog.e(TAG, "Error running logcat", e); 10179 } finally { 10180 if (input != null) try { input.close(); } catch (IOException e) {} 10181 } 10182 } 10183 10184 dbox.addText(dropboxTag, sb.toString()); 10185 } 10186 }; 10187 10188 if (process == null) { 10189 // If process is null, we are being called from some internal code 10190 // and may be about to die -- run this synchronously. 10191 worker.run(); 10192 } else { 10193 worker.start(); 10194 } 10195 } 10196 10197 /** 10198 * Bring up the "unexpected error" dialog box for a crashing app. 10199 * Deal with edge cases (intercepts from instrumented applications, 10200 * ActivityController, error intent receivers, that sort of thing). 10201 * @param r the application crashing 10202 * @param crashInfo describing the failure 10203 */ 10204 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10205 long timeMillis = System.currentTimeMillis(); 10206 String shortMsg = crashInfo.exceptionClassName; 10207 String longMsg = crashInfo.exceptionMessage; 10208 String stackTrace = crashInfo.stackTrace; 10209 if (shortMsg != null && longMsg != null) { 10210 longMsg = shortMsg + ": " + longMsg; 10211 } else if (shortMsg != null) { 10212 longMsg = shortMsg; 10213 } 10214 10215 AppErrorResult result = new AppErrorResult(); 10216 synchronized (this) { 10217 if (mController != null) { 10218 try { 10219 String name = r != null ? r.processName : null; 10220 int pid = r != null ? r.pid : Binder.getCallingPid(); 10221 if (!mController.appCrashed(name, pid, 10222 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10223 Slog.w(TAG, "Force-killing crashed app " + name 10224 + " at watcher's request"); 10225 Process.killProcess(pid); 10226 return; 10227 } 10228 } catch (RemoteException e) { 10229 mController = null; 10230 Watchdog.getInstance().setActivityController(null); 10231 } 10232 } 10233 10234 final long origId = Binder.clearCallingIdentity(); 10235 10236 // If this process is running instrumentation, finish it. 10237 if (r != null && r.instrumentationClass != null) { 10238 Slog.w(TAG, "Error in app " + r.processName 10239 + " running instrumentation " + r.instrumentationClass + ":"); 10240 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10241 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10242 Bundle info = new Bundle(); 10243 info.putString("shortMsg", shortMsg); 10244 info.putString("longMsg", longMsg); 10245 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10246 Binder.restoreCallingIdentity(origId); 10247 return; 10248 } 10249 10250 // If we can't identify the process or it's already exceeded its crash quota, 10251 // quit right away without showing a crash dialog. 10252 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10253 Binder.restoreCallingIdentity(origId); 10254 return; 10255 } 10256 10257 Message msg = Message.obtain(); 10258 msg.what = SHOW_ERROR_MSG; 10259 HashMap data = new HashMap(); 10260 data.put("result", result); 10261 data.put("app", r); 10262 msg.obj = data; 10263 mHandler.sendMessage(msg); 10264 10265 Binder.restoreCallingIdentity(origId); 10266 } 10267 10268 int res = result.get(); 10269 10270 Intent appErrorIntent = null; 10271 synchronized (this) { 10272 if (r != null && !r.isolated) { 10273 // XXX Can't keep track of crash time for isolated processes, 10274 // since they don't have a persistent identity. 10275 mProcessCrashTimes.put(r.info.processName, r.uid, 10276 SystemClock.uptimeMillis()); 10277 } 10278 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10279 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10280 } 10281 } 10282 10283 if (appErrorIntent != null) { 10284 try { 10285 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10286 } catch (ActivityNotFoundException e) { 10287 Slog.w(TAG, "bug report receiver dissappeared", e); 10288 } 10289 } 10290 } 10291 10292 Intent createAppErrorIntentLocked(ProcessRecord r, 10293 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10294 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10295 if (report == null) { 10296 return null; 10297 } 10298 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10299 result.setComponent(r.errorReportReceiver); 10300 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10301 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10302 return result; 10303 } 10304 10305 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10306 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10307 if (r.errorReportReceiver == null) { 10308 return null; 10309 } 10310 10311 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10312 return null; 10313 } 10314 10315 ApplicationErrorReport report = new ApplicationErrorReport(); 10316 report.packageName = r.info.packageName; 10317 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10318 report.processName = r.processName; 10319 report.time = timeMillis; 10320 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10321 10322 if (r.crashing || r.forceCrashReport) { 10323 report.type = ApplicationErrorReport.TYPE_CRASH; 10324 report.crashInfo = crashInfo; 10325 } else if (r.notResponding) { 10326 report.type = ApplicationErrorReport.TYPE_ANR; 10327 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10328 10329 report.anrInfo.activity = r.notRespondingReport.tag; 10330 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10331 report.anrInfo.info = r.notRespondingReport.longMsg; 10332 } 10333 10334 return report; 10335 } 10336 10337 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10338 enforceNotIsolatedCaller("getProcessesInErrorState"); 10339 // assume our apps are happy - lazy create the list 10340 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10341 10342 final boolean allUsers = ActivityManager.checkUidPermission( 10343 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10344 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10345 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10346 10347 synchronized (this) { 10348 10349 // iterate across all processes 10350 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10351 ProcessRecord app = mLruProcesses.get(i); 10352 if (!allUsers && app.userId != userId) { 10353 continue; 10354 } 10355 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10356 // This one's in trouble, so we'll generate a report for it 10357 // crashes are higher priority (in case there's a crash *and* an anr) 10358 ActivityManager.ProcessErrorStateInfo report = null; 10359 if (app.crashing) { 10360 report = app.crashingReport; 10361 } else if (app.notResponding) { 10362 report = app.notRespondingReport; 10363 } 10364 10365 if (report != null) { 10366 if (errList == null) { 10367 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10368 } 10369 errList.add(report); 10370 } else { 10371 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10372 " crashing = " + app.crashing + 10373 " notResponding = " + app.notResponding); 10374 } 10375 } 10376 } 10377 } 10378 10379 return errList; 10380 } 10381 10382 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10383 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10384 if (currApp != null) { 10385 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10386 } 10387 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10388 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10389 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10390 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10391 if (currApp != null) { 10392 currApp.lru = 0; 10393 } 10394 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10395 } else if (adj >= ProcessList.SERVICE_ADJ) { 10396 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10397 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10398 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10399 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10400 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10401 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10402 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10403 } else { 10404 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10405 } 10406 } 10407 10408 private void fillInProcMemInfo(ProcessRecord app, 10409 ActivityManager.RunningAppProcessInfo outInfo) { 10410 outInfo.pid = app.pid; 10411 outInfo.uid = app.info.uid; 10412 if (mHeavyWeightProcess == app) { 10413 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10414 } 10415 if (app.persistent) { 10416 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10417 } 10418 if (app.activities.size() > 0) { 10419 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10420 } 10421 outInfo.lastTrimLevel = app.trimMemoryLevel; 10422 int adj = app.curAdj; 10423 outInfo.importance = oomAdjToImportance(adj, outInfo); 10424 outInfo.importanceReasonCode = app.adjTypeCode; 10425 } 10426 10427 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10428 enforceNotIsolatedCaller("getRunningAppProcesses"); 10429 // Lazy instantiation of list 10430 List<ActivityManager.RunningAppProcessInfo> runList = null; 10431 final boolean allUsers = ActivityManager.checkUidPermission( 10432 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10433 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10434 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10435 synchronized (this) { 10436 // Iterate across all processes 10437 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10438 ProcessRecord app = mLruProcesses.get(i); 10439 if (!allUsers && app.userId != userId) { 10440 continue; 10441 } 10442 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10443 // Generate process state info for running application 10444 ActivityManager.RunningAppProcessInfo currApp = 10445 new ActivityManager.RunningAppProcessInfo(app.processName, 10446 app.pid, app.getPackageList()); 10447 fillInProcMemInfo(app, currApp); 10448 if (app.adjSource instanceof ProcessRecord) { 10449 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10450 currApp.importanceReasonImportance = oomAdjToImportance( 10451 app.adjSourceOom, null); 10452 } else if (app.adjSource instanceof ActivityRecord) { 10453 ActivityRecord r = (ActivityRecord)app.adjSource; 10454 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10455 } 10456 if (app.adjTarget instanceof ComponentName) { 10457 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10458 } 10459 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10460 // + " lru=" + currApp.lru); 10461 if (runList == null) { 10462 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10463 } 10464 runList.add(currApp); 10465 } 10466 } 10467 } 10468 return runList; 10469 } 10470 10471 public List<ApplicationInfo> getRunningExternalApplications() { 10472 enforceNotIsolatedCaller("getRunningExternalApplications"); 10473 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10474 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10475 if (runningApps != null && runningApps.size() > 0) { 10476 Set<String> extList = new HashSet<String>(); 10477 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10478 if (app.pkgList != null) { 10479 for (String pkg : app.pkgList) { 10480 extList.add(pkg); 10481 } 10482 } 10483 } 10484 IPackageManager pm = AppGlobals.getPackageManager(); 10485 for (String pkg : extList) { 10486 try { 10487 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10488 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10489 retList.add(info); 10490 } 10491 } catch (RemoteException e) { 10492 } 10493 } 10494 } 10495 return retList; 10496 } 10497 10498 @Override 10499 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10500 enforceNotIsolatedCaller("getMyMemoryState"); 10501 synchronized (this) { 10502 ProcessRecord proc; 10503 synchronized (mPidsSelfLocked) { 10504 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10505 } 10506 fillInProcMemInfo(proc, outInfo); 10507 } 10508 } 10509 10510 @Override 10511 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10512 if (checkCallingPermission(android.Manifest.permission.DUMP) 10513 != PackageManager.PERMISSION_GRANTED) { 10514 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10515 + Binder.getCallingPid() 10516 + ", uid=" + Binder.getCallingUid() 10517 + " without permission " 10518 + android.Manifest.permission.DUMP); 10519 return; 10520 } 10521 10522 boolean dumpAll = false; 10523 boolean dumpClient = false; 10524 String dumpPackage = null; 10525 10526 int opti = 0; 10527 while (opti < args.length) { 10528 String opt = args[opti]; 10529 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10530 break; 10531 } 10532 opti++; 10533 if ("-a".equals(opt)) { 10534 dumpAll = true; 10535 } else if ("-c".equals(opt)) { 10536 dumpClient = true; 10537 } else if ("-h".equals(opt)) { 10538 pw.println("Activity manager dump options:"); 10539 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10540 pw.println(" cmd may be one of:"); 10541 pw.println(" a[ctivities]: activity stack state"); 10542 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10543 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10544 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10545 pw.println(" o[om]: out of memory management"); 10546 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10547 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10548 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10549 pw.println(" service [COMP_SPEC]: service client-side state"); 10550 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10551 pw.println(" all: dump all activities"); 10552 pw.println(" top: dump the top activity"); 10553 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10554 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10555 pw.println(" a partial substring in a component name, a"); 10556 pw.println(" hex object identifier."); 10557 pw.println(" -a: include all available server state."); 10558 pw.println(" -c: include client state."); 10559 return; 10560 } else { 10561 pw.println("Unknown argument: " + opt + "; use -h for help"); 10562 } 10563 } 10564 10565 long origId = Binder.clearCallingIdentity(); 10566 boolean more = false; 10567 // Is the caller requesting to dump a particular piece of data? 10568 if (opti < args.length) { 10569 String cmd = args[opti]; 10570 opti++; 10571 if ("activities".equals(cmd) || "a".equals(cmd)) { 10572 synchronized (this) { 10573 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10574 } 10575 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10576 String[] newArgs; 10577 String name; 10578 if (opti >= args.length) { 10579 name = null; 10580 newArgs = EMPTY_STRING_ARRAY; 10581 } else { 10582 name = args[opti]; 10583 opti++; 10584 newArgs = new String[args.length - opti]; 10585 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10586 args.length - opti); 10587 } 10588 synchronized (this) { 10589 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10590 } 10591 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10592 String[] newArgs; 10593 String name; 10594 if (opti >= args.length) { 10595 name = null; 10596 newArgs = EMPTY_STRING_ARRAY; 10597 } else { 10598 name = args[opti]; 10599 opti++; 10600 newArgs = new String[args.length - opti]; 10601 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10602 args.length - opti); 10603 } 10604 synchronized (this) { 10605 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10606 } 10607 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10608 String[] newArgs; 10609 String name; 10610 if (opti >= args.length) { 10611 name = null; 10612 newArgs = EMPTY_STRING_ARRAY; 10613 } else { 10614 name = args[opti]; 10615 opti++; 10616 newArgs = new String[args.length - opti]; 10617 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10618 args.length - opti); 10619 } 10620 synchronized (this) { 10621 dumpProcessesLocked(fd, pw, args, opti, true, name); 10622 } 10623 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10624 synchronized (this) { 10625 dumpOomLocked(fd, pw, args, opti, true); 10626 } 10627 } else if ("provider".equals(cmd)) { 10628 String[] newArgs; 10629 String name; 10630 if (opti >= args.length) { 10631 name = null; 10632 newArgs = EMPTY_STRING_ARRAY; 10633 } else { 10634 name = args[opti]; 10635 opti++; 10636 newArgs = new String[args.length - opti]; 10637 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10638 } 10639 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10640 pw.println("No providers match: " + name); 10641 pw.println("Use -h for help."); 10642 } 10643 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10644 synchronized (this) { 10645 dumpProvidersLocked(fd, pw, args, opti, true, null); 10646 } 10647 } else if ("service".equals(cmd)) { 10648 String[] newArgs; 10649 String name; 10650 if (opti >= args.length) { 10651 name = null; 10652 newArgs = EMPTY_STRING_ARRAY; 10653 } else { 10654 name = args[opti]; 10655 opti++; 10656 newArgs = new String[args.length - opti]; 10657 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10658 args.length - opti); 10659 } 10660 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10661 pw.println("No services match: " + name); 10662 pw.println("Use -h for help."); 10663 } 10664 } else if ("package".equals(cmd)) { 10665 String[] newArgs; 10666 if (opti >= args.length) { 10667 pw.println("package: no package name specified"); 10668 pw.println("Use -h for help."); 10669 } else { 10670 dumpPackage = args[opti]; 10671 opti++; 10672 newArgs = new String[args.length - opti]; 10673 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10674 args.length - opti); 10675 args = newArgs; 10676 opti = 0; 10677 more = true; 10678 } 10679 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10680 synchronized (this) { 10681 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10682 } 10683 } else { 10684 // Dumping a single activity? 10685 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10686 pw.println("Bad activity command, or no activities match: " + cmd); 10687 pw.println("Use -h for help."); 10688 } 10689 } 10690 if (!more) { 10691 Binder.restoreCallingIdentity(origId); 10692 return; 10693 } 10694 } 10695 10696 // No piece of data specified, dump everything. 10697 synchronized (this) { 10698 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10699 pw.println(); 10700 if (dumpAll) { 10701 pw.println("-------------------------------------------------------------------------------"); 10702 } 10703 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10704 pw.println(); 10705 if (dumpAll) { 10706 pw.println("-------------------------------------------------------------------------------"); 10707 } 10708 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10709 pw.println(); 10710 if (dumpAll) { 10711 pw.println("-------------------------------------------------------------------------------"); 10712 } 10713 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10714 pw.println(); 10715 if (dumpAll) { 10716 pw.println("-------------------------------------------------------------------------------"); 10717 } 10718 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10719 pw.println(); 10720 if (dumpAll) { 10721 pw.println("-------------------------------------------------------------------------------"); 10722 } 10723 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10724 } 10725 Binder.restoreCallingIdentity(origId); 10726 } 10727 10728 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10729 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10730 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10731 10732 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10733 dumpPackage); 10734 boolean needSep = printedAnything; 10735 10736 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10737 dumpPackage, needSep, " mFocusedActivity: "); 10738 if (printed) { 10739 printedAnything = true; 10740 needSep = false; 10741 } 10742 10743 if (dumpPackage == null) { 10744 if (needSep) { 10745 pw.println(); 10746 } 10747 needSep = true; 10748 printedAnything = true; 10749 mStackSupervisor.dump(pw, " "); 10750 } 10751 10752 if (mRecentTasks.size() > 0) { 10753 boolean printedHeader = false; 10754 10755 final int N = mRecentTasks.size(); 10756 for (int i=0; i<N; i++) { 10757 TaskRecord tr = mRecentTasks.get(i); 10758 if (dumpPackage != null) { 10759 if (tr.realActivity == null || 10760 !dumpPackage.equals(tr.realActivity)) { 10761 continue; 10762 } 10763 } 10764 if (!printedHeader) { 10765 if (needSep) { 10766 pw.println(); 10767 } 10768 pw.println(" Recent tasks:"); 10769 printedHeader = true; 10770 printedAnything = true; 10771 } 10772 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10773 pw.println(tr); 10774 if (dumpAll) { 10775 mRecentTasks.get(i).dump(pw, " "); 10776 } 10777 } 10778 } 10779 10780 if (!printedAnything) { 10781 pw.println(" (nothing)"); 10782 } 10783 } 10784 10785 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10786 int opti, boolean dumpAll, String dumpPackage) { 10787 boolean needSep = false; 10788 boolean printedAnything = false; 10789 int numPers = 0; 10790 10791 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10792 10793 if (dumpAll) { 10794 final int NP = mProcessNames.getMap().size(); 10795 for (int ip=0; ip<NP; ip++) { 10796 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10797 final int NA = procs.size(); 10798 for (int ia=0; ia<NA; ia++) { 10799 ProcessRecord r = procs.valueAt(ia); 10800 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10801 continue; 10802 } 10803 if (!needSep) { 10804 pw.println(" All known processes:"); 10805 needSep = true; 10806 printedAnything = true; 10807 } 10808 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10809 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10810 pw.print(" "); pw.println(r); 10811 r.dump(pw, " "); 10812 if (r.persistent) { 10813 numPers++; 10814 } 10815 } 10816 } 10817 } 10818 10819 if (mIsolatedProcesses.size() > 0) { 10820 boolean printed = false; 10821 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10822 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10823 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10824 continue; 10825 } 10826 if (!printed) { 10827 if (needSep) { 10828 pw.println(); 10829 } 10830 pw.println(" Isolated process list (sorted by uid):"); 10831 printedAnything = true; 10832 printed = true; 10833 needSep = true; 10834 } 10835 pw.println(String.format("%sIsolated #%2d: %s", 10836 " ", i, r.toString())); 10837 } 10838 } 10839 10840 if (mLruProcesses.size() > 0) { 10841 if (needSep) { 10842 pw.println(); 10843 } 10844 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10845 pw.print(" total, non-act at "); 10846 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10847 pw.print(", non-svc at "); 10848 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10849 pw.println("):"); 10850 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10851 needSep = true; 10852 printedAnything = true; 10853 } 10854 10855 if (dumpAll || dumpPackage != null) { 10856 synchronized (mPidsSelfLocked) { 10857 boolean printed = false; 10858 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10859 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10860 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10861 continue; 10862 } 10863 if (!printed) { 10864 if (needSep) pw.println(); 10865 needSep = true; 10866 pw.println(" PID mappings:"); 10867 printed = true; 10868 printedAnything = true; 10869 } 10870 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10871 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10872 } 10873 } 10874 } 10875 10876 if (mForegroundProcesses.size() > 0) { 10877 synchronized (mPidsSelfLocked) { 10878 boolean printed = false; 10879 for (int i=0; i<mForegroundProcesses.size(); i++) { 10880 ProcessRecord r = mPidsSelfLocked.get( 10881 mForegroundProcesses.valueAt(i).pid); 10882 if (dumpPackage != null && (r == null 10883 || !r.pkgList.containsKey(dumpPackage))) { 10884 continue; 10885 } 10886 if (!printed) { 10887 if (needSep) pw.println(); 10888 needSep = true; 10889 pw.println(" Foreground Processes:"); 10890 printed = true; 10891 printedAnything = true; 10892 } 10893 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10894 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10895 } 10896 } 10897 } 10898 10899 if (mPersistentStartingProcesses.size() > 0) { 10900 if (needSep) pw.println(); 10901 needSep = true; 10902 printedAnything = true; 10903 pw.println(" Persisent processes that are starting:"); 10904 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10905 "Starting Norm", "Restarting PERS", dumpPackage); 10906 } 10907 10908 if (mRemovedProcesses.size() > 0) { 10909 if (needSep) pw.println(); 10910 needSep = true; 10911 printedAnything = true; 10912 pw.println(" Processes that are being removed:"); 10913 dumpProcessList(pw, this, mRemovedProcesses, " ", 10914 "Removed Norm", "Removed PERS", dumpPackage); 10915 } 10916 10917 if (mProcessesOnHold.size() > 0) { 10918 if (needSep) pw.println(); 10919 needSep = true; 10920 printedAnything = true; 10921 pw.println(" Processes that are on old until the system is ready:"); 10922 dumpProcessList(pw, this, mProcessesOnHold, " ", 10923 "OnHold Norm", "OnHold PERS", dumpPackage); 10924 } 10925 10926 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10927 10928 if (mProcessCrashTimes.getMap().size() > 0) { 10929 boolean printed = false; 10930 long now = SystemClock.uptimeMillis(); 10931 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10932 final int NP = pmap.size(); 10933 for (int ip=0; ip<NP; ip++) { 10934 String pname = pmap.keyAt(ip); 10935 SparseArray<Long> uids = pmap.valueAt(ip); 10936 final int N = uids.size(); 10937 for (int i=0; i<N; i++) { 10938 int puid = uids.keyAt(i); 10939 ProcessRecord r = mProcessNames.get(pname, puid); 10940 if (dumpPackage != null && (r == null 10941 || !r.pkgList.containsKey(dumpPackage))) { 10942 continue; 10943 } 10944 if (!printed) { 10945 if (needSep) pw.println(); 10946 needSep = true; 10947 pw.println(" Time since processes crashed:"); 10948 printed = true; 10949 printedAnything = true; 10950 } 10951 pw.print(" Process "); pw.print(pname); 10952 pw.print(" uid "); pw.print(puid); 10953 pw.print(": last crashed "); 10954 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10955 pw.println(" ago"); 10956 } 10957 } 10958 } 10959 10960 if (mBadProcesses.getMap().size() > 0) { 10961 boolean printed = false; 10962 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10963 final int NP = pmap.size(); 10964 for (int ip=0; ip<NP; ip++) { 10965 String pname = pmap.keyAt(ip); 10966 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10967 final int N = uids.size(); 10968 for (int i=0; i<N; i++) { 10969 int puid = uids.keyAt(i); 10970 ProcessRecord r = mProcessNames.get(pname, puid); 10971 if (dumpPackage != null && (r == null 10972 || !r.pkgList.containsKey(dumpPackage))) { 10973 continue; 10974 } 10975 if (!printed) { 10976 if (needSep) pw.println(); 10977 needSep = true; 10978 pw.println(" Bad processes:"); 10979 printedAnything = true; 10980 } 10981 BadProcessInfo info = uids.valueAt(i); 10982 pw.print(" Bad process "); pw.print(pname); 10983 pw.print(" uid "); pw.print(puid); 10984 pw.print(": crashed at time "); pw.println(info.time); 10985 if (info.shortMsg != null) { 10986 pw.print(" Short msg: "); pw.println(info.shortMsg); 10987 } 10988 if (info.longMsg != null) { 10989 pw.print(" Long msg: "); pw.println(info.longMsg); 10990 } 10991 if (info.stack != null) { 10992 pw.println(" Stack:"); 10993 int lastPos = 0; 10994 for (int pos=0; pos<info.stack.length(); pos++) { 10995 if (info.stack.charAt(pos) == '\n') { 10996 pw.print(" "); 10997 pw.write(info.stack, lastPos, pos-lastPos); 10998 pw.println(); 10999 lastPos = pos+1; 11000 } 11001 } 11002 if (lastPos < info.stack.length()) { 11003 pw.print(" "); 11004 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11005 pw.println(); 11006 } 11007 } 11008 } 11009 } 11010 } 11011 11012 if (dumpPackage == null) { 11013 pw.println(); 11014 needSep = false; 11015 pw.println(" mStartedUsers:"); 11016 for (int i=0; i<mStartedUsers.size(); i++) { 11017 UserStartedState uss = mStartedUsers.valueAt(i); 11018 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11019 pw.print(": "); uss.dump("", pw); 11020 } 11021 pw.print(" mStartedUserArray: ["); 11022 for (int i=0; i<mStartedUserArray.length; i++) { 11023 if (i > 0) pw.print(", "); 11024 pw.print(mStartedUserArray[i]); 11025 } 11026 pw.println("]"); 11027 pw.print(" mUserLru: ["); 11028 for (int i=0; i<mUserLru.size(); i++) { 11029 if (i > 0) pw.print(", "); 11030 pw.print(mUserLru.get(i)); 11031 } 11032 pw.println("]"); 11033 if (dumpAll) { 11034 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11035 } 11036 } 11037 if (mHomeProcess != null && (dumpPackage == null 11038 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11039 if (needSep) { 11040 pw.println(); 11041 needSep = false; 11042 } 11043 pw.println(" mHomeProcess: " + mHomeProcess); 11044 } 11045 if (mPreviousProcess != null && (dumpPackage == null 11046 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11047 if (needSep) { 11048 pw.println(); 11049 needSep = false; 11050 } 11051 pw.println(" mPreviousProcess: " + mPreviousProcess); 11052 } 11053 if (dumpAll) { 11054 StringBuilder sb = new StringBuilder(128); 11055 sb.append(" mPreviousProcessVisibleTime: "); 11056 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11057 pw.println(sb); 11058 } 11059 if (mHeavyWeightProcess != null && (dumpPackage == null 11060 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11061 if (needSep) { 11062 pw.println(); 11063 needSep = false; 11064 } 11065 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11066 } 11067 if (dumpPackage == null) { 11068 pw.println(" mConfiguration: " + mConfiguration); 11069 } 11070 if (dumpAll) { 11071 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11072 if (mCompatModePackages.getPackages().size() > 0) { 11073 boolean printed = false; 11074 for (Map.Entry<String, Integer> entry 11075 : mCompatModePackages.getPackages().entrySet()) { 11076 String pkg = entry.getKey(); 11077 int mode = entry.getValue(); 11078 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11079 continue; 11080 } 11081 if (!printed) { 11082 pw.println(" mScreenCompatPackages:"); 11083 printed = true; 11084 } 11085 pw.print(" "); pw.print(pkg); pw.print(": "); 11086 pw.print(mode); pw.println(); 11087 } 11088 } 11089 } 11090 if (dumpPackage == null) { 11091 if (mSleeping || mWentToSleep || mLockScreenShown) { 11092 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11093 + " mLockScreenShown " + mLockScreenShown); 11094 } 11095 if (mShuttingDown) { 11096 pw.println(" mShuttingDown=" + mShuttingDown); 11097 } 11098 } 11099 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11100 || mOrigWaitForDebugger) { 11101 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11102 || dumpPackage.equals(mOrigDebugApp)) { 11103 if (needSep) { 11104 pw.println(); 11105 needSep = false; 11106 } 11107 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11108 + " mDebugTransient=" + mDebugTransient 11109 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11110 } 11111 } 11112 if (mOpenGlTraceApp != null) { 11113 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11114 if (needSep) { 11115 pw.println(); 11116 needSep = false; 11117 } 11118 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11119 } 11120 } 11121 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11122 || mProfileFd != null) { 11123 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11124 if (needSep) { 11125 pw.println(); 11126 needSep = false; 11127 } 11128 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11129 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11130 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11131 + mAutoStopProfiler); 11132 } 11133 } 11134 if (dumpPackage == null) { 11135 if (mAlwaysFinishActivities || mController != null) { 11136 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11137 + " mController=" + mController); 11138 } 11139 if (dumpAll) { 11140 pw.println(" Total persistent processes: " + numPers); 11141 pw.println(" mStartRunning=" + mStartRunning 11142 + " mProcessesReady=" + mProcessesReady 11143 + " mSystemReady=" + mSystemReady); 11144 pw.println(" mBooting=" + mBooting 11145 + " mBooted=" + mBooted 11146 + " mFactoryTest=" + mFactoryTest); 11147 pw.print(" mLastPowerCheckRealtime="); 11148 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11149 pw.println(""); 11150 pw.print(" mLastPowerCheckUptime="); 11151 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11152 pw.println(""); 11153 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11154 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11155 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11156 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11157 + " (" + mLruProcesses.size() + " total)" 11158 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11159 + " mNumServiceProcs=" + mNumServiceProcs 11160 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11161 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11162 + " mLastMemoryLevel" + mLastMemoryLevel 11163 + " mLastNumProcesses" + mLastNumProcesses); 11164 long now = SystemClock.uptimeMillis(); 11165 pw.print(" mLastIdleTime="); 11166 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11167 pw.print(" mLowRamSinceLastIdle="); 11168 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11169 pw.println(); 11170 } 11171 } 11172 11173 if (!printedAnything) { 11174 pw.println(" (nothing)"); 11175 } 11176 } 11177 11178 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11179 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11180 if (mProcessesToGc.size() > 0) { 11181 boolean printed = false; 11182 long now = SystemClock.uptimeMillis(); 11183 for (int i=0; i<mProcessesToGc.size(); i++) { 11184 ProcessRecord proc = mProcessesToGc.get(i); 11185 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11186 continue; 11187 } 11188 if (!printed) { 11189 if (needSep) pw.println(); 11190 needSep = true; 11191 pw.println(" Processes that are waiting to GC:"); 11192 printed = true; 11193 } 11194 pw.print(" Process "); pw.println(proc); 11195 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11196 pw.print(", last gced="); 11197 pw.print(now-proc.lastRequestedGc); 11198 pw.print(" ms ago, last lowMem="); 11199 pw.print(now-proc.lastLowMemory); 11200 pw.println(" ms ago"); 11201 11202 } 11203 } 11204 return needSep; 11205 } 11206 11207 void printOomLevel(PrintWriter pw, String name, int adj) { 11208 pw.print(" "); 11209 if (adj >= 0) { 11210 pw.print(' '); 11211 if (adj < 10) pw.print(' '); 11212 } else { 11213 if (adj > -10) pw.print(' '); 11214 } 11215 pw.print(adj); 11216 pw.print(": "); 11217 pw.print(name); 11218 pw.print(" ("); 11219 pw.print(mProcessList.getMemLevel(adj)/1024); 11220 pw.println(" kB)"); 11221 } 11222 11223 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11224 int opti, boolean dumpAll) { 11225 boolean needSep = false; 11226 11227 if (mLruProcesses.size() > 0) { 11228 if (needSep) pw.println(); 11229 needSep = true; 11230 pw.println(" OOM levels:"); 11231 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11232 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11233 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11234 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11235 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11236 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11237 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11238 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11239 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11240 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11241 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11242 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11243 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11244 11245 if (needSep) pw.println(); 11246 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11247 pw.print(" total, non-act at "); 11248 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11249 pw.print(", non-svc at "); 11250 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11251 pw.println("):"); 11252 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11253 needSep = true; 11254 } 11255 11256 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11257 11258 pw.println(); 11259 pw.println(" mHomeProcess: " + mHomeProcess); 11260 pw.println(" mPreviousProcess: " + mPreviousProcess); 11261 if (mHeavyWeightProcess != null) { 11262 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11263 } 11264 11265 return true; 11266 } 11267 11268 /** 11269 * There are three ways to call this: 11270 * - no provider specified: dump all the providers 11271 * - a flattened component name that matched an existing provider was specified as the 11272 * first arg: dump that one provider 11273 * - the first arg isn't the flattened component name of an existing provider: 11274 * dump all providers whose component contains the first arg as a substring 11275 */ 11276 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11277 int opti, boolean dumpAll) { 11278 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11279 } 11280 11281 static class ItemMatcher { 11282 ArrayList<ComponentName> components; 11283 ArrayList<String> strings; 11284 ArrayList<Integer> objects; 11285 boolean all; 11286 11287 ItemMatcher() { 11288 all = true; 11289 } 11290 11291 void build(String name) { 11292 ComponentName componentName = ComponentName.unflattenFromString(name); 11293 if (componentName != null) { 11294 if (components == null) { 11295 components = new ArrayList<ComponentName>(); 11296 } 11297 components.add(componentName); 11298 all = false; 11299 } else { 11300 int objectId = 0; 11301 // Not a '/' separated full component name; maybe an object ID? 11302 try { 11303 objectId = Integer.parseInt(name, 16); 11304 if (objects == null) { 11305 objects = new ArrayList<Integer>(); 11306 } 11307 objects.add(objectId); 11308 all = false; 11309 } catch (RuntimeException e) { 11310 // Not an integer; just do string match. 11311 if (strings == null) { 11312 strings = new ArrayList<String>(); 11313 } 11314 strings.add(name); 11315 all = false; 11316 } 11317 } 11318 } 11319 11320 int build(String[] args, int opti) { 11321 for (; opti<args.length; opti++) { 11322 String name = args[opti]; 11323 if ("--".equals(name)) { 11324 return opti+1; 11325 } 11326 build(name); 11327 } 11328 return opti; 11329 } 11330 11331 boolean match(Object object, ComponentName comp) { 11332 if (all) { 11333 return true; 11334 } 11335 if (components != null) { 11336 for (int i=0; i<components.size(); i++) { 11337 if (components.get(i).equals(comp)) { 11338 return true; 11339 } 11340 } 11341 } 11342 if (objects != null) { 11343 for (int i=0; i<objects.size(); i++) { 11344 if (System.identityHashCode(object) == objects.get(i)) { 11345 return true; 11346 } 11347 } 11348 } 11349 if (strings != null) { 11350 String flat = comp.flattenToString(); 11351 for (int i=0; i<strings.size(); i++) { 11352 if (flat.contains(strings.get(i))) { 11353 return true; 11354 } 11355 } 11356 } 11357 return false; 11358 } 11359 } 11360 11361 /** 11362 * There are three things that cmd can be: 11363 * - a flattened component name that matches an existing activity 11364 * - the cmd arg isn't the flattened component name of an existing activity: 11365 * dump all activity whose component contains the cmd as a substring 11366 * - A hex number of the ActivityRecord object instance. 11367 */ 11368 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11369 int opti, boolean dumpAll) { 11370 ArrayList<ActivityRecord> activities; 11371 11372 synchronized (this) { 11373 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11374 } 11375 11376 if (activities.size() <= 0) { 11377 return false; 11378 } 11379 11380 String[] newArgs = new String[args.length - opti]; 11381 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11382 11383 TaskRecord lastTask = null; 11384 boolean needSep = false; 11385 for (int i=activities.size()-1; i>=0; i--) { 11386 ActivityRecord r = activities.get(i); 11387 if (needSep) { 11388 pw.println(); 11389 } 11390 needSep = true; 11391 synchronized (this) { 11392 if (lastTask != r.task) { 11393 lastTask = r.task; 11394 pw.print("TASK "); pw.print(lastTask.affinity); 11395 pw.print(" id="); pw.println(lastTask.taskId); 11396 if (dumpAll) { 11397 lastTask.dump(pw, " "); 11398 } 11399 } 11400 } 11401 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11402 } 11403 return true; 11404 } 11405 11406 /** 11407 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11408 * there is a thread associated with the activity. 11409 */ 11410 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11411 final ActivityRecord r, String[] args, boolean dumpAll) { 11412 String innerPrefix = prefix + " "; 11413 synchronized (this) { 11414 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11415 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11416 pw.print(" pid="); 11417 if (r.app != null) pw.println(r.app.pid); 11418 else pw.println("(not running)"); 11419 if (dumpAll) { 11420 r.dump(pw, innerPrefix); 11421 } 11422 } 11423 if (r.app != null && r.app.thread != null) { 11424 // flush anything that is already in the PrintWriter since the thread is going 11425 // to write to the file descriptor directly 11426 pw.flush(); 11427 try { 11428 TransferPipe tp = new TransferPipe(); 11429 try { 11430 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11431 r.appToken, innerPrefix, args); 11432 tp.go(fd); 11433 } finally { 11434 tp.kill(); 11435 } 11436 } catch (IOException e) { 11437 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11438 } catch (RemoteException e) { 11439 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11440 } 11441 } 11442 } 11443 11444 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11445 int opti, boolean dumpAll, String dumpPackage) { 11446 boolean needSep = false; 11447 boolean onlyHistory = false; 11448 boolean printedAnything = false; 11449 11450 if ("history".equals(dumpPackage)) { 11451 if (opti < args.length && "-s".equals(args[opti])) { 11452 dumpAll = false; 11453 } 11454 onlyHistory = true; 11455 dumpPackage = null; 11456 } 11457 11458 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11459 if (!onlyHistory && dumpAll) { 11460 if (mRegisteredReceivers.size() > 0) { 11461 boolean printed = false; 11462 Iterator it = mRegisteredReceivers.values().iterator(); 11463 while (it.hasNext()) { 11464 ReceiverList r = (ReceiverList)it.next(); 11465 if (dumpPackage != null && (r.app == null || 11466 !dumpPackage.equals(r.app.info.packageName))) { 11467 continue; 11468 } 11469 if (!printed) { 11470 pw.println(" Registered Receivers:"); 11471 needSep = true; 11472 printed = true; 11473 printedAnything = true; 11474 } 11475 pw.print(" * "); pw.println(r); 11476 r.dump(pw, " "); 11477 } 11478 } 11479 11480 if (mReceiverResolver.dump(pw, needSep ? 11481 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11482 " ", dumpPackage, false)) { 11483 needSep = true; 11484 printedAnything = true; 11485 } 11486 } 11487 11488 for (BroadcastQueue q : mBroadcastQueues) { 11489 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11490 printedAnything |= needSep; 11491 } 11492 11493 needSep = true; 11494 11495 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11496 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11497 if (needSep) { 11498 pw.println(); 11499 } 11500 needSep = true; 11501 printedAnything = true; 11502 pw.print(" Sticky broadcasts for user "); 11503 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11504 StringBuilder sb = new StringBuilder(128); 11505 for (Map.Entry<String, ArrayList<Intent>> ent 11506 : mStickyBroadcasts.valueAt(user).entrySet()) { 11507 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11508 if (dumpAll) { 11509 pw.println(":"); 11510 ArrayList<Intent> intents = ent.getValue(); 11511 final int N = intents.size(); 11512 for (int i=0; i<N; i++) { 11513 sb.setLength(0); 11514 sb.append(" Intent: "); 11515 intents.get(i).toShortString(sb, false, true, false, false); 11516 pw.println(sb.toString()); 11517 Bundle bundle = intents.get(i).getExtras(); 11518 if (bundle != null) { 11519 pw.print(" "); 11520 pw.println(bundle.toString()); 11521 } 11522 } 11523 } else { 11524 pw.println(""); 11525 } 11526 } 11527 } 11528 } 11529 11530 if (!onlyHistory && dumpAll) { 11531 pw.println(); 11532 for (BroadcastQueue queue : mBroadcastQueues) { 11533 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11534 + queue.mBroadcastsScheduled); 11535 } 11536 pw.println(" mHandler:"); 11537 mHandler.dump(new PrintWriterPrinter(pw), " "); 11538 needSep = true; 11539 printedAnything = true; 11540 } 11541 11542 if (!printedAnything) { 11543 pw.println(" (nothing)"); 11544 } 11545 } 11546 11547 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11548 int opti, boolean dumpAll, String dumpPackage) { 11549 boolean needSep; 11550 boolean printedAnything = false; 11551 11552 ItemMatcher matcher = new ItemMatcher(); 11553 matcher.build(args, opti); 11554 11555 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11556 11557 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11558 printedAnything |= needSep; 11559 11560 if (mLaunchingProviders.size() > 0) { 11561 boolean printed = false; 11562 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11563 ContentProviderRecord r = mLaunchingProviders.get(i); 11564 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11565 continue; 11566 } 11567 if (!printed) { 11568 if (needSep) pw.println(); 11569 needSep = true; 11570 pw.println(" Launching content providers:"); 11571 printed = true; 11572 printedAnything = true; 11573 } 11574 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11575 pw.println(r); 11576 } 11577 } 11578 11579 if (mGrantedUriPermissions.size() > 0) { 11580 boolean printed = false; 11581 int dumpUid = -2; 11582 if (dumpPackage != null) { 11583 try { 11584 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11585 } catch (NameNotFoundException e) { 11586 dumpUid = -1; 11587 } 11588 } 11589 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11590 int uid = mGrantedUriPermissions.keyAt(i); 11591 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11592 continue; 11593 } 11594 ArrayMap<Uri, UriPermission> perms 11595 = mGrantedUriPermissions.valueAt(i); 11596 if (!printed) { 11597 if (needSep) pw.println(); 11598 needSep = true; 11599 pw.println(" Granted Uri Permissions:"); 11600 printed = true; 11601 printedAnything = true; 11602 } 11603 pw.print(" * UID "); pw.print(uid); 11604 pw.println(" holds:"); 11605 for (UriPermission perm : perms.values()) { 11606 pw.print(" "); pw.println(perm); 11607 if (dumpAll) { 11608 perm.dump(pw, " "); 11609 } 11610 } 11611 } 11612 } 11613 11614 if (!printedAnything) { 11615 pw.println(" (nothing)"); 11616 } 11617 } 11618 11619 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11620 int opti, boolean dumpAll, String dumpPackage) { 11621 boolean printed = false; 11622 11623 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11624 11625 if (mIntentSenderRecords.size() > 0) { 11626 Iterator<WeakReference<PendingIntentRecord>> it 11627 = mIntentSenderRecords.values().iterator(); 11628 while (it.hasNext()) { 11629 WeakReference<PendingIntentRecord> ref = it.next(); 11630 PendingIntentRecord rec = ref != null ? ref.get(): null; 11631 if (dumpPackage != null && (rec == null 11632 || !dumpPackage.equals(rec.key.packageName))) { 11633 continue; 11634 } 11635 printed = true; 11636 if (rec != null) { 11637 pw.print(" * "); pw.println(rec); 11638 if (dumpAll) { 11639 rec.dump(pw, " "); 11640 } 11641 } else { 11642 pw.print(" * "); pw.println(ref); 11643 } 11644 } 11645 } 11646 11647 if (!printed) { 11648 pw.println(" (nothing)"); 11649 } 11650 } 11651 11652 private static final int dumpProcessList(PrintWriter pw, 11653 ActivityManagerService service, List list, 11654 String prefix, String normalLabel, String persistentLabel, 11655 String dumpPackage) { 11656 int numPers = 0; 11657 final int N = list.size()-1; 11658 for (int i=N; i>=0; i--) { 11659 ProcessRecord r = (ProcessRecord)list.get(i); 11660 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11661 continue; 11662 } 11663 pw.println(String.format("%s%s #%2d: %s", 11664 prefix, (r.persistent ? persistentLabel : normalLabel), 11665 i, r.toString())); 11666 if (r.persistent) { 11667 numPers++; 11668 } 11669 } 11670 return numPers; 11671 } 11672 11673 private static final boolean dumpProcessOomList(PrintWriter pw, 11674 ActivityManagerService service, List<ProcessRecord> origList, 11675 String prefix, String normalLabel, String persistentLabel, 11676 boolean inclDetails, String dumpPackage) { 11677 11678 ArrayList<Pair<ProcessRecord, Integer>> list 11679 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11680 for (int i=0; i<origList.size(); i++) { 11681 ProcessRecord r = origList.get(i); 11682 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11683 continue; 11684 } 11685 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11686 } 11687 11688 if (list.size() <= 0) { 11689 return false; 11690 } 11691 11692 Comparator<Pair<ProcessRecord, Integer>> comparator 11693 = new Comparator<Pair<ProcessRecord, Integer>>() { 11694 @Override 11695 public int compare(Pair<ProcessRecord, Integer> object1, 11696 Pair<ProcessRecord, Integer> object2) { 11697 if (object1.first.setAdj != object2.first.setAdj) { 11698 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11699 } 11700 if (object1.second.intValue() != object2.second.intValue()) { 11701 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11702 } 11703 return 0; 11704 } 11705 }; 11706 11707 Collections.sort(list, comparator); 11708 11709 final long curRealtime = SystemClock.elapsedRealtime(); 11710 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11711 final long curUptime = SystemClock.uptimeMillis(); 11712 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11713 11714 for (int i=list.size()-1; i>=0; i--) { 11715 ProcessRecord r = list.get(i).first; 11716 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11717 char schedGroup; 11718 switch (r.setSchedGroup) { 11719 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11720 schedGroup = 'B'; 11721 break; 11722 case Process.THREAD_GROUP_DEFAULT: 11723 schedGroup = 'F'; 11724 break; 11725 default: 11726 schedGroup = '?'; 11727 break; 11728 } 11729 char foreground; 11730 if (r.foregroundActivities) { 11731 foreground = 'A'; 11732 } else if (r.foregroundServices) { 11733 foreground = 'S'; 11734 } else { 11735 foreground = ' '; 11736 } 11737 String procState = ProcessList.makeProcStateString(r.curProcState); 11738 pw.print(prefix); 11739 pw.print(r.persistent ? persistentLabel : normalLabel); 11740 pw.print(" #"); 11741 int num = (origList.size()-1)-list.get(i).second; 11742 if (num < 10) pw.print(' '); 11743 pw.print(num); 11744 pw.print(": "); 11745 pw.print(oomAdj); 11746 pw.print(' '); 11747 pw.print(schedGroup); 11748 pw.print('/'); 11749 pw.print(foreground); 11750 pw.print('/'); 11751 pw.print(procState); 11752 pw.print(" trm:"); 11753 if (r.trimMemoryLevel < 10) pw.print(' '); 11754 pw.print(r.trimMemoryLevel); 11755 pw.print(' '); 11756 pw.print(r.toShortString()); 11757 pw.print(" ("); 11758 pw.print(r.adjType); 11759 pw.println(')'); 11760 if (r.adjSource != null || r.adjTarget != null) { 11761 pw.print(prefix); 11762 pw.print(" "); 11763 if (r.adjTarget instanceof ComponentName) { 11764 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11765 } else if (r.adjTarget != null) { 11766 pw.print(r.adjTarget.toString()); 11767 } else { 11768 pw.print("{null}"); 11769 } 11770 pw.print("<="); 11771 if (r.adjSource instanceof ProcessRecord) { 11772 pw.print("Proc{"); 11773 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11774 pw.println("}"); 11775 } else if (r.adjSource != null) { 11776 pw.println(r.adjSource.toString()); 11777 } else { 11778 pw.println("{null}"); 11779 } 11780 } 11781 if (inclDetails) { 11782 pw.print(prefix); 11783 pw.print(" "); 11784 pw.print("oom: max="); pw.print(r.maxAdj); 11785 pw.print(" curRaw="); pw.print(r.curRawAdj); 11786 pw.print(" setRaw="); pw.print(r.setRawAdj); 11787 pw.print(" cur="); pw.print(r.curAdj); 11788 pw.print(" set="); pw.println(r.setAdj); 11789 pw.print(prefix); 11790 pw.print(" "); 11791 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11792 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11793 pw.print(" lastPss="); pw.print(r.lastPss); 11794 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11795 pw.print(prefix); 11796 pw.print(" "); 11797 pw.print("keeping="); pw.print(r.keeping); 11798 pw.print(" cached="); pw.print(r.cached); 11799 pw.print(" empty="); pw.print(r.empty); 11800 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11801 11802 if (!r.keeping) { 11803 if (r.lastWakeTime != 0) { 11804 long wtime; 11805 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11806 synchronized (stats) { 11807 wtime = stats.getProcessWakeTime(r.info.uid, 11808 r.pid, curRealtime); 11809 } 11810 long timeUsed = wtime - r.lastWakeTime; 11811 pw.print(prefix); 11812 pw.print(" "); 11813 pw.print("keep awake over "); 11814 TimeUtils.formatDuration(realtimeSince, pw); 11815 pw.print(" used "); 11816 TimeUtils.formatDuration(timeUsed, pw); 11817 pw.print(" ("); 11818 pw.print((timeUsed*100)/realtimeSince); 11819 pw.println("%)"); 11820 } 11821 if (r.lastCpuTime != 0) { 11822 long timeUsed = r.curCpuTime - r.lastCpuTime; 11823 pw.print(prefix); 11824 pw.print(" "); 11825 pw.print("run cpu over "); 11826 TimeUtils.formatDuration(uptimeSince, pw); 11827 pw.print(" used "); 11828 TimeUtils.formatDuration(timeUsed, pw); 11829 pw.print(" ("); 11830 pw.print((timeUsed*100)/uptimeSince); 11831 pw.println("%)"); 11832 } 11833 } 11834 } 11835 } 11836 return true; 11837 } 11838 11839 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11840 ArrayList<ProcessRecord> procs; 11841 synchronized (this) { 11842 if (args != null && args.length > start 11843 && args[start].charAt(0) != '-') { 11844 procs = new ArrayList<ProcessRecord>(); 11845 int pid = -1; 11846 try { 11847 pid = Integer.parseInt(args[start]); 11848 } catch (NumberFormatException e) { 11849 } 11850 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11851 ProcessRecord proc = mLruProcesses.get(i); 11852 if (proc.pid == pid) { 11853 procs.add(proc); 11854 } else if (proc.processName.equals(args[start])) { 11855 procs.add(proc); 11856 } 11857 } 11858 if (procs.size() <= 0) { 11859 return null; 11860 } 11861 } else { 11862 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11863 } 11864 } 11865 return procs; 11866 } 11867 11868 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11869 PrintWriter pw, String[] args) { 11870 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11871 if (procs == null) { 11872 pw.println("No process found for: " + args[0]); 11873 return; 11874 } 11875 11876 long uptime = SystemClock.uptimeMillis(); 11877 long realtime = SystemClock.elapsedRealtime(); 11878 pw.println("Applications Graphics Acceleration Info:"); 11879 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11880 11881 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11882 ProcessRecord r = procs.get(i); 11883 if (r.thread != null) { 11884 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11885 pw.flush(); 11886 try { 11887 TransferPipe tp = new TransferPipe(); 11888 try { 11889 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11890 tp.go(fd); 11891 } finally { 11892 tp.kill(); 11893 } 11894 } catch (IOException e) { 11895 pw.println("Failure while dumping the app: " + r); 11896 pw.flush(); 11897 } catch (RemoteException e) { 11898 pw.println("Got a RemoteException while dumping the app " + r); 11899 pw.flush(); 11900 } 11901 } 11902 } 11903 } 11904 11905 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11906 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11907 if (procs == null) { 11908 pw.println("No process found for: " + args[0]); 11909 return; 11910 } 11911 11912 pw.println("Applications Database Info:"); 11913 11914 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11915 ProcessRecord r = procs.get(i); 11916 if (r.thread != null) { 11917 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11918 pw.flush(); 11919 try { 11920 TransferPipe tp = new TransferPipe(); 11921 try { 11922 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11923 tp.go(fd); 11924 } finally { 11925 tp.kill(); 11926 } 11927 } catch (IOException e) { 11928 pw.println("Failure while dumping the app: " + r); 11929 pw.flush(); 11930 } catch (RemoteException e) { 11931 pw.println("Got a RemoteException while dumping the app " + r); 11932 pw.flush(); 11933 } 11934 } 11935 } 11936 } 11937 11938 final static class MemItem { 11939 final boolean isProc; 11940 final String label; 11941 final String shortLabel; 11942 final long pss; 11943 final int id; 11944 final boolean hasActivities; 11945 ArrayList<MemItem> subitems; 11946 11947 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11948 boolean _hasActivities) { 11949 isProc = true; 11950 label = _label; 11951 shortLabel = _shortLabel; 11952 pss = _pss; 11953 id = _id; 11954 hasActivities = _hasActivities; 11955 } 11956 11957 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11958 isProc = false; 11959 label = _label; 11960 shortLabel = _shortLabel; 11961 pss = _pss; 11962 id = _id; 11963 hasActivities = false; 11964 } 11965 } 11966 11967 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11968 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11969 if (sort && !isCompact) { 11970 Collections.sort(items, new Comparator<MemItem>() { 11971 @Override 11972 public int compare(MemItem lhs, MemItem rhs) { 11973 if (lhs.pss < rhs.pss) { 11974 return 1; 11975 } else if (lhs.pss > rhs.pss) { 11976 return -1; 11977 } 11978 return 0; 11979 } 11980 }); 11981 } 11982 11983 for (int i=0; i<items.size(); i++) { 11984 MemItem mi = items.get(i); 11985 if (!isCompact) { 11986 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11987 } else if (mi.isProc) { 11988 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11989 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11990 pw.println(mi.hasActivities ? ",a" : ",e"); 11991 } else { 11992 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11993 pw.println(mi.pss); 11994 } 11995 if (mi.subitems != null) { 11996 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11997 true, isCompact); 11998 } 11999 } 12000 } 12001 12002 // These are in KB. 12003 static final long[] DUMP_MEM_BUCKETS = new long[] { 12004 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12005 120*1024, 160*1024, 200*1024, 12006 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12007 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12008 }; 12009 12010 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12011 boolean stackLike) { 12012 int start = label.lastIndexOf('.'); 12013 if (start >= 0) start++; 12014 else start = 0; 12015 int end = label.length(); 12016 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12017 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12018 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12019 out.append(bucket); 12020 out.append(stackLike ? "MB." : "MB "); 12021 out.append(label, start, end); 12022 return; 12023 } 12024 } 12025 out.append(memKB/1024); 12026 out.append(stackLike ? "MB." : "MB "); 12027 out.append(label, start, end); 12028 } 12029 12030 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12031 ProcessList.NATIVE_ADJ, 12032 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12033 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12034 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12035 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12036 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12037 }; 12038 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12039 "Native", 12040 "System", "Persistent", "Foreground", 12041 "Visible", "Perceptible", 12042 "Heavy Weight", "Backup", 12043 "A Services", "Home", 12044 "Previous", "B Services", "Cached" 12045 }; 12046 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12047 "native", 12048 "sys", "pers", "fore", 12049 "vis", "percept", 12050 "heavy", "backup", 12051 "servicea", "home", 12052 "prev", "serviceb", "cached" 12053 }; 12054 12055 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12056 long realtime, boolean isCheckinRequest, boolean isCompact) { 12057 if (isCheckinRequest || isCompact) { 12058 // short checkin version 12059 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12060 } else { 12061 pw.println("Applications Memory Usage (kB):"); 12062 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12063 } 12064 } 12065 12066 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12067 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12068 boolean dumpDetails = false; 12069 boolean dumpFullDetails = false; 12070 boolean dumpDalvik = false; 12071 boolean oomOnly = false; 12072 boolean isCompact = false; 12073 boolean localOnly = false; 12074 12075 int opti = 0; 12076 while (opti < args.length) { 12077 String opt = args[opti]; 12078 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12079 break; 12080 } 12081 opti++; 12082 if ("-a".equals(opt)) { 12083 dumpDetails = true; 12084 dumpFullDetails = true; 12085 dumpDalvik = true; 12086 } else if ("-d".equals(opt)) { 12087 dumpDalvik = true; 12088 } else if ("-c".equals(opt)) { 12089 isCompact = true; 12090 } else if ("--oom".equals(opt)) { 12091 oomOnly = true; 12092 } else if ("--local".equals(opt)) { 12093 localOnly = true; 12094 } else if ("-h".equals(opt)) { 12095 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12096 pw.println(" -a: include all available information for each process."); 12097 pw.println(" -d: include dalvik details when dumping process details."); 12098 pw.println(" -c: dump in a compact machine-parseable representation."); 12099 pw.println(" --oom: only show processes organized by oom adj."); 12100 pw.println(" --local: only collect details locally, don't call process."); 12101 pw.println("If [process] is specified it can be the name or "); 12102 pw.println("pid of a specific process to dump."); 12103 return; 12104 } else { 12105 pw.println("Unknown argument: " + opt + "; use -h for help"); 12106 } 12107 } 12108 12109 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12110 long uptime = SystemClock.uptimeMillis(); 12111 long realtime = SystemClock.elapsedRealtime(); 12112 final long[] tmpLong = new long[1]; 12113 12114 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12115 if (procs == null) { 12116 // No Java processes. Maybe they want to print a native process. 12117 if (args != null && args.length > opti 12118 && args[opti].charAt(0) != '-') { 12119 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12120 = new ArrayList<ProcessCpuTracker.Stats>(); 12121 updateCpuStatsNow(); 12122 int findPid = -1; 12123 try { 12124 findPid = Integer.parseInt(args[opti]); 12125 } catch (NumberFormatException e) { 12126 } 12127 synchronized (mProcessCpuThread) { 12128 final int N = mProcessCpuTracker.countStats(); 12129 for (int i=0; i<N; i++) { 12130 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12131 if (st.pid == findPid || (st.baseName != null 12132 && st.baseName.equals(args[opti]))) { 12133 nativeProcs.add(st); 12134 } 12135 } 12136 } 12137 if (nativeProcs.size() > 0) { 12138 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12139 isCompact); 12140 Debug.MemoryInfo mi = null; 12141 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12142 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12143 final int pid = r.pid; 12144 if (!isCheckinRequest && dumpDetails) { 12145 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12146 } 12147 if (mi == null) { 12148 mi = new Debug.MemoryInfo(); 12149 } 12150 if (dumpDetails || (!brief && !oomOnly)) { 12151 Debug.getMemoryInfo(pid, mi); 12152 } else { 12153 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12154 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12155 } 12156 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12157 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12158 if (isCheckinRequest) { 12159 pw.println(); 12160 } 12161 } 12162 return; 12163 } 12164 } 12165 pw.println("No process found for: " + args[opti]); 12166 return; 12167 } 12168 12169 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12170 dumpDetails = true; 12171 } 12172 12173 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12174 12175 String[] innerArgs = new String[args.length-opti]; 12176 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12177 12178 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12179 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12180 long nativePss=0, dalvikPss=0, otherPss=0; 12181 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12182 12183 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12184 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12185 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12186 12187 long totalPss = 0; 12188 long cachedPss = 0; 12189 12190 Debug.MemoryInfo mi = null; 12191 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12192 final ProcessRecord r = procs.get(i); 12193 final IApplicationThread thread; 12194 final int pid; 12195 final int oomAdj; 12196 final boolean hasActivities; 12197 synchronized (this) { 12198 thread = r.thread; 12199 pid = r.pid; 12200 oomAdj = r.getSetAdjWithServices(); 12201 hasActivities = r.activities.size() > 0; 12202 } 12203 if (thread != null) { 12204 if (!isCheckinRequest && dumpDetails) { 12205 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12206 } 12207 if (mi == null) { 12208 mi = new Debug.MemoryInfo(); 12209 } 12210 if (dumpDetails || (!brief && !oomOnly)) { 12211 Debug.getMemoryInfo(pid, mi); 12212 } else { 12213 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12214 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12215 } 12216 if (dumpDetails) { 12217 if (localOnly) { 12218 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12219 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12220 if (isCheckinRequest) { 12221 pw.println(); 12222 } 12223 } else { 12224 try { 12225 pw.flush(); 12226 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12227 dumpDalvik, innerArgs); 12228 } catch (RemoteException e) { 12229 if (!isCheckinRequest) { 12230 pw.println("Got RemoteException!"); 12231 pw.flush(); 12232 } 12233 } 12234 } 12235 } 12236 12237 final long myTotalPss = mi.getTotalPss(); 12238 final long myTotalUss = mi.getTotalUss(); 12239 12240 synchronized (this) { 12241 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12242 // Record this for posterity if the process has been stable. 12243 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12244 } 12245 } 12246 12247 if (!isCheckinRequest && mi != null) { 12248 totalPss += myTotalPss; 12249 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12250 (hasActivities ? " / activities)" : ")"), 12251 r.processName, myTotalPss, pid, hasActivities); 12252 procMems.add(pssItem); 12253 procMemsMap.put(pid, pssItem); 12254 12255 nativePss += mi.nativePss; 12256 dalvikPss += mi.dalvikPss; 12257 otherPss += mi.otherPss; 12258 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12259 long mem = mi.getOtherPss(j); 12260 miscPss[j] += mem; 12261 otherPss -= mem; 12262 } 12263 12264 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12265 cachedPss += myTotalPss; 12266 } 12267 12268 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12269 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12270 || oomIndex == (oomPss.length-1)) { 12271 oomPss[oomIndex] += myTotalPss; 12272 if (oomProcs[oomIndex] == null) { 12273 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12274 } 12275 oomProcs[oomIndex].add(pssItem); 12276 break; 12277 } 12278 } 12279 } 12280 } 12281 } 12282 12283 if (!isCheckinRequest && procs.size() > 1) { 12284 // If we are showing aggregations, also look for native processes to 12285 // include so that our aggregations are more accurate. 12286 updateCpuStatsNow(); 12287 synchronized (mProcessCpuThread) { 12288 final int N = mProcessCpuTracker.countStats(); 12289 for (int i=0; i<N; i++) { 12290 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12291 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12292 if (mi == null) { 12293 mi = new Debug.MemoryInfo(); 12294 } 12295 if (!brief && !oomOnly) { 12296 Debug.getMemoryInfo(st.pid, mi); 12297 } else { 12298 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12299 mi.nativePrivateDirty = (int)tmpLong[0]; 12300 } 12301 12302 final long myTotalPss = mi.getTotalPss(); 12303 totalPss += myTotalPss; 12304 12305 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12306 st.name, myTotalPss, st.pid, false); 12307 procMems.add(pssItem); 12308 12309 nativePss += mi.nativePss; 12310 dalvikPss += mi.dalvikPss; 12311 otherPss += mi.otherPss; 12312 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12313 long mem = mi.getOtherPss(j); 12314 miscPss[j] += mem; 12315 otherPss -= mem; 12316 } 12317 oomPss[0] += myTotalPss; 12318 if (oomProcs[0] == null) { 12319 oomProcs[0] = new ArrayList<MemItem>(); 12320 } 12321 oomProcs[0].add(pssItem); 12322 } 12323 } 12324 } 12325 12326 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12327 12328 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12329 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12330 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12331 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12332 String label = Debug.MemoryInfo.getOtherLabel(j); 12333 catMems.add(new MemItem(label, label, miscPss[j], j)); 12334 } 12335 12336 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12337 for (int j=0; j<oomPss.length; j++) { 12338 if (oomPss[j] != 0) { 12339 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12340 : DUMP_MEM_OOM_LABEL[j]; 12341 MemItem item = new MemItem(label, label, oomPss[j], 12342 DUMP_MEM_OOM_ADJ[j]); 12343 item.subitems = oomProcs[j]; 12344 oomMems.add(item); 12345 } 12346 } 12347 12348 if (!brief && !oomOnly && !isCompact) { 12349 pw.println(); 12350 pw.println("Total PSS by process:"); 12351 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12352 pw.println(); 12353 } 12354 if (!isCompact) { 12355 pw.println("Total PSS by OOM adjustment:"); 12356 } 12357 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12358 if (!brief && !oomOnly) { 12359 PrintWriter out = categoryPw != null ? categoryPw : pw; 12360 if (!isCompact) { 12361 out.println(); 12362 out.println("Total PSS by category:"); 12363 } 12364 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12365 } 12366 if (!isCompact) { 12367 pw.println(); 12368 } 12369 MemInfoReader memInfo = new MemInfoReader(); 12370 memInfo.readMemInfo(); 12371 if (!brief) { 12372 if (!isCompact) { 12373 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12374 pw.print(" kB (status "); 12375 switch (mLastMemoryLevel) { 12376 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12377 pw.println("normal)"); 12378 break; 12379 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12380 pw.println("moderate)"); 12381 break; 12382 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12383 pw.println("low)"); 12384 break; 12385 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12386 pw.println("critical)"); 12387 break; 12388 default: 12389 pw.print(mLastMemoryLevel); 12390 pw.println(")"); 12391 break; 12392 } 12393 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12394 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12395 pw.print(cachedPss); pw.print(" cached pss + "); 12396 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12397 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12398 } else { 12399 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12400 pw.print(cachedPss + memInfo.getCachedSizeKb() 12401 + memInfo.getFreeSizeKb()); pw.print(","); 12402 pw.println(totalPss - cachedPss); 12403 } 12404 } 12405 if (!isCompact) { 12406 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12407 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12408 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12409 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12410 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12411 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12412 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12413 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12414 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12415 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12416 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12417 } 12418 if (!brief) { 12419 if (memInfo.getZramTotalSizeKb() != 0) { 12420 if (!isCompact) { 12421 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12422 pw.print(" kB physical used for "); 12423 pw.print(memInfo.getSwapTotalSizeKb() 12424 - memInfo.getSwapFreeSizeKb()); 12425 pw.print(" kB in swap ("); 12426 pw.print(memInfo.getSwapTotalSizeKb()); 12427 pw.println(" kB total swap)"); 12428 } else { 12429 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12430 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12431 pw.println(memInfo.getSwapFreeSizeKb()); 12432 } 12433 } 12434 final int[] SINGLE_LONG_FORMAT = new int[] { 12435 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12436 }; 12437 long[] longOut = new long[1]; 12438 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12439 SINGLE_LONG_FORMAT, null, longOut, null); 12440 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12441 longOut[0] = 0; 12442 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12443 SINGLE_LONG_FORMAT, null, longOut, null); 12444 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12445 longOut[0] = 0; 12446 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12447 SINGLE_LONG_FORMAT, null, longOut, null); 12448 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12449 longOut[0] = 0; 12450 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12451 SINGLE_LONG_FORMAT, null, longOut, null); 12452 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12453 if (!isCompact) { 12454 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12455 pw.print(" KSM: "); pw.print(sharing); 12456 pw.print(" kB saved from shared "); 12457 pw.print(shared); pw.println(" kB"); 12458 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12459 pw.print(voltile); pw.println(" kB volatile"); 12460 } 12461 pw.print(" Tuning: "); 12462 pw.print(ActivityManager.staticGetMemoryClass()); 12463 pw.print(" (large "); 12464 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12465 pw.print("), oom "); 12466 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12467 pw.print(" kB"); 12468 pw.print(", restore limit "); 12469 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12470 pw.print(" kB"); 12471 if (ActivityManager.isLowRamDeviceStatic()) { 12472 pw.print(" (low-ram)"); 12473 } 12474 if (ActivityManager.isHighEndGfx()) { 12475 pw.print(" (high-end-gfx)"); 12476 } 12477 pw.println(); 12478 } else { 12479 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12480 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12481 pw.println(voltile); 12482 pw.print("tuning,"); 12483 pw.print(ActivityManager.staticGetMemoryClass()); 12484 pw.print(','); 12485 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12486 pw.print(','); 12487 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12488 if (ActivityManager.isLowRamDeviceStatic()) { 12489 pw.print(",low-ram"); 12490 } 12491 if (ActivityManager.isHighEndGfx()) { 12492 pw.print(",high-end-gfx"); 12493 } 12494 pw.println(); 12495 } 12496 } 12497 } 12498 } 12499 12500 /** 12501 * Searches array of arguments for the specified string 12502 * @param args array of argument strings 12503 * @param value value to search for 12504 * @return true if the value is contained in the array 12505 */ 12506 private static boolean scanArgs(String[] args, String value) { 12507 if (args != null) { 12508 for (String arg : args) { 12509 if (value.equals(arg)) { 12510 return true; 12511 } 12512 } 12513 } 12514 return false; 12515 } 12516 12517 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12518 ContentProviderRecord cpr, boolean always) { 12519 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12520 12521 if (!inLaunching || always) { 12522 synchronized (cpr) { 12523 cpr.launchingApp = null; 12524 cpr.notifyAll(); 12525 } 12526 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12527 String names[] = cpr.info.authority.split(";"); 12528 for (int j = 0; j < names.length; j++) { 12529 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12530 } 12531 } 12532 12533 for (int i=0; i<cpr.connections.size(); i++) { 12534 ContentProviderConnection conn = cpr.connections.get(i); 12535 if (conn.waiting) { 12536 // If this connection is waiting for the provider, then we don't 12537 // need to mess with its process unless we are always removing 12538 // or for some reason the provider is not currently launching. 12539 if (inLaunching && !always) { 12540 continue; 12541 } 12542 } 12543 ProcessRecord capp = conn.client; 12544 conn.dead = true; 12545 if (conn.stableCount > 0) { 12546 if (!capp.persistent && capp.thread != null 12547 && capp.pid != 0 12548 && capp.pid != MY_PID) { 12549 killUnneededProcessLocked(capp, "depends on provider " 12550 + cpr.name.flattenToShortString() 12551 + " in dying proc " + (proc != null ? proc.processName : "??")); 12552 } 12553 } else if (capp.thread != null && conn.provider.provider != null) { 12554 try { 12555 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12556 } catch (RemoteException e) { 12557 } 12558 // In the protocol here, we don't expect the client to correctly 12559 // clean up this connection, we'll just remove it. 12560 cpr.connections.remove(i); 12561 conn.client.conProviders.remove(conn); 12562 } 12563 } 12564 12565 if (inLaunching && always) { 12566 mLaunchingProviders.remove(cpr); 12567 } 12568 return inLaunching; 12569 } 12570 12571 /** 12572 * Main code for cleaning up a process when it has gone away. This is 12573 * called both as a result of the process dying, or directly when stopping 12574 * a process when running in single process mode. 12575 */ 12576 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12577 boolean restarting, boolean allowRestart, int index) { 12578 if (index >= 0) { 12579 removeLruProcessLocked(app); 12580 ProcessList.remove(app.pid); 12581 } 12582 12583 mProcessesToGc.remove(app); 12584 mPendingPssProcesses.remove(app); 12585 12586 // Dismiss any open dialogs. 12587 if (app.crashDialog != null && !app.forceCrashReport) { 12588 app.crashDialog.dismiss(); 12589 app.crashDialog = null; 12590 } 12591 if (app.anrDialog != null) { 12592 app.anrDialog.dismiss(); 12593 app.anrDialog = null; 12594 } 12595 if (app.waitDialog != null) { 12596 app.waitDialog.dismiss(); 12597 app.waitDialog = null; 12598 } 12599 12600 app.crashing = false; 12601 app.notResponding = false; 12602 12603 app.resetPackageList(mProcessStats); 12604 app.unlinkDeathRecipient(); 12605 app.makeInactive(mProcessStats); 12606 app.forcingToForeground = null; 12607 updateProcessForegroundLocked(app, false, false); 12608 app.foregroundActivities = false; 12609 app.hasShownUi = false; 12610 app.treatLikeActivity = false; 12611 app.hasAboveClient = false; 12612 app.hasClientActivities = false; 12613 12614 mServices.killServicesLocked(app, allowRestart); 12615 12616 boolean restart = false; 12617 12618 // Remove published content providers. 12619 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12620 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12621 final boolean always = app.bad || !allowRestart; 12622 if (removeDyingProviderLocked(app, cpr, always) || always) { 12623 // We left the provider in the launching list, need to 12624 // restart it. 12625 restart = true; 12626 } 12627 12628 cpr.provider = null; 12629 cpr.proc = null; 12630 } 12631 app.pubProviders.clear(); 12632 12633 // Take care of any launching providers waiting for this process. 12634 if (checkAppInLaunchingProvidersLocked(app, false)) { 12635 restart = true; 12636 } 12637 12638 // Unregister from connected content providers. 12639 if (!app.conProviders.isEmpty()) { 12640 for (int i=0; i<app.conProviders.size(); i++) { 12641 ContentProviderConnection conn = app.conProviders.get(i); 12642 conn.provider.connections.remove(conn); 12643 } 12644 app.conProviders.clear(); 12645 } 12646 12647 // At this point there may be remaining entries in mLaunchingProviders 12648 // where we were the only one waiting, so they are no longer of use. 12649 // Look for these and clean up if found. 12650 // XXX Commented out for now. Trying to figure out a way to reproduce 12651 // the actual situation to identify what is actually going on. 12652 if (false) { 12653 for (int i=0; i<mLaunchingProviders.size(); i++) { 12654 ContentProviderRecord cpr = (ContentProviderRecord) 12655 mLaunchingProviders.get(i); 12656 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12657 synchronized (cpr) { 12658 cpr.launchingApp = null; 12659 cpr.notifyAll(); 12660 } 12661 } 12662 } 12663 } 12664 12665 skipCurrentReceiverLocked(app); 12666 12667 // Unregister any receivers. 12668 for (int i=app.receivers.size()-1; i>=0; i--) { 12669 removeReceiverLocked(app.receivers.valueAt(i)); 12670 } 12671 app.receivers.clear(); 12672 12673 // If the app is undergoing backup, tell the backup manager about it 12674 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12675 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12676 + mBackupTarget.appInfo + " died during backup"); 12677 try { 12678 IBackupManager bm = IBackupManager.Stub.asInterface( 12679 ServiceManager.getService(Context.BACKUP_SERVICE)); 12680 bm.agentDisconnected(app.info.packageName); 12681 } catch (RemoteException e) { 12682 // can't happen; backup manager is local 12683 } 12684 } 12685 12686 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12687 ProcessChangeItem item = mPendingProcessChanges.get(i); 12688 if (item.pid == app.pid) { 12689 mPendingProcessChanges.remove(i); 12690 mAvailProcessChanges.add(item); 12691 } 12692 } 12693 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12694 12695 // If the caller is restarting this app, then leave it in its 12696 // current lists and let the caller take care of it. 12697 if (restarting) { 12698 return; 12699 } 12700 12701 if (!app.persistent || app.isolated) { 12702 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12703 "Removing non-persistent process during cleanup: " + app); 12704 mProcessNames.remove(app.processName, app.uid); 12705 mIsolatedProcesses.remove(app.uid); 12706 if (mHeavyWeightProcess == app) { 12707 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12708 mHeavyWeightProcess.userId, 0)); 12709 mHeavyWeightProcess = null; 12710 } 12711 } else if (!app.removed) { 12712 // This app is persistent, so we need to keep its record around. 12713 // If it is not already on the pending app list, add it there 12714 // and start a new process for it. 12715 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12716 mPersistentStartingProcesses.add(app); 12717 restart = true; 12718 } 12719 } 12720 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12721 "Clean-up removing on hold: " + app); 12722 mProcessesOnHold.remove(app); 12723 12724 if (app == mHomeProcess) { 12725 mHomeProcess = null; 12726 } 12727 if (app == mPreviousProcess) { 12728 mPreviousProcess = null; 12729 } 12730 12731 if (restart && !app.isolated) { 12732 // We have components that still need to be running in the 12733 // process, so re-launch it. 12734 mProcessNames.put(app.processName, app.uid, app); 12735 startProcessLocked(app, "restart", app.processName); 12736 } else if (app.pid > 0 && app.pid != MY_PID) { 12737 // Goodbye! 12738 boolean removed; 12739 synchronized (mPidsSelfLocked) { 12740 mPidsSelfLocked.remove(app.pid); 12741 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12742 } 12743 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12744 app.processName, app.info.uid); 12745 if (app.isolated) { 12746 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12747 } 12748 app.setPid(0); 12749 } 12750 } 12751 12752 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12753 // Look through the content providers we are waiting to have launched, 12754 // and if any run in this process then either schedule a restart of 12755 // the process or kill the client waiting for it if this process has 12756 // gone bad. 12757 int NL = mLaunchingProviders.size(); 12758 boolean restart = false; 12759 for (int i=0; i<NL; i++) { 12760 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12761 if (cpr.launchingApp == app) { 12762 if (!alwaysBad && !app.bad) { 12763 restart = true; 12764 } else { 12765 removeDyingProviderLocked(app, cpr, true); 12766 // cpr should have been removed from mLaunchingProviders 12767 NL = mLaunchingProviders.size(); 12768 i--; 12769 } 12770 } 12771 } 12772 return restart; 12773 } 12774 12775 // ========================================================= 12776 // SERVICES 12777 // ========================================================= 12778 12779 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12780 int flags) { 12781 enforceNotIsolatedCaller("getServices"); 12782 synchronized (this) { 12783 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12784 } 12785 } 12786 12787 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12788 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12789 synchronized (this) { 12790 return mServices.getRunningServiceControlPanelLocked(name); 12791 } 12792 } 12793 12794 public ComponentName startService(IApplicationThread caller, Intent service, 12795 String resolvedType, int userId) { 12796 enforceNotIsolatedCaller("startService"); 12797 // Refuse possible leaked file descriptors 12798 if (service != null && service.hasFileDescriptors() == true) { 12799 throw new IllegalArgumentException("File descriptors passed in Intent"); 12800 } 12801 12802 if (DEBUG_SERVICE) 12803 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12804 synchronized(this) { 12805 final int callingPid = Binder.getCallingPid(); 12806 final int callingUid = Binder.getCallingUid(); 12807 final long origId = Binder.clearCallingIdentity(); 12808 ComponentName res = mServices.startServiceLocked(caller, service, 12809 resolvedType, callingPid, callingUid, userId); 12810 Binder.restoreCallingIdentity(origId); 12811 return res; 12812 } 12813 } 12814 12815 ComponentName startServiceInPackage(int uid, 12816 Intent service, String resolvedType, int userId) { 12817 synchronized(this) { 12818 if (DEBUG_SERVICE) 12819 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12820 final long origId = Binder.clearCallingIdentity(); 12821 ComponentName res = mServices.startServiceLocked(null, service, 12822 resolvedType, -1, uid, userId); 12823 Binder.restoreCallingIdentity(origId); 12824 return res; 12825 } 12826 } 12827 12828 public int stopService(IApplicationThread caller, Intent service, 12829 String resolvedType, int userId) { 12830 enforceNotIsolatedCaller("stopService"); 12831 // Refuse possible leaked file descriptors 12832 if (service != null && service.hasFileDescriptors() == true) { 12833 throw new IllegalArgumentException("File descriptors passed in Intent"); 12834 } 12835 12836 synchronized(this) { 12837 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12838 } 12839 } 12840 12841 public IBinder peekService(Intent service, String resolvedType) { 12842 enforceNotIsolatedCaller("peekService"); 12843 // Refuse possible leaked file descriptors 12844 if (service != null && service.hasFileDescriptors() == true) { 12845 throw new IllegalArgumentException("File descriptors passed in Intent"); 12846 } 12847 synchronized(this) { 12848 return mServices.peekServiceLocked(service, resolvedType); 12849 } 12850 } 12851 12852 public boolean stopServiceToken(ComponentName className, IBinder token, 12853 int startId) { 12854 synchronized(this) { 12855 return mServices.stopServiceTokenLocked(className, token, startId); 12856 } 12857 } 12858 12859 public void setServiceForeground(ComponentName className, IBinder token, 12860 int id, Notification notification, boolean removeNotification) { 12861 synchronized(this) { 12862 mServices.setServiceForegroundLocked(className, token, id, notification, 12863 removeNotification); 12864 } 12865 } 12866 12867 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12868 boolean requireFull, String name, String callerPackage) { 12869 final int callingUserId = UserHandle.getUserId(callingUid); 12870 if (callingUserId != userId) { 12871 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12872 if ((requireFull || checkComponentPermission( 12873 android.Manifest.permission.INTERACT_ACROSS_USERS, 12874 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12875 && checkComponentPermission( 12876 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12877 callingPid, callingUid, -1, true) 12878 != PackageManager.PERMISSION_GRANTED) { 12879 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12880 // In this case, they would like to just execute as their 12881 // owner user instead of failing. 12882 userId = callingUserId; 12883 } else { 12884 StringBuilder builder = new StringBuilder(128); 12885 builder.append("Permission Denial: "); 12886 builder.append(name); 12887 if (callerPackage != null) { 12888 builder.append(" from "); 12889 builder.append(callerPackage); 12890 } 12891 builder.append(" asks to run as user "); 12892 builder.append(userId); 12893 builder.append(" but is calling from user "); 12894 builder.append(UserHandle.getUserId(callingUid)); 12895 builder.append("; this requires "); 12896 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12897 if (!requireFull) { 12898 builder.append(" or "); 12899 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12900 } 12901 String msg = builder.toString(); 12902 Slog.w(TAG, msg); 12903 throw new SecurityException(msg); 12904 } 12905 } 12906 } 12907 if (userId == UserHandle.USER_CURRENT 12908 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12909 // Note that we may be accessing this outside of a lock... 12910 // shouldn't be a big deal, if this is being called outside 12911 // of a locked context there is intrinsically a race with 12912 // the value the caller will receive and someone else changing it. 12913 userId = mCurrentUserId; 12914 } 12915 if (!allowAll && userId < 0) { 12916 throw new IllegalArgumentException( 12917 "Call does not support special user #" + userId); 12918 } 12919 } 12920 return userId; 12921 } 12922 12923 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12924 String className, int flags) { 12925 boolean result = false; 12926 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12927 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12928 if (ActivityManager.checkUidPermission( 12929 android.Manifest.permission.INTERACT_ACROSS_USERS, 12930 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12931 ComponentName comp = new ComponentName(aInfo.packageName, className); 12932 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12933 + " requests FLAG_SINGLE_USER, but app does not hold " 12934 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12935 Slog.w(TAG, msg); 12936 throw new SecurityException(msg); 12937 } 12938 result = true; 12939 } 12940 } else if (componentProcessName == aInfo.packageName) { 12941 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12942 } else if ("system".equals(componentProcessName)) { 12943 result = true; 12944 } 12945 if (DEBUG_MU) { 12946 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12947 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12948 } 12949 return result; 12950 } 12951 12952 public int bindService(IApplicationThread caller, IBinder token, 12953 Intent service, String resolvedType, 12954 IServiceConnection connection, int flags, int userId) { 12955 enforceNotIsolatedCaller("bindService"); 12956 // Refuse possible leaked file descriptors 12957 if (service != null && service.hasFileDescriptors() == true) { 12958 throw new IllegalArgumentException("File descriptors passed in Intent"); 12959 } 12960 12961 synchronized(this) { 12962 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12963 connection, flags, userId); 12964 } 12965 } 12966 12967 public boolean unbindService(IServiceConnection connection) { 12968 synchronized (this) { 12969 return mServices.unbindServiceLocked(connection); 12970 } 12971 } 12972 12973 public void publishService(IBinder token, Intent intent, IBinder service) { 12974 // Refuse possible leaked file descriptors 12975 if (intent != null && intent.hasFileDescriptors() == true) { 12976 throw new IllegalArgumentException("File descriptors passed in Intent"); 12977 } 12978 12979 synchronized(this) { 12980 if (!(token instanceof ServiceRecord)) { 12981 throw new IllegalArgumentException("Invalid service token"); 12982 } 12983 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12984 } 12985 } 12986 12987 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12988 // Refuse possible leaked file descriptors 12989 if (intent != null && intent.hasFileDescriptors() == true) { 12990 throw new IllegalArgumentException("File descriptors passed in Intent"); 12991 } 12992 12993 synchronized(this) { 12994 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12995 } 12996 } 12997 12998 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12999 synchronized(this) { 13000 if (!(token instanceof ServiceRecord)) { 13001 throw new IllegalArgumentException("Invalid service token"); 13002 } 13003 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13004 } 13005 } 13006 13007 // ========================================================= 13008 // BACKUP AND RESTORE 13009 // ========================================================= 13010 13011 // Cause the target app to be launched if necessary and its backup agent 13012 // instantiated. The backup agent will invoke backupAgentCreated() on the 13013 // activity manager to announce its creation. 13014 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13015 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13016 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13017 13018 synchronized(this) { 13019 // !!! TODO: currently no check here that we're already bound 13020 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13021 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13022 synchronized (stats) { 13023 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13024 } 13025 13026 // Backup agent is now in use, its package can't be stopped. 13027 try { 13028 AppGlobals.getPackageManager().setPackageStoppedState( 13029 app.packageName, false, UserHandle.getUserId(app.uid)); 13030 } catch (RemoteException e) { 13031 } catch (IllegalArgumentException e) { 13032 Slog.w(TAG, "Failed trying to unstop package " 13033 + app.packageName + ": " + e); 13034 } 13035 13036 BackupRecord r = new BackupRecord(ss, app, backupMode); 13037 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13038 ? new ComponentName(app.packageName, app.backupAgentName) 13039 : new ComponentName("android", "FullBackupAgent"); 13040 // startProcessLocked() returns existing proc's record if it's already running 13041 ProcessRecord proc = startProcessLocked(app.processName, app, 13042 false, 0, "backup", hostingName, false, false, false); 13043 if (proc == null) { 13044 Slog.e(TAG, "Unable to start backup agent process " + r); 13045 return false; 13046 } 13047 13048 r.app = proc; 13049 mBackupTarget = r; 13050 mBackupAppName = app.packageName; 13051 13052 // Try not to kill the process during backup 13053 updateOomAdjLocked(proc); 13054 13055 // If the process is already attached, schedule the creation of the backup agent now. 13056 // If it is not yet live, this will be done when it attaches to the framework. 13057 if (proc.thread != null) { 13058 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13059 try { 13060 proc.thread.scheduleCreateBackupAgent(app, 13061 compatibilityInfoForPackageLocked(app), backupMode); 13062 } catch (RemoteException e) { 13063 // Will time out on the backup manager side 13064 } 13065 } else { 13066 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13067 } 13068 // Invariants: at this point, the target app process exists and the application 13069 // is either already running or in the process of coming up. mBackupTarget and 13070 // mBackupAppName describe the app, so that when it binds back to the AM we 13071 // know that it's scheduled for a backup-agent operation. 13072 } 13073 13074 return true; 13075 } 13076 13077 @Override 13078 public void clearPendingBackup() { 13079 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13080 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13081 13082 synchronized (this) { 13083 mBackupTarget = null; 13084 mBackupAppName = null; 13085 } 13086 } 13087 13088 // A backup agent has just come up 13089 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13090 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13091 + " = " + agent); 13092 13093 synchronized(this) { 13094 if (!agentPackageName.equals(mBackupAppName)) { 13095 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13096 return; 13097 } 13098 } 13099 13100 long oldIdent = Binder.clearCallingIdentity(); 13101 try { 13102 IBackupManager bm = IBackupManager.Stub.asInterface( 13103 ServiceManager.getService(Context.BACKUP_SERVICE)); 13104 bm.agentConnected(agentPackageName, agent); 13105 } catch (RemoteException e) { 13106 // can't happen; the backup manager service is local 13107 } catch (Exception e) { 13108 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13109 e.printStackTrace(); 13110 } finally { 13111 Binder.restoreCallingIdentity(oldIdent); 13112 } 13113 } 13114 13115 // done with this agent 13116 public void unbindBackupAgent(ApplicationInfo appInfo) { 13117 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13118 if (appInfo == null) { 13119 Slog.w(TAG, "unbind backup agent for null app"); 13120 return; 13121 } 13122 13123 synchronized(this) { 13124 try { 13125 if (mBackupAppName == null) { 13126 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13127 return; 13128 } 13129 13130 if (!mBackupAppName.equals(appInfo.packageName)) { 13131 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13132 return; 13133 } 13134 13135 // Not backing this app up any more; reset its OOM adjustment 13136 final ProcessRecord proc = mBackupTarget.app; 13137 updateOomAdjLocked(proc); 13138 13139 // If the app crashed during backup, 'thread' will be null here 13140 if (proc.thread != null) { 13141 try { 13142 proc.thread.scheduleDestroyBackupAgent(appInfo, 13143 compatibilityInfoForPackageLocked(appInfo)); 13144 } catch (Exception e) { 13145 Slog.e(TAG, "Exception when unbinding backup agent:"); 13146 e.printStackTrace(); 13147 } 13148 } 13149 } finally { 13150 mBackupTarget = null; 13151 mBackupAppName = null; 13152 } 13153 } 13154 } 13155 // ========================================================= 13156 // BROADCASTS 13157 // ========================================================= 13158 13159 private final List getStickiesLocked(String action, IntentFilter filter, 13160 List cur, int userId) { 13161 final ContentResolver resolver = mContext.getContentResolver(); 13162 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13163 if (stickies == null) { 13164 return cur; 13165 } 13166 final ArrayList<Intent> list = stickies.get(action); 13167 if (list == null) { 13168 return cur; 13169 } 13170 int N = list.size(); 13171 for (int i=0; i<N; i++) { 13172 Intent intent = list.get(i); 13173 if (filter.match(resolver, intent, true, TAG) >= 0) { 13174 if (cur == null) { 13175 cur = new ArrayList<Intent>(); 13176 } 13177 cur.add(intent); 13178 } 13179 } 13180 return cur; 13181 } 13182 13183 boolean isPendingBroadcastProcessLocked(int pid) { 13184 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13185 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13186 } 13187 13188 void skipPendingBroadcastLocked(int pid) { 13189 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13190 for (BroadcastQueue queue : mBroadcastQueues) { 13191 queue.skipPendingBroadcastLocked(pid); 13192 } 13193 } 13194 13195 // The app just attached; send any pending broadcasts that it should receive 13196 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13197 boolean didSomething = false; 13198 for (BroadcastQueue queue : mBroadcastQueues) { 13199 didSomething |= queue.sendPendingBroadcastsLocked(app); 13200 } 13201 return didSomething; 13202 } 13203 13204 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13205 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13206 enforceNotIsolatedCaller("registerReceiver"); 13207 int callingUid; 13208 int callingPid; 13209 synchronized(this) { 13210 ProcessRecord callerApp = null; 13211 if (caller != null) { 13212 callerApp = getRecordForAppLocked(caller); 13213 if (callerApp == null) { 13214 throw new SecurityException( 13215 "Unable to find app for caller " + caller 13216 + " (pid=" + Binder.getCallingPid() 13217 + ") when registering receiver " + receiver); 13218 } 13219 if (callerApp.info.uid != Process.SYSTEM_UID && 13220 !callerApp.pkgList.containsKey(callerPackage) && 13221 !"android".equals(callerPackage)) { 13222 throw new SecurityException("Given caller package " + callerPackage 13223 + " is not running in process " + callerApp); 13224 } 13225 callingUid = callerApp.info.uid; 13226 callingPid = callerApp.pid; 13227 } else { 13228 callerPackage = null; 13229 callingUid = Binder.getCallingUid(); 13230 callingPid = Binder.getCallingPid(); 13231 } 13232 13233 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13234 true, true, "registerReceiver", callerPackage); 13235 13236 List allSticky = null; 13237 13238 // Look for any matching sticky broadcasts... 13239 Iterator actions = filter.actionsIterator(); 13240 if (actions != null) { 13241 while (actions.hasNext()) { 13242 String action = (String)actions.next(); 13243 allSticky = getStickiesLocked(action, filter, allSticky, 13244 UserHandle.USER_ALL); 13245 allSticky = getStickiesLocked(action, filter, allSticky, 13246 UserHandle.getUserId(callingUid)); 13247 } 13248 } else { 13249 allSticky = getStickiesLocked(null, filter, allSticky, 13250 UserHandle.USER_ALL); 13251 allSticky = getStickiesLocked(null, filter, allSticky, 13252 UserHandle.getUserId(callingUid)); 13253 } 13254 13255 // The first sticky in the list is returned directly back to 13256 // the client. 13257 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13258 13259 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13260 + ": " + sticky); 13261 13262 if (receiver == null) { 13263 return sticky; 13264 } 13265 13266 ReceiverList rl 13267 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13268 if (rl == null) { 13269 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13270 userId, receiver); 13271 if (rl.app != null) { 13272 rl.app.receivers.add(rl); 13273 } else { 13274 try { 13275 receiver.asBinder().linkToDeath(rl, 0); 13276 } catch (RemoteException e) { 13277 return sticky; 13278 } 13279 rl.linkedToDeath = true; 13280 } 13281 mRegisteredReceivers.put(receiver.asBinder(), rl); 13282 } else if (rl.uid != callingUid) { 13283 throw new IllegalArgumentException( 13284 "Receiver requested to register for uid " + callingUid 13285 + " was previously registered for uid " + rl.uid); 13286 } else if (rl.pid != callingPid) { 13287 throw new IllegalArgumentException( 13288 "Receiver requested to register for pid " + callingPid 13289 + " was previously registered for pid " + rl.pid); 13290 } else if (rl.userId != userId) { 13291 throw new IllegalArgumentException( 13292 "Receiver requested to register for user " + userId 13293 + " was previously registered for user " + rl.userId); 13294 } 13295 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13296 permission, callingUid, userId); 13297 rl.add(bf); 13298 if (!bf.debugCheck()) { 13299 Slog.w(TAG, "==> For Dynamic broadast"); 13300 } 13301 mReceiverResolver.addFilter(bf); 13302 13303 // Enqueue broadcasts for all existing stickies that match 13304 // this filter. 13305 if (allSticky != null) { 13306 ArrayList receivers = new ArrayList(); 13307 receivers.add(bf); 13308 13309 int N = allSticky.size(); 13310 for (int i=0; i<N; i++) { 13311 Intent intent = (Intent)allSticky.get(i); 13312 BroadcastQueue queue = broadcastQueueForIntent(intent); 13313 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13314 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13315 null, null, false, true, true, -1); 13316 queue.enqueueParallelBroadcastLocked(r); 13317 queue.scheduleBroadcastsLocked(); 13318 } 13319 } 13320 13321 return sticky; 13322 } 13323 } 13324 13325 public void unregisterReceiver(IIntentReceiver receiver) { 13326 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13327 13328 final long origId = Binder.clearCallingIdentity(); 13329 try { 13330 boolean doTrim = false; 13331 13332 synchronized(this) { 13333 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13334 if (rl != null) { 13335 if (rl.curBroadcast != null) { 13336 BroadcastRecord r = rl.curBroadcast; 13337 final boolean doNext = finishReceiverLocked( 13338 receiver.asBinder(), r.resultCode, r.resultData, 13339 r.resultExtras, r.resultAbort); 13340 if (doNext) { 13341 doTrim = true; 13342 r.queue.processNextBroadcast(false); 13343 } 13344 } 13345 13346 if (rl.app != null) { 13347 rl.app.receivers.remove(rl); 13348 } 13349 removeReceiverLocked(rl); 13350 if (rl.linkedToDeath) { 13351 rl.linkedToDeath = false; 13352 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13353 } 13354 } 13355 } 13356 13357 // If we actually concluded any broadcasts, we might now be able 13358 // to trim the recipients' apps from our working set 13359 if (doTrim) { 13360 trimApplications(); 13361 return; 13362 } 13363 13364 } finally { 13365 Binder.restoreCallingIdentity(origId); 13366 } 13367 } 13368 13369 void removeReceiverLocked(ReceiverList rl) { 13370 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13371 int N = rl.size(); 13372 for (int i=0; i<N; i++) { 13373 mReceiverResolver.removeFilter(rl.get(i)); 13374 } 13375 } 13376 13377 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13378 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13379 ProcessRecord r = mLruProcesses.get(i); 13380 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13381 try { 13382 r.thread.dispatchPackageBroadcast(cmd, packages); 13383 } catch (RemoteException ex) { 13384 } 13385 } 13386 } 13387 } 13388 13389 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13390 int[] users) { 13391 List<ResolveInfo> receivers = null; 13392 try { 13393 HashSet<ComponentName> singleUserReceivers = null; 13394 boolean scannedFirstReceivers = false; 13395 for (int user : users) { 13396 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13397 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13398 if (user != 0 && newReceivers != null) { 13399 // If this is not the primary user, we need to check for 13400 // any receivers that should be filtered out. 13401 for (int i=0; i<newReceivers.size(); i++) { 13402 ResolveInfo ri = newReceivers.get(i); 13403 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13404 newReceivers.remove(i); 13405 i--; 13406 } 13407 } 13408 } 13409 if (newReceivers != null && newReceivers.size() == 0) { 13410 newReceivers = null; 13411 } 13412 if (receivers == null) { 13413 receivers = newReceivers; 13414 } else if (newReceivers != null) { 13415 // We need to concatenate the additional receivers 13416 // found with what we have do far. This would be easy, 13417 // but we also need to de-dup any receivers that are 13418 // singleUser. 13419 if (!scannedFirstReceivers) { 13420 // Collect any single user receivers we had already retrieved. 13421 scannedFirstReceivers = true; 13422 for (int i=0; i<receivers.size(); i++) { 13423 ResolveInfo ri = receivers.get(i); 13424 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13425 ComponentName cn = new ComponentName( 13426 ri.activityInfo.packageName, ri.activityInfo.name); 13427 if (singleUserReceivers == null) { 13428 singleUserReceivers = new HashSet<ComponentName>(); 13429 } 13430 singleUserReceivers.add(cn); 13431 } 13432 } 13433 } 13434 // Add the new results to the existing results, tracking 13435 // and de-dupping single user receivers. 13436 for (int i=0; i<newReceivers.size(); i++) { 13437 ResolveInfo ri = newReceivers.get(i); 13438 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13439 ComponentName cn = new ComponentName( 13440 ri.activityInfo.packageName, ri.activityInfo.name); 13441 if (singleUserReceivers == null) { 13442 singleUserReceivers = new HashSet<ComponentName>(); 13443 } 13444 if (!singleUserReceivers.contains(cn)) { 13445 singleUserReceivers.add(cn); 13446 receivers.add(ri); 13447 } 13448 } else { 13449 receivers.add(ri); 13450 } 13451 } 13452 } 13453 } 13454 } catch (RemoteException ex) { 13455 // pm is in same process, this will never happen. 13456 } 13457 return receivers; 13458 } 13459 13460 private final int broadcastIntentLocked(ProcessRecord callerApp, 13461 String callerPackage, Intent intent, String resolvedType, 13462 IIntentReceiver resultTo, int resultCode, String resultData, 13463 Bundle map, String requiredPermission, int appOp, 13464 boolean ordered, boolean sticky, int callingPid, int callingUid, 13465 int userId) { 13466 intent = new Intent(intent); 13467 13468 // By default broadcasts do not go to stopped apps. 13469 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13470 13471 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13472 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13473 + " ordered=" + ordered + " userid=" + userId); 13474 if ((resultTo != null) && !ordered) { 13475 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13476 } 13477 13478 userId = handleIncomingUser(callingPid, callingUid, userId, 13479 true, false, "broadcast", callerPackage); 13480 13481 // Make sure that the user who is receiving this broadcast is started. 13482 // If not, we will just skip it. 13483 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13484 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13485 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13486 Slog.w(TAG, "Skipping broadcast of " + intent 13487 + ": user " + userId + " is stopped"); 13488 return ActivityManager.BROADCAST_SUCCESS; 13489 } 13490 } 13491 13492 /* 13493 * Prevent non-system code (defined here to be non-persistent 13494 * processes) from sending protected broadcasts. 13495 */ 13496 int callingAppId = UserHandle.getAppId(callingUid); 13497 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13498 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13499 callingUid == 0) { 13500 // Always okay. 13501 } else if (callerApp == null || !callerApp.persistent) { 13502 try { 13503 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13504 intent.getAction())) { 13505 String msg = "Permission Denial: not allowed to send broadcast " 13506 + intent.getAction() + " from pid=" 13507 + callingPid + ", uid=" + callingUid; 13508 Slog.w(TAG, msg); 13509 throw new SecurityException(msg); 13510 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13511 // Special case for compatibility: we don't want apps to send this, 13512 // but historically it has not been protected and apps may be using it 13513 // to poke their own app widget. So, instead of making it protected, 13514 // just limit it to the caller. 13515 if (callerApp == null) { 13516 String msg = "Permission Denial: not allowed to send broadcast " 13517 + intent.getAction() + " from unknown caller."; 13518 Slog.w(TAG, msg); 13519 throw new SecurityException(msg); 13520 } else if (intent.getComponent() != null) { 13521 // They are good enough to send to an explicit component... verify 13522 // it is being sent to the calling app. 13523 if (!intent.getComponent().getPackageName().equals( 13524 callerApp.info.packageName)) { 13525 String msg = "Permission Denial: not allowed to send broadcast " 13526 + intent.getAction() + " to " 13527 + intent.getComponent().getPackageName() + " from " 13528 + callerApp.info.packageName; 13529 Slog.w(TAG, msg); 13530 throw new SecurityException(msg); 13531 } 13532 } else { 13533 // Limit broadcast to their own package. 13534 intent.setPackage(callerApp.info.packageName); 13535 } 13536 } 13537 } catch (RemoteException e) { 13538 Slog.w(TAG, "Remote exception", e); 13539 return ActivityManager.BROADCAST_SUCCESS; 13540 } 13541 } 13542 13543 // Handle special intents: if this broadcast is from the package 13544 // manager about a package being removed, we need to remove all of 13545 // its activities from the history stack. 13546 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13547 intent.getAction()); 13548 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13549 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13550 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13551 || uidRemoved) { 13552 if (checkComponentPermission( 13553 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13554 callingPid, callingUid, -1, true) 13555 == PackageManager.PERMISSION_GRANTED) { 13556 if (uidRemoved) { 13557 final Bundle intentExtras = intent.getExtras(); 13558 final int uid = intentExtras != null 13559 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13560 if (uid >= 0) { 13561 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13562 synchronized (bs) { 13563 bs.removeUidStatsLocked(uid); 13564 } 13565 mAppOpsService.uidRemoved(uid); 13566 } 13567 } else { 13568 // If resources are unavailable just force stop all 13569 // those packages and flush the attribute cache as well. 13570 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13571 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13572 if (list != null && (list.length > 0)) { 13573 for (String pkg : list) { 13574 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13575 "storage unmount"); 13576 } 13577 sendPackageBroadcastLocked( 13578 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13579 } 13580 } else { 13581 Uri data = intent.getData(); 13582 String ssp; 13583 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13584 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13585 intent.getAction()); 13586 boolean fullUninstall = removed && 13587 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13588 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13589 forceStopPackageLocked(ssp, UserHandle.getAppId( 13590 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13591 false, fullUninstall, userId, 13592 removed ? "pkg removed" : "pkg changed"); 13593 } 13594 if (removed) { 13595 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13596 new String[] {ssp}, userId); 13597 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13598 mAppOpsService.packageRemoved( 13599 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13600 13601 // Remove all permissions granted from/to this package 13602 removeUriPermissionsForPackageLocked(ssp, userId, true); 13603 } 13604 } 13605 } 13606 } 13607 } 13608 } else { 13609 String msg = "Permission Denial: " + intent.getAction() 13610 + " broadcast from " + callerPackage + " (pid=" + callingPid 13611 + ", uid=" + callingUid + ")" 13612 + " requires " 13613 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13614 Slog.w(TAG, msg); 13615 throw new SecurityException(msg); 13616 } 13617 13618 // Special case for adding a package: by default turn on compatibility 13619 // mode. 13620 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13621 Uri data = intent.getData(); 13622 String ssp; 13623 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13624 mCompatModePackages.handlePackageAddedLocked(ssp, 13625 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13626 } 13627 } 13628 13629 /* 13630 * If this is the time zone changed action, queue up a message that will reset the timezone 13631 * of all currently running processes. This message will get queued up before the broadcast 13632 * happens. 13633 */ 13634 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13635 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13636 } 13637 13638 /* 13639 * If the user set the time, let all running processes know. 13640 */ 13641 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13642 final int is24Hour = intent.getBooleanExtra( 13643 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13644 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13645 } 13646 13647 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13648 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13649 } 13650 13651 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13652 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13653 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13654 } 13655 13656 // Add to the sticky list if requested. 13657 if (sticky) { 13658 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13659 callingPid, callingUid) 13660 != PackageManager.PERMISSION_GRANTED) { 13661 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13662 + callingPid + ", uid=" + callingUid 13663 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13664 Slog.w(TAG, msg); 13665 throw new SecurityException(msg); 13666 } 13667 if (requiredPermission != null) { 13668 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13669 + " and enforce permission " + requiredPermission); 13670 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13671 } 13672 if (intent.getComponent() != null) { 13673 throw new SecurityException( 13674 "Sticky broadcasts can't target a specific component"); 13675 } 13676 // We use userId directly here, since the "all" target is maintained 13677 // as a separate set of sticky broadcasts. 13678 if (userId != UserHandle.USER_ALL) { 13679 // But first, if this is not a broadcast to all users, then 13680 // make sure it doesn't conflict with an existing broadcast to 13681 // all users. 13682 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13683 UserHandle.USER_ALL); 13684 if (stickies != null) { 13685 ArrayList<Intent> list = stickies.get(intent.getAction()); 13686 if (list != null) { 13687 int N = list.size(); 13688 int i; 13689 for (i=0; i<N; i++) { 13690 if (intent.filterEquals(list.get(i))) { 13691 throw new IllegalArgumentException( 13692 "Sticky broadcast " + intent + " for user " 13693 + userId + " conflicts with existing global broadcast"); 13694 } 13695 } 13696 } 13697 } 13698 } 13699 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13700 if (stickies == null) { 13701 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13702 mStickyBroadcasts.put(userId, stickies); 13703 } 13704 ArrayList<Intent> list = stickies.get(intent.getAction()); 13705 if (list == null) { 13706 list = new ArrayList<Intent>(); 13707 stickies.put(intent.getAction(), list); 13708 } 13709 int N = list.size(); 13710 int i; 13711 for (i=0; i<N; i++) { 13712 if (intent.filterEquals(list.get(i))) { 13713 // This sticky already exists, replace it. 13714 list.set(i, new Intent(intent)); 13715 break; 13716 } 13717 } 13718 if (i >= N) { 13719 list.add(new Intent(intent)); 13720 } 13721 } 13722 13723 int[] users; 13724 if (userId == UserHandle.USER_ALL) { 13725 // Caller wants broadcast to go to all started users. 13726 users = mStartedUserArray; 13727 } else { 13728 // Caller wants broadcast to go to one specific user. 13729 users = new int[] {userId}; 13730 } 13731 13732 // Figure out who all will receive this broadcast. 13733 List receivers = null; 13734 List<BroadcastFilter> registeredReceivers = null; 13735 // Need to resolve the intent to interested receivers... 13736 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13737 == 0) { 13738 receivers = collectReceiverComponents(intent, resolvedType, users); 13739 } 13740 if (intent.getComponent() == null) { 13741 registeredReceivers = mReceiverResolver.queryIntent(intent, 13742 resolvedType, false, userId); 13743 } 13744 13745 final boolean replacePending = 13746 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13747 13748 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13749 + " replacePending=" + replacePending); 13750 13751 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13752 if (!ordered && NR > 0) { 13753 // If we are not serializing this broadcast, then send the 13754 // registered receivers separately so they don't wait for the 13755 // components to be launched. 13756 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13757 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13758 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13759 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13760 ordered, sticky, false, userId); 13761 if (DEBUG_BROADCAST) Slog.v( 13762 TAG, "Enqueueing parallel broadcast " + r); 13763 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13764 if (!replaced) { 13765 queue.enqueueParallelBroadcastLocked(r); 13766 queue.scheduleBroadcastsLocked(); 13767 } 13768 registeredReceivers = null; 13769 NR = 0; 13770 } 13771 13772 // Merge into one list. 13773 int ir = 0; 13774 if (receivers != null) { 13775 // A special case for PACKAGE_ADDED: do not allow the package 13776 // being added to see this broadcast. This prevents them from 13777 // using this as a back door to get run as soon as they are 13778 // installed. Maybe in the future we want to have a special install 13779 // broadcast or such for apps, but we'd like to deliberately make 13780 // this decision. 13781 String skipPackages[] = null; 13782 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13783 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13784 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13785 Uri data = intent.getData(); 13786 if (data != null) { 13787 String pkgName = data.getSchemeSpecificPart(); 13788 if (pkgName != null) { 13789 skipPackages = new String[] { pkgName }; 13790 } 13791 } 13792 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13793 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13794 } 13795 if (skipPackages != null && (skipPackages.length > 0)) { 13796 for (String skipPackage : skipPackages) { 13797 if (skipPackage != null) { 13798 int NT = receivers.size(); 13799 for (int it=0; it<NT; it++) { 13800 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13801 if (curt.activityInfo.packageName.equals(skipPackage)) { 13802 receivers.remove(it); 13803 it--; 13804 NT--; 13805 } 13806 } 13807 } 13808 } 13809 } 13810 13811 int NT = receivers != null ? receivers.size() : 0; 13812 int it = 0; 13813 ResolveInfo curt = null; 13814 BroadcastFilter curr = null; 13815 while (it < NT && ir < NR) { 13816 if (curt == null) { 13817 curt = (ResolveInfo)receivers.get(it); 13818 } 13819 if (curr == null) { 13820 curr = registeredReceivers.get(ir); 13821 } 13822 if (curr.getPriority() >= curt.priority) { 13823 // Insert this broadcast record into the final list. 13824 receivers.add(it, curr); 13825 ir++; 13826 curr = null; 13827 it++; 13828 NT++; 13829 } else { 13830 // Skip to the next ResolveInfo in the final list. 13831 it++; 13832 curt = null; 13833 } 13834 } 13835 } 13836 while (ir < NR) { 13837 if (receivers == null) { 13838 receivers = new ArrayList(); 13839 } 13840 receivers.add(registeredReceivers.get(ir)); 13841 ir++; 13842 } 13843 13844 if ((receivers != null && receivers.size() > 0) 13845 || resultTo != null) { 13846 BroadcastQueue queue = broadcastQueueForIntent(intent); 13847 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13848 callerPackage, callingPid, callingUid, resolvedType, 13849 requiredPermission, appOp, receivers, resultTo, resultCode, 13850 resultData, map, ordered, sticky, false, userId); 13851 if (DEBUG_BROADCAST) Slog.v( 13852 TAG, "Enqueueing ordered broadcast " + r 13853 + ": prev had " + queue.mOrderedBroadcasts.size()); 13854 if (DEBUG_BROADCAST) { 13855 int seq = r.intent.getIntExtra("seq", -1); 13856 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13857 } 13858 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13859 if (!replaced) { 13860 queue.enqueueOrderedBroadcastLocked(r); 13861 queue.scheduleBroadcastsLocked(); 13862 } 13863 } 13864 13865 return ActivityManager.BROADCAST_SUCCESS; 13866 } 13867 13868 final Intent verifyBroadcastLocked(Intent intent) { 13869 // Refuse possible leaked file descriptors 13870 if (intent != null && intent.hasFileDescriptors() == true) { 13871 throw new IllegalArgumentException("File descriptors passed in Intent"); 13872 } 13873 13874 int flags = intent.getFlags(); 13875 13876 if (!mProcessesReady) { 13877 // if the caller really truly claims to know what they're doing, go 13878 // ahead and allow the broadcast without launching any receivers 13879 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13880 intent = new Intent(intent); 13881 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13882 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13883 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13884 + " before boot completion"); 13885 throw new IllegalStateException("Cannot broadcast before boot completed"); 13886 } 13887 } 13888 13889 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13890 throw new IllegalArgumentException( 13891 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13892 } 13893 13894 return intent; 13895 } 13896 13897 public final int broadcastIntent(IApplicationThread caller, 13898 Intent intent, String resolvedType, IIntentReceiver resultTo, 13899 int resultCode, String resultData, Bundle map, 13900 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13901 enforceNotIsolatedCaller("broadcastIntent"); 13902 synchronized(this) { 13903 intent = verifyBroadcastLocked(intent); 13904 13905 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13906 final int callingPid = Binder.getCallingPid(); 13907 final int callingUid = Binder.getCallingUid(); 13908 final long origId = Binder.clearCallingIdentity(); 13909 int res = broadcastIntentLocked(callerApp, 13910 callerApp != null ? callerApp.info.packageName : null, 13911 intent, resolvedType, resultTo, 13912 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13913 callingPid, callingUid, userId); 13914 Binder.restoreCallingIdentity(origId); 13915 return res; 13916 } 13917 } 13918 13919 int broadcastIntentInPackage(String packageName, int uid, 13920 Intent intent, String resolvedType, IIntentReceiver resultTo, 13921 int resultCode, String resultData, Bundle map, 13922 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13923 synchronized(this) { 13924 intent = verifyBroadcastLocked(intent); 13925 13926 final long origId = Binder.clearCallingIdentity(); 13927 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13928 resultTo, resultCode, resultData, map, requiredPermission, 13929 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13930 Binder.restoreCallingIdentity(origId); 13931 return res; 13932 } 13933 } 13934 13935 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13936 // Refuse possible leaked file descriptors 13937 if (intent != null && intent.hasFileDescriptors() == true) { 13938 throw new IllegalArgumentException("File descriptors passed in Intent"); 13939 } 13940 13941 userId = handleIncomingUser(Binder.getCallingPid(), 13942 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13943 13944 synchronized(this) { 13945 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13946 != PackageManager.PERMISSION_GRANTED) { 13947 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13948 + Binder.getCallingPid() 13949 + ", uid=" + Binder.getCallingUid() 13950 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13951 Slog.w(TAG, msg); 13952 throw new SecurityException(msg); 13953 } 13954 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13955 if (stickies != null) { 13956 ArrayList<Intent> list = stickies.get(intent.getAction()); 13957 if (list != null) { 13958 int N = list.size(); 13959 int i; 13960 for (i=0; i<N; i++) { 13961 if (intent.filterEquals(list.get(i))) { 13962 list.remove(i); 13963 break; 13964 } 13965 } 13966 if (list.size() <= 0) { 13967 stickies.remove(intent.getAction()); 13968 } 13969 } 13970 if (stickies.size() <= 0) { 13971 mStickyBroadcasts.remove(userId); 13972 } 13973 } 13974 } 13975 } 13976 13977 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13978 String resultData, Bundle resultExtras, boolean resultAbort) { 13979 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13980 if (r == null) { 13981 Slog.w(TAG, "finishReceiver called but not found on queue"); 13982 return false; 13983 } 13984 13985 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13986 } 13987 13988 void backgroundServicesFinishedLocked(int userId) { 13989 for (BroadcastQueue queue : mBroadcastQueues) { 13990 queue.backgroundServicesFinishedLocked(userId); 13991 } 13992 } 13993 13994 public void finishReceiver(IBinder who, int resultCode, String resultData, 13995 Bundle resultExtras, boolean resultAbort) { 13996 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13997 13998 // Refuse possible leaked file descriptors 13999 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14000 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14001 } 14002 14003 final long origId = Binder.clearCallingIdentity(); 14004 try { 14005 boolean doNext = false; 14006 BroadcastRecord r; 14007 14008 synchronized(this) { 14009 r = broadcastRecordForReceiverLocked(who); 14010 if (r != null) { 14011 doNext = r.queue.finishReceiverLocked(r, resultCode, 14012 resultData, resultExtras, resultAbort, true); 14013 } 14014 } 14015 14016 if (doNext) { 14017 r.queue.processNextBroadcast(false); 14018 } 14019 trimApplications(); 14020 } finally { 14021 Binder.restoreCallingIdentity(origId); 14022 } 14023 } 14024 14025 // ========================================================= 14026 // INSTRUMENTATION 14027 // ========================================================= 14028 14029 public boolean startInstrumentation(ComponentName className, 14030 String profileFile, int flags, Bundle arguments, 14031 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14032 int userId) { 14033 enforceNotIsolatedCaller("startInstrumentation"); 14034 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14035 userId, false, true, "startInstrumentation", null); 14036 // Refuse possible leaked file descriptors 14037 if (arguments != null && arguments.hasFileDescriptors()) { 14038 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14039 } 14040 14041 synchronized(this) { 14042 InstrumentationInfo ii = null; 14043 ApplicationInfo ai = null; 14044 try { 14045 ii = mContext.getPackageManager().getInstrumentationInfo( 14046 className, STOCK_PM_FLAGS); 14047 ai = AppGlobals.getPackageManager().getApplicationInfo( 14048 ii.targetPackage, STOCK_PM_FLAGS, userId); 14049 } catch (PackageManager.NameNotFoundException e) { 14050 } catch (RemoteException e) { 14051 } 14052 if (ii == null) { 14053 reportStartInstrumentationFailure(watcher, className, 14054 "Unable to find instrumentation info for: " + className); 14055 return false; 14056 } 14057 if (ai == null) { 14058 reportStartInstrumentationFailure(watcher, className, 14059 "Unable to find instrumentation target package: " + ii.targetPackage); 14060 return false; 14061 } 14062 14063 int match = mContext.getPackageManager().checkSignatures( 14064 ii.targetPackage, ii.packageName); 14065 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14066 String msg = "Permission Denial: starting instrumentation " 14067 + className + " from pid=" 14068 + Binder.getCallingPid() 14069 + ", uid=" + Binder.getCallingPid() 14070 + " not allowed because package " + ii.packageName 14071 + " does not have a signature matching the target " 14072 + ii.targetPackage; 14073 reportStartInstrumentationFailure(watcher, className, msg); 14074 throw new SecurityException(msg); 14075 } 14076 14077 final long origId = Binder.clearCallingIdentity(); 14078 // Instrumentation can kill and relaunch even persistent processes 14079 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14080 "start instr"); 14081 ProcessRecord app = addAppLocked(ai, false); 14082 app.instrumentationClass = className; 14083 app.instrumentationInfo = ai; 14084 app.instrumentationProfileFile = profileFile; 14085 app.instrumentationArguments = arguments; 14086 app.instrumentationWatcher = watcher; 14087 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14088 app.instrumentationResultClass = className; 14089 Binder.restoreCallingIdentity(origId); 14090 } 14091 14092 return true; 14093 } 14094 14095 /** 14096 * Report errors that occur while attempting to start Instrumentation. Always writes the 14097 * error to the logs, but if somebody is watching, send the report there too. This enables 14098 * the "am" command to report errors with more information. 14099 * 14100 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14101 * @param cn The component name of the instrumentation. 14102 * @param report The error report. 14103 */ 14104 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14105 ComponentName cn, String report) { 14106 Slog.w(TAG, report); 14107 try { 14108 if (watcher != null) { 14109 Bundle results = new Bundle(); 14110 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14111 results.putString("Error", report); 14112 watcher.instrumentationStatus(cn, -1, results); 14113 } 14114 } catch (RemoteException e) { 14115 Slog.w(TAG, e); 14116 } 14117 } 14118 14119 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14120 if (app.instrumentationWatcher != null) { 14121 try { 14122 // NOTE: IInstrumentationWatcher *must* be oneway here 14123 app.instrumentationWatcher.instrumentationFinished( 14124 app.instrumentationClass, 14125 resultCode, 14126 results); 14127 } catch (RemoteException e) { 14128 } 14129 } 14130 if (app.instrumentationUiAutomationConnection != null) { 14131 try { 14132 app.instrumentationUiAutomationConnection.shutdown(); 14133 } catch (RemoteException re) { 14134 /* ignore */ 14135 } 14136 // Only a UiAutomation can set this flag and now that 14137 // it is finished we make sure it is reset to its default. 14138 mUserIsMonkey = false; 14139 } 14140 app.instrumentationWatcher = null; 14141 app.instrumentationUiAutomationConnection = null; 14142 app.instrumentationClass = null; 14143 app.instrumentationInfo = null; 14144 app.instrumentationProfileFile = null; 14145 app.instrumentationArguments = null; 14146 14147 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14148 "finished inst"); 14149 } 14150 14151 public void finishInstrumentation(IApplicationThread target, 14152 int resultCode, Bundle results) { 14153 int userId = UserHandle.getCallingUserId(); 14154 // Refuse possible leaked file descriptors 14155 if (results != null && results.hasFileDescriptors()) { 14156 throw new IllegalArgumentException("File descriptors passed in Intent"); 14157 } 14158 14159 synchronized(this) { 14160 ProcessRecord app = getRecordForAppLocked(target); 14161 if (app == null) { 14162 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14163 return; 14164 } 14165 final long origId = Binder.clearCallingIdentity(); 14166 finishInstrumentationLocked(app, resultCode, results); 14167 Binder.restoreCallingIdentity(origId); 14168 } 14169 } 14170 14171 // ========================================================= 14172 // CONFIGURATION 14173 // ========================================================= 14174 14175 public ConfigurationInfo getDeviceConfigurationInfo() { 14176 ConfigurationInfo config = new ConfigurationInfo(); 14177 synchronized (this) { 14178 config.reqTouchScreen = mConfiguration.touchscreen; 14179 config.reqKeyboardType = mConfiguration.keyboard; 14180 config.reqNavigation = mConfiguration.navigation; 14181 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14182 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14183 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14184 } 14185 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14186 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14187 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14188 } 14189 config.reqGlEsVersion = GL_ES_VERSION; 14190 } 14191 return config; 14192 } 14193 14194 ActivityStack getFocusedStack() { 14195 return mStackSupervisor.getFocusedStack(); 14196 } 14197 14198 public Configuration getConfiguration() { 14199 Configuration ci; 14200 synchronized(this) { 14201 ci = new Configuration(mConfiguration); 14202 } 14203 return ci; 14204 } 14205 14206 public void updatePersistentConfiguration(Configuration values) { 14207 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14208 "updateConfiguration()"); 14209 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14210 "updateConfiguration()"); 14211 if (values == null) { 14212 throw new NullPointerException("Configuration must not be null"); 14213 } 14214 14215 synchronized(this) { 14216 final long origId = Binder.clearCallingIdentity(); 14217 updateConfigurationLocked(values, null, true, false); 14218 Binder.restoreCallingIdentity(origId); 14219 } 14220 } 14221 14222 public void updateConfiguration(Configuration values) { 14223 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14224 "updateConfiguration()"); 14225 14226 synchronized(this) { 14227 if (values == null && mWindowManager != null) { 14228 // sentinel: fetch the current configuration from the window manager 14229 values = mWindowManager.computeNewConfiguration(); 14230 } 14231 14232 if (mWindowManager != null) { 14233 mProcessList.applyDisplaySize(mWindowManager); 14234 } 14235 14236 final long origId = Binder.clearCallingIdentity(); 14237 if (values != null) { 14238 Settings.System.clearConfiguration(values); 14239 } 14240 updateConfigurationLocked(values, null, false, false); 14241 Binder.restoreCallingIdentity(origId); 14242 } 14243 } 14244 14245 /** 14246 * Do either or both things: (1) change the current configuration, and (2) 14247 * make sure the given activity is running with the (now) current 14248 * configuration. Returns true if the activity has been left running, or 14249 * false if <var>starting</var> is being destroyed to match the new 14250 * configuration. 14251 * @param persistent TODO 14252 */ 14253 boolean updateConfigurationLocked(Configuration values, 14254 ActivityRecord starting, boolean persistent, boolean initLocale) { 14255 int changes = 0; 14256 14257 if (values != null) { 14258 Configuration newConfig = new Configuration(mConfiguration); 14259 changes = newConfig.updateFrom(values); 14260 if (changes != 0) { 14261 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14262 Slog.i(TAG, "Updating configuration to: " + values); 14263 } 14264 14265 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14266 14267 if (values.locale != null && !initLocale) { 14268 saveLocaleLocked(values.locale, 14269 !values.locale.equals(mConfiguration.locale), 14270 values.userSetLocale); 14271 } 14272 14273 mConfigurationSeq++; 14274 if (mConfigurationSeq <= 0) { 14275 mConfigurationSeq = 1; 14276 } 14277 newConfig.seq = mConfigurationSeq; 14278 mConfiguration = newConfig; 14279 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14280 14281 final Configuration configCopy = new Configuration(mConfiguration); 14282 14283 // TODO: If our config changes, should we auto dismiss any currently 14284 // showing dialogs? 14285 mShowDialogs = shouldShowDialogs(newConfig); 14286 14287 AttributeCache ac = AttributeCache.instance(); 14288 if (ac != null) { 14289 ac.updateConfiguration(configCopy); 14290 } 14291 14292 // Make sure all resources in our process are updated 14293 // right now, so that anyone who is going to retrieve 14294 // resource values after we return will be sure to get 14295 // the new ones. This is especially important during 14296 // boot, where the first config change needs to guarantee 14297 // all resources have that config before following boot 14298 // code is executed. 14299 mSystemThread.applyConfigurationToResources(configCopy); 14300 14301 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14302 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14303 msg.obj = new Configuration(configCopy); 14304 mHandler.sendMessage(msg); 14305 } 14306 14307 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14308 ProcessRecord app = mLruProcesses.get(i); 14309 try { 14310 if (app.thread != null) { 14311 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14312 + app.processName + " new config " + mConfiguration); 14313 app.thread.scheduleConfigurationChanged(configCopy); 14314 } 14315 } catch (Exception e) { 14316 } 14317 } 14318 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14319 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14320 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14321 | Intent.FLAG_RECEIVER_FOREGROUND); 14322 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14323 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14324 Process.SYSTEM_UID, UserHandle.USER_ALL); 14325 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14326 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14327 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14328 broadcastIntentLocked(null, null, intent, 14329 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14330 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14331 } 14332 } 14333 } 14334 14335 boolean kept = true; 14336 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14337 // mainStack is null during startup. 14338 if (mainStack != null) { 14339 if (changes != 0 && starting == null) { 14340 // If the configuration changed, and the caller is not already 14341 // in the process of starting an activity, then find the top 14342 // activity to check if its configuration needs to change. 14343 starting = mainStack.topRunningActivityLocked(null); 14344 } 14345 14346 if (starting != null) { 14347 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14348 // And we need to make sure at this point that all other activities 14349 // are made visible with the correct configuration. 14350 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14351 } 14352 } 14353 14354 if (values != null && mWindowManager != null) { 14355 mWindowManager.setNewConfiguration(mConfiguration); 14356 } 14357 14358 return kept; 14359 } 14360 14361 /** 14362 * Decide based on the configuration whether we should shouw the ANR, 14363 * crash, etc dialogs. The idea is that if there is no affordnace to 14364 * press the on-screen buttons, we shouldn't show the dialog. 14365 * 14366 * A thought: SystemUI might also want to get told about this, the Power 14367 * dialog / global actions also might want different behaviors. 14368 */ 14369 private static final boolean shouldShowDialogs(Configuration config) { 14370 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14371 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14372 } 14373 14374 /** 14375 * Save the locale. You must be inside a synchronized (this) block. 14376 */ 14377 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14378 if(isDiff) { 14379 SystemProperties.set("user.language", l.getLanguage()); 14380 SystemProperties.set("user.region", l.getCountry()); 14381 } 14382 14383 if(isPersist) { 14384 SystemProperties.set("persist.sys.language", l.getLanguage()); 14385 SystemProperties.set("persist.sys.country", l.getCountry()); 14386 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14387 } 14388 } 14389 14390 @Override 14391 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14392 ActivityRecord srec = ActivityRecord.forToken(token); 14393 return srec != null && srec.task.affinity != null && 14394 srec.task.affinity.equals(destAffinity); 14395 } 14396 14397 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14398 Intent resultData) { 14399 14400 synchronized (this) { 14401 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14402 if (stack != null) { 14403 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14404 } 14405 return false; 14406 } 14407 } 14408 14409 public int getLaunchedFromUid(IBinder activityToken) { 14410 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14411 if (srec == null) { 14412 return -1; 14413 } 14414 return srec.launchedFromUid; 14415 } 14416 14417 public String getLaunchedFromPackage(IBinder activityToken) { 14418 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14419 if (srec == null) { 14420 return null; 14421 } 14422 return srec.launchedFromPackage; 14423 } 14424 14425 // ========================================================= 14426 // LIFETIME MANAGEMENT 14427 // ========================================================= 14428 14429 // Returns which broadcast queue the app is the current [or imminent] receiver 14430 // on, or 'null' if the app is not an active broadcast recipient. 14431 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14432 BroadcastRecord r = app.curReceiver; 14433 if (r != null) { 14434 return r.queue; 14435 } 14436 14437 // It's not the current receiver, but it might be starting up to become one 14438 synchronized (this) { 14439 for (BroadcastQueue queue : mBroadcastQueues) { 14440 r = queue.mPendingBroadcast; 14441 if (r != null && r.curApp == app) { 14442 // found it; report which queue it's in 14443 return queue; 14444 } 14445 } 14446 } 14447 14448 return null; 14449 } 14450 14451 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14452 boolean doingAll, long now) { 14453 if (mAdjSeq == app.adjSeq) { 14454 // This adjustment has already been computed. 14455 return app.curRawAdj; 14456 } 14457 14458 if (app.thread == null) { 14459 app.adjSeq = mAdjSeq; 14460 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14461 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14462 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14463 } 14464 14465 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14466 app.adjSource = null; 14467 app.adjTarget = null; 14468 app.empty = false; 14469 app.cached = false; 14470 14471 final int activitiesSize = app.activities.size(); 14472 14473 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14474 // The max adjustment doesn't allow this app to be anything 14475 // below foreground, so it is not worth doing work for it. 14476 app.adjType = "fixed"; 14477 app.adjSeq = mAdjSeq; 14478 app.curRawAdj = app.maxAdj; 14479 app.foregroundActivities = false; 14480 app.keeping = true; 14481 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14482 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14483 // System process can do UI, and when they do we want to have 14484 // them trim their memory after the user leaves the UI. To 14485 // facilitate this, here we need to determine whether or not it 14486 // is currently showing UI. 14487 app.systemNoUi = true; 14488 if (app == TOP_APP) { 14489 app.systemNoUi = false; 14490 } else if (activitiesSize > 0) { 14491 for (int j = 0; j < activitiesSize; j++) { 14492 final ActivityRecord r = app.activities.get(j); 14493 if (r.visible) { 14494 app.systemNoUi = false; 14495 } 14496 } 14497 } 14498 if (!app.systemNoUi) { 14499 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14500 } 14501 return (app.curAdj=app.maxAdj); 14502 } 14503 14504 app.keeping = false; 14505 app.systemNoUi = false; 14506 14507 // Determine the importance of the process, starting with most 14508 // important to least, and assign an appropriate OOM adjustment. 14509 int adj; 14510 int schedGroup; 14511 int procState; 14512 boolean foregroundActivities = false; 14513 boolean interesting = false; 14514 BroadcastQueue queue; 14515 if (app == TOP_APP) { 14516 // The last app on the list is the foreground app. 14517 adj = ProcessList.FOREGROUND_APP_ADJ; 14518 schedGroup = Process.THREAD_GROUP_DEFAULT; 14519 app.adjType = "top-activity"; 14520 foregroundActivities = true; 14521 interesting = true; 14522 procState = ActivityManager.PROCESS_STATE_TOP; 14523 } else if (app.instrumentationClass != null) { 14524 // Don't want to kill running instrumentation. 14525 adj = ProcessList.FOREGROUND_APP_ADJ; 14526 schedGroup = Process.THREAD_GROUP_DEFAULT; 14527 app.adjType = "instrumentation"; 14528 interesting = true; 14529 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14530 } else if ((queue = isReceivingBroadcast(app)) != null) { 14531 // An app that is currently receiving a broadcast also 14532 // counts as being in the foreground for OOM killer purposes. 14533 // It's placed in a sched group based on the nature of the 14534 // broadcast as reflected by which queue it's active in. 14535 adj = ProcessList.FOREGROUND_APP_ADJ; 14536 schedGroup = (queue == mFgBroadcastQueue) 14537 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14538 app.adjType = "broadcast"; 14539 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14540 } else if (app.executingServices.size() > 0) { 14541 // An app that is currently executing a service callback also 14542 // counts as being in the foreground. 14543 adj = ProcessList.FOREGROUND_APP_ADJ; 14544 schedGroup = app.execServicesFg ? 14545 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14546 app.adjType = "exec-service"; 14547 procState = ActivityManager.PROCESS_STATE_SERVICE; 14548 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14549 } else { 14550 // As far as we know the process is empty. We may change our mind later. 14551 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14552 // At this point we don't actually know the adjustment. Use the cached adj 14553 // value that the caller wants us to. 14554 adj = cachedAdj; 14555 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14556 app.cached = true; 14557 app.empty = true; 14558 app.adjType = "cch-empty"; 14559 } 14560 14561 // Examine all activities if not already foreground. 14562 if (!foregroundActivities && activitiesSize > 0) { 14563 for (int j = 0; j < activitiesSize; j++) { 14564 final ActivityRecord r = app.activities.get(j); 14565 if (r.app != app) { 14566 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14567 + app + "?!?"); 14568 continue; 14569 } 14570 if (r.visible) { 14571 // App has a visible activity; only upgrade adjustment. 14572 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14573 adj = ProcessList.VISIBLE_APP_ADJ; 14574 app.adjType = "visible"; 14575 } 14576 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14577 procState = ActivityManager.PROCESS_STATE_TOP; 14578 } 14579 schedGroup = Process.THREAD_GROUP_DEFAULT; 14580 app.cached = false; 14581 app.empty = false; 14582 foregroundActivities = true; 14583 break; 14584 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14585 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14586 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14587 app.adjType = "pausing"; 14588 } 14589 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14590 procState = ActivityManager.PROCESS_STATE_TOP; 14591 } 14592 schedGroup = Process.THREAD_GROUP_DEFAULT; 14593 app.cached = false; 14594 app.empty = false; 14595 foregroundActivities = true; 14596 } else if (r.state == ActivityState.STOPPING) { 14597 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14598 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14599 app.adjType = "stopping"; 14600 } 14601 // For the process state, we will at this point consider the 14602 // process to be cached. It will be cached either as an activity 14603 // or empty depending on whether the activity is finishing. We do 14604 // this so that we can treat the process as cached for purposes of 14605 // memory trimming (determing current memory level, trim command to 14606 // send to process) since there can be an arbitrary number of stopping 14607 // processes and they should soon all go into the cached state. 14608 if (!r.finishing) { 14609 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14610 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14611 } 14612 } 14613 app.cached = false; 14614 app.empty = false; 14615 foregroundActivities = true; 14616 } else { 14617 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14618 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14619 app.adjType = "cch-act"; 14620 } 14621 } 14622 } 14623 } 14624 14625 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14626 if (app.foregroundServices) { 14627 // The user is aware of this app, so make it visible. 14628 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14629 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14630 app.cached = false; 14631 app.adjType = "fg-service"; 14632 schedGroup = Process.THREAD_GROUP_DEFAULT; 14633 } else if (app.forcingToForeground != null) { 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 = "force-fg"; 14639 app.adjSource = app.forcingToForeground; 14640 schedGroup = Process.THREAD_GROUP_DEFAULT; 14641 } 14642 } 14643 14644 if (app.foregroundServices) { 14645 interesting = true; 14646 } 14647 14648 if (app == mHeavyWeightProcess) { 14649 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14650 // We don't want to kill the current heavy-weight process. 14651 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14652 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14653 app.cached = false; 14654 app.adjType = "heavy"; 14655 } 14656 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14657 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14658 } 14659 } 14660 14661 if (app == mHomeProcess) { 14662 if (adj > ProcessList.HOME_APP_ADJ) { 14663 // This process is hosting what we currently consider to be the 14664 // home app, so we don't want to let it go into the background. 14665 adj = ProcessList.HOME_APP_ADJ; 14666 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14667 app.cached = false; 14668 app.adjType = "home"; 14669 } 14670 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14671 procState = ActivityManager.PROCESS_STATE_HOME; 14672 } 14673 } 14674 14675 if (app == mPreviousProcess && app.activities.size() > 0) { 14676 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14677 // This was the previous process that showed UI to the user. 14678 // We want to try to keep it around more aggressively, to give 14679 // a good experience around switching between two apps. 14680 adj = ProcessList.PREVIOUS_APP_ADJ; 14681 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14682 app.cached = false; 14683 app.adjType = "previous"; 14684 } 14685 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14686 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14687 } 14688 } 14689 14690 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14691 + " reason=" + app.adjType); 14692 14693 // By default, we use the computed adjustment. It may be changed if 14694 // there are applications dependent on our services or providers, but 14695 // this gives us a baseline and makes sure we don't get into an 14696 // infinite recursion. 14697 app.adjSeq = mAdjSeq; 14698 app.curRawAdj = adj; 14699 app.hasStartedServices = false; 14700 14701 if (mBackupTarget != null && app == mBackupTarget.app) { 14702 // If possible we want to avoid killing apps while they're being backed up 14703 if (adj > ProcessList.BACKUP_APP_ADJ) { 14704 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14705 adj = ProcessList.BACKUP_APP_ADJ; 14706 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14707 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14708 } 14709 app.adjType = "backup"; 14710 app.cached = false; 14711 } 14712 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14713 procState = ActivityManager.PROCESS_STATE_BACKUP; 14714 } 14715 } 14716 14717 boolean mayBeTop = false; 14718 14719 for (int is = app.services.size()-1; 14720 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14721 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14722 || procState > ActivityManager.PROCESS_STATE_TOP); 14723 is--) { 14724 ServiceRecord s = app.services.valueAt(is); 14725 if (s.startRequested) { 14726 app.hasStartedServices = true; 14727 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14728 procState = ActivityManager.PROCESS_STATE_SERVICE; 14729 } 14730 if (app.hasShownUi && app != mHomeProcess) { 14731 // If this process has shown some UI, let it immediately 14732 // go to the LRU list because it may be pretty heavy with 14733 // UI stuff. We'll tag it with a label just to help 14734 // debug and understand what is going on. 14735 if (adj > ProcessList.SERVICE_ADJ) { 14736 app.adjType = "cch-started-ui-services"; 14737 } 14738 } else { 14739 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14740 // This service has seen some activity within 14741 // recent memory, so we will keep its process ahead 14742 // of the background processes. 14743 if (adj > ProcessList.SERVICE_ADJ) { 14744 adj = ProcessList.SERVICE_ADJ; 14745 app.adjType = "started-services"; 14746 app.cached = false; 14747 } 14748 } 14749 // If we have let the service slide into the background 14750 // state, still have some text describing what it is doing 14751 // even though the service no longer has an impact. 14752 if (adj > ProcessList.SERVICE_ADJ) { 14753 app.adjType = "cch-started-services"; 14754 } 14755 } 14756 // Don't kill this process because it is doing work; it 14757 // has said it is doing work. 14758 app.keeping = true; 14759 } 14760 for (int conni = s.connections.size()-1; 14761 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14762 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14763 || procState > ActivityManager.PROCESS_STATE_TOP); 14764 conni--) { 14765 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14766 for (int i = 0; 14767 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14768 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14769 || procState > ActivityManager.PROCESS_STATE_TOP); 14770 i++) { 14771 // XXX should compute this based on the max of 14772 // all connected clients. 14773 ConnectionRecord cr = clist.get(i); 14774 if (cr.binding.client == app) { 14775 // Binding to ourself is not interesting. 14776 continue; 14777 } 14778 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14779 ProcessRecord client = cr.binding.client; 14780 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14781 TOP_APP, doingAll, now); 14782 int clientProcState = client.curProcState; 14783 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14784 // If the other app is cached for any reason, for purposes here 14785 // we are going to consider it empty. The specific cached state 14786 // doesn't propagate except under certain conditions. 14787 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14788 } 14789 String adjType = null; 14790 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14791 // Not doing bind OOM management, so treat 14792 // this guy more like a started service. 14793 if (app.hasShownUi && app != mHomeProcess) { 14794 // If this process has shown some UI, let it immediately 14795 // go to the LRU list because it may be pretty heavy with 14796 // UI stuff. We'll tag it with a label just to help 14797 // debug and understand what is going on. 14798 if (adj > clientAdj) { 14799 adjType = "cch-bound-ui-services"; 14800 } 14801 app.cached = false; 14802 clientAdj = adj; 14803 clientProcState = procState; 14804 } else { 14805 if (now >= (s.lastActivity 14806 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14807 // This service has not seen activity within 14808 // recent memory, so allow it to drop to the 14809 // LRU list if there is no other reason to keep 14810 // it around. We'll also tag it with a label just 14811 // to help debug and undertand what is going on. 14812 if (adj > clientAdj) { 14813 adjType = "cch-bound-services"; 14814 } 14815 clientAdj = adj; 14816 } 14817 } 14818 } 14819 if (adj > clientAdj) { 14820 // If this process has recently shown UI, and 14821 // the process that is binding to it is less 14822 // important than being visible, then we don't 14823 // care about the binding as much as we care 14824 // about letting this process get into the LRU 14825 // list to be killed and restarted if needed for 14826 // memory. 14827 if (app.hasShownUi && app != mHomeProcess 14828 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14829 adjType = "cch-bound-ui-services"; 14830 } else { 14831 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14832 |Context.BIND_IMPORTANT)) != 0) { 14833 adj = clientAdj; 14834 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14835 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14836 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14837 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14838 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14839 adj = clientAdj; 14840 } else { 14841 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14842 adj = ProcessList.VISIBLE_APP_ADJ; 14843 } 14844 } 14845 if (!client.cached) { 14846 app.cached = false; 14847 } 14848 if (client.keeping) { 14849 app.keeping = true; 14850 } 14851 adjType = "service"; 14852 } 14853 } 14854 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14855 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14856 schedGroup = Process.THREAD_GROUP_DEFAULT; 14857 } 14858 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14859 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14860 // Special handling of clients who are in the top state. 14861 // We *may* want to consider this process to be in the 14862 // top state as well, but only if there is not another 14863 // reason for it to be running. Being on the top is a 14864 // special state, meaning you are specifically running 14865 // for the current top app. If the process is already 14866 // running in the background for some other reason, it 14867 // is more important to continue considering it to be 14868 // in the background state. 14869 mayBeTop = true; 14870 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14871 } else { 14872 // Special handling for above-top states (persistent 14873 // processes). These should not bring the current process 14874 // into the top state, since they are not on top. Instead 14875 // give them the best state after that. 14876 clientProcState = 14877 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14878 } 14879 } 14880 } else { 14881 if (clientProcState < 14882 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14883 clientProcState = 14884 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14885 } 14886 } 14887 if (procState > clientProcState) { 14888 procState = clientProcState; 14889 } 14890 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14891 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14892 app.pendingUiClean = true; 14893 } 14894 if (adjType != null) { 14895 app.adjType = adjType; 14896 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14897 .REASON_SERVICE_IN_USE; 14898 app.adjSource = cr.binding.client; 14899 app.adjSourceOom = clientAdj; 14900 app.adjTarget = s.name; 14901 } 14902 } 14903 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 14904 app.treatLikeActivity = true; 14905 } 14906 final ActivityRecord a = cr.activity; 14907 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14908 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14909 (a.visible || a.state == ActivityState.RESUMED 14910 || a.state == ActivityState.PAUSING)) { 14911 adj = ProcessList.FOREGROUND_APP_ADJ; 14912 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14913 schedGroup = Process.THREAD_GROUP_DEFAULT; 14914 } 14915 app.cached = false; 14916 app.adjType = "service"; 14917 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14918 .REASON_SERVICE_IN_USE; 14919 app.adjSource = a; 14920 app.adjSourceOom = adj; 14921 app.adjTarget = s.name; 14922 } 14923 } 14924 } 14925 } 14926 } 14927 14928 for (int provi = app.pubProviders.size()-1; 14929 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14930 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14931 || procState > ActivityManager.PROCESS_STATE_TOP); 14932 provi--) { 14933 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14934 for (int i = cpr.connections.size()-1; 14935 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14936 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14937 || procState > ActivityManager.PROCESS_STATE_TOP); 14938 i--) { 14939 ContentProviderConnection conn = cpr.connections.get(i); 14940 ProcessRecord client = conn.client; 14941 if (client == app) { 14942 // Being our own client is not interesting. 14943 continue; 14944 } 14945 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14946 int clientProcState = client.curProcState; 14947 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14948 // If the other app is cached for any reason, for purposes here 14949 // we are going to consider it empty. 14950 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14951 } 14952 if (adj > clientAdj) { 14953 if (app.hasShownUi && app != mHomeProcess 14954 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14955 app.adjType = "cch-ui-provider"; 14956 } else { 14957 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14958 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14959 app.adjType = "provider"; 14960 } 14961 app.cached &= client.cached; 14962 app.keeping |= client.keeping; 14963 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14964 .REASON_PROVIDER_IN_USE; 14965 app.adjSource = client; 14966 app.adjSourceOom = clientAdj; 14967 app.adjTarget = cpr.name; 14968 } 14969 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14970 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14971 // Special handling of clients who are in the top state. 14972 // We *may* want to consider this process to be in the 14973 // top state as well, but only if there is not another 14974 // reason for it to be running. Being on the top is a 14975 // special state, meaning you are specifically running 14976 // for the current top app. If the process is already 14977 // running in the background for some other reason, it 14978 // is more important to continue considering it to be 14979 // in the background state. 14980 mayBeTop = true; 14981 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14982 } else { 14983 // Special handling for above-top states (persistent 14984 // processes). These should not bring the current process 14985 // into the top state, since they are not on top. Instead 14986 // give them the best state after that. 14987 clientProcState = 14988 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14989 } 14990 } 14991 if (procState > clientProcState) { 14992 procState = clientProcState; 14993 } 14994 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14995 schedGroup = Process.THREAD_GROUP_DEFAULT; 14996 } 14997 } 14998 // If the provider has external (non-framework) process 14999 // dependencies, ensure that its adjustment is at least 15000 // FOREGROUND_APP_ADJ. 15001 if (cpr.hasExternalProcessHandles()) { 15002 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15003 adj = ProcessList.FOREGROUND_APP_ADJ; 15004 schedGroup = Process.THREAD_GROUP_DEFAULT; 15005 app.cached = false; 15006 app.keeping = true; 15007 app.adjType = "provider"; 15008 app.adjTarget = cpr.name; 15009 } 15010 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15011 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15012 } 15013 } 15014 } 15015 15016 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15017 // A client of one of our services or providers is in the top state. We 15018 // *may* want to be in the top state, but not if we are already running in 15019 // the background for some other reason. For the decision here, we are going 15020 // to pick out a few specific states that we want to remain in when a client 15021 // is top (states that tend to be longer-term) and otherwise allow it to go 15022 // to the top state. 15023 switch (procState) { 15024 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15025 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15026 case ActivityManager.PROCESS_STATE_SERVICE: 15027 // These all are longer-term states, so pull them up to the top 15028 // of the background states, but not all the way to the top state. 15029 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15030 break; 15031 default: 15032 // Otherwise, top is a better choice, so take it. 15033 procState = ActivityManager.PROCESS_STATE_TOP; 15034 break; 15035 } 15036 } 15037 15038 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15039 if (app.hasClientActivities) { 15040 // This is a cached process, but with client activities. Mark it so. 15041 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15042 app.adjType = "cch-client-act"; 15043 } else if (app.treatLikeActivity) { 15044 // This is a cached process, but somebody wants us to treat it like it has 15045 // an activity, okay! 15046 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15047 app.adjType = "cch-as-act"; 15048 } 15049 } 15050 15051 if (adj == ProcessList.SERVICE_ADJ) { 15052 if (doingAll) { 15053 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15054 mNewNumServiceProcs++; 15055 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15056 if (!app.serviceb) { 15057 // This service isn't far enough down on the LRU list to 15058 // normally be a B service, but if we are low on RAM and it 15059 // is large we want to force it down since we would prefer to 15060 // keep launcher over it. 15061 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15062 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15063 app.serviceHighRam = true; 15064 app.serviceb = true; 15065 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15066 } else { 15067 mNewNumAServiceProcs++; 15068 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15069 } 15070 } else { 15071 app.serviceHighRam = false; 15072 } 15073 } 15074 if (app.serviceb) { 15075 adj = ProcessList.SERVICE_B_ADJ; 15076 } 15077 } 15078 15079 app.curRawAdj = adj; 15080 15081 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15082 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15083 if (adj > app.maxAdj) { 15084 adj = app.maxAdj; 15085 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15086 schedGroup = Process.THREAD_GROUP_DEFAULT; 15087 } 15088 } 15089 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15090 app.keeping = true; 15091 } 15092 15093 // Do final modification to adj. Everything we do between here and applying 15094 // the final setAdj must be done in this function, because we will also use 15095 // it when computing the final cached adj later. Note that we don't need to 15096 // worry about this for max adj above, since max adj will always be used to 15097 // keep it out of the cached vaues. 15098 adj = app.modifyRawOomAdj(adj); 15099 15100 app.curProcState = procState; 15101 15102 int importance = app.memImportance; 15103 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15104 app.curAdj = adj; 15105 app.curSchedGroup = schedGroup; 15106 if (!interesting) { 15107 // For this reporting, if there is not something explicitly 15108 // interesting in this process then we will push it to the 15109 // background importance. 15110 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15111 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15112 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15113 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15114 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15115 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15116 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15117 } else if (adj >= ProcessList.SERVICE_ADJ) { 15118 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15119 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15120 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15121 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15122 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15123 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15124 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15125 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15126 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15127 } else { 15128 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15129 } 15130 } 15131 15132 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15133 if (foregroundActivities != app.foregroundActivities) { 15134 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15135 } 15136 if (changes != 0) { 15137 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15138 app.memImportance = importance; 15139 app.foregroundActivities = foregroundActivities; 15140 int i = mPendingProcessChanges.size()-1; 15141 ProcessChangeItem item = null; 15142 while (i >= 0) { 15143 item = mPendingProcessChanges.get(i); 15144 if (item.pid == app.pid) { 15145 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15146 break; 15147 } 15148 i--; 15149 } 15150 if (i < 0) { 15151 // No existing item in pending changes; need a new one. 15152 final int NA = mAvailProcessChanges.size(); 15153 if (NA > 0) { 15154 item = mAvailProcessChanges.remove(NA-1); 15155 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15156 } else { 15157 item = new ProcessChangeItem(); 15158 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15159 } 15160 item.changes = 0; 15161 item.pid = app.pid; 15162 item.uid = app.info.uid; 15163 if (mPendingProcessChanges.size() == 0) { 15164 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15165 "*** Enqueueing dispatch processes changed!"); 15166 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15167 } 15168 mPendingProcessChanges.add(item); 15169 } 15170 item.changes |= changes; 15171 item.importance = importance; 15172 item.foregroundActivities = foregroundActivities; 15173 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15174 + Integer.toHexString(System.identityHashCode(item)) 15175 + " " + app.toShortString() + ": changes=" + item.changes 15176 + " importance=" + item.importance 15177 + " foreground=" + item.foregroundActivities 15178 + " type=" + app.adjType + " source=" + app.adjSource 15179 + " target=" + app.adjTarget); 15180 } 15181 15182 return app.curRawAdj; 15183 } 15184 15185 /** 15186 * Schedule PSS collection of a process. 15187 */ 15188 void requestPssLocked(ProcessRecord proc, int procState) { 15189 if (mPendingPssProcesses.contains(proc)) { 15190 return; 15191 } 15192 if (mPendingPssProcesses.size() == 0) { 15193 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15194 } 15195 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15196 proc.pssProcState = procState; 15197 mPendingPssProcesses.add(proc); 15198 } 15199 15200 /** 15201 * Schedule PSS collection of all processes. 15202 */ 15203 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15204 if (!always) { 15205 if (now < (mLastFullPssTime + 15206 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15207 return; 15208 } 15209 } 15210 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15211 mLastFullPssTime = now; 15212 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15213 mPendingPssProcesses.clear(); 15214 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15215 ProcessRecord app = mLruProcesses.get(i); 15216 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15217 app.pssProcState = app.setProcState; 15218 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15219 mSleeping, now); 15220 mPendingPssProcesses.add(app); 15221 } 15222 } 15223 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15224 } 15225 15226 /** 15227 * Ask a given process to GC right now. 15228 */ 15229 final void performAppGcLocked(ProcessRecord app) { 15230 try { 15231 app.lastRequestedGc = SystemClock.uptimeMillis(); 15232 if (app.thread != null) { 15233 if (app.reportLowMemory) { 15234 app.reportLowMemory = false; 15235 app.thread.scheduleLowMemory(); 15236 } else { 15237 app.thread.processInBackground(); 15238 } 15239 } 15240 } catch (Exception e) { 15241 // whatever. 15242 } 15243 } 15244 15245 /** 15246 * Returns true if things are idle enough to perform GCs. 15247 */ 15248 private final boolean canGcNowLocked() { 15249 boolean processingBroadcasts = false; 15250 for (BroadcastQueue q : mBroadcastQueues) { 15251 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15252 processingBroadcasts = true; 15253 } 15254 } 15255 return !processingBroadcasts 15256 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15257 } 15258 15259 /** 15260 * Perform GCs on all processes that are waiting for it, but only 15261 * if things are idle. 15262 */ 15263 final void performAppGcsLocked() { 15264 final int N = mProcessesToGc.size(); 15265 if (N <= 0) { 15266 return; 15267 } 15268 if (canGcNowLocked()) { 15269 while (mProcessesToGc.size() > 0) { 15270 ProcessRecord proc = mProcessesToGc.remove(0); 15271 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15272 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15273 <= SystemClock.uptimeMillis()) { 15274 // To avoid spamming the system, we will GC processes one 15275 // at a time, waiting a few seconds between each. 15276 performAppGcLocked(proc); 15277 scheduleAppGcsLocked(); 15278 return; 15279 } else { 15280 // It hasn't been long enough since we last GCed this 15281 // process... put it in the list to wait for its time. 15282 addProcessToGcListLocked(proc); 15283 break; 15284 } 15285 } 15286 } 15287 15288 scheduleAppGcsLocked(); 15289 } 15290 } 15291 15292 /** 15293 * If all looks good, perform GCs on all processes waiting for them. 15294 */ 15295 final void performAppGcsIfAppropriateLocked() { 15296 if (canGcNowLocked()) { 15297 performAppGcsLocked(); 15298 return; 15299 } 15300 // Still not idle, wait some more. 15301 scheduleAppGcsLocked(); 15302 } 15303 15304 /** 15305 * Schedule the execution of all pending app GCs. 15306 */ 15307 final void scheduleAppGcsLocked() { 15308 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15309 15310 if (mProcessesToGc.size() > 0) { 15311 // Schedule a GC for the time to the next process. 15312 ProcessRecord proc = mProcessesToGc.get(0); 15313 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15314 15315 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15316 long now = SystemClock.uptimeMillis(); 15317 if (when < (now+GC_TIMEOUT)) { 15318 when = now + GC_TIMEOUT; 15319 } 15320 mHandler.sendMessageAtTime(msg, when); 15321 } 15322 } 15323 15324 /** 15325 * Add a process to the array of processes waiting to be GCed. Keeps the 15326 * list in sorted order by the last GC time. The process can't already be 15327 * on the list. 15328 */ 15329 final void addProcessToGcListLocked(ProcessRecord proc) { 15330 boolean added = false; 15331 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15332 if (mProcessesToGc.get(i).lastRequestedGc < 15333 proc.lastRequestedGc) { 15334 added = true; 15335 mProcessesToGc.add(i+1, proc); 15336 break; 15337 } 15338 } 15339 if (!added) { 15340 mProcessesToGc.add(0, proc); 15341 } 15342 } 15343 15344 /** 15345 * Set up to ask a process to GC itself. This will either do it 15346 * immediately, or put it on the list of processes to gc the next 15347 * time things are idle. 15348 */ 15349 final void scheduleAppGcLocked(ProcessRecord app) { 15350 long now = SystemClock.uptimeMillis(); 15351 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15352 return; 15353 } 15354 if (!mProcessesToGc.contains(app)) { 15355 addProcessToGcListLocked(app); 15356 scheduleAppGcsLocked(); 15357 } 15358 } 15359 15360 final void checkExcessivePowerUsageLocked(boolean doKills) { 15361 updateCpuStatsNow(); 15362 15363 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15364 boolean doWakeKills = doKills; 15365 boolean doCpuKills = doKills; 15366 if (mLastPowerCheckRealtime == 0) { 15367 doWakeKills = false; 15368 } 15369 if (mLastPowerCheckUptime == 0) { 15370 doCpuKills = false; 15371 } 15372 if (stats.isScreenOn()) { 15373 doWakeKills = false; 15374 } 15375 final long curRealtime = SystemClock.elapsedRealtime(); 15376 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15377 final long curUptime = SystemClock.uptimeMillis(); 15378 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15379 mLastPowerCheckRealtime = curRealtime; 15380 mLastPowerCheckUptime = curUptime; 15381 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15382 doWakeKills = false; 15383 } 15384 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15385 doCpuKills = false; 15386 } 15387 int i = mLruProcesses.size(); 15388 while (i > 0) { 15389 i--; 15390 ProcessRecord app = mLruProcesses.get(i); 15391 if (!app.keeping) { 15392 long wtime; 15393 synchronized (stats) { 15394 wtime = stats.getProcessWakeTime(app.info.uid, 15395 app.pid, curRealtime); 15396 } 15397 long wtimeUsed = wtime - app.lastWakeTime; 15398 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15399 if (DEBUG_POWER) { 15400 StringBuilder sb = new StringBuilder(128); 15401 sb.append("Wake for "); 15402 app.toShortString(sb); 15403 sb.append(": over "); 15404 TimeUtils.formatDuration(realtimeSince, sb); 15405 sb.append(" used "); 15406 TimeUtils.formatDuration(wtimeUsed, sb); 15407 sb.append(" ("); 15408 sb.append((wtimeUsed*100)/realtimeSince); 15409 sb.append("%)"); 15410 Slog.i(TAG, sb.toString()); 15411 sb.setLength(0); 15412 sb.append("CPU for "); 15413 app.toShortString(sb); 15414 sb.append(": over "); 15415 TimeUtils.formatDuration(uptimeSince, sb); 15416 sb.append(" used "); 15417 TimeUtils.formatDuration(cputimeUsed, sb); 15418 sb.append(" ("); 15419 sb.append((cputimeUsed*100)/uptimeSince); 15420 sb.append("%)"); 15421 Slog.i(TAG, sb.toString()); 15422 } 15423 // If a process has held a wake lock for more 15424 // than 50% of the time during this period, 15425 // that sounds bad. Kill! 15426 if (doWakeKills && realtimeSince > 0 15427 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15428 synchronized (stats) { 15429 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15430 realtimeSince, wtimeUsed); 15431 } 15432 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15433 + " during " + realtimeSince); 15434 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15435 } else if (doCpuKills && uptimeSince > 0 15436 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15437 synchronized (stats) { 15438 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15439 uptimeSince, cputimeUsed); 15440 } 15441 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15442 + " during " + uptimeSince); 15443 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15444 } else { 15445 app.lastWakeTime = wtime; 15446 app.lastCpuTime = app.curCpuTime; 15447 } 15448 } 15449 } 15450 } 15451 15452 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15453 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15454 boolean success = true; 15455 15456 if (app.curRawAdj != app.setRawAdj) { 15457 if (wasKeeping && !app.keeping) { 15458 // This app is no longer something we want to keep. Note 15459 // its current wake lock time to later know to kill it if 15460 // it is not behaving well. 15461 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15462 synchronized (stats) { 15463 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15464 app.pid, SystemClock.elapsedRealtime()); 15465 } 15466 app.lastCpuTime = app.curCpuTime; 15467 } 15468 15469 app.setRawAdj = app.curRawAdj; 15470 } 15471 15472 if (app.curAdj != app.setAdj) { 15473 ProcessList.setOomAdj(app.pid, app.curAdj); 15474 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15475 TAG, "Set " + app.pid + " " + app.processName + 15476 " adj " + app.curAdj + ": " + app.adjType); 15477 app.setAdj = app.curAdj; 15478 } 15479 15480 if (app.setSchedGroup != app.curSchedGroup) { 15481 app.setSchedGroup = app.curSchedGroup; 15482 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15483 "Setting process group of " + app.processName 15484 + " to " + app.curSchedGroup); 15485 if (app.waitingToKill != null && 15486 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15487 killUnneededProcessLocked(app, app.waitingToKill); 15488 success = false; 15489 } else { 15490 if (true) { 15491 long oldId = Binder.clearCallingIdentity(); 15492 try { 15493 Process.setProcessGroup(app.pid, app.curSchedGroup); 15494 } catch (Exception e) { 15495 Slog.w(TAG, "Failed setting process group of " + app.pid 15496 + " to " + app.curSchedGroup); 15497 e.printStackTrace(); 15498 } finally { 15499 Binder.restoreCallingIdentity(oldId); 15500 } 15501 } else { 15502 if (app.thread != null) { 15503 try { 15504 app.thread.setSchedulingGroup(app.curSchedGroup); 15505 } catch (RemoteException e) { 15506 } 15507 } 15508 } 15509 Process.setSwappiness(app.pid, 15510 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15511 } 15512 } 15513 if (app.repProcState != app.curProcState) { 15514 app.repProcState = app.curProcState; 15515 if (!reportingProcessState && app.thread != null) { 15516 try { 15517 if (false) { 15518 //RuntimeException h = new RuntimeException("here"); 15519 Slog.i(TAG, "Sending new process state " + app.repProcState 15520 + " to " + app /*, h*/); 15521 } 15522 app.thread.setProcessState(app.repProcState); 15523 } catch (RemoteException e) { 15524 } 15525 } 15526 } 15527 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15528 app.setProcState)) { 15529 app.lastStateTime = now; 15530 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15531 mSleeping, now); 15532 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15533 + ProcessList.makeProcStateString(app.setProcState) + " to " 15534 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15535 + (app.nextPssTime-now) + ": " + app); 15536 } else { 15537 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15538 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15539 requestPssLocked(app, app.setProcState); 15540 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15541 mSleeping, now); 15542 } else if (false && DEBUG_PSS) { 15543 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15544 } 15545 } 15546 if (app.setProcState != app.curProcState) { 15547 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15548 "Proc state change of " + app.processName 15549 + " to " + app.curProcState); 15550 app.setProcState = app.curProcState; 15551 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15552 app.notCachedSinceIdle = false; 15553 } 15554 if (!doingAll) { 15555 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15556 } else { 15557 app.procStateChanged = true; 15558 } 15559 } 15560 return success; 15561 } 15562 15563 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15564 if (proc.thread != null && proc.baseProcessTracker != null) { 15565 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15566 } 15567 } 15568 15569 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15570 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15571 if (app.thread == null) { 15572 return false; 15573 } 15574 15575 final boolean wasKeeping = app.keeping; 15576 15577 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15578 15579 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15580 reportingProcessState, now); 15581 } 15582 15583 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15584 boolean oomAdj) { 15585 if (isForeground != proc.foregroundServices) { 15586 proc.foregroundServices = isForeground; 15587 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15588 proc.info.uid); 15589 if (isForeground) { 15590 if (curProcs == null) { 15591 curProcs = new ArrayList<ProcessRecord>(); 15592 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15593 } 15594 if (!curProcs.contains(proc)) { 15595 curProcs.add(proc); 15596 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15597 proc.info.packageName, proc.info.uid); 15598 } 15599 } else { 15600 if (curProcs != null) { 15601 if (curProcs.remove(proc)) { 15602 mBatteryStatsService.noteEvent( 15603 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15604 proc.info.packageName, proc.info.uid); 15605 if (curProcs.size() <= 0) { 15606 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15607 } 15608 } 15609 } 15610 } 15611 if (oomAdj) { 15612 updateOomAdjLocked(); 15613 } 15614 } 15615 } 15616 15617 private final ActivityRecord resumedAppLocked() { 15618 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15619 String pkg; 15620 int uid; 15621 if (act != null) { 15622 pkg = act.packageName; 15623 uid = act.info.applicationInfo.uid; 15624 } else { 15625 pkg = null; 15626 uid = -1; 15627 } 15628 // Has the UID or resumed package name changed? 15629 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15630 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15631 if (mCurResumedPackage != null) { 15632 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15633 mCurResumedPackage, mCurResumedUid); 15634 } 15635 mCurResumedPackage = pkg; 15636 mCurResumedUid = uid; 15637 if (mCurResumedPackage != null) { 15638 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15639 mCurResumedPackage, mCurResumedUid); 15640 } 15641 } 15642 return act; 15643 } 15644 15645 final boolean updateOomAdjLocked(ProcessRecord app) { 15646 return updateOomAdjLocked(app, false); 15647 } 15648 15649 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15650 final ActivityRecord TOP_ACT = resumedAppLocked(); 15651 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15652 final boolean wasCached = app.cached; 15653 15654 mAdjSeq++; 15655 15656 // This is the desired cached adjusment we want to tell it to use. 15657 // If our app is currently cached, we know it, and that is it. Otherwise, 15658 // we don't know it yet, and it needs to now be cached we will then 15659 // need to do a complete oom adj. 15660 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15661 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15662 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15663 SystemClock.uptimeMillis()); 15664 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15665 // Changed to/from cached state, so apps after it in the LRU 15666 // list may also be changed. 15667 updateOomAdjLocked(); 15668 } 15669 return success; 15670 } 15671 15672 final void updateOomAdjLocked() { 15673 final ActivityRecord TOP_ACT = resumedAppLocked(); 15674 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15675 final long now = SystemClock.uptimeMillis(); 15676 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15677 final int N = mLruProcesses.size(); 15678 15679 if (false) { 15680 RuntimeException e = new RuntimeException(); 15681 e.fillInStackTrace(); 15682 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15683 } 15684 15685 mAdjSeq++; 15686 mNewNumServiceProcs = 0; 15687 mNewNumAServiceProcs = 0; 15688 15689 final int emptyProcessLimit; 15690 final int cachedProcessLimit; 15691 if (mProcessLimit <= 0) { 15692 emptyProcessLimit = cachedProcessLimit = 0; 15693 } else if (mProcessLimit == 1) { 15694 emptyProcessLimit = 1; 15695 cachedProcessLimit = 0; 15696 } else { 15697 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15698 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15699 } 15700 15701 // Let's determine how many processes we have running vs. 15702 // how many slots we have for background processes; we may want 15703 // to put multiple processes in a slot of there are enough of 15704 // them. 15705 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15706 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15707 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15708 if (numEmptyProcs > cachedProcessLimit) { 15709 // If there are more empty processes than our limit on cached 15710 // processes, then use the cached process limit for the factor. 15711 // This ensures that the really old empty processes get pushed 15712 // down to the bottom, so if we are running low on memory we will 15713 // have a better chance at keeping around more cached processes 15714 // instead of a gazillion empty processes. 15715 numEmptyProcs = cachedProcessLimit; 15716 } 15717 int emptyFactor = numEmptyProcs/numSlots; 15718 if (emptyFactor < 1) emptyFactor = 1; 15719 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15720 if (cachedFactor < 1) cachedFactor = 1; 15721 int stepCached = 0; 15722 int stepEmpty = 0; 15723 int numCached = 0; 15724 int numEmpty = 0; 15725 int numTrimming = 0; 15726 15727 mNumNonCachedProcs = 0; 15728 mNumCachedHiddenProcs = 0; 15729 15730 // First update the OOM adjustment for each of the 15731 // application processes based on their current state. 15732 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15733 int nextCachedAdj = curCachedAdj+1; 15734 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15735 int nextEmptyAdj = curEmptyAdj+2; 15736 for (int i=N-1; i>=0; i--) { 15737 ProcessRecord app = mLruProcesses.get(i); 15738 if (!app.killedByAm && app.thread != null) { 15739 app.procStateChanged = false; 15740 final boolean wasKeeping = app.keeping; 15741 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15742 15743 // If we haven't yet assigned the final cached adj 15744 // to the process, do that now. 15745 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15746 switch (app.curProcState) { 15747 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15748 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15749 // This process is a cached process holding activities... 15750 // assign it the next cached value for that type, and then 15751 // step that cached level. 15752 app.curRawAdj = curCachedAdj; 15753 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15754 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15755 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15756 + ")"); 15757 if (curCachedAdj != nextCachedAdj) { 15758 stepCached++; 15759 if (stepCached >= cachedFactor) { 15760 stepCached = 0; 15761 curCachedAdj = nextCachedAdj; 15762 nextCachedAdj += 2; 15763 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15764 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15765 } 15766 } 15767 } 15768 break; 15769 default: 15770 // For everything else, assign next empty cached process 15771 // level and bump that up. Note that this means that 15772 // long-running services that have dropped down to the 15773 // cached level will be treated as empty (since their process 15774 // state is still as a service), which is what we want. 15775 app.curRawAdj = curEmptyAdj; 15776 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15777 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15778 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15779 + ")"); 15780 if (curEmptyAdj != nextEmptyAdj) { 15781 stepEmpty++; 15782 if (stepEmpty >= emptyFactor) { 15783 stepEmpty = 0; 15784 curEmptyAdj = nextEmptyAdj; 15785 nextEmptyAdj += 2; 15786 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15787 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15788 } 15789 } 15790 } 15791 break; 15792 } 15793 } 15794 15795 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15796 15797 // Count the number of process types. 15798 switch (app.curProcState) { 15799 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15800 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15801 mNumCachedHiddenProcs++; 15802 numCached++; 15803 if (numCached > cachedProcessLimit) { 15804 killUnneededProcessLocked(app, "cached #" + numCached); 15805 } 15806 break; 15807 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15808 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15809 && app.lastActivityTime < oldTime) { 15810 killUnneededProcessLocked(app, "empty for " 15811 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15812 / 1000) + "s"); 15813 } else { 15814 numEmpty++; 15815 if (numEmpty > emptyProcessLimit) { 15816 killUnneededProcessLocked(app, "empty #" + numEmpty); 15817 } 15818 } 15819 break; 15820 default: 15821 mNumNonCachedProcs++; 15822 break; 15823 } 15824 15825 if (app.isolated && app.services.size() <= 0) { 15826 // If this is an isolated process, and there are no 15827 // services running in it, then the process is no longer 15828 // needed. We agressively kill these because we can by 15829 // definition not re-use the same process again, and it is 15830 // good to avoid having whatever code was running in them 15831 // left sitting around after no longer needed. 15832 killUnneededProcessLocked(app, "isolated not needed"); 15833 } 15834 15835 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15836 && !app.killedByAm) { 15837 numTrimming++; 15838 } 15839 } 15840 } 15841 15842 mNumServiceProcs = mNewNumServiceProcs; 15843 15844 // Now determine the memory trimming level of background processes. 15845 // Unfortunately we need to start at the back of the list to do this 15846 // properly. We only do this if the number of background apps we 15847 // are managing to keep around is less than half the maximum we desire; 15848 // if we are keeping a good number around, we'll let them use whatever 15849 // memory they want. 15850 final int numCachedAndEmpty = numCached + numEmpty; 15851 int memFactor; 15852 if (numCached <= ProcessList.TRIM_CACHED_APPS 15853 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15854 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15855 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15856 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15857 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15858 } else { 15859 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15860 } 15861 } else { 15862 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15863 } 15864 // We always allow the memory level to go up (better). We only allow it to go 15865 // down if we are in a state where that is allowed, *and* the total number of processes 15866 // has gone down since last time. 15867 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15868 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15869 + " last=" + mLastNumProcesses); 15870 if (memFactor > mLastMemoryLevel) { 15871 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15872 memFactor = mLastMemoryLevel; 15873 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15874 } 15875 } 15876 mLastMemoryLevel = memFactor; 15877 mLastNumProcesses = mLruProcesses.size(); 15878 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15879 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15880 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15881 if (mLowRamStartTime == 0) { 15882 mLowRamStartTime = now; 15883 } 15884 int step = 0; 15885 int fgTrimLevel; 15886 switch (memFactor) { 15887 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15888 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15889 break; 15890 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15891 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15892 break; 15893 default: 15894 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15895 break; 15896 } 15897 int factor = numTrimming/3; 15898 int minFactor = 2; 15899 if (mHomeProcess != null) minFactor++; 15900 if (mPreviousProcess != null) minFactor++; 15901 if (factor < minFactor) factor = minFactor; 15902 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15903 for (int i=N-1; i>=0; i--) { 15904 ProcessRecord app = mLruProcesses.get(i); 15905 if (allChanged || app.procStateChanged) { 15906 setProcessTrackerState(app, trackerMemFactor, now); 15907 app.procStateChanged = false; 15908 } 15909 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15910 && !app.killedByAm) { 15911 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15912 try { 15913 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15914 "Trimming memory of " + app.processName 15915 + " to " + curLevel); 15916 app.thread.scheduleTrimMemory(curLevel); 15917 } catch (RemoteException e) { 15918 } 15919 if (false) { 15920 // For now we won't do this; our memory trimming seems 15921 // to be good enough at this point that destroying 15922 // activities causes more harm than good. 15923 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15924 && app != mHomeProcess && app != mPreviousProcess) { 15925 // Need to do this on its own message because the stack may not 15926 // be in a consistent state at this point. 15927 // For these apps we will also finish their activities 15928 // to help them free memory. 15929 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15930 } 15931 } 15932 } 15933 app.trimMemoryLevel = curLevel; 15934 step++; 15935 if (step >= factor) { 15936 step = 0; 15937 switch (curLevel) { 15938 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15939 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15940 break; 15941 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15942 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15943 break; 15944 } 15945 } 15946 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15947 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15948 && app.thread != null) { 15949 try { 15950 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15951 "Trimming memory of heavy-weight " + app.processName 15952 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15953 app.thread.scheduleTrimMemory( 15954 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15955 } catch (RemoteException e) { 15956 } 15957 } 15958 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15959 } else { 15960 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15961 || app.systemNoUi) && app.pendingUiClean) { 15962 // If this application is now in the background and it 15963 // had done UI, then give it the special trim level to 15964 // have it free UI resources. 15965 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15966 if (app.trimMemoryLevel < level && app.thread != null) { 15967 try { 15968 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15969 "Trimming memory of bg-ui " + app.processName 15970 + " to " + level); 15971 app.thread.scheduleTrimMemory(level); 15972 } catch (RemoteException e) { 15973 } 15974 } 15975 app.pendingUiClean = false; 15976 } 15977 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15978 try { 15979 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15980 "Trimming memory of fg " + app.processName 15981 + " to " + fgTrimLevel); 15982 app.thread.scheduleTrimMemory(fgTrimLevel); 15983 } catch (RemoteException e) { 15984 } 15985 } 15986 app.trimMemoryLevel = fgTrimLevel; 15987 } 15988 } 15989 } else { 15990 if (mLowRamStartTime != 0) { 15991 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15992 mLowRamStartTime = 0; 15993 } 15994 for (int i=N-1; i>=0; i--) { 15995 ProcessRecord app = mLruProcesses.get(i); 15996 if (allChanged || app.procStateChanged) { 15997 setProcessTrackerState(app, trackerMemFactor, now); 15998 app.procStateChanged = false; 15999 } 16000 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16001 || app.systemNoUi) && app.pendingUiClean) { 16002 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16003 && app.thread != null) { 16004 try { 16005 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16006 "Trimming memory of ui hidden " + app.processName 16007 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16008 app.thread.scheduleTrimMemory( 16009 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16010 } catch (RemoteException e) { 16011 } 16012 } 16013 app.pendingUiClean = false; 16014 } 16015 app.trimMemoryLevel = 0; 16016 } 16017 } 16018 16019 if (mAlwaysFinishActivities) { 16020 // Need to do this on its own message because the stack may not 16021 // be in a consistent state at this point. 16022 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16023 } 16024 16025 if (allChanged) { 16026 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16027 } 16028 16029 if (mProcessStats.shouldWriteNowLocked(now)) { 16030 mHandler.post(new Runnable() { 16031 @Override public void run() { 16032 synchronized (ActivityManagerService.this) { 16033 mProcessStats.writeStateAsyncLocked(); 16034 } 16035 } 16036 }); 16037 } 16038 16039 if (DEBUG_OOM_ADJ) { 16040 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16041 } 16042 } 16043 16044 final void trimApplications() { 16045 synchronized (this) { 16046 int i; 16047 16048 // First remove any unused application processes whose package 16049 // has been removed. 16050 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16051 final ProcessRecord app = mRemovedProcesses.get(i); 16052 if (app.activities.size() == 0 16053 && app.curReceiver == null && app.services.size() == 0) { 16054 Slog.i( 16055 TAG, "Exiting empty application process " 16056 + app.processName + " (" 16057 + (app.thread != null ? app.thread.asBinder() : null) 16058 + ")\n"); 16059 if (app.pid > 0 && app.pid != MY_PID) { 16060 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16061 app.processName, app.setAdj, "empty"); 16062 app.killedByAm = true; 16063 Process.killProcessQuiet(app.pid); 16064 } else { 16065 try { 16066 app.thread.scheduleExit(); 16067 } catch (Exception e) { 16068 // Ignore exceptions. 16069 } 16070 } 16071 cleanUpApplicationRecordLocked(app, false, true, -1); 16072 mRemovedProcesses.remove(i); 16073 16074 if (app.persistent) { 16075 if (app.persistent) { 16076 addAppLocked(app.info, false); 16077 } 16078 } 16079 } 16080 } 16081 16082 // Now update the oom adj for all processes. 16083 updateOomAdjLocked(); 16084 } 16085 } 16086 16087 /** This method sends the specified signal to each of the persistent apps */ 16088 public void signalPersistentProcesses(int sig) throws RemoteException { 16089 if (sig != Process.SIGNAL_USR1) { 16090 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16091 } 16092 16093 synchronized (this) { 16094 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16095 != PackageManager.PERMISSION_GRANTED) { 16096 throw new SecurityException("Requires permission " 16097 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16098 } 16099 16100 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16101 ProcessRecord r = mLruProcesses.get(i); 16102 if (r.thread != null && r.persistent) { 16103 Process.sendSignal(r.pid, sig); 16104 } 16105 } 16106 } 16107 } 16108 16109 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16110 if (proc == null || proc == mProfileProc) { 16111 proc = mProfileProc; 16112 path = mProfileFile; 16113 profileType = mProfileType; 16114 clearProfilerLocked(); 16115 } 16116 if (proc == null) { 16117 return; 16118 } 16119 try { 16120 proc.thread.profilerControl(false, path, null, profileType); 16121 } catch (RemoteException e) { 16122 throw new IllegalStateException("Process disappeared"); 16123 } 16124 } 16125 16126 private void clearProfilerLocked() { 16127 if (mProfileFd != null) { 16128 try { 16129 mProfileFd.close(); 16130 } catch (IOException e) { 16131 } 16132 } 16133 mProfileApp = null; 16134 mProfileProc = null; 16135 mProfileFile = null; 16136 mProfileType = 0; 16137 mAutoStopProfiler = false; 16138 } 16139 16140 public boolean profileControl(String process, int userId, boolean start, 16141 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16142 16143 try { 16144 synchronized (this) { 16145 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16146 // its own permission. 16147 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16148 != PackageManager.PERMISSION_GRANTED) { 16149 throw new SecurityException("Requires permission " 16150 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16151 } 16152 16153 if (start && fd == null) { 16154 throw new IllegalArgumentException("null fd"); 16155 } 16156 16157 ProcessRecord proc = null; 16158 if (process != null) { 16159 proc = findProcessLocked(process, userId, "profileControl"); 16160 } 16161 16162 if (start && (proc == null || proc.thread == null)) { 16163 throw new IllegalArgumentException("Unknown process: " + process); 16164 } 16165 16166 if (start) { 16167 stopProfilerLocked(null, null, 0); 16168 setProfileApp(proc.info, proc.processName, path, fd, false); 16169 mProfileProc = proc; 16170 mProfileType = profileType; 16171 try { 16172 fd = fd.dup(); 16173 } catch (IOException e) { 16174 fd = null; 16175 } 16176 proc.thread.profilerControl(start, path, fd, profileType); 16177 fd = null; 16178 mProfileFd = null; 16179 } else { 16180 stopProfilerLocked(proc, path, profileType); 16181 if (fd != null) { 16182 try { 16183 fd.close(); 16184 } catch (IOException e) { 16185 } 16186 } 16187 } 16188 16189 return true; 16190 } 16191 } catch (RemoteException e) { 16192 throw new IllegalStateException("Process disappeared"); 16193 } finally { 16194 if (fd != null) { 16195 try { 16196 fd.close(); 16197 } catch (IOException e) { 16198 } 16199 } 16200 } 16201 } 16202 16203 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16204 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16205 userId, true, true, callName, null); 16206 ProcessRecord proc = null; 16207 try { 16208 int pid = Integer.parseInt(process); 16209 synchronized (mPidsSelfLocked) { 16210 proc = mPidsSelfLocked.get(pid); 16211 } 16212 } catch (NumberFormatException e) { 16213 } 16214 16215 if (proc == null) { 16216 ArrayMap<String, SparseArray<ProcessRecord>> all 16217 = mProcessNames.getMap(); 16218 SparseArray<ProcessRecord> procs = all.get(process); 16219 if (procs != null && procs.size() > 0) { 16220 proc = procs.valueAt(0); 16221 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16222 for (int i=1; i<procs.size(); i++) { 16223 ProcessRecord thisProc = procs.valueAt(i); 16224 if (thisProc.userId == userId) { 16225 proc = thisProc; 16226 break; 16227 } 16228 } 16229 } 16230 } 16231 } 16232 16233 return proc; 16234 } 16235 16236 public boolean dumpHeap(String process, int userId, boolean managed, 16237 String path, ParcelFileDescriptor fd) throws RemoteException { 16238 16239 try { 16240 synchronized (this) { 16241 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16242 // its own permission (same as profileControl). 16243 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16244 != PackageManager.PERMISSION_GRANTED) { 16245 throw new SecurityException("Requires permission " 16246 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16247 } 16248 16249 if (fd == null) { 16250 throw new IllegalArgumentException("null fd"); 16251 } 16252 16253 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16254 if (proc == null || proc.thread == null) { 16255 throw new IllegalArgumentException("Unknown process: " + process); 16256 } 16257 16258 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16259 if (!isDebuggable) { 16260 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16261 throw new SecurityException("Process not debuggable: " + proc); 16262 } 16263 } 16264 16265 proc.thread.dumpHeap(managed, path, fd); 16266 fd = null; 16267 return true; 16268 } 16269 } catch (RemoteException e) { 16270 throw new IllegalStateException("Process disappeared"); 16271 } finally { 16272 if (fd != null) { 16273 try { 16274 fd.close(); 16275 } catch (IOException e) { 16276 } 16277 } 16278 } 16279 } 16280 16281 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16282 public void monitor() { 16283 synchronized (this) { } 16284 } 16285 16286 void onCoreSettingsChange(Bundle settings) { 16287 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16288 ProcessRecord processRecord = mLruProcesses.get(i); 16289 try { 16290 if (processRecord.thread != null) { 16291 processRecord.thread.setCoreSettings(settings); 16292 } 16293 } catch (RemoteException re) { 16294 /* ignore */ 16295 } 16296 } 16297 } 16298 16299 // Multi-user methods 16300 16301 /** 16302 * Start user, if its not already running, but don't bring it to foreground. 16303 */ 16304 @Override 16305 public boolean startUserInBackground(final int userId) { 16306 return startUser(userId, /* foreground */ false); 16307 } 16308 16309 /** 16310 * Refreshes the list of users related to the current user when either a 16311 * user switch happens or when a new related user is started in the 16312 * background. 16313 */ 16314 private void updateRelatedUserIdsLocked() { 16315 final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16316 int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null 16317 for (int i = 0; i < relatedUserIds.length; i++) { 16318 relatedUserIds[i] = relatedUsers.get(i).id; 16319 } 16320 mRelatedUserIds = relatedUserIds; 16321 } 16322 16323 private Set getRelatedUsersLocked(int userId) { 16324 Set userIds = new HashSet<Integer>(); 16325 final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(userId); 16326 for (UserInfo user : relatedUsers) { 16327 userIds.add(Integer.valueOf(user.id)); 16328 } 16329 return userIds; 16330 } 16331 16332 @Override 16333 public boolean switchUser(final int userId) { 16334 return startUser(userId, /* foregound */ true); 16335 } 16336 16337 private boolean startUser(final int userId, boolean foreground) { 16338 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16339 != PackageManager.PERMISSION_GRANTED) { 16340 String msg = "Permission Denial: switchUser() from pid=" 16341 + Binder.getCallingPid() 16342 + ", uid=" + Binder.getCallingUid() 16343 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16344 Slog.w(TAG, msg); 16345 throw new SecurityException(msg); 16346 } 16347 16348 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16349 16350 final long ident = Binder.clearCallingIdentity(); 16351 try { 16352 synchronized (this) { 16353 final int oldUserId = mCurrentUserId; 16354 if (oldUserId == userId) { 16355 return true; 16356 } 16357 16358 mStackSupervisor.setLockTaskModeLocked(null); 16359 16360 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16361 if (userInfo == null) { 16362 Slog.w(TAG, "No user info for user #" + userId); 16363 return false; 16364 } 16365 16366 if (foreground) { 16367 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16368 R.anim.screen_user_enter); 16369 } 16370 16371 boolean needStart = false; 16372 16373 // If the user we are switching to is not currently started, then 16374 // we need to start it now. 16375 if (mStartedUsers.get(userId) == null) { 16376 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16377 updateStartedUserArrayLocked(); 16378 needStart = true; 16379 } 16380 16381 final Integer userIdInt = Integer.valueOf(userId); 16382 mUserLru.remove(userIdInt); 16383 mUserLru.add(userIdInt); 16384 16385 if (foreground) { 16386 mCurrentUserId = userId; 16387 updateRelatedUserIdsLocked(); 16388 mWindowManager.setCurrentUser(userId, mRelatedUserIds); 16389 // Once the internal notion of the active user has switched, we lock the device 16390 // with the option to show the user switcher on the keyguard. 16391 mWindowManager.lockNow(null); 16392 } else { 16393 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16394 updateRelatedUserIdsLocked(); 16395 mWindowManager.updateRelatedUserIds(mRelatedUserIds); 16396 mUserLru.remove(currentUserIdInt); 16397 mUserLru.add(currentUserIdInt); 16398 } 16399 16400 final UserStartedState uss = mStartedUsers.get(userId); 16401 16402 // Make sure user is in the started state. If it is currently 16403 // stopping, we need to knock that off. 16404 if (uss.mState == UserStartedState.STATE_STOPPING) { 16405 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16406 // so we can just fairly silently bring the user back from 16407 // the almost-dead. 16408 uss.mState = UserStartedState.STATE_RUNNING; 16409 updateStartedUserArrayLocked(); 16410 needStart = true; 16411 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16412 // This means ACTION_SHUTDOWN has been sent, so we will 16413 // need to treat this as a new boot of the user. 16414 uss.mState = UserStartedState.STATE_BOOTING; 16415 updateStartedUserArrayLocked(); 16416 needStart = true; 16417 } 16418 16419 if (foreground) { 16420 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16421 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16422 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16423 oldUserId, userId, uss)); 16424 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16425 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16426 } 16427 16428 if (needStart) { 16429 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16430 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16431 | Intent.FLAG_RECEIVER_FOREGROUND); 16432 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16433 broadcastIntentLocked(null, null, intent, 16434 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16435 false, false, MY_PID, Process.SYSTEM_UID, userId); 16436 } 16437 16438 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16439 if (userId != 0) { 16440 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16441 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16442 broadcastIntentLocked(null, null, intent, null, 16443 new IIntentReceiver.Stub() { 16444 public void performReceive(Intent intent, int resultCode, 16445 String data, Bundle extras, boolean ordered, 16446 boolean sticky, int sendingUser) { 16447 userInitialized(uss, userId); 16448 } 16449 }, 0, null, null, null, AppOpsManager.OP_NONE, 16450 true, false, MY_PID, Process.SYSTEM_UID, 16451 userId); 16452 uss.initializing = true; 16453 } else { 16454 getUserManagerLocked().makeInitialized(userInfo.id); 16455 } 16456 } 16457 16458 if (foreground) { 16459 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16460 if (homeInFront) { 16461 startHomeActivityLocked(userId); 16462 } else { 16463 mStackSupervisor.resumeTopActivitiesLocked(); 16464 } 16465 EventLogTags.writeAmSwitchUser(userId); 16466 getUserManagerLocked().userForeground(userId); 16467 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16468 } 16469 16470 if (needStart) { 16471 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16472 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16473 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16474 broadcastIntentLocked(null, null, intent, 16475 null, new IIntentReceiver.Stub() { 16476 @Override 16477 public void performReceive(Intent intent, int resultCode, String data, 16478 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16479 throws RemoteException { 16480 } 16481 }, 0, null, null, 16482 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16483 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16484 } 16485 } 16486 } finally { 16487 Binder.restoreCallingIdentity(ident); 16488 } 16489 16490 return true; 16491 } 16492 16493 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16494 long ident = Binder.clearCallingIdentity(); 16495 try { 16496 Intent intent; 16497 if (oldUserId >= 0) { 16498 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16499 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16500 | Intent.FLAG_RECEIVER_FOREGROUND); 16501 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16502 broadcastIntentLocked(null, null, intent, 16503 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16504 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16505 } 16506 if (newUserId >= 0) { 16507 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16508 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16509 | Intent.FLAG_RECEIVER_FOREGROUND); 16510 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16511 broadcastIntentLocked(null, null, intent, 16512 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16513 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16514 intent = new Intent(Intent.ACTION_USER_SWITCHED); 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, 16520 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16521 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16522 } 16523 } finally { 16524 Binder.restoreCallingIdentity(ident); 16525 } 16526 } 16527 16528 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16529 final int newUserId) { 16530 final int N = mUserSwitchObservers.beginBroadcast(); 16531 if (N > 0) { 16532 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16533 int mCount = 0; 16534 @Override 16535 public void sendResult(Bundle data) throws RemoteException { 16536 synchronized (ActivityManagerService.this) { 16537 if (mCurUserSwitchCallback == this) { 16538 mCount++; 16539 if (mCount == N) { 16540 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16541 } 16542 } 16543 } 16544 } 16545 }; 16546 synchronized (this) { 16547 uss.switching = true; 16548 mCurUserSwitchCallback = callback; 16549 } 16550 for (int i=0; i<N; i++) { 16551 try { 16552 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16553 newUserId, callback); 16554 } catch (RemoteException e) { 16555 } 16556 } 16557 } else { 16558 synchronized (this) { 16559 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16560 } 16561 } 16562 mUserSwitchObservers.finishBroadcast(); 16563 } 16564 16565 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16566 synchronized (this) { 16567 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16568 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16569 } 16570 } 16571 16572 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16573 mCurUserSwitchCallback = null; 16574 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16575 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16576 oldUserId, newUserId, uss)); 16577 } 16578 16579 void userInitialized(UserStartedState uss, int newUserId) { 16580 completeSwitchAndInitalize(uss, newUserId, true, false); 16581 } 16582 16583 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16584 completeSwitchAndInitalize(uss, newUserId, false, true); 16585 } 16586 16587 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16588 boolean clearInitializing, boolean clearSwitching) { 16589 boolean unfrozen = false; 16590 synchronized (this) { 16591 if (clearInitializing) { 16592 uss.initializing = false; 16593 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16594 } 16595 if (clearSwitching) { 16596 uss.switching = false; 16597 } 16598 if (!uss.switching && !uss.initializing) { 16599 mWindowManager.stopFreezingScreen(); 16600 unfrozen = true; 16601 } 16602 } 16603 if (unfrozen) { 16604 final int N = mUserSwitchObservers.beginBroadcast(); 16605 for (int i=0; i<N; i++) { 16606 try { 16607 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16608 } catch (RemoteException e) { 16609 } 16610 } 16611 mUserSwitchObservers.finishBroadcast(); 16612 } 16613 } 16614 16615 void scheduleStartRelatedUsersLocked() { 16616 if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) { 16617 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG), 16618 DateUtils.SECOND_IN_MILLIS); 16619 } 16620 } 16621 16622 void startRelatedUsersLocked() { 16623 if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked"); 16624 List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16625 List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size()); 16626 for (UserInfo relatedUser : relatedUsers) { 16627 if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) { 16628 toStart.add(relatedUser); 16629 } 16630 } 16631 final int n = toStart.size(); 16632 int i = 0; 16633 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16634 startUserInBackground(toStart.get(i).id); 16635 } 16636 if (i < n) { 16637 Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS"); 16638 } 16639 } 16640 16641 void finishUserSwitch(UserStartedState uss) { 16642 synchronized (this) { 16643 if (uss.mState == UserStartedState.STATE_BOOTING 16644 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16645 uss.mState = UserStartedState.STATE_RUNNING; 16646 final int userId = uss.mHandle.getIdentifier(); 16647 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16648 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16649 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16650 broadcastIntentLocked(null, null, intent, 16651 null, null, 0, null, null, 16652 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16653 true, false, MY_PID, Process.SYSTEM_UID, userId); 16654 } 16655 16656 startRelatedUsersLocked(); 16657 16658 int num = mUserLru.size(); 16659 int i = 0; 16660 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16661 Integer oldUserId = mUserLru.get(i); 16662 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16663 if (oldUss == null) { 16664 // Shouldn't happen, but be sane if it does. 16665 mUserLru.remove(i); 16666 num--; 16667 continue; 16668 } 16669 if (oldUss.mState == UserStartedState.STATE_STOPPING 16670 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16671 // This user is already stopping, doesn't count. 16672 num--; 16673 i++; 16674 continue; 16675 } 16676 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16677 // Owner and current can't be stopped, but count as running. 16678 i++; 16679 continue; 16680 } 16681 // This is a user to be stopped. 16682 stopUserLocked(oldUserId, null); 16683 num--; 16684 i++; 16685 } 16686 } 16687 } 16688 16689 @Override 16690 public int stopUser(final int userId, final IStopUserCallback callback) { 16691 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16692 != PackageManager.PERMISSION_GRANTED) { 16693 String msg = "Permission Denial: switchUser() from pid=" 16694 + Binder.getCallingPid() 16695 + ", uid=" + Binder.getCallingUid() 16696 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16697 Slog.w(TAG, msg); 16698 throw new SecurityException(msg); 16699 } 16700 if (userId <= 0) { 16701 throw new IllegalArgumentException("Can't stop primary user " + userId); 16702 } 16703 synchronized (this) { 16704 return stopUserLocked(userId, callback); 16705 } 16706 } 16707 16708 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16709 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16710 if (mCurrentUserId == userId) { 16711 return ActivityManager.USER_OP_IS_CURRENT; 16712 } 16713 16714 final UserStartedState uss = mStartedUsers.get(userId); 16715 if (uss == null) { 16716 // User is not started, nothing to do... but we do need to 16717 // callback if requested. 16718 if (callback != null) { 16719 mHandler.post(new Runnable() { 16720 @Override 16721 public void run() { 16722 try { 16723 callback.userStopped(userId); 16724 } catch (RemoteException e) { 16725 } 16726 } 16727 }); 16728 } 16729 return ActivityManager.USER_OP_SUCCESS; 16730 } 16731 16732 if (callback != null) { 16733 uss.mStopCallbacks.add(callback); 16734 } 16735 16736 if (uss.mState != UserStartedState.STATE_STOPPING 16737 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16738 uss.mState = UserStartedState.STATE_STOPPING; 16739 updateStartedUserArrayLocked(); 16740 16741 long ident = Binder.clearCallingIdentity(); 16742 try { 16743 // We are going to broadcast ACTION_USER_STOPPING and then 16744 // once that is done send a final ACTION_SHUTDOWN and then 16745 // stop the user. 16746 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16747 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16748 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16749 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16750 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16751 // This is the result receiver for the final shutdown broadcast. 16752 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16753 @Override 16754 public void performReceive(Intent intent, int resultCode, String data, 16755 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16756 finishUserStop(uss); 16757 } 16758 }; 16759 // This is the result receiver for the initial stopping broadcast. 16760 final IIntentReceiver stoppingReceiver = 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 // On to the next. 16765 synchronized (ActivityManagerService.this) { 16766 if (uss.mState != UserStartedState.STATE_STOPPING) { 16767 // Whoops, we are being started back up. Abort, abort! 16768 return; 16769 } 16770 uss.mState = UserStartedState.STATE_SHUTDOWN; 16771 } 16772 broadcastIntentLocked(null, null, shutdownIntent, 16773 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16774 true, false, MY_PID, Process.SYSTEM_UID, userId); 16775 } 16776 }; 16777 // Kick things off. 16778 broadcastIntentLocked(null, null, stoppingIntent, 16779 null, stoppingReceiver, 0, null, null, 16780 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16781 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16782 } finally { 16783 Binder.restoreCallingIdentity(ident); 16784 } 16785 } 16786 16787 return ActivityManager.USER_OP_SUCCESS; 16788 } 16789 16790 void finishUserStop(UserStartedState uss) { 16791 final int userId = uss.mHandle.getIdentifier(); 16792 boolean stopped; 16793 ArrayList<IStopUserCallback> callbacks; 16794 synchronized (this) { 16795 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16796 if (mStartedUsers.get(userId) != uss) { 16797 stopped = false; 16798 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16799 stopped = false; 16800 } else { 16801 stopped = true; 16802 // User can no longer run. 16803 mStartedUsers.remove(userId); 16804 mUserLru.remove(Integer.valueOf(userId)); 16805 updateStartedUserArrayLocked(); 16806 16807 // Clean up all state and processes associated with the user. 16808 // Kill all the processes for the user. 16809 forceStopUserLocked(userId, "finish user"); 16810 } 16811 } 16812 16813 for (int i=0; i<callbacks.size(); i++) { 16814 try { 16815 if (stopped) callbacks.get(i).userStopped(userId); 16816 else callbacks.get(i).userStopAborted(userId); 16817 } catch (RemoteException e) { 16818 } 16819 } 16820 16821 mStackSupervisor.removeUserLocked(userId); 16822 } 16823 16824 @Override 16825 public UserInfo getCurrentUser() { 16826 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16827 != PackageManager.PERMISSION_GRANTED) && ( 16828 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16829 != PackageManager.PERMISSION_GRANTED)) { 16830 String msg = "Permission Denial: getCurrentUser() from pid=" 16831 + Binder.getCallingPid() 16832 + ", uid=" + Binder.getCallingUid() 16833 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16834 Slog.w(TAG, msg); 16835 throw new SecurityException(msg); 16836 } 16837 synchronized (this) { 16838 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16839 } 16840 } 16841 16842 int getCurrentUserIdLocked() { 16843 return mCurrentUserId; 16844 } 16845 16846 @Override 16847 public boolean isUserRunning(int userId, boolean orStopped) { 16848 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16849 != PackageManager.PERMISSION_GRANTED) { 16850 String msg = "Permission Denial: isUserRunning() from pid=" 16851 + Binder.getCallingPid() 16852 + ", uid=" + Binder.getCallingUid() 16853 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16854 Slog.w(TAG, msg); 16855 throw new SecurityException(msg); 16856 } 16857 synchronized (this) { 16858 return isUserRunningLocked(userId, orStopped); 16859 } 16860 } 16861 16862 boolean isUserRunningLocked(int userId, boolean orStopped) { 16863 UserStartedState state = mStartedUsers.get(userId); 16864 if (state == null) { 16865 return false; 16866 } 16867 if (orStopped) { 16868 return true; 16869 } 16870 return state.mState != UserStartedState.STATE_STOPPING 16871 && state.mState != UserStartedState.STATE_SHUTDOWN; 16872 } 16873 16874 @Override 16875 public int[] getRunningUserIds() { 16876 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16877 != PackageManager.PERMISSION_GRANTED) { 16878 String msg = "Permission Denial: isUserRunning() from pid=" 16879 + Binder.getCallingPid() 16880 + ", uid=" + Binder.getCallingUid() 16881 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16882 Slog.w(TAG, msg); 16883 throw new SecurityException(msg); 16884 } 16885 synchronized (this) { 16886 return mStartedUserArray; 16887 } 16888 } 16889 16890 private void updateStartedUserArrayLocked() { 16891 int num = 0; 16892 for (int i=0; i<mStartedUsers.size(); i++) { 16893 UserStartedState uss = mStartedUsers.valueAt(i); 16894 // This list does not include stopping users. 16895 if (uss.mState != UserStartedState.STATE_STOPPING 16896 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16897 num++; 16898 } 16899 } 16900 mStartedUserArray = new int[num]; 16901 num = 0; 16902 for (int i=0; i<mStartedUsers.size(); i++) { 16903 UserStartedState uss = mStartedUsers.valueAt(i); 16904 if (uss.mState != UserStartedState.STATE_STOPPING 16905 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16906 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16907 num++; 16908 } 16909 } 16910 } 16911 16912 @Override 16913 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16914 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16915 != PackageManager.PERMISSION_GRANTED) { 16916 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16917 + Binder.getCallingPid() 16918 + ", uid=" + Binder.getCallingUid() 16919 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16920 Slog.w(TAG, msg); 16921 throw new SecurityException(msg); 16922 } 16923 16924 mUserSwitchObservers.register(observer); 16925 } 16926 16927 @Override 16928 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16929 mUserSwitchObservers.unregister(observer); 16930 } 16931 16932 private boolean userExists(int userId) { 16933 if (userId == 0) { 16934 return true; 16935 } 16936 UserManagerService ums = getUserManagerLocked(); 16937 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16938 } 16939 16940 int[] getUsersLocked() { 16941 UserManagerService ums = getUserManagerLocked(); 16942 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16943 } 16944 16945 UserManagerService getUserManagerLocked() { 16946 if (mUserManager == null) { 16947 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16948 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16949 } 16950 return mUserManager; 16951 } 16952 16953 private int applyUserId(int uid, int userId) { 16954 return UserHandle.getUid(userId, uid); 16955 } 16956 16957 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16958 if (info == null) return null; 16959 ApplicationInfo newInfo = new ApplicationInfo(info); 16960 newInfo.uid = applyUserId(info.uid, userId); 16961 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16962 + info.packageName; 16963 return newInfo; 16964 } 16965 16966 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16967 if (aInfo == null 16968 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16969 return aInfo; 16970 } 16971 16972 ActivityInfo info = new ActivityInfo(aInfo); 16973 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16974 return info; 16975 } 16976} 16977