ActivityManagerService.java revision 688b5105d665a56e6f2f040f3ca89ca3006801df
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 // Traverse upwards looking for any break between main task activities and 6899 // utility activities. 6900 final ArrayList<ActivityRecord> activities = tr.mActivities; 6901 int activityNdx; 6902 final int numActivities = activities.size(); 6903 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 6904 ++activityNdx) { 6905 final ActivityRecord r = activities.get(activityNdx); 6906 if (r.intent != null && 6907 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 6908 != 0) { 6909 break; 6910 } 6911 } 6912 // Traverse downwards starting below break looking for set label and icon. 6913 for (--activityNdx; activityNdx >= 0; --activityNdx) { 6914 final ActivityRecord r = activities.get(activityNdx); 6915 if (r.activityLabel != null || r.activityIcon != null) { 6916 rti.activityLabel = r.activityLabel; 6917 rti.activityIcon = r.activityIcon; 6918 break; 6919 } 6920 } 6921 6922 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6923 // Check whether this activity is currently available. 6924 try { 6925 if (rti.origActivity != null) { 6926 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6927 == null) { 6928 continue; 6929 } 6930 } else if (rti.baseIntent != null) { 6931 if (pm.queryIntentActivities(rti.baseIntent, 6932 null, 0, userId) == null) { 6933 continue; 6934 } 6935 } 6936 } catch (RemoteException e) { 6937 // Will never happen. 6938 } 6939 } 6940 6941 res.add(rti); 6942 maxNum--; 6943 } 6944 } 6945 return res; 6946 } 6947 } 6948 6949 private TaskRecord recentTaskForIdLocked(int id) { 6950 final int N = mRecentTasks.size(); 6951 for (int i=0; i<N; i++) { 6952 TaskRecord tr = mRecentTasks.get(i); 6953 if (tr.taskId == id) { 6954 return tr; 6955 } 6956 } 6957 return null; 6958 } 6959 6960 @Override 6961 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6962 synchronized (this) { 6963 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6964 "getTaskThumbnails()"); 6965 TaskRecord tr = recentTaskForIdLocked(id); 6966 if (tr != null) { 6967 return tr.getTaskThumbnailsLocked(); 6968 } 6969 } 6970 return null; 6971 } 6972 6973 @Override 6974 public Bitmap getTaskTopThumbnail(int id) { 6975 synchronized (this) { 6976 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6977 "getTaskTopThumbnail()"); 6978 TaskRecord tr = recentTaskForIdLocked(id); 6979 if (tr != null) { 6980 return tr.getTaskTopThumbnailLocked(); 6981 } 6982 } 6983 return null; 6984 } 6985 6986 @Override 6987 public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel, 6988 Bitmap activityIcon) { 6989 synchronized (this) { 6990 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6991 if (r != null) { 6992 r.activityLabel = activityLabel.toString(); 6993 r.activityIcon = activityIcon; 6994 } 6995 } 6996 } 6997 6998 @Override 6999 public boolean removeSubTask(int taskId, int subTaskIndex) { 7000 synchronized (this) { 7001 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7002 "removeSubTask()"); 7003 long ident = Binder.clearCallingIdentity(); 7004 try { 7005 TaskRecord tr = recentTaskForIdLocked(taskId); 7006 if (tr != null) { 7007 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7008 } 7009 return false; 7010 } finally { 7011 Binder.restoreCallingIdentity(ident); 7012 } 7013 } 7014 } 7015 7016 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7017 if (!pr.killedByAm) { 7018 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7019 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7020 pr.processName, pr.setAdj, reason); 7021 pr.killedByAm = true; 7022 Process.killProcessQuiet(pr.pid); 7023 } 7024 } 7025 7026 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7027 tr.disposeThumbnail(); 7028 mRecentTasks.remove(tr); 7029 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7030 Intent baseIntent = new Intent( 7031 tr.intent != null ? tr.intent : tr.affinityIntent); 7032 ComponentName component = baseIntent.getComponent(); 7033 if (component == null) { 7034 Slog.w(TAG, "Now component for base intent of task: " + tr); 7035 return; 7036 } 7037 7038 // Find any running services associated with this app. 7039 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7040 7041 if (killProcesses) { 7042 // Find any running processes associated with this app. 7043 final String pkg = component.getPackageName(); 7044 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7045 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7046 for (int i=0; i<pmap.size(); i++) { 7047 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7048 for (int j=0; j<uids.size(); j++) { 7049 ProcessRecord proc = uids.valueAt(j); 7050 if (proc.userId != tr.userId) { 7051 continue; 7052 } 7053 if (!proc.pkgList.containsKey(pkg)) { 7054 continue; 7055 } 7056 procs.add(proc); 7057 } 7058 } 7059 7060 // Kill the running processes. 7061 for (int i=0; i<procs.size(); i++) { 7062 ProcessRecord pr = procs.get(i); 7063 if (pr == mHomeProcess) { 7064 // Don't kill the home process along with tasks from the same package. 7065 continue; 7066 } 7067 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7068 killUnneededProcessLocked(pr, "remove task"); 7069 } else { 7070 pr.waitingToKill = "remove task"; 7071 } 7072 } 7073 } 7074 } 7075 7076 @Override 7077 public boolean removeTask(int taskId, int flags) { 7078 synchronized (this) { 7079 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7080 "removeTask()"); 7081 long ident = Binder.clearCallingIdentity(); 7082 try { 7083 TaskRecord tr = recentTaskForIdLocked(taskId); 7084 if (tr != null) { 7085 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7086 if (r != null) { 7087 cleanUpRemovedTaskLocked(tr, flags); 7088 return true; 7089 } 7090 if (tr.mActivities.size() == 0) { 7091 // Caller is just removing a recent task that is 7092 // not actively running. That is easy! 7093 cleanUpRemovedTaskLocked(tr, flags); 7094 return true; 7095 } 7096 Slog.w(TAG, "removeTask: task " + taskId 7097 + " does not have activities to remove, " 7098 + " but numActivities=" + tr.numActivities 7099 + ": " + tr); 7100 } 7101 } finally { 7102 Binder.restoreCallingIdentity(ident); 7103 } 7104 } 7105 return false; 7106 } 7107 7108 /** 7109 * TODO: Add mController hook 7110 */ 7111 @Override 7112 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7113 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7114 "moveTaskToFront()"); 7115 7116 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7117 synchronized(this) { 7118 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7119 Binder.getCallingUid(), "Task to front")) { 7120 ActivityOptions.abort(options); 7121 return; 7122 } 7123 final long origId = Binder.clearCallingIdentity(); 7124 try { 7125 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7126 if (task == null) { 7127 return; 7128 } 7129 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7130 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7131 return; 7132 } 7133 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7134 } finally { 7135 Binder.restoreCallingIdentity(origId); 7136 } 7137 ActivityOptions.abort(options); 7138 } 7139 } 7140 7141 @Override 7142 public void moveTaskToBack(int taskId) { 7143 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7144 "moveTaskToBack()"); 7145 7146 synchronized(this) { 7147 TaskRecord tr = recentTaskForIdLocked(taskId); 7148 if (tr != null) { 7149 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7150 ActivityStack stack = tr.stack; 7151 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7152 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7153 Binder.getCallingUid(), "Task to back")) { 7154 return; 7155 } 7156 } 7157 final long origId = Binder.clearCallingIdentity(); 7158 try { 7159 stack.moveTaskToBackLocked(taskId, null); 7160 } finally { 7161 Binder.restoreCallingIdentity(origId); 7162 } 7163 } 7164 } 7165 } 7166 7167 /** 7168 * Moves an activity, and all of the other activities within the same task, to the bottom 7169 * of the history stack. The activity's order within the task is unchanged. 7170 * 7171 * @param token A reference to the activity we wish to move 7172 * @param nonRoot If false then this only works if the activity is the root 7173 * of a task; if true it will work for any activity in a task. 7174 * @return Returns true if the move completed, false if not. 7175 */ 7176 @Override 7177 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7178 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7179 synchronized(this) { 7180 final long origId = Binder.clearCallingIdentity(); 7181 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7182 if (taskId >= 0) { 7183 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7184 } 7185 Binder.restoreCallingIdentity(origId); 7186 } 7187 return false; 7188 } 7189 7190 @Override 7191 public void moveTaskBackwards(int task) { 7192 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7193 "moveTaskBackwards()"); 7194 7195 synchronized(this) { 7196 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7197 Binder.getCallingUid(), "Task backwards")) { 7198 return; 7199 } 7200 final long origId = Binder.clearCallingIdentity(); 7201 moveTaskBackwardsLocked(task); 7202 Binder.restoreCallingIdentity(origId); 7203 } 7204 } 7205 7206 private final void moveTaskBackwardsLocked(int task) { 7207 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7208 } 7209 7210 @Override 7211 public IBinder getHomeActivityToken() throws RemoteException { 7212 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7213 "getHomeActivityToken()"); 7214 synchronized (this) { 7215 return mStackSupervisor.getHomeActivityToken(); 7216 } 7217 } 7218 7219 @Override 7220 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7221 IActivityContainerCallback callback) throws RemoteException { 7222 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7223 "createActivityContainer()"); 7224 synchronized (this) { 7225 if (parentActivityToken == null) { 7226 throw new IllegalArgumentException("parent token must not be null"); 7227 } 7228 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7229 if (r == null) { 7230 return null; 7231 } 7232 return mStackSupervisor.createActivityContainer(r, callback); 7233 } 7234 } 7235 7236 @Override 7237 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7238 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7239 "deleteActivityContainer()"); 7240 synchronized (this) { 7241 mStackSupervisor.deleteActivityContainer(container); 7242 } 7243 } 7244 7245 @Override 7246 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7247 throws RemoteException { 7248 synchronized (this) { 7249 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7250 if (stack != null) { 7251 return stack.mActivityContainer; 7252 } 7253 return null; 7254 } 7255 } 7256 7257 @Override 7258 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7259 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7260 "moveTaskToStack()"); 7261 if (stackId == HOME_STACK_ID) { 7262 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7263 new RuntimeException("here").fillInStackTrace()); 7264 } 7265 synchronized (this) { 7266 long ident = Binder.clearCallingIdentity(); 7267 try { 7268 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7269 + stackId + " toTop=" + toTop); 7270 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7271 } finally { 7272 Binder.restoreCallingIdentity(ident); 7273 } 7274 } 7275 } 7276 7277 @Override 7278 public void resizeStack(int stackBoxId, Rect bounds) { 7279 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7280 "resizeStackBox()"); 7281 long ident = Binder.clearCallingIdentity(); 7282 try { 7283 mWindowManager.resizeStack(stackBoxId, bounds); 7284 } finally { 7285 Binder.restoreCallingIdentity(ident); 7286 } 7287 } 7288 7289 @Override 7290 public List<StackInfo> getAllStackInfos() { 7291 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7292 "getAllStackInfos()"); 7293 long ident = Binder.clearCallingIdentity(); 7294 try { 7295 synchronized (this) { 7296 return mStackSupervisor.getAllStackInfosLocked(); 7297 } 7298 } finally { 7299 Binder.restoreCallingIdentity(ident); 7300 } 7301 } 7302 7303 @Override 7304 public StackInfo getStackInfo(int stackId) { 7305 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7306 "getStackInfo()"); 7307 long ident = Binder.clearCallingIdentity(); 7308 try { 7309 synchronized (this) { 7310 return mStackSupervisor.getStackInfoLocked(stackId); 7311 } 7312 } finally { 7313 Binder.restoreCallingIdentity(ident); 7314 } 7315 } 7316 7317 @Override 7318 public boolean isInHomeStack(int taskId) { 7319 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7320 "getStackInfo()"); 7321 long ident = Binder.clearCallingIdentity(); 7322 try { 7323 synchronized (this) { 7324 TaskRecord tr = recentTaskForIdLocked(taskId); 7325 if (tr != null) { 7326 return tr.stack.isHomeStack(); 7327 } 7328 } 7329 } finally { 7330 Binder.restoreCallingIdentity(ident); 7331 } 7332 return false; 7333 } 7334 7335 @Override 7336 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7337 synchronized(this) { 7338 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7339 } 7340 } 7341 7342 private boolean isLockTaskAuthorized(ComponentName name) { 7343// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7344// "startLockTaskMode()"); 7345// DevicePolicyManager dpm = (DevicePolicyManager) 7346// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7347// return dpm != null && dpm.isLockTaskPermitted(name); 7348 return true; 7349 } 7350 7351 private void startLockTaskMode(TaskRecord task) { 7352 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7353 return; 7354 } 7355 long ident = Binder.clearCallingIdentity(); 7356 try { 7357 synchronized (this) { 7358 // Since we lost lock on task, make sure it is still there. 7359 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7360 if (task != null) { 7361 mStackSupervisor.setLockTaskModeLocked(task); 7362 } 7363 } 7364 } finally { 7365 Binder.restoreCallingIdentity(ident); 7366 } 7367 } 7368 7369 @Override 7370 public void startLockTaskMode(int taskId) { 7371 long ident = Binder.clearCallingIdentity(); 7372 try { 7373 final TaskRecord task; 7374 synchronized (this) { 7375 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7376 } 7377 if (task != null) { 7378 startLockTaskMode(task); 7379 } 7380 } finally { 7381 Binder.restoreCallingIdentity(ident); 7382 } 7383 } 7384 7385 @Override 7386 public void startLockTaskMode(IBinder token) { 7387 long ident = Binder.clearCallingIdentity(); 7388 try { 7389 final TaskRecord task; 7390 synchronized (this) { 7391 final ActivityRecord r = ActivityRecord.forToken(token); 7392 if (r == null) { 7393 return; 7394 } 7395 task = r.task; 7396 } 7397 if (task != null) { 7398 startLockTaskMode(task); 7399 } 7400 } finally { 7401 Binder.restoreCallingIdentity(ident); 7402 } 7403 } 7404 7405 @Override 7406 public void stopLockTaskMode() { 7407// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7408// "stopLockTaskMode()"); 7409 synchronized (this) { 7410 mStackSupervisor.setLockTaskModeLocked(null); 7411 } 7412 } 7413 7414 @Override 7415 public boolean isInLockTaskMode() { 7416 synchronized (this) { 7417 return mStackSupervisor.isInLockTaskMode(); 7418 } 7419 } 7420 7421 // ========================================================= 7422 // THUMBNAILS 7423 // ========================================================= 7424 7425 public void reportThumbnail(IBinder token, 7426 Bitmap thumbnail, CharSequence description) { 7427 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7428 final long origId = Binder.clearCallingIdentity(); 7429 sendPendingThumbnail(null, token, thumbnail, description, true); 7430 Binder.restoreCallingIdentity(origId); 7431 } 7432 7433 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7434 Bitmap thumbnail, CharSequence description, boolean always) { 7435 TaskRecord task; 7436 ArrayList<PendingThumbnailsRecord> receivers = null; 7437 7438 //System.out.println("Send pending thumbnail: " + r); 7439 7440 synchronized(this) { 7441 if (r == null) { 7442 r = ActivityRecord.isInStackLocked(token); 7443 if (r == null) { 7444 return; 7445 } 7446 } 7447 if (thumbnail == null && r.thumbHolder != null) { 7448 thumbnail = r.thumbHolder.lastThumbnail; 7449 description = r.thumbHolder.lastDescription; 7450 } 7451 if (thumbnail == null && !always) { 7452 // If there is no thumbnail, and this entry is not actually 7453 // going away, then abort for now and pick up the next 7454 // thumbnail we get. 7455 return; 7456 } 7457 task = r.task; 7458 7459 int N = mPendingThumbnails.size(); 7460 int i=0; 7461 while (i<N) { 7462 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7463 //System.out.println("Looking in " + pr.pendingRecords); 7464 if (pr.pendingRecords.remove(r)) { 7465 if (receivers == null) { 7466 receivers = new ArrayList<PendingThumbnailsRecord>(); 7467 } 7468 receivers.add(pr); 7469 if (pr.pendingRecords.size() == 0) { 7470 pr.finished = true; 7471 mPendingThumbnails.remove(i); 7472 N--; 7473 continue; 7474 } 7475 } 7476 i++; 7477 } 7478 } 7479 7480 if (receivers != null) { 7481 final int N = receivers.size(); 7482 for (int i=0; i<N; i++) { 7483 try { 7484 PendingThumbnailsRecord pr = receivers.get(i); 7485 pr.receiver.newThumbnail( 7486 task != null ? task.taskId : -1, thumbnail, description); 7487 if (pr.finished) { 7488 pr.receiver.finished(); 7489 } 7490 } catch (Exception e) { 7491 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7492 } 7493 } 7494 } 7495 } 7496 7497 // ========================================================= 7498 // CONTENT PROVIDERS 7499 // ========================================================= 7500 7501 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7502 List<ProviderInfo> providers = null; 7503 try { 7504 providers = AppGlobals.getPackageManager(). 7505 queryContentProviders(app.processName, app.uid, 7506 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7507 } catch (RemoteException ex) { 7508 } 7509 if (DEBUG_MU) 7510 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7511 int userId = app.userId; 7512 if (providers != null) { 7513 int N = providers.size(); 7514 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7515 for (int i=0; i<N; i++) { 7516 ProviderInfo cpi = 7517 (ProviderInfo)providers.get(i); 7518 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7519 cpi.name, cpi.flags); 7520 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7521 // This is a singleton provider, but a user besides the 7522 // default user is asking to initialize a process it runs 7523 // in... well, no, it doesn't actually run in this process, 7524 // it runs in the process of the default user. Get rid of it. 7525 providers.remove(i); 7526 N--; 7527 i--; 7528 continue; 7529 } 7530 7531 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7532 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7533 if (cpr == null) { 7534 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7535 mProviderMap.putProviderByClass(comp, cpr); 7536 } 7537 if (DEBUG_MU) 7538 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7539 app.pubProviders.put(cpi.name, cpr); 7540 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7541 // Don't add this if it is a platform component that is marked 7542 // to run in multiple processes, because this is actually 7543 // part of the framework so doesn't make sense to track as a 7544 // separate apk in the process. 7545 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7546 } 7547 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7548 } 7549 } 7550 return providers; 7551 } 7552 7553 /** 7554 * Check if {@link ProcessRecord} has a possible chance at accessing the 7555 * given {@link ProviderInfo}. Final permission checking is always done 7556 * in {@link ContentProvider}. 7557 */ 7558 private final String checkContentProviderPermissionLocked( 7559 ProviderInfo cpi, ProcessRecord r) { 7560 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7561 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7562 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7563 cpi.applicationInfo.uid, cpi.exported) 7564 == PackageManager.PERMISSION_GRANTED) { 7565 return null; 7566 } 7567 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7568 cpi.applicationInfo.uid, cpi.exported) 7569 == PackageManager.PERMISSION_GRANTED) { 7570 return null; 7571 } 7572 7573 PathPermission[] pps = cpi.pathPermissions; 7574 if (pps != null) { 7575 int i = pps.length; 7576 while (i > 0) { 7577 i--; 7578 PathPermission pp = pps[i]; 7579 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7580 cpi.applicationInfo.uid, cpi.exported) 7581 == PackageManager.PERMISSION_GRANTED) { 7582 return null; 7583 } 7584 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7585 cpi.applicationInfo.uid, cpi.exported) 7586 == PackageManager.PERMISSION_GRANTED) { 7587 return null; 7588 } 7589 } 7590 } 7591 7592 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7593 if (perms != null) { 7594 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7595 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7596 return null; 7597 } 7598 } 7599 } 7600 7601 String msg; 7602 if (!cpi.exported) { 7603 msg = "Permission Denial: opening provider " + cpi.name 7604 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7605 + ", uid=" + callingUid + ") that is not exported from uid " 7606 + cpi.applicationInfo.uid; 7607 } else { 7608 msg = "Permission Denial: opening provider " + cpi.name 7609 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7610 + ", uid=" + callingUid + ") requires " 7611 + cpi.readPermission + " or " + cpi.writePermission; 7612 } 7613 Slog.w(TAG, msg); 7614 return msg; 7615 } 7616 7617 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7618 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7619 if (r != null) { 7620 for (int i=0; i<r.conProviders.size(); i++) { 7621 ContentProviderConnection conn = r.conProviders.get(i); 7622 if (conn.provider == cpr) { 7623 if (DEBUG_PROVIDER) Slog.v(TAG, 7624 "Adding provider requested by " 7625 + r.processName + " from process " 7626 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7627 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7628 if (stable) { 7629 conn.stableCount++; 7630 conn.numStableIncs++; 7631 } else { 7632 conn.unstableCount++; 7633 conn.numUnstableIncs++; 7634 } 7635 return conn; 7636 } 7637 } 7638 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7639 if (stable) { 7640 conn.stableCount = 1; 7641 conn.numStableIncs = 1; 7642 } else { 7643 conn.unstableCount = 1; 7644 conn.numUnstableIncs = 1; 7645 } 7646 cpr.connections.add(conn); 7647 r.conProviders.add(conn); 7648 return conn; 7649 } 7650 cpr.addExternalProcessHandleLocked(externalProcessToken); 7651 return null; 7652 } 7653 7654 boolean decProviderCountLocked(ContentProviderConnection conn, 7655 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7656 if (conn != null) { 7657 cpr = conn.provider; 7658 if (DEBUG_PROVIDER) Slog.v(TAG, 7659 "Removing provider requested by " 7660 + conn.client.processName + " from process " 7661 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7662 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7663 if (stable) { 7664 conn.stableCount--; 7665 } else { 7666 conn.unstableCount--; 7667 } 7668 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7669 cpr.connections.remove(conn); 7670 conn.client.conProviders.remove(conn); 7671 return true; 7672 } 7673 return false; 7674 } 7675 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7676 return false; 7677 } 7678 7679 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7680 String name, IBinder token, boolean stable, int userId) { 7681 ContentProviderRecord cpr; 7682 ContentProviderConnection conn = null; 7683 ProviderInfo cpi = null; 7684 7685 synchronized(this) { 7686 ProcessRecord r = null; 7687 if (caller != null) { 7688 r = getRecordForAppLocked(caller); 7689 if (r == null) { 7690 throw new SecurityException( 7691 "Unable to find app for caller " + caller 7692 + " (pid=" + Binder.getCallingPid() 7693 + ") when getting content provider " + name); 7694 } 7695 } 7696 7697 // First check if this content provider has been published... 7698 cpr = mProviderMap.getProviderByName(name, userId); 7699 boolean providerRunning = cpr != null; 7700 if (providerRunning) { 7701 cpi = cpr.info; 7702 String msg; 7703 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7704 throw new SecurityException(msg); 7705 } 7706 7707 if (r != null && cpr.canRunHere(r)) { 7708 // This provider has been published or is in the process 7709 // of being published... but it is also allowed to run 7710 // in the caller's process, so don't make a connection 7711 // and just let the caller instantiate its own instance. 7712 ContentProviderHolder holder = cpr.newHolder(null); 7713 // don't give caller the provider object, it needs 7714 // to make its own. 7715 holder.provider = null; 7716 return holder; 7717 } 7718 7719 final long origId = Binder.clearCallingIdentity(); 7720 7721 // In this case the provider instance already exists, so we can 7722 // return it right away. 7723 conn = incProviderCountLocked(r, cpr, token, stable); 7724 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7725 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7726 // If this is a perceptible app accessing the provider, 7727 // make sure to count it as being accessed and thus 7728 // back up on the LRU list. This is good because 7729 // content providers are often expensive to start. 7730 updateLruProcessLocked(cpr.proc, false, null); 7731 } 7732 } 7733 7734 if (cpr.proc != null) { 7735 if (false) { 7736 if (cpr.name.flattenToShortString().equals( 7737 "com.android.providers.calendar/.CalendarProvider2")) { 7738 Slog.v(TAG, "****************** KILLING " 7739 + cpr.name.flattenToShortString()); 7740 Process.killProcess(cpr.proc.pid); 7741 } 7742 } 7743 boolean success = updateOomAdjLocked(cpr.proc); 7744 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7745 // NOTE: there is still a race here where a signal could be 7746 // pending on the process even though we managed to update its 7747 // adj level. Not sure what to do about this, but at least 7748 // the race is now smaller. 7749 if (!success) { 7750 // Uh oh... it looks like the provider's process 7751 // has been killed on us. We need to wait for a new 7752 // process to be started, and make sure its death 7753 // doesn't kill our process. 7754 Slog.i(TAG, 7755 "Existing provider " + cpr.name.flattenToShortString() 7756 + " is crashing; detaching " + r); 7757 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7758 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7759 if (!lastRef) { 7760 // This wasn't the last ref our process had on 7761 // the provider... we have now been killed, bail. 7762 return null; 7763 } 7764 providerRunning = false; 7765 conn = null; 7766 } 7767 } 7768 7769 Binder.restoreCallingIdentity(origId); 7770 } 7771 7772 boolean singleton; 7773 if (!providerRunning) { 7774 try { 7775 cpi = AppGlobals.getPackageManager(). 7776 resolveContentProvider(name, 7777 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7778 } catch (RemoteException ex) { 7779 } 7780 if (cpi == null) { 7781 return null; 7782 } 7783 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7784 cpi.name, cpi.flags); 7785 if (singleton) { 7786 userId = 0; 7787 } 7788 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7789 7790 String msg; 7791 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7792 throw new SecurityException(msg); 7793 } 7794 7795 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7796 && !cpi.processName.equals("system")) { 7797 // If this content provider does not run in the system 7798 // process, and the system is not yet ready to run other 7799 // processes, then fail fast instead of hanging. 7800 throw new IllegalArgumentException( 7801 "Attempt to launch content provider before system ready"); 7802 } 7803 7804 // Make sure that the user who owns this provider is started. If not, 7805 // we don't want to allow it to run. 7806 if (mStartedUsers.get(userId) == null) { 7807 Slog.w(TAG, "Unable to launch app " 7808 + cpi.applicationInfo.packageName + "/" 7809 + cpi.applicationInfo.uid + " for provider " 7810 + name + ": user " + userId + " is stopped"); 7811 return null; 7812 } 7813 7814 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7815 cpr = mProviderMap.getProviderByClass(comp, userId); 7816 final boolean firstClass = cpr == null; 7817 if (firstClass) { 7818 try { 7819 ApplicationInfo ai = 7820 AppGlobals.getPackageManager(). 7821 getApplicationInfo( 7822 cpi.applicationInfo.packageName, 7823 STOCK_PM_FLAGS, userId); 7824 if (ai == null) { 7825 Slog.w(TAG, "No package info for content provider " 7826 + cpi.name); 7827 return null; 7828 } 7829 ai = getAppInfoForUser(ai, userId); 7830 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7831 } catch (RemoteException ex) { 7832 // pm is in same process, this will never happen. 7833 } 7834 } 7835 7836 if (r != null && cpr.canRunHere(r)) { 7837 // If this is a multiprocess provider, then just return its 7838 // info and allow the caller to instantiate it. Only do 7839 // this if the provider is the same user as the caller's 7840 // process, or can run as root (so can be in any process). 7841 return cpr.newHolder(null); 7842 } 7843 7844 if (DEBUG_PROVIDER) { 7845 RuntimeException e = new RuntimeException("here"); 7846 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7847 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7848 } 7849 7850 // This is single process, and our app is now connecting to it. 7851 // See if we are already in the process of launching this 7852 // provider. 7853 final int N = mLaunchingProviders.size(); 7854 int i; 7855 for (i=0; i<N; i++) { 7856 if (mLaunchingProviders.get(i) == cpr) { 7857 break; 7858 } 7859 } 7860 7861 // If the provider is not already being launched, then get it 7862 // started. 7863 if (i >= N) { 7864 final long origId = Binder.clearCallingIdentity(); 7865 7866 try { 7867 // Content provider is now in use, its package can't be stopped. 7868 try { 7869 AppGlobals.getPackageManager().setPackageStoppedState( 7870 cpr.appInfo.packageName, false, userId); 7871 } catch (RemoteException e) { 7872 } catch (IllegalArgumentException e) { 7873 Slog.w(TAG, "Failed trying to unstop package " 7874 + cpr.appInfo.packageName + ": " + e); 7875 } 7876 7877 // Use existing process if already started 7878 ProcessRecord proc = getProcessRecordLocked( 7879 cpi.processName, cpr.appInfo.uid, false); 7880 if (proc != null && proc.thread != null) { 7881 if (DEBUG_PROVIDER) { 7882 Slog.d(TAG, "Installing in existing process " + proc); 7883 } 7884 proc.pubProviders.put(cpi.name, cpr); 7885 try { 7886 proc.thread.scheduleInstallProvider(cpi); 7887 } catch (RemoteException e) { 7888 } 7889 } else { 7890 proc = startProcessLocked(cpi.processName, 7891 cpr.appInfo, false, 0, "content provider", 7892 new ComponentName(cpi.applicationInfo.packageName, 7893 cpi.name), false, false, false); 7894 if (proc == null) { 7895 Slog.w(TAG, "Unable to launch app " 7896 + cpi.applicationInfo.packageName + "/" 7897 + cpi.applicationInfo.uid + " for provider " 7898 + name + ": process is bad"); 7899 return null; 7900 } 7901 } 7902 cpr.launchingApp = proc; 7903 mLaunchingProviders.add(cpr); 7904 } finally { 7905 Binder.restoreCallingIdentity(origId); 7906 } 7907 } 7908 7909 // Make sure the provider is published (the same provider class 7910 // may be published under multiple names). 7911 if (firstClass) { 7912 mProviderMap.putProviderByClass(comp, cpr); 7913 } 7914 7915 mProviderMap.putProviderByName(name, cpr); 7916 conn = incProviderCountLocked(r, cpr, token, stable); 7917 if (conn != null) { 7918 conn.waiting = true; 7919 } 7920 } 7921 } 7922 7923 // Wait for the provider to be published... 7924 synchronized (cpr) { 7925 while (cpr.provider == null) { 7926 if (cpr.launchingApp == null) { 7927 Slog.w(TAG, "Unable to launch app " 7928 + cpi.applicationInfo.packageName + "/" 7929 + cpi.applicationInfo.uid + " for provider " 7930 + name + ": launching app became null"); 7931 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7932 UserHandle.getUserId(cpi.applicationInfo.uid), 7933 cpi.applicationInfo.packageName, 7934 cpi.applicationInfo.uid, name); 7935 return null; 7936 } 7937 try { 7938 if (DEBUG_MU) { 7939 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7940 + cpr.launchingApp); 7941 } 7942 if (conn != null) { 7943 conn.waiting = true; 7944 } 7945 cpr.wait(); 7946 } catch (InterruptedException ex) { 7947 } finally { 7948 if (conn != null) { 7949 conn.waiting = false; 7950 } 7951 } 7952 } 7953 } 7954 return cpr != null ? cpr.newHolder(conn) : null; 7955 } 7956 7957 public final ContentProviderHolder getContentProvider( 7958 IApplicationThread caller, String name, int userId, boolean stable) { 7959 enforceNotIsolatedCaller("getContentProvider"); 7960 if (caller == null) { 7961 String msg = "null IApplicationThread when getting content provider " 7962 + name; 7963 Slog.w(TAG, msg); 7964 throw new SecurityException(msg); 7965 } 7966 7967 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7968 false, true, "getContentProvider", null); 7969 return getContentProviderImpl(caller, name, null, stable, userId); 7970 } 7971 7972 public ContentProviderHolder getContentProviderExternal( 7973 String name, int userId, IBinder token) { 7974 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7975 "Do not have permission in call getContentProviderExternal()"); 7976 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7977 false, true, "getContentProvider", null); 7978 return getContentProviderExternalUnchecked(name, token, userId); 7979 } 7980 7981 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7982 IBinder token, int userId) { 7983 return getContentProviderImpl(null, name, token, true, userId); 7984 } 7985 7986 /** 7987 * Drop a content provider from a ProcessRecord's bookkeeping 7988 */ 7989 public void removeContentProvider(IBinder connection, boolean stable) { 7990 enforceNotIsolatedCaller("removeContentProvider"); 7991 long ident = Binder.clearCallingIdentity(); 7992 try { 7993 synchronized (this) { 7994 ContentProviderConnection conn; 7995 try { 7996 conn = (ContentProviderConnection)connection; 7997 } catch (ClassCastException e) { 7998 String msg ="removeContentProvider: " + connection 7999 + " not a ContentProviderConnection"; 8000 Slog.w(TAG, msg); 8001 throw new IllegalArgumentException(msg); 8002 } 8003 if (conn == null) { 8004 throw new NullPointerException("connection is null"); 8005 } 8006 if (decProviderCountLocked(conn, null, null, stable)) { 8007 updateOomAdjLocked(); 8008 } 8009 } 8010 } finally { 8011 Binder.restoreCallingIdentity(ident); 8012 } 8013 } 8014 8015 public void removeContentProviderExternal(String name, IBinder token) { 8016 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8017 "Do not have permission in call removeContentProviderExternal()"); 8018 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8019 } 8020 8021 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8022 synchronized (this) { 8023 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8024 if(cpr == null) { 8025 //remove from mProvidersByClass 8026 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8027 return; 8028 } 8029 8030 //update content provider record entry info 8031 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8032 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8033 if (localCpr.hasExternalProcessHandles()) { 8034 if (localCpr.removeExternalProcessHandleLocked(token)) { 8035 updateOomAdjLocked(); 8036 } else { 8037 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8038 + " with no external reference for token: " 8039 + token + "."); 8040 } 8041 } else { 8042 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8043 + " with no external references."); 8044 } 8045 } 8046 } 8047 8048 public final void publishContentProviders(IApplicationThread caller, 8049 List<ContentProviderHolder> providers) { 8050 if (providers == null) { 8051 return; 8052 } 8053 8054 enforceNotIsolatedCaller("publishContentProviders"); 8055 synchronized (this) { 8056 final ProcessRecord r = getRecordForAppLocked(caller); 8057 if (DEBUG_MU) 8058 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8059 if (r == null) { 8060 throw new SecurityException( 8061 "Unable to find app for caller " + caller 8062 + " (pid=" + Binder.getCallingPid() 8063 + ") when publishing content providers"); 8064 } 8065 8066 final long origId = Binder.clearCallingIdentity(); 8067 8068 final int N = providers.size(); 8069 for (int i=0; i<N; i++) { 8070 ContentProviderHolder src = providers.get(i); 8071 if (src == null || src.info == null || src.provider == null) { 8072 continue; 8073 } 8074 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8075 if (DEBUG_MU) 8076 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8077 if (dst != null) { 8078 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8079 mProviderMap.putProviderByClass(comp, dst); 8080 String names[] = dst.info.authority.split(";"); 8081 for (int j = 0; j < names.length; j++) { 8082 mProviderMap.putProviderByName(names[j], dst); 8083 } 8084 8085 int NL = mLaunchingProviders.size(); 8086 int j; 8087 for (j=0; j<NL; j++) { 8088 if (mLaunchingProviders.get(j) == dst) { 8089 mLaunchingProviders.remove(j); 8090 j--; 8091 NL--; 8092 } 8093 } 8094 synchronized (dst) { 8095 dst.provider = src.provider; 8096 dst.proc = r; 8097 dst.notifyAll(); 8098 } 8099 updateOomAdjLocked(r); 8100 } 8101 } 8102 8103 Binder.restoreCallingIdentity(origId); 8104 } 8105 } 8106 8107 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8108 ContentProviderConnection conn; 8109 try { 8110 conn = (ContentProviderConnection)connection; 8111 } catch (ClassCastException e) { 8112 String msg ="refContentProvider: " + connection 8113 + " not a ContentProviderConnection"; 8114 Slog.w(TAG, msg); 8115 throw new IllegalArgumentException(msg); 8116 } 8117 if (conn == null) { 8118 throw new NullPointerException("connection is null"); 8119 } 8120 8121 synchronized (this) { 8122 if (stable > 0) { 8123 conn.numStableIncs += stable; 8124 } 8125 stable = conn.stableCount + stable; 8126 if (stable < 0) { 8127 throw new IllegalStateException("stableCount < 0: " + stable); 8128 } 8129 8130 if (unstable > 0) { 8131 conn.numUnstableIncs += unstable; 8132 } 8133 unstable = conn.unstableCount + unstable; 8134 if (unstable < 0) { 8135 throw new IllegalStateException("unstableCount < 0: " + unstable); 8136 } 8137 8138 if ((stable+unstable) <= 0) { 8139 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8140 + stable + " unstable=" + unstable); 8141 } 8142 conn.stableCount = stable; 8143 conn.unstableCount = unstable; 8144 return !conn.dead; 8145 } 8146 } 8147 8148 public void unstableProviderDied(IBinder connection) { 8149 ContentProviderConnection conn; 8150 try { 8151 conn = (ContentProviderConnection)connection; 8152 } catch (ClassCastException e) { 8153 String msg ="refContentProvider: " + connection 8154 + " not a ContentProviderConnection"; 8155 Slog.w(TAG, msg); 8156 throw new IllegalArgumentException(msg); 8157 } 8158 if (conn == null) { 8159 throw new NullPointerException("connection is null"); 8160 } 8161 8162 // Safely retrieve the content provider associated with the connection. 8163 IContentProvider provider; 8164 synchronized (this) { 8165 provider = conn.provider.provider; 8166 } 8167 8168 if (provider == null) { 8169 // Um, yeah, we're way ahead of you. 8170 return; 8171 } 8172 8173 // Make sure the caller is being honest with us. 8174 if (provider.asBinder().pingBinder()) { 8175 // Er, no, still looks good to us. 8176 synchronized (this) { 8177 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8178 + " says " + conn + " died, but we don't agree"); 8179 return; 8180 } 8181 } 8182 8183 // Well look at that! It's dead! 8184 synchronized (this) { 8185 if (conn.provider.provider != provider) { 8186 // But something changed... good enough. 8187 return; 8188 } 8189 8190 ProcessRecord proc = conn.provider.proc; 8191 if (proc == null || proc.thread == null) { 8192 // Seems like the process is already cleaned up. 8193 return; 8194 } 8195 8196 // As far as we're concerned, this is just like receiving a 8197 // death notification... just a bit prematurely. 8198 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8199 + ") early provider death"); 8200 final long ident = Binder.clearCallingIdentity(); 8201 try { 8202 appDiedLocked(proc, proc.pid, proc.thread); 8203 } finally { 8204 Binder.restoreCallingIdentity(ident); 8205 } 8206 } 8207 } 8208 8209 @Override 8210 public void appNotRespondingViaProvider(IBinder connection) { 8211 enforceCallingPermission( 8212 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8213 8214 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8215 if (conn == null) { 8216 Slog.w(TAG, "ContentProviderConnection is null"); 8217 return; 8218 } 8219 8220 final ProcessRecord host = conn.provider.proc; 8221 if (host == null) { 8222 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8223 return; 8224 } 8225 8226 final long token = Binder.clearCallingIdentity(); 8227 try { 8228 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8229 } finally { 8230 Binder.restoreCallingIdentity(token); 8231 } 8232 } 8233 8234 public final void installSystemProviders() { 8235 List<ProviderInfo> providers; 8236 synchronized (this) { 8237 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8238 providers = generateApplicationProvidersLocked(app); 8239 if (providers != null) { 8240 for (int i=providers.size()-1; i>=0; i--) { 8241 ProviderInfo pi = (ProviderInfo)providers.get(i); 8242 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8243 Slog.w(TAG, "Not installing system proc provider " + pi.name 8244 + ": not system .apk"); 8245 providers.remove(i); 8246 } 8247 } 8248 } 8249 } 8250 if (providers != null) { 8251 mSystemThread.installSystemProviders(providers); 8252 } 8253 8254 mCoreSettingsObserver = new CoreSettingsObserver(this); 8255 8256 mUsageStatsService.monitorPackages(); 8257 } 8258 8259 /** 8260 * Allows app to retrieve the MIME type of a URI without having permission 8261 * to access its content provider. 8262 * 8263 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8264 * 8265 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8266 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8267 */ 8268 public String getProviderMimeType(Uri uri, int userId) { 8269 enforceNotIsolatedCaller("getProviderMimeType"); 8270 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8271 userId, false, true, "getProviderMimeType", null); 8272 final String name = uri.getAuthority(); 8273 final long ident = Binder.clearCallingIdentity(); 8274 ContentProviderHolder holder = null; 8275 8276 try { 8277 holder = getContentProviderExternalUnchecked(name, null, userId); 8278 if (holder != null) { 8279 return holder.provider.getType(uri); 8280 } 8281 } catch (RemoteException e) { 8282 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8283 return null; 8284 } finally { 8285 if (holder != null) { 8286 removeContentProviderExternalUnchecked(name, null, userId); 8287 } 8288 Binder.restoreCallingIdentity(ident); 8289 } 8290 8291 return null; 8292 } 8293 8294 // ========================================================= 8295 // GLOBAL MANAGEMENT 8296 // ========================================================= 8297 8298 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8299 boolean isolated) { 8300 String proc = customProcess != null ? customProcess : info.processName; 8301 BatteryStatsImpl.Uid.Proc ps = null; 8302 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8303 int uid = info.uid; 8304 if (isolated) { 8305 int userId = UserHandle.getUserId(uid); 8306 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8307 while (true) { 8308 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8309 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8310 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8311 } 8312 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8313 mNextIsolatedProcessUid++; 8314 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8315 // No process for this uid, use it. 8316 break; 8317 } 8318 stepsLeft--; 8319 if (stepsLeft <= 0) { 8320 return null; 8321 } 8322 } 8323 } 8324 return new ProcessRecord(stats, info, proc, uid); 8325 } 8326 8327 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8328 ProcessRecord app; 8329 if (!isolated) { 8330 app = getProcessRecordLocked(info.processName, info.uid, true); 8331 } else { 8332 app = null; 8333 } 8334 8335 if (app == null) { 8336 app = newProcessRecordLocked(info, null, isolated); 8337 mProcessNames.put(info.processName, app.uid, app); 8338 if (isolated) { 8339 mIsolatedProcesses.put(app.uid, app); 8340 } 8341 updateLruProcessLocked(app, false, null); 8342 updateOomAdjLocked(); 8343 } 8344 8345 // This package really, really can not be stopped. 8346 try { 8347 AppGlobals.getPackageManager().setPackageStoppedState( 8348 info.packageName, false, UserHandle.getUserId(app.uid)); 8349 } catch (RemoteException e) { 8350 } catch (IllegalArgumentException e) { 8351 Slog.w(TAG, "Failed trying to unstop package " 8352 + info.packageName + ": " + e); 8353 } 8354 8355 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8356 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8357 app.persistent = true; 8358 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8359 } 8360 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8361 mPersistentStartingProcesses.add(app); 8362 startProcessLocked(app, "added application", app.processName); 8363 } 8364 8365 return app; 8366 } 8367 8368 public void unhandledBack() { 8369 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8370 "unhandledBack()"); 8371 8372 synchronized(this) { 8373 final long origId = Binder.clearCallingIdentity(); 8374 try { 8375 getFocusedStack().unhandledBackLocked(); 8376 } finally { 8377 Binder.restoreCallingIdentity(origId); 8378 } 8379 } 8380 } 8381 8382 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8383 enforceNotIsolatedCaller("openContentUri"); 8384 final int userId = UserHandle.getCallingUserId(); 8385 String name = uri.getAuthority(); 8386 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8387 ParcelFileDescriptor pfd = null; 8388 if (cph != null) { 8389 // We record the binder invoker's uid in thread-local storage before 8390 // going to the content provider to open the file. Later, in the code 8391 // that handles all permissions checks, we look for this uid and use 8392 // that rather than the Activity Manager's own uid. The effect is that 8393 // we do the check against the caller's permissions even though it looks 8394 // to the content provider like the Activity Manager itself is making 8395 // the request. 8396 sCallerIdentity.set(new Identity( 8397 Binder.getCallingPid(), Binder.getCallingUid())); 8398 try { 8399 pfd = cph.provider.openFile(null, uri, "r", null); 8400 } catch (FileNotFoundException e) { 8401 // do nothing; pfd will be returned null 8402 } finally { 8403 // Ensure that whatever happens, we clean up the identity state 8404 sCallerIdentity.remove(); 8405 } 8406 8407 // We've got the fd now, so we're done with the provider. 8408 removeContentProviderExternalUnchecked(name, null, userId); 8409 } else { 8410 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8411 } 8412 return pfd; 8413 } 8414 8415 // Actually is sleeping or shutting down or whatever else in the future 8416 // is an inactive state. 8417 public boolean isSleepingOrShuttingDown() { 8418 return mSleeping || mShuttingDown; 8419 } 8420 8421 public void goingToSleep() { 8422 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8423 != PackageManager.PERMISSION_GRANTED) { 8424 throw new SecurityException("Requires permission " 8425 + android.Manifest.permission.DEVICE_POWER); 8426 } 8427 8428 synchronized(this) { 8429 mWentToSleep = true; 8430 updateEventDispatchingLocked(); 8431 8432 if (!mSleeping) { 8433 mSleeping = true; 8434 mStackSupervisor.goingToSleepLocked(); 8435 8436 // Initialize the wake times of all processes. 8437 checkExcessivePowerUsageLocked(false); 8438 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8439 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8440 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8441 } 8442 } 8443 } 8444 8445 @Override 8446 public boolean shutdown(int timeout) { 8447 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8448 != PackageManager.PERMISSION_GRANTED) { 8449 throw new SecurityException("Requires permission " 8450 + android.Manifest.permission.SHUTDOWN); 8451 } 8452 8453 boolean timedout = false; 8454 8455 synchronized(this) { 8456 mShuttingDown = true; 8457 updateEventDispatchingLocked(); 8458 timedout = mStackSupervisor.shutdownLocked(timeout); 8459 } 8460 8461 mAppOpsService.shutdown(); 8462 mUsageStatsService.shutdown(); 8463 mBatteryStatsService.shutdown(); 8464 synchronized (this) { 8465 mProcessStats.shutdownLocked(); 8466 } 8467 8468 return timedout; 8469 } 8470 8471 public final void activitySlept(IBinder token) { 8472 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8473 8474 final long origId = Binder.clearCallingIdentity(); 8475 8476 synchronized (this) { 8477 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8478 if (r != null) { 8479 mStackSupervisor.activitySleptLocked(r); 8480 } 8481 } 8482 8483 Binder.restoreCallingIdentity(origId); 8484 } 8485 8486 void logLockScreen(String msg) { 8487 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8488 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8489 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8490 mStackSupervisor.mDismissKeyguardOnNextActivity); 8491 } 8492 8493 private void comeOutOfSleepIfNeededLocked() { 8494 if (!mWentToSleep && !mLockScreenShown) { 8495 if (mSleeping) { 8496 mSleeping = false; 8497 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8498 } 8499 } 8500 } 8501 8502 public void wakingUp() { 8503 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8504 != PackageManager.PERMISSION_GRANTED) { 8505 throw new SecurityException("Requires permission " 8506 + android.Manifest.permission.DEVICE_POWER); 8507 } 8508 8509 synchronized(this) { 8510 mWentToSleep = false; 8511 updateEventDispatchingLocked(); 8512 comeOutOfSleepIfNeededLocked(); 8513 } 8514 } 8515 8516 private void updateEventDispatchingLocked() { 8517 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8518 } 8519 8520 public void setLockScreenShown(boolean shown) { 8521 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8522 != PackageManager.PERMISSION_GRANTED) { 8523 throw new SecurityException("Requires permission " 8524 + android.Manifest.permission.DEVICE_POWER); 8525 } 8526 8527 synchronized(this) { 8528 long ident = Binder.clearCallingIdentity(); 8529 try { 8530 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8531 mLockScreenShown = shown; 8532 comeOutOfSleepIfNeededLocked(); 8533 } finally { 8534 Binder.restoreCallingIdentity(ident); 8535 } 8536 } 8537 } 8538 8539 public void stopAppSwitches() { 8540 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8541 != PackageManager.PERMISSION_GRANTED) { 8542 throw new SecurityException("Requires permission " 8543 + android.Manifest.permission.STOP_APP_SWITCHES); 8544 } 8545 8546 synchronized(this) { 8547 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8548 + APP_SWITCH_DELAY_TIME; 8549 mDidAppSwitch = false; 8550 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8551 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8552 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8553 } 8554 } 8555 8556 public void resumeAppSwitches() { 8557 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8558 != PackageManager.PERMISSION_GRANTED) { 8559 throw new SecurityException("Requires permission " 8560 + android.Manifest.permission.STOP_APP_SWITCHES); 8561 } 8562 8563 synchronized(this) { 8564 // Note that we don't execute any pending app switches... we will 8565 // let those wait until either the timeout, or the next start 8566 // activity request. 8567 mAppSwitchesAllowedTime = 0; 8568 } 8569 } 8570 8571 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8572 String name) { 8573 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8574 return true; 8575 } 8576 8577 final int perm = checkComponentPermission( 8578 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8579 callingUid, -1, true); 8580 if (perm == PackageManager.PERMISSION_GRANTED) { 8581 return true; 8582 } 8583 8584 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8585 return false; 8586 } 8587 8588 public void setDebugApp(String packageName, boolean waitForDebugger, 8589 boolean persistent) { 8590 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8591 "setDebugApp()"); 8592 8593 long ident = Binder.clearCallingIdentity(); 8594 try { 8595 // Note that this is not really thread safe if there are multiple 8596 // callers into it at the same time, but that's not a situation we 8597 // care about. 8598 if (persistent) { 8599 final ContentResolver resolver = mContext.getContentResolver(); 8600 Settings.Global.putString( 8601 resolver, Settings.Global.DEBUG_APP, 8602 packageName); 8603 Settings.Global.putInt( 8604 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8605 waitForDebugger ? 1 : 0); 8606 } 8607 8608 synchronized (this) { 8609 if (!persistent) { 8610 mOrigDebugApp = mDebugApp; 8611 mOrigWaitForDebugger = mWaitForDebugger; 8612 } 8613 mDebugApp = packageName; 8614 mWaitForDebugger = waitForDebugger; 8615 mDebugTransient = !persistent; 8616 if (packageName != null) { 8617 forceStopPackageLocked(packageName, -1, false, false, true, true, 8618 false, UserHandle.USER_ALL, "set debug app"); 8619 } 8620 } 8621 } finally { 8622 Binder.restoreCallingIdentity(ident); 8623 } 8624 } 8625 8626 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8627 synchronized (this) { 8628 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8629 if (!isDebuggable) { 8630 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8631 throw new SecurityException("Process not debuggable: " + app.packageName); 8632 } 8633 } 8634 8635 mOpenGlTraceApp = processName; 8636 } 8637 } 8638 8639 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8640 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8641 synchronized (this) { 8642 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8643 if (!isDebuggable) { 8644 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8645 throw new SecurityException("Process not debuggable: " + app.packageName); 8646 } 8647 } 8648 mProfileApp = processName; 8649 mProfileFile = profileFile; 8650 if (mProfileFd != null) { 8651 try { 8652 mProfileFd.close(); 8653 } catch (IOException e) { 8654 } 8655 mProfileFd = null; 8656 } 8657 mProfileFd = profileFd; 8658 mProfileType = 0; 8659 mAutoStopProfiler = autoStopProfiler; 8660 } 8661 } 8662 8663 @Override 8664 public void setAlwaysFinish(boolean enabled) { 8665 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8666 "setAlwaysFinish()"); 8667 8668 Settings.Global.putInt( 8669 mContext.getContentResolver(), 8670 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8671 8672 synchronized (this) { 8673 mAlwaysFinishActivities = enabled; 8674 } 8675 } 8676 8677 @Override 8678 public void setActivityController(IActivityController controller) { 8679 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8680 "setActivityController()"); 8681 synchronized (this) { 8682 mController = controller; 8683 Watchdog.getInstance().setActivityController(controller); 8684 } 8685 } 8686 8687 @Override 8688 public void setUserIsMonkey(boolean userIsMonkey) { 8689 synchronized (this) { 8690 synchronized (mPidsSelfLocked) { 8691 final int callingPid = Binder.getCallingPid(); 8692 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8693 if (precessRecord == null) { 8694 throw new SecurityException("Unknown process: " + callingPid); 8695 } 8696 if (precessRecord.instrumentationUiAutomationConnection == null) { 8697 throw new SecurityException("Only an instrumentation process " 8698 + "with a UiAutomation can call setUserIsMonkey"); 8699 } 8700 } 8701 mUserIsMonkey = userIsMonkey; 8702 } 8703 } 8704 8705 @Override 8706 public boolean isUserAMonkey() { 8707 synchronized (this) { 8708 // If there is a controller also implies the user is a monkey. 8709 return (mUserIsMonkey || mController != null); 8710 } 8711 } 8712 8713 public void requestBugReport() { 8714 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8715 SystemProperties.set("ctl.start", "bugreport"); 8716 } 8717 8718 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8719 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8720 } 8721 8722 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8723 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8724 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8725 } 8726 return KEY_DISPATCHING_TIMEOUT; 8727 } 8728 8729 @Override 8730 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8731 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8732 != PackageManager.PERMISSION_GRANTED) { 8733 throw new SecurityException("Requires permission " 8734 + android.Manifest.permission.FILTER_EVENTS); 8735 } 8736 ProcessRecord proc; 8737 long timeout; 8738 synchronized (this) { 8739 synchronized (mPidsSelfLocked) { 8740 proc = mPidsSelfLocked.get(pid); 8741 } 8742 timeout = getInputDispatchingTimeoutLocked(proc); 8743 } 8744 8745 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8746 return -1; 8747 } 8748 8749 return timeout; 8750 } 8751 8752 /** 8753 * Handle input dispatching timeouts. 8754 * Returns whether input dispatching should be aborted or not. 8755 */ 8756 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8757 final ActivityRecord activity, final ActivityRecord parent, 8758 final boolean aboveSystem, String reason) { 8759 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8760 != PackageManager.PERMISSION_GRANTED) { 8761 throw new SecurityException("Requires permission " 8762 + android.Manifest.permission.FILTER_EVENTS); 8763 } 8764 8765 final String annotation; 8766 if (reason == null) { 8767 annotation = "Input dispatching timed out"; 8768 } else { 8769 annotation = "Input dispatching timed out (" + reason + ")"; 8770 } 8771 8772 if (proc != null) { 8773 synchronized (this) { 8774 if (proc.debugging) { 8775 return false; 8776 } 8777 8778 if (mDidDexOpt) { 8779 // Give more time since we were dexopting. 8780 mDidDexOpt = false; 8781 return false; 8782 } 8783 8784 if (proc.instrumentationClass != null) { 8785 Bundle info = new Bundle(); 8786 info.putString("shortMsg", "keyDispatchingTimedOut"); 8787 info.putString("longMsg", annotation); 8788 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8789 return true; 8790 } 8791 } 8792 mHandler.post(new Runnable() { 8793 @Override 8794 public void run() { 8795 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8796 } 8797 }); 8798 } 8799 8800 return true; 8801 } 8802 8803 public Bundle getAssistContextExtras(int requestType) { 8804 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8805 "getAssistContextExtras()"); 8806 PendingAssistExtras pae; 8807 Bundle extras = new Bundle(); 8808 synchronized (this) { 8809 ActivityRecord activity = getFocusedStack().mResumedActivity; 8810 if (activity == null) { 8811 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8812 return null; 8813 } 8814 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8815 if (activity.app == null || activity.app.thread == null) { 8816 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8817 return extras; 8818 } 8819 if (activity.app.pid == Binder.getCallingPid()) { 8820 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8821 return extras; 8822 } 8823 pae = new PendingAssistExtras(activity); 8824 try { 8825 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8826 requestType); 8827 mPendingAssistExtras.add(pae); 8828 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8829 } catch (RemoteException e) { 8830 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8831 return extras; 8832 } 8833 } 8834 synchronized (pae) { 8835 while (!pae.haveResult) { 8836 try { 8837 pae.wait(); 8838 } catch (InterruptedException e) { 8839 } 8840 } 8841 if (pae.result != null) { 8842 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8843 } 8844 } 8845 synchronized (this) { 8846 mPendingAssistExtras.remove(pae); 8847 mHandler.removeCallbacks(pae); 8848 } 8849 return extras; 8850 } 8851 8852 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8853 PendingAssistExtras pae = (PendingAssistExtras)token; 8854 synchronized (pae) { 8855 pae.result = extras; 8856 pae.haveResult = true; 8857 pae.notifyAll(); 8858 } 8859 } 8860 8861 public void registerProcessObserver(IProcessObserver observer) { 8862 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8863 "registerProcessObserver()"); 8864 synchronized (this) { 8865 mProcessObservers.register(observer); 8866 } 8867 } 8868 8869 @Override 8870 public void unregisterProcessObserver(IProcessObserver observer) { 8871 synchronized (this) { 8872 mProcessObservers.unregister(observer); 8873 } 8874 } 8875 8876 @Override 8877 public boolean convertFromTranslucent(IBinder token) { 8878 final long origId = Binder.clearCallingIdentity(); 8879 try { 8880 synchronized (this) { 8881 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8882 if (r == null) { 8883 return false; 8884 } 8885 if (r.changeWindowTranslucency(true)) { 8886 mWindowManager.setAppFullscreen(token, true); 8887 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8888 return true; 8889 } 8890 return false; 8891 } 8892 } finally { 8893 Binder.restoreCallingIdentity(origId); 8894 } 8895 } 8896 8897 @Override 8898 public boolean convertToTranslucent(IBinder token) { 8899 final long origId = Binder.clearCallingIdentity(); 8900 try { 8901 synchronized (this) { 8902 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8903 if (r == null) { 8904 return false; 8905 } 8906 if (r.changeWindowTranslucency(false)) { 8907 r.task.stack.convertToTranslucent(r); 8908 mWindowManager.setAppFullscreen(token, false); 8909 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8910 return true; 8911 } 8912 return false; 8913 } 8914 } finally { 8915 Binder.restoreCallingIdentity(origId); 8916 } 8917 } 8918 8919 @Override 8920 public void setImmersive(IBinder token, boolean immersive) { 8921 synchronized(this) { 8922 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8923 if (r == null) { 8924 throw new IllegalArgumentException(); 8925 } 8926 r.immersive = immersive; 8927 8928 // update associated state if we're frontmost 8929 if (r == mFocusedActivity) { 8930 if (DEBUG_IMMERSIVE) { 8931 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8932 } 8933 applyUpdateLockStateLocked(r); 8934 } 8935 } 8936 } 8937 8938 @Override 8939 public boolean isImmersive(IBinder token) { 8940 synchronized (this) { 8941 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8942 if (r == null) { 8943 throw new IllegalArgumentException(); 8944 } 8945 return r.immersive; 8946 } 8947 } 8948 8949 public boolean isTopActivityImmersive() { 8950 enforceNotIsolatedCaller("startActivity"); 8951 synchronized (this) { 8952 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8953 return (r != null) ? r.immersive : false; 8954 } 8955 } 8956 8957 public final void enterSafeMode() { 8958 synchronized(this) { 8959 // It only makes sense to do this before the system is ready 8960 // and started launching other packages. 8961 if (!mSystemReady) { 8962 try { 8963 AppGlobals.getPackageManager().enterSafeMode(); 8964 } catch (RemoteException e) { 8965 } 8966 } 8967 } 8968 } 8969 8970 public final void showSafeModeOverlay() { 8971 View v = LayoutInflater.from(mContext).inflate( 8972 com.android.internal.R.layout.safe_mode, null); 8973 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8974 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8975 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8976 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8977 lp.gravity = Gravity.BOTTOM | Gravity.START; 8978 lp.format = v.getBackground().getOpacity(); 8979 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8980 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8981 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8982 ((WindowManager)mContext.getSystemService( 8983 Context.WINDOW_SERVICE)).addView(v, lp); 8984 } 8985 8986 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8987 if (!(sender instanceof PendingIntentRecord)) { 8988 return; 8989 } 8990 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8991 synchronized (stats) { 8992 if (mBatteryStatsService.isOnBattery()) { 8993 mBatteryStatsService.enforceCallingPermission(); 8994 PendingIntentRecord rec = (PendingIntentRecord)sender; 8995 int MY_UID = Binder.getCallingUid(); 8996 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8997 BatteryStatsImpl.Uid.Pkg pkg = 8998 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8999 sourcePkg != null ? sourcePkg : rec.key.packageName); 9000 pkg.incWakeupsLocked(); 9001 } 9002 } 9003 } 9004 9005 public boolean killPids(int[] pids, String pReason, boolean secure) { 9006 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9007 throw new SecurityException("killPids only available to the system"); 9008 } 9009 String reason = (pReason == null) ? "Unknown" : pReason; 9010 // XXX Note: don't acquire main activity lock here, because the window 9011 // manager calls in with its locks held. 9012 9013 boolean killed = false; 9014 synchronized (mPidsSelfLocked) { 9015 int[] types = new int[pids.length]; 9016 int worstType = 0; 9017 for (int i=0; i<pids.length; i++) { 9018 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9019 if (proc != null) { 9020 int type = proc.setAdj; 9021 types[i] = type; 9022 if (type > worstType) { 9023 worstType = type; 9024 } 9025 } 9026 } 9027 9028 // If the worst oom_adj is somewhere in the cached proc LRU range, 9029 // then constrain it so we will kill all cached procs. 9030 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9031 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9032 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9033 } 9034 9035 // If this is not a secure call, don't let it kill processes that 9036 // are important. 9037 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9038 worstType = ProcessList.SERVICE_ADJ; 9039 } 9040 9041 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9042 for (int i=0; i<pids.length; i++) { 9043 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9044 if (proc == null) { 9045 continue; 9046 } 9047 int adj = proc.setAdj; 9048 if (adj >= worstType && !proc.killedByAm) { 9049 killUnneededProcessLocked(proc, reason); 9050 killed = true; 9051 } 9052 } 9053 } 9054 return killed; 9055 } 9056 9057 @Override 9058 public void killUid(int uid, String reason) { 9059 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9060 throw new SecurityException("killUid only available to the system"); 9061 } 9062 synchronized (this) { 9063 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9064 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9065 reason != null ? reason : "kill uid"); 9066 } 9067 } 9068 9069 @Override 9070 public boolean killProcessesBelowForeground(String reason) { 9071 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9072 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9073 } 9074 9075 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9076 } 9077 9078 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9079 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9080 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9081 } 9082 9083 boolean killed = false; 9084 synchronized (mPidsSelfLocked) { 9085 final int size = mPidsSelfLocked.size(); 9086 for (int i = 0; i < size; i++) { 9087 final int pid = mPidsSelfLocked.keyAt(i); 9088 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9089 if (proc == null) continue; 9090 9091 final int adj = proc.setAdj; 9092 if (adj > belowAdj && !proc.killedByAm) { 9093 killUnneededProcessLocked(proc, reason); 9094 killed = true; 9095 } 9096 } 9097 } 9098 return killed; 9099 } 9100 9101 @Override 9102 public void hang(final IBinder who, boolean allowRestart) { 9103 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9104 != PackageManager.PERMISSION_GRANTED) { 9105 throw new SecurityException("Requires permission " 9106 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9107 } 9108 9109 final IBinder.DeathRecipient death = new DeathRecipient() { 9110 @Override 9111 public void binderDied() { 9112 synchronized (this) { 9113 notifyAll(); 9114 } 9115 } 9116 }; 9117 9118 try { 9119 who.linkToDeath(death, 0); 9120 } catch (RemoteException e) { 9121 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9122 return; 9123 } 9124 9125 synchronized (this) { 9126 Watchdog.getInstance().setAllowRestart(allowRestart); 9127 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9128 synchronized (death) { 9129 while (who.isBinderAlive()) { 9130 try { 9131 death.wait(); 9132 } catch (InterruptedException e) { 9133 } 9134 } 9135 } 9136 Watchdog.getInstance().setAllowRestart(true); 9137 } 9138 } 9139 9140 @Override 9141 public void restart() { 9142 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9143 != PackageManager.PERMISSION_GRANTED) { 9144 throw new SecurityException("Requires permission " 9145 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9146 } 9147 9148 Log.i(TAG, "Sending shutdown broadcast..."); 9149 9150 BroadcastReceiver br = new BroadcastReceiver() { 9151 @Override public void onReceive(Context context, Intent intent) { 9152 // Now the broadcast is done, finish up the low-level shutdown. 9153 Log.i(TAG, "Shutting down activity manager..."); 9154 shutdown(10000); 9155 Log.i(TAG, "Shutdown complete, restarting!"); 9156 Process.killProcess(Process.myPid()); 9157 System.exit(10); 9158 } 9159 }; 9160 9161 // First send the high-level shut down broadcast. 9162 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9163 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9164 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9165 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9166 mContext.sendOrderedBroadcastAsUser(intent, 9167 UserHandle.ALL, null, br, mHandler, 0, null, null); 9168 */ 9169 br.onReceive(mContext, intent); 9170 } 9171 9172 private long getLowRamTimeSinceIdle(long now) { 9173 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9174 } 9175 9176 @Override 9177 public void performIdleMaintenance() { 9178 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9179 != PackageManager.PERMISSION_GRANTED) { 9180 throw new SecurityException("Requires permission " 9181 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9182 } 9183 9184 synchronized (this) { 9185 final long now = SystemClock.uptimeMillis(); 9186 final long timeSinceLastIdle = now - mLastIdleTime; 9187 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9188 mLastIdleTime = now; 9189 mLowRamTimeSinceLastIdle = 0; 9190 if (mLowRamStartTime != 0) { 9191 mLowRamStartTime = now; 9192 } 9193 9194 StringBuilder sb = new StringBuilder(128); 9195 sb.append("Idle maintenance over "); 9196 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9197 sb.append(" low RAM for "); 9198 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9199 Slog.i(TAG, sb.toString()); 9200 9201 // If at least 1/3 of our time since the last idle period has been spent 9202 // with RAM low, then we want to kill processes. 9203 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9204 9205 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9206 ProcessRecord proc = mLruProcesses.get(i); 9207 if (proc.notCachedSinceIdle) { 9208 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9209 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9210 if (doKilling && proc.initialIdlePss != 0 9211 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9212 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9213 + " from " + proc.initialIdlePss + ")"); 9214 } 9215 } 9216 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9217 proc.notCachedSinceIdle = true; 9218 proc.initialIdlePss = 0; 9219 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9220 mSleeping, now); 9221 } 9222 } 9223 9224 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9225 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9226 } 9227 } 9228 9229 public final void startRunning(String pkg, String cls, String action, 9230 String data) { 9231 synchronized(this) { 9232 if (mStartRunning) { 9233 return; 9234 } 9235 mStartRunning = true; 9236 mTopComponent = pkg != null && cls != null 9237 ? new ComponentName(pkg, cls) : null; 9238 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9239 mTopData = data; 9240 if (!mSystemReady) { 9241 return; 9242 } 9243 } 9244 9245 systemReady(null); 9246 } 9247 9248 private void retrieveSettings() { 9249 final ContentResolver resolver = mContext.getContentResolver(); 9250 String debugApp = Settings.Global.getString( 9251 resolver, Settings.Global.DEBUG_APP); 9252 boolean waitForDebugger = Settings.Global.getInt( 9253 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9254 boolean alwaysFinishActivities = Settings.Global.getInt( 9255 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9256 boolean forceRtl = Settings.Global.getInt( 9257 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9258 // Transfer any global setting for forcing RTL layout, into a System Property 9259 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9260 9261 Configuration configuration = new Configuration(); 9262 Settings.System.getConfiguration(resolver, configuration); 9263 if (forceRtl) { 9264 // This will take care of setting the correct layout direction flags 9265 configuration.setLayoutDirection(configuration.locale); 9266 } 9267 9268 synchronized (this) { 9269 mDebugApp = mOrigDebugApp = debugApp; 9270 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9271 mAlwaysFinishActivities = alwaysFinishActivities; 9272 // This happens before any activities are started, so we can 9273 // change mConfiguration in-place. 9274 updateConfigurationLocked(configuration, null, false, true); 9275 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9276 } 9277 } 9278 9279 public boolean testIsSystemReady() { 9280 // no need to synchronize(this) just to read & return the value 9281 return mSystemReady; 9282 } 9283 9284 private static File getCalledPreBootReceiversFile() { 9285 File dataDir = Environment.getDataDirectory(); 9286 File systemDir = new File(dataDir, "system"); 9287 File fname = new File(systemDir, "called_pre_boots.dat"); 9288 return fname; 9289 } 9290 9291 static final int LAST_DONE_VERSION = 10000; 9292 9293 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9294 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9295 File file = getCalledPreBootReceiversFile(); 9296 FileInputStream fis = null; 9297 try { 9298 fis = new FileInputStream(file); 9299 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9300 int fvers = dis.readInt(); 9301 if (fvers == LAST_DONE_VERSION) { 9302 String vers = dis.readUTF(); 9303 String codename = dis.readUTF(); 9304 String build = dis.readUTF(); 9305 if (android.os.Build.VERSION.RELEASE.equals(vers) 9306 && android.os.Build.VERSION.CODENAME.equals(codename) 9307 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9308 int num = dis.readInt(); 9309 while (num > 0) { 9310 num--; 9311 String pkg = dis.readUTF(); 9312 String cls = dis.readUTF(); 9313 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9314 } 9315 } 9316 } 9317 } catch (FileNotFoundException e) { 9318 } catch (IOException e) { 9319 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9320 } finally { 9321 if (fis != null) { 9322 try { 9323 fis.close(); 9324 } catch (IOException e) { 9325 } 9326 } 9327 } 9328 return lastDoneReceivers; 9329 } 9330 9331 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9332 File file = getCalledPreBootReceiversFile(); 9333 FileOutputStream fos = null; 9334 DataOutputStream dos = null; 9335 try { 9336 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9337 fos = new FileOutputStream(file); 9338 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9339 dos.writeInt(LAST_DONE_VERSION); 9340 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9341 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9342 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9343 dos.writeInt(list.size()); 9344 for (int i=0; i<list.size(); i++) { 9345 dos.writeUTF(list.get(i).getPackageName()); 9346 dos.writeUTF(list.get(i).getClassName()); 9347 } 9348 } catch (IOException e) { 9349 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9350 file.delete(); 9351 } finally { 9352 FileUtils.sync(fos); 9353 if (dos != null) { 9354 try { 9355 dos.close(); 9356 } catch (IOException e) { 9357 // TODO Auto-generated catch block 9358 e.printStackTrace(); 9359 } 9360 } 9361 } 9362 } 9363 9364 public void systemReady(final Runnable goingCallback) { 9365 synchronized(this) { 9366 if (mSystemReady) { 9367 if (goingCallback != null) goingCallback.run(); 9368 return; 9369 } 9370 9371 // Check to see if there are any update receivers to run. 9372 if (!mDidUpdate) { 9373 if (mWaitingUpdate) { 9374 return; 9375 } 9376 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9377 List<ResolveInfo> ris = null; 9378 try { 9379 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9380 intent, null, 0, 0); 9381 } catch (RemoteException e) { 9382 } 9383 if (ris != null) { 9384 for (int i=ris.size()-1; i>=0; i--) { 9385 if ((ris.get(i).activityInfo.applicationInfo.flags 9386 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9387 ris.remove(i); 9388 } 9389 } 9390 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9391 9392 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9393 9394 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9395 for (int i=0; i<ris.size(); i++) { 9396 ActivityInfo ai = ris.get(i).activityInfo; 9397 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9398 if (lastDoneReceivers.contains(comp)) { 9399 // We already did the pre boot receiver for this app with the current 9400 // platform version, so don't do it again... 9401 ris.remove(i); 9402 i--; 9403 // ...however, do keep it as one that has been done, so we don't 9404 // forget about it when rewriting the file of last done receivers. 9405 doneReceivers.add(comp); 9406 } 9407 } 9408 9409 final int[] users = getUsersLocked(); 9410 for (int i=0; i<ris.size(); i++) { 9411 ActivityInfo ai = ris.get(i).activityInfo; 9412 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9413 doneReceivers.add(comp); 9414 intent.setComponent(comp); 9415 for (int j=0; j<users.length; j++) { 9416 IIntentReceiver finisher = null; 9417 if (i == ris.size()-1 && j == users.length-1) { 9418 finisher = new IIntentReceiver.Stub() { 9419 public void performReceive(Intent intent, int resultCode, 9420 String data, Bundle extras, boolean ordered, 9421 boolean sticky, int sendingUser) { 9422 // The raw IIntentReceiver interface is called 9423 // with the AM lock held, so redispatch to 9424 // execute our code without the lock. 9425 mHandler.post(new Runnable() { 9426 public void run() { 9427 synchronized (ActivityManagerService.this) { 9428 mDidUpdate = true; 9429 } 9430 writeLastDonePreBootReceivers(doneReceivers); 9431 showBootMessage(mContext.getText( 9432 R.string.android_upgrading_complete), 9433 false); 9434 systemReady(goingCallback); 9435 } 9436 }); 9437 } 9438 }; 9439 } 9440 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9441 + " for user " + users[j]); 9442 broadcastIntentLocked(null, null, intent, null, finisher, 9443 0, null, null, null, AppOpsManager.OP_NONE, 9444 true, false, MY_PID, Process.SYSTEM_UID, 9445 users[j]); 9446 if (finisher != null) { 9447 mWaitingUpdate = true; 9448 } 9449 } 9450 } 9451 } 9452 if (mWaitingUpdate) { 9453 return; 9454 } 9455 mDidUpdate = true; 9456 } 9457 9458 mAppOpsService.systemReady(); 9459 mSystemReady = true; 9460 if (!mStartRunning) { 9461 return; 9462 } 9463 } 9464 9465 ArrayList<ProcessRecord> procsToKill = null; 9466 synchronized(mPidsSelfLocked) { 9467 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9468 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9469 if (!isAllowedWhileBooting(proc.info)){ 9470 if (procsToKill == null) { 9471 procsToKill = new ArrayList<ProcessRecord>(); 9472 } 9473 procsToKill.add(proc); 9474 } 9475 } 9476 } 9477 9478 synchronized(this) { 9479 if (procsToKill != null) { 9480 for (int i=procsToKill.size()-1; i>=0; i--) { 9481 ProcessRecord proc = procsToKill.get(i); 9482 Slog.i(TAG, "Removing system update proc: " + proc); 9483 removeProcessLocked(proc, true, false, "system update done"); 9484 } 9485 } 9486 9487 // Now that we have cleaned up any update processes, we 9488 // are ready to start launching real processes and know that 9489 // we won't trample on them any more. 9490 mProcessesReady = true; 9491 } 9492 9493 Slog.i(TAG, "System now ready"); 9494 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9495 SystemClock.uptimeMillis()); 9496 9497 synchronized(this) { 9498 // Make sure we have no pre-ready processes sitting around. 9499 9500 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9501 ResolveInfo ri = mContext.getPackageManager() 9502 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9503 STOCK_PM_FLAGS); 9504 CharSequence errorMsg = null; 9505 if (ri != null) { 9506 ActivityInfo ai = ri.activityInfo; 9507 ApplicationInfo app = ai.applicationInfo; 9508 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9509 mTopAction = Intent.ACTION_FACTORY_TEST; 9510 mTopData = null; 9511 mTopComponent = new ComponentName(app.packageName, 9512 ai.name); 9513 } else { 9514 errorMsg = mContext.getResources().getText( 9515 com.android.internal.R.string.factorytest_not_system); 9516 } 9517 } else { 9518 errorMsg = mContext.getResources().getText( 9519 com.android.internal.R.string.factorytest_no_action); 9520 } 9521 if (errorMsg != null) { 9522 mTopAction = null; 9523 mTopData = null; 9524 mTopComponent = null; 9525 Message msg = Message.obtain(); 9526 msg.what = SHOW_FACTORY_ERROR_MSG; 9527 msg.getData().putCharSequence("msg", errorMsg); 9528 mHandler.sendMessage(msg); 9529 } 9530 } 9531 } 9532 9533 retrieveSettings(); 9534 9535 synchronized (this) { 9536 readGrantedUriPermissionsLocked(); 9537 } 9538 9539 if (goingCallback != null) goingCallback.run(); 9540 9541 synchronized (this) { 9542 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9543 try { 9544 List apps = AppGlobals.getPackageManager(). 9545 getPersistentApplications(STOCK_PM_FLAGS); 9546 if (apps != null) { 9547 int N = apps.size(); 9548 int i; 9549 for (i=0; i<N; i++) { 9550 ApplicationInfo info 9551 = (ApplicationInfo)apps.get(i); 9552 if (info != null && 9553 !info.packageName.equals("android")) { 9554 addAppLocked(info, false); 9555 } 9556 } 9557 } 9558 } catch (RemoteException ex) { 9559 // pm is in same process, this will never happen. 9560 } 9561 } 9562 9563 // Start up initial activity. 9564 mBooting = true; 9565 9566 try { 9567 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9568 Message msg = Message.obtain(); 9569 msg.what = SHOW_UID_ERROR_MSG; 9570 mHandler.sendMessage(msg); 9571 } 9572 } catch (RemoteException e) { 9573 } 9574 9575 long ident = Binder.clearCallingIdentity(); 9576 try { 9577 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9578 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9579 | Intent.FLAG_RECEIVER_FOREGROUND); 9580 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9581 broadcastIntentLocked(null, null, intent, 9582 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9583 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9584 intent = new Intent(Intent.ACTION_USER_STARTING); 9585 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9586 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9587 broadcastIntentLocked(null, null, intent, 9588 null, new IIntentReceiver.Stub() { 9589 @Override 9590 public void performReceive(Intent intent, int resultCode, String data, 9591 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9592 throws RemoteException { 9593 } 9594 }, 0, null, null, 9595 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9596 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9597 } finally { 9598 Binder.restoreCallingIdentity(ident); 9599 } 9600 mStackSupervisor.resumeTopActivitiesLocked(); 9601 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9602 } 9603 } 9604 9605 private boolean makeAppCrashingLocked(ProcessRecord app, 9606 String shortMsg, String longMsg, String stackTrace) { 9607 app.crashing = true; 9608 app.crashingReport = generateProcessError(app, 9609 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9610 startAppProblemLocked(app); 9611 app.stopFreezingAllLocked(); 9612 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9613 } 9614 9615 private void makeAppNotRespondingLocked(ProcessRecord app, 9616 String activity, String shortMsg, String longMsg) { 9617 app.notResponding = true; 9618 app.notRespondingReport = generateProcessError(app, 9619 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9620 activity, shortMsg, longMsg, null); 9621 startAppProblemLocked(app); 9622 app.stopFreezingAllLocked(); 9623 } 9624 9625 /** 9626 * Generate a process error record, suitable for attachment to a ProcessRecord. 9627 * 9628 * @param app The ProcessRecord in which the error occurred. 9629 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9630 * ActivityManager.AppErrorStateInfo 9631 * @param activity The activity associated with the crash, if known. 9632 * @param shortMsg Short message describing the crash. 9633 * @param longMsg Long message describing the crash. 9634 * @param stackTrace Full crash stack trace, may be null. 9635 * 9636 * @return Returns a fully-formed AppErrorStateInfo record. 9637 */ 9638 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9639 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9640 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9641 9642 report.condition = condition; 9643 report.processName = app.processName; 9644 report.pid = app.pid; 9645 report.uid = app.info.uid; 9646 report.tag = activity; 9647 report.shortMsg = shortMsg; 9648 report.longMsg = longMsg; 9649 report.stackTrace = stackTrace; 9650 9651 return report; 9652 } 9653 9654 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9655 synchronized (this) { 9656 app.crashing = false; 9657 app.crashingReport = null; 9658 app.notResponding = false; 9659 app.notRespondingReport = null; 9660 if (app.anrDialog == fromDialog) { 9661 app.anrDialog = null; 9662 } 9663 if (app.waitDialog == fromDialog) { 9664 app.waitDialog = null; 9665 } 9666 if (app.pid > 0 && app.pid != MY_PID) { 9667 handleAppCrashLocked(app, null, null, null); 9668 killUnneededProcessLocked(app, "user request after error"); 9669 } 9670 } 9671 } 9672 9673 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9674 String stackTrace) { 9675 long now = SystemClock.uptimeMillis(); 9676 9677 Long crashTime; 9678 if (!app.isolated) { 9679 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9680 } else { 9681 crashTime = null; 9682 } 9683 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9684 // This process loses! 9685 Slog.w(TAG, "Process " + app.info.processName 9686 + " has crashed too many times: killing!"); 9687 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9688 app.userId, app.info.processName, app.uid); 9689 mStackSupervisor.handleAppCrashLocked(app); 9690 if (!app.persistent) { 9691 // We don't want to start this process again until the user 9692 // explicitly does so... but for persistent process, we really 9693 // need to keep it running. If a persistent process is actually 9694 // repeatedly crashing, then badness for everyone. 9695 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9696 app.info.processName); 9697 if (!app.isolated) { 9698 // XXX We don't have a way to mark isolated processes 9699 // as bad, since they don't have a peristent identity. 9700 mBadProcesses.put(app.info.processName, app.uid, 9701 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9702 mProcessCrashTimes.remove(app.info.processName, app.uid); 9703 } 9704 app.bad = true; 9705 app.removed = true; 9706 // Don't let services in this process be restarted and potentially 9707 // annoy the user repeatedly. Unless it is persistent, since those 9708 // processes run critical code. 9709 removeProcessLocked(app, false, false, "crash"); 9710 mStackSupervisor.resumeTopActivitiesLocked(); 9711 return false; 9712 } 9713 mStackSupervisor.resumeTopActivitiesLocked(); 9714 } else { 9715 mStackSupervisor.finishTopRunningActivityLocked(app); 9716 } 9717 9718 // Bump up the crash count of any services currently running in the proc. 9719 for (int i=app.services.size()-1; i>=0; i--) { 9720 // Any services running in the application need to be placed 9721 // back in the pending list. 9722 ServiceRecord sr = app.services.valueAt(i); 9723 sr.crashCount++; 9724 } 9725 9726 // If the crashing process is what we consider to be the "home process" and it has been 9727 // replaced by a third-party app, clear the package preferred activities from packages 9728 // with a home activity running in the process to prevent a repeatedly crashing app 9729 // from blocking the user to manually clear the list. 9730 final ArrayList<ActivityRecord> activities = app.activities; 9731 if (app == mHomeProcess && activities.size() > 0 9732 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9733 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9734 final ActivityRecord r = activities.get(activityNdx); 9735 if (r.isHomeActivity()) { 9736 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9737 try { 9738 ActivityThread.getPackageManager() 9739 .clearPackagePreferredActivities(r.packageName); 9740 } catch (RemoteException c) { 9741 // pm is in same process, this will never happen. 9742 } 9743 } 9744 } 9745 } 9746 9747 if (!app.isolated) { 9748 // XXX Can't keep track of crash times for isolated processes, 9749 // because they don't have a perisistent identity. 9750 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9751 } 9752 9753 return true; 9754 } 9755 9756 void startAppProblemLocked(ProcessRecord app) { 9757 if (app.userId == mCurrentUserId) { 9758 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9759 mContext, app.info.packageName, app.info.flags); 9760 } else { 9761 // If this app is not running under the current user, then we 9762 // can't give it a report button because that would require 9763 // launching the report UI under a different user. 9764 app.errorReportReceiver = null; 9765 } 9766 skipCurrentReceiverLocked(app); 9767 } 9768 9769 void skipCurrentReceiverLocked(ProcessRecord app) { 9770 for (BroadcastQueue queue : mBroadcastQueues) { 9771 queue.skipCurrentReceiverLocked(app); 9772 } 9773 } 9774 9775 /** 9776 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9777 * The application process will exit immediately after this call returns. 9778 * @param app object of the crashing app, null for the system server 9779 * @param crashInfo describing the exception 9780 */ 9781 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9782 ProcessRecord r = findAppProcess(app, "Crash"); 9783 final String processName = app == null ? "system_server" 9784 : (r == null ? "unknown" : r.processName); 9785 9786 handleApplicationCrashInner("crash", r, processName, crashInfo); 9787 } 9788 9789 /* Native crash reporting uses this inner version because it needs to be somewhat 9790 * decoupled from the AM-managed cleanup lifecycle 9791 */ 9792 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9793 ApplicationErrorReport.CrashInfo crashInfo) { 9794 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9795 UserHandle.getUserId(Binder.getCallingUid()), processName, 9796 r == null ? -1 : r.info.flags, 9797 crashInfo.exceptionClassName, 9798 crashInfo.exceptionMessage, 9799 crashInfo.throwFileName, 9800 crashInfo.throwLineNumber); 9801 9802 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9803 9804 crashApplication(r, crashInfo); 9805 } 9806 9807 public void handleApplicationStrictModeViolation( 9808 IBinder app, 9809 int violationMask, 9810 StrictMode.ViolationInfo info) { 9811 ProcessRecord r = findAppProcess(app, "StrictMode"); 9812 if (r == null) { 9813 return; 9814 } 9815 9816 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9817 Integer stackFingerprint = info.hashCode(); 9818 boolean logIt = true; 9819 synchronized (mAlreadyLoggedViolatedStacks) { 9820 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9821 logIt = false; 9822 // TODO: sub-sample into EventLog for these, with 9823 // the info.durationMillis? Then we'd get 9824 // the relative pain numbers, without logging all 9825 // the stack traces repeatedly. We'd want to do 9826 // likewise in the client code, which also does 9827 // dup suppression, before the Binder call. 9828 } else { 9829 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9830 mAlreadyLoggedViolatedStacks.clear(); 9831 } 9832 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9833 } 9834 } 9835 if (logIt) { 9836 logStrictModeViolationToDropBox(r, info); 9837 } 9838 } 9839 9840 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9841 AppErrorResult result = new AppErrorResult(); 9842 synchronized (this) { 9843 final long origId = Binder.clearCallingIdentity(); 9844 9845 Message msg = Message.obtain(); 9846 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9847 HashMap<String, Object> data = new HashMap<String, Object>(); 9848 data.put("result", result); 9849 data.put("app", r); 9850 data.put("violationMask", violationMask); 9851 data.put("info", info); 9852 msg.obj = data; 9853 mHandler.sendMessage(msg); 9854 9855 Binder.restoreCallingIdentity(origId); 9856 } 9857 int res = result.get(); 9858 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9859 } 9860 } 9861 9862 // Depending on the policy in effect, there could be a bunch of 9863 // these in quick succession so we try to batch these together to 9864 // minimize disk writes, number of dropbox entries, and maximize 9865 // compression, by having more fewer, larger records. 9866 private void logStrictModeViolationToDropBox( 9867 ProcessRecord process, 9868 StrictMode.ViolationInfo info) { 9869 if (info == null) { 9870 return; 9871 } 9872 final boolean isSystemApp = process == null || 9873 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9874 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9875 final String processName = process == null ? "unknown" : process.processName; 9876 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9877 final DropBoxManager dbox = (DropBoxManager) 9878 mContext.getSystemService(Context.DROPBOX_SERVICE); 9879 9880 // Exit early if the dropbox isn't configured to accept this report type. 9881 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9882 9883 boolean bufferWasEmpty; 9884 boolean needsFlush; 9885 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9886 synchronized (sb) { 9887 bufferWasEmpty = sb.length() == 0; 9888 appendDropBoxProcessHeaders(process, processName, sb); 9889 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9890 sb.append("System-App: ").append(isSystemApp).append("\n"); 9891 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9892 if (info.violationNumThisLoop != 0) { 9893 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9894 } 9895 if (info.numAnimationsRunning != 0) { 9896 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9897 } 9898 if (info.broadcastIntentAction != null) { 9899 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9900 } 9901 if (info.durationMillis != -1) { 9902 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9903 } 9904 if (info.numInstances != -1) { 9905 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9906 } 9907 if (info.tags != null) { 9908 for (String tag : info.tags) { 9909 sb.append("Span-Tag: ").append(tag).append("\n"); 9910 } 9911 } 9912 sb.append("\n"); 9913 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9914 sb.append(info.crashInfo.stackTrace); 9915 } 9916 sb.append("\n"); 9917 9918 // Only buffer up to ~64k. Various logging bits truncate 9919 // things at 128k. 9920 needsFlush = (sb.length() > 64 * 1024); 9921 } 9922 9923 // Flush immediately if the buffer's grown too large, or this 9924 // is a non-system app. Non-system apps are isolated with a 9925 // different tag & policy and not batched. 9926 // 9927 // Batching is useful during internal testing with 9928 // StrictMode settings turned up high. Without batching, 9929 // thousands of separate files could be created on boot. 9930 if (!isSystemApp || needsFlush) { 9931 new Thread("Error dump: " + dropboxTag) { 9932 @Override 9933 public void run() { 9934 String report; 9935 synchronized (sb) { 9936 report = sb.toString(); 9937 sb.delete(0, sb.length()); 9938 sb.trimToSize(); 9939 } 9940 if (report.length() != 0) { 9941 dbox.addText(dropboxTag, report); 9942 } 9943 } 9944 }.start(); 9945 return; 9946 } 9947 9948 // System app batching: 9949 if (!bufferWasEmpty) { 9950 // An existing dropbox-writing thread is outstanding, so 9951 // we don't need to start it up. The existing thread will 9952 // catch the buffer appends we just did. 9953 return; 9954 } 9955 9956 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9957 // (After this point, we shouldn't access AMS internal data structures.) 9958 new Thread("Error dump: " + dropboxTag) { 9959 @Override 9960 public void run() { 9961 // 5 second sleep to let stacks arrive and be batched together 9962 try { 9963 Thread.sleep(5000); // 5 seconds 9964 } catch (InterruptedException e) {} 9965 9966 String errorReport; 9967 synchronized (mStrictModeBuffer) { 9968 errorReport = mStrictModeBuffer.toString(); 9969 if (errorReport.length() == 0) { 9970 return; 9971 } 9972 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9973 mStrictModeBuffer.trimToSize(); 9974 } 9975 dbox.addText(dropboxTag, errorReport); 9976 } 9977 }.start(); 9978 } 9979 9980 /** 9981 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9982 * @param app object of the crashing app, null for the system server 9983 * @param tag reported by the caller 9984 * @param crashInfo describing the context of the error 9985 * @return true if the process should exit immediately (WTF is fatal) 9986 */ 9987 public boolean handleApplicationWtf(IBinder app, String tag, 9988 ApplicationErrorReport.CrashInfo crashInfo) { 9989 ProcessRecord r = findAppProcess(app, "WTF"); 9990 final String processName = app == null ? "system_server" 9991 : (r == null ? "unknown" : r.processName); 9992 9993 EventLog.writeEvent(EventLogTags.AM_WTF, 9994 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9995 processName, 9996 r == null ? -1 : r.info.flags, 9997 tag, crashInfo.exceptionMessage); 9998 9999 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10000 10001 if (r != null && r.pid != Process.myPid() && 10002 Settings.Global.getInt(mContext.getContentResolver(), 10003 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10004 crashApplication(r, crashInfo); 10005 return true; 10006 } else { 10007 return false; 10008 } 10009 } 10010 10011 /** 10012 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10013 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10014 */ 10015 private ProcessRecord findAppProcess(IBinder app, String reason) { 10016 if (app == null) { 10017 return null; 10018 } 10019 10020 synchronized (this) { 10021 final int NP = mProcessNames.getMap().size(); 10022 for (int ip=0; ip<NP; ip++) { 10023 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10024 final int NA = apps.size(); 10025 for (int ia=0; ia<NA; ia++) { 10026 ProcessRecord p = apps.valueAt(ia); 10027 if (p.thread != null && p.thread.asBinder() == app) { 10028 return p; 10029 } 10030 } 10031 } 10032 10033 Slog.w(TAG, "Can't find mystery application for " + reason 10034 + " from pid=" + Binder.getCallingPid() 10035 + " uid=" + Binder.getCallingUid() + ": " + app); 10036 return null; 10037 } 10038 } 10039 10040 /** 10041 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10042 * to append various headers to the dropbox log text. 10043 */ 10044 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10045 StringBuilder sb) { 10046 // Watchdog thread ends up invoking this function (with 10047 // a null ProcessRecord) to add the stack file to dropbox. 10048 // Do not acquire a lock on this (am) in such cases, as it 10049 // could cause a potential deadlock, if and when watchdog 10050 // is invoked due to unavailability of lock on am and it 10051 // would prevent watchdog from killing system_server. 10052 if (process == null) { 10053 sb.append("Process: ").append(processName).append("\n"); 10054 return; 10055 } 10056 // Note: ProcessRecord 'process' is guarded by the service 10057 // instance. (notably process.pkgList, which could otherwise change 10058 // concurrently during execution of this method) 10059 synchronized (this) { 10060 sb.append("Process: ").append(processName).append("\n"); 10061 int flags = process.info.flags; 10062 IPackageManager pm = AppGlobals.getPackageManager(); 10063 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10064 for (int ip=0; ip<process.pkgList.size(); ip++) { 10065 String pkg = process.pkgList.keyAt(ip); 10066 sb.append("Package: ").append(pkg); 10067 try { 10068 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10069 if (pi != null) { 10070 sb.append(" v").append(pi.versionCode); 10071 if (pi.versionName != null) { 10072 sb.append(" (").append(pi.versionName).append(")"); 10073 } 10074 } 10075 } catch (RemoteException e) { 10076 Slog.e(TAG, "Error getting package info: " + pkg, e); 10077 } 10078 sb.append("\n"); 10079 } 10080 } 10081 } 10082 10083 private static String processClass(ProcessRecord process) { 10084 if (process == null || process.pid == MY_PID) { 10085 return "system_server"; 10086 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10087 return "system_app"; 10088 } else { 10089 return "data_app"; 10090 } 10091 } 10092 10093 /** 10094 * Write a description of an error (crash, WTF, ANR) to the drop box. 10095 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10096 * @param process which caused the error, null means the system server 10097 * @param activity which triggered the error, null if unknown 10098 * @param parent activity related to the error, null if unknown 10099 * @param subject line related to the error, null if absent 10100 * @param report in long form describing the error, null if absent 10101 * @param logFile to include in the report, null if none 10102 * @param crashInfo giving an application stack trace, null if absent 10103 */ 10104 public void addErrorToDropBox(String eventType, 10105 ProcessRecord process, String processName, ActivityRecord activity, 10106 ActivityRecord parent, String subject, 10107 final String report, final File logFile, 10108 final ApplicationErrorReport.CrashInfo crashInfo) { 10109 // NOTE -- this must never acquire the ActivityManagerService lock, 10110 // otherwise the watchdog may be prevented from resetting the system. 10111 10112 final String dropboxTag = processClass(process) + "_" + eventType; 10113 final DropBoxManager dbox = (DropBoxManager) 10114 mContext.getSystemService(Context.DROPBOX_SERVICE); 10115 10116 // Exit early if the dropbox isn't configured to accept this report type. 10117 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10118 10119 final StringBuilder sb = new StringBuilder(1024); 10120 appendDropBoxProcessHeaders(process, processName, sb); 10121 if (activity != null) { 10122 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10123 } 10124 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10125 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10126 } 10127 if (parent != null && parent != activity) { 10128 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10129 } 10130 if (subject != null) { 10131 sb.append("Subject: ").append(subject).append("\n"); 10132 } 10133 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10134 if (Debug.isDebuggerConnected()) { 10135 sb.append("Debugger: Connected\n"); 10136 } 10137 sb.append("\n"); 10138 10139 // Do the rest in a worker thread to avoid blocking the caller on I/O 10140 // (After this point, we shouldn't access AMS internal data structures.) 10141 Thread worker = new Thread("Error dump: " + dropboxTag) { 10142 @Override 10143 public void run() { 10144 if (report != null) { 10145 sb.append(report); 10146 } 10147 if (logFile != null) { 10148 try { 10149 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10150 "\n\n[[TRUNCATED]]")); 10151 } catch (IOException e) { 10152 Slog.e(TAG, "Error reading " + logFile, e); 10153 } 10154 } 10155 if (crashInfo != null && crashInfo.stackTrace != null) { 10156 sb.append(crashInfo.stackTrace); 10157 } 10158 10159 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10160 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10161 if (lines > 0) { 10162 sb.append("\n"); 10163 10164 // Merge several logcat streams, and take the last N lines 10165 InputStreamReader input = null; 10166 try { 10167 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10168 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10169 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10170 10171 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10172 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10173 input = new InputStreamReader(logcat.getInputStream()); 10174 10175 int num; 10176 char[] buf = new char[8192]; 10177 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10178 } catch (IOException e) { 10179 Slog.e(TAG, "Error running logcat", e); 10180 } finally { 10181 if (input != null) try { input.close(); } catch (IOException e) {} 10182 } 10183 } 10184 10185 dbox.addText(dropboxTag, sb.toString()); 10186 } 10187 }; 10188 10189 if (process == null) { 10190 // If process is null, we are being called from some internal code 10191 // and may be about to die -- run this synchronously. 10192 worker.run(); 10193 } else { 10194 worker.start(); 10195 } 10196 } 10197 10198 /** 10199 * Bring up the "unexpected error" dialog box for a crashing app. 10200 * Deal with edge cases (intercepts from instrumented applications, 10201 * ActivityController, error intent receivers, that sort of thing). 10202 * @param r the application crashing 10203 * @param crashInfo describing the failure 10204 */ 10205 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10206 long timeMillis = System.currentTimeMillis(); 10207 String shortMsg = crashInfo.exceptionClassName; 10208 String longMsg = crashInfo.exceptionMessage; 10209 String stackTrace = crashInfo.stackTrace; 10210 if (shortMsg != null && longMsg != null) { 10211 longMsg = shortMsg + ": " + longMsg; 10212 } else if (shortMsg != null) { 10213 longMsg = shortMsg; 10214 } 10215 10216 AppErrorResult result = new AppErrorResult(); 10217 synchronized (this) { 10218 if (mController != null) { 10219 try { 10220 String name = r != null ? r.processName : null; 10221 int pid = r != null ? r.pid : Binder.getCallingPid(); 10222 if (!mController.appCrashed(name, pid, 10223 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10224 Slog.w(TAG, "Force-killing crashed app " + name 10225 + " at watcher's request"); 10226 Process.killProcess(pid); 10227 return; 10228 } 10229 } catch (RemoteException e) { 10230 mController = null; 10231 Watchdog.getInstance().setActivityController(null); 10232 } 10233 } 10234 10235 final long origId = Binder.clearCallingIdentity(); 10236 10237 // If this process is running instrumentation, finish it. 10238 if (r != null && r.instrumentationClass != null) { 10239 Slog.w(TAG, "Error in app " + r.processName 10240 + " running instrumentation " + r.instrumentationClass + ":"); 10241 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10242 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10243 Bundle info = new Bundle(); 10244 info.putString("shortMsg", shortMsg); 10245 info.putString("longMsg", longMsg); 10246 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10247 Binder.restoreCallingIdentity(origId); 10248 return; 10249 } 10250 10251 // If we can't identify the process or it's already exceeded its crash quota, 10252 // quit right away without showing a crash dialog. 10253 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10254 Binder.restoreCallingIdentity(origId); 10255 return; 10256 } 10257 10258 Message msg = Message.obtain(); 10259 msg.what = SHOW_ERROR_MSG; 10260 HashMap data = new HashMap(); 10261 data.put("result", result); 10262 data.put("app", r); 10263 msg.obj = data; 10264 mHandler.sendMessage(msg); 10265 10266 Binder.restoreCallingIdentity(origId); 10267 } 10268 10269 int res = result.get(); 10270 10271 Intent appErrorIntent = null; 10272 synchronized (this) { 10273 if (r != null && !r.isolated) { 10274 // XXX Can't keep track of crash time for isolated processes, 10275 // since they don't have a persistent identity. 10276 mProcessCrashTimes.put(r.info.processName, r.uid, 10277 SystemClock.uptimeMillis()); 10278 } 10279 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10280 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10281 } 10282 } 10283 10284 if (appErrorIntent != null) { 10285 try { 10286 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10287 } catch (ActivityNotFoundException e) { 10288 Slog.w(TAG, "bug report receiver dissappeared", e); 10289 } 10290 } 10291 } 10292 10293 Intent createAppErrorIntentLocked(ProcessRecord r, 10294 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10295 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10296 if (report == null) { 10297 return null; 10298 } 10299 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10300 result.setComponent(r.errorReportReceiver); 10301 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10302 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10303 return result; 10304 } 10305 10306 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10307 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10308 if (r.errorReportReceiver == null) { 10309 return null; 10310 } 10311 10312 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10313 return null; 10314 } 10315 10316 ApplicationErrorReport report = new ApplicationErrorReport(); 10317 report.packageName = r.info.packageName; 10318 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10319 report.processName = r.processName; 10320 report.time = timeMillis; 10321 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10322 10323 if (r.crashing || r.forceCrashReport) { 10324 report.type = ApplicationErrorReport.TYPE_CRASH; 10325 report.crashInfo = crashInfo; 10326 } else if (r.notResponding) { 10327 report.type = ApplicationErrorReport.TYPE_ANR; 10328 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10329 10330 report.anrInfo.activity = r.notRespondingReport.tag; 10331 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10332 report.anrInfo.info = r.notRespondingReport.longMsg; 10333 } 10334 10335 return report; 10336 } 10337 10338 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10339 enforceNotIsolatedCaller("getProcessesInErrorState"); 10340 // assume our apps are happy - lazy create the list 10341 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10342 10343 final boolean allUsers = ActivityManager.checkUidPermission( 10344 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10345 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10346 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10347 10348 synchronized (this) { 10349 10350 // iterate across all processes 10351 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10352 ProcessRecord app = mLruProcesses.get(i); 10353 if (!allUsers && app.userId != userId) { 10354 continue; 10355 } 10356 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10357 // This one's in trouble, so we'll generate a report for it 10358 // crashes are higher priority (in case there's a crash *and* an anr) 10359 ActivityManager.ProcessErrorStateInfo report = null; 10360 if (app.crashing) { 10361 report = app.crashingReport; 10362 } else if (app.notResponding) { 10363 report = app.notRespondingReport; 10364 } 10365 10366 if (report != null) { 10367 if (errList == null) { 10368 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10369 } 10370 errList.add(report); 10371 } else { 10372 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10373 " crashing = " + app.crashing + 10374 " notResponding = " + app.notResponding); 10375 } 10376 } 10377 } 10378 } 10379 10380 return errList; 10381 } 10382 10383 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10384 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10385 if (currApp != null) { 10386 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10387 } 10388 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10389 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10390 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10391 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10392 if (currApp != null) { 10393 currApp.lru = 0; 10394 } 10395 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10396 } else if (adj >= ProcessList.SERVICE_ADJ) { 10397 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10398 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10399 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10400 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10401 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10402 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10403 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10404 } else { 10405 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10406 } 10407 } 10408 10409 private void fillInProcMemInfo(ProcessRecord app, 10410 ActivityManager.RunningAppProcessInfo outInfo) { 10411 outInfo.pid = app.pid; 10412 outInfo.uid = app.info.uid; 10413 if (mHeavyWeightProcess == app) { 10414 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10415 } 10416 if (app.persistent) { 10417 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10418 } 10419 if (app.activities.size() > 0) { 10420 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10421 } 10422 outInfo.lastTrimLevel = app.trimMemoryLevel; 10423 int adj = app.curAdj; 10424 outInfo.importance = oomAdjToImportance(adj, outInfo); 10425 outInfo.importanceReasonCode = app.adjTypeCode; 10426 } 10427 10428 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10429 enforceNotIsolatedCaller("getRunningAppProcesses"); 10430 // Lazy instantiation of list 10431 List<ActivityManager.RunningAppProcessInfo> runList = null; 10432 final boolean allUsers = ActivityManager.checkUidPermission( 10433 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10434 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10435 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10436 synchronized (this) { 10437 // Iterate across all processes 10438 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10439 ProcessRecord app = mLruProcesses.get(i); 10440 if (!allUsers && app.userId != userId) { 10441 continue; 10442 } 10443 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10444 // Generate process state info for running application 10445 ActivityManager.RunningAppProcessInfo currApp = 10446 new ActivityManager.RunningAppProcessInfo(app.processName, 10447 app.pid, app.getPackageList()); 10448 fillInProcMemInfo(app, currApp); 10449 if (app.adjSource instanceof ProcessRecord) { 10450 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10451 currApp.importanceReasonImportance = oomAdjToImportance( 10452 app.adjSourceOom, null); 10453 } else if (app.adjSource instanceof ActivityRecord) { 10454 ActivityRecord r = (ActivityRecord)app.adjSource; 10455 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10456 } 10457 if (app.adjTarget instanceof ComponentName) { 10458 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10459 } 10460 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10461 // + " lru=" + currApp.lru); 10462 if (runList == null) { 10463 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10464 } 10465 runList.add(currApp); 10466 } 10467 } 10468 } 10469 return runList; 10470 } 10471 10472 public List<ApplicationInfo> getRunningExternalApplications() { 10473 enforceNotIsolatedCaller("getRunningExternalApplications"); 10474 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10475 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10476 if (runningApps != null && runningApps.size() > 0) { 10477 Set<String> extList = new HashSet<String>(); 10478 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10479 if (app.pkgList != null) { 10480 for (String pkg : app.pkgList) { 10481 extList.add(pkg); 10482 } 10483 } 10484 } 10485 IPackageManager pm = AppGlobals.getPackageManager(); 10486 for (String pkg : extList) { 10487 try { 10488 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10489 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10490 retList.add(info); 10491 } 10492 } catch (RemoteException e) { 10493 } 10494 } 10495 } 10496 return retList; 10497 } 10498 10499 @Override 10500 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10501 enforceNotIsolatedCaller("getMyMemoryState"); 10502 synchronized (this) { 10503 ProcessRecord proc; 10504 synchronized (mPidsSelfLocked) { 10505 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10506 } 10507 fillInProcMemInfo(proc, outInfo); 10508 } 10509 } 10510 10511 @Override 10512 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10513 if (checkCallingPermission(android.Manifest.permission.DUMP) 10514 != PackageManager.PERMISSION_GRANTED) { 10515 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10516 + Binder.getCallingPid() 10517 + ", uid=" + Binder.getCallingUid() 10518 + " without permission " 10519 + android.Manifest.permission.DUMP); 10520 return; 10521 } 10522 10523 boolean dumpAll = false; 10524 boolean dumpClient = false; 10525 String dumpPackage = null; 10526 10527 int opti = 0; 10528 while (opti < args.length) { 10529 String opt = args[opti]; 10530 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10531 break; 10532 } 10533 opti++; 10534 if ("-a".equals(opt)) { 10535 dumpAll = true; 10536 } else if ("-c".equals(opt)) { 10537 dumpClient = true; 10538 } else if ("-h".equals(opt)) { 10539 pw.println("Activity manager dump options:"); 10540 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10541 pw.println(" cmd may be one of:"); 10542 pw.println(" a[ctivities]: activity stack state"); 10543 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10544 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10545 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10546 pw.println(" o[om]: out of memory management"); 10547 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10548 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10549 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10550 pw.println(" service [COMP_SPEC]: service client-side state"); 10551 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10552 pw.println(" all: dump all activities"); 10553 pw.println(" top: dump the top activity"); 10554 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10555 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10556 pw.println(" a partial substring in a component name, a"); 10557 pw.println(" hex object identifier."); 10558 pw.println(" -a: include all available server state."); 10559 pw.println(" -c: include client state."); 10560 return; 10561 } else { 10562 pw.println("Unknown argument: " + opt + "; use -h for help"); 10563 } 10564 } 10565 10566 long origId = Binder.clearCallingIdentity(); 10567 boolean more = false; 10568 // Is the caller requesting to dump a particular piece of data? 10569 if (opti < args.length) { 10570 String cmd = args[opti]; 10571 opti++; 10572 if ("activities".equals(cmd) || "a".equals(cmd)) { 10573 synchronized (this) { 10574 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10575 } 10576 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10577 String[] newArgs; 10578 String name; 10579 if (opti >= args.length) { 10580 name = null; 10581 newArgs = EMPTY_STRING_ARRAY; 10582 } else { 10583 name = args[opti]; 10584 opti++; 10585 newArgs = new String[args.length - opti]; 10586 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10587 args.length - opti); 10588 } 10589 synchronized (this) { 10590 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10591 } 10592 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10593 String[] newArgs; 10594 String name; 10595 if (opti >= args.length) { 10596 name = null; 10597 newArgs = EMPTY_STRING_ARRAY; 10598 } else { 10599 name = args[opti]; 10600 opti++; 10601 newArgs = new String[args.length - opti]; 10602 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10603 args.length - opti); 10604 } 10605 synchronized (this) { 10606 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10607 } 10608 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10609 String[] newArgs; 10610 String name; 10611 if (opti >= args.length) { 10612 name = null; 10613 newArgs = EMPTY_STRING_ARRAY; 10614 } else { 10615 name = args[opti]; 10616 opti++; 10617 newArgs = new String[args.length - opti]; 10618 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10619 args.length - opti); 10620 } 10621 synchronized (this) { 10622 dumpProcessesLocked(fd, pw, args, opti, true, name); 10623 } 10624 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10625 synchronized (this) { 10626 dumpOomLocked(fd, pw, args, opti, true); 10627 } 10628 } else if ("provider".equals(cmd)) { 10629 String[] newArgs; 10630 String name; 10631 if (opti >= args.length) { 10632 name = null; 10633 newArgs = EMPTY_STRING_ARRAY; 10634 } else { 10635 name = args[opti]; 10636 opti++; 10637 newArgs = new String[args.length - opti]; 10638 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10639 } 10640 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10641 pw.println("No providers match: " + name); 10642 pw.println("Use -h for help."); 10643 } 10644 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10645 synchronized (this) { 10646 dumpProvidersLocked(fd, pw, args, opti, true, null); 10647 } 10648 } else if ("service".equals(cmd)) { 10649 String[] newArgs; 10650 String name; 10651 if (opti >= args.length) { 10652 name = null; 10653 newArgs = EMPTY_STRING_ARRAY; 10654 } else { 10655 name = args[opti]; 10656 opti++; 10657 newArgs = new String[args.length - opti]; 10658 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10659 args.length - opti); 10660 } 10661 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10662 pw.println("No services match: " + name); 10663 pw.println("Use -h for help."); 10664 } 10665 } else if ("package".equals(cmd)) { 10666 String[] newArgs; 10667 if (opti >= args.length) { 10668 pw.println("package: no package name specified"); 10669 pw.println("Use -h for help."); 10670 } else { 10671 dumpPackage = args[opti]; 10672 opti++; 10673 newArgs = new String[args.length - opti]; 10674 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10675 args.length - opti); 10676 args = newArgs; 10677 opti = 0; 10678 more = true; 10679 } 10680 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10681 synchronized (this) { 10682 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10683 } 10684 } else { 10685 // Dumping a single activity? 10686 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10687 pw.println("Bad activity command, or no activities match: " + cmd); 10688 pw.println("Use -h for help."); 10689 } 10690 } 10691 if (!more) { 10692 Binder.restoreCallingIdentity(origId); 10693 return; 10694 } 10695 } 10696 10697 // No piece of data specified, dump everything. 10698 synchronized (this) { 10699 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10700 pw.println(); 10701 if (dumpAll) { 10702 pw.println("-------------------------------------------------------------------------------"); 10703 } 10704 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10705 pw.println(); 10706 if (dumpAll) { 10707 pw.println("-------------------------------------------------------------------------------"); 10708 } 10709 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10710 pw.println(); 10711 if (dumpAll) { 10712 pw.println("-------------------------------------------------------------------------------"); 10713 } 10714 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10715 pw.println(); 10716 if (dumpAll) { 10717 pw.println("-------------------------------------------------------------------------------"); 10718 } 10719 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10720 pw.println(); 10721 if (dumpAll) { 10722 pw.println("-------------------------------------------------------------------------------"); 10723 } 10724 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10725 } 10726 Binder.restoreCallingIdentity(origId); 10727 } 10728 10729 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10730 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10731 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10732 10733 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10734 dumpPackage); 10735 boolean needSep = printedAnything; 10736 10737 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10738 dumpPackage, needSep, " mFocusedActivity: "); 10739 if (printed) { 10740 printedAnything = true; 10741 needSep = false; 10742 } 10743 10744 if (dumpPackage == null) { 10745 if (needSep) { 10746 pw.println(); 10747 } 10748 needSep = true; 10749 printedAnything = true; 10750 mStackSupervisor.dump(pw, " "); 10751 } 10752 10753 if (mRecentTasks.size() > 0) { 10754 boolean printedHeader = false; 10755 10756 final int N = mRecentTasks.size(); 10757 for (int i=0; i<N; i++) { 10758 TaskRecord tr = mRecentTasks.get(i); 10759 if (dumpPackage != null) { 10760 if (tr.realActivity == null || 10761 !dumpPackage.equals(tr.realActivity)) { 10762 continue; 10763 } 10764 } 10765 if (!printedHeader) { 10766 if (needSep) { 10767 pw.println(); 10768 } 10769 pw.println(" Recent tasks:"); 10770 printedHeader = true; 10771 printedAnything = true; 10772 } 10773 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10774 pw.println(tr); 10775 if (dumpAll) { 10776 mRecentTasks.get(i).dump(pw, " "); 10777 } 10778 } 10779 } 10780 10781 if (!printedAnything) { 10782 pw.println(" (nothing)"); 10783 } 10784 } 10785 10786 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10787 int opti, boolean dumpAll, String dumpPackage) { 10788 boolean needSep = false; 10789 boolean printedAnything = false; 10790 int numPers = 0; 10791 10792 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10793 10794 if (dumpAll) { 10795 final int NP = mProcessNames.getMap().size(); 10796 for (int ip=0; ip<NP; ip++) { 10797 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10798 final int NA = procs.size(); 10799 for (int ia=0; ia<NA; ia++) { 10800 ProcessRecord r = procs.valueAt(ia); 10801 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10802 continue; 10803 } 10804 if (!needSep) { 10805 pw.println(" All known processes:"); 10806 needSep = true; 10807 printedAnything = true; 10808 } 10809 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10810 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10811 pw.print(" "); pw.println(r); 10812 r.dump(pw, " "); 10813 if (r.persistent) { 10814 numPers++; 10815 } 10816 } 10817 } 10818 } 10819 10820 if (mIsolatedProcesses.size() > 0) { 10821 boolean printed = false; 10822 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10823 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10824 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10825 continue; 10826 } 10827 if (!printed) { 10828 if (needSep) { 10829 pw.println(); 10830 } 10831 pw.println(" Isolated process list (sorted by uid):"); 10832 printedAnything = true; 10833 printed = true; 10834 needSep = true; 10835 } 10836 pw.println(String.format("%sIsolated #%2d: %s", 10837 " ", i, r.toString())); 10838 } 10839 } 10840 10841 if (mLruProcesses.size() > 0) { 10842 if (needSep) { 10843 pw.println(); 10844 } 10845 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10846 pw.print(" total, non-act at "); 10847 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10848 pw.print(", non-svc at "); 10849 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10850 pw.println("):"); 10851 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10852 needSep = true; 10853 printedAnything = true; 10854 } 10855 10856 if (dumpAll || dumpPackage != null) { 10857 synchronized (mPidsSelfLocked) { 10858 boolean printed = false; 10859 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10860 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10861 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10862 continue; 10863 } 10864 if (!printed) { 10865 if (needSep) pw.println(); 10866 needSep = true; 10867 pw.println(" PID mappings:"); 10868 printed = true; 10869 printedAnything = true; 10870 } 10871 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10872 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10873 } 10874 } 10875 } 10876 10877 if (mForegroundProcesses.size() > 0) { 10878 synchronized (mPidsSelfLocked) { 10879 boolean printed = false; 10880 for (int i=0; i<mForegroundProcesses.size(); i++) { 10881 ProcessRecord r = mPidsSelfLocked.get( 10882 mForegroundProcesses.valueAt(i).pid); 10883 if (dumpPackage != null && (r == null 10884 || !r.pkgList.containsKey(dumpPackage))) { 10885 continue; 10886 } 10887 if (!printed) { 10888 if (needSep) pw.println(); 10889 needSep = true; 10890 pw.println(" Foreground Processes:"); 10891 printed = true; 10892 printedAnything = true; 10893 } 10894 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10895 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10896 } 10897 } 10898 } 10899 10900 if (mPersistentStartingProcesses.size() > 0) { 10901 if (needSep) pw.println(); 10902 needSep = true; 10903 printedAnything = true; 10904 pw.println(" Persisent processes that are starting:"); 10905 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10906 "Starting Norm", "Restarting PERS", dumpPackage); 10907 } 10908 10909 if (mRemovedProcesses.size() > 0) { 10910 if (needSep) pw.println(); 10911 needSep = true; 10912 printedAnything = true; 10913 pw.println(" Processes that are being removed:"); 10914 dumpProcessList(pw, this, mRemovedProcesses, " ", 10915 "Removed Norm", "Removed PERS", dumpPackage); 10916 } 10917 10918 if (mProcessesOnHold.size() > 0) { 10919 if (needSep) pw.println(); 10920 needSep = true; 10921 printedAnything = true; 10922 pw.println(" Processes that are on old until the system is ready:"); 10923 dumpProcessList(pw, this, mProcessesOnHold, " ", 10924 "OnHold Norm", "OnHold PERS", dumpPackage); 10925 } 10926 10927 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10928 10929 if (mProcessCrashTimes.getMap().size() > 0) { 10930 boolean printed = false; 10931 long now = SystemClock.uptimeMillis(); 10932 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10933 final int NP = pmap.size(); 10934 for (int ip=0; ip<NP; ip++) { 10935 String pname = pmap.keyAt(ip); 10936 SparseArray<Long> uids = pmap.valueAt(ip); 10937 final int N = uids.size(); 10938 for (int i=0; i<N; i++) { 10939 int puid = uids.keyAt(i); 10940 ProcessRecord r = mProcessNames.get(pname, puid); 10941 if (dumpPackage != null && (r == null 10942 || !r.pkgList.containsKey(dumpPackage))) { 10943 continue; 10944 } 10945 if (!printed) { 10946 if (needSep) pw.println(); 10947 needSep = true; 10948 pw.println(" Time since processes crashed:"); 10949 printed = true; 10950 printedAnything = true; 10951 } 10952 pw.print(" Process "); pw.print(pname); 10953 pw.print(" uid "); pw.print(puid); 10954 pw.print(": last crashed "); 10955 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10956 pw.println(" ago"); 10957 } 10958 } 10959 } 10960 10961 if (mBadProcesses.getMap().size() > 0) { 10962 boolean printed = false; 10963 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10964 final int NP = pmap.size(); 10965 for (int ip=0; ip<NP; ip++) { 10966 String pname = pmap.keyAt(ip); 10967 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10968 final int N = uids.size(); 10969 for (int i=0; i<N; i++) { 10970 int puid = uids.keyAt(i); 10971 ProcessRecord r = mProcessNames.get(pname, puid); 10972 if (dumpPackage != null && (r == null 10973 || !r.pkgList.containsKey(dumpPackage))) { 10974 continue; 10975 } 10976 if (!printed) { 10977 if (needSep) pw.println(); 10978 needSep = true; 10979 pw.println(" Bad processes:"); 10980 printedAnything = true; 10981 } 10982 BadProcessInfo info = uids.valueAt(i); 10983 pw.print(" Bad process "); pw.print(pname); 10984 pw.print(" uid "); pw.print(puid); 10985 pw.print(": crashed at time "); pw.println(info.time); 10986 if (info.shortMsg != null) { 10987 pw.print(" Short msg: "); pw.println(info.shortMsg); 10988 } 10989 if (info.longMsg != null) { 10990 pw.print(" Long msg: "); pw.println(info.longMsg); 10991 } 10992 if (info.stack != null) { 10993 pw.println(" Stack:"); 10994 int lastPos = 0; 10995 for (int pos=0; pos<info.stack.length(); pos++) { 10996 if (info.stack.charAt(pos) == '\n') { 10997 pw.print(" "); 10998 pw.write(info.stack, lastPos, pos-lastPos); 10999 pw.println(); 11000 lastPos = pos+1; 11001 } 11002 } 11003 if (lastPos < info.stack.length()) { 11004 pw.print(" "); 11005 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11006 pw.println(); 11007 } 11008 } 11009 } 11010 } 11011 } 11012 11013 if (dumpPackage == null) { 11014 pw.println(); 11015 needSep = false; 11016 pw.println(" mStartedUsers:"); 11017 for (int i=0; i<mStartedUsers.size(); i++) { 11018 UserStartedState uss = mStartedUsers.valueAt(i); 11019 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11020 pw.print(": "); uss.dump("", pw); 11021 } 11022 pw.print(" mStartedUserArray: ["); 11023 for (int i=0; i<mStartedUserArray.length; i++) { 11024 if (i > 0) pw.print(", "); 11025 pw.print(mStartedUserArray[i]); 11026 } 11027 pw.println("]"); 11028 pw.print(" mUserLru: ["); 11029 for (int i=0; i<mUserLru.size(); i++) { 11030 if (i > 0) pw.print(", "); 11031 pw.print(mUserLru.get(i)); 11032 } 11033 pw.println("]"); 11034 if (dumpAll) { 11035 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11036 } 11037 } 11038 if (mHomeProcess != null && (dumpPackage == null 11039 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11040 if (needSep) { 11041 pw.println(); 11042 needSep = false; 11043 } 11044 pw.println(" mHomeProcess: " + mHomeProcess); 11045 } 11046 if (mPreviousProcess != null && (dumpPackage == null 11047 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11048 if (needSep) { 11049 pw.println(); 11050 needSep = false; 11051 } 11052 pw.println(" mPreviousProcess: " + mPreviousProcess); 11053 } 11054 if (dumpAll) { 11055 StringBuilder sb = new StringBuilder(128); 11056 sb.append(" mPreviousProcessVisibleTime: "); 11057 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11058 pw.println(sb); 11059 } 11060 if (mHeavyWeightProcess != null && (dumpPackage == null 11061 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11062 if (needSep) { 11063 pw.println(); 11064 needSep = false; 11065 } 11066 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11067 } 11068 if (dumpPackage == null) { 11069 pw.println(" mConfiguration: " + mConfiguration); 11070 } 11071 if (dumpAll) { 11072 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11073 if (mCompatModePackages.getPackages().size() > 0) { 11074 boolean printed = false; 11075 for (Map.Entry<String, Integer> entry 11076 : mCompatModePackages.getPackages().entrySet()) { 11077 String pkg = entry.getKey(); 11078 int mode = entry.getValue(); 11079 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11080 continue; 11081 } 11082 if (!printed) { 11083 pw.println(" mScreenCompatPackages:"); 11084 printed = true; 11085 } 11086 pw.print(" "); pw.print(pkg); pw.print(": "); 11087 pw.print(mode); pw.println(); 11088 } 11089 } 11090 } 11091 if (dumpPackage == null) { 11092 if (mSleeping || mWentToSleep || mLockScreenShown) { 11093 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11094 + " mLockScreenShown " + mLockScreenShown); 11095 } 11096 if (mShuttingDown) { 11097 pw.println(" mShuttingDown=" + mShuttingDown); 11098 } 11099 } 11100 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11101 || mOrigWaitForDebugger) { 11102 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11103 || dumpPackage.equals(mOrigDebugApp)) { 11104 if (needSep) { 11105 pw.println(); 11106 needSep = false; 11107 } 11108 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11109 + " mDebugTransient=" + mDebugTransient 11110 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11111 } 11112 } 11113 if (mOpenGlTraceApp != null) { 11114 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11115 if (needSep) { 11116 pw.println(); 11117 needSep = false; 11118 } 11119 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11120 } 11121 } 11122 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11123 || mProfileFd != null) { 11124 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11125 if (needSep) { 11126 pw.println(); 11127 needSep = false; 11128 } 11129 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11130 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11131 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11132 + mAutoStopProfiler); 11133 } 11134 } 11135 if (dumpPackage == null) { 11136 if (mAlwaysFinishActivities || mController != null) { 11137 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11138 + " mController=" + mController); 11139 } 11140 if (dumpAll) { 11141 pw.println(" Total persistent processes: " + numPers); 11142 pw.println(" mStartRunning=" + mStartRunning 11143 + " mProcessesReady=" + mProcessesReady 11144 + " mSystemReady=" + mSystemReady); 11145 pw.println(" mBooting=" + mBooting 11146 + " mBooted=" + mBooted 11147 + " mFactoryTest=" + mFactoryTest); 11148 pw.print(" mLastPowerCheckRealtime="); 11149 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11150 pw.println(""); 11151 pw.print(" mLastPowerCheckUptime="); 11152 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11153 pw.println(""); 11154 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11155 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11156 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11157 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11158 + " (" + mLruProcesses.size() + " total)" 11159 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11160 + " mNumServiceProcs=" + mNumServiceProcs 11161 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11162 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11163 + " mLastMemoryLevel" + mLastMemoryLevel 11164 + " mLastNumProcesses" + mLastNumProcesses); 11165 long now = SystemClock.uptimeMillis(); 11166 pw.print(" mLastIdleTime="); 11167 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11168 pw.print(" mLowRamSinceLastIdle="); 11169 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11170 pw.println(); 11171 } 11172 } 11173 11174 if (!printedAnything) { 11175 pw.println(" (nothing)"); 11176 } 11177 } 11178 11179 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11180 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11181 if (mProcessesToGc.size() > 0) { 11182 boolean printed = false; 11183 long now = SystemClock.uptimeMillis(); 11184 for (int i=0; i<mProcessesToGc.size(); i++) { 11185 ProcessRecord proc = mProcessesToGc.get(i); 11186 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11187 continue; 11188 } 11189 if (!printed) { 11190 if (needSep) pw.println(); 11191 needSep = true; 11192 pw.println(" Processes that are waiting to GC:"); 11193 printed = true; 11194 } 11195 pw.print(" Process "); pw.println(proc); 11196 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11197 pw.print(", last gced="); 11198 pw.print(now-proc.lastRequestedGc); 11199 pw.print(" ms ago, last lowMem="); 11200 pw.print(now-proc.lastLowMemory); 11201 pw.println(" ms ago"); 11202 11203 } 11204 } 11205 return needSep; 11206 } 11207 11208 void printOomLevel(PrintWriter pw, String name, int adj) { 11209 pw.print(" "); 11210 if (adj >= 0) { 11211 pw.print(' '); 11212 if (adj < 10) pw.print(' '); 11213 } else { 11214 if (adj > -10) pw.print(' '); 11215 } 11216 pw.print(adj); 11217 pw.print(": "); 11218 pw.print(name); 11219 pw.print(" ("); 11220 pw.print(mProcessList.getMemLevel(adj)/1024); 11221 pw.println(" kB)"); 11222 } 11223 11224 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11225 int opti, boolean dumpAll) { 11226 boolean needSep = false; 11227 11228 if (mLruProcesses.size() > 0) { 11229 if (needSep) pw.println(); 11230 needSep = true; 11231 pw.println(" OOM levels:"); 11232 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11233 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11234 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11235 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11236 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11237 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11238 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11239 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11240 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11241 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11242 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11243 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11244 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11245 11246 if (needSep) pw.println(); 11247 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11248 pw.print(" total, non-act at "); 11249 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11250 pw.print(", non-svc at "); 11251 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11252 pw.println("):"); 11253 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11254 needSep = true; 11255 } 11256 11257 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11258 11259 pw.println(); 11260 pw.println(" mHomeProcess: " + mHomeProcess); 11261 pw.println(" mPreviousProcess: " + mPreviousProcess); 11262 if (mHeavyWeightProcess != null) { 11263 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11264 } 11265 11266 return true; 11267 } 11268 11269 /** 11270 * There are three ways to call this: 11271 * - no provider specified: dump all the providers 11272 * - a flattened component name that matched an existing provider was specified as the 11273 * first arg: dump that one provider 11274 * - the first arg isn't the flattened component name of an existing provider: 11275 * dump all providers whose component contains the first arg as a substring 11276 */ 11277 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11278 int opti, boolean dumpAll) { 11279 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11280 } 11281 11282 static class ItemMatcher { 11283 ArrayList<ComponentName> components; 11284 ArrayList<String> strings; 11285 ArrayList<Integer> objects; 11286 boolean all; 11287 11288 ItemMatcher() { 11289 all = true; 11290 } 11291 11292 void build(String name) { 11293 ComponentName componentName = ComponentName.unflattenFromString(name); 11294 if (componentName != null) { 11295 if (components == null) { 11296 components = new ArrayList<ComponentName>(); 11297 } 11298 components.add(componentName); 11299 all = false; 11300 } else { 11301 int objectId = 0; 11302 // Not a '/' separated full component name; maybe an object ID? 11303 try { 11304 objectId = Integer.parseInt(name, 16); 11305 if (objects == null) { 11306 objects = new ArrayList<Integer>(); 11307 } 11308 objects.add(objectId); 11309 all = false; 11310 } catch (RuntimeException e) { 11311 // Not an integer; just do string match. 11312 if (strings == null) { 11313 strings = new ArrayList<String>(); 11314 } 11315 strings.add(name); 11316 all = false; 11317 } 11318 } 11319 } 11320 11321 int build(String[] args, int opti) { 11322 for (; opti<args.length; opti++) { 11323 String name = args[opti]; 11324 if ("--".equals(name)) { 11325 return opti+1; 11326 } 11327 build(name); 11328 } 11329 return opti; 11330 } 11331 11332 boolean match(Object object, ComponentName comp) { 11333 if (all) { 11334 return true; 11335 } 11336 if (components != null) { 11337 for (int i=0; i<components.size(); i++) { 11338 if (components.get(i).equals(comp)) { 11339 return true; 11340 } 11341 } 11342 } 11343 if (objects != null) { 11344 for (int i=0; i<objects.size(); i++) { 11345 if (System.identityHashCode(object) == objects.get(i)) { 11346 return true; 11347 } 11348 } 11349 } 11350 if (strings != null) { 11351 String flat = comp.flattenToString(); 11352 for (int i=0; i<strings.size(); i++) { 11353 if (flat.contains(strings.get(i))) { 11354 return true; 11355 } 11356 } 11357 } 11358 return false; 11359 } 11360 } 11361 11362 /** 11363 * There are three things that cmd can be: 11364 * - a flattened component name that matches an existing activity 11365 * - the cmd arg isn't the flattened component name of an existing activity: 11366 * dump all activity whose component contains the cmd as a substring 11367 * - A hex number of the ActivityRecord object instance. 11368 */ 11369 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11370 int opti, boolean dumpAll) { 11371 ArrayList<ActivityRecord> activities; 11372 11373 synchronized (this) { 11374 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11375 } 11376 11377 if (activities.size() <= 0) { 11378 return false; 11379 } 11380 11381 String[] newArgs = new String[args.length - opti]; 11382 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11383 11384 TaskRecord lastTask = null; 11385 boolean needSep = false; 11386 for (int i=activities.size()-1; i>=0; i--) { 11387 ActivityRecord r = activities.get(i); 11388 if (needSep) { 11389 pw.println(); 11390 } 11391 needSep = true; 11392 synchronized (this) { 11393 if (lastTask != r.task) { 11394 lastTask = r.task; 11395 pw.print("TASK "); pw.print(lastTask.affinity); 11396 pw.print(" id="); pw.println(lastTask.taskId); 11397 if (dumpAll) { 11398 lastTask.dump(pw, " "); 11399 } 11400 } 11401 } 11402 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11403 } 11404 return true; 11405 } 11406 11407 /** 11408 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11409 * there is a thread associated with the activity. 11410 */ 11411 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11412 final ActivityRecord r, String[] args, boolean dumpAll) { 11413 String innerPrefix = prefix + " "; 11414 synchronized (this) { 11415 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11416 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11417 pw.print(" pid="); 11418 if (r.app != null) pw.println(r.app.pid); 11419 else pw.println("(not running)"); 11420 if (dumpAll) { 11421 r.dump(pw, innerPrefix); 11422 } 11423 } 11424 if (r.app != null && r.app.thread != null) { 11425 // flush anything that is already in the PrintWriter since the thread is going 11426 // to write to the file descriptor directly 11427 pw.flush(); 11428 try { 11429 TransferPipe tp = new TransferPipe(); 11430 try { 11431 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11432 r.appToken, innerPrefix, args); 11433 tp.go(fd); 11434 } finally { 11435 tp.kill(); 11436 } 11437 } catch (IOException e) { 11438 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11439 } catch (RemoteException e) { 11440 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11441 } 11442 } 11443 } 11444 11445 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11446 int opti, boolean dumpAll, String dumpPackage) { 11447 boolean needSep = false; 11448 boolean onlyHistory = false; 11449 boolean printedAnything = false; 11450 11451 if ("history".equals(dumpPackage)) { 11452 if (opti < args.length && "-s".equals(args[opti])) { 11453 dumpAll = false; 11454 } 11455 onlyHistory = true; 11456 dumpPackage = null; 11457 } 11458 11459 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11460 if (!onlyHistory && dumpAll) { 11461 if (mRegisteredReceivers.size() > 0) { 11462 boolean printed = false; 11463 Iterator it = mRegisteredReceivers.values().iterator(); 11464 while (it.hasNext()) { 11465 ReceiverList r = (ReceiverList)it.next(); 11466 if (dumpPackage != null && (r.app == null || 11467 !dumpPackage.equals(r.app.info.packageName))) { 11468 continue; 11469 } 11470 if (!printed) { 11471 pw.println(" Registered Receivers:"); 11472 needSep = true; 11473 printed = true; 11474 printedAnything = true; 11475 } 11476 pw.print(" * "); pw.println(r); 11477 r.dump(pw, " "); 11478 } 11479 } 11480 11481 if (mReceiverResolver.dump(pw, needSep ? 11482 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11483 " ", dumpPackage, false)) { 11484 needSep = true; 11485 printedAnything = true; 11486 } 11487 } 11488 11489 for (BroadcastQueue q : mBroadcastQueues) { 11490 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11491 printedAnything |= needSep; 11492 } 11493 11494 needSep = true; 11495 11496 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11497 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11498 if (needSep) { 11499 pw.println(); 11500 } 11501 needSep = true; 11502 printedAnything = true; 11503 pw.print(" Sticky broadcasts for user "); 11504 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11505 StringBuilder sb = new StringBuilder(128); 11506 for (Map.Entry<String, ArrayList<Intent>> ent 11507 : mStickyBroadcasts.valueAt(user).entrySet()) { 11508 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11509 if (dumpAll) { 11510 pw.println(":"); 11511 ArrayList<Intent> intents = ent.getValue(); 11512 final int N = intents.size(); 11513 for (int i=0; i<N; i++) { 11514 sb.setLength(0); 11515 sb.append(" Intent: "); 11516 intents.get(i).toShortString(sb, false, true, false, false); 11517 pw.println(sb.toString()); 11518 Bundle bundle = intents.get(i).getExtras(); 11519 if (bundle != null) { 11520 pw.print(" "); 11521 pw.println(bundle.toString()); 11522 } 11523 } 11524 } else { 11525 pw.println(""); 11526 } 11527 } 11528 } 11529 } 11530 11531 if (!onlyHistory && dumpAll) { 11532 pw.println(); 11533 for (BroadcastQueue queue : mBroadcastQueues) { 11534 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11535 + queue.mBroadcastsScheduled); 11536 } 11537 pw.println(" mHandler:"); 11538 mHandler.dump(new PrintWriterPrinter(pw), " "); 11539 needSep = true; 11540 printedAnything = true; 11541 } 11542 11543 if (!printedAnything) { 11544 pw.println(" (nothing)"); 11545 } 11546 } 11547 11548 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11549 int opti, boolean dumpAll, String dumpPackage) { 11550 boolean needSep; 11551 boolean printedAnything = false; 11552 11553 ItemMatcher matcher = new ItemMatcher(); 11554 matcher.build(args, opti); 11555 11556 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11557 11558 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11559 printedAnything |= needSep; 11560 11561 if (mLaunchingProviders.size() > 0) { 11562 boolean printed = false; 11563 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11564 ContentProviderRecord r = mLaunchingProviders.get(i); 11565 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11566 continue; 11567 } 11568 if (!printed) { 11569 if (needSep) pw.println(); 11570 needSep = true; 11571 pw.println(" Launching content providers:"); 11572 printed = true; 11573 printedAnything = true; 11574 } 11575 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11576 pw.println(r); 11577 } 11578 } 11579 11580 if (mGrantedUriPermissions.size() > 0) { 11581 boolean printed = false; 11582 int dumpUid = -2; 11583 if (dumpPackage != null) { 11584 try { 11585 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11586 } catch (NameNotFoundException e) { 11587 dumpUid = -1; 11588 } 11589 } 11590 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11591 int uid = mGrantedUriPermissions.keyAt(i); 11592 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11593 continue; 11594 } 11595 ArrayMap<Uri, UriPermission> perms 11596 = mGrantedUriPermissions.valueAt(i); 11597 if (!printed) { 11598 if (needSep) pw.println(); 11599 needSep = true; 11600 pw.println(" Granted Uri Permissions:"); 11601 printed = true; 11602 printedAnything = true; 11603 } 11604 pw.print(" * UID "); pw.print(uid); 11605 pw.println(" holds:"); 11606 for (UriPermission perm : perms.values()) { 11607 pw.print(" "); pw.println(perm); 11608 if (dumpAll) { 11609 perm.dump(pw, " "); 11610 } 11611 } 11612 } 11613 } 11614 11615 if (!printedAnything) { 11616 pw.println(" (nothing)"); 11617 } 11618 } 11619 11620 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11621 int opti, boolean dumpAll, String dumpPackage) { 11622 boolean printed = false; 11623 11624 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11625 11626 if (mIntentSenderRecords.size() > 0) { 11627 Iterator<WeakReference<PendingIntentRecord>> it 11628 = mIntentSenderRecords.values().iterator(); 11629 while (it.hasNext()) { 11630 WeakReference<PendingIntentRecord> ref = it.next(); 11631 PendingIntentRecord rec = ref != null ? ref.get(): null; 11632 if (dumpPackage != null && (rec == null 11633 || !dumpPackage.equals(rec.key.packageName))) { 11634 continue; 11635 } 11636 printed = true; 11637 if (rec != null) { 11638 pw.print(" * "); pw.println(rec); 11639 if (dumpAll) { 11640 rec.dump(pw, " "); 11641 } 11642 } else { 11643 pw.print(" * "); pw.println(ref); 11644 } 11645 } 11646 } 11647 11648 if (!printed) { 11649 pw.println(" (nothing)"); 11650 } 11651 } 11652 11653 private static final int dumpProcessList(PrintWriter pw, 11654 ActivityManagerService service, List list, 11655 String prefix, String normalLabel, String persistentLabel, 11656 String dumpPackage) { 11657 int numPers = 0; 11658 final int N = list.size()-1; 11659 for (int i=N; i>=0; i--) { 11660 ProcessRecord r = (ProcessRecord)list.get(i); 11661 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11662 continue; 11663 } 11664 pw.println(String.format("%s%s #%2d: %s", 11665 prefix, (r.persistent ? persistentLabel : normalLabel), 11666 i, r.toString())); 11667 if (r.persistent) { 11668 numPers++; 11669 } 11670 } 11671 return numPers; 11672 } 11673 11674 private static final boolean dumpProcessOomList(PrintWriter pw, 11675 ActivityManagerService service, List<ProcessRecord> origList, 11676 String prefix, String normalLabel, String persistentLabel, 11677 boolean inclDetails, String dumpPackage) { 11678 11679 ArrayList<Pair<ProcessRecord, Integer>> list 11680 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11681 for (int i=0; i<origList.size(); i++) { 11682 ProcessRecord r = origList.get(i); 11683 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11684 continue; 11685 } 11686 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11687 } 11688 11689 if (list.size() <= 0) { 11690 return false; 11691 } 11692 11693 Comparator<Pair<ProcessRecord, Integer>> comparator 11694 = new Comparator<Pair<ProcessRecord, Integer>>() { 11695 @Override 11696 public int compare(Pair<ProcessRecord, Integer> object1, 11697 Pair<ProcessRecord, Integer> object2) { 11698 if (object1.first.setAdj != object2.first.setAdj) { 11699 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11700 } 11701 if (object1.second.intValue() != object2.second.intValue()) { 11702 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11703 } 11704 return 0; 11705 } 11706 }; 11707 11708 Collections.sort(list, comparator); 11709 11710 final long curRealtime = SystemClock.elapsedRealtime(); 11711 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11712 final long curUptime = SystemClock.uptimeMillis(); 11713 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11714 11715 for (int i=list.size()-1; i>=0; i--) { 11716 ProcessRecord r = list.get(i).first; 11717 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11718 char schedGroup; 11719 switch (r.setSchedGroup) { 11720 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11721 schedGroup = 'B'; 11722 break; 11723 case Process.THREAD_GROUP_DEFAULT: 11724 schedGroup = 'F'; 11725 break; 11726 default: 11727 schedGroup = '?'; 11728 break; 11729 } 11730 char foreground; 11731 if (r.foregroundActivities) { 11732 foreground = 'A'; 11733 } else if (r.foregroundServices) { 11734 foreground = 'S'; 11735 } else { 11736 foreground = ' '; 11737 } 11738 String procState = ProcessList.makeProcStateString(r.curProcState); 11739 pw.print(prefix); 11740 pw.print(r.persistent ? persistentLabel : normalLabel); 11741 pw.print(" #"); 11742 int num = (origList.size()-1)-list.get(i).second; 11743 if (num < 10) pw.print(' '); 11744 pw.print(num); 11745 pw.print(": "); 11746 pw.print(oomAdj); 11747 pw.print(' '); 11748 pw.print(schedGroup); 11749 pw.print('/'); 11750 pw.print(foreground); 11751 pw.print('/'); 11752 pw.print(procState); 11753 pw.print(" trm:"); 11754 if (r.trimMemoryLevel < 10) pw.print(' '); 11755 pw.print(r.trimMemoryLevel); 11756 pw.print(' '); 11757 pw.print(r.toShortString()); 11758 pw.print(" ("); 11759 pw.print(r.adjType); 11760 pw.println(')'); 11761 if (r.adjSource != null || r.adjTarget != null) { 11762 pw.print(prefix); 11763 pw.print(" "); 11764 if (r.adjTarget instanceof ComponentName) { 11765 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11766 } else if (r.adjTarget != null) { 11767 pw.print(r.adjTarget.toString()); 11768 } else { 11769 pw.print("{null}"); 11770 } 11771 pw.print("<="); 11772 if (r.adjSource instanceof ProcessRecord) { 11773 pw.print("Proc{"); 11774 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11775 pw.println("}"); 11776 } else if (r.adjSource != null) { 11777 pw.println(r.adjSource.toString()); 11778 } else { 11779 pw.println("{null}"); 11780 } 11781 } 11782 if (inclDetails) { 11783 pw.print(prefix); 11784 pw.print(" "); 11785 pw.print("oom: max="); pw.print(r.maxAdj); 11786 pw.print(" curRaw="); pw.print(r.curRawAdj); 11787 pw.print(" setRaw="); pw.print(r.setRawAdj); 11788 pw.print(" cur="); pw.print(r.curAdj); 11789 pw.print(" set="); pw.println(r.setAdj); 11790 pw.print(prefix); 11791 pw.print(" "); 11792 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11793 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11794 pw.print(" lastPss="); pw.print(r.lastPss); 11795 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11796 pw.print(prefix); 11797 pw.print(" "); 11798 pw.print("keeping="); pw.print(r.keeping); 11799 pw.print(" cached="); pw.print(r.cached); 11800 pw.print(" empty="); pw.print(r.empty); 11801 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11802 11803 if (!r.keeping) { 11804 if (r.lastWakeTime != 0) { 11805 long wtime; 11806 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11807 synchronized (stats) { 11808 wtime = stats.getProcessWakeTime(r.info.uid, 11809 r.pid, curRealtime); 11810 } 11811 long timeUsed = wtime - r.lastWakeTime; 11812 pw.print(prefix); 11813 pw.print(" "); 11814 pw.print("keep awake over "); 11815 TimeUtils.formatDuration(realtimeSince, pw); 11816 pw.print(" used "); 11817 TimeUtils.formatDuration(timeUsed, pw); 11818 pw.print(" ("); 11819 pw.print((timeUsed*100)/realtimeSince); 11820 pw.println("%)"); 11821 } 11822 if (r.lastCpuTime != 0) { 11823 long timeUsed = r.curCpuTime - r.lastCpuTime; 11824 pw.print(prefix); 11825 pw.print(" "); 11826 pw.print("run cpu over "); 11827 TimeUtils.formatDuration(uptimeSince, pw); 11828 pw.print(" used "); 11829 TimeUtils.formatDuration(timeUsed, pw); 11830 pw.print(" ("); 11831 pw.print((timeUsed*100)/uptimeSince); 11832 pw.println("%)"); 11833 } 11834 } 11835 } 11836 } 11837 return true; 11838 } 11839 11840 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11841 ArrayList<ProcessRecord> procs; 11842 synchronized (this) { 11843 if (args != null && args.length > start 11844 && args[start].charAt(0) != '-') { 11845 procs = new ArrayList<ProcessRecord>(); 11846 int pid = -1; 11847 try { 11848 pid = Integer.parseInt(args[start]); 11849 } catch (NumberFormatException e) { 11850 } 11851 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11852 ProcessRecord proc = mLruProcesses.get(i); 11853 if (proc.pid == pid) { 11854 procs.add(proc); 11855 } else if (proc.processName.equals(args[start])) { 11856 procs.add(proc); 11857 } 11858 } 11859 if (procs.size() <= 0) { 11860 return null; 11861 } 11862 } else { 11863 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11864 } 11865 } 11866 return procs; 11867 } 11868 11869 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11870 PrintWriter pw, String[] args) { 11871 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11872 if (procs == null) { 11873 pw.println("No process found for: " + args[0]); 11874 return; 11875 } 11876 11877 long uptime = SystemClock.uptimeMillis(); 11878 long realtime = SystemClock.elapsedRealtime(); 11879 pw.println("Applications Graphics Acceleration Info:"); 11880 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11881 11882 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11883 ProcessRecord r = procs.get(i); 11884 if (r.thread != null) { 11885 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11886 pw.flush(); 11887 try { 11888 TransferPipe tp = new TransferPipe(); 11889 try { 11890 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11891 tp.go(fd); 11892 } finally { 11893 tp.kill(); 11894 } 11895 } catch (IOException e) { 11896 pw.println("Failure while dumping the app: " + r); 11897 pw.flush(); 11898 } catch (RemoteException e) { 11899 pw.println("Got a RemoteException while dumping the app " + r); 11900 pw.flush(); 11901 } 11902 } 11903 } 11904 } 11905 11906 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11907 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11908 if (procs == null) { 11909 pw.println("No process found for: " + args[0]); 11910 return; 11911 } 11912 11913 pw.println("Applications Database Info:"); 11914 11915 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11916 ProcessRecord r = procs.get(i); 11917 if (r.thread != null) { 11918 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11919 pw.flush(); 11920 try { 11921 TransferPipe tp = new TransferPipe(); 11922 try { 11923 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11924 tp.go(fd); 11925 } finally { 11926 tp.kill(); 11927 } 11928 } catch (IOException e) { 11929 pw.println("Failure while dumping the app: " + r); 11930 pw.flush(); 11931 } catch (RemoteException e) { 11932 pw.println("Got a RemoteException while dumping the app " + r); 11933 pw.flush(); 11934 } 11935 } 11936 } 11937 } 11938 11939 final static class MemItem { 11940 final boolean isProc; 11941 final String label; 11942 final String shortLabel; 11943 final long pss; 11944 final int id; 11945 final boolean hasActivities; 11946 ArrayList<MemItem> subitems; 11947 11948 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11949 boolean _hasActivities) { 11950 isProc = true; 11951 label = _label; 11952 shortLabel = _shortLabel; 11953 pss = _pss; 11954 id = _id; 11955 hasActivities = _hasActivities; 11956 } 11957 11958 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11959 isProc = false; 11960 label = _label; 11961 shortLabel = _shortLabel; 11962 pss = _pss; 11963 id = _id; 11964 hasActivities = false; 11965 } 11966 } 11967 11968 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11969 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11970 if (sort && !isCompact) { 11971 Collections.sort(items, new Comparator<MemItem>() { 11972 @Override 11973 public int compare(MemItem lhs, MemItem rhs) { 11974 if (lhs.pss < rhs.pss) { 11975 return 1; 11976 } else if (lhs.pss > rhs.pss) { 11977 return -1; 11978 } 11979 return 0; 11980 } 11981 }); 11982 } 11983 11984 for (int i=0; i<items.size(); i++) { 11985 MemItem mi = items.get(i); 11986 if (!isCompact) { 11987 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11988 } else if (mi.isProc) { 11989 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11990 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11991 pw.println(mi.hasActivities ? ",a" : ",e"); 11992 } else { 11993 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11994 pw.println(mi.pss); 11995 } 11996 if (mi.subitems != null) { 11997 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11998 true, isCompact); 11999 } 12000 } 12001 } 12002 12003 // These are in KB. 12004 static final long[] DUMP_MEM_BUCKETS = new long[] { 12005 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12006 120*1024, 160*1024, 200*1024, 12007 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12008 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12009 }; 12010 12011 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12012 boolean stackLike) { 12013 int start = label.lastIndexOf('.'); 12014 if (start >= 0) start++; 12015 else start = 0; 12016 int end = label.length(); 12017 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12018 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12019 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12020 out.append(bucket); 12021 out.append(stackLike ? "MB." : "MB "); 12022 out.append(label, start, end); 12023 return; 12024 } 12025 } 12026 out.append(memKB/1024); 12027 out.append(stackLike ? "MB." : "MB "); 12028 out.append(label, start, end); 12029 } 12030 12031 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12032 ProcessList.NATIVE_ADJ, 12033 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12034 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12035 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12036 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12037 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12038 }; 12039 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12040 "Native", 12041 "System", "Persistent", "Foreground", 12042 "Visible", "Perceptible", 12043 "Heavy Weight", "Backup", 12044 "A Services", "Home", 12045 "Previous", "B Services", "Cached" 12046 }; 12047 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12048 "native", 12049 "sys", "pers", "fore", 12050 "vis", "percept", 12051 "heavy", "backup", 12052 "servicea", "home", 12053 "prev", "serviceb", "cached" 12054 }; 12055 12056 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12057 long realtime, boolean isCheckinRequest, boolean isCompact) { 12058 if (isCheckinRequest || isCompact) { 12059 // short checkin version 12060 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12061 } else { 12062 pw.println("Applications Memory Usage (kB):"); 12063 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12064 } 12065 } 12066 12067 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12068 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12069 boolean dumpDetails = false; 12070 boolean dumpFullDetails = false; 12071 boolean dumpDalvik = false; 12072 boolean oomOnly = false; 12073 boolean isCompact = false; 12074 boolean localOnly = false; 12075 12076 int opti = 0; 12077 while (opti < args.length) { 12078 String opt = args[opti]; 12079 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12080 break; 12081 } 12082 opti++; 12083 if ("-a".equals(opt)) { 12084 dumpDetails = true; 12085 dumpFullDetails = true; 12086 dumpDalvik = true; 12087 } else if ("-d".equals(opt)) { 12088 dumpDalvik = true; 12089 } else if ("-c".equals(opt)) { 12090 isCompact = true; 12091 } else if ("--oom".equals(opt)) { 12092 oomOnly = true; 12093 } else if ("--local".equals(opt)) { 12094 localOnly = true; 12095 } else if ("-h".equals(opt)) { 12096 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12097 pw.println(" -a: include all available information for each process."); 12098 pw.println(" -d: include dalvik details when dumping process details."); 12099 pw.println(" -c: dump in a compact machine-parseable representation."); 12100 pw.println(" --oom: only show processes organized by oom adj."); 12101 pw.println(" --local: only collect details locally, don't call process."); 12102 pw.println("If [process] is specified it can be the name or "); 12103 pw.println("pid of a specific process to dump."); 12104 return; 12105 } else { 12106 pw.println("Unknown argument: " + opt + "; use -h for help"); 12107 } 12108 } 12109 12110 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12111 long uptime = SystemClock.uptimeMillis(); 12112 long realtime = SystemClock.elapsedRealtime(); 12113 final long[] tmpLong = new long[1]; 12114 12115 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12116 if (procs == null) { 12117 // No Java processes. Maybe they want to print a native process. 12118 if (args != null && args.length > opti 12119 && args[opti].charAt(0) != '-') { 12120 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12121 = new ArrayList<ProcessCpuTracker.Stats>(); 12122 updateCpuStatsNow(); 12123 int findPid = -1; 12124 try { 12125 findPid = Integer.parseInt(args[opti]); 12126 } catch (NumberFormatException e) { 12127 } 12128 synchronized (mProcessCpuThread) { 12129 final int N = mProcessCpuTracker.countStats(); 12130 for (int i=0; i<N; i++) { 12131 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12132 if (st.pid == findPid || (st.baseName != null 12133 && st.baseName.equals(args[opti]))) { 12134 nativeProcs.add(st); 12135 } 12136 } 12137 } 12138 if (nativeProcs.size() > 0) { 12139 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12140 isCompact); 12141 Debug.MemoryInfo mi = null; 12142 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12143 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12144 final int pid = r.pid; 12145 if (!isCheckinRequest && dumpDetails) { 12146 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12147 } 12148 if (mi == null) { 12149 mi = new Debug.MemoryInfo(); 12150 } 12151 if (dumpDetails || (!brief && !oomOnly)) { 12152 Debug.getMemoryInfo(pid, mi); 12153 } else { 12154 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12155 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12156 } 12157 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12158 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12159 if (isCheckinRequest) { 12160 pw.println(); 12161 } 12162 } 12163 return; 12164 } 12165 } 12166 pw.println("No process found for: " + args[opti]); 12167 return; 12168 } 12169 12170 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12171 dumpDetails = true; 12172 } 12173 12174 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12175 12176 String[] innerArgs = new String[args.length-opti]; 12177 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12178 12179 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12180 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12181 long nativePss=0, dalvikPss=0, otherPss=0; 12182 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12183 12184 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12185 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12186 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12187 12188 long totalPss = 0; 12189 long cachedPss = 0; 12190 12191 Debug.MemoryInfo mi = null; 12192 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12193 final ProcessRecord r = procs.get(i); 12194 final IApplicationThread thread; 12195 final int pid; 12196 final int oomAdj; 12197 final boolean hasActivities; 12198 synchronized (this) { 12199 thread = r.thread; 12200 pid = r.pid; 12201 oomAdj = r.getSetAdjWithServices(); 12202 hasActivities = r.activities.size() > 0; 12203 } 12204 if (thread != null) { 12205 if (!isCheckinRequest && dumpDetails) { 12206 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12207 } 12208 if (mi == null) { 12209 mi = new Debug.MemoryInfo(); 12210 } 12211 if (dumpDetails || (!brief && !oomOnly)) { 12212 Debug.getMemoryInfo(pid, mi); 12213 } else { 12214 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12215 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12216 } 12217 if (dumpDetails) { 12218 if (localOnly) { 12219 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12220 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12221 if (isCheckinRequest) { 12222 pw.println(); 12223 } 12224 } else { 12225 try { 12226 pw.flush(); 12227 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12228 dumpDalvik, innerArgs); 12229 } catch (RemoteException e) { 12230 if (!isCheckinRequest) { 12231 pw.println("Got RemoteException!"); 12232 pw.flush(); 12233 } 12234 } 12235 } 12236 } 12237 12238 final long myTotalPss = mi.getTotalPss(); 12239 final long myTotalUss = mi.getTotalUss(); 12240 12241 synchronized (this) { 12242 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12243 // Record this for posterity if the process has been stable. 12244 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12245 } 12246 } 12247 12248 if (!isCheckinRequest && mi != null) { 12249 totalPss += myTotalPss; 12250 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12251 (hasActivities ? " / activities)" : ")"), 12252 r.processName, myTotalPss, pid, hasActivities); 12253 procMems.add(pssItem); 12254 procMemsMap.put(pid, pssItem); 12255 12256 nativePss += mi.nativePss; 12257 dalvikPss += mi.dalvikPss; 12258 otherPss += mi.otherPss; 12259 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12260 long mem = mi.getOtherPss(j); 12261 miscPss[j] += mem; 12262 otherPss -= mem; 12263 } 12264 12265 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12266 cachedPss += myTotalPss; 12267 } 12268 12269 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12270 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12271 || oomIndex == (oomPss.length-1)) { 12272 oomPss[oomIndex] += myTotalPss; 12273 if (oomProcs[oomIndex] == null) { 12274 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12275 } 12276 oomProcs[oomIndex].add(pssItem); 12277 break; 12278 } 12279 } 12280 } 12281 } 12282 } 12283 12284 if (!isCheckinRequest && procs.size() > 1) { 12285 // If we are showing aggregations, also look for native processes to 12286 // include so that our aggregations are more accurate. 12287 updateCpuStatsNow(); 12288 synchronized (mProcessCpuThread) { 12289 final int N = mProcessCpuTracker.countStats(); 12290 for (int i=0; i<N; i++) { 12291 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12292 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12293 if (mi == null) { 12294 mi = new Debug.MemoryInfo(); 12295 } 12296 if (!brief && !oomOnly) { 12297 Debug.getMemoryInfo(st.pid, mi); 12298 } else { 12299 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12300 mi.nativePrivateDirty = (int)tmpLong[0]; 12301 } 12302 12303 final long myTotalPss = mi.getTotalPss(); 12304 totalPss += myTotalPss; 12305 12306 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12307 st.name, myTotalPss, st.pid, false); 12308 procMems.add(pssItem); 12309 12310 nativePss += mi.nativePss; 12311 dalvikPss += mi.dalvikPss; 12312 otherPss += mi.otherPss; 12313 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12314 long mem = mi.getOtherPss(j); 12315 miscPss[j] += mem; 12316 otherPss -= mem; 12317 } 12318 oomPss[0] += myTotalPss; 12319 if (oomProcs[0] == null) { 12320 oomProcs[0] = new ArrayList<MemItem>(); 12321 } 12322 oomProcs[0].add(pssItem); 12323 } 12324 } 12325 } 12326 12327 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12328 12329 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12330 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12331 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12332 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12333 String label = Debug.MemoryInfo.getOtherLabel(j); 12334 catMems.add(new MemItem(label, label, miscPss[j], j)); 12335 } 12336 12337 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12338 for (int j=0; j<oomPss.length; j++) { 12339 if (oomPss[j] != 0) { 12340 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12341 : DUMP_MEM_OOM_LABEL[j]; 12342 MemItem item = new MemItem(label, label, oomPss[j], 12343 DUMP_MEM_OOM_ADJ[j]); 12344 item.subitems = oomProcs[j]; 12345 oomMems.add(item); 12346 } 12347 } 12348 12349 if (!brief && !oomOnly && !isCompact) { 12350 pw.println(); 12351 pw.println("Total PSS by process:"); 12352 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12353 pw.println(); 12354 } 12355 if (!isCompact) { 12356 pw.println("Total PSS by OOM adjustment:"); 12357 } 12358 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12359 if (!brief && !oomOnly) { 12360 PrintWriter out = categoryPw != null ? categoryPw : pw; 12361 if (!isCompact) { 12362 out.println(); 12363 out.println("Total PSS by category:"); 12364 } 12365 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12366 } 12367 if (!isCompact) { 12368 pw.println(); 12369 } 12370 MemInfoReader memInfo = new MemInfoReader(); 12371 memInfo.readMemInfo(); 12372 if (!brief) { 12373 if (!isCompact) { 12374 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12375 pw.print(" kB (status "); 12376 switch (mLastMemoryLevel) { 12377 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12378 pw.println("normal)"); 12379 break; 12380 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12381 pw.println("moderate)"); 12382 break; 12383 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12384 pw.println("low)"); 12385 break; 12386 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12387 pw.println("critical)"); 12388 break; 12389 default: 12390 pw.print(mLastMemoryLevel); 12391 pw.println(")"); 12392 break; 12393 } 12394 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12395 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12396 pw.print(cachedPss); pw.print(" cached pss + "); 12397 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12398 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12399 } else { 12400 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12401 pw.print(cachedPss + memInfo.getCachedSizeKb() 12402 + memInfo.getFreeSizeKb()); pw.print(","); 12403 pw.println(totalPss - cachedPss); 12404 } 12405 } 12406 if (!isCompact) { 12407 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12408 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12409 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12410 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12411 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12412 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12413 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12414 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12415 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12416 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12417 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12418 } 12419 if (!brief) { 12420 if (memInfo.getZramTotalSizeKb() != 0) { 12421 if (!isCompact) { 12422 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12423 pw.print(" kB physical used for "); 12424 pw.print(memInfo.getSwapTotalSizeKb() 12425 - memInfo.getSwapFreeSizeKb()); 12426 pw.print(" kB in swap ("); 12427 pw.print(memInfo.getSwapTotalSizeKb()); 12428 pw.println(" kB total swap)"); 12429 } else { 12430 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12431 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12432 pw.println(memInfo.getSwapFreeSizeKb()); 12433 } 12434 } 12435 final int[] SINGLE_LONG_FORMAT = new int[] { 12436 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12437 }; 12438 long[] longOut = new long[1]; 12439 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12440 SINGLE_LONG_FORMAT, null, longOut, null); 12441 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12442 longOut[0] = 0; 12443 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12444 SINGLE_LONG_FORMAT, null, longOut, null); 12445 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12446 longOut[0] = 0; 12447 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12448 SINGLE_LONG_FORMAT, null, longOut, null); 12449 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12450 longOut[0] = 0; 12451 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12452 SINGLE_LONG_FORMAT, null, longOut, null); 12453 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12454 if (!isCompact) { 12455 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12456 pw.print(" KSM: "); pw.print(sharing); 12457 pw.print(" kB saved from shared "); 12458 pw.print(shared); pw.println(" kB"); 12459 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12460 pw.print(voltile); pw.println(" kB volatile"); 12461 } 12462 pw.print(" Tuning: "); 12463 pw.print(ActivityManager.staticGetMemoryClass()); 12464 pw.print(" (large "); 12465 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12466 pw.print("), oom "); 12467 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12468 pw.print(" kB"); 12469 pw.print(", restore limit "); 12470 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12471 pw.print(" kB"); 12472 if (ActivityManager.isLowRamDeviceStatic()) { 12473 pw.print(" (low-ram)"); 12474 } 12475 if (ActivityManager.isHighEndGfx()) { 12476 pw.print(" (high-end-gfx)"); 12477 } 12478 pw.println(); 12479 } else { 12480 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12481 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12482 pw.println(voltile); 12483 pw.print("tuning,"); 12484 pw.print(ActivityManager.staticGetMemoryClass()); 12485 pw.print(','); 12486 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12487 pw.print(','); 12488 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12489 if (ActivityManager.isLowRamDeviceStatic()) { 12490 pw.print(",low-ram"); 12491 } 12492 if (ActivityManager.isHighEndGfx()) { 12493 pw.print(",high-end-gfx"); 12494 } 12495 pw.println(); 12496 } 12497 } 12498 } 12499 } 12500 12501 /** 12502 * Searches array of arguments for the specified string 12503 * @param args array of argument strings 12504 * @param value value to search for 12505 * @return true if the value is contained in the array 12506 */ 12507 private static boolean scanArgs(String[] args, String value) { 12508 if (args != null) { 12509 for (String arg : args) { 12510 if (value.equals(arg)) { 12511 return true; 12512 } 12513 } 12514 } 12515 return false; 12516 } 12517 12518 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12519 ContentProviderRecord cpr, boolean always) { 12520 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12521 12522 if (!inLaunching || always) { 12523 synchronized (cpr) { 12524 cpr.launchingApp = null; 12525 cpr.notifyAll(); 12526 } 12527 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12528 String names[] = cpr.info.authority.split(";"); 12529 for (int j = 0; j < names.length; j++) { 12530 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12531 } 12532 } 12533 12534 for (int i=0; i<cpr.connections.size(); i++) { 12535 ContentProviderConnection conn = cpr.connections.get(i); 12536 if (conn.waiting) { 12537 // If this connection is waiting for the provider, then we don't 12538 // need to mess with its process unless we are always removing 12539 // or for some reason the provider is not currently launching. 12540 if (inLaunching && !always) { 12541 continue; 12542 } 12543 } 12544 ProcessRecord capp = conn.client; 12545 conn.dead = true; 12546 if (conn.stableCount > 0) { 12547 if (!capp.persistent && capp.thread != null 12548 && capp.pid != 0 12549 && capp.pid != MY_PID) { 12550 killUnneededProcessLocked(capp, "depends on provider " 12551 + cpr.name.flattenToShortString() 12552 + " in dying proc " + (proc != null ? proc.processName : "??")); 12553 } 12554 } else if (capp.thread != null && conn.provider.provider != null) { 12555 try { 12556 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12557 } catch (RemoteException e) { 12558 } 12559 // In the protocol here, we don't expect the client to correctly 12560 // clean up this connection, we'll just remove it. 12561 cpr.connections.remove(i); 12562 conn.client.conProviders.remove(conn); 12563 } 12564 } 12565 12566 if (inLaunching && always) { 12567 mLaunchingProviders.remove(cpr); 12568 } 12569 return inLaunching; 12570 } 12571 12572 /** 12573 * Main code for cleaning up a process when it has gone away. This is 12574 * called both as a result of the process dying, or directly when stopping 12575 * a process when running in single process mode. 12576 */ 12577 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12578 boolean restarting, boolean allowRestart, int index) { 12579 if (index >= 0) { 12580 removeLruProcessLocked(app); 12581 ProcessList.remove(app.pid); 12582 } 12583 12584 mProcessesToGc.remove(app); 12585 mPendingPssProcesses.remove(app); 12586 12587 // Dismiss any open dialogs. 12588 if (app.crashDialog != null && !app.forceCrashReport) { 12589 app.crashDialog.dismiss(); 12590 app.crashDialog = null; 12591 } 12592 if (app.anrDialog != null) { 12593 app.anrDialog.dismiss(); 12594 app.anrDialog = null; 12595 } 12596 if (app.waitDialog != null) { 12597 app.waitDialog.dismiss(); 12598 app.waitDialog = null; 12599 } 12600 12601 app.crashing = false; 12602 app.notResponding = false; 12603 12604 app.resetPackageList(mProcessStats); 12605 app.unlinkDeathRecipient(); 12606 app.makeInactive(mProcessStats); 12607 app.forcingToForeground = null; 12608 updateProcessForegroundLocked(app, false, false); 12609 app.foregroundActivities = false; 12610 app.hasShownUi = false; 12611 app.treatLikeActivity = false; 12612 app.hasAboveClient = false; 12613 app.hasClientActivities = false; 12614 12615 mServices.killServicesLocked(app, allowRestart); 12616 12617 boolean restart = false; 12618 12619 // Remove published content providers. 12620 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12621 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12622 final boolean always = app.bad || !allowRestart; 12623 if (removeDyingProviderLocked(app, cpr, always) || always) { 12624 // We left the provider in the launching list, need to 12625 // restart it. 12626 restart = true; 12627 } 12628 12629 cpr.provider = null; 12630 cpr.proc = null; 12631 } 12632 app.pubProviders.clear(); 12633 12634 // Take care of any launching providers waiting for this process. 12635 if (checkAppInLaunchingProvidersLocked(app, false)) { 12636 restart = true; 12637 } 12638 12639 // Unregister from connected content providers. 12640 if (!app.conProviders.isEmpty()) { 12641 for (int i=0; i<app.conProviders.size(); i++) { 12642 ContentProviderConnection conn = app.conProviders.get(i); 12643 conn.provider.connections.remove(conn); 12644 } 12645 app.conProviders.clear(); 12646 } 12647 12648 // At this point there may be remaining entries in mLaunchingProviders 12649 // where we were the only one waiting, so they are no longer of use. 12650 // Look for these and clean up if found. 12651 // XXX Commented out for now. Trying to figure out a way to reproduce 12652 // the actual situation to identify what is actually going on. 12653 if (false) { 12654 for (int i=0; i<mLaunchingProviders.size(); i++) { 12655 ContentProviderRecord cpr = (ContentProviderRecord) 12656 mLaunchingProviders.get(i); 12657 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12658 synchronized (cpr) { 12659 cpr.launchingApp = null; 12660 cpr.notifyAll(); 12661 } 12662 } 12663 } 12664 } 12665 12666 skipCurrentReceiverLocked(app); 12667 12668 // Unregister any receivers. 12669 for (int i=app.receivers.size()-1; i>=0; i--) { 12670 removeReceiverLocked(app.receivers.valueAt(i)); 12671 } 12672 app.receivers.clear(); 12673 12674 // If the app is undergoing backup, tell the backup manager about it 12675 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12676 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12677 + mBackupTarget.appInfo + " died during backup"); 12678 try { 12679 IBackupManager bm = IBackupManager.Stub.asInterface( 12680 ServiceManager.getService(Context.BACKUP_SERVICE)); 12681 bm.agentDisconnected(app.info.packageName); 12682 } catch (RemoteException e) { 12683 // can't happen; backup manager is local 12684 } 12685 } 12686 12687 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12688 ProcessChangeItem item = mPendingProcessChanges.get(i); 12689 if (item.pid == app.pid) { 12690 mPendingProcessChanges.remove(i); 12691 mAvailProcessChanges.add(item); 12692 } 12693 } 12694 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12695 12696 // If the caller is restarting this app, then leave it in its 12697 // current lists and let the caller take care of it. 12698 if (restarting) { 12699 return; 12700 } 12701 12702 if (!app.persistent || app.isolated) { 12703 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12704 "Removing non-persistent process during cleanup: " + app); 12705 mProcessNames.remove(app.processName, app.uid); 12706 mIsolatedProcesses.remove(app.uid); 12707 if (mHeavyWeightProcess == app) { 12708 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12709 mHeavyWeightProcess.userId, 0)); 12710 mHeavyWeightProcess = null; 12711 } 12712 } else if (!app.removed) { 12713 // This app is persistent, so we need to keep its record around. 12714 // If it is not already on the pending app list, add it there 12715 // and start a new process for it. 12716 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12717 mPersistentStartingProcesses.add(app); 12718 restart = true; 12719 } 12720 } 12721 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12722 "Clean-up removing on hold: " + app); 12723 mProcessesOnHold.remove(app); 12724 12725 if (app == mHomeProcess) { 12726 mHomeProcess = null; 12727 } 12728 if (app == mPreviousProcess) { 12729 mPreviousProcess = null; 12730 } 12731 12732 if (restart && !app.isolated) { 12733 // We have components that still need to be running in the 12734 // process, so re-launch it. 12735 mProcessNames.put(app.processName, app.uid, app); 12736 startProcessLocked(app, "restart", app.processName); 12737 } else if (app.pid > 0 && app.pid != MY_PID) { 12738 // Goodbye! 12739 boolean removed; 12740 synchronized (mPidsSelfLocked) { 12741 mPidsSelfLocked.remove(app.pid); 12742 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12743 } 12744 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12745 app.processName, app.info.uid); 12746 if (app.isolated) { 12747 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12748 } 12749 app.setPid(0); 12750 } 12751 } 12752 12753 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12754 // Look through the content providers we are waiting to have launched, 12755 // and if any run in this process then either schedule a restart of 12756 // the process or kill the client waiting for it if this process has 12757 // gone bad. 12758 int NL = mLaunchingProviders.size(); 12759 boolean restart = false; 12760 for (int i=0; i<NL; i++) { 12761 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12762 if (cpr.launchingApp == app) { 12763 if (!alwaysBad && !app.bad) { 12764 restart = true; 12765 } else { 12766 removeDyingProviderLocked(app, cpr, true); 12767 // cpr should have been removed from mLaunchingProviders 12768 NL = mLaunchingProviders.size(); 12769 i--; 12770 } 12771 } 12772 } 12773 return restart; 12774 } 12775 12776 // ========================================================= 12777 // SERVICES 12778 // ========================================================= 12779 12780 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12781 int flags) { 12782 enforceNotIsolatedCaller("getServices"); 12783 synchronized (this) { 12784 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12785 } 12786 } 12787 12788 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12789 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12790 synchronized (this) { 12791 return mServices.getRunningServiceControlPanelLocked(name); 12792 } 12793 } 12794 12795 public ComponentName startService(IApplicationThread caller, Intent service, 12796 String resolvedType, int userId) { 12797 enforceNotIsolatedCaller("startService"); 12798 // Refuse possible leaked file descriptors 12799 if (service != null && service.hasFileDescriptors() == true) { 12800 throw new IllegalArgumentException("File descriptors passed in Intent"); 12801 } 12802 12803 if (DEBUG_SERVICE) 12804 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12805 synchronized(this) { 12806 final int callingPid = Binder.getCallingPid(); 12807 final int callingUid = Binder.getCallingUid(); 12808 final long origId = Binder.clearCallingIdentity(); 12809 ComponentName res = mServices.startServiceLocked(caller, service, 12810 resolvedType, callingPid, callingUid, userId); 12811 Binder.restoreCallingIdentity(origId); 12812 return res; 12813 } 12814 } 12815 12816 ComponentName startServiceInPackage(int uid, 12817 Intent service, String resolvedType, int userId) { 12818 synchronized(this) { 12819 if (DEBUG_SERVICE) 12820 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12821 final long origId = Binder.clearCallingIdentity(); 12822 ComponentName res = mServices.startServiceLocked(null, service, 12823 resolvedType, -1, uid, userId); 12824 Binder.restoreCallingIdentity(origId); 12825 return res; 12826 } 12827 } 12828 12829 public int stopService(IApplicationThread caller, Intent service, 12830 String resolvedType, int userId) { 12831 enforceNotIsolatedCaller("stopService"); 12832 // Refuse possible leaked file descriptors 12833 if (service != null && service.hasFileDescriptors() == true) { 12834 throw new IllegalArgumentException("File descriptors passed in Intent"); 12835 } 12836 12837 synchronized(this) { 12838 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12839 } 12840 } 12841 12842 public IBinder peekService(Intent service, String resolvedType) { 12843 enforceNotIsolatedCaller("peekService"); 12844 // Refuse possible leaked file descriptors 12845 if (service != null && service.hasFileDescriptors() == true) { 12846 throw new IllegalArgumentException("File descriptors passed in Intent"); 12847 } 12848 synchronized(this) { 12849 return mServices.peekServiceLocked(service, resolvedType); 12850 } 12851 } 12852 12853 public boolean stopServiceToken(ComponentName className, IBinder token, 12854 int startId) { 12855 synchronized(this) { 12856 return mServices.stopServiceTokenLocked(className, token, startId); 12857 } 12858 } 12859 12860 public void setServiceForeground(ComponentName className, IBinder token, 12861 int id, Notification notification, boolean removeNotification) { 12862 synchronized(this) { 12863 mServices.setServiceForegroundLocked(className, token, id, notification, 12864 removeNotification); 12865 } 12866 } 12867 12868 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12869 boolean requireFull, String name, String callerPackage) { 12870 final int callingUserId = UserHandle.getUserId(callingUid); 12871 if (callingUserId != userId) { 12872 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12873 if ((requireFull || checkComponentPermission( 12874 android.Manifest.permission.INTERACT_ACROSS_USERS, 12875 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12876 && checkComponentPermission( 12877 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12878 callingPid, callingUid, -1, true) 12879 != PackageManager.PERMISSION_GRANTED) { 12880 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12881 // In this case, they would like to just execute as their 12882 // owner user instead of failing. 12883 userId = callingUserId; 12884 } else { 12885 StringBuilder builder = new StringBuilder(128); 12886 builder.append("Permission Denial: "); 12887 builder.append(name); 12888 if (callerPackage != null) { 12889 builder.append(" from "); 12890 builder.append(callerPackage); 12891 } 12892 builder.append(" asks to run as user "); 12893 builder.append(userId); 12894 builder.append(" but is calling from user "); 12895 builder.append(UserHandle.getUserId(callingUid)); 12896 builder.append("; this requires "); 12897 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12898 if (!requireFull) { 12899 builder.append(" or "); 12900 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12901 } 12902 String msg = builder.toString(); 12903 Slog.w(TAG, msg); 12904 throw new SecurityException(msg); 12905 } 12906 } 12907 } 12908 if (userId == UserHandle.USER_CURRENT 12909 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12910 // Note that we may be accessing this outside of a lock... 12911 // shouldn't be a big deal, if this is being called outside 12912 // of a locked context there is intrinsically a race with 12913 // the value the caller will receive and someone else changing it. 12914 userId = mCurrentUserId; 12915 } 12916 if (!allowAll && userId < 0) { 12917 throw new IllegalArgumentException( 12918 "Call does not support special user #" + userId); 12919 } 12920 } 12921 return userId; 12922 } 12923 12924 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12925 String className, int flags) { 12926 boolean result = false; 12927 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12928 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12929 if (ActivityManager.checkUidPermission( 12930 android.Manifest.permission.INTERACT_ACROSS_USERS, 12931 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12932 ComponentName comp = new ComponentName(aInfo.packageName, className); 12933 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12934 + " requests FLAG_SINGLE_USER, but app does not hold " 12935 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12936 Slog.w(TAG, msg); 12937 throw new SecurityException(msg); 12938 } 12939 result = true; 12940 } 12941 } else if (componentProcessName == aInfo.packageName) { 12942 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12943 } else if ("system".equals(componentProcessName)) { 12944 result = true; 12945 } 12946 if (DEBUG_MU) { 12947 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12948 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12949 } 12950 return result; 12951 } 12952 12953 public int bindService(IApplicationThread caller, IBinder token, 12954 Intent service, String resolvedType, 12955 IServiceConnection connection, int flags, int userId) { 12956 enforceNotIsolatedCaller("bindService"); 12957 // Refuse possible leaked file descriptors 12958 if (service != null && service.hasFileDescriptors() == true) { 12959 throw new IllegalArgumentException("File descriptors passed in Intent"); 12960 } 12961 12962 synchronized(this) { 12963 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12964 connection, flags, userId); 12965 } 12966 } 12967 12968 public boolean unbindService(IServiceConnection connection) { 12969 synchronized (this) { 12970 return mServices.unbindServiceLocked(connection); 12971 } 12972 } 12973 12974 public void publishService(IBinder token, Intent intent, IBinder service) { 12975 // Refuse possible leaked file descriptors 12976 if (intent != null && intent.hasFileDescriptors() == true) { 12977 throw new IllegalArgumentException("File descriptors passed in Intent"); 12978 } 12979 12980 synchronized(this) { 12981 if (!(token instanceof ServiceRecord)) { 12982 throw new IllegalArgumentException("Invalid service token"); 12983 } 12984 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12985 } 12986 } 12987 12988 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12989 // Refuse possible leaked file descriptors 12990 if (intent != null && intent.hasFileDescriptors() == true) { 12991 throw new IllegalArgumentException("File descriptors passed in Intent"); 12992 } 12993 12994 synchronized(this) { 12995 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12996 } 12997 } 12998 12999 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13000 synchronized(this) { 13001 if (!(token instanceof ServiceRecord)) { 13002 throw new IllegalArgumentException("Invalid service token"); 13003 } 13004 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13005 } 13006 } 13007 13008 // ========================================================= 13009 // BACKUP AND RESTORE 13010 // ========================================================= 13011 13012 // Cause the target app to be launched if necessary and its backup agent 13013 // instantiated. The backup agent will invoke backupAgentCreated() on the 13014 // activity manager to announce its creation. 13015 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13016 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13017 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13018 13019 synchronized(this) { 13020 // !!! TODO: currently no check here that we're already bound 13021 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13022 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13023 synchronized (stats) { 13024 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13025 } 13026 13027 // Backup agent is now in use, its package can't be stopped. 13028 try { 13029 AppGlobals.getPackageManager().setPackageStoppedState( 13030 app.packageName, false, UserHandle.getUserId(app.uid)); 13031 } catch (RemoteException e) { 13032 } catch (IllegalArgumentException e) { 13033 Slog.w(TAG, "Failed trying to unstop package " 13034 + app.packageName + ": " + e); 13035 } 13036 13037 BackupRecord r = new BackupRecord(ss, app, backupMode); 13038 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13039 ? new ComponentName(app.packageName, app.backupAgentName) 13040 : new ComponentName("android", "FullBackupAgent"); 13041 // startProcessLocked() returns existing proc's record if it's already running 13042 ProcessRecord proc = startProcessLocked(app.processName, app, 13043 false, 0, "backup", hostingName, false, false, false); 13044 if (proc == null) { 13045 Slog.e(TAG, "Unable to start backup agent process " + r); 13046 return false; 13047 } 13048 13049 r.app = proc; 13050 mBackupTarget = r; 13051 mBackupAppName = app.packageName; 13052 13053 // Try not to kill the process during backup 13054 updateOomAdjLocked(proc); 13055 13056 // If the process is already attached, schedule the creation of the backup agent now. 13057 // If it is not yet live, this will be done when it attaches to the framework. 13058 if (proc.thread != null) { 13059 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13060 try { 13061 proc.thread.scheduleCreateBackupAgent(app, 13062 compatibilityInfoForPackageLocked(app), backupMode); 13063 } catch (RemoteException e) { 13064 // Will time out on the backup manager side 13065 } 13066 } else { 13067 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13068 } 13069 // Invariants: at this point, the target app process exists and the application 13070 // is either already running or in the process of coming up. mBackupTarget and 13071 // mBackupAppName describe the app, so that when it binds back to the AM we 13072 // know that it's scheduled for a backup-agent operation. 13073 } 13074 13075 return true; 13076 } 13077 13078 @Override 13079 public void clearPendingBackup() { 13080 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13081 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13082 13083 synchronized (this) { 13084 mBackupTarget = null; 13085 mBackupAppName = null; 13086 } 13087 } 13088 13089 // A backup agent has just come up 13090 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13091 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13092 + " = " + agent); 13093 13094 synchronized(this) { 13095 if (!agentPackageName.equals(mBackupAppName)) { 13096 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13097 return; 13098 } 13099 } 13100 13101 long oldIdent = Binder.clearCallingIdentity(); 13102 try { 13103 IBackupManager bm = IBackupManager.Stub.asInterface( 13104 ServiceManager.getService(Context.BACKUP_SERVICE)); 13105 bm.agentConnected(agentPackageName, agent); 13106 } catch (RemoteException e) { 13107 // can't happen; the backup manager service is local 13108 } catch (Exception e) { 13109 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13110 e.printStackTrace(); 13111 } finally { 13112 Binder.restoreCallingIdentity(oldIdent); 13113 } 13114 } 13115 13116 // done with this agent 13117 public void unbindBackupAgent(ApplicationInfo appInfo) { 13118 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13119 if (appInfo == null) { 13120 Slog.w(TAG, "unbind backup agent for null app"); 13121 return; 13122 } 13123 13124 synchronized(this) { 13125 try { 13126 if (mBackupAppName == null) { 13127 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13128 return; 13129 } 13130 13131 if (!mBackupAppName.equals(appInfo.packageName)) { 13132 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13133 return; 13134 } 13135 13136 // Not backing this app up any more; reset its OOM adjustment 13137 final ProcessRecord proc = mBackupTarget.app; 13138 updateOomAdjLocked(proc); 13139 13140 // If the app crashed during backup, 'thread' will be null here 13141 if (proc.thread != null) { 13142 try { 13143 proc.thread.scheduleDestroyBackupAgent(appInfo, 13144 compatibilityInfoForPackageLocked(appInfo)); 13145 } catch (Exception e) { 13146 Slog.e(TAG, "Exception when unbinding backup agent:"); 13147 e.printStackTrace(); 13148 } 13149 } 13150 } finally { 13151 mBackupTarget = null; 13152 mBackupAppName = null; 13153 } 13154 } 13155 } 13156 // ========================================================= 13157 // BROADCASTS 13158 // ========================================================= 13159 13160 private final List getStickiesLocked(String action, IntentFilter filter, 13161 List cur, int userId) { 13162 final ContentResolver resolver = mContext.getContentResolver(); 13163 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13164 if (stickies == null) { 13165 return cur; 13166 } 13167 final ArrayList<Intent> list = stickies.get(action); 13168 if (list == null) { 13169 return cur; 13170 } 13171 int N = list.size(); 13172 for (int i=0; i<N; i++) { 13173 Intent intent = list.get(i); 13174 if (filter.match(resolver, intent, true, TAG) >= 0) { 13175 if (cur == null) { 13176 cur = new ArrayList<Intent>(); 13177 } 13178 cur.add(intent); 13179 } 13180 } 13181 return cur; 13182 } 13183 13184 boolean isPendingBroadcastProcessLocked(int pid) { 13185 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13186 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13187 } 13188 13189 void skipPendingBroadcastLocked(int pid) { 13190 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13191 for (BroadcastQueue queue : mBroadcastQueues) { 13192 queue.skipPendingBroadcastLocked(pid); 13193 } 13194 } 13195 13196 // The app just attached; send any pending broadcasts that it should receive 13197 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13198 boolean didSomething = false; 13199 for (BroadcastQueue queue : mBroadcastQueues) { 13200 didSomething |= queue.sendPendingBroadcastsLocked(app); 13201 } 13202 return didSomething; 13203 } 13204 13205 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13206 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13207 enforceNotIsolatedCaller("registerReceiver"); 13208 int callingUid; 13209 int callingPid; 13210 synchronized(this) { 13211 ProcessRecord callerApp = null; 13212 if (caller != null) { 13213 callerApp = getRecordForAppLocked(caller); 13214 if (callerApp == null) { 13215 throw new SecurityException( 13216 "Unable to find app for caller " + caller 13217 + " (pid=" + Binder.getCallingPid() 13218 + ") when registering receiver " + receiver); 13219 } 13220 if (callerApp.info.uid != Process.SYSTEM_UID && 13221 !callerApp.pkgList.containsKey(callerPackage) && 13222 !"android".equals(callerPackage)) { 13223 throw new SecurityException("Given caller package " + callerPackage 13224 + " is not running in process " + callerApp); 13225 } 13226 callingUid = callerApp.info.uid; 13227 callingPid = callerApp.pid; 13228 } else { 13229 callerPackage = null; 13230 callingUid = Binder.getCallingUid(); 13231 callingPid = Binder.getCallingPid(); 13232 } 13233 13234 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13235 true, true, "registerReceiver", callerPackage); 13236 13237 List allSticky = null; 13238 13239 // Look for any matching sticky broadcasts... 13240 Iterator actions = filter.actionsIterator(); 13241 if (actions != null) { 13242 while (actions.hasNext()) { 13243 String action = (String)actions.next(); 13244 allSticky = getStickiesLocked(action, filter, allSticky, 13245 UserHandle.USER_ALL); 13246 allSticky = getStickiesLocked(action, filter, allSticky, 13247 UserHandle.getUserId(callingUid)); 13248 } 13249 } else { 13250 allSticky = getStickiesLocked(null, filter, allSticky, 13251 UserHandle.USER_ALL); 13252 allSticky = getStickiesLocked(null, filter, allSticky, 13253 UserHandle.getUserId(callingUid)); 13254 } 13255 13256 // The first sticky in the list is returned directly back to 13257 // the client. 13258 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13259 13260 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13261 + ": " + sticky); 13262 13263 if (receiver == null) { 13264 return sticky; 13265 } 13266 13267 ReceiverList rl 13268 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13269 if (rl == null) { 13270 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13271 userId, receiver); 13272 if (rl.app != null) { 13273 rl.app.receivers.add(rl); 13274 } else { 13275 try { 13276 receiver.asBinder().linkToDeath(rl, 0); 13277 } catch (RemoteException e) { 13278 return sticky; 13279 } 13280 rl.linkedToDeath = true; 13281 } 13282 mRegisteredReceivers.put(receiver.asBinder(), rl); 13283 } else if (rl.uid != callingUid) { 13284 throw new IllegalArgumentException( 13285 "Receiver requested to register for uid " + callingUid 13286 + " was previously registered for uid " + rl.uid); 13287 } else if (rl.pid != callingPid) { 13288 throw new IllegalArgumentException( 13289 "Receiver requested to register for pid " + callingPid 13290 + " was previously registered for pid " + rl.pid); 13291 } else if (rl.userId != userId) { 13292 throw new IllegalArgumentException( 13293 "Receiver requested to register for user " + userId 13294 + " was previously registered for user " + rl.userId); 13295 } 13296 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13297 permission, callingUid, userId); 13298 rl.add(bf); 13299 if (!bf.debugCheck()) { 13300 Slog.w(TAG, "==> For Dynamic broadast"); 13301 } 13302 mReceiverResolver.addFilter(bf); 13303 13304 // Enqueue broadcasts for all existing stickies that match 13305 // this filter. 13306 if (allSticky != null) { 13307 ArrayList receivers = new ArrayList(); 13308 receivers.add(bf); 13309 13310 int N = allSticky.size(); 13311 for (int i=0; i<N; i++) { 13312 Intent intent = (Intent)allSticky.get(i); 13313 BroadcastQueue queue = broadcastQueueForIntent(intent); 13314 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13315 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13316 null, null, false, true, true, -1); 13317 queue.enqueueParallelBroadcastLocked(r); 13318 queue.scheduleBroadcastsLocked(); 13319 } 13320 } 13321 13322 return sticky; 13323 } 13324 } 13325 13326 public void unregisterReceiver(IIntentReceiver receiver) { 13327 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13328 13329 final long origId = Binder.clearCallingIdentity(); 13330 try { 13331 boolean doTrim = false; 13332 13333 synchronized(this) { 13334 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13335 if (rl != null) { 13336 if (rl.curBroadcast != null) { 13337 BroadcastRecord r = rl.curBroadcast; 13338 final boolean doNext = finishReceiverLocked( 13339 receiver.asBinder(), r.resultCode, r.resultData, 13340 r.resultExtras, r.resultAbort); 13341 if (doNext) { 13342 doTrim = true; 13343 r.queue.processNextBroadcast(false); 13344 } 13345 } 13346 13347 if (rl.app != null) { 13348 rl.app.receivers.remove(rl); 13349 } 13350 removeReceiverLocked(rl); 13351 if (rl.linkedToDeath) { 13352 rl.linkedToDeath = false; 13353 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13354 } 13355 } 13356 } 13357 13358 // If we actually concluded any broadcasts, we might now be able 13359 // to trim the recipients' apps from our working set 13360 if (doTrim) { 13361 trimApplications(); 13362 return; 13363 } 13364 13365 } finally { 13366 Binder.restoreCallingIdentity(origId); 13367 } 13368 } 13369 13370 void removeReceiverLocked(ReceiverList rl) { 13371 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13372 int N = rl.size(); 13373 for (int i=0; i<N; i++) { 13374 mReceiverResolver.removeFilter(rl.get(i)); 13375 } 13376 } 13377 13378 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13379 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13380 ProcessRecord r = mLruProcesses.get(i); 13381 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13382 try { 13383 r.thread.dispatchPackageBroadcast(cmd, packages); 13384 } catch (RemoteException ex) { 13385 } 13386 } 13387 } 13388 } 13389 13390 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13391 int[] users) { 13392 List<ResolveInfo> receivers = null; 13393 try { 13394 HashSet<ComponentName> singleUserReceivers = null; 13395 boolean scannedFirstReceivers = false; 13396 for (int user : users) { 13397 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13398 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13399 if (user != 0 && newReceivers != null) { 13400 // If this is not the primary user, we need to check for 13401 // any receivers that should be filtered out. 13402 for (int i=0; i<newReceivers.size(); i++) { 13403 ResolveInfo ri = newReceivers.get(i); 13404 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13405 newReceivers.remove(i); 13406 i--; 13407 } 13408 } 13409 } 13410 if (newReceivers != null && newReceivers.size() == 0) { 13411 newReceivers = null; 13412 } 13413 if (receivers == null) { 13414 receivers = newReceivers; 13415 } else if (newReceivers != null) { 13416 // We need to concatenate the additional receivers 13417 // found with what we have do far. This would be easy, 13418 // but we also need to de-dup any receivers that are 13419 // singleUser. 13420 if (!scannedFirstReceivers) { 13421 // Collect any single user receivers we had already retrieved. 13422 scannedFirstReceivers = true; 13423 for (int i=0; i<receivers.size(); i++) { 13424 ResolveInfo ri = receivers.get(i); 13425 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13426 ComponentName cn = new ComponentName( 13427 ri.activityInfo.packageName, ri.activityInfo.name); 13428 if (singleUserReceivers == null) { 13429 singleUserReceivers = new HashSet<ComponentName>(); 13430 } 13431 singleUserReceivers.add(cn); 13432 } 13433 } 13434 } 13435 // Add the new results to the existing results, tracking 13436 // and de-dupping single user receivers. 13437 for (int i=0; i<newReceivers.size(); i++) { 13438 ResolveInfo ri = newReceivers.get(i); 13439 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13440 ComponentName cn = new ComponentName( 13441 ri.activityInfo.packageName, ri.activityInfo.name); 13442 if (singleUserReceivers == null) { 13443 singleUserReceivers = new HashSet<ComponentName>(); 13444 } 13445 if (!singleUserReceivers.contains(cn)) { 13446 singleUserReceivers.add(cn); 13447 receivers.add(ri); 13448 } 13449 } else { 13450 receivers.add(ri); 13451 } 13452 } 13453 } 13454 } 13455 } catch (RemoteException ex) { 13456 // pm is in same process, this will never happen. 13457 } 13458 return receivers; 13459 } 13460 13461 private final int broadcastIntentLocked(ProcessRecord callerApp, 13462 String callerPackage, Intent intent, String resolvedType, 13463 IIntentReceiver resultTo, int resultCode, String resultData, 13464 Bundle map, String requiredPermission, int appOp, 13465 boolean ordered, boolean sticky, int callingPid, int callingUid, 13466 int userId) { 13467 intent = new Intent(intent); 13468 13469 // By default broadcasts do not go to stopped apps. 13470 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13471 13472 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13473 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13474 + " ordered=" + ordered + " userid=" + userId); 13475 if ((resultTo != null) && !ordered) { 13476 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13477 } 13478 13479 userId = handleIncomingUser(callingPid, callingUid, userId, 13480 true, false, "broadcast", callerPackage); 13481 13482 // Make sure that the user who is receiving this broadcast is started. 13483 // If not, we will just skip it. 13484 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13485 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13486 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13487 Slog.w(TAG, "Skipping broadcast of " + intent 13488 + ": user " + userId + " is stopped"); 13489 return ActivityManager.BROADCAST_SUCCESS; 13490 } 13491 } 13492 13493 /* 13494 * Prevent non-system code (defined here to be non-persistent 13495 * processes) from sending protected broadcasts. 13496 */ 13497 int callingAppId = UserHandle.getAppId(callingUid); 13498 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13499 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13500 callingUid == 0) { 13501 // Always okay. 13502 } else if (callerApp == null || !callerApp.persistent) { 13503 try { 13504 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13505 intent.getAction())) { 13506 String msg = "Permission Denial: not allowed to send broadcast " 13507 + intent.getAction() + " from pid=" 13508 + callingPid + ", uid=" + callingUid; 13509 Slog.w(TAG, msg); 13510 throw new SecurityException(msg); 13511 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13512 // Special case for compatibility: we don't want apps to send this, 13513 // but historically it has not been protected and apps may be using it 13514 // to poke their own app widget. So, instead of making it protected, 13515 // just limit it to the caller. 13516 if (callerApp == null) { 13517 String msg = "Permission Denial: not allowed to send broadcast " 13518 + intent.getAction() + " from unknown caller."; 13519 Slog.w(TAG, msg); 13520 throw new SecurityException(msg); 13521 } else if (intent.getComponent() != null) { 13522 // They are good enough to send to an explicit component... verify 13523 // it is being sent to the calling app. 13524 if (!intent.getComponent().getPackageName().equals( 13525 callerApp.info.packageName)) { 13526 String msg = "Permission Denial: not allowed to send broadcast " 13527 + intent.getAction() + " to " 13528 + intent.getComponent().getPackageName() + " from " 13529 + callerApp.info.packageName; 13530 Slog.w(TAG, msg); 13531 throw new SecurityException(msg); 13532 } 13533 } else { 13534 // Limit broadcast to their own package. 13535 intent.setPackage(callerApp.info.packageName); 13536 } 13537 } 13538 } catch (RemoteException e) { 13539 Slog.w(TAG, "Remote exception", e); 13540 return ActivityManager.BROADCAST_SUCCESS; 13541 } 13542 } 13543 13544 // Handle special intents: if this broadcast is from the package 13545 // manager about a package being removed, we need to remove all of 13546 // its activities from the history stack. 13547 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13548 intent.getAction()); 13549 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13550 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13551 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13552 || uidRemoved) { 13553 if (checkComponentPermission( 13554 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13555 callingPid, callingUid, -1, true) 13556 == PackageManager.PERMISSION_GRANTED) { 13557 if (uidRemoved) { 13558 final Bundle intentExtras = intent.getExtras(); 13559 final int uid = intentExtras != null 13560 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13561 if (uid >= 0) { 13562 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13563 synchronized (bs) { 13564 bs.removeUidStatsLocked(uid); 13565 } 13566 mAppOpsService.uidRemoved(uid); 13567 } 13568 } else { 13569 // If resources are unavailable just force stop all 13570 // those packages and flush the attribute cache as well. 13571 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13572 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13573 if (list != null && (list.length > 0)) { 13574 for (String pkg : list) { 13575 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13576 "storage unmount"); 13577 } 13578 sendPackageBroadcastLocked( 13579 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13580 } 13581 } else { 13582 Uri data = intent.getData(); 13583 String ssp; 13584 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13585 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13586 intent.getAction()); 13587 boolean fullUninstall = removed && 13588 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13589 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13590 forceStopPackageLocked(ssp, UserHandle.getAppId( 13591 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13592 false, fullUninstall, userId, 13593 removed ? "pkg removed" : "pkg changed"); 13594 } 13595 if (removed) { 13596 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13597 new String[] {ssp}, userId); 13598 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13599 mAppOpsService.packageRemoved( 13600 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13601 13602 // Remove all permissions granted from/to this package 13603 removeUriPermissionsForPackageLocked(ssp, userId, true); 13604 } 13605 } 13606 } 13607 } 13608 } 13609 } else { 13610 String msg = "Permission Denial: " + intent.getAction() 13611 + " broadcast from " + callerPackage + " (pid=" + callingPid 13612 + ", uid=" + callingUid + ")" 13613 + " requires " 13614 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13615 Slog.w(TAG, msg); 13616 throw new SecurityException(msg); 13617 } 13618 13619 // Special case for adding a package: by default turn on compatibility 13620 // mode. 13621 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13622 Uri data = intent.getData(); 13623 String ssp; 13624 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13625 mCompatModePackages.handlePackageAddedLocked(ssp, 13626 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13627 } 13628 } 13629 13630 /* 13631 * If this is the time zone changed action, queue up a message that will reset the timezone 13632 * of all currently running processes. This message will get queued up before the broadcast 13633 * happens. 13634 */ 13635 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13636 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13637 } 13638 13639 /* 13640 * If the user set the time, let all running processes know. 13641 */ 13642 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13643 final int is24Hour = intent.getBooleanExtra( 13644 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13645 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13646 } 13647 13648 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13649 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13650 } 13651 13652 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13653 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13654 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13655 } 13656 13657 // Add to the sticky list if requested. 13658 if (sticky) { 13659 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13660 callingPid, callingUid) 13661 != PackageManager.PERMISSION_GRANTED) { 13662 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13663 + callingPid + ", uid=" + callingUid 13664 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13665 Slog.w(TAG, msg); 13666 throw new SecurityException(msg); 13667 } 13668 if (requiredPermission != null) { 13669 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13670 + " and enforce permission " + requiredPermission); 13671 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13672 } 13673 if (intent.getComponent() != null) { 13674 throw new SecurityException( 13675 "Sticky broadcasts can't target a specific component"); 13676 } 13677 // We use userId directly here, since the "all" target is maintained 13678 // as a separate set of sticky broadcasts. 13679 if (userId != UserHandle.USER_ALL) { 13680 // But first, if this is not a broadcast to all users, then 13681 // make sure it doesn't conflict with an existing broadcast to 13682 // all users. 13683 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13684 UserHandle.USER_ALL); 13685 if (stickies != null) { 13686 ArrayList<Intent> list = stickies.get(intent.getAction()); 13687 if (list != null) { 13688 int N = list.size(); 13689 int i; 13690 for (i=0; i<N; i++) { 13691 if (intent.filterEquals(list.get(i))) { 13692 throw new IllegalArgumentException( 13693 "Sticky broadcast " + intent + " for user " 13694 + userId + " conflicts with existing global broadcast"); 13695 } 13696 } 13697 } 13698 } 13699 } 13700 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13701 if (stickies == null) { 13702 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13703 mStickyBroadcasts.put(userId, stickies); 13704 } 13705 ArrayList<Intent> list = stickies.get(intent.getAction()); 13706 if (list == null) { 13707 list = new ArrayList<Intent>(); 13708 stickies.put(intent.getAction(), list); 13709 } 13710 int N = list.size(); 13711 int i; 13712 for (i=0; i<N; i++) { 13713 if (intent.filterEquals(list.get(i))) { 13714 // This sticky already exists, replace it. 13715 list.set(i, new Intent(intent)); 13716 break; 13717 } 13718 } 13719 if (i >= N) { 13720 list.add(new Intent(intent)); 13721 } 13722 } 13723 13724 int[] users; 13725 if (userId == UserHandle.USER_ALL) { 13726 // Caller wants broadcast to go to all started users. 13727 users = mStartedUserArray; 13728 } else { 13729 // Caller wants broadcast to go to one specific user. 13730 users = new int[] {userId}; 13731 } 13732 13733 // Figure out who all will receive this broadcast. 13734 List receivers = null; 13735 List<BroadcastFilter> registeredReceivers = null; 13736 // Need to resolve the intent to interested receivers... 13737 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13738 == 0) { 13739 receivers = collectReceiverComponents(intent, resolvedType, users); 13740 } 13741 if (intent.getComponent() == null) { 13742 registeredReceivers = mReceiverResolver.queryIntent(intent, 13743 resolvedType, false, userId); 13744 } 13745 13746 final boolean replacePending = 13747 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13748 13749 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13750 + " replacePending=" + replacePending); 13751 13752 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13753 if (!ordered && NR > 0) { 13754 // If we are not serializing this broadcast, then send the 13755 // registered receivers separately so they don't wait for the 13756 // components to be launched. 13757 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13758 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13759 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13760 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13761 ordered, sticky, false, userId); 13762 if (DEBUG_BROADCAST) Slog.v( 13763 TAG, "Enqueueing parallel broadcast " + r); 13764 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13765 if (!replaced) { 13766 queue.enqueueParallelBroadcastLocked(r); 13767 queue.scheduleBroadcastsLocked(); 13768 } 13769 registeredReceivers = null; 13770 NR = 0; 13771 } 13772 13773 // Merge into one list. 13774 int ir = 0; 13775 if (receivers != null) { 13776 // A special case for PACKAGE_ADDED: do not allow the package 13777 // being added to see this broadcast. This prevents them from 13778 // using this as a back door to get run as soon as they are 13779 // installed. Maybe in the future we want to have a special install 13780 // broadcast or such for apps, but we'd like to deliberately make 13781 // this decision. 13782 String skipPackages[] = null; 13783 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13784 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13785 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13786 Uri data = intent.getData(); 13787 if (data != null) { 13788 String pkgName = data.getSchemeSpecificPart(); 13789 if (pkgName != null) { 13790 skipPackages = new String[] { pkgName }; 13791 } 13792 } 13793 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13794 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13795 } 13796 if (skipPackages != null && (skipPackages.length > 0)) { 13797 for (String skipPackage : skipPackages) { 13798 if (skipPackage != null) { 13799 int NT = receivers.size(); 13800 for (int it=0; it<NT; it++) { 13801 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13802 if (curt.activityInfo.packageName.equals(skipPackage)) { 13803 receivers.remove(it); 13804 it--; 13805 NT--; 13806 } 13807 } 13808 } 13809 } 13810 } 13811 13812 int NT = receivers != null ? receivers.size() : 0; 13813 int it = 0; 13814 ResolveInfo curt = null; 13815 BroadcastFilter curr = null; 13816 while (it < NT && ir < NR) { 13817 if (curt == null) { 13818 curt = (ResolveInfo)receivers.get(it); 13819 } 13820 if (curr == null) { 13821 curr = registeredReceivers.get(ir); 13822 } 13823 if (curr.getPriority() >= curt.priority) { 13824 // Insert this broadcast record into the final list. 13825 receivers.add(it, curr); 13826 ir++; 13827 curr = null; 13828 it++; 13829 NT++; 13830 } else { 13831 // Skip to the next ResolveInfo in the final list. 13832 it++; 13833 curt = null; 13834 } 13835 } 13836 } 13837 while (ir < NR) { 13838 if (receivers == null) { 13839 receivers = new ArrayList(); 13840 } 13841 receivers.add(registeredReceivers.get(ir)); 13842 ir++; 13843 } 13844 13845 if ((receivers != null && receivers.size() > 0) 13846 || resultTo != null) { 13847 BroadcastQueue queue = broadcastQueueForIntent(intent); 13848 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13849 callerPackage, callingPid, callingUid, resolvedType, 13850 requiredPermission, appOp, receivers, resultTo, resultCode, 13851 resultData, map, ordered, sticky, false, userId); 13852 if (DEBUG_BROADCAST) Slog.v( 13853 TAG, "Enqueueing ordered broadcast " + r 13854 + ": prev had " + queue.mOrderedBroadcasts.size()); 13855 if (DEBUG_BROADCAST) { 13856 int seq = r.intent.getIntExtra("seq", -1); 13857 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13858 } 13859 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13860 if (!replaced) { 13861 queue.enqueueOrderedBroadcastLocked(r); 13862 queue.scheduleBroadcastsLocked(); 13863 } 13864 } 13865 13866 return ActivityManager.BROADCAST_SUCCESS; 13867 } 13868 13869 final Intent verifyBroadcastLocked(Intent intent) { 13870 // Refuse possible leaked file descriptors 13871 if (intent != null && intent.hasFileDescriptors() == true) { 13872 throw new IllegalArgumentException("File descriptors passed in Intent"); 13873 } 13874 13875 int flags = intent.getFlags(); 13876 13877 if (!mProcessesReady) { 13878 // if the caller really truly claims to know what they're doing, go 13879 // ahead and allow the broadcast without launching any receivers 13880 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13881 intent = new Intent(intent); 13882 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13883 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13884 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13885 + " before boot completion"); 13886 throw new IllegalStateException("Cannot broadcast before boot completed"); 13887 } 13888 } 13889 13890 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13891 throw new IllegalArgumentException( 13892 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13893 } 13894 13895 return intent; 13896 } 13897 13898 public final int broadcastIntent(IApplicationThread caller, 13899 Intent intent, String resolvedType, IIntentReceiver resultTo, 13900 int resultCode, String resultData, Bundle map, 13901 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13902 enforceNotIsolatedCaller("broadcastIntent"); 13903 synchronized(this) { 13904 intent = verifyBroadcastLocked(intent); 13905 13906 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13907 final int callingPid = Binder.getCallingPid(); 13908 final int callingUid = Binder.getCallingUid(); 13909 final long origId = Binder.clearCallingIdentity(); 13910 int res = broadcastIntentLocked(callerApp, 13911 callerApp != null ? callerApp.info.packageName : null, 13912 intent, resolvedType, resultTo, 13913 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13914 callingPid, callingUid, userId); 13915 Binder.restoreCallingIdentity(origId); 13916 return res; 13917 } 13918 } 13919 13920 int broadcastIntentInPackage(String packageName, int uid, 13921 Intent intent, String resolvedType, IIntentReceiver resultTo, 13922 int resultCode, String resultData, Bundle map, 13923 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13924 synchronized(this) { 13925 intent = verifyBroadcastLocked(intent); 13926 13927 final long origId = Binder.clearCallingIdentity(); 13928 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13929 resultTo, resultCode, resultData, map, requiredPermission, 13930 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13931 Binder.restoreCallingIdentity(origId); 13932 return res; 13933 } 13934 } 13935 13936 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13937 // Refuse possible leaked file descriptors 13938 if (intent != null && intent.hasFileDescriptors() == true) { 13939 throw new IllegalArgumentException("File descriptors passed in Intent"); 13940 } 13941 13942 userId = handleIncomingUser(Binder.getCallingPid(), 13943 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13944 13945 synchronized(this) { 13946 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13947 != PackageManager.PERMISSION_GRANTED) { 13948 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13949 + Binder.getCallingPid() 13950 + ", uid=" + Binder.getCallingUid() 13951 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13952 Slog.w(TAG, msg); 13953 throw new SecurityException(msg); 13954 } 13955 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13956 if (stickies != null) { 13957 ArrayList<Intent> list = stickies.get(intent.getAction()); 13958 if (list != null) { 13959 int N = list.size(); 13960 int i; 13961 for (i=0; i<N; i++) { 13962 if (intent.filterEquals(list.get(i))) { 13963 list.remove(i); 13964 break; 13965 } 13966 } 13967 if (list.size() <= 0) { 13968 stickies.remove(intent.getAction()); 13969 } 13970 } 13971 if (stickies.size() <= 0) { 13972 mStickyBroadcasts.remove(userId); 13973 } 13974 } 13975 } 13976 } 13977 13978 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13979 String resultData, Bundle resultExtras, boolean resultAbort) { 13980 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13981 if (r == null) { 13982 Slog.w(TAG, "finishReceiver called but not found on queue"); 13983 return false; 13984 } 13985 13986 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13987 } 13988 13989 void backgroundServicesFinishedLocked(int userId) { 13990 for (BroadcastQueue queue : mBroadcastQueues) { 13991 queue.backgroundServicesFinishedLocked(userId); 13992 } 13993 } 13994 13995 public void finishReceiver(IBinder who, int resultCode, String resultData, 13996 Bundle resultExtras, boolean resultAbort) { 13997 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13998 13999 // Refuse possible leaked file descriptors 14000 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14001 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14002 } 14003 14004 final long origId = Binder.clearCallingIdentity(); 14005 try { 14006 boolean doNext = false; 14007 BroadcastRecord r; 14008 14009 synchronized(this) { 14010 r = broadcastRecordForReceiverLocked(who); 14011 if (r != null) { 14012 doNext = r.queue.finishReceiverLocked(r, resultCode, 14013 resultData, resultExtras, resultAbort, true); 14014 } 14015 } 14016 14017 if (doNext) { 14018 r.queue.processNextBroadcast(false); 14019 } 14020 trimApplications(); 14021 } finally { 14022 Binder.restoreCallingIdentity(origId); 14023 } 14024 } 14025 14026 // ========================================================= 14027 // INSTRUMENTATION 14028 // ========================================================= 14029 14030 public boolean startInstrumentation(ComponentName className, 14031 String profileFile, int flags, Bundle arguments, 14032 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14033 int userId) { 14034 enforceNotIsolatedCaller("startInstrumentation"); 14035 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14036 userId, false, true, "startInstrumentation", null); 14037 // Refuse possible leaked file descriptors 14038 if (arguments != null && arguments.hasFileDescriptors()) { 14039 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14040 } 14041 14042 synchronized(this) { 14043 InstrumentationInfo ii = null; 14044 ApplicationInfo ai = null; 14045 try { 14046 ii = mContext.getPackageManager().getInstrumentationInfo( 14047 className, STOCK_PM_FLAGS); 14048 ai = AppGlobals.getPackageManager().getApplicationInfo( 14049 ii.targetPackage, STOCK_PM_FLAGS, userId); 14050 } catch (PackageManager.NameNotFoundException e) { 14051 } catch (RemoteException e) { 14052 } 14053 if (ii == null) { 14054 reportStartInstrumentationFailure(watcher, className, 14055 "Unable to find instrumentation info for: " + className); 14056 return false; 14057 } 14058 if (ai == null) { 14059 reportStartInstrumentationFailure(watcher, className, 14060 "Unable to find instrumentation target package: " + ii.targetPackage); 14061 return false; 14062 } 14063 14064 int match = mContext.getPackageManager().checkSignatures( 14065 ii.targetPackage, ii.packageName); 14066 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14067 String msg = "Permission Denial: starting instrumentation " 14068 + className + " from pid=" 14069 + Binder.getCallingPid() 14070 + ", uid=" + Binder.getCallingPid() 14071 + " not allowed because package " + ii.packageName 14072 + " does not have a signature matching the target " 14073 + ii.targetPackage; 14074 reportStartInstrumentationFailure(watcher, className, msg); 14075 throw new SecurityException(msg); 14076 } 14077 14078 final long origId = Binder.clearCallingIdentity(); 14079 // Instrumentation can kill and relaunch even persistent processes 14080 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14081 "start instr"); 14082 ProcessRecord app = addAppLocked(ai, false); 14083 app.instrumentationClass = className; 14084 app.instrumentationInfo = ai; 14085 app.instrumentationProfileFile = profileFile; 14086 app.instrumentationArguments = arguments; 14087 app.instrumentationWatcher = watcher; 14088 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14089 app.instrumentationResultClass = className; 14090 Binder.restoreCallingIdentity(origId); 14091 } 14092 14093 return true; 14094 } 14095 14096 /** 14097 * Report errors that occur while attempting to start Instrumentation. Always writes the 14098 * error to the logs, but if somebody is watching, send the report there too. This enables 14099 * the "am" command to report errors with more information. 14100 * 14101 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14102 * @param cn The component name of the instrumentation. 14103 * @param report The error report. 14104 */ 14105 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14106 ComponentName cn, String report) { 14107 Slog.w(TAG, report); 14108 try { 14109 if (watcher != null) { 14110 Bundle results = new Bundle(); 14111 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14112 results.putString("Error", report); 14113 watcher.instrumentationStatus(cn, -1, results); 14114 } 14115 } catch (RemoteException e) { 14116 Slog.w(TAG, e); 14117 } 14118 } 14119 14120 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14121 if (app.instrumentationWatcher != null) { 14122 try { 14123 // NOTE: IInstrumentationWatcher *must* be oneway here 14124 app.instrumentationWatcher.instrumentationFinished( 14125 app.instrumentationClass, 14126 resultCode, 14127 results); 14128 } catch (RemoteException e) { 14129 } 14130 } 14131 if (app.instrumentationUiAutomationConnection != null) { 14132 try { 14133 app.instrumentationUiAutomationConnection.shutdown(); 14134 } catch (RemoteException re) { 14135 /* ignore */ 14136 } 14137 // Only a UiAutomation can set this flag and now that 14138 // it is finished we make sure it is reset to its default. 14139 mUserIsMonkey = false; 14140 } 14141 app.instrumentationWatcher = null; 14142 app.instrumentationUiAutomationConnection = null; 14143 app.instrumentationClass = null; 14144 app.instrumentationInfo = null; 14145 app.instrumentationProfileFile = null; 14146 app.instrumentationArguments = null; 14147 14148 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14149 "finished inst"); 14150 } 14151 14152 public void finishInstrumentation(IApplicationThread target, 14153 int resultCode, Bundle results) { 14154 int userId = UserHandle.getCallingUserId(); 14155 // Refuse possible leaked file descriptors 14156 if (results != null && results.hasFileDescriptors()) { 14157 throw new IllegalArgumentException("File descriptors passed in Intent"); 14158 } 14159 14160 synchronized(this) { 14161 ProcessRecord app = getRecordForAppLocked(target); 14162 if (app == null) { 14163 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14164 return; 14165 } 14166 final long origId = Binder.clearCallingIdentity(); 14167 finishInstrumentationLocked(app, resultCode, results); 14168 Binder.restoreCallingIdentity(origId); 14169 } 14170 } 14171 14172 // ========================================================= 14173 // CONFIGURATION 14174 // ========================================================= 14175 14176 public ConfigurationInfo getDeviceConfigurationInfo() { 14177 ConfigurationInfo config = new ConfigurationInfo(); 14178 synchronized (this) { 14179 config.reqTouchScreen = mConfiguration.touchscreen; 14180 config.reqKeyboardType = mConfiguration.keyboard; 14181 config.reqNavigation = mConfiguration.navigation; 14182 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14183 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14184 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14185 } 14186 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14187 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14188 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14189 } 14190 config.reqGlEsVersion = GL_ES_VERSION; 14191 } 14192 return config; 14193 } 14194 14195 ActivityStack getFocusedStack() { 14196 return mStackSupervisor.getFocusedStack(); 14197 } 14198 14199 public Configuration getConfiguration() { 14200 Configuration ci; 14201 synchronized(this) { 14202 ci = new Configuration(mConfiguration); 14203 } 14204 return ci; 14205 } 14206 14207 public void updatePersistentConfiguration(Configuration values) { 14208 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14209 "updateConfiguration()"); 14210 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14211 "updateConfiguration()"); 14212 if (values == null) { 14213 throw new NullPointerException("Configuration must not be null"); 14214 } 14215 14216 synchronized(this) { 14217 final long origId = Binder.clearCallingIdentity(); 14218 updateConfigurationLocked(values, null, true, false); 14219 Binder.restoreCallingIdentity(origId); 14220 } 14221 } 14222 14223 public void updateConfiguration(Configuration values) { 14224 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14225 "updateConfiguration()"); 14226 14227 synchronized(this) { 14228 if (values == null && mWindowManager != null) { 14229 // sentinel: fetch the current configuration from the window manager 14230 values = mWindowManager.computeNewConfiguration(); 14231 } 14232 14233 if (mWindowManager != null) { 14234 mProcessList.applyDisplaySize(mWindowManager); 14235 } 14236 14237 final long origId = Binder.clearCallingIdentity(); 14238 if (values != null) { 14239 Settings.System.clearConfiguration(values); 14240 } 14241 updateConfigurationLocked(values, null, false, false); 14242 Binder.restoreCallingIdentity(origId); 14243 } 14244 } 14245 14246 /** 14247 * Do either or both things: (1) change the current configuration, and (2) 14248 * make sure the given activity is running with the (now) current 14249 * configuration. Returns true if the activity has been left running, or 14250 * false if <var>starting</var> is being destroyed to match the new 14251 * configuration. 14252 * @param persistent TODO 14253 */ 14254 boolean updateConfigurationLocked(Configuration values, 14255 ActivityRecord starting, boolean persistent, boolean initLocale) { 14256 int changes = 0; 14257 14258 if (values != null) { 14259 Configuration newConfig = new Configuration(mConfiguration); 14260 changes = newConfig.updateFrom(values); 14261 if (changes != 0) { 14262 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14263 Slog.i(TAG, "Updating configuration to: " + values); 14264 } 14265 14266 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14267 14268 if (values.locale != null && !initLocale) { 14269 saveLocaleLocked(values.locale, 14270 !values.locale.equals(mConfiguration.locale), 14271 values.userSetLocale); 14272 } 14273 14274 mConfigurationSeq++; 14275 if (mConfigurationSeq <= 0) { 14276 mConfigurationSeq = 1; 14277 } 14278 newConfig.seq = mConfigurationSeq; 14279 mConfiguration = newConfig; 14280 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14281 14282 final Configuration configCopy = new Configuration(mConfiguration); 14283 14284 // TODO: If our config changes, should we auto dismiss any currently 14285 // showing dialogs? 14286 mShowDialogs = shouldShowDialogs(newConfig); 14287 14288 AttributeCache ac = AttributeCache.instance(); 14289 if (ac != null) { 14290 ac.updateConfiguration(configCopy); 14291 } 14292 14293 // Make sure all resources in our process are updated 14294 // right now, so that anyone who is going to retrieve 14295 // resource values after we return will be sure to get 14296 // the new ones. This is especially important during 14297 // boot, where the first config change needs to guarantee 14298 // all resources have that config before following boot 14299 // code is executed. 14300 mSystemThread.applyConfigurationToResources(configCopy); 14301 14302 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14303 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14304 msg.obj = new Configuration(configCopy); 14305 mHandler.sendMessage(msg); 14306 } 14307 14308 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14309 ProcessRecord app = mLruProcesses.get(i); 14310 try { 14311 if (app.thread != null) { 14312 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14313 + app.processName + " new config " + mConfiguration); 14314 app.thread.scheduleConfigurationChanged(configCopy); 14315 } 14316 } catch (Exception e) { 14317 } 14318 } 14319 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14320 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14321 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14322 | Intent.FLAG_RECEIVER_FOREGROUND); 14323 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14324 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14325 Process.SYSTEM_UID, UserHandle.USER_ALL); 14326 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14327 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14328 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14329 broadcastIntentLocked(null, null, intent, 14330 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14331 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14332 } 14333 } 14334 } 14335 14336 boolean kept = true; 14337 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14338 // mainStack is null during startup. 14339 if (mainStack != null) { 14340 if (changes != 0 && starting == null) { 14341 // If the configuration changed, and the caller is not already 14342 // in the process of starting an activity, then find the top 14343 // activity to check if its configuration needs to change. 14344 starting = mainStack.topRunningActivityLocked(null); 14345 } 14346 14347 if (starting != null) { 14348 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14349 // And we need to make sure at this point that all other activities 14350 // are made visible with the correct configuration. 14351 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14352 } 14353 } 14354 14355 if (values != null && mWindowManager != null) { 14356 mWindowManager.setNewConfiguration(mConfiguration); 14357 } 14358 14359 return kept; 14360 } 14361 14362 /** 14363 * Decide based on the configuration whether we should shouw the ANR, 14364 * crash, etc dialogs. The idea is that if there is no affordnace to 14365 * press the on-screen buttons, we shouldn't show the dialog. 14366 * 14367 * A thought: SystemUI might also want to get told about this, the Power 14368 * dialog / global actions also might want different behaviors. 14369 */ 14370 private static final boolean shouldShowDialogs(Configuration config) { 14371 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14372 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14373 } 14374 14375 /** 14376 * Save the locale. You must be inside a synchronized (this) block. 14377 */ 14378 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14379 if(isDiff) { 14380 SystemProperties.set("user.language", l.getLanguage()); 14381 SystemProperties.set("user.region", l.getCountry()); 14382 } 14383 14384 if(isPersist) { 14385 SystemProperties.set("persist.sys.language", l.getLanguage()); 14386 SystemProperties.set("persist.sys.country", l.getCountry()); 14387 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14388 } 14389 } 14390 14391 @Override 14392 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14393 ActivityRecord srec = ActivityRecord.forToken(token); 14394 return srec != null && srec.task.affinity != null && 14395 srec.task.affinity.equals(destAffinity); 14396 } 14397 14398 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14399 Intent resultData) { 14400 14401 synchronized (this) { 14402 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14403 if (stack != null) { 14404 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14405 } 14406 return false; 14407 } 14408 } 14409 14410 public int getLaunchedFromUid(IBinder activityToken) { 14411 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14412 if (srec == null) { 14413 return -1; 14414 } 14415 return srec.launchedFromUid; 14416 } 14417 14418 public String getLaunchedFromPackage(IBinder activityToken) { 14419 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14420 if (srec == null) { 14421 return null; 14422 } 14423 return srec.launchedFromPackage; 14424 } 14425 14426 // ========================================================= 14427 // LIFETIME MANAGEMENT 14428 // ========================================================= 14429 14430 // Returns which broadcast queue the app is the current [or imminent] receiver 14431 // on, or 'null' if the app is not an active broadcast recipient. 14432 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14433 BroadcastRecord r = app.curReceiver; 14434 if (r != null) { 14435 return r.queue; 14436 } 14437 14438 // It's not the current receiver, but it might be starting up to become one 14439 synchronized (this) { 14440 for (BroadcastQueue queue : mBroadcastQueues) { 14441 r = queue.mPendingBroadcast; 14442 if (r != null && r.curApp == app) { 14443 // found it; report which queue it's in 14444 return queue; 14445 } 14446 } 14447 } 14448 14449 return null; 14450 } 14451 14452 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14453 boolean doingAll, long now) { 14454 if (mAdjSeq == app.adjSeq) { 14455 // This adjustment has already been computed. 14456 return app.curRawAdj; 14457 } 14458 14459 if (app.thread == null) { 14460 app.adjSeq = mAdjSeq; 14461 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14462 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14463 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14464 } 14465 14466 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14467 app.adjSource = null; 14468 app.adjTarget = null; 14469 app.empty = false; 14470 app.cached = false; 14471 14472 final int activitiesSize = app.activities.size(); 14473 14474 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14475 // The max adjustment doesn't allow this app to be anything 14476 // below foreground, so it is not worth doing work for it. 14477 app.adjType = "fixed"; 14478 app.adjSeq = mAdjSeq; 14479 app.curRawAdj = app.maxAdj; 14480 app.foregroundActivities = false; 14481 app.keeping = true; 14482 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14483 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14484 // System process can do UI, and when they do we want to have 14485 // them trim their memory after the user leaves the UI. To 14486 // facilitate this, here we need to determine whether or not it 14487 // is currently showing UI. 14488 app.systemNoUi = true; 14489 if (app == TOP_APP) { 14490 app.systemNoUi = false; 14491 } else if (activitiesSize > 0) { 14492 for (int j = 0; j < activitiesSize; j++) { 14493 final ActivityRecord r = app.activities.get(j); 14494 if (r.visible) { 14495 app.systemNoUi = false; 14496 } 14497 } 14498 } 14499 if (!app.systemNoUi) { 14500 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14501 } 14502 return (app.curAdj=app.maxAdj); 14503 } 14504 14505 app.keeping = false; 14506 app.systemNoUi = false; 14507 14508 // Determine the importance of the process, starting with most 14509 // important to least, and assign an appropriate OOM adjustment. 14510 int adj; 14511 int schedGroup; 14512 int procState; 14513 boolean foregroundActivities = false; 14514 boolean interesting = false; 14515 BroadcastQueue queue; 14516 if (app == TOP_APP) { 14517 // The last app on the list is the foreground app. 14518 adj = ProcessList.FOREGROUND_APP_ADJ; 14519 schedGroup = Process.THREAD_GROUP_DEFAULT; 14520 app.adjType = "top-activity"; 14521 foregroundActivities = true; 14522 interesting = true; 14523 procState = ActivityManager.PROCESS_STATE_TOP; 14524 } else if (app.instrumentationClass != null) { 14525 // Don't want to kill running instrumentation. 14526 adj = ProcessList.FOREGROUND_APP_ADJ; 14527 schedGroup = Process.THREAD_GROUP_DEFAULT; 14528 app.adjType = "instrumentation"; 14529 interesting = true; 14530 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14531 } else if ((queue = isReceivingBroadcast(app)) != null) { 14532 // An app that is currently receiving a broadcast also 14533 // counts as being in the foreground for OOM killer purposes. 14534 // It's placed in a sched group based on the nature of the 14535 // broadcast as reflected by which queue it's active in. 14536 adj = ProcessList.FOREGROUND_APP_ADJ; 14537 schedGroup = (queue == mFgBroadcastQueue) 14538 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14539 app.adjType = "broadcast"; 14540 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14541 } else if (app.executingServices.size() > 0) { 14542 // An app that is currently executing a service callback also 14543 // counts as being in the foreground. 14544 adj = ProcessList.FOREGROUND_APP_ADJ; 14545 schedGroup = app.execServicesFg ? 14546 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14547 app.adjType = "exec-service"; 14548 procState = ActivityManager.PROCESS_STATE_SERVICE; 14549 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14550 } else { 14551 // As far as we know the process is empty. We may change our mind later. 14552 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14553 // At this point we don't actually know the adjustment. Use the cached adj 14554 // value that the caller wants us to. 14555 adj = cachedAdj; 14556 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14557 app.cached = true; 14558 app.empty = true; 14559 app.adjType = "cch-empty"; 14560 } 14561 14562 // Examine all activities if not already foreground. 14563 if (!foregroundActivities && activitiesSize > 0) { 14564 for (int j = 0; j < activitiesSize; j++) { 14565 final ActivityRecord r = app.activities.get(j); 14566 if (r.app != app) { 14567 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14568 + app + "?!?"); 14569 continue; 14570 } 14571 if (r.visible) { 14572 // App has a visible activity; only upgrade adjustment. 14573 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14574 adj = ProcessList.VISIBLE_APP_ADJ; 14575 app.adjType = "visible"; 14576 } 14577 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14578 procState = ActivityManager.PROCESS_STATE_TOP; 14579 } 14580 schedGroup = Process.THREAD_GROUP_DEFAULT; 14581 app.cached = false; 14582 app.empty = false; 14583 foregroundActivities = true; 14584 break; 14585 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14586 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14587 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14588 app.adjType = "pausing"; 14589 } 14590 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14591 procState = ActivityManager.PROCESS_STATE_TOP; 14592 } 14593 schedGroup = Process.THREAD_GROUP_DEFAULT; 14594 app.cached = false; 14595 app.empty = false; 14596 foregroundActivities = true; 14597 } else if (r.state == ActivityState.STOPPING) { 14598 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14599 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14600 app.adjType = "stopping"; 14601 } 14602 // For the process state, we will at this point consider the 14603 // process to be cached. It will be cached either as an activity 14604 // or empty depending on whether the activity is finishing. We do 14605 // this so that we can treat the process as cached for purposes of 14606 // memory trimming (determing current memory level, trim command to 14607 // send to process) since there can be an arbitrary number of stopping 14608 // processes and they should soon all go into the cached state. 14609 if (!r.finishing) { 14610 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14611 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14612 } 14613 } 14614 app.cached = false; 14615 app.empty = false; 14616 foregroundActivities = true; 14617 } else { 14618 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14619 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14620 app.adjType = "cch-act"; 14621 } 14622 } 14623 } 14624 } 14625 14626 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14627 if (app.foregroundServices) { 14628 // The user is aware of this app, so make it visible. 14629 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14630 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14631 app.cached = false; 14632 app.adjType = "fg-service"; 14633 schedGroup = Process.THREAD_GROUP_DEFAULT; 14634 } else if (app.forcingToForeground != null) { 14635 // The user is aware of this app, so make it visible. 14636 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14637 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14638 app.cached = false; 14639 app.adjType = "force-fg"; 14640 app.adjSource = app.forcingToForeground; 14641 schedGroup = Process.THREAD_GROUP_DEFAULT; 14642 } 14643 } 14644 14645 if (app.foregroundServices) { 14646 interesting = true; 14647 } 14648 14649 if (app == mHeavyWeightProcess) { 14650 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14651 // We don't want to kill the current heavy-weight process. 14652 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14653 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14654 app.cached = false; 14655 app.adjType = "heavy"; 14656 } 14657 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14658 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14659 } 14660 } 14661 14662 if (app == mHomeProcess) { 14663 if (adj > ProcessList.HOME_APP_ADJ) { 14664 // This process is hosting what we currently consider to be the 14665 // home app, so we don't want to let it go into the background. 14666 adj = ProcessList.HOME_APP_ADJ; 14667 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14668 app.cached = false; 14669 app.adjType = "home"; 14670 } 14671 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14672 procState = ActivityManager.PROCESS_STATE_HOME; 14673 } 14674 } 14675 14676 if (app == mPreviousProcess && app.activities.size() > 0) { 14677 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14678 // This was the previous process that showed UI to the user. 14679 // We want to try to keep it around more aggressively, to give 14680 // a good experience around switching between two apps. 14681 adj = ProcessList.PREVIOUS_APP_ADJ; 14682 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14683 app.cached = false; 14684 app.adjType = "previous"; 14685 } 14686 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14687 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14688 } 14689 } 14690 14691 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14692 + " reason=" + app.adjType); 14693 14694 // By default, we use the computed adjustment. It may be changed if 14695 // there are applications dependent on our services or providers, but 14696 // this gives us a baseline and makes sure we don't get into an 14697 // infinite recursion. 14698 app.adjSeq = mAdjSeq; 14699 app.curRawAdj = adj; 14700 app.hasStartedServices = false; 14701 14702 if (mBackupTarget != null && app == mBackupTarget.app) { 14703 // If possible we want to avoid killing apps while they're being backed up 14704 if (adj > ProcessList.BACKUP_APP_ADJ) { 14705 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14706 adj = ProcessList.BACKUP_APP_ADJ; 14707 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14708 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14709 } 14710 app.adjType = "backup"; 14711 app.cached = false; 14712 } 14713 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14714 procState = ActivityManager.PROCESS_STATE_BACKUP; 14715 } 14716 } 14717 14718 boolean mayBeTop = false; 14719 14720 for (int is = app.services.size()-1; 14721 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14722 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14723 || procState > ActivityManager.PROCESS_STATE_TOP); 14724 is--) { 14725 ServiceRecord s = app.services.valueAt(is); 14726 if (s.startRequested) { 14727 app.hasStartedServices = true; 14728 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14729 procState = ActivityManager.PROCESS_STATE_SERVICE; 14730 } 14731 if (app.hasShownUi && app != mHomeProcess) { 14732 // If this process has shown some UI, let it immediately 14733 // go to the LRU list because it may be pretty heavy with 14734 // UI stuff. We'll tag it with a label just to help 14735 // debug and understand what is going on. 14736 if (adj > ProcessList.SERVICE_ADJ) { 14737 app.adjType = "cch-started-ui-services"; 14738 } 14739 } else { 14740 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14741 // This service has seen some activity within 14742 // recent memory, so we will keep its process ahead 14743 // of the background processes. 14744 if (adj > ProcessList.SERVICE_ADJ) { 14745 adj = ProcessList.SERVICE_ADJ; 14746 app.adjType = "started-services"; 14747 app.cached = false; 14748 } 14749 } 14750 // If we have let the service slide into the background 14751 // state, still have some text describing what it is doing 14752 // even though the service no longer has an impact. 14753 if (adj > ProcessList.SERVICE_ADJ) { 14754 app.adjType = "cch-started-services"; 14755 } 14756 } 14757 // Don't kill this process because it is doing work; it 14758 // has said it is doing work. 14759 app.keeping = true; 14760 } 14761 for (int conni = s.connections.size()-1; 14762 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14763 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14764 || procState > ActivityManager.PROCESS_STATE_TOP); 14765 conni--) { 14766 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14767 for (int i = 0; 14768 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14769 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14770 || procState > ActivityManager.PROCESS_STATE_TOP); 14771 i++) { 14772 // XXX should compute this based on the max of 14773 // all connected clients. 14774 ConnectionRecord cr = clist.get(i); 14775 if (cr.binding.client == app) { 14776 // Binding to ourself is not interesting. 14777 continue; 14778 } 14779 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14780 ProcessRecord client = cr.binding.client; 14781 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14782 TOP_APP, doingAll, now); 14783 int clientProcState = client.curProcState; 14784 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14785 // If the other app is cached for any reason, for purposes here 14786 // we are going to consider it empty. The specific cached state 14787 // doesn't propagate except under certain conditions. 14788 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14789 } 14790 String adjType = null; 14791 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14792 // Not doing bind OOM management, so treat 14793 // this guy more like a started service. 14794 if (app.hasShownUi && app != mHomeProcess) { 14795 // If this process has shown some UI, let it immediately 14796 // go to the LRU list because it may be pretty heavy with 14797 // UI stuff. We'll tag it with a label just to help 14798 // debug and understand what is going on. 14799 if (adj > clientAdj) { 14800 adjType = "cch-bound-ui-services"; 14801 } 14802 app.cached = false; 14803 clientAdj = adj; 14804 clientProcState = procState; 14805 } else { 14806 if (now >= (s.lastActivity 14807 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14808 // This service has not seen activity within 14809 // recent memory, so allow it to drop to the 14810 // LRU list if there is no other reason to keep 14811 // it around. We'll also tag it with a label just 14812 // to help debug and undertand what is going on. 14813 if (adj > clientAdj) { 14814 adjType = "cch-bound-services"; 14815 } 14816 clientAdj = adj; 14817 } 14818 } 14819 } 14820 if (adj > clientAdj) { 14821 // If this process has recently shown UI, and 14822 // the process that is binding to it is less 14823 // important than being visible, then we don't 14824 // care about the binding as much as we care 14825 // about letting this process get into the LRU 14826 // list to be killed and restarted if needed for 14827 // memory. 14828 if (app.hasShownUi && app != mHomeProcess 14829 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14830 adjType = "cch-bound-ui-services"; 14831 } else { 14832 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14833 |Context.BIND_IMPORTANT)) != 0) { 14834 adj = clientAdj; 14835 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14836 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14837 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14838 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14839 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14840 adj = clientAdj; 14841 } else { 14842 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14843 adj = ProcessList.VISIBLE_APP_ADJ; 14844 } 14845 } 14846 if (!client.cached) { 14847 app.cached = false; 14848 } 14849 if (client.keeping) { 14850 app.keeping = true; 14851 } 14852 adjType = "service"; 14853 } 14854 } 14855 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14856 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14857 schedGroup = Process.THREAD_GROUP_DEFAULT; 14858 } 14859 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14860 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14861 // Special handling of clients who are in the top state. 14862 // We *may* want to consider this process to be in the 14863 // top state as well, but only if there is not another 14864 // reason for it to be running. Being on the top is a 14865 // special state, meaning you are specifically running 14866 // for the current top app. If the process is already 14867 // running in the background for some other reason, it 14868 // is more important to continue considering it to be 14869 // in the background state. 14870 mayBeTop = true; 14871 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14872 } else { 14873 // Special handling for above-top states (persistent 14874 // processes). These should not bring the current process 14875 // into the top state, since they are not on top. Instead 14876 // give them the best state after that. 14877 clientProcState = 14878 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14879 } 14880 } 14881 } else { 14882 if (clientProcState < 14883 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14884 clientProcState = 14885 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14886 } 14887 } 14888 if (procState > clientProcState) { 14889 procState = clientProcState; 14890 } 14891 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14892 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14893 app.pendingUiClean = true; 14894 } 14895 if (adjType != null) { 14896 app.adjType = adjType; 14897 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14898 .REASON_SERVICE_IN_USE; 14899 app.adjSource = cr.binding.client; 14900 app.adjSourceOom = clientAdj; 14901 app.adjTarget = s.name; 14902 } 14903 } 14904 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 14905 app.treatLikeActivity = true; 14906 } 14907 final ActivityRecord a = cr.activity; 14908 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14909 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14910 (a.visible || a.state == ActivityState.RESUMED 14911 || a.state == ActivityState.PAUSING)) { 14912 adj = ProcessList.FOREGROUND_APP_ADJ; 14913 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14914 schedGroup = Process.THREAD_GROUP_DEFAULT; 14915 } 14916 app.cached = false; 14917 app.adjType = "service"; 14918 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14919 .REASON_SERVICE_IN_USE; 14920 app.adjSource = a; 14921 app.adjSourceOom = adj; 14922 app.adjTarget = s.name; 14923 } 14924 } 14925 } 14926 } 14927 } 14928 14929 for (int provi = app.pubProviders.size()-1; 14930 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14931 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14932 || procState > ActivityManager.PROCESS_STATE_TOP); 14933 provi--) { 14934 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14935 for (int i = cpr.connections.size()-1; 14936 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14937 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14938 || procState > ActivityManager.PROCESS_STATE_TOP); 14939 i--) { 14940 ContentProviderConnection conn = cpr.connections.get(i); 14941 ProcessRecord client = conn.client; 14942 if (client == app) { 14943 // Being our own client is not interesting. 14944 continue; 14945 } 14946 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14947 int clientProcState = client.curProcState; 14948 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14949 // If the other app is cached for any reason, for purposes here 14950 // we are going to consider it empty. 14951 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14952 } 14953 if (adj > clientAdj) { 14954 if (app.hasShownUi && app != mHomeProcess 14955 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14956 app.adjType = "cch-ui-provider"; 14957 } else { 14958 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14959 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14960 app.adjType = "provider"; 14961 } 14962 app.cached &= client.cached; 14963 app.keeping |= client.keeping; 14964 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14965 .REASON_PROVIDER_IN_USE; 14966 app.adjSource = client; 14967 app.adjSourceOom = clientAdj; 14968 app.adjTarget = cpr.name; 14969 } 14970 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14971 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14972 // Special handling of clients who are in the top state. 14973 // We *may* want to consider this process to be in the 14974 // top state as well, but only if there is not another 14975 // reason for it to be running. Being on the top is a 14976 // special state, meaning you are specifically running 14977 // for the current top app. If the process is already 14978 // running in the background for some other reason, it 14979 // is more important to continue considering it to be 14980 // in the background state. 14981 mayBeTop = true; 14982 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14983 } else { 14984 // Special handling for above-top states (persistent 14985 // processes). These should not bring the current process 14986 // into the top state, since they are not on top. Instead 14987 // give them the best state after that. 14988 clientProcState = 14989 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14990 } 14991 } 14992 if (procState > clientProcState) { 14993 procState = clientProcState; 14994 } 14995 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14996 schedGroup = Process.THREAD_GROUP_DEFAULT; 14997 } 14998 } 14999 // If the provider has external (non-framework) process 15000 // dependencies, ensure that its adjustment is at least 15001 // FOREGROUND_APP_ADJ. 15002 if (cpr.hasExternalProcessHandles()) { 15003 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15004 adj = ProcessList.FOREGROUND_APP_ADJ; 15005 schedGroup = Process.THREAD_GROUP_DEFAULT; 15006 app.cached = false; 15007 app.keeping = true; 15008 app.adjType = "provider"; 15009 app.adjTarget = cpr.name; 15010 } 15011 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15012 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15013 } 15014 } 15015 } 15016 15017 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15018 // A client of one of our services or providers is in the top state. We 15019 // *may* want to be in the top state, but not if we are already running in 15020 // the background for some other reason. For the decision here, we are going 15021 // to pick out a few specific states that we want to remain in when a client 15022 // is top (states that tend to be longer-term) and otherwise allow it to go 15023 // to the top state. 15024 switch (procState) { 15025 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15026 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15027 case ActivityManager.PROCESS_STATE_SERVICE: 15028 // These all are longer-term states, so pull them up to the top 15029 // of the background states, but not all the way to the top state. 15030 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15031 break; 15032 default: 15033 // Otherwise, top is a better choice, so take it. 15034 procState = ActivityManager.PROCESS_STATE_TOP; 15035 break; 15036 } 15037 } 15038 15039 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15040 if (app.hasClientActivities) { 15041 // This is a cached process, but with client activities. Mark it so. 15042 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15043 app.adjType = "cch-client-act"; 15044 } else if (app.treatLikeActivity) { 15045 // This is a cached process, but somebody wants us to treat it like it has 15046 // an activity, okay! 15047 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15048 app.adjType = "cch-as-act"; 15049 } 15050 } 15051 15052 if (adj == ProcessList.SERVICE_ADJ) { 15053 if (doingAll) { 15054 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15055 mNewNumServiceProcs++; 15056 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15057 if (!app.serviceb) { 15058 // This service isn't far enough down on the LRU list to 15059 // normally be a B service, but if we are low on RAM and it 15060 // is large we want to force it down since we would prefer to 15061 // keep launcher over it. 15062 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15063 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15064 app.serviceHighRam = true; 15065 app.serviceb = true; 15066 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15067 } else { 15068 mNewNumAServiceProcs++; 15069 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15070 } 15071 } else { 15072 app.serviceHighRam = false; 15073 } 15074 } 15075 if (app.serviceb) { 15076 adj = ProcessList.SERVICE_B_ADJ; 15077 } 15078 } 15079 15080 app.curRawAdj = adj; 15081 15082 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15083 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15084 if (adj > app.maxAdj) { 15085 adj = app.maxAdj; 15086 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15087 schedGroup = Process.THREAD_GROUP_DEFAULT; 15088 } 15089 } 15090 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15091 app.keeping = true; 15092 } 15093 15094 // Do final modification to adj. Everything we do between here and applying 15095 // the final setAdj must be done in this function, because we will also use 15096 // it when computing the final cached adj later. Note that we don't need to 15097 // worry about this for max adj above, since max adj will always be used to 15098 // keep it out of the cached vaues. 15099 adj = app.modifyRawOomAdj(adj); 15100 15101 app.curProcState = procState; 15102 15103 int importance = app.memImportance; 15104 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15105 app.curAdj = adj; 15106 app.curSchedGroup = schedGroup; 15107 if (!interesting) { 15108 // For this reporting, if there is not something explicitly 15109 // interesting in this process then we will push it to the 15110 // background importance. 15111 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15112 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15113 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15114 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15115 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15116 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15117 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15118 } else if (adj >= ProcessList.SERVICE_ADJ) { 15119 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15120 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15121 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15122 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15123 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15124 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15125 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15126 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15127 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15128 } else { 15129 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15130 } 15131 } 15132 15133 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15134 if (foregroundActivities != app.foregroundActivities) { 15135 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15136 } 15137 if (changes != 0) { 15138 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15139 app.memImportance = importance; 15140 app.foregroundActivities = foregroundActivities; 15141 int i = mPendingProcessChanges.size()-1; 15142 ProcessChangeItem item = null; 15143 while (i >= 0) { 15144 item = mPendingProcessChanges.get(i); 15145 if (item.pid == app.pid) { 15146 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15147 break; 15148 } 15149 i--; 15150 } 15151 if (i < 0) { 15152 // No existing item in pending changes; need a new one. 15153 final int NA = mAvailProcessChanges.size(); 15154 if (NA > 0) { 15155 item = mAvailProcessChanges.remove(NA-1); 15156 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15157 } else { 15158 item = new ProcessChangeItem(); 15159 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15160 } 15161 item.changes = 0; 15162 item.pid = app.pid; 15163 item.uid = app.info.uid; 15164 if (mPendingProcessChanges.size() == 0) { 15165 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15166 "*** Enqueueing dispatch processes changed!"); 15167 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15168 } 15169 mPendingProcessChanges.add(item); 15170 } 15171 item.changes |= changes; 15172 item.importance = importance; 15173 item.foregroundActivities = foregroundActivities; 15174 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15175 + Integer.toHexString(System.identityHashCode(item)) 15176 + " " + app.toShortString() + ": changes=" + item.changes 15177 + " importance=" + item.importance 15178 + " foreground=" + item.foregroundActivities 15179 + " type=" + app.adjType + " source=" + app.adjSource 15180 + " target=" + app.adjTarget); 15181 } 15182 15183 return app.curRawAdj; 15184 } 15185 15186 /** 15187 * Schedule PSS collection of a process. 15188 */ 15189 void requestPssLocked(ProcessRecord proc, int procState) { 15190 if (mPendingPssProcesses.contains(proc)) { 15191 return; 15192 } 15193 if (mPendingPssProcesses.size() == 0) { 15194 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15195 } 15196 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15197 proc.pssProcState = procState; 15198 mPendingPssProcesses.add(proc); 15199 } 15200 15201 /** 15202 * Schedule PSS collection of all processes. 15203 */ 15204 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15205 if (!always) { 15206 if (now < (mLastFullPssTime + 15207 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15208 return; 15209 } 15210 } 15211 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15212 mLastFullPssTime = now; 15213 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15214 mPendingPssProcesses.clear(); 15215 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15216 ProcessRecord app = mLruProcesses.get(i); 15217 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15218 app.pssProcState = app.setProcState; 15219 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15220 mSleeping, now); 15221 mPendingPssProcesses.add(app); 15222 } 15223 } 15224 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15225 } 15226 15227 /** 15228 * Ask a given process to GC right now. 15229 */ 15230 final void performAppGcLocked(ProcessRecord app) { 15231 try { 15232 app.lastRequestedGc = SystemClock.uptimeMillis(); 15233 if (app.thread != null) { 15234 if (app.reportLowMemory) { 15235 app.reportLowMemory = false; 15236 app.thread.scheduleLowMemory(); 15237 } else { 15238 app.thread.processInBackground(); 15239 } 15240 } 15241 } catch (Exception e) { 15242 // whatever. 15243 } 15244 } 15245 15246 /** 15247 * Returns true if things are idle enough to perform GCs. 15248 */ 15249 private final boolean canGcNowLocked() { 15250 boolean processingBroadcasts = false; 15251 for (BroadcastQueue q : mBroadcastQueues) { 15252 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15253 processingBroadcasts = true; 15254 } 15255 } 15256 return !processingBroadcasts 15257 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15258 } 15259 15260 /** 15261 * Perform GCs on all processes that are waiting for it, but only 15262 * if things are idle. 15263 */ 15264 final void performAppGcsLocked() { 15265 final int N = mProcessesToGc.size(); 15266 if (N <= 0) { 15267 return; 15268 } 15269 if (canGcNowLocked()) { 15270 while (mProcessesToGc.size() > 0) { 15271 ProcessRecord proc = mProcessesToGc.remove(0); 15272 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15273 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15274 <= SystemClock.uptimeMillis()) { 15275 // To avoid spamming the system, we will GC processes one 15276 // at a time, waiting a few seconds between each. 15277 performAppGcLocked(proc); 15278 scheduleAppGcsLocked(); 15279 return; 15280 } else { 15281 // It hasn't been long enough since we last GCed this 15282 // process... put it in the list to wait for its time. 15283 addProcessToGcListLocked(proc); 15284 break; 15285 } 15286 } 15287 } 15288 15289 scheduleAppGcsLocked(); 15290 } 15291 } 15292 15293 /** 15294 * If all looks good, perform GCs on all processes waiting for them. 15295 */ 15296 final void performAppGcsIfAppropriateLocked() { 15297 if (canGcNowLocked()) { 15298 performAppGcsLocked(); 15299 return; 15300 } 15301 // Still not idle, wait some more. 15302 scheduleAppGcsLocked(); 15303 } 15304 15305 /** 15306 * Schedule the execution of all pending app GCs. 15307 */ 15308 final void scheduleAppGcsLocked() { 15309 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15310 15311 if (mProcessesToGc.size() > 0) { 15312 // Schedule a GC for the time to the next process. 15313 ProcessRecord proc = mProcessesToGc.get(0); 15314 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15315 15316 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15317 long now = SystemClock.uptimeMillis(); 15318 if (when < (now+GC_TIMEOUT)) { 15319 when = now + GC_TIMEOUT; 15320 } 15321 mHandler.sendMessageAtTime(msg, when); 15322 } 15323 } 15324 15325 /** 15326 * Add a process to the array of processes waiting to be GCed. Keeps the 15327 * list in sorted order by the last GC time. The process can't already be 15328 * on the list. 15329 */ 15330 final void addProcessToGcListLocked(ProcessRecord proc) { 15331 boolean added = false; 15332 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15333 if (mProcessesToGc.get(i).lastRequestedGc < 15334 proc.lastRequestedGc) { 15335 added = true; 15336 mProcessesToGc.add(i+1, proc); 15337 break; 15338 } 15339 } 15340 if (!added) { 15341 mProcessesToGc.add(0, proc); 15342 } 15343 } 15344 15345 /** 15346 * Set up to ask a process to GC itself. This will either do it 15347 * immediately, or put it on the list of processes to gc the next 15348 * time things are idle. 15349 */ 15350 final void scheduleAppGcLocked(ProcessRecord app) { 15351 long now = SystemClock.uptimeMillis(); 15352 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15353 return; 15354 } 15355 if (!mProcessesToGc.contains(app)) { 15356 addProcessToGcListLocked(app); 15357 scheduleAppGcsLocked(); 15358 } 15359 } 15360 15361 final void checkExcessivePowerUsageLocked(boolean doKills) { 15362 updateCpuStatsNow(); 15363 15364 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15365 boolean doWakeKills = doKills; 15366 boolean doCpuKills = doKills; 15367 if (mLastPowerCheckRealtime == 0) { 15368 doWakeKills = false; 15369 } 15370 if (mLastPowerCheckUptime == 0) { 15371 doCpuKills = false; 15372 } 15373 if (stats.isScreenOn()) { 15374 doWakeKills = false; 15375 } 15376 final long curRealtime = SystemClock.elapsedRealtime(); 15377 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15378 final long curUptime = SystemClock.uptimeMillis(); 15379 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15380 mLastPowerCheckRealtime = curRealtime; 15381 mLastPowerCheckUptime = curUptime; 15382 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15383 doWakeKills = false; 15384 } 15385 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15386 doCpuKills = false; 15387 } 15388 int i = mLruProcesses.size(); 15389 while (i > 0) { 15390 i--; 15391 ProcessRecord app = mLruProcesses.get(i); 15392 if (!app.keeping) { 15393 long wtime; 15394 synchronized (stats) { 15395 wtime = stats.getProcessWakeTime(app.info.uid, 15396 app.pid, curRealtime); 15397 } 15398 long wtimeUsed = wtime - app.lastWakeTime; 15399 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15400 if (DEBUG_POWER) { 15401 StringBuilder sb = new StringBuilder(128); 15402 sb.append("Wake for "); 15403 app.toShortString(sb); 15404 sb.append(": over "); 15405 TimeUtils.formatDuration(realtimeSince, sb); 15406 sb.append(" used "); 15407 TimeUtils.formatDuration(wtimeUsed, sb); 15408 sb.append(" ("); 15409 sb.append((wtimeUsed*100)/realtimeSince); 15410 sb.append("%)"); 15411 Slog.i(TAG, sb.toString()); 15412 sb.setLength(0); 15413 sb.append("CPU for "); 15414 app.toShortString(sb); 15415 sb.append(": over "); 15416 TimeUtils.formatDuration(uptimeSince, sb); 15417 sb.append(" used "); 15418 TimeUtils.formatDuration(cputimeUsed, sb); 15419 sb.append(" ("); 15420 sb.append((cputimeUsed*100)/uptimeSince); 15421 sb.append("%)"); 15422 Slog.i(TAG, sb.toString()); 15423 } 15424 // If a process has held a wake lock for more 15425 // than 50% of the time during this period, 15426 // that sounds bad. Kill! 15427 if (doWakeKills && realtimeSince > 0 15428 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15429 synchronized (stats) { 15430 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15431 realtimeSince, wtimeUsed); 15432 } 15433 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15434 + " during " + realtimeSince); 15435 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15436 } else if (doCpuKills && uptimeSince > 0 15437 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15438 synchronized (stats) { 15439 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15440 uptimeSince, cputimeUsed); 15441 } 15442 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15443 + " during " + uptimeSince); 15444 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15445 } else { 15446 app.lastWakeTime = wtime; 15447 app.lastCpuTime = app.curCpuTime; 15448 } 15449 } 15450 } 15451 } 15452 15453 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15454 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15455 boolean success = true; 15456 15457 if (app.curRawAdj != app.setRawAdj) { 15458 if (wasKeeping && !app.keeping) { 15459 // This app is no longer something we want to keep. Note 15460 // its current wake lock time to later know to kill it if 15461 // it is not behaving well. 15462 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15463 synchronized (stats) { 15464 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15465 app.pid, SystemClock.elapsedRealtime()); 15466 } 15467 app.lastCpuTime = app.curCpuTime; 15468 } 15469 15470 app.setRawAdj = app.curRawAdj; 15471 } 15472 15473 if (app.curAdj != app.setAdj) { 15474 ProcessList.setOomAdj(app.pid, app.curAdj); 15475 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15476 TAG, "Set " + app.pid + " " + app.processName + 15477 " adj " + app.curAdj + ": " + app.adjType); 15478 app.setAdj = app.curAdj; 15479 } 15480 15481 if (app.setSchedGroup != app.curSchedGroup) { 15482 app.setSchedGroup = app.curSchedGroup; 15483 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15484 "Setting process group of " + app.processName 15485 + " to " + app.curSchedGroup); 15486 if (app.waitingToKill != null && 15487 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15488 killUnneededProcessLocked(app, app.waitingToKill); 15489 success = false; 15490 } else { 15491 if (true) { 15492 long oldId = Binder.clearCallingIdentity(); 15493 try { 15494 Process.setProcessGroup(app.pid, app.curSchedGroup); 15495 } catch (Exception e) { 15496 Slog.w(TAG, "Failed setting process group of " + app.pid 15497 + " to " + app.curSchedGroup); 15498 e.printStackTrace(); 15499 } finally { 15500 Binder.restoreCallingIdentity(oldId); 15501 } 15502 } else { 15503 if (app.thread != null) { 15504 try { 15505 app.thread.setSchedulingGroup(app.curSchedGroup); 15506 } catch (RemoteException e) { 15507 } 15508 } 15509 } 15510 Process.setSwappiness(app.pid, 15511 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15512 } 15513 } 15514 if (app.repProcState != app.curProcState) { 15515 app.repProcState = app.curProcState; 15516 if (!reportingProcessState && app.thread != null) { 15517 try { 15518 if (false) { 15519 //RuntimeException h = new RuntimeException("here"); 15520 Slog.i(TAG, "Sending new process state " + app.repProcState 15521 + " to " + app /*, h*/); 15522 } 15523 app.thread.setProcessState(app.repProcState); 15524 } catch (RemoteException e) { 15525 } 15526 } 15527 } 15528 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15529 app.setProcState)) { 15530 app.lastStateTime = now; 15531 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15532 mSleeping, now); 15533 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15534 + ProcessList.makeProcStateString(app.setProcState) + " to " 15535 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15536 + (app.nextPssTime-now) + ": " + app); 15537 } else { 15538 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15539 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15540 requestPssLocked(app, app.setProcState); 15541 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15542 mSleeping, now); 15543 } else if (false && DEBUG_PSS) { 15544 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15545 } 15546 } 15547 if (app.setProcState != app.curProcState) { 15548 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15549 "Proc state change of " + app.processName 15550 + " to " + app.curProcState); 15551 app.setProcState = app.curProcState; 15552 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15553 app.notCachedSinceIdle = false; 15554 } 15555 if (!doingAll) { 15556 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15557 } else { 15558 app.procStateChanged = true; 15559 } 15560 } 15561 return success; 15562 } 15563 15564 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15565 if (proc.thread != null && proc.baseProcessTracker != null) { 15566 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15567 } 15568 } 15569 15570 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15571 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15572 if (app.thread == null) { 15573 return false; 15574 } 15575 15576 final boolean wasKeeping = app.keeping; 15577 15578 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15579 15580 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15581 reportingProcessState, now); 15582 } 15583 15584 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15585 boolean oomAdj) { 15586 if (isForeground != proc.foregroundServices) { 15587 proc.foregroundServices = isForeground; 15588 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15589 proc.info.uid); 15590 if (isForeground) { 15591 if (curProcs == null) { 15592 curProcs = new ArrayList<ProcessRecord>(); 15593 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15594 } 15595 if (!curProcs.contains(proc)) { 15596 curProcs.add(proc); 15597 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15598 proc.info.packageName, proc.info.uid); 15599 } 15600 } else { 15601 if (curProcs != null) { 15602 if (curProcs.remove(proc)) { 15603 mBatteryStatsService.noteEvent( 15604 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15605 proc.info.packageName, proc.info.uid); 15606 if (curProcs.size() <= 0) { 15607 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15608 } 15609 } 15610 } 15611 } 15612 if (oomAdj) { 15613 updateOomAdjLocked(); 15614 } 15615 } 15616 } 15617 15618 private final ActivityRecord resumedAppLocked() { 15619 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15620 String pkg; 15621 int uid; 15622 if (act != null && !act.sleeping) { 15623 pkg = act.packageName; 15624 uid = act.info.applicationInfo.uid; 15625 } else { 15626 pkg = null; 15627 uid = -1; 15628 } 15629 // Has the UID or resumed package name changed? 15630 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15631 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15632 if (mCurResumedPackage != null) { 15633 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15634 mCurResumedPackage, mCurResumedUid); 15635 } 15636 mCurResumedPackage = pkg; 15637 mCurResumedUid = uid; 15638 if (mCurResumedPackage != null) { 15639 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15640 mCurResumedPackage, mCurResumedUid); 15641 } 15642 } 15643 return act; 15644 } 15645 15646 final boolean updateOomAdjLocked(ProcessRecord app) { 15647 return updateOomAdjLocked(app, false); 15648 } 15649 15650 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15651 final ActivityRecord TOP_ACT = resumedAppLocked(); 15652 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15653 final boolean wasCached = app.cached; 15654 15655 mAdjSeq++; 15656 15657 // This is the desired cached adjusment we want to tell it to use. 15658 // If our app is currently cached, we know it, and that is it. Otherwise, 15659 // we don't know it yet, and it needs to now be cached we will then 15660 // need to do a complete oom adj. 15661 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15662 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15663 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15664 SystemClock.uptimeMillis()); 15665 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15666 // Changed to/from cached state, so apps after it in the LRU 15667 // list may also be changed. 15668 updateOomAdjLocked(); 15669 } 15670 return success; 15671 } 15672 15673 final void updateOomAdjLocked() { 15674 final ActivityRecord TOP_ACT = resumedAppLocked(); 15675 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15676 final long now = SystemClock.uptimeMillis(); 15677 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15678 final int N = mLruProcesses.size(); 15679 15680 if (false) { 15681 RuntimeException e = new RuntimeException(); 15682 e.fillInStackTrace(); 15683 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15684 } 15685 15686 mAdjSeq++; 15687 mNewNumServiceProcs = 0; 15688 mNewNumAServiceProcs = 0; 15689 15690 final int emptyProcessLimit; 15691 final int cachedProcessLimit; 15692 if (mProcessLimit <= 0) { 15693 emptyProcessLimit = cachedProcessLimit = 0; 15694 } else if (mProcessLimit == 1) { 15695 emptyProcessLimit = 1; 15696 cachedProcessLimit = 0; 15697 } else { 15698 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15699 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15700 } 15701 15702 // Let's determine how many processes we have running vs. 15703 // how many slots we have for background processes; we may want 15704 // to put multiple processes in a slot of there are enough of 15705 // them. 15706 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15707 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15708 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15709 if (numEmptyProcs > cachedProcessLimit) { 15710 // If there are more empty processes than our limit on cached 15711 // processes, then use the cached process limit for the factor. 15712 // This ensures that the really old empty processes get pushed 15713 // down to the bottom, so if we are running low on memory we will 15714 // have a better chance at keeping around more cached processes 15715 // instead of a gazillion empty processes. 15716 numEmptyProcs = cachedProcessLimit; 15717 } 15718 int emptyFactor = numEmptyProcs/numSlots; 15719 if (emptyFactor < 1) emptyFactor = 1; 15720 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15721 if (cachedFactor < 1) cachedFactor = 1; 15722 int stepCached = 0; 15723 int stepEmpty = 0; 15724 int numCached = 0; 15725 int numEmpty = 0; 15726 int numTrimming = 0; 15727 15728 mNumNonCachedProcs = 0; 15729 mNumCachedHiddenProcs = 0; 15730 15731 // First update the OOM adjustment for each of the 15732 // application processes based on their current state. 15733 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15734 int nextCachedAdj = curCachedAdj+1; 15735 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15736 int nextEmptyAdj = curEmptyAdj+2; 15737 for (int i=N-1; i>=0; i--) { 15738 ProcessRecord app = mLruProcesses.get(i); 15739 if (!app.killedByAm && app.thread != null) { 15740 app.procStateChanged = false; 15741 final boolean wasKeeping = app.keeping; 15742 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15743 15744 // If we haven't yet assigned the final cached adj 15745 // to the process, do that now. 15746 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15747 switch (app.curProcState) { 15748 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15749 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15750 // This process is a cached process holding activities... 15751 // assign it the next cached value for that type, and then 15752 // step that cached level. 15753 app.curRawAdj = curCachedAdj; 15754 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15755 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15756 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15757 + ")"); 15758 if (curCachedAdj != nextCachedAdj) { 15759 stepCached++; 15760 if (stepCached >= cachedFactor) { 15761 stepCached = 0; 15762 curCachedAdj = nextCachedAdj; 15763 nextCachedAdj += 2; 15764 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15765 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15766 } 15767 } 15768 } 15769 break; 15770 default: 15771 // For everything else, assign next empty cached process 15772 // level and bump that up. Note that this means that 15773 // long-running services that have dropped down to the 15774 // cached level will be treated as empty (since their process 15775 // state is still as a service), which is what we want. 15776 app.curRawAdj = curEmptyAdj; 15777 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15778 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15779 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15780 + ")"); 15781 if (curEmptyAdj != nextEmptyAdj) { 15782 stepEmpty++; 15783 if (stepEmpty >= emptyFactor) { 15784 stepEmpty = 0; 15785 curEmptyAdj = nextEmptyAdj; 15786 nextEmptyAdj += 2; 15787 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15788 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15789 } 15790 } 15791 } 15792 break; 15793 } 15794 } 15795 15796 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15797 15798 // Count the number of process types. 15799 switch (app.curProcState) { 15800 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15801 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15802 mNumCachedHiddenProcs++; 15803 numCached++; 15804 if (numCached > cachedProcessLimit) { 15805 killUnneededProcessLocked(app, "cached #" + numCached); 15806 } 15807 break; 15808 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15809 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15810 && app.lastActivityTime < oldTime) { 15811 killUnneededProcessLocked(app, "empty for " 15812 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15813 / 1000) + "s"); 15814 } else { 15815 numEmpty++; 15816 if (numEmpty > emptyProcessLimit) { 15817 killUnneededProcessLocked(app, "empty #" + numEmpty); 15818 } 15819 } 15820 break; 15821 default: 15822 mNumNonCachedProcs++; 15823 break; 15824 } 15825 15826 if (app.isolated && app.services.size() <= 0) { 15827 // If this is an isolated process, and there are no 15828 // services running in it, then the process is no longer 15829 // needed. We agressively kill these because we can by 15830 // definition not re-use the same process again, and it is 15831 // good to avoid having whatever code was running in them 15832 // left sitting around after no longer needed. 15833 killUnneededProcessLocked(app, "isolated not needed"); 15834 } 15835 15836 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15837 && !app.killedByAm) { 15838 numTrimming++; 15839 } 15840 } 15841 } 15842 15843 mNumServiceProcs = mNewNumServiceProcs; 15844 15845 // Now determine the memory trimming level of background processes. 15846 // Unfortunately we need to start at the back of the list to do this 15847 // properly. We only do this if the number of background apps we 15848 // are managing to keep around is less than half the maximum we desire; 15849 // if we are keeping a good number around, we'll let them use whatever 15850 // memory they want. 15851 final int numCachedAndEmpty = numCached + numEmpty; 15852 int memFactor; 15853 if (numCached <= ProcessList.TRIM_CACHED_APPS 15854 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15855 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15856 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15857 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15858 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15859 } else { 15860 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15861 } 15862 } else { 15863 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15864 } 15865 // We always allow the memory level to go up (better). We only allow it to go 15866 // down if we are in a state where that is allowed, *and* the total number of processes 15867 // has gone down since last time. 15868 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15869 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15870 + " last=" + mLastNumProcesses); 15871 if (memFactor > mLastMemoryLevel) { 15872 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15873 memFactor = mLastMemoryLevel; 15874 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15875 } 15876 } 15877 mLastMemoryLevel = memFactor; 15878 mLastNumProcesses = mLruProcesses.size(); 15879 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15880 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15881 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15882 if (mLowRamStartTime == 0) { 15883 mLowRamStartTime = now; 15884 } 15885 int step = 0; 15886 int fgTrimLevel; 15887 switch (memFactor) { 15888 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15889 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15890 break; 15891 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15892 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15893 break; 15894 default: 15895 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15896 break; 15897 } 15898 int factor = numTrimming/3; 15899 int minFactor = 2; 15900 if (mHomeProcess != null) minFactor++; 15901 if (mPreviousProcess != null) minFactor++; 15902 if (factor < minFactor) factor = minFactor; 15903 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15904 for (int i=N-1; i>=0; i--) { 15905 ProcessRecord app = mLruProcesses.get(i); 15906 if (allChanged || app.procStateChanged) { 15907 setProcessTrackerState(app, trackerMemFactor, now); 15908 app.procStateChanged = false; 15909 } 15910 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15911 && !app.killedByAm) { 15912 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15913 try { 15914 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15915 "Trimming memory of " + app.processName 15916 + " to " + curLevel); 15917 app.thread.scheduleTrimMemory(curLevel); 15918 } catch (RemoteException e) { 15919 } 15920 if (false) { 15921 // For now we won't do this; our memory trimming seems 15922 // to be good enough at this point that destroying 15923 // activities causes more harm than good. 15924 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15925 && app != mHomeProcess && app != mPreviousProcess) { 15926 // Need to do this on its own message because the stack may not 15927 // be in a consistent state at this point. 15928 // For these apps we will also finish their activities 15929 // to help them free memory. 15930 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15931 } 15932 } 15933 } 15934 app.trimMemoryLevel = curLevel; 15935 step++; 15936 if (step >= factor) { 15937 step = 0; 15938 switch (curLevel) { 15939 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15940 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15941 break; 15942 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15943 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15944 break; 15945 } 15946 } 15947 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15948 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15949 && app.thread != null) { 15950 try { 15951 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15952 "Trimming memory of heavy-weight " + app.processName 15953 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15954 app.thread.scheduleTrimMemory( 15955 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15956 } catch (RemoteException e) { 15957 } 15958 } 15959 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15960 } else { 15961 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15962 || app.systemNoUi) && app.pendingUiClean) { 15963 // If this application is now in the background and it 15964 // had done UI, then give it the special trim level to 15965 // have it free UI resources. 15966 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15967 if (app.trimMemoryLevel < level && app.thread != null) { 15968 try { 15969 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15970 "Trimming memory of bg-ui " + app.processName 15971 + " to " + level); 15972 app.thread.scheduleTrimMemory(level); 15973 } catch (RemoteException e) { 15974 } 15975 } 15976 app.pendingUiClean = false; 15977 } 15978 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15979 try { 15980 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15981 "Trimming memory of fg " + app.processName 15982 + " to " + fgTrimLevel); 15983 app.thread.scheduleTrimMemory(fgTrimLevel); 15984 } catch (RemoteException e) { 15985 } 15986 } 15987 app.trimMemoryLevel = fgTrimLevel; 15988 } 15989 } 15990 } else { 15991 if (mLowRamStartTime != 0) { 15992 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15993 mLowRamStartTime = 0; 15994 } 15995 for (int i=N-1; i>=0; i--) { 15996 ProcessRecord app = mLruProcesses.get(i); 15997 if (allChanged || app.procStateChanged) { 15998 setProcessTrackerState(app, trackerMemFactor, now); 15999 app.procStateChanged = false; 16000 } 16001 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16002 || app.systemNoUi) && app.pendingUiClean) { 16003 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16004 && app.thread != null) { 16005 try { 16006 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16007 "Trimming memory of ui hidden " + app.processName 16008 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16009 app.thread.scheduleTrimMemory( 16010 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16011 } catch (RemoteException e) { 16012 } 16013 } 16014 app.pendingUiClean = false; 16015 } 16016 app.trimMemoryLevel = 0; 16017 } 16018 } 16019 16020 if (mAlwaysFinishActivities) { 16021 // Need to do this on its own message because the stack may not 16022 // be in a consistent state at this point. 16023 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16024 } 16025 16026 if (allChanged) { 16027 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16028 } 16029 16030 if (mProcessStats.shouldWriteNowLocked(now)) { 16031 mHandler.post(new Runnable() { 16032 @Override public void run() { 16033 synchronized (ActivityManagerService.this) { 16034 mProcessStats.writeStateAsyncLocked(); 16035 } 16036 } 16037 }); 16038 } 16039 16040 if (DEBUG_OOM_ADJ) { 16041 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16042 } 16043 } 16044 16045 final void trimApplications() { 16046 synchronized (this) { 16047 int i; 16048 16049 // First remove any unused application processes whose package 16050 // has been removed. 16051 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16052 final ProcessRecord app = mRemovedProcesses.get(i); 16053 if (app.activities.size() == 0 16054 && app.curReceiver == null && app.services.size() == 0) { 16055 Slog.i( 16056 TAG, "Exiting empty application process " 16057 + app.processName + " (" 16058 + (app.thread != null ? app.thread.asBinder() : null) 16059 + ")\n"); 16060 if (app.pid > 0 && app.pid != MY_PID) { 16061 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16062 app.processName, app.setAdj, "empty"); 16063 app.killedByAm = true; 16064 Process.killProcessQuiet(app.pid); 16065 } else { 16066 try { 16067 app.thread.scheduleExit(); 16068 } catch (Exception e) { 16069 // Ignore exceptions. 16070 } 16071 } 16072 cleanUpApplicationRecordLocked(app, false, true, -1); 16073 mRemovedProcesses.remove(i); 16074 16075 if (app.persistent) { 16076 if (app.persistent) { 16077 addAppLocked(app.info, false); 16078 } 16079 } 16080 } 16081 } 16082 16083 // Now update the oom adj for all processes. 16084 updateOomAdjLocked(); 16085 } 16086 } 16087 16088 /** This method sends the specified signal to each of the persistent apps */ 16089 public void signalPersistentProcesses(int sig) throws RemoteException { 16090 if (sig != Process.SIGNAL_USR1) { 16091 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16092 } 16093 16094 synchronized (this) { 16095 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16096 != PackageManager.PERMISSION_GRANTED) { 16097 throw new SecurityException("Requires permission " 16098 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16099 } 16100 16101 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16102 ProcessRecord r = mLruProcesses.get(i); 16103 if (r.thread != null && r.persistent) { 16104 Process.sendSignal(r.pid, sig); 16105 } 16106 } 16107 } 16108 } 16109 16110 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16111 if (proc == null || proc == mProfileProc) { 16112 proc = mProfileProc; 16113 path = mProfileFile; 16114 profileType = mProfileType; 16115 clearProfilerLocked(); 16116 } 16117 if (proc == null) { 16118 return; 16119 } 16120 try { 16121 proc.thread.profilerControl(false, path, null, profileType); 16122 } catch (RemoteException e) { 16123 throw new IllegalStateException("Process disappeared"); 16124 } 16125 } 16126 16127 private void clearProfilerLocked() { 16128 if (mProfileFd != null) { 16129 try { 16130 mProfileFd.close(); 16131 } catch (IOException e) { 16132 } 16133 } 16134 mProfileApp = null; 16135 mProfileProc = null; 16136 mProfileFile = null; 16137 mProfileType = 0; 16138 mAutoStopProfiler = false; 16139 } 16140 16141 public boolean profileControl(String process, int userId, boolean start, 16142 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16143 16144 try { 16145 synchronized (this) { 16146 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16147 // its own permission. 16148 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16149 != PackageManager.PERMISSION_GRANTED) { 16150 throw new SecurityException("Requires permission " 16151 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16152 } 16153 16154 if (start && fd == null) { 16155 throw new IllegalArgumentException("null fd"); 16156 } 16157 16158 ProcessRecord proc = null; 16159 if (process != null) { 16160 proc = findProcessLocked(process, userId, "profileControl"); 16161 } 16162 16163 if (start && (proc == null || proc.thread == null)) { 16164 throw new IllegalArgumentException("Unknown process: " + process); 16165 } 16166 16167 if (start) { 16168 stopProfilerLocked(null, null, 0); 16169 setProfileApp(proc.info, proc.processName, path, fd, false); 16170 mProfileProc = proc; 16171 mProfileType = profileType; 16172 try { 16173 fd = fd.dup(); 16174 } catch (IOException e) { 16175 fd = null; 16176 } 16177 proc.thread.profilerControl(start, path, fd, profileType); 16178 fd = null; 16179 mProfileFd = null; 16180 } else { 16181 stopProfilerLocked(proc, path, profileType); 16182 if (fd != null) { 16183 try { 16184 fd.close(); 16185 } catch (IOException e) { 16186 } 16187 } 16188 } 16189 16190 return true; 16191 } 16192 } catch (RemoteException e) { 16193 throw new IllegalStateException("Process disappeared"); 16194 } finally { 16195 if (fd != null) { 16196 try { 16197 fd.close(); 16198 } catch (IOException e) { 16199 } 16200 } 16201 } 16202 } 16203 16204 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16205 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16206 userId, true, true, callName, null); 16207 ProcessRecord proc = null; 16208 try { 16209 int pid = Integer.parseInt(process); 16210 synchronized (mPidsSelfLocked) { 16211 proc = mPidsSelfLocked.get(pid); 16212 } 16213 } catch (NumberFormatException e) { 16214 } 16215 16216 if (proc == null) { 16217 ArrayMap<String, SparseArray<ProcessRecord>> all 16218 = mProcessNames.getMap(); 16219 SparseArray<ProcessRecord> procs = all.get(process); 16220 if (procs != null && procs.size() > 0) { 16221 proc = procs.valueAt(0); 16222 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16223 for (int i=1; i<procs.size(); i++) { 16224 ProcessRecord thisProc = procs.valueAt(i); 16225 if (thisProc.userId == userId) { 16226 proc = thisProc; 16227 break; 16228 } 16229 } 16230 } 16231 } 16232 } 16233 16234 return proc; 16235 } 16236 16237 public boolean dumpHeap(String process, int userId, boolean managed, 16238 String path, ParcelFileDescriptor fd) throws RemoteException { 16239 16240 try { 16241 synchronized (this) { 16242 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16243 // its own permission (same as profileControl). 16244 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16245 != PackageManager.PERMISSION_GRANTED) { 16246 throw new SecurityException("Requires permission " 16247 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16248 } 16249 16250 if (fd == null) { 16251 throw new IllegalArgumentException("null fd"); 16252 } 16253 16254 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16255 if (proc == null || proc.thread == null) { 16256 throw new IllegalArgumentException("Unknown process: " + process); 16257 } 16258 16259 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16260 if (!isDebuggable) { 16261 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16262 throw new SecurityException("Process not debuggable: " + proc); 16263 } 16264 } 16265 16266 proc.thread.dumpHeap(managed, path, fd); 16267 fd = null; 16268 return true; 16269 } 16270 } catch (RemoteException e) { 16271 throw new IllegalStateException("Process disappeared"); 16272 } finally { 16273 if (fd != null) { 16274 try { 16275 fd.close(); 16276 } catch (IOException e) { 16277 } 16278 } 16279 } 16280 } 16281 16282 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16283 public void monitor() { 16284 synchronized (this) { } 16285 } 16286 16287 void onCoreSettingsChange(Bundle settings) { 16288 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16289 ProcessRecord processRecord = mLruProcesses.get(i); 16290 try { 16291 if (processRecord.thread != null) { 16292 processRecord.thread.setCoreSettings(settings); 16293 } 16294 } catch (RemoteException re) { 16295 /* ignore */ 16296 } 16297 } 16298 } 16299 16300 // Multi-user methods 16301 16302 /** 16303 * Start user, if its not already running, but don't bring it to foreground. 16304 */ 16305 @Override 16306 public boolean startUserInBackground(final int userId) { 16307 return startUser(userId, /* foreground */ false); 16308 } 16309 16310 /** 16311 * Refreshes the list of users related to the current user when either a 16312 * user switch happens or when a new related user is started in the 16313 * background. 16314 */ 16315 private void updateRelatedUserIdsLocked() { 16316 final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16317 int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null 16318 for (int i = 0; i < relatedUserIds.length; i++) { 16319 relatedUserIds[i] = relatedUsers.get(i).id; 16320 } 16321 mRelatedUserIds = relatedUserIds; 16322 } 16323 16324 private Set getRelatedUsersLocked(int userId) { 16325 Set userIds = new HashSet<Integer>(); 16326 final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(userId); 16327 for (UserInfo user : relatedUsers) { 16328 userIds.add(Integer.valueOf(user.id)); 16329 } 16330 return userIds; 16331 } 16332 16333 @Override 16334 public boolean switchUser(final int userId) { 16335 return startUser(userId, /* foregound */ true); 16336 } 16337 16338 private boolean startUser(final int userId, boolean foreground) { 16339 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16340 != PackageManager.PERMISSION_GRANTED) { 16341 String msg = "Permission Denial: switchUser() from pid=" 16342 + Binder.getCallingPid() 16343 + ", uid=" + Binder.getCallingUid() 16344 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16345 Slog.w(TAG, msg); 16346 throw new SecurityException(msg); 16347 } 16348 16349 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16350 16351 final long ident = Binder.clearCallingIdentity(); 16352 try { 16353 synchronized (this) { 16354 final int oldUserId = mCurrentUserId; 16355 if (oldUserId == userId) { 16356 return true; 16357 } 16358 16359 mStackSupervisor.setLockTaskModeLocked(null); 16360 16361 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16362 if (userInfo == null) { 16363 Slog.w(TAG, "No user info for user #" + userId); 16364 return false; 16365 } 16366 16367 if (foreground) { 16368 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16369 R.anim.screen_user_enter); 16370 } 16371 16372 boolean needStart = false; 16373 16374 // If the user we are switching to is not currently started, then 16375 // we need to start it now. 16376 if (mStartedUsers.get(userId) == null) { 16377 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16378 updateStartedUserArrayLocked(); 16379 needStart = true; 16380 } 16381 16382 final Integer userIdInt = Integer.valueOf(userId); 16383 mUserLru.remove(userIdInt); 16384 mUserLru.add(userIdInt); 16385 16386 if (foreground) { 16387 mCurrentUserId = userId; 16388 updateRelatedUserIdsLocked(); 16389 mWindowManager.setCurrentUser(userId, mRelatedUserIds); 16390 // Once the internal notion of the active user has switched, we lock the device 16391 // with the option to show the user switcher on the keyguard. 16392 mWindowManager.lockNow(null); 16393 } else { 16394 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16395 updateRelatedUserIdsLocked(); 16396 mWindowManager.updateRelatedUserIds(mRelatedUserIds); 16397 mUserLru.remove(currentUserIdInt); 16398 mUserLru.add(currentUserIdInt); 16399 } 16400 16401 final UserStartedState uss = mStartedUsers.get(userId); 16402 16403 // Make sure user is in the started state. If it is currently 16404 // stopping, we need to knock that off. 16405 if (uss.mState == UserStartedState.STATE_STOPPING) { 16406 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16407 // so we can just fairly silently bring the user back from 16408 // the almost-dead. 16409 uss.mState = UserStartedState.STATE_RUNNING; 16410 updateStartedUserArrayLocked(); 16411 needStart = true; 16412 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16413 // This means ACTION_SHUTDOWN has been sent, so we will 16414 // need to treat this as a new boot of the user. 16415 uss.mState = UserStartedState.STATE_BOOTING; 16416 updateStartedUserArrayLocked(); 16417 needStart = true; 16418 } 16419 16420 if (foreground) { 16421 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16422 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16423 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16424 oldUserId, userId, uss)); 16425 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16426 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16427 } 16428 16429 if (needStart) { 16430 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16431 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16432 | Intent.FLAG_RECEIVER_FOREGROUND); 16433 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16434 broadcastIntentLocked(null, null, intent, 16435 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16436 false, false, MY_PID, Process.SYSTEM_UID, userId); 16437 } 16438 16439 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16440 if (userId != 0) { 16441 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16442 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16443 broadcastIntentLocked(null, null, intent, null, 16444 new IIntentReceiver.Stub() { 16445 public void performReceive(Intent intent, int resultCode, 16446 String data, Bundle extras, boolean ordered, 16447 boolean sticky, int sendingUser) { 16448 userInitialized(uss, userId); 16449 } 16450 }, 0, null, null, null, AppOpsManager.OP_NONE, 16451 true, false, MY_PID, Process.SYSTEM_UID, 16452 userId); 16453 uss.initializing = true; 16454 } else { 16455 getUserManagerLocked().makeInitialized(userInfo.id); 16456 } 16457 } 16458 16459 if (foreground) { 16460 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16461 if (homeInFront) { 16462 startHomeActivityLocked(userId); 16463 } else { 16464 mStackSupervisor.resumeTopActivitiesLocked(); 16465 } 16466 EventLogTags.writeAmSwitchUser(userId); 16467 getUserManagerLocked().userForeground(userId); 16468 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16469 } 16470 16471 if (needStart) { 16472 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16473 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16474 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16475 broadcastIntentLocked(null, null, intent, 16476 null, new IIntentReceiver.Stub() { 16477 @Override 16478 public void performReceive(Intent intent, int resultCode, String data, 16479 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16480 throws RemoteException { 16481 } 16482 }, 0, null, null, 16483 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16484 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16485 } 16486 } 16487 } finally { 16488 Binder.restoreCallingIdentity(ident); 16489 } 16490 16491 return true; 16492 } 16493 16494 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16495 long ident = Binder.clearCallingIdentity(); 16496 try { 16497 Intent intent; 16498 if (oldUserId >= 0) { 16499 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16500 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16501 | Intent.FLAG_RECEIVER_FOREGROUND); 16502 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16503 broadcastIntentLocked(null, null, intent, 16504 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16505 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16506 } 16507 if (newUserId >= 0) { 16508 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16509 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16510 | Intent.FLAG_RECEIVER_FOREGROUND); 16511 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16512 broadcastIntentLocked(null, null, intent, 16513 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16514 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16515 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16516 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16517 | Intent.FLAG_RECEIVER_FOREGROUND); 16518 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16519 broadcastIntentLocked(null, null, intent, 16520 null, null, 0, null, null, 16521 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16522 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16523 } 16524 } finally { 16525 Binder.restoreCallingIdentity(ident); 16526 } 16527 } 16528 16529 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16530 final int newUserId) { 16531 final int N = mUserSwitchObservers.beginBroadcast(); 16532 if (N > 0) { 16533 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16534 int mCount = 0; 16535 @Override 16536 public void sendResult(Bundle data) throws RemoteException { 16537 synchronized (ActivityManagerService.this) { 16538 if (mCurUserSwitchCallback == this) { 16539 mCount++; 16540 if (mCount == N) { 16541 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16542 } 16543 } 16544 } 16545 } 16546 }; 16547 synchronized (this) { 16548 uss.switching = true; 16549 mCurUserSwitchCallback = callback; 16550 } 16551 for (int i=0; i<N; i++) { 16552 try { 16553 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16554 newUserId, callback); 16555 } catch (RemoteException e) { 16556 } 16557 } 16558 } else { 16559 synchronized (this) { 16560 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16561 } 16562 } 16563 mUserSwitchObservers.finishBroadcast(); 16564 } 16565 16566 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16567 synchronized (this) { 16568 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16569 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16570 } 16571 } 16572 16573 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16574 mCurUserSwitchCallback = null; 16575 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16576 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16577 oldUserId, newUserId, uss)); 16578 } 16579 16580 void userInitialized(UserStartedState uss, int newUserId) { 16581 completeSwitchAndInitalize(uss, newUserId, true, false); 16582 } 16583 16584 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16585 completeSwitchAndInitalize(uss, newUserId, false, true); 16586 } 16587 16588 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16589 boolean clearInitializing, boolean clearSwitching) { 16590 boolean unfrozen = false; 16591 synchronized (this) { 16592 if (clearInitializing) { 16593 uss.initializing = false; 16594 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16595 } 16596 if (clearSwitching) { 16597 uss.switching = false; 16598 } 16599 if (!uss.switching && !uss.initializing) { 16600 mWindowManager.stopFreezingScreen(); 16601 unfrozen = true; 16602 } 16603 } 16604 if (unfrozen) { 16605 final int N = mUserSwitchObservers.beginBroadcast(); 16606 for (int i=0; i<N; i++) { 16607 try { 16608 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16609 } catch (RemoteException e) { 16610 } 16611 } 16612 mUserSwitchObservers.finishBroadcast(); 16613 } 16614 } 16615 16616 void scheduleStartRelatedUsersLocked() { 16617 if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) { 16618 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG), 16619 DateUtils.SECOND_IN_MILLIS); 16620 } 16621 } 16622 16623 void startRelatedUsersLocked() { 16624 if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked"); 16625 List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16626 List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size()); 16627 for (UserInfo relatedUser : relatedUsers) { 16628 if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) { 16629 toStart.add(relatedUser); 16630 } 16631 } 16632 final int n = toStart.size(); 16633 int i = 0; 16634 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16635 startUserInBackground(toStart.get(i).id); 16636 } 16637 if (i < n) { 16638 Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS"); 16639 } 16640 } 16641 16642 void finishUserSwitch(UserStartedState uss) { 16643 synchronized (this) { 16644 if (uss.mState == UserStartedState.STATE_BOOTING 16645 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16646 uss.mState = UserStartedState.STATE_RUNNING; 16647 final int userId = uss.mHandle.getIdentifier(); 16648 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16649 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16650 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16651 broadcastIntentLocked(null, null, intent, 16652 null, null, 0, null, null, 16653 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16654 true, false, MY_PID, Process.SYSTEM_UID, userId); 16655 } 16656 16657 startRelatedUsersLocked(); 16658 16659 int num = mUserLru.size(); 16660 int i = 0; 16661 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16662 Integer oldUserId = mUserLru.get(i); 16663 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16664 if (oldUss == null) { 16665 // Shouldn't happen, but be sane if it does. 16666 mUserLru.remove(i); 16667 num--; 16668 continue; 16669 } 16670 if (oldUss.mState == UserStartedState.STATE_STOPPING 16671 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16672 // This user is already stopping, doesn't count. 16673 num--; 16674 i++; 16675 continue; 16676 } 16677 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16678 // Owner and current can't be stopped, but count as running. 16679 i++; 16680 continue; 16681 } 16682 // This is a user to be stopped. 16683 stopUserLocked(oldUserId, null); 16684 num--; 16685 i++; 16686 } 16687 } 16688 } 16689 16690 @Override 16691 public int stopUser(final int userId, final IStopUserCallback callback) { 16692 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16693 != PackageManager.PERMISSION_GRANTED) { 16694 String msg = "Permission Denial: switchUser() from pid=" 16695 + Binder.getCallingPid() 16696 + ", uid=" + Binder.getCallingUid() 16697 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16698 Slog.w(TAG, msg); 16699 throw new SecurityException(msg); 16700 } 16701 if (userId <= 0) { 16702 throw new IllegalArgumentException("Can't stop primary user " + userId); 16703 } 16704 synchronized (this) { 16705 return stopUserLocked(userId, callback); 16706 } 16707 } 16708 16709 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16710 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16711 if (mCurrentUserId == userId) { 16712 return ActivityManager.USER_OP_IS_CURRENT; 16713 } 16714 16715 final UserStartedState uss = mStartedUsers.get(userId); 16716 if (uss == null) { 16717 // User is not started, nothing to do... but we do need to 16718 // callback if requested. 16719 if (callback != null) { 16720 mHandler.post(new Runnable() { 16721 @Override 16722 public void run() { 16723 try { 16724 callback.userStopped(userId); 16725 } catch (RemoteException e) { 16726 } 16727 } 16728 }); 16729 } 16730 return ActivityManager.USER_OP_SUCCESS; 16731 } 16732 16733 if (callback != null) { 16734 uss.mStopCallbacks.add(callback); 16735 } 16736 16737 if (uss.mState != UserStartedState.STATE_STOPPING 16738 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16739 uss.mState = UserStartedState.STATE_STOPPING; 16740 updateStartedUserArrayLocked(); 16741 16742 long ident = Binder.clearCallingIdentity(); 16743 try { 16744 // We are going to broadcast ACTION_USER_STOPPING and then 16745 // once that is done send a final ACTION_SHUTDOWN and then 16746 // stop the user. 16747 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16748 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16749 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16750 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16751 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16752 // This is the result receiver for the final shutdown broadcast. 16753 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16754 @Override 16755 public void performReceive(Intent intent, int resultCode, String data, 16756 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16757 finishUserStop(uss); 16758 } 16759 }; 16760 // This is the result receiver for the initial stopping broadcast. 16761 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16762 @Override 16763 public void performReceive(Intent intent, int resultCode, String data, 16764 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16765 // On to the next. 16766 synchronized (ActivityManagerService.this) { 16767 if (uss.mState != UserStartedState.STATE_STOPPING) { 16768 // Whoops, we are being started back up. Abort, abort! 16769 return; 16770 } 16771 uss.mState = UserStartedState.STATE_SHUTDOWN; 16772 } 16773 broadcastIntentLocked(null, null, shutdownIntent, 16774 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16775 true, false, MY_PID, Process.SYSTEM_UID, userId); 16776 } 16777 }; 16778 // Kick things off. 16779 broadcastIntentLocked(null, null, stoppingIntent, 16780 null, stoppingReceiver, 0, null, null, 16781 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16782 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16783 } finally { 16784 Binder.restoreCallingIdentity(ident); 16785 } 16786 } 16787 16788 return ActivityManager.USER_OP_SUCCESS; 16789 } 16790 16791 void finishUserStop(UserStartedState uss) { 16792 final int userId = uss.mHandle.getIdentifier(); 16793 boolean stopped; 16794 ArrayList<IStopUserCallback> callbacks; 16795 synchronized (this) { 16796 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16797 if (mStartedUsers.get(userId) != uss) { 16798 stopped = false; 16799 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16800 stopped = false; 16801 } else { 16802 stopped = true; 16803 // User can no longer run. 16804 mStartedUsers.remove(userId); 16805 mUserLru.remove(Integer.valueOf(userId)); 16806 updateStartedUserArrayLocked(); 16807 16808 // Clean up all state and processes associated with the user. 16809 // Kill all the processes for the user. 16810 forceStopUserLocked(userId, "finish user"); 16811 } 16812 } 16813 16814 for (int i=0; i<callbacks.size(); i++) { 16815 try { 16816 if (stopped) callbacks.get(i).userStopped(userId); 16817 else callbacks.get(i).userStopAborted(userId); 16818 } catch (RemoteException e) { 16819 } 16820 } 16821 16822 mStackSupervisor.removeUserLocked(userId); 16823 } 16824 16825 @Override 16826 public UserInfo getCurrentUser() { 16827 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16828 != PackageManager.PERMISSION_GRANTED) && ( 16829 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16830 != PackageManager.PERMISSION_GRANTED)) { 16831 String msg = "Permission Denial: getCurrentUser() from pid=" 16832 + Binder.getCallingPid() 16833 + ", uid=" + Binder.getCallingUid() 16834 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16835 Slog.w(TAG, msg); 16836 throw new SecurityException(msg); 16837 } 16838 synchronized (this) { 16839 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16840 } 16841 } 16842 16843 int getCurrentUserIdLocked() { 16844 return mCurrentUserId; 16845 } 16846 16847 @Override 16848 public boolean isUserRunning(int userId, boolean orStopped) { 16849 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16850 != PackageManager.PERMISSION_GRANTED) { 16851 String msg = "Permission Denial: isUserRunning() from pid=" 16852 + Binder.getCallingPid() 16853 + ", uid=" + Binder.getCallingUid() 16854 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16855 Slog.w(TAG, msg); 16856 throw new SecurityException(msg); 16857 } 16858 synchronized (this) { 16859 return isUserRunningLocked(userId, orStopped); 16860 } 16861 } 16862 16863 boolean isUserRunningLocked(int userId, boolean orStopped) { 16864 UserStartedState state = mStartedUsers.get(userId); 16865 if (state == null) { 16866 return false; 16867 } 16868 if (orStopped) { 16869 return true; 16870 } 16871 return state.mState != UserStartedState.STATE_STOPPING 16872 && state.mState != UserStartedState.STATE_SHUTDOWN; 16873 } 16874 16875 @Override 16876 public int[] getRunningUserIds() { 16877 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16878 != PackageManager.PERMISSION_GRANTED) { 16879 String msg = "Permission Denial: isUserRunning() from pid=" 16880 + Binder.getCallingPid() 16881 + ", uid=" + Binder.getCallingUid() 16882 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16883 Slog.w(TAG, msg); 16884 throw new SecurityException(msg); 16885 } 16886 synchronized (this) { 16887 return mStartedUserArray; 16888 } 16889 } 16890 16891 private void updateStartedUserArrayLocked() { 16892 int num = 0; 16893 for (int i=0; i<mStartedUsers.size(); i++) { 16894 UserStartedState uss = mStartedUsers.valueAt(i); 16895 // This list does not include stopping users. 16896 if (uss.mState != UserStartedState.STATE_STOPPING 16897 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16898 num++; 16899 } 16900 } 16901 mStartedUserArray = new int[num]; 16902 num = 0; 16903 for (int i=0; i<mStartedUsers.size(); i++) { 16904 UserStartedState uss = mStartedUsers.valueAt(i); 16905 if (uss.mState != UserStartedState.STATE_STOPPING 16906 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16907 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16908 num++; 16909 } 16910 } 16911 } 16912 16913 @Override 16914 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16915 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16916 != PackageManager.PERMISSION_GRANTED) { 16917 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16918 + Binder.getCallingPid() 16919 + ", uid=" + Binder.getCallingUid() 16920 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16921 Slog.w(TAG, msg); 16922 throw new SecurityException(msg); 16923 } 16924 16925 mUserSwitchObservers.register(observer); 16926 } 16927 16928 @Override 16929 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16930 mUserSwitchObservers.unregister(observer); 16931 } 16932 16933 private boolean userExists(int userId) { 16934 if (userId == 0) { 16935 return true; 16936 } 16937 UserManagerService ums = getUserManagerLocked(); 16938 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16939 } 16940 16941 int[] getUsersLocked() { 16942 UserManagerService ums = getUserManagerLocked(); 16943 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16944 } 16945 16946 UserManagerService getUserManagerLocked() { 16947 if (mUserManager == null) { 16948 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16949 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16950 } 16951 return mUserManager; 16952 } 16953 16954 private int applyUserId(int uid, int userId) { 16955 return UserHandle.getUid(userId, uid); 16956 } 16957 16958 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16959 if (info == null) return null; 16960 ApplicationInfo newInfo = new ApplicationInfo(info); 16961 newInfo.uid = applyUserId(info.uid, userId); 16962 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16963 + info.packageName; 16964 return newInfo; 16965 } 16966 16967 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16968 if (aInfo == null 16969 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16970 return aInfo; 16971 } 16972 16973 ActivityInfo info = new ActivityInfo(aInfo); 16974 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16975 return info; 16976 } 16977} 16978