ActivityManagerService.java revision 3b3f464445d1d369c8e87f526deba606ca62f76c
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; 27import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 28 29import android.app.AppOpsManager; 30import android.app.IActivityContainer; 31import android.app.IActivityContainerCallback; 32import android.appwidget.AppWidgetManager; 33import android.graphics.Rect; 34import android.os.BatteryStats; 35import android.util.ArrayMap; 36 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.os.Zygote; 47import com.android.internal.util.FastPrintWriter; 48import com.android.internal.util.FastXmlSerializer; 49import com.android.internal.util.MemInfoReader; 50import com.android.internal.util.Preconditions; 51import com.android.server.AppOpsService; 52import com.android.server.AttributeCache; 53import com.android.server.IntentResolver; 54import com.android.server.LocalServices; 55import com.android.server.ServiceThread; 56import com.android.server.SystemService; 57import com.android.server.Watchdog; 58import com.android.server.am.ActivityStack.ActivityState; 59import com.android.server.firewall.IntentFirewall; 60import com.android.server.pm.UserManagerService; 61import com.android.server.wm.AppTransition; 62import com.android.server.wm.WindowManagerService; 63import com.google.android.collect.Lists; 64import com.google.android.collect.Maps; 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.ActivityManagerInternal; 77import android.app.ActivityManagerNative; 78import android.app.ActivityOptions; 79import android.app.ActivityThread; 80import android.app.AlertDialog; 81import android.app.AppGlobals; 82import android.app.ApplicationErrorReport; 83import android.app.Dialog; 84import android.app.IActivityController; 85import android.app.IApplicationThread; 86import android.app.IInstrumentationWatcher; 87import android.app.INotificationManager; 88import android.app.IProcessObserver; 89import android.app.IServiceConnection; 90import android.app.IStopUserCallback; 91import android.app.IThumbnailReceiver; 92import android.app.IUiAutomationConnection; 93import android.app.IUserSwitchObserver; 94import android.app.Instrumentation; 95import android.app.Notification; 96import android.app.NotificationManager; 97import android.app.PendingIntent; 98import android.app.backup.IBackupManager; 99import android.content.ActivityNotFoundException; 100import android.content.BroadcastReceiver; 101import android.content.ClipData; 102import android.content.ComponentCallbacks2; 103import android.content.ComponentName; 104import android.content.ContentProvider; 105import android.content.ContentResolver; 106import android.content.Context; 107import android.content.DialogInterface; 108import android.content.IContentProvider; 109import android.content.IIntentReceiver; 110import android.content.IIntentSender; 111import android.content.Intent; 112import android.content.IntentFilter; 113import android.content.IntentSender; 114import android.content.pm.ActivityInfo; 115import android.content.pm.ApplicationInfo; 116import android.content.pm.ConfigurationInfo; 117import android.content.pm.IPackageDataObserver; 118import android.content.pm.IPackageManager; 119import android.content.pm.InstrumentationInfo; 120import android.content.pm.PackageInfo; 121import android.content.pm.PackageManager; 122import android.content.pm.ParceledListSlice; 123import android.content.pm.UserInfo; 124import android.content.pm.PackageManager.NameNotFoundException; 125import android.content.pm.PathPermission; 126import android.content.pm.ProviderInfo; 127import android.content.pm.ResolveInfo; 128import android.content.pm.ServiceInfo; 129import android.content.res.CompatibilityInfo; 130import android.content.res.Configuration; 131import android.graphics.Bitmap; 132import android.net.Proxy; 133import android.net.ProxyProperties; 134import android.net.Uri; 135import android.os.Binder; 136import android.os.Build; 137import android.os.Bundle; 138import android.os.Debug; 139import android.os.DropBoxManager; 140import android.os.Environment; 141import android.os.FactoryTest; 142import android.os.FileObserver; 143import android.os.FileUtils; 144import android.os.Handler; 145import android.os.IBinder; 146import android.os.IPermissionController; 147import android.os.IRemoteCallback; 148import android.os.IUserManager; 149import android.os.Looper; 150import android.os.Message; 151import android.os.Parcel; 152import android.os.ParcelFileDescriptor; 153import android.os.Process; 154import android.os.RemoteCallbackList; 155import android.os.RemoteException; 156import android.os.SELinux; 157import android.os.ServiceManager; 158import android.os.StrictMode; 159import android.os.SystemClock; 160import android.os.SystemProperties; 161import android.os.UpdateLock; 162import android.os.UserHandle; 163import android.provider.Settings; 164import android.text.format.DateUtils; 165import android.text.format.Time; 166import android.util.AtomicFile; 167import android.util.EventLog; 168import android.util.Log; 169import android.util.Pair; 170import android.util.PrintWriterPrinter; 171import android.util.Slog; 172import android.util.SparseArray; 173import android.util.TimeUtils; 174import android.util.Xml; 175import android.view.Gravity; 176import android.view.LayoutInflater; 177import android.view.View; 178import android.view.WindowManager; 179 180import java.io.BufferedInputStream; 181import java.io.BufferedOutputStream; 182import java.io.DataInputStream; 183import java.io.DataOutputStream; 184import java.io.File; 185import java.io.FileDescriptor; 186import java.io.FileInputStream; 187import java.io.FileNotFoundException; 188import java.io.FileOutputStream; 189import java.io.IOException; 190import java.io.InputStreamReader; 191import java.io.PrintWriter; 192import java.io.StringWriter; 193import java.lang.ref.WeakReference; 194import java.util.ArrayList; 195import java.util.Arrays; 196import java.util.Collections; 197import java.util.Comparator; 198import java.util.HashMap; 199import java.util.HashSet; 200import java.util.Iterator; 201import java.util.List; 202import java.util.Locale; 203import java.util.Map; 204import java.util.Set; 205import java.util.concurrent.atomic.AtomicBoolean; 206import java.util.concurrent.atomic.AtomicLong; 207 208public final class ActivityManagerService extends ActivityManagerNative 209 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 210 private static final String USER_DATA_DIR = "/data/user/"; 211 static final String TAG = "ActivityManager"; 212 static final String TAG_MU = "ActivityManagerServiceMU"; 213 static final boolean DEBUG = false; 214 static final boolean localLOGV = DEBUG; 215 static final boolean DEBUG_BACKUP = localLOGV || false; 216 static final boolean DEBUG_BROADCAST = localLOGV || false; 217 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 219 static final boolean DEBUG_CLEANUP = localLOGV || false; 220 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 221 static final boolean DEBUG_FOCUS = false; 222 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 223 static final boolean DEBUG_MU = localLOGV || false; 224 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 225 static final boolean DEBUG_LRU = localLOGV || false; 226 static final boolean DEBUG_PAUSE = localLOGV || false; 227 static final boolean DEBUG_POWER = localLOGV || false; 228 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 229 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 230 static final boolean DEBUG_PROCESSES = localLOGV || false; 231 static final boolean DEBUG_PROVIDER = localLOGV || false; 232 static final boolean DEBUG_RESULTS = localLOGV || false; 233 static final boolean DEBUG_SERVICE = localLOGV || false; 234 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 235 static final boolean DEBUG_STACK = localLOGV || false; 236 static final boolean DEBUG_SWITCH = localLOGV || false; 237 static final boolean DEBUG_TASKS = localLOGV || false; 238 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 239 static final boolean DEBUG_TRANSITION = localLOGV || false; 240 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 241 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 242 static final boolean DEBUG_VISBILITY = localLOGV || false; 243 static final boolean DEBUG_PSS = localLOGV || false; 244 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 245 static final boolean VALIDATE_TOKENS = false; 246 static final boolean SHOW_ACTIVITY_START_TIME = true; 247 248 // Control over CPU and battery monitoring. 249 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 250 static final boolean MONITOR_CPU_USAGE = true; 251 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 252 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 253 static final boolean MONITOR_THREAD_CPU_USAGE = false; 254 255 // The flags that are set for all calls we make to the package manager. 256 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 257 258 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 259 260 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 261 262 // Maximum number of recent tasks that we can remember. 263 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 264 265 // Amount of time after a call to stopAppSwitches() during which we will 266 // prevent further untrusted switches from happening. 267 static final long APP_SWITCH_DELAY_TIME = 5*1000; 268 269 // How long we wait for a launched process to attach to the activity manager 270 // before we decide it's never going to come up for real. 271 static final int PROC_START_TIMEOUT = 10*1000; 272 273 // How long we wait for a launched process to attach to the activity manager 274 // before we decide it's never going to come up for real, when the process was 275 // started with a wrapper for instrumentation (such as Valgrind) because it 276 // could take much longer than usual. 277 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 278 279 // How long to wait after going idle before forcing apps to GC. 280 static final int GC_TIMEOUT = 5*1000; 281 282 // The minimum amount of time between successive GC requests for a process. 283 static final int GC_MIN_INTERVAL = 60*1000; 284 285 // The minimum amount of time between successive PSS requests for a process. 286 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 287 288 // The minimum amount of time between successive PSS requests for a process 289 // when the request is due to the memory state being lowered. 290 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 291 292 // The rate at which we check for apps using excessive power -- 15 mins. 293 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 294 295 // The minimum sample duration we will allow before deciding we have 296 // enough data on wake locks to start killing things. 297 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 298 299 // The minimum sample duration we will allow before deciding we have 300 // enough data on CPU usage to start killing things. 301 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 302 303 // How long we allow a receiver to run before giving up on it. 304 static final int BROADCAST_FG_TIMEOUT = 10*1000; 305 static final int BROADCAST_BG_TIMEOUT = 60*1000; 306 307 // How long we wait until we timeout on key dispatching. 308 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 309 310 // How long we wait until we timeout on key dispatching during instrumentation. 311 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 312 313 // Amount of time we wait for observers to handle a user switch before 314 // giving up on them and unfreezing the screen. 315 static final int USER_SWITCH_TIMEOUT = 2*1000; 316 317 // Maximum number of users we allow to be running at a time. 318 static final int MAX_RUNNING_USERS = 3; 319 320 // How long to wait in getAssistContextExtras for the activity and foreground services 321 // to respond with the result. 322 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 323 324 // Maximum number of persisted Uri grants a package is allowed 325 static final int MAX_PERSISTED_URI_GRANTS = 128; 326 327 static final int MY_PID = Process.myPid(); 328 329 static final String[] EMPTY_STRING_ARRAY = new String[0]; 330 331 // How many bytes to write into the dropbox log before truncating 332 static final int DROPBOX_MAX_SIZE = 256 * 1024; 333 334 /** Run all ActivityStacks through this */ 335 ActivityStackSupervisor mStackSupervisor; 336 337 public IntentFirewall mIntentFirewall; 338 339 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 340 // default actuion automatically. Important for devices without direct input 341 // devices. 342 private boolean mShowDialogs = true; 343 344 /** 345 * Description of a request to start a new activity, which has been held 346 * due to app switches being disabled. 347 */ 348 static class PendingActivityLaunch { 349 final ActivityRecord r; 350 final ActivityRecord sourceRecord; 351 final int startFlags; 352 final ActivityStack stack; 353 354 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 355 int _startFlags, ActivityStack _stack) { 356 r = _r; 357 sourceRecord = _sourceRecord; 358 startFlags = _startFlags; 359 stack = _stack; 360 } 361 } 362 363 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 364 = new ArrayList<PendingActivityLaunch>(); 365 366 BroadcastQueue mFgBroadcastQueue; 367 BroadcastQueue mBgBroadcastQueue; 368 // Convenient for easy iteration over the queues. Foreground is first 369 // so that dispatch of foreground broadcasts gets precedence. 370 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 371 372 BroadcastQueue broadcastQueueForIntent(Intent intent) { 373 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 374 if (DEBUG_BACKGROUND_BROADCAST) { 375 Slog.i(TAG, "Broadcast intent " + intent + " on " 376 + (isFg ? "foreground" : "background") 377 + " queue"); 378 } 379 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 380 } 381 382 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 383 for (BroadcastQueue queue : mBroadcastQueues) { 384 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 385 if (r != null) { 386 return r; 387 } 388 } 389 return null; 390 } 391 392 /** 393 * Activity we have told the window manager to have key focus. 394 */ 395 ActivityRecord mFocusedActivity = null; 396 397 /** 398 * List of intents that were used to start the most recent tasks. 399 */ 400 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 401 402 public class PendingAssistExtras extends Binder implements Runnable { 403 public final ActivityRecord activity; 404 public boolean haveResult = false; 405 public Bundle result = null; 406 public PendingAssistExtras(ActivityRecord _activity) { 407 activity = _activity; 408 } 409 @Override 410 public void run() { 411 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 412 synchronized (this) { 413 haveResult = true; 414 notifyAll(); 415 } 416 } 417 } 418 419 final ArrayList<PendingAssistExtras> mPendingAssistExtras 420 = new ArrayList<PendingAssistExtras>(); 421 422 /** 423 * Process management. 424 */ 425 final ProcessList mProcessList = new ProcessList(); 426 427 /** 428 * All of the applications we currently have running organized by name. 429 * The keys are strings of the application package name (as 430 * returned by the package manager), and the keys are ApplicationRecord 431 * objects. 432 */ 433 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 434 435 /** 436 * Tracking long-term execution of processes to look for abuse and other 437 * bad app behavior. 438 */ 439 final ProcessStatsService mProcessStats; 440 441 /** 442 * The currently running isolated processes. 443 */ 444 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 445 446 /** 447 * Counter for assigning isolated process uids, to avoid frequently reusing the 448 * same ones. 449 */ 450 int mNextIsolatedProcessUid = 0; 451 452 /** 453 * The currently running heavy-weight process, if any. 454 */ 455 ProcessRecord mHeavyWeightProcess = null; 456 457 /** 458 * The last time that various processes have crashed. 459 */ 460 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 461 462 /** 463 * Information about a process that is currently marked as bad. 464 */ 465 static final class BadProcessInfo { 466 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 467 this.time = time; 468 this.shortMsg = shortMsg; 469 this.longMsg = longMsg; 470 this.stack = stack; 471 } 472 473 final long time; 474 final String shortMsg; 475 final String longMsg; 476 final String stack; 477 } 478 479 /** 480 * Set of applications that we consider to be bad, and will reject 481 * incoming broadcasts from (which the user has no control over). 482 * Processes are added to this set when they have crashed twice within 483 * a minimum amount of time; they are removed from it when they are 484 * later restarted (hopefully due to some user action). The value is the 485 * time it was added to the list. 486 */ 487 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 488 489 /** 490 * All of the processes we currently have running organized by pid. 491 * The keys are the pid running the application. 492 * 493 * <p>NOTE: This object is protected by its own lock, NOT the global 494 * activity manager lock! 495 */ 496 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 497 498 /** 499 * All of the processes that have been forced to be foreground. The key 500 * is the pid of the caller who requested it (we hold a death 501 * link on it). 502 */ 503 abstract class ForegroundToken implements IBinder.DeathRecipient { 504 int pid; 505 IBinder token; 506 } 507 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 508 509 /** 510 * List of records for processes that someone had tried to start before the 511 * system was ready. We don't start them at that point, but ensure they 512 * are started by the time booting is complete. 513 */ 514 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 515 516 /** 517 * List of persistent applications that are in the process 518 * of being started. 519 */ 520 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 521 522 /** 523 * Processes that are being forcibly torn down. 524 */ 525 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 526 527 /** 528 * List of running applications, sorted by recent usage. 529 * The first entry in the list is the least recently used. 530 */ 531 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 532 533 /** 534 * Where in mLruProcesses that the processes hosting activities start. 535 */ 536 int mLruProcessActivityStart = 0; 537 538 /** 539 * Where in mLruProcesses that the processes hosting services start. 540 * This is after (lower index) than mLruProcessesActivityStart. 541 */ 542 int mLruProcessServiceStart = 0; 543 544 /** 545 * List of processes that should gc as soon as things are idle. 546 */ 547 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 548 549 /** 550 * Processes we want to collect PSS data from. 551 */ 552 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 553 554 /** 555 * Last time we requested PSS data of all processes. 556 */ 557 long mLastFullPssTime = SystemClock.uptimeMillis(); 558 559 /** 560 * This is the process holding what we currently consider to be 561 * the "home" activity. 562 */ 563 ProcessRecord mHomeProcess; 564 565 /** 566 * This is the process holding the activity the user last visited that 567 * is in a different process from the one they are currently in. 568 */ 569 ProcessRecord mPreviousProcess; 570 571 /** 572 * The time at which the previous process was last visible. 573 */ 574 long mPreviousProcessVisibleTime; 575 576 /** 577 * Which uses have been started, so are allowed to run code. 578 */ 579 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 580 581 /** 582 * LRU list of history of current users. Most recently current is at the end. 583 */ 584 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 585 586 /** 587 * Constant array of the users that are currently started. 588 */ 589 int[] mStartedUserArray = new int[] { 0 }; 590 591 /** 592 * Registered observers of the user switching mechanics. 593 */ 594 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 595 = new RemoteCallbackList<IUserSwitchObserver>(); 596 597 /** 598 * Currently active user switch. 599 */ 600 Object mCurUserSwitchCallback; 601 602 /** 603 * Packages that the user has asked to have run in screen size 604 * compatibility mode instead of filling the screen. 605 */ 606 final CompatModePackages mCompatModePackages; 607 608 /** 609 * Set of IntentSenderRecord objects that are currently active. 610 */ 611 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 612 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 613 614 /** 615 * Fingerprints (hashCode()) of stack traces that we've 616 * already logged DropBox entries for. Guarded by itself. If 617 * something (rogue user app) forces this over 618 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 619 */ 620 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 621 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 622 623 /** 624 * Strict Mode background batched logging state. 625 * 626 * The string buffer is guarded by itself, and its lock is also 627 * used to determine if another batched write is already 628 * in-flight. 629 */ 630 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 631 632 /** 633 * Keeps track of all IIntentReceivers that have been registered for 634 * broadcasts. Hash keys are the receiver IBinder, hash value is 635 * a ReceiverList. 636 */ 637 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 638 new HashMap<IBinder, ReceiverList>(); 639 640 /** 641 * Resolver for broadcast intents to registered receivers. 642 * Holds BroadcastFilter (subclass of IntentFilter). 643 */ 644 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 645 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 646 @Override 647 protected boolean allowFilterResult( 648 BroadcastFilter filter, List<BroadcastFilter> dest) { 649 IBinder target = filter.receiverList.receiver.asBinder(); 650 for (int i=dest.size()-1; i>=0; i--) { 651 if (dest.get(i).receiverList.receiver.asBinder() == target) { 652 return false; 653 } 654 } 655 return true; 656 } 657 658 @Override 659 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 660 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 661 || userId == filter.owningUserId) { 662 return super.newResult(filter, match, userId); 663 } 664 return null; 665 } 666 667 @Override 668 protected BroadcastFilter[] newArray(int size) { 669 return new BroadcastFilter[size]; 670 } 671 672 @Override 673 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 674 return packageName.equals(filter.packageName); 675 } 676 }; 677 678 /** 679 * State of all active sticky broadcasts per user. Keys are the action of the 680 * sticky Intent, values are an ArrayList of all broadcasted intents with 681 * that action (which should usually be one). The SparseArray is keyed 682 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 683 * for stickies that are sent to all users. 684 */ 685 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 686 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 687 688 final ActiveServices mServices; 689 690 /** 691 * Backup/restore process management 692 */ 693 String mBackupAppName = null; 694 BackupRecord mBackupTarget = null; 695 696 /** 697 * List of PendingThumbnailsRecord objects of clients who are still 698 * waiting to receive all of the thumbnails for a task. 699 */ 700 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 701 new ArrayList<PendingThumbnailsRecord>(); 702 703 final ProviderMap mProviderMap; 704 705 /** 706 * List of content providers who have clients waiting for them. The 707 * application is currently being launched and the provider will be 708 * removed from this list once it is published. 709 */ 710 final ArrayList<ContentProviderRecord> mLaunchingProviders 711 = new ArrayList<ContentProviderRecord>(); 712 713 /** 714 * File storing persisted {@link #mGrantedUriPermissions}. 715 */ 716 private final AtomicFile mGrantFile; 717 718 /** XML constants used in {@link #mGrantFile} */ 719 private static final String TAG_URI_GRANTS = "uri-grants"; 720 private static final String TAG_URI_GRANT = "uri-grant"; 721 private static final String ATTR_USER_HANDLE = "userHandle"; 722 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 723 private static final String ATTR_TARGET_PKG = "targetPkg"; 724 private static final String ATTR_URI = "uri"; 725 private static final String ATTR_MODE_FLAGS = "modeFlags"; 726 private static final String ATTR_CREATED_TIME = "createdTime"; 727 728 /** 729 * Global set of specific {@link Uri} permissions that have been granted. 730 * This optimized lookup structure maps from {@link UriPermission#targetUid} 731 * to {@link UriPermission#uri} to {@link UriPermission}. 732 */ 733 @GuardedBy("this") 734 private final SparseArray<ArrayMap<Uri, UriPermission>> 735 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 736 737 CoreSettingsObserver mCoreSettingsObserver; 738 739 /** 740 * Thread-local storage used to carry caller permissions over through 741 * indirect content-provider access. 742 */ 743 private class Identity { 744 public int pid; 745 public int uid; 746 747 Identity(int _pid, int _uid) { 748 pid = _pid; 749 uid = _uid; 750 } 751 } 752 753 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 754 755 /** 756 * All information we have collected about the runtime performance of 757 * any user id that can impact battery performance. 758 */ 759 final BatteryStatsService mBatteryStatsService; 760 761 /** 762 * Information about component usage 763 */ 764 final UsageStatsService mUsageStatsService; 765 766 /** 767 * Information about and control over application operations 768 */ 769 final AppOpsService mAppOpsService; 770 771 /** 772 * Current configuration information. HistoryRecord objects are given 773 * a reference to this object to indicate which configuration they are 774 * currently running in, so this object must be kept immutable. 775 */ 776 Configuration mConfiguration = new Configuration(); 777 778 /** 779 * Current sequencing integer of the configuration, for skipping old 780 * configurations. 781 */ 782 int mConfigurationSeq = 0; 783 784 /** 785 * Hardware-reported OpenGLES version. 786 */ 787 final int GL_ES_VERSION; 788 789 /** 790 * List of initialization arguments to pass to all processes when binding applications to them. 791 * For example, references to the commonly used services. 792 */ 793 HashMap<String, IBinder> mAppBindArgs; 794 795 /** 796 * Temporary to avoid allocations. Protected by main lock. 797 */ 798 final StringBuilder mStringBuilder = new StringBuilder(256); 799 800 /** 801 * Used to control how we initialize the service. 802 */ 803 ComponentName mTopComponent; 804 String mTopAction = Intent.ACTION_MAIN; 805 String mTopData; 806 boolean mProcessesReady = false; 807 boolean mSystemReady = false; 808 boolean mBooting = false; 809 boolean mWaitingUpdate = false; 810 boolean mDidUpdate = false; 811 boolean mOnBattery = false; 812 boolean mLaunchWarningShown = false; 813 814 Context mContext; 815 816 int mFactoryTest; 817 818 boolean mCheckedForSetup; 819 820 /** 821 * The time at which we will allow normal application switches again, 822 * after a call to {@link #stopAppSwitches()}. 823 */ 824 long mAppSwitchesAllowedTime; 825 826 /** 827 * This is set to true after the first switch after mAppSwitchesAllowedTime 828 * is set; any switches after that will clear the time. 829 */ 830 boolean mDidAppSwitch; 831 832 /** 833 * Last time (in realtime) at which we checked for power usage. 834 */ 835 long mLastPowerCheckRealtime; 836 837 /** 838 * Last time (in uptime) at which we checked for power usage. 839 */ 840 long mLastPowerCheckUptime; 841 842 /** 843 * Set while we are wanting to sleep, to prevent any 844 * activities from being started/resumed. 845 */ 846 boolean mSleeping = false; 847 848 /** 849 * State of external calls telling us if the device is asleep. 850 */ 851 boolean mWentToSleep = false; 852 853 /** 854 * State of external call telling us if the lock screen is shown. 855 */ 856 boolean mLockScreenShown = false; 857 858 /** 859 * Set if we are shutting down the system, similar to sleeping. 860 */ 861 boolean mShuttingDown = false; 862 863 /** 864 * Current sequence id for oom_adj computation traversal. 865 */ 866 int mAdjSeq = 0; 867 868 /** 869 * Current sequence id for process LRU updating. 870 */ 871 int mLruSeq = 0; 872 873 /** 874 * Keep track of the non-cached/empty process we last found, to help 875 * determine how to distribute cached/empty processes next time. 876 */ 877 int mNumNonCachedProcs = 0; 878 879 /** 880 * Keep track of the number of cached hidden procs, to balance oom adj 881 * distribution between those and empty procs. 882 */ 883 int mNumCachedHiddenProcs = 0; 884 885 /** 886 * Keep track of the number of service processes we last found, to 887 * determine on the next iteration which should be B services. 888 */ 889 int mNumServiceProcs = 0; 890 int mNewNumAServiceProcs = 0; 891 int mNewNumServiceProcs = 0; 892 893 /** 894 * Allow the current computed overall memory level of the system to go down? 895 * This is set to false when we are killing processes for reasons other than 896 * memory management, so that the now smaller process list will not be taken as 897 * an indication that memory is tighter. 898 */ 899 boolean mAllowLowerMemLevel = false; 900 901 /** 902 * The last computed memory level, for holding when we are in a state that 903 * processes are going away for other reasons. 904 */ 905 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 906 907 /** 908 * The last total number of process we have, to determine if changes actually look 909 * like a shrinking number of process due to lower RAM. 910 */ 911 int mLastNumProcesses; 912 913 /** 914 * The uptime of the last time we performed idle maintenance. 915 */ 916 long mLastIdleTime = SystemClock.uptimeMillis(); 917 918 /** 919 * Total time spent with RAM that has been added in the past since the last idle time. 920 */ 921 long mLowRamTimeSinceLastIdle = 0; 922 923 /** 924 * If RAM is currently low, when that horrible situation started. 925 */ 926 long mLowRamStartTime = 0; 927 928 /** 929 * For reporting to battery stats the current top application. 930 */ 931 private String mCurResumedPackage = null; 932 private int mCurResumedUid = -1; 933 934 /** 935 * For reporting to battery stats the apps currently running foreground 936 * service. The ProcessMap is package/uid tuples; each of these contain 937 * an array of the currently foreground processes. 938 */ 939 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 940 = new ProcessMap<ArrayList<ProcessRecord>>(); 941 942 /** 943 * This is set if we had to do a delayed dexopt of an app before launching 944 * it, to increasing the ANR timeouts in that case. 945 */ 946 boolean mDidDexOpt; 947 948 /** 949 * Set if the systemServer made a call to enterSafeMode. 950 */ 951 boolean mSafeMode; 952 953 String mDebugApp = null; 954 boolean mWaitForDebugger = false; 955 boolean mDebugTransient = false; 956 String mOrigDebugApp = null; 957 boolean mOrigWaitForDebugger = false; 958 boolean mAlwaysFinishActivities = false; 959 IActivityController mController = null; 960 String mProfileApp = null; 961 ProcessRecord mProfileProc = null; 962 String mProfileFile; 963 ParcelFileDescriptor mProfileFd; 964 int mProfileType = 0; 965 boolean mAutoStopProfiler = false; 966 String mOpenGlTraceApp = null; 967 968 static class ProcessChangeItem { 969 static final int CHANGE_ACTIVITIES = 1<<0; 970 static final int CHANGE_IMPORTANCE= 1<<1; 971 int changes; 972 int uid; 973 int pid; 974 int importance; 975 boolean foregroundActivities; 976 } 977 978 final RemoteCallbackList<IProcessObserver> mProcessObservers 979 = new RemoteCallbackList<IProcessObserver>(); 980 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 981 982 final ArrayList<ProcessChangeItem> mPendingProcessChanges 983 = new ArrayList<ProcessChangeItem>(); 984 final ArrayList<ProcessChangeItem> mAvailProcessChanges 985 = new ArrayList<ProcessChangeItem>(); 986 987 /** 988 * Runtime CPU use collection thread. This object's lock is used to 989 * protect all related state. 990 */ 991 final Thread mProcessCpuThread; 992 993 /** 994 * Used to collect process stats when showing not responding dialog. 995 * Protected by mProcessCpuThread. 996 */ 997 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 998 MONITOR_THREAD_CPU_USAGE); 999 final AtomicLong mLastCpuTime = new AtomicLong(0); 1000 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1001 1002 long mLastWriteTime = 0; 1003 1004 /** 1005 * Used to retain an update lock when the foreground activity is in 1006 * immersive mode. 1007 */ 1008 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1009 1010 /** 1011 * Set to true after the system has finished booting. 1012 */ 1013 boolean mBooted = false; 1014 1015 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1016 int mProcessLimitOverride = -1; 1017 1018 WindowManagerService mWindowManager; 1019 1020 final ActivityThread mSystemThread; 1021 1022 int mCurrentUserId = 0; 1023 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1024 private UserManagerService mUserManager; 1025 1026 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1027 final ProcessRecord mApp; 1028 final int mPid; 1029 final IApplicationThread mAppThread; 1030 1031 AppDeathRecipient(ProcessRecord app, int pid, 1032 IApplicationThread thread) { 1033 if (localLOGV) Slog.v( 1034 TAG, "New death recipient " + this 1035 + " for thread " + thread.asBinder()); 1036 mApp = app; 1037 mPid = pid; 1038 mAppThread = thread; 1039 } 1040 1041 @Override 1042 public void binderDied() { 1043 if (localLOGV) Slog.v( 1044 TAG, "Death received in " + this 1045 + " for thread " + mAppThread.asBinder()); 1046 synchronized(ActivityManagerService.this) { 1047 appDiedLocked(mApp, mPid, mAppThread); 1048 } 1049 } 1050 } 1051 1052 static final int SHOW_ERROR_MSG = 1; 1053 static final int SHOW_NOT_RESPONDING_MSG = 2; 1054 static final int SHOW_FACTORY_ERROR_MSG = 3; 1055 static final int UPDATE_CONFIGURATION_MSG = 4; 1056 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1057 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1058 static final int SERVICE_TIMEOUT_MSG = 12; 1059 static final int UPDATE_TIME_ZONE = 13; 1060 static final int SHOW_UID_ERROR_MSG = 14; 1061 static final int IM_FEELING_LUCKY_MSG = 15; 1062 static final int PROC_START_TIMEOUT_MSG = 20; 1063 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1064 static final int KILL_APPLICATION_MSG = 22; 1065 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1066 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1067 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1068 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1069 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1070 static final int CLEAR_DNS_CACHE_MSG = 28; 1071 static final int UPDATE_HTTP_PROXY_MSG = 29; 1072 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1073 static final int DISPATCH_PROCESSES_CHANGED = 31; 1074 static final int DISPATCH_PROCESS_DIED = 32; 1075 static final int REPORT_MEM_USAGE_MSG = 33; 1076 static final int REPORT_USER_SWITCH_MSG = 34; 1077 static final int CONTINUE_USER_SWITCH_MSG = 35; 1078 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1079 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1080 static final int PERSIST_URI_GRANTS_MSG = 38; 1081 static final int REQUEST_ALL_PSS_MSG = 39; 1082 static final int START_PROFILES_MSG = 40; 1083 static final int UPDATE_TIME = 41; 1084 1085 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1086 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1087 static final int FIRST_COMPAT_MODE_MSG = 300; 1088 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1089 1090 AlertDialog mUidAlert; 1091 CompatModeDialog mCompatModeDialog; 1092 long mLastMemUsageReportTime = 0; 1093 1094 /** 1095 * Flag whether the current user is a "monkey", i.e. whether 1096 * the UI is driven by a UI automation tool. 1097 */ 1098 private boolean mUserIsMonkey; 1099 1100 final ServiceThread mHandlerThread; 1101 final MainHandler mHandler; 1102 1103 final class MainHandler extends Handler { 1104 public MainHandler(Looper looper) { 1105 super(looper, null, true); 1106 } 1107 1108 @Override 1109 public void handleMessage(Message msg) { 1110 switch (msg.what) { 1111 case SHOW_ERROR_MSG: { 1112 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1113 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1114 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1115 synchronized (ActivityManagerService.this) { 1116 ProcessRecord proc = (ProcessRecord)data.get("app"); 1117 AppErrorResult res = (AppErrorResult) data.get("result"); 1118 if (proc != null && proc.crashDialog != null) { 1119 Slog.e(TAG, "App already has crash dialog: " + proc); 1120 if (res != null) { 1121 res.set(0); 1122 } 1123 return; 1124 } 1125 if (!showBackground && UserHandle.getAppId(proc.uid) 1126 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1127 && proc.pid != MY_PID) { 1128 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1129 if (res != null) { 1130 res.set(0); 1131 } 1132 return; 1133 } 1134 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1135 Dialog d = new AppErrorDialog(mContext, 1136 ActivityManagerService.this, res, proc); 1137 d.show(); 1138 proc.crashDialog = d; 1139 } else { 1140 // The device is asleep, so just pretend that the user 1141 // saw a crash dialog and hit "force quit". 1142 if (res != null) { 1143 res.set(0); 1144 } 1145 } 1146 } 1147 1148 ensureBootCompleted(); 1149 } break; 1150 case SHOW_NOT_RESPONDING_MSG: { 1151 synchronized (ActivityManagerService.this) { 1152 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1153 ProcessRecord proc = (ProcessRecord)data.get("app"); 1154 if (proc != null && proc.anrDialog != null) { 1155 Slog.e(TAG, "App already has anr dialog: " + proc); 1156 return; 1157 } 1158 1159 Intent intent = new Intent("android.intent.action.ANR"); 1160 if (!mProcessesReady) { 1161 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1162 | Intent.FLAG_RECEIVER_FOREGROUND); 1163 } 1164 broadcastIntentLocked(null, null, intent, 1165 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1166 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1167 1168 if (mShowDialogs) { 1169 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1170 mContext, proc, (ActivityRecord)data.get("activity"), 1171 msg.arg1 != 0); 1172 d.show(); 1173 proc.anrDialog = d; 1174 } else { 1175 // Just kill the app if there is no dialog to be shown. 1176 killAppAtUsersRequest(proc, null); 1177 } 1178 } 1179 1180 ensureBootCompleted(); 1181 } break; 1182 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1183 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1184 synchronized (ActivityManagerService.this) { 1185 ProcessRecord proc = (ProcessRecord) data.get("app"); 1186 if (proc == null) { 1187 Slog.e(TAG, "App not found when showing strict mode dialog."); 1188 break; 1189 } 1190 if (proc.crashDialog != null) { 1191 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1192 return; 1193 } 1194 AppErrorResult res = (AppErrorResult) data.get("result"); 1195 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1196 Dialog d = new StrictModeViolationDialog(mContext, 1197 ActivityManagerService.this, res, proc); 1198 d.show(); 1199 proc.crashDialog = d; 1200 } else { 1201 // The device is asleep, so just pretend that the user 1202 // saw a crash dialog and hit "force quit". 1203 res.set(0); 1204 } 1205 } 1206 ensureBootCompleted(); 1207 } break; 1208 case SHOW_FACTORY_ERROR_MSG: { 1209 Dialog d = new FactoryErrorDialog( 1210 mContext, msg.getData().getCharSequence("msg")); 1211 d.show(); 1212 ensureBootCompleted(); 1213 } break; 1214 case UPDATE_CONFIGURATION_MSG: { 1215 final ContentResolver resolver = mContext.getContentResolver(); 1216 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1217 } break; 1218 case GC_BACKGROUND_PROCESSES_MSG: { 1219 synchronized (ActivityManagerService.this) { 1220 performAppGcsIfAppropriateLocked(); 1221 } 1222 } break; 1223 case WAIT_FOR_DEBUGGER_MSG: { 1224 synchronized (ActivityManagerService.this) { 1225 ProcessRecord app = (ProcessRecord)msg.obj; 1226 if (msg.arg1 != 0) { 1227 if (!app.waitedForDebugger) { 1228 Dialog d = new AppWaitingForDebuggerDialog( 1229 ActivityManagerService.this, 1230 mContext, app); 1231 app.waitDialog = d; 1232 app.waitedForDebugger = true; 1233 d.show(); 1234 } 1235 } else { 1236 if (app.waitDialog != null) { 1237 app.waitDialog.dismiss(); 1238 app.waitDialog = null; 1239 } 1240 } 1241 } 1242 } break; 1243 case SERVICE_TIMEOUT_MSG: { 1244 if (mDidDexOpt) { 1245 mDidDexOpt = false; 1246 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1247 nmsg.obj = msg.obj; 1248 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1249 return; 1250 } 1251 mServices.serviceTimeout((ProcessRecord)msg.obj); 1252 } break; 1253 case UPDATE_TIME_ZONE: { 1254 synchronized (ActivityManagerService.this) { 1255 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1256 ProcessRecord r = mLruProcesses.get(i); 1257 if (r.thread != null) { 1258 try { 1259 r.thread.updateTimeZone(); 1260 } catch (RemoteException ex) { 1261 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1262 } 1263 } 1264 } 1265 } 1266 } break; 1267 case CLEAR_DNS_CACHE_MSG: { 1268 synchronized (ActivityManagerService.this) { 1269 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1270 ProcessRecord r = mLruProcesses.get(i); 1271 if (r.thread != null) { 1272 try { 1273 r.thread.clearDnsCache(); 1274 } catch (RemoteException ex) { 1275 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1276 } 1277 } 1278 } 1279 } 1280 } break; 1281 case UPDATE_HTTP_PROXY_MSG: { 1282 ProxyProperties proxy = (ProxyProperties)msg.obj; 1283 String host = ""; 1284 String port = ""; 1285 String exclList = ""; 1286 String pacFileUrl = null; 1287 if (proxy != null) { 1288 host = proxy.getHost(); 1289 port = Integer.toString(proxy.getPort()); 1290 exclList = proxy.getExclusionList(); 1291 pacFileUrl = proxy.getPacFileUrl(); 1292 } 1293 synchronized (ActivityManagerService.this) { 1294 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1295 ProcessRecord r = mLruProcesses.get(i); 1296 if (r.thread != null) { 1297 try { 1298 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1299 } catch (RemoteException ex) { 1300 Slog.w(TAG, "Failed to update http proxy for: " + 1301 r.info.processName); 1302 } 1303 } 1304 } 1305 } 1306 } break; 1307 case SHOW_UID_ERROR_MSG: { 1308 String title = "System UIDs Inconsistent"; 1309 String text = "UIDs on the system are inconsistent, you need to wipe your" 1310 + " data partition or your device will be unstable."; 1311 Log.e(TAG, title + ": " + text); 1312 if (mShowDialogs) { 1313 // XXX This is a temporary dialog, no need to localize. 1314 AlertDialog d = new BaseErrorDialog(mContext); 1315 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1316 d.setCancelable(false); 1317 d.setTitle(title); 1318 d.setMessage(text); 1319 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1320 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1321 mUidAlert = d; 1322 d.show(); 1323 } 1324 } break; 1325 case IM_FEELING_LUCKY_MSG: { 1326 if (mUidAlert != null) { 1327 mUidAlert.dismiss(); 1328 mUidAlert = null; 1329 } 1330 } break; 1331 case PROC_START_TIMEOUT_MSG: { 1332 if (mDidDexOpt) { 1333 mDidDexOpt = false; 1334 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1335 nmsg.obj = msg.obj; 1336 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1337 return; 1338 } 1339 ProcessRecord app = (ProcessRecord)msg.obj; 1340 synchronized (ActivityManagerService.this) { 1341 processStartTimedOutLocked(app); 1342 } 1343 } break; 1344 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1345 synchronized (ActivityManagerService.this) { 1346 doPendingActivityLaunchesLocked(true); 1347 } 1348 } break; 1349 case KILL_APPLICATION_MSG: { 1350 synchronized (ActivityManagerService.this) { 1351 int appid = msg.arg1; 1352 boolean restart = (msg.arg2 == 1); 1353 Bundle bundle = (Bundle)msg.obj; 1354 String pkg = bundle.getString("pkg"); 1355 String reason = bundle.getString("reason"); 1356 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1357 false, UserHandle.USER_ALL, reason); 1358 } 1359 } break; 1360 case FINALIZE_PENDING_INTENT_MSG: { 1361 ((PendingIntentRecord)msg.obj).completeFinalize(); 1362 } break; 1363 case POST_HEAVY_NOTIFICATION_MSG: { 1364 INotificationManager inm = NotificationManager.getService(); 1365 if (inm == null) { 1366 return; 1367 } 1368 1369 ActivityRecord root = (ActivityRecord)msg.obj; 1370 ProcessRecord process = root.app; 1371 if (process == null) { 1372 return; 1373 } 1374 1375 try { 1376 Context context = mContext.createPackageContext(process.info.packageName, 0); 1377 String text = mContext.getString(R.string.heavy_weight_notification, 1378 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1379 Notification notification = new Notification(); 1380 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1381 notification.when = 0; 1382 notification.flags = Notification.FLAG_ONGOING_EVENT; 1383 notification.tickerText = text; 1384 notification.defaults = 0; // please be quiet 1385 notification.sound = null; 1386 notification.vibrate = null; 1387 notification.setLatestEventInfo(context, text, 1388 mContext.getText(R.string.heavy_weight_notification_detail), 1389 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1390 PendingIntent.FLAG_CANCEL_CURRENT, null, 1391 new UserHandle(root.userId))); 1392 1393 try { 1394 int[] outId = new int[1]; 1395 inm.enqueueNotificationWithTag("android", "android", null, 1396 R.string.heavy_weight_notification, 1397 notification, outId, root.userId); 1398 } catch (RuntimeException e) { 1399 Slog.w(ActivityManagerService.TAG, 1400 "Error showing notification for heavy-weight app", e); 1401 } catch (RemoteException e) { 1402 } 1403 } catch (NameNotFoundException e) { 1404 Slog.w(TAG, "Unable to create context for heavy notification", e); 1405 } 1406 } break; 1407 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1408 INotificationManager inm = NotificationManager.getService(); 1409 if (inm == null) { 1410 return; 1411 } 1412 try { 1413 inm.cancelNotificationWithTag("android", null, 1414 R.string.heavy_weight_notification, msg.arg1); 1415 } catch (RuntimeException e) { 1416 Slog.w(ActivityManagerService.TAG, 1417 "Error canceling notification for service", e); 1418 } catch (RemoteException e) { 1419 } 1420 } break; 1421 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1422 synchronized (ActivityManagerService.this) { 1423 checkExcessivePowerUsageLocked(true); 1424 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1425 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1426 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1427 } 1428 } break; 1429 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1430 synchronized (ActivityManagerService.this) { 1431 ActivityRecord ar = (ActivityRecord)msg.obj; 1432 if (mCompatModeDialog != null) { 1433 if (mCompatModeDialog.mAppInfo.packageName.equals( 1434 ar.info.applicationInfo.packageName)) { 1435 return; 1436 } 1437 mCompatModeDialog.dismiss(); 1438 mCompatModeDialog = null; 1439 } 1440 if (ar != null && false) { 1441 if (mCompatModePackages.getPackageAskCompatModeLocked( 1442 ar.packageName)) { 1443 int mode = mCompatModePackages.computeCompatModeLocked( 1444 ar.info.applicationInfo); 1445 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1446 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1447 mCompatModeDialog = new CompatModeDialog( 1448 ActivityManagerService.this, mContext, 1449 ar.info.applicationInfo); 1450 mCompatModeDialog.show(); 1451 } 1452 } 1453 } 1454 } 1455 break; 1456 } 1457 case DISPATCH_PROCESSES_CHANGED: { 1458 dispatchProcessesChanged(); 1459 break; 1460 } 1461 case DISPATCH_PROCESS_DIED: { 1462 final int pid = msg.arg1; 1463 final int uid = msg.arg2; 1464 dispatchProcessDied(pid, uid); 1465 break; 1466 } 1467 case REPORT_MEM_USAGE_MSG: { 1468 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1469 Thread thread = new Thread() { 1470 @Override public void run() { 1471 final SparseArray<ProcessMemInfo> infoMap 1472 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1473 for (int i=0, N=memInfos.size(); i<N; i++) { 1474 ProcessMemInfo mi = memInfos.get(i); 1475 infoMap.put(mi.pid, mi); 1476 } 1477 updateCpuStatsNow(); 1478 synchronized (mProcessCpuThread) { 1479 final int N = mProcessCpuTracker.countStats(); 1480 for (int i=0; i<N; i++) { 1481 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1482 if (st.vsize > 0) { 1483 long pss = Debug.getPss(st.pid, null); 1484 if (pss > 0) { 1485 if (infoMap.indexOfKey(st.pid) < 0) { 1486 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1487 ProcessList.NATIVE_ADJ, -1, "native", null); 1488 mi.pss = pss; 1489 memInfos.add(mi); 1490 } 1491 } 1492 } 1493 } 1494 } 1495 1496 long totalPss = 0; 1497 for (int i=0, N=memInfos.size(); i<N; i++) { 1498 ProcessMemInfo mi = memInfos.get(i); 1499 if (mi.pss == 0) { 1500 mi.pss = Debug.getPss(mi.pid, null); 1501 } 1502 totalPss += mi.pss; 1503 } 1504 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1505 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1506 if (lhs.oomAdj != rhs.oomAdj) { 1507 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1508 } 1509 if (lhs.pss != rhs.pss) { 1510 return lhs.pss < rhs.pss ? 1 : -1; 1511 } 1512 return 0; 1513 } 1514 }); 1515 1516 StringBuilder tag = new StringBuilder(128); 1517 StringBuilder stack = new StringBuilder(128); 1518 tag.append("Low on memory -- "); 1519 appendMemBucket(tag, totalPss, "total", false); 1520 appendMemBucket(stack, totalPss, "total", true); 1521 1522 StringBuilder logBuilder = new StringBuilder(1024); 1523 logBuilder.append("Low on memory:\n"); 1524 1525 boolean firstLine = true; 1526 int lastOomAdj = Integer.MIN_VALUE; 1527 for (int i=0, N=memInfos.size(); i<N; i++) { 1528 ProcessMemInfo mi = memInfos.get(i); 1529 1530 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1531 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1532 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1533 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1534 if (lastOomAdj != mi.oomAdj) { 1535 lastOomAdj = mi.oomAdj; 1536 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1537 tag.append(" / "); 1538 } 1539 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1540 if (firstLine) { 1541 stack.append(":"); 1542 firstLine = false; 1543 } 1544 stack.append("\n\t at "); 1545 } else { 1546 stack.append("$"); 1547 } 1548 } else { 1549 tag.append(" "); 1550 stack.append("$"); 1551 } 1552 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1553 appendMemBucket(tag, mi.pss, mi.name, false); 1554 } 1555 appendMemBucket(stack, mi.pss, mi.name, true); 1556 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1557 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1558 stack.append("("); 1559 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1560 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1561 stack.append(DUMP_MEM_OOM_LABEL[k]); 1562 stack.append(":"); 1563 stack.append(DUMP_MEM_OOM_ADJ[k]); 1564 } 1565 } 1566 stack.append(")"); 1567 } 1568 } 1569 1570 logBuilder.append(" "); 1571 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1572 logBuilder.append(' '); 1573 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1574 logBuilder.append(' '); 1575 ProcessList.appendRamKb(logBuilder, mi.pss); 1576 logBuilder.append(" kB: "); 1577 logBuilder.append(mi.name); 1578 logBuilder.append(" ("); 1579 logBuilder.append(mi.pid); 1580 logBuilder.append(") "); 1581 logBuilder.append(mi.adjType); 1582 logBuilder.append('\n'); 1583 if (mi.adjReason != null) { 1584 logBuilder.append(" "); 1585 logBuilder.append(mi.adjReason); 1586 logBuilder.append('\n'); 1587 } 1588 } 1589 1590 logBuilder.append(" "); 1591 ProcessList.appendRamKb(logBuilder, totalPss); 1592 logBuilder.append(" kB: TOTAL\n"); 1593 1594 long[] infos = new long[Debug.MEMINFO_COUNT]; 1595 Debug.getMemInfo(infos); 1596 logBuilder.append(" MemInfo: "); 1597 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1598 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1599 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1600 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1601 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1602 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1603 logBuilder.append(" ZRAM: "); 1604 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1605 logBuilder.append(" kB RAM, "); 1606 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1607 logBuilder.append(" kB swap total, "); 1608 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1609 logBuilder.append(" kB swap free\n"); 1610 } 1611 Slog.i(TAG, logBuilder.toString()); 1612 1613 StringBuilder dropBuilder = new StringBuilder(1024); 1614 /* 1615 StringWriter oomSw = new StringWriter(); 1616 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1617 StringWriter catSw = new StringWriter(); 1618 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1619 String[] emptyArgs = new String[] { }; 1620 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1621 oomPw.flush(); 1622 String oomString = oomSw.toString(); 1623 */ 1624 dropBuilder.append(stack); 1625 dropBuilder.append('\n'); 1626 dropBuilder.append('\n'); 1627 dropBuilder.append(logBuilder); 1628 dropBuilder.append('\n'); 1629 /* 1630 dropBuilder.append(oomString); 1631 dropBuilder.append('\n'); 1632 */ 1633 StringWriter catSw = new StringWriter(); 1634 synchronized (ActivityManagerService.this) { 1635 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1636 String[] emptyArgs = new String[] { }; 1637 catPw.println(); 1638 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1639 catPw.println(); 1640 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1641 false, false, null); 1642 catPw.println(); 1643 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1644 catPw.flush(); 1645 } 1646 dropBuilder.append(catSw.toString()); 1647 addErrorToDropBox("lowmem", null, "system_server", null, 1648 null, tag.toString(), dropBuilder.toString(), null, null); 1649 //Slog.i(TAG, "Sent to dropbox:"); 1650 //Slog.i(TAG, dropBuilder.toString()); 1651 synchronized (ActivityManagerService.this) { 1652 long now = SystemClock.uptimeMillis(); 1653 if (mLastMemUsageReportTime < now) { 1654 mLastMemUsageReportTime = now; 1655 } 1656 } 1657 } 1658 }; 1659 thread.start(); 1660 break; 1661 } 1662 case REPORT_USER_SWITCH_MSG: { 1663 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1664 break; 1665 } 1666 case CONTINUE_USER_SWITCH_MSG: { 1667 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1668 break; 1669 } 1670 case USER_SWITCH_TIMEOUT_MSG: { 1671 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1672 break; 1673 } 1674 case IMMERSIVE_MODE_LOCK_MSG: { 1675 final boolean nextState = (msg.arg1 != 0); 1676 if (mUpdateLock.isHeld() != nextState) { 1677 if (DEBUG_IMMERSIVE) { 1678 final ActivityRecord r = (ActivityRecord) msg.obj; 1679 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1680 } 1681 if (nextState) { 1682 mUpdateLock.acquire(); 1683 } else { 1684 mUpdateLock.release(); 1685 } 1686 } 1687 break; 1688 } 1689 case PERSIST_URI_GRANTS_MSG: { 1690 writeGrantedUriPermissions(); 1691 break; 1692 } 1693 case REQUEST_ALL_PSS_MSG: { 1694 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1695 break; 1696 } 1697 case START_PROFILES_MSG: { 1698 synchronized (ActivityManagerService.this) { 1699 startProfilesLocked(); 1700 } 1701 break; 1702 } 1703 case UPDATE_TIME: { 1704 synchronized (ActivityManagerService.this) { 1705 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1706 ProcessRecord r = mLruProcesses.get(i); 1707 if (r.thread != null) { 1708 try { 1709 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1710 } catch (RemoteException ex) { 1711 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1712 } 1713 } 1714 } 1715 } 1716 break; 1717 } 1718 } 1719 } 1720 }; 1721 1722 static final int COLLECT_PSS_BG_MSG = 1; 1723 1724 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1725 @Override 1726 public void handleMessage(Message msg) { 1727 switch (msg.what) { 1728 case COLLECT_PSS_BG_MSG: { 1729 int i=0, num=0; 1730 long start = SystemClock.uptimeMillis(); 1731 long[] tmp = new long[1]; 1732 do { 1733 ProcessRecord proc; 1734 int procState; 1735 int pid; 1736 synchronized (ActivityManagerService.this) { 1737 if (i >= mPendingPssProcesses.size()) { 1738 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1739 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1740 mPendingPssProcesses.clear(); 1741 return; 1742 } 1743 proc = mPendingPssProcesses.get(i); 1744 procState = proc.pssProcState; 1745 if (proc.thread != null && procState == proc.setProcState) { 1746 pid = proc.pid; 1747 } else { 1748 proc = null; 1749 pid = 0; 1750 } 1751 i++; 1752 } 1753 if (proc != null) { 1754 long pss = Debug.getPss(pid, tmp); 1755 synchronized (ActivityManagerService.this) { 1756 if (proc.thread != null && proc.setProcState == procState 1757 && proc.pid == pid) { 1758 num++; 1759 proc.lastPssTime = SystemClock.uptimeMillis(); 1760 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1761 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1762 + ": " + pss + " lastPss=" + proc.lastPss 1763 + " state=" + ProcessList.makeProcStateString(procState)); 1764 if (proc.initialIdlePss == 0) { 1765 proc.initialIdlePss = pss; 1766 } 1767 proc.lastPss = pss; 1768 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1769 proc.lastCachedPss = pss; 1770 } 1771 } 1772 } 1773 } 1774 } while (true); 1775 } 1776 } 1777 } 1778 }; 1779 1780 public void setSystemProcess() { 1781 try { 1782 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1783 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1784 ServiceManager.addService("meminfo", new MemBinder(this)); 1785 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1786 ServiceManager.addService("dbinfo", new DbBinder(this)); 1787 if (MONITOR_CPU_USAGE) { 1788 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1789 } 1790 ServiceManager.addService("permission", new PermissionController(this)); 1791 1792 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1793 "android", STOCK_PM_FLAGS); 1794 mSystemThread.installSystemApplicationInfo(info); 1795 1796 synchronized (this) { 1797 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1798 app.persistent = true; 1799 app.pid = MY_PID; 1800 app.maxAdj = ProcessList.SYSTEM_ADJ; 1801 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1802 mProcessNames.put(app.processName, app.uid, app); 1803 synchronized (mPidsSelfLocked) { 1804 mPidsSelfLocked.put(app.pid, app); 1805 } 1806 updateLruProcessLocked(app, false, null); 1807 updateOomAdjLocked(); 1808 } 1809 } catch (PackageManager.NameNotFoundException e) { 1810 throw new RuntimeException( 1811 "Unable to find android system package", e); 1812 } 1813 } 1814 1815 public void setWindowManager(WindowManagerService wm) { 1816 mWindowManager = wm; 1817 mStackSupervisor.setWindowManager(wm); 1818 } 1819 1820 public void startObservingNativeCrashes() { 1821 final NativeCrashListener ncl = new NativeCrashListener(this); 1822 ncl.start(); 1823 } 1824 1825 public IAppOpsService getAppOpsService() { 1826 return mAppOpsService; 1827 } 1828 1829 static class MemBinder extends Binder { 1830 ActivityManagerService mActivityManagerService; 1831 MemBinder(ActivityManagerService activityManagerService) { 1832 mActivityManagerService = activityManagerService; 1833 } 1834 1835 @Override 1836 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1837 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1838 != PackageManager.PERMISSION_GRANTED) { 1839 pw.println("Permission Denial: can't dump meminfo from from pid=" 1840 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1841 + " without permission " + android.Manifest.permission.DUMP); 1842 return; 1843 } 1844 1845 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1846 } 1847 } 1848 1849 static class GraphicsBinder extends Binder { 1850 ActivityManagerService mActivityManagerService; 1851 GraphicsBinder(ActivityManagerService activityManagerService) { 1852 mActivityManagerService = activityManagerService; 1853 } 1854 1855 @Override 1856 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1857 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1858 != PackageManager.PERMISSION_GRANTED) { 1859 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1860 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1861 + " without permission " + android.Manifest.permission.DUMP); 1862 return; 1863 } 1864 1865 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1866 } 1867 } 1868 1869 static class DbBinder extends Binder { 1870 ActivityManagerService mActivityManagerService; 1871 DbBinder(ActivityManagerService activityManagerService) { 1872 mActivityManagerService = activityManagerService; 1873 } 1874 1875 @Override 1876 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1877 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1878 != PackageManager.PERMISSION_GRANTED) { 1879 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1880 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1881 + " without permission " + android.Manifest.permission.DUMP); 1882 return; 1883 } 1884 1885 mActivityManagerService.dumpDbInfo(fd, pw, args); 1886 } 1887 } 1888 1889 static class CpuBinder extends Binder { 1890 ActivityManagerService mActivityManagerService; 1891 CpuBinder(ActivityManagerService activityManagerService) { 1892 mActivityManagerService = activityManagerService; 1893 } 1894 1895 @Override 1896 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1897 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1898 != PackageManager.PERMISSION_GRANTED) { 1899 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1900 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1901 + " without permission " + android.Manifest.permission.DUMP); 1902 return; 1903 } 1904 1905 synchronized (mActivityManagerService.mProcessCpuThread) { 1906 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1907 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1908 SystemClock.uptimeMillis())); 1909 } 1910 } 1911 } 1912 1913 public static final class Lifecycle extends SystemService { 1914 private final ActivityManagerService mService; 1915 1916 public Lifecycle(Context context) { 1917 super(context); 1918 mService = new ActivityManagerService(context); 1919 } 1920 1921 @Override 1922 public void onStart() { 1923 mService.start(); 1924 } 1925 1926 public ActivityManagerService getService() { 1927 return mService; 1928 } 1929 } 1930 1931 // Note: This method is invoked on the main thread but may need to attach various 1932 // handlers to other threads. So take care to be explicit about the looper. 1933 public ActivityManagerService(Context systemContext) { 1934 mContext = systemContext; 1935 mFactoryTest = FactoryTest.getMode(); 1936 mSystemThread = ActivityThread.currentActivityThread(); 1937 1938 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1939 1940 mHandlerThread = new ServiceThread(TAG, 1941 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1942 mHandlerThread.start(); 1943 mHandler = new MainHandler(mHandlerThread.getLooper()); 1944 1945 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1946 "foreground", BROADCAST_FG_TIMEOUT, false); 1947 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1948 "background", BROADCAST_BG_TIMEOUT, true); 1949 mBroadcastQueues[0] = mFgBroadcastQueue; 1950 mBroadcastQueues[1] = mBgBroadcastQueue; 1951 1952 mServices = new ActiveServices(this); 1953 mProviderMap = new ProviderMap(this); 1954 1955 // TODO: Move creation of battery stats service outside of activity manager service. 1956 File dataDir = Environment.getDataDirectory(); 1957 File systemDir = new File(dataDir, "system"); 1958 systemDir.mkdirs(); 1959 mBatteryStatsService = new BatteryStatsService(new File( 1960 systemDir, "batterystats.bin").toString(), mHandler); 1961 mBatteryStatsService.getActiveStatistics().readLocked(); 1962 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1963 mOnBattery = DEBUG_POWER ? true 1964 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1965 mBatteryStatsService.getActiveStatistics().setCallback(this); 1966 1967 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1968 1969 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1970 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1971 1972 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1973 1974 // User 0 is the first and only user that runs at boot. 1975 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1976 mUserLru.add(Integer.valueOf(0)); 1977 updateStartedUserArrayLocked(); 1978 1979 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1980 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1981 1982 mConfiguration.setToDefaults(); 1983 mConfiguration.setLocale(Locale.getDefault()); 1984 1985 mConfigurationSeq = mConfiguration.seq = 1; 1986 mProcessCpuTracker.init(); 1987 1988 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1989 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1990 mStackSupervisor = new ActivityStackSupervisor(this); 1991 1992 mProcessCpuThread = new Thread("CpuTracker") { 1993 @Override 1994 public void run() { 1995 while (true) { 1996 try { 1997 try { 1998 synchronized(this) { 1999 final long now = SystemClock.uptimeMillis(); 2000 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2001 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2002 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2003 // + ", write delay=" + nextWriteDelay); 2004 if (nextWriteDelay < nextCpuDelay) { 2005 nextCpuDelay = nextWriteDelay; 2006 } 2007 if (nextCpuDelay > 0) { 2008 mProcessCpuMutexFree.set(true); 2009 this.wait(nextCpuDelay); 2010 } 2011 } 2012 } catch (InterruptedException e) { 2013 } 2014 updateCpuStatsNow(); 2015 } catch (Exception e) { 2016 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2017 } 2018 } 2019 } 2020 }; 2021 2022 Watchdog.getInstance().addMonitor(this); 2023 Watchdog.getInstance().addThread(mHandler); 2024 } 2025 2026 private void start() { 2027 mProcessCpuThread.start(); 2028 2029 mBatteryStatsService.publish(mContext); 2030 mUsageStatsService.publish(mContext); 2031 mAppOpsService.publish(mContext); 2032 2033 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2034 } 2035 2036 @Override 2037 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2038 throws RemoteException { 2039 if (code == SYSPROPS_TRANSACTION) { 2040 // We need to tell all apps about the system property change. 2041 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2042 synchronized(this) { 2043 final int NP = mProcessNames.getMap().size(); 2044 for (int ip=0; ip<NP; ip++) { 2045 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2046 final int NA = apps.size(); 2047 for (int ia=0; ia<NA; ia++) { 2048 ProcessRecord app = apps.valueAt(ia); 2049 if (app.thread != null) { 2050 procs.add(app.thread.asBinder()); 2051 } 2052 } 2053 } 2054 } 2055 2056 int N = procs.size(); 2057 for (int i=0; i<N; i++) { 2058 Parcel data2 = Parcel.obtain(); 2059 try { 2060 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2061 } catch (RemoteException e) { 2062 } 2063 data2.recycle(); 2064 } 2065 } 2066 try { 2067 return super.onTransact(code, data, reply, flags); 2068 } catch (RuntimeException e) { 2069 // The activity manager only throws security exceptions, so let's 2070 // log all others. 2071 if (!(e instanceof SecurityException)) { 2072 Slog.wtf(TAG, "Activity Manager Crash", e); 2073 } 2074 throw e; 2075 } 2076 } 2077 2078 void updateCpuStats() { 2079 final long now = SystemClock.uptimeMillis(); 2080 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2081 return; 2082 } 2083 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2084 synchronized (mProcessCpuThread) { 2085 mProcessCpuThread.notify(); 2086 } 2087 } 2088 } 2089 2090 void updateCpuStatsNow() { 2091 synchronized (mProcessCpuThread) { 2092 mProcessCpuMutexFree.set(false); 2093 final long now = SystemClock.uptimeMillis(); 2094 boolean haveNewCpuStats = false; 2095 2096 if (MONITOR_CPU_USAGE && 2097 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2098 mLastCpuTime.set(now); 2099 haveNewCpuStats = true; 2100 mProcessCpuTracker.update(); 2101 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2102 //Slog.i(TAG, "Total CPU usage: " 2103 // + mProcessCpu.getTotalCpuPercent() + "%"); 2104 2105 // Slog the cpu usage if the property is set. 2106 if ("true".equals(SystemProperties.get("events.cpu"))) { 2107 int user = mProcessCpuTracker.getLastUserTime(); 2108 int system = mProcessCpuTracker.getLastSystemTime(); 2109 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2110 int irq = mProcessCpuTracker.getLastIrqTime(); 2111 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2112 int idle = mProcessCpuTracker.getLastIdleTime(); 2113 2114 int total = user + system + iowait + irq + softIrq + idle; 2115 if (total == 0) total = 1; 2116 2117 EventLog.writeEvent(EventLogTags.CPU, 2118 ((user+system+iowait+irq+softIrq) * 100) / total, 2119 (user * 100) / total, 2120 (system * 100) / total, 2121 (iowait * 100) / total, 2122 (irq * 100) / total, 2123 (softIrq * 100) / total); 2124 } 2125 } 2126 2127 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2128 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2129 synchronized(bstats) { 2130 synchronized(mPidsSelfLocked) { 2131 if (haveNewCpuStats) { 2132 if (mOnBattery) { 2133 int perc = bstats.startAddingCpuLocked(); 2134 int totalUTime = 0; 2135 int totalSTime = 0; 2136 final int N = mProcessCpuTracker.countStats(); 2137 for (int i=0; i<N; i++) { 2138 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2139 if (!st.working) { 2140 continue; 2141 } 2142 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2143 int otherUTime = (st.rel_utime*perc)/100; 2144 int otherSTime = (st.rel_stime*perc)/100; 2145 totalUTime += otherUTime; 2146 totalSTime += otherSTime; 2147 if (pr != null) { 2148 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2149 if (ps == null || !ps.isActive()) { 2150 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2151 pr.info.uid, pr.processName); 2152 } 2153 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2154 st.rel_stime-otherSTime); 2155 ps.addSpeedStepTimes(cpuSpeedTimes); 2156 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2157 } else { 2158 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2159 if (ps == null || !ps.isActive()) { 2160 st.batteryStats = ps = bstats.getProcessStatsLocked( 2161 bstats.mapUid(st.uid), st.name); 2162 } 2163 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2164 st.rel_stime-otherSTime); 2165 ps.addSpeedStepTimes(cpuSpeedTimes); 2166 } 2167 } 2168 bstats.finishAddingCpuLocked(perc, totalUTime, 2169 totalSTime, cpuSpeedTimes); 2170 } 2171 } 2172 } 2173 2174 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2175 mLastWriteTime = now; 2176 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2177 } 2178 } 2179 } 2180 } 2181 2182 @Override 2183 public void batteryNeedsCpuUpdate() { 2184 updateCpuStatsNow(); 2185 } 2186 2187 @Override 2188 public void batteryPowerChanged(boolean onBattery) { 2189 // When plugging in, update the CPU stats first before changing 2190 // the plug state. 2191 updateCpuStatsNow(); 2192 synchronized (this) { 2193 synchronized(mPidsSelfLocked) { 2194 mOnBattery = DEBUG_POWER ? true : onBattery; 2195 } 2196 } 2197 } 2198 2199 /** 2200 * Initialize the application bind args. These are passed to each 2201 * process when the bindApplication() IPC is sent to the process. They're 2202 * lazily setup to make sure the services are running when they're asked for. 2203 */ 2204 private HashMap<String, IBinder> getCommonServicesLocked() { 2205 if (mAppBindArgs == null) { 2206 mAppBindArgs = new HashMap<String, IBinder>(); 2207 2208 // Setup the application init args 2209 mAppBindArgs.put("package", ServiceManager.getService("package")); 2210 mAppBindArgs.put("window", ServiceManager.getService("window")); 2211 mAppBindArgs.put(Context.ALARM_SERVICE, 2212 ServiceManager.getService(Context.ALARM_SERVICE)); 2213 } 2214 return mAppBindArgs; 2215 } 2216 2217 final void setFocusedActivityLocked(ActivityRecord r) { 2218 if (mFocusedActivity != r) { 2219 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2220 mFocusedActivity = r; 2221 mStackSupervisor.setFocusedStack(r); 2222 if (r != null) { 2223 mWindowManager.setFocusedApp(r.appToken, true); 2224 } 2225 applyUpdateLockStateLocked(r); 2226 } 2227 } 2228 2229 @Override 2230 public void setFocusedStack(int stackId) { 2231 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2232 synchronized (ActivityManagerService.this) { 2233 ActivityStack stack = mStackSupervisor.getStack(stackId); 2234 if (stack != null) { 2235 ActivityRecord r = stack.topRunningActivityLocked(null); 2236 if (r != null) { 2237 setFocusedActivityLocked(r); 2238 } 2239 } 2240 } 2241 } 2242 2243 @Override 2244 public void notifyActivityDrawn(IBinder token) { 2245 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2246 synchronized (this) { 2247 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2248 if (r != null) { 2249 r.task.stack.notifyActivityDrawnLocked(r); 2250 } 2251 } 2252 } 2253 2254 final void applyUpdateLockStateLocked(ActivityRecord r) { 2255 // Modifications to the UpdateLock state are done on our handler, outside 2256 // the activity manager's locks. The new state is determined based on the 2257 // state *now* of the relevant activity record. The object is passed to 2258 // the handler solely for logging detail, not to be consulted/modified. 2259 final boolean nextState = r != null && r.immersive; 2260 mHandler.sendMessage( 2261 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2262 } 2263 2264 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2265 Message msg = Message.obtain(); 2266 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2267 msg.obj = r.task.askedCompatMode ? null : r; 2268 mHandler.sendMessage(msg); 2269 } 2270 2271 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2272 String what, Object obj, ProcessRecord srcApp) { 2273 app.lastActivityTime = now; 2274 2275 if (app.activities.size() > 0) { 2276 // Don't want to touch dependent processes that are hosting activities. 2277 return index; 2278 } 2279 2280 int lrui = mLruProcesses.lastIndexOf(app); 2281 if (lrui < 0) { 2282 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2283 + what + " " + obj + " from " + srcApp); 2284 return index; 2285 } 2286 2287 if (lrui >= index) { 2288 // Don't want to cause this to move dependent processes *back* in the 2289 // list as if they were less frequently used. 2290 return index; 2291 } 2292 2293 if (lrui >= mLruProcessActivityStart) { 2294 // Don't want to touch dependent processes that are hosting activities. 2295 return index; 2296 } 2297 2298 mLruProcesses.remove(lrui); 2299 if (index > 0) { 2300 index--; 2301 } 2302 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2303 + " in LRU list: " + app); 2304 mLruProcesses.add(index, app); 2305 return index; 2306 } 2307 2308 final void removeLruProcessLocked(ProcessRecord app) { 2309 int lrui = mLruProcesses.lastIndexOf(app); 2310 if (lrui >= 0) { 2311 if (lrui <= mLruProcessActivityStart) { 2312 mLruProcessActivityStart--; 2313 } 2314 if (lrui <= mLruProcessServiceStart) { 2315 mLruProcessServiceStart--; 2316 } 2317 mLruProcesses.remove(lrui); 2318 } 2319 } 2320 2321 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2322 ProcessRecord client) { 2323 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2324 || app.treatLikeActivity; 2325 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2326 if (!activityChange && hasActivity) { 2327 // The process has activities, so we are only allowing activity-based adjustments 2328 // to move it. It should be kept in the front of the list with other 2329 // processes that have activities, and we don't want those to change their 2330 // order except due to activity operations. 2331 return; 2332 } 2333 2334 mLruSeq++; 2335 final long now = SystemClock.uptimeMillis(); 2336 app.lastActivityTime = now; 2337 2338 // First a quick reject: if the app is already at the position we will 2339 // put it, then there is nothing to do. 2340 if (hasActivity) { 2341 final int N = mLruProcesses.size(); 2342 if (N > 0 && mLruProcesses.get(N-1) == app) { 2343 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2344 return; 2345 } 2346 } else { 2347 if (mLruProcessServiceStart > 0 2348 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2349 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2350 return; 2351 } 2352 } 2353 2354 int lrui = mLruProcesses.lastIndexOf(app); 2355 2356 if (app.persistent && lrui >= 0) { 2357 // We don't care about the position of persistent processes, as long as 2358 // they are in the list. 2359 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2360 return; 2361 } 2362 2363 /* In progress: compute new position first, so we can avoid doing work 2364 if the process is not actually going to move. Not yet working. 2365 int addIndex; 2366 int nextIndex; 2367 boolean inActivity = false, inService = false; 2368 if (hasActivity) { 2369 // Process has activities, put it at the very tipsy-top. 2370 addIndex = mLruProcesses.size(); 2371 nextIndex = mLruProcessServiceStart; 2372 inActivity = true; 2373 } else if (hasService) { 2374 // Process has services, put it at the top of the service list. 2375 addIndex = mLruProcessActivityStart; 2376 nextIndex = mLruProcessServiceStart; 2377 inActivity = true; 2378 inService = true; 2379 } else { 2380 // Process not otherwise of interest, it goes to the top of the non-service area. 2381 addIndex = mLruProcessServiceStart; 2382 if (client != null) { 2383 int clientIndex = mLruProcesses.lastIndexOf(client); 2384 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2385 + app); 2386 if (clientIndex >= 0 && addIndex > clientIndex) { 2387 addIndex = clientIndex; 2388 } 2389 } 2390 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2391 } 2392 2393 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2394 + mLruProcessActivityStart + "): " + app); 2395 */ 2396 2397 if (lrui >= 0) { 2398 if (lrui < mLruProcessActivityStart) { 2399 mLruProcessActivityStart--; 2400 } 2401 if (lrui < mLruProcessServiceStart) { 2402 mLruProcessServiceStart--; 2403 } 2404 /* 2405 if (addIndex > lrui) { 2406 addIndex--; 2407 } 2408 if (nextIndex > lrui) { 2409 nextIndex--; 2410 } 2411 */ 2412 mLruProcesses.remove(lrui); 2413 } 2414 2415 /* 2416 mLruProcesses.add(addIndex, app); 2417 if (inActivity) { 2418 mLruProcessActivityStart++; 2419 } 2420 if (inService) { 2421 mLruProcessActivityStart++; 2422 } 2423 */ 2424 2425 int nextIndex; 2426 if (hasActivity) { 2427 final int N = mLruProcesses.size(); 2428 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2429 // Process doesn't have activities, but has clients with 2430 // activities... move it up, but one below the top (the top 2431 // should always have a real activity). 2432 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2433 mLruProcesses.add(N-1, app); 2434 // To keep it from spamming the LRU list (by making a bunch of clients), 2435 // we will push down any other entries owned by the app. 2436 final int uid = app.info.uid; 2437 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2438 ProcessRecord subProc = mLruProcesses.get(i); 2439 if (subProc.info.uid == uid) { 2440 // We want to push this one down the list. If the process after 2441 // it is for the same uid, however, don't do so, because we don't 2442 // want them internally to be re-ordered. 2443 if (mLruProcesses.get(i-1).info.uid != uid) { 2444 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2445 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2446 ProcessRecord tmp = mLruProcesses.get(i); 2447 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2448 mLruProcesses.set(i-1, tmp); 2449 i--; 2450 } 2451 } else { 2452 // A gap, we can stop here. 2453 break; 2454 } 2455 } 2456 } else { 2457 // Process has activities, put it at the very tipsy-top. 2458 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2459 mLruProcesses.add(app); 2460 } 2461 nextIndex = mLruProcessServiceStart; 2462 } else if (hasService) { 2463 // Process has services, put it at the top of the service list. 2464 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2465 mLruProcesses.add(mLruProcessActivityStart, app); 2466 nextIndex = mLruProcessServiceStart; 2467 mLruProcessActivityStart++; 2468 } else { 2469 // Process not otherwise of interest, it goes to the top of the non-service area. 2470 int index = mLruProcessServiceStart; 2471 if (client != null) { 2472 // If there is a client, don't allow the process to be moved up higher 2473 // in the list than that client. 2474 int clientIndex = mLruProcesses.lastIndexOf(client); 2475 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2476 + " when updating " + app); 2477 if (clientIndex <= lrui) { 2478 // Don't allow the client index restriction to push it down farther in the 2479 // list than it already is. 2480 clientIndex = lrui; 2481 } 2482 if (clientIndex >= 0 && index > clientIndex) { 2483 index = clientIndex; 2484 } 2485 } 2486 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2487 mLruProcesses.add(index, app); 2488 nextIndex = index-1; 2489 mLruProcessActivityStart++; 2490 mLruProcessServiceStart++; 2491 } 2492 2493 // If the app is currently using a content provider or service, 2494 // bump those processes as well. 2495 for (int j=app.connections.size()-1; j>=0; j--) { 2496 ConnectionRecord cr = app.connections.valueAt(j); 2497 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2498 && cr.binding.service.app != null 2499 && cr.binding.service.app.lruSeq != mLruSeq 2500 && !cr.binding.service.app.persistent) { 2501 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2502 "service connection", cr, app); 2503 } 2504 } 2505 for (int j=app.conProviders.size()-1; j>=0; j--) { 2506 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2507 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2508 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2509 "provider reference", cpr, app); 2510 } 2511 } 2512 } 2513 2514 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2515 if (uid == Process.SYSTEM_UID) { 2516 // The system gets to run in any process. If there are multiple 2517 // processes with the same uid, just pick the first (this 2518 // should never happen). 2519 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2520 if (procs == null) return null; 2521 final int N = procs.size(); 2522 for (int i = 0; i < N; i++) { 2523 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2524 } 2525 } 2526 ProcessRecord proc = mProcessNames.get(processName, uid); 2527 if (false && proc != null && !keepIfLarge 2528 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2529 && proc.lastCachedPss >= 4000) { 2530 // Turn this condition on to cause killing to happen regularly, for testing. 2531 if (proc.baseProcessTracker != null) { 2532 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2533 } 2534 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2535 + "k from cached"); 2536 } else if (proc != null && !keepIfLarge 2537 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2538 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2539 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2540 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2541 if (proc.baseProcessTracker != null) { 2542 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2543 } 2544 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2545 + "k from cached"); 2546 } 2547 } 2548 return proc; 2549 } 2550 2551 void ensurePackageDexOpt(String packageName) { 2552 IPackageManager pm = AppGlobals.getPackageManager(); 2553 try { 2554 if (pm.performDexOpt(packageName)) { 2555 mDidDexOpt = true; 2556 } 2557 } catch (RemoteException e) { 2558 } 2559 } 2560 2561 boolean isNextTransitionForward() { 2562 int transit = mWindowManager.getPendingAppTransition(); 2563 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2564 || transit == AppTransition.TRANSIT_TASK_OPEN 2565 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2566 } 2567 2568 final ProcessRecord startProcessLocked(String processName, 2569 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2570 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2571 boolean isolated, boolean keepIfLarge) { 2572 ProcessRecord app; 2573 if (!isolated) { 2574 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2575 } else { 2576 // If this is an isolated process, it can't re-use an existing process. 2577 app = null; 2578 } 2579 // We don't have to do anything more if: 2580 // (1) There is an existing application record; and 2581 // (2) The caller doesn't think it is dead, OR there is no thread 2582 // object attached to it so we know it couldn't have crashed; and 2583 // (3) There is a pid assigned to it, so it is either starting or 2584 // already running. 2585 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2586 + " app=" + app + " knownToBeDead=" + knownToBeDead 2587 + " thread=" + (app != null ? app.thread : null) 2588 + " pid=" + (app != null ? app.pid : -1)); 2589 if (app != null && app.pid > 0) { 2590 if (!knownToBeDead || app.thread == null) { 2591 // We already have the app running, or are waiting for it to 2592 // come up (we have a pid but not yet its thread), so keep it. 2593 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2594 // If this is a new package in the process, add the package to the list 2595 app.addPackage(info.packageName, mProcessStats); 2596 return app; 2597 } 2598 2599 // An application record is attached to a previous process, 2600 // clean it up now. 2601 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2602 handleAppDiedLocked(app, true, true); 2603 } 2604 2605 String hostingNameStr = hostingName != null 2606 ? hostingName.flattenToShortString() : null; 2607 2608 if (!isolated) { 2609 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2610 // If we are in the background, then check to see if this process 2611 // is bad. If so, we will just silently fail. 2612 if (mBadProcesses.get(info.processName, info.uid) != null) { 2613 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2614 + "/" + info.processName); 2615 return null; 2616 } 2617 } else { 2618 // When the user is explicitly starting a process, then clear its 2619 // crash count so that we won't make it bad until they see at 2620 // least one crash dialog again, and make the process good again 2621 // if it had been bad. 2622 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2623 + "/" + info.processName); 2624 mProcessCrashTimes.remove(info.processName, info.uid); 2625 if (mBadProcesses.get(info.processName, info.uid) != null) { 2626 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2627 UserHandle.getUserId(info.uid), info.uid, 2628 info.processName); 2629 mBadProcesses.remove(info.processName, info.uid); 2630 if (app != null) { 2631 app.bad = false; 2632 } 2633 } 2634 } 2635 } 2636 2637 if (app == null) { 2638 app = newProcessRecordLocked(info, processName, isolated); 2639 if (app == null) { 2640 Slog.w(TAG, "Failed making new process record for " 2641 + processName + "/" + info.uid + " isolated=" + isolated); 2642 return null; 2643 } 2644 mProcessNames.put(processName, app.uid, app); 2645 if (isolated) { 2646 mIsolatedProcesses.put(app.uid, app); 2647 } 2648 } else { 2649 // If this is a new package in the process, add the package to the list 2650 app.addPackage(info.packageName, mProcessStats); 2651 } 2652 2653 // If the system is not ready yet, then hold off on starting this 2654 // process until it is. 2655 if (!mProcessesReady 2656 && !isAllowedWhileBooting(info) 2657 && !allowWhileBooting) { 2658 if (!mProcessesOnHold.contains(app)) { 2659 mProcessesOnHold.add(app); 2660 } 2661 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2662 return app; 2663 } 2664 2665 startProcessLocked(app, hostingType, hostingNameStr); 2666 return (app.pid != 0) ? app : null; 2667 } 2668 2669 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2670 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2671 } 2672 2673 private final void startProcessLocked(ProcessRecord app, 2674 String hostingType, String hostingNameStr) { 2675 if (app.pid > 0 && app.pid != MY_PID) { 2676 synchronized (mPidsSelfLocked) { 2677 mPidsSelfLocked.remove(app.pid); 2678 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2679 } 2680 app.setPid(0); 2681 } 2682 2683 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2684 "startProcessLocked removing on hold: " + app); 2685 mProcessesOnHold.remove(app); 2686 2687 updateCpuStats(); 2688 2689 try { 2690 int uid = app.uid; 2691 2692 int[] gids = null; 2693 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2694 if (!app.isolated) { 2695 int[] permGids = null; 2696 try { 2697 final PackageManager pm = mContext.getPackageManager(); 2698 permGids = pm.getPackageGids(app.info.packageName); 2699 2700 if (Environment.isExternalStorageEmulated()) { 2701 if (pm.checkPermission( 2702 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2703 app.info.packageName) == PERMISSION_GRANTED) { 2704 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2705 } else { 2706 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2707 } 2708 } 2709 } catch (PackageManager.NameNotFoundException e) { 2710 Slog.w(TAG, "Unable to retrieve gids", e); 2711 } 2712 2713 /* 2714 * Add shared application GID so applications can share some 2715 * resources like shared libraries 2716 */ 2717 if (permGids == null) { 2718 gids = new int[1]; 2719 } else { 2720 gids = new int[permGids.length + 1]; 2721 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2722 } 2723 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2724 } 2725 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2726 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2727 && mTopComponent != null 2728 && app.processName.equals(mTopComponent.getPackageName())) { 2729 uid = 0; 2730 } 2731 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2732 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2733 uid = 0; 2734 } 2735 } 2736 int debugFlags = 0; 2737 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2738 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2739 // Also turn on CheckJNI for debuggable apps. It's quite 2740 // awkward to turn on otherwise. 2741 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2742 } 2743 // Run the app in safe mode if its manifest requests so or the 2744 // system is booted in safe mode. 2745 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2746 mSafeMode == true) { 2747 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2748 } 2749 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2750 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2751 } 2752 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2753 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2754 } 2755 if ("1".equals(SystemProperties.get("debug.assert"))) { 2756 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2757 } 2758 2759 String requiredAbi = app.info.requiredCpuAbi; 2760 if (requiredAbi == null) { 2761 requiredAbi = Build.SUPPORTED_ABIS[0]; 2762 } 2763 2764 // Start the process. It will either succeed and return a result containing 2765 // the PID of the new process, or else throw a RuntimeException. 2766 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2767 app.processName, uid, uid, gids, debugFlags, mountExternal, 2768 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2769 2770 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2771 synchronized (bs) { 2772 if (bs.isOnBattery()) { 2773 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2774 } 2775 } 2776 2777 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2778 UserHandle.getUserId(uid), startResult.pid, uid, 2779 app.processName, hostingType, 2780 hostingNameStr != null ? hostingNameStr : ""); 2781 2782 if (app.persistent) { 2783 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2784 } 2785 2786 StringBuilder buf = mStringBuilder; 2787 buf.setLength(0); 2788 buf.append("Start proc "); 2789 buf.append(app.processName); 2790 buf.append(" for "); 2791 buf.append(hostingType); 2792 if (hostingNameStr != null) { 2793 buf.append(" "); 2794 buf.append(hostingNameStr); 2795 } 2796 buf.append(": pid="); 2797 buf.append(startResult.pid); 2798 buf.append(" uid="); 2799 buf.append(uid); 2800 buf.append(" gids={"); 2801 if (gids != null) { 2802 for (int gi=0; gi<gids.length; gi++) { 2803 if (gi != 0) buf.append(", "); 2804 buf.append(gids[gi]); 2805 2806 } 2807 } 2808 buf.append("}"); 2809 Slog.i(TAG, buf.toString()); 2810 app.setPid(startResult.pid); 2811 app.usingWrapper = startResult.usingWrapper; 2812 app.removed = false; 2813 synchronized (mPidsSelfLocked) { 2814 this.mPidsSelfLocked.put(startResult.pid, app); 2815 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2816 msg.obj = app; 2817 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2818 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2819 } 2820 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2821 app.processName, app.info.uid); 2822 if (app.isolated) { 2823 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2824 } 2825 } catch (RuntimeException e) { 2826 // XXX do better error recovery. 2827 app.setPid(0); 2828 Slog.e(TAG, "Failure starting process " + app.processName, e); 2829 } 2830 } 2831 2832 void updateUsageStats(ActivityRecord component, boolean resumed) { 2833 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2834 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2835 if (resumed) { 2836 mUsageStatsService.noteResumeComponent(component.realActivity); 2837 synchronized (stats) { 2838 stats.noteActivityResumedLocked(component.app.uid); 2839 } 2840 } else { 2841 mUsageStatsService.notePauseComponent(component.realActivity); 2842 synchronized (stats) { 2843 stats.noteActivityPausedLocked(component.app.uid); 2844 } 2845 } 2846 } 2847 2848 Intent getHomeIntent() { 2849 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2850 intent.setComponent(mTopComponent); 2851 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2852 intent.addCategory(Intent.CATEGORY_HOME); 2853 } 2854 return intent; 2855 } 2856 2857 boolean startHomeActivityLocked(int userId) { 2858 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2859 && mTopAction == null) { 2860 // We are running in factory test mode, but unable to find 2861 // the factory test app, so just sit around displaying the 2862 // error message and don't try to start anything. 2863 return false; 2864 } 2865 Intent intent = getHomeIntent(); 2866 ActivityInfo aInfo = 2867 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2868 if (aInfo != null) { 2869 intent.setComponent(new ComponentName( 2870 aInfo.applicationInfo.packageName, aInfo.name)); 2871 // Don't do this if the home app is currently being 2872 // instrumented. 2873 aInfo = new ActivityInfo(aInfo); 2874 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2875 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2876 aInfo.applicationInfo.uid, true); 2877 if (app == null || app.instrumentationClass == null) { 2878 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2879 mStackSupervisor.startHomeActivity(intent, aInfo); 2880 } 2881 } 2882 2883 return true; 2884 } 2885 2886 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2887 ActivityInfo ai = null; 2888 ComponentName comp = intent.getComponent(); 2889 try { 2890 if (comp != null) { 2891 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2892 } else { 2893 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2894 intent, 2895 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2896 flags, userId); 2897 2898 if (info != null) { 2899 ai = info.activityInfo; 2900 } 2901 } 2902 } catch (RemoteException e) { 2903 // ignore 2904 } 2905 2906 return ai; 2907 } 2908 2909 /** 2910 * Starts the "new version setup screen" if appropriate. 2911 */ 2912 void startSetupActivityLocked() { 2913 // Only do this once per boot. 2914 if (mCheckedForSetup) { 2915 return; 2916 } 2917 2918 // We will show this screen if the current one is a different 2919 // version than the last one shown, and we are not running in 2920 // low-level factory test mode. 2921 final ContentResolver resolver = mContext.getContentResolver(); 2922 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2923 Settings.Global.getInt(resolver, 2924 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2925 mCheckedForSetup = true; 2926 2927 // See if we should be showing the platform update setup UI. 2928 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2929 List<ResolveInfo> ris = mContext.getPackageManager() 2930 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2931 2932 // We don't allow third party apps to replace this. 2933 ResolveInfo ri = null; 2934 for (int i=0; ris != null && i<ris.size(); i++) { 2935 if ((ris.get(i).activityInfo.applicationInfo.flags 2936 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2937 ri = ris.get(i); 2938 break; 2939 } 2940 } 2941 2942 if (ri != null) { 2943 String vers = ri.activityInfo.metaData != null 2944 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2945 : null; 2946 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2947 vers = ri.activityInfo.applicationInfo.metaData.getString( 2948 Intent.METADATA_SETUP_VERSION); 2949 } 2950 String lastVers = Settings.Secure.getString( 2951 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2952 if (vers != null && !vers.equals(lastVers)) { 2953 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2954 intent.setComponent(new ComponentName( 2955 ri.activityInfo.packageName, ri.activityInfo.name)); 2956 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2957 null, null, 0, 0, 0, null, 0, null, false, null, null); 2958 } 2959 } 2960 } 2961 } 2962 2963 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2964 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2965 } 2966 2967 void enforceNotIsolatedCaller(String caller) { 2968 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2969 throw new SecurityException("Isolated process not allowed to call " + caller); 2970 } 2971 } 2972 2973 @Override 2974 public int getFrontActivityScreenCompatMode() { 2975 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2976 synchronized (this) { 2977 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2978 } 2979 } 2980 2981 @Override 2982 public void setFrontActivityScreenCompatMode(int mode) { 2983 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2984 "setFrontActivityScreenCompatMode"); 2985 synchronized (this) { 2986 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2987 } 2988 } 2989 2990 @Override 2991 public int getPackageScreenCompatMode(String packageName) { 2992 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2993 synchronized (this) { 2994 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2995 } 2996 } 2997 2998 @Override 2999 public void setPackageScreenCompatMode(String packageName, int mode) { 3000 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3001 "setPackageScreenCompatMode"); 3002 synchronized (this) { 3003 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3004 } 3005 } 3006 3007 @Override 3008 public boolean getPackageAskScreenCompat(String packageName) { 3009 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3010 synchronized (this) { 3011 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3012 } 3013 } 3014 3015 @Override 3016 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3017 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3018 "setPackageAskScreenCompat"); 3019 synchronized (this) { 3020 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3021 } 3022 } 3023 3024 private void dispatchProcessesChanged() { 3025 int N; 3026 synchronized (this) { 3027 N = mPendingProcessChanges.size(); 3028 if (mActiveProcessChanges.length < N) { 3029 mActiveProcessChanges = new ProcessChangeItem[N]; 3030 } 3031 mPendingProcessChanges.toArray(mActiveProcessChanges); 3032 mAvailProcessChanges.addAll(mPendingProcessChanges); 3033 mPendingProcessChanges.clear(); 3034 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3035 } 3036 3037 int i = mProcessObservers.beginBroadcast(); 3038 while (i > 0) { 3039 i--; 3040 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3041 if (observer != null) { 3042 try { 3043 for (int j=0; j<N; j++) { 3044 ProcessChangeItem item = mActiveProcessChanges[j]; 3045 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3046 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3047 + item.pid + " uid=" + item.uid + ": " 3048 + item.foregroundActivities); 3049 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3050 item.foregroundActivities); 3051 } 3052 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3053 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3054 + item.pid + " uid=" + item.uid + ": " + item.importance); 3055 observer.onImportanceChanged(item.pid, item.uid, 3056 item.importance); 3057 } 3058 } 3059 } catch (RemoteException e) { 3060 } 3061 } 3062 } 3063 mProcessObservers.finishBroadcast(); 3064 } 3065 3066 private void dispatchProcessDied(int pid, int uid) { 3067 int i = mProcessObservers.beginBroadcast(); 3068 while (i > 0) { 3069 i--; 3070 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3071 if (observer != null) { 3072 try { 3073 observer.onProcessDied(pid, uid); 3074 } catch (RemoteException e) { 3075 } 3076 } 3077 } 3078 mProcessObservers.finishBroadcast(); 3079 } 3080 3081 final void doPendingActivityLaunchesLocked(boolean doResume) { 3082 final int N = mPendingActivityLaunches.size(); 3083 if (N <= 0) { 3084 return; 3085 } 3086 for (int i=0; i<N; i++) { 3087 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3088 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3089 doResume && i == (N-1), null); 3090 } 3091 mPendingActivityLaunches.clear(); 3092 } 3093 3094 @Override 3095 public final int startActivity(IApplicationThread caller, String callingPackage, 3096 Intent intent, String resolvedType, IBinder resultTo, 3097 String resultWho, int requestCode, int startFlags, 3098 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3099 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3100 resultWho, requestCode, 3101 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3102 } 3103 3104 @Override 3105 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3106 Intent intent, String resolvedType, IBinder resultTo, 3107 String resultWho, int requestCode, int startFlags, 3108 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3109 enforceNotIsolatedCaller("startActivity"); 3110 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3111 false, true, "startActivity", null); 3112 // TODO: Switch to user app stacks here. 3113 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3114 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3115 null, null, options, userId, null); 3116 } 3117 3118 @Override 3119 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3120 Intent intent, String resolvedType, IBinder resultTo, 3121 String resultWho, int requestCode, int startFlags, String profileFile, 3122 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3123 enforceNotIsolatedCaller("startActivityAndWait"); 3124 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3125 false, true, "startActivityAndWait", null); 3126 WaitResult res = new WaitResult(); 3127 // TODO: Switch to user app stacks here. 3128 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3129 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3130 res, null, options, UserHandle.getCallingUserId(), null); 3131 return res; 3132 } 3133 3134 @Override 3135 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3136 Intent intent, String resolvedType, IBinder resultTo, 3137 String resultWho, int requestCode, int startFlags, Configuration config, 3138 Bundle options, int userId) { 3139 enforceNotIsolatedCaller("startActivityWithConfig"); 3140 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3141 false, true, "startActivityWithConfig", null); 3142 // TODO: Switch to user app stacks here. 3143 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3144 resolvedType, resultTo, resultWho, requestCode, startFlags, 3145 null, null, null, config, options, userId, null); 3146 return ret; 3147 } 3148 3149 @Override 3150 public int startActivityIntentSender(IApplicationThread caller, 3151 IntentSender intent, Intent fillInIntent, String resolvedType, 3152 IBinder resultTo, String resultWho, int requestCode, 3153 int flagsMask, int flagsValues, Bundle options) { 3154 enforceNotIsolatedCaller("startActivityIntentSender"); 3155 // Refuse possible leaked file descriptors 3156 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3157 throw new IllegalArgumentException("File descriptors passed in Intent"); 3158 } 3159 3160 IIntentSender sender = intent.getTarget(); 3161 if (!(sender instanceof PendingIntentRecord)) { 3162 throw new IllegalArgumentException("Bad PendingIntent object"); 3163 } 3164 3165 PendingIntentRecord pir = (PendingIntentRecord)sender; 3166 3167 synchronized (this) { 3168 // If this is coming from the currently resumed activity, it is 3169 // effectively saying that app switches are allowed at this point. 3170 final ActivityStack stack = getFocusedStack(); 3171 if (stack.mResumedActivity != null && 3172 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3173 mAppSwitchesAllowedTime = 0; 3174 } 3175 } 3176 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3177 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3178 return ret; 3179 } 3180 3181 @Override 3182 public boolean startNextMatchingActivity(IBinder callingActivity, 3183 Intent intent, Bundle options) { 3184 // Refuse possible leaked file descriptors 3185 if (intent != null && intent.hasFileDescriptors() == true) { 3186 throw new IllegalArgumentException("File descriptors passed in Intent"); 3187 } 3188 3189 synchronized (this) { 3190 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3191 if (r == null) { 3192 ActivityOptions.abort(options); 3193 return false; 3194 } 3195 if (r.app == null || r.app.thread == null) { 3196 // The caller is not running... d'oh! 3197 ActivityOptions.abort(options); 3198 return false; 3199 } 3200 intent = new Intent(intent); 3201 // The caller is not allowed to change the data. 3202 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3203 // And we are resetting to find the next component... 3204 intent.setComponent(null); 3205 3206 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3207 3208 ActivityInfo aInfo = null; 3209 try { 3210 List<ResolveInfo> resolves = 3211 AppGlobals.getPackageManager().queryIntentActivities( 3212 intent, r.resolvedType, 3213 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3214 UserHandle.getCallingUserId()); 3215 3216 // Look for the original activity in the list... 3217 final int N = resolves != null ? resolves.size() : 0; 3218 for (int i=0; i<N; i++) { 3219 ResolveInfo rInfo = resolves.get(i); 3220 if (rInfo.activityInfo.packageName.equals(r.packageName) 3221 && rInfo.activityInfo.name.equals(r.info.name)) { 3222 // We found the current one... the next matching is 3223 // after it. 3224 i++; 3225 if (i<N) { 3226 aInfo = resolves.get(i).activityInfo; 3227 } 3228 if (debug) { 3229 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3230 + "/" + r.info.name); 3231 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3232 + "/" + aInfo.name); 3233 } 3234 break; 3235 } 3236 } 3237 } catch (RemoteException e) { 3238 } 3239 3240 if (aInfo == null) { 3241 // Nobody who is next! 3242 ActivityOptions.abort(options); 3243 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3244 return false; 3245 } 3246 3247 intent.setComponent(new ComponentName( 3248 aInfo.applicationInfo.packageName, aInfo.name)); 3249 intent.setFlags(intent.getFlags()&~( 3250 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3251 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3252 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3253 Intent.FLAG_ACTIVITY_NEW_TASK)); 3254 3255 // Okay now we need to start the new activity, replacing the 3256 // currently running activity. This is a little tricky because 3257 // we want to start the new one as if the current one is finished, 3258 // but not finish the current one first so that there is no flicker. 3259 // And thus... 3260 final boolean wasFinishing = r.finishing; 3261 r.finishing = true; 3262 3263 // Propagate reply information over to the new activity. 3264 final ActivityRecord resultTo = r.resultTo; 3265 final String resultWho = r.resultWho; 3266 final int requestCode = r.requestCode; 3267 r.resultTo = null; 3268 if (resultTo != null) { 3269 resultTo.removeResultsLocked(r, resultWho, requestCode); 3270 } 3271 3272 final long origId = Binder.clearCallingIdentity(); 3273 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3274 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3275 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3276 options, false, null, null); 3277 Binder.restoreCallingIdentity(origId); 3278 3279 r.finishing = wasFinishing; 3280 if (res != ActivityManager.START_SUCCESS) { 3281 return false; 3282 } 3283 return true; 3284 } 3285 } 3286 3287 final int startActivityInPackage(int uid, String callingPackage, 3288 Intent intent, String resolvedType, IBinder resultTo, 3289 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3290 IActivityContainer container) { 3291 3292 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3293 false, true, "startActivityInPackage", null); 3294 3295 // TODO: Switch to user app stacks here. 3296 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3297 resultTo, resultWho, requestCode, startFlags, 3298 null, null, null, null, options, userId, container); 3299 return ret; 3300 } 3301 3302 @Override 3303 public final int startActivities(IApplicationThread caller, String callingPackage, 3304 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3305 int userId) { 3306 enforceNotIsolatedCaller("startActivities"); 3307 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3308 false, true, "startActivity", null); 3309 // TODO: Switch to user app stacks here. 3310 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3311 resolvedTypes, resultTo, options, userId); 3312 return ret; 3313 } 3314 3315 final int startActivitiesInPackage(int uid, String callingPackage, 3316 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3317 Bundle options, int userId) { 3318 3319 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3320 false, true, "startActivityInPackage", null); 3321 // TODO: Switch to user app stacks here. 3322 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3323 resultTo, options, userId); 3324 return ret; 3325 } 3326 3327 final void addRecentTaskLocked(TaskRecord task) { 3328 int N = mRecentTasks.size(); 3329 // Quick case: check if the top-most recent task is the same. 3330 if (N > 0 && mRecentTasks.get(0) == task) { 3331 return; 3332 } 3333 // Remove any existing entries that are the same kind of task. 3334 final Intent intent = task.intent; 3335 final boolean document = intent != null && intent.isDocument(); 3336 for (int i=0; i<N; i++) { 3337 TaskRecord tr = mRecentTasks.get(i); 3338 if (task != tr) { 3339 if (task.userId != tr.userId) { 3340 continue; 3341 } 3342 final Intent trIntent = tr.intent; 3343 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3344 (intent == null || !intent.filterEquals(trIntent))) { 3345 continue; 3346 } 3347 if (document || trIntent != null && trIntent.isDocument()) { 3348 // Document tasks do not match other tasks. 3349 continue; 3350 } 3351 } 3352 3353 // Either task and tr are the same or, their affinities match or their intents match 3354 // and neither of them is a document. 3355 tr.disposeThumbnail(); 3356 mRecentTasks.remove(i); 3357 i--; 3358 N--; 3359 if (task.intent == null) { 3360 // If the new recent task we are adding is not fully 3361 // specified, then replace it with the existing recent task. 3362 task = tr; 3363 } 3364 } 3365 if (N >= MAX_RECENT_TASKS) { 3366 mRecentTasks.remove(N-1).disposeThumbnail(); 3367 } 3368 mRecentTasks.add(0, task); 3369 } 3370 3371 @Override 3372 public void reportActivityFullyDrawn(IBinder token) { 3373 synchronized (this) { 3374 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3375 if (r == null) { 3376 return; 3377 } 3378 r.reportFullyDrawnLocked(); 3379 } 3380 } 3381 3382 @Override 3383 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3384 synchronized (this) { 3385 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3386 if (r == null) { 3387 return; 3388 } 3389 final long origId = Binder.clearCallingIdentity(); 3390 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3391 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3392 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3393 if (config != null) { 3394 r.frozenBeforeDestroy = true; 3395 if (!updateConfigurationLocked(config, r, false, false)) { 3396 mStackSupervisor.resumeTopActivitiesLocked(); 3397 } 3398 } 3399 Binder.restoreCallingIdentity(origId); 3400 } 3401 } 3402 3403 @Override 3404 public int getRequestedOrientation(IBinder token) { 3405 synchronized (this) { 3406 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3407 if (r == null) { 3408 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3409 } 3410 return mWindowManager.getAppOrientation(r.appToken); 3411 } 3412 } 3413 3414 /** 3415 * This is the internal entry point for handling Activity.finish(). 3416 * 3417 * @param token The Binder token referencing the Activity we want to finish. 3418 * @param resultCode Result code, if any, from this Activity. 3419 * @param resultData Result data (Intent), if any, from this Activity. 3420 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3421 * the root Activity in the task. 3422 * 3423 * @return Returns true if the activity successfully finished, or false if it is still running. 3424 */ 3425 @Override 3426 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3427 boolean finishTask) { 3428 // Refuse possible leaked file descriptors 3429 if (resultData != null && resultData.hasFileDescriptors() == true) { 3430 throw new IllegalArgumentException("File descriptors passed in Intent"); 3431 } 3432 3433 synchronized(this) { 3434 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3435 if (r == null) { 3436 return true; 3437 } 3438 // Keep track of the root activity of the task before we finish it 3439 TaskRecord tr = r.task; 3440 ActivityRecord rootR = tr.getRootActivity(); 3441 if (mController != null) { 3442 // Find the first activity that is not finishing. 3443 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3444 if (next != null) { 3445 // ask watcher if this is allowed 3446 boolean resumeOK = true; 3447 try { 3448 resumeOK = mController.activityResuming(next.packageName); 3449 } catch (RemoteException e) { 3450 mController = null; 3451 Watchdog.getInstance().setActivityController(null); 3452 } 3453 3454 if (!resumeOK) { 3455 return false; 3456 } 3457 } 3458 } 3459 final long origId = Binder.clearCallingIdentity(); 3460 try { 3461 boolean res; 3462 if (finishTask && r == rootR) { 3463 // If requested, remove the task that is associated to this activity only if it 3464 // was the root activity in the task. The result code and data is ignored because 3465 // we don't support returning them across task boundaries. 3466 res = removeTaskByIdLocked(tr.taskId, 0); 3467 } else { 3468 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3469 resultData, "app-request", true); 3470 } 3471 return res; 3472 } finally { 3473 Binder.restoreCallingIdentity(origId); 3474 } 3475 } 3476 } 3477 3478 @Override 3479 public final void finishHeavyWeightApp() { 3480 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3481 != PackageManager.PERMISSION_GRANTED) { 3482 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3483 + Binder.getCallingPid() 3484 + ", uid=" + Binder.getCallingUid() 3485 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3486 Slog.w(TAG, msg); 3487 throw new SecurityException(msg); 3488 } 3489 3490 synchronized(this) { 3491 if (mHeavyWeightProcess == null) { 3492 return; 3493 } 3494 3495 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3496 mHeavyWeightProcess.activities); 3497 for (int i=0; i<activities.size(); i++) { 3498 ActivityRecord r = activities.get(i); 3499 if (!r.finishing) { 3500 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3501 null, "finish-heavy", true); 3502 } 3503 } 3504 3505 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3506 mHeavyWeightProcess.userId, 0)); 3507 mHeavyWeightProcess = null; 3508 } 3509 } 3510 3511 @Override 3512 public void crashApplication(int uid, int initialPid, String packageName, 3513 String message) { 3514 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3515 != PackageManager.PERMISSION_GRANTED) { 3516 String msg = "Permission Denial: crashApplication() from pid=" 3517 + Binder.getCallingPid() 3518 + ", uid=" + Binder.getCallingUid() 3519 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3520 Slog.w(TAG, msg); 3521 throw new SecurityException(msg); 3522 } 3523 3524 synchronized(this) { 3525 ProcessRecord proc = null; 3526 3527 // Figure out which process to kill. We don't trust that initialPid 3528 // still has any relation to current pids, so must scan through the 3529 // list. 3530 synchronized (mPidsSelfLocked) { 3531 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3532 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3533 if (p.uid != uid) { 3534 continue; 3535 } 3536 if (p.pid == initialPid) { 3537 proc = p; 3538 break; 3539 } 3540 if (p.pkgList.containsKey(packageName)) { 3541 proc = p; 3542 } 3543 } 3544 } 3545 3546 if (proc == null) { 3547 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3548 + " initialPid=" + initialPid 3549 + " packageName=" + packageName); 3550 return; 3551 } 3552 3553 if (proc.thread != null) { 3554 if (proc.pid == Process.myPid()) { 3555 Log.w(TAG, "crashApplication: trying to crash self!"); 3556 return; 3557 } 3558 long ident = Binder.clearCallingIdentity(); 3559 try { 3560 proc.thread.scheduleCrash(message); 3561 } catch (RemoteException e) { 3562 } 3563 Binder.restoreCallingIdentity(ident); 3564 } 3565 } 3566 } 3567 3568 @Override 3569 public final void finishSubActivity(IBinder token, String resultWho, 3570 int requestCode) { 3571 synchronized(this) { 3572 final long origId = Binder.clearCallingIdentity(); 3573 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3574 if (r != null) { 3575 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3576 } 3577 Binder.restoreCallingIdentity(origId); 3578 } 3579 } 3580 3581 @Override 3582 public boolean finishActivityAffinity(IBinder token) { 3583 synchronized(this) { 3584 final long origId = Binder.clearCallingIdentity(); 3585 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3586 boolean res = false; 3587 if (r != null) { 3588 res = r.task.stack.finishActivityAffinityLocked(r); 3589 } 3590 Binder.restoreCallingIdentity(origId); 3591 return res; 3592 } 3593 } 3594 3595 @Override 3596 public boolean willActivityBeVisible(IBinder token) { 3597 synchronized(this) { 3598 ActivityStack stack = ActivityRecord.getStackLocked(token); 3599 if (stack != null) { 3600 return stack.willActivityBeVisibleLocked(token); 3601 } 3602 return false; 3603 } 3604 } 3605 3606 @Override 3607 public void overridePendingTransition(IBinder token, String packageName, 3608 int enterAnim, int exitAnim) { 3609 synchronized(this) { 3610 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3611 if (self == null) { 3612 return; 3613 } 3614 3615 final long origId = Binder.clearCallingIdentity(); 3616 3617 if (self.state == ActivityState.RESUMED 3618 || self.state == ActivityState.PAUSING) { 3619 mWindowManager.overridePendingAppTransition(packageName, 3620 enterAnim, exitAnim, null); 3621 } 3622 3623 Binder.restoreCallingIdentity(origId); 3624 } 3625 } 3626 3627 /** 3628 * Main function for removing an existing process from the activity manager 3629 * as a result of that process going away. Clears out all connections 3630 * to the process. 3631 */ 3632 private final void handleAppDiedLocked(ProcessRecord app, 3633 boolean restarting, boolean allowRestart) { 3634 int pid = app.pid; 3635 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3636 if (!restarting) { 3637 removeLruProcessLocked(app); 3638 if (pid > 0) { 3639 ProcessList.remove(pid); 3640 } 3641 } 3642 3643 if (mProfileProc == app) { 3644 clearProfilerLocked(); 3645 } 3646 3647 // Remove this application's activities from active lists. 3648 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3649 3650 app.activities.clear(); 3651 3652 if (app.instrumentationClass != null) { 3653 Slog.w(TAG, "Crash of app " + app.processName 3654 + " running instrumentation " + app.instrumentationClass); 3655 Bundle info = new Bundle(); 3656 info.putString("shortMsg", "Process crashed."); 3657 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3658 } 3659 3660 if (!restarting) { 3661 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3662 // If there was nothing to resume, and we are not already 3663 // restarting this process, but there is a visible activity that 3664 // is hosted by the process... then make sure all visible 3665 // activities are running, taking care of restarting this 3666 // process. 3667 if (hasVisibleActivities) { 3668 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3669 } 3670 } 3671 } 3672 } 3673 3674 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3675 IBinder threadBinder = thread.asBinder(); 3676 // Find the application record. 3677 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3678 ProcessRecord rec = mLruProcesses.get(i); 3679 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3680 return i; 3681 } 3682 } 3683 return -1; 3684 } 3685 3686 final ProcessRecord getRecordForAppLocked( 3687 IApplicationThread thread) { 3688 if (thread == null) { 3689 return null; 3690 } 3691 3692 int appIndex = getLRURecordIndexForAppLocked(thread); 3693 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3694 } 3695 3696 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3697 // If there are no longer any background processes running, 3698 // and the app that died was not running instrumentation, 3699 // then tell everyone we are now low on memory. 3700 boolean haveBg = false; 3701 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3702 ProcessRecord rec = mLruProcesses.get(i); 3703 if (rec.thread != null 3704 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3705 haveBg = true; 3706 break; 3707 } 3708 } 3709 3710 if (!haveBg) { 3711 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3712 if (doReport) { 3713 long now = SystemClock.uptimeMillis(); 3714 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3715 doReport = false; 3716 } else { 3717 mLastMemUsageReportTime = now; 3718 } 3719 } 3720 final ArrayList<ProcessMemInfo> memInfos 3721 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3722 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3723 long now = SystemClock.uptimeMillis(); 3724 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3725 ProcessRecord rec = mLruProcesses.get(i); 3726 if (rec == dyingProc || rec.thread == null) { 3727 continue; 3728 } 3729 if (doReport) { 3730 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3731 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3732 } 3733 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3734 // The low memory report is overriding any current 3735 // state for a GC request. Make sure to do 3736 // heavy/important/visible/foreground processes first. 3737 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3738 rec.lastRequestedGc = 0; 3739 } else { 3740 rec.lastRequestedGc = rec.lastLowMemory; 3741 } 3742 rec.reportLowMemory = true; 3743 rec.lastLowMemory = now; 3744 mProcessesToGc.remove(rec); 3745 addProcessToGcListLocked(rec); 3746 } 3747 } 3748 if (doReport) { 3749 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3750 mHandler.sendMessage(msg); 3751 } 3752 scheduleAppGcsLocked(); 3753 } 3754 } 3755 3756 final void appDiedLocked(ProcessRecord app, int pid, 3757 IApplicationThread thread) { 3758 3759 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3760 synchronized (stats) { 3761 stats.noteProcessDiedLocked(app.info.uid, pid); 3762 } 3763 3764 // Clean up already done if the process has been re-started. 3765 if (app.pid == pid && app.thread != null && 3766 app.thread.asBinder() == thread.asBinder()) { 3767 boolean doLowMem = app.instrumentationClass == null; 3768 boolean doOomAdj = doLowMem; 3769 if (!app.killedByAm) { 3770 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3771 + ") has died."); 3772 mAllowLowerMemLevel = true; 3773 } else { 3774 // Note that we always want to do oom adj to update our state with the 3775 // new number of procs. 3776 mAllowLowerMemLevel = false; 3777 doLowMem = false; 3778 } 3779 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3780 if (DEBUG_CLEANUP) Slog.v( 3781 TAG, "Dying app: " + app + ", pid: " + pid 3782 + ", thread: " + thread.asBinder()); 3783 handleAppDiedLocked(app, false, true); 3784 3785 if (doOomAdj) { 3786 updateOomAdjLocked(); 3787 } 3788 if (doLowMem) { 3789 doLowMemReportIfNeededLocked(app); 3790 } 3791 } else if (app.pid != pid) { 3792 // A new process has already been started. 3793 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3794 + ") has died and restarted (pid " + app.pid + ")."); 3795 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3796 } else if (DEBUG_PROCESSES) { 3797 Slog.d(TAG, "Received spurious death notification for thread " 3798 + thread.asBinder()); 3799 } 3800 } 3801 3802 /** 3803 * If a stack trace dump file is configured, dump process stack traces. 3804 * @param clearTraces causes the dump file to be erased prior to the new 3805 * traces being written, if true; when false, the new traces will be 3806 * appended to any existing file content. 3807 * @param firstPids of dalvik VM processes to dump stack traces for first 3808 * @param lastPids of dalvik VM processes to dump stack traces for last 3809 * @param nativeProcs optional list of native process names to dump stack crawls 3810 * @return file containing stack traces, or null if no dump file is configured 3811 */ 3812 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3813 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3814 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3815 if (tracesPath == null || tracesPath.length() == 0) { 3816 return null; 3817 } 3818 3819 File tracesFile = new File(tracesPath); 3820 try { 3821 File tracesDir = tracesFile.getParentFile(); 3822 if (!tracesDir.exists()) { 3823 tracesFile.mkdirs(); 3824 if (!SELinux.restorecon(tracesDir)) { 3825 return null; 3826 } 3827 } 3828 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3829 3830 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3831 tracesFile.createNewFile(); 3832 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3833 } catch (IOException e) { 3834 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3835 return null; 3836 } 3837 3838 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3839 return tracesFile; 3840 } 3841 3842 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3843 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3844 // Use a FileObserver to detect when traces finish writing. 3845 // The order of traces is considered important to maintain for legibility. 3846 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3847 @Override 3848 public synchronized void onEvent(int event, String path) { notify(); } 3849 }; 3850 3851 try { 3852 observer.startWatching(); 3853 3854 // First collect all of the stacks of the most important pids. 3855 if (firstPids != null) { 3856 try { 3857 int num = firstPids.size(); 3858 for (int i = 0; i < num; i++) { 3859 synchronized (observer) { 3860 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3861 observer.wait(200); // Wait for write-close, give up after 200msec 3862 } 3863 } 3864 } catch (InterruptedException e) { 3865 Log.wtf(TAG, e); 3866 } 3867 } 3868 3869 // Next collect the stacks of the native pids 3870 if (nativeProcs != null) { 3871 int[] pids = Process.getPidsForCommands(nativeProcs); 3872 if (pids != null) { 3873 for (int pid : pids) { 3874 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3875 } 3876 } 3877 } 3878 3879 // Lastly, measure CPU usage. 3880 if (processCpuTracker != null) { 3881 processCpuTracker.init(); 3882 System.gc(); 3883 processCpuTracker.update(); 3884 try { 3885 synchronized (processCpuTracker) { 3886 processCpuTracker.wait(500); // measure over 1/2 second. 3887 } 3888 } catch (InterruptedException e) { 3889 } 3890 processCpuTracker.update(); 3891 3892 // We'll take the stack crawls of just the top apps using CPU. 3893 final int N = processCpuTracker.countWorkingStats(); 3894 int numProcs = 0; 3895 for (int i=0; i<N && numProcs<5; i++) { 3896 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3897 if (lastPids.indexOfKey(stats.pid) >= 0) { 3898 numProcs++; 3899 try { 3900 synchronized (observer) { 3901 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3902 observer.wait(200); // Wait for write-close, give up after 200msec 3903 } 3904 } catch (InterruptedException e) { 3905 Log.wtf(TAG, e); 3906 } 3907 3908 } 3909 } 3910 } 3911 } finally { 3912 observer.stopWatching(); 3913 } 3914 } 3915 3916 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3917 if (true || IS_USER_BUILD) { 3918 return; 3919 } 3920 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3921 if (tracesPath == null || tracesPath.length() == 0) { 3922 return; 3923 } 3924 3925 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3926 StrictMode.allowThreadDiskWrites(); 3927 try { 3928 final File tracesFile = new File(tracesPath); 3929 final File tracesDir = tracesFile.getParentFile(); 3930 final File tracesTmp = new File(tracesDir, "__tmp__"); 3931 try { 3932 if (!tracesDir.exists()) { 3933 tracesFile.mkdirs(); 3934 if (!SELinux.restorecon(tracesDir.getPath())) { 3935 return; 3936 } 3937 } 3938 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3939 3940 if (tracesFile.exists()) { 3941 tracesTmp.delete(); 3942 tracesFile.renameTo(tracesTmp); 3943 } 3944 StringBuilder sb = new StringBuilder(); 3945 Time tobj = new Time(); 3946 tobj.set(System.currentTimeMillis()); 3947 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3948 sb.append(": "); 3949 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3950 sb.append(" since "); 3951 sb.append(msg); 3952 FileOutputStream fos = new FileOutputStream(tracesFile); 3953 fos.write(sb.toString().getBytes()); 3954 if (app == null) { 3955 fos.write("\n*** No application process!".getBytes()); 3956 } 3957 fos.close(); 3958 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3959 } catch (IOException e) { 3960 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3961 return; 3962 } 3963 3964 if (app != null) { 3965 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3966 firstPids.add(app.pid); 3967 dumpStackTraces(tracesPath, firstPids, null, null, null); 3968 } 3969 3970 File lastTracesFile = null; 3971 File curTracesFile = null; 3972 for (int i=9; i>=0; i--) { 3973 String name = String.format(Locale.US, "slow%02d.txt", i); 3974 curTracesFile = new File(tracesDir, name); 3975 if (curTracesFile.exists()) { 3976 if (lastTracesFile != null) { 3977 curTracesFile.renameTo(lastTracesFile); 3978 } else { 3979 curTracesFile.delete(); 3980 } 3981 } 3982 lastTracesFile = curTracesFile; 3983 } 3984 tracesFile.renameTo(curTracesFile); 3985 if (tracesTmp.exists()) { 3986 tracesTmp.renameTo(tracesFile); 3987 } 3988 } finally { 3989 StrictMode.setThreadPolicy(oldPolicy); 3990 } 3991 } 3992 3993 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3994 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3995 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3996 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3997 3998 if (mController != null) { 3999 try { 4000 // 0 == continue, -1 = kill process immediately 4001 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4002 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4003 } catch (RemoteException e) { 4004 mController = null; 4005 Watchdog.getInstance().setActivityController(null); 4006 } 4007 } 4008 4009 long anrTime = SystemClock.uptimeMillis(); 4010 if (MONITOR_CPU_USAGE) { 4011 updateCpuStatsNow(); 4012 } 4013 4014 synchronized (this) { 4015 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4016 if (mShuttingDown) { 4017 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4018 return; 4019 } else if (app.notResponding) { 4020 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4021 return; 4022 } else if (app.crashing) { 4023 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4024 return; 4025 } 4026 4027 // In case we come through here for the same app before completing 4028 // this one, mark as anring now so we will bail out. 4029 app.notResponding = true; 4030 4031 // Log the ANR to the event log. 4032 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4033 app.processName, app.info.flags, annotation); 4034 4035 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4036 firstPids.add(app.pid); 4037 4038 int parentPid = app.pid; 4039 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4040 if (parentPid != app.pid) firstPids.add(parentPid); 4041 4042 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4043 4044 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4045 ProcessRecord r = mLruProcesses.get(i); 4046 if (r != null && r.thread != null) { 4047 int pid = r.pid; 4048 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4049 if (r.persistent) { 4050 firstPids.add(pid); 4051 } else { 4052 lastPids.put(pid, Boolean.TRUE); 4053 } 4054 } 4055 } 4056 } 4057 } 4058 4059 // Log the ANR to the main log. 4060 StringBuilder info = new StringBuilder(); 4061 info.setLength(0); 4062 info.append("ANR in ").append(app.processName); 4063 if (activity != null && activity.shortComponentName != null) { 4064 info.append(" (").append(activity.shortComponentName).append(")"); 4065 } 4066 info.append("\n"); 4067 info.append("PID: ").append(app.pid).append("\n"); 4068 if (annotation != null) { 4069 info.append("Reason: ").append(annotation).append("\n"); 4070 } 4071 if (parent != null && parent != activity) { 4072 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4073 } 4074 4075 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4076 4077 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4078 NATIVE_STACKS_OF_INTEREST); 4079 4080 String cpuInfo = null; 4081 if (MONITOR_CPU_USAGE) { 4082 updateCpuStatsNow(); 4083 synchronized (mProcessCpuThread) { 4084 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4085 } 4086 info.append(processCpuTracker.printCurrentLoad()); 4087 info.append(cpuInfo); 4088 } 4089 4090 info.append(processCpuTracker.printCurrentState(anrTime)); 4091 4092 Slog.e(TAG, info.toString()); 4093 if (tracesFile == null) { 4094 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4095 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4096 } 4097 4098 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4099 cpuInfo, tracesFile, null); 4100 4101 if (mController != null) { 4102 try { 4103 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4104 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4105 if (res != 0) { 4106 if (res < 0 && app.pid != MY_PID) { 4107 Process.killProcess(app.pid); 4108 } else { 4109 synchronized (this) { 4110 mServices.scheduleServiceTimeoutLocked(app); 4111 } 4112 } 4113 return; 4114 } 4115 } catch (RemoteException e) { 4116 mController = null; 4117 Watchdog.getInstance().setActivityController(null); 4118 } 4119 } 4120 4121 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4122 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4123 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4124 4125 synchronized (this) { 4126 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4127 killUnneededProcessLocked(app, "background ANR"); 4128 return; 4129 } 4130 4131 // Set the app's notResponding state, and look up the errorReportReceiver 4132 makeAppNotRespondingLocked(app, 4133 activity != null ? activity.shortComponentName : null, 4134 annotation != null ? "ANR " + annotation : "ANR", 4135 info.toString()); 4136 4137 // Bring up the infamous App Not Responding dialog 4138 Message msg = Message.obtain(); 4139 HashMap<String, Object> map = new HashMap<String, Object>(); 4140 msg.what = SHOW_NOT_RESPONDING_MSG; 4141 msg.obj = map; 4142 msg.arg1 = aboveSystem ? 1 : 0; 4143 map.put("app", app); 4144 if (activity != null) { 4145 map.put("activity", activity); 4146 } 4147 4148 mHandler.sendMessage(msg); 4149 } 4150 } 4151 4152 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4153 if (!mLaunchWarningShown) { 4154 mLaunchWarningShown = true; 4155 mHandler.post(new Runnable() { 4156 @Override 4157 public void run() { 4158 synchronized (ActivityManagerService.this) { 4159 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4160 d.show(); 4161 mHandler.postDelayed(new Runnable() { 4162 @Override 4163 public void run() { 4164 synchronized (ActivityManagerService.this) { 4165 d.dismiss(); 4166 mLaunchWarningShown = false; 4167 } 4168 } 4169 }, 4000); 4170 } 4171 } 4172 }); 4173 } 4174 } 4175 4176 @Override 4177 public boolean clearApplicationUserData(final String packageName, 4178 final IPackageDataObserver observer, int userId) { 4179 enforceNotIsolatedCaller("clearApplicationUserData"); 4180 int uid = Binder.getCallingUid(); 4181 int pid = Binder.getCallingPid(); 4182 userId = handleIncomingUser(pid, uid, 4183 userId, false, true, "clearApplicationUserData", null); 4184 long callingId = Binder.clearCallingIdentity(); 4185 try { 4186 IPackageManager pm = AppGlobals.getPackageManager(); 4187 int pkgUid = -1; 4188 synchronized(this) { 4189 try { 4190 pkgUid = pm.getPackageUid(packageName, userId); 4191 } catch (RemoteException e) { 4192 } 4193 if (pkgUid == -1) { 4194 Slog.w(TAG, "Invalid packageName: " + packageName); 4195 if (observer != null) { 4196 try { 4197 observer.onRemoveCompleted(packageName, false); 4198 } catch (RemoteException e) { 4199 Slog.i(TAG, "Observer no longer exists."); 4200 } 4201 } 4202 return false; 4203 } 4204 if (uid == pkgUid || checkComponentPermission( 4205 android.Manifest.permission.CLEAR_APP_USER_DATA, 4206 pid, uid, -1, true) 4207 == PackageManager.PERMISSION_GRANTED) { 4208 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4209 } else { 4210 throw new SecurityException("PID " + pid + " does not have permission " 4211 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4212 + " of package " + packageName); 4213 } 4214 } 4215 4216 try { 4217 // Clear application user data 4218 pm.clearApplicationUserData(packageName, observer, userId); 4219 4220 // Remove all permissions granted from/to this package 4221 removeUriPermissionsForPackageLocked(packageName, userId, true); 4222 4223 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4224 Uri.fromParts("package", packageName, null)); 4225 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4226 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4227 null, null, 0, null, null, null, false, false, userId); 4228 } catch (RemoteException e) { 4229 } 4230 } finally { 4231 Binder.restoreCallingIdentity(callingId); 4232 } 4233 return true; 4234 } 4235 4236 @Override 4237 public void killBackgroundProcesses(final String packageName, int userId) { 4238 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4239 != PackageManager.PERMISSION_GRANTED && 4240 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4241 != PackageManager.PERMISSION_GRANTED) { 4242 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4243 + Binder.getCallingPid() 4244 + ", uid=" + Binder.getCallingUid() 4245 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4246 Slog.w(TAG, msg); 4247 throw new SecurityException(msg); 4248 } 4249 4250 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4251 userId, true, true, "killBackgroundProcesses", null); 4252 long callingId = Binder.clearCallingIdentity(); 4253 try { 4254 IPackageManager pm = AppGlobals.getPackageManager(); 4255 synchronized(this) { 4256 int appId = -1; 4257 try { 4258 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4259 } catch (RemoteException e) { 4260 } 4261 if (appId == -1) { 4262 Slog.w(TAG, "Invalid packageName: " + packageName); 4263 return; 4264 } 4265 killPackageProcessesLocked(packageName, appId, userId, 4266 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4267 } 4268 } finally { 4269 Binder.restoreCallingIdentity(callingId); 4270 } 4271 } 4272 4273 @Override 4274 public void killAllBackgroundProcesses() { 4275 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4276 != PackageManager.PERMISSION_GRANTED) { 4277 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4278 + Binder.getCallingPid() 4279 + ", uid=" + Binder.getCallingUid() 4280 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4281 Slog.w(TAG, msg); 4282 throw new SecurityException(msg); 4283 } 4284 4285 long callingId = Binder.clearCallingIdentity(); 4286 try { 4287 synchronized(this) { 4288 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4289 final int NP = mProcessNames.getMap().size(); 4290 for (int ip=0; ip<NP; ip++) { 4291 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4292 final int NA = apps.size(); 4293 for (int ia=0; ia<NA; ia++) { 4294 ProcessRecord app = apps.valueAt(ia); 4295 if (app.persistent) { 4296 // we don't kill persistent processes 4297 continue; 4298 } 4299 if (app.removed) { 4300 procs.add(app); 4301 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4302 app.removed = true; 4303 procs.add(app); 4304 } 4305 } 4306 } 4307 4308 int N = procs.size(); 4309 for (int i=0; i<N; i++) { 4310 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4311 } 4312 mAllowLowerMemLevel = true; 4313 updateOomAdjLocked(); 4314 doLowMemReportIfNeededLocked(null); 4315 } 4316 } finally { 4317 Binder.restoreCallingIdentity(callingId); 4318 } 4319 } 4320 4321 @Override 4322 public void forceStopPackage(final String packageName, int userId) { 4323 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4324 != PackageManager.PERMISSION_GRANTED) { 4325 String msg = "Permission Denial: forceStopPackage() from pid=" 4326 + Binder.getCallingPid() 4327 + ", uid=" + Binder.getCallingUid() 4328 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4329 Slog.w(TAG, msg); 4330 throw new SecurityException(msg); 4331 } 4332 final int callingPid = Binder.getCallingPid(); 4333 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4334 userId, true, true, "forceStopPackage", null); 4335 long callingId = Binder.clearCallingIdentity(); 4336 try { 4337 IPackageManager pm = AppGlobals.getPackageManager(); 4338 synchronized(this) { 4339 int[] users = userId == UserHandle.USER_ALL 4340 ? getUsersLocked() : new int[] { userId }; 4341 for (int user : users) { 4342 int pkgUid = -1; 4343 try { 4344 pkgUid = pm.getPackageUid(packageName, user); 4345 } catch (RemoteException e) { 4346 } 4347 if (pkgUid == -1) { 4348 Slog.w(TAG, "Invalid packageName: " + packageName); 4349 continue; 4350 } 4351 try { 4352 pm.setPackageStoppedState(packageName, true, user); 4353 } catch (RemoteException e) { 4354 } catch (IllegalArgumentException e) { 4355 Slog.w(TAG, "Failed trying to unstop package " 4356 + packageName + ": " + e); 4357 } 4358 if (isUserRunningLocked(user, false)) { 4359 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4360 } 4361 } 4362 } 4363 } finally { 4364 Binder.restoreCallingIdentity(callingId); 4365 } 4366 } 4367 4368 /* 4369 * The pkg name and app id have to be specified. 4370 */ 4371 @Override 4372 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4373 if (pkg == null) { 4374 return; 4375 } 4376 // Make sure the uid is valid. 4377 if (appid < 0) { 4378 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4379 return; 4380 } 4381 int callerUid = Binder.getCallingUid(); 4382 // Only the system server can kill an application 4383 if (callerUid == Process.SYSTEM_UID) { 4384 // Post an aysnc message to kill the application 4385 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4386 msg.arg1 = appid; 4387 msg.arg2 = 0; 4388 Bundle bundle = new Bundle(); 4389 bundle.putString("pkg", pkg); 4390 bundle.putString("reason", reason); 4391 msg.obj = bundle; 4392 mHandler.sendMessage(msg); 4393 } else { 4394 throw new SecurityException(callerUid + " cannot kill pkg: " + 4395 pkg); 4396 } 4397 } 4398 4399 @Override 4400 public void closeSystemDialogs(String reason) { 4401 enforceNotIsolatedCaller("closeSystemDialogs"); 4402 4403 final int pid = Binder.getCallingPid(); 4404 final int uid = Binder.getCallingUid(); 4405 final long origId = Binder.clearCallingIdentity(); 4406 try { 4407 synchronized (this) { 4408 // Only allow this from foreground processes, so that background 4409 // applications can't abuse it to prevent system UI from being shown. 4410 if (uid >= Process.FIRST_APPLICATION_UID) { 4411 ProcessRecord proc; 4412 synchronized (mPidsSelfLocked) { 4413 proc = mPidsSelfLocked.get(pid); 4414 } 4415 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4416 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4417 + " from background process " + proc); 4418 return; 4419 } 4420 } 4421 closeSystemDialogsLocked(reason); 4422 } 4423 } finally { 4424 Binder.restoreCallingIdentity(origId); 4425 } 4426 } 4427 4428 void closeSystemDialogsLocked(String reason) { 4429 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4430 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4431 | Intent.FLAG_RECEIVER_FOREGROUND); 4432 if (reason != null) { 4433 intent.putExtra("reason", reason); 4434 } 4435 mWindowManager.closeSystemDialogs(reason); 4436 4437 mStackSupervisor.closeSystemDialogsLocked(); 4438 4439 broadcastIntentLocked(null, null, intent, null, 4440 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4441 Process.SYSTEM_UID, UserHandle.USER_ALL); 4442 } 4443 4444 @Override 4445 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4446 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4447 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[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 infos[i] = new Debug.MemoryInfo(); 4458 Debug.getMemoryInfo(pids[i], infos[i]); 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(infos[i].getTotalPss(), 4464 infos[i].getTotalUss(), false, proc.pkgList); 4465 } 4466 } 4467 } 4468 } 4469 return infos; 4470 } 4471 4472 @Override 4473 public long[] getProcessPss(int[] pids) { 4474 enforceNotIsolatedCaller("getProcessPss"); 4475 long[] pss = new long[pids.length]; 4476 for (int i=pids.length-1; i>=0; i--) { 4477 ProcessRecord proc; 4478 int oomAdj; 4479 synchronized (this) { 4480 synchronized (mPidsSelfLocked) { 4481 proc = mPidsSelfLocked.get(pids[i]); 4482 oomAdj = proc != null ? proc.setAdj : 0; 4483 } 4484 } 4485 long[] tmpUss = new long[1]; 4486 pss[i] = Debug.getPss(pids[i], tmpUss); 4487 if (proc != null) { 4488 synchronized (this) { 4489 if (proc.thread != null && proc.setAdj == oomAdj) { 4490 // Record this for posterity if the process has been stable. 4491 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4492 } 4493 } 4494 } 4495 } 4496 return pss; 4497 } 4498 4499 @Override 4500 public void killApplicationProcess(String processName, int uid) { 4501 if (processName == null) { 4502 return; 4503 } 4504 4505 int callerUid = Binder.getCallingUid(); 4506 // Only the system server can kill an application 4507 if (callerUid == Process.SYSTEM_UID) { 4508 synchronized (this) { 4509 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4510 if (app != null && app.thread != null) { 4511 try { 4512 app.thread.scheduleSuicide(); 4513 } catch (RemoteException e) { 4514 // If the other end already died, then our work here is done. 4515 } 4516 } else { 4517 Slog.w(TAG, "Process/uid not found attempting kill of " 4518 + processName + " / " + uid); 4519 } 4520 } 4521 } else { 4522 throw new SecurityException(callerUid + " cannot kill app process: " + 4523 processName); 4524 } 4525 } 4526 4527 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4528 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4529 false, true, false, false, UserHandle.getUserId(uid), reason); 4530 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4531 Uri.fromParts("package", packageName, null)); 4532 if (!mProcessesReady) { 4533 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4534 | Intent.FLAG_RECEIVER_FOREGROUND); 4535 } 4536 intent.putExtra(Intent.EXTRA_UID, uid); 4537 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4538 broadcastIntentLocked(null, null, intent, 4539 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4540 false, false, 4541 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4542 } 4543 4544 private void forceStopUserLocked(int userId, String reason) { 4545 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4546 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4547 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4548 | Intent.FLAG_RECEIVER_FOREGROUND); 4549 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4550 broadcastIntentLocked(null, null, intent, 4551 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4552 false, false, 4553 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4554 } 4555 4556 private final boolean killPackageProcessesLocked(String packageName, int appId, 4557 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4558 boolean doit, boolean evenPersistent, String reason) { 4559 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4560 4561 // Remove all processes this package may have touched: all with the 4562 // same UID (except for the system or root user), and all whose name 4563 // matches the package name. 4564 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4565 final int NP = mProcessNames.getMap().size(); 4566 for (int ip=0; ip<NP; ip++) { 4567 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4568 final int NA = apps.size(); 4569 for (int ia=0; ia<NA; ia++) { 4570 ProcessRecord app = apps.valueAt(ia); 4571 if (app.persistent && !evenPersistent) { 4572 // we don't kill persistent processes 4573 continue; 4574 } 4575 if (app.removed) { 4576 if (doit) { 4577 procs.add(app); 4578 } 4579 continue; 4580 } 4581 4582 // Skip process if it doesn't meet our oom adj requirement. 4583 if (app.setAdj < minOomAdj) { 4584 continue; 4585 } 4586 4587 // If no package is specified, we call all processes under the 4588 // give user id. 4589 if (packageName == null) { 4590 if (app.userId != userId) { 4591 continue; 4592 } 4593 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4594 continue; 4595 } 4596 // Package has been specified, we want to hit all processes 4597 // that match it. We need to qualify this by the processes 4598 // that are running under the specified app and user ID. 4599 } else { 4600 if (UserHandle.getAppId(app.uid) != appId) { 4601 continue; 4602 } 4603 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4604 continue; 4605 } 4606 if (!app.pkgList.containsKey(packageName)) { 4607 continue; 4608 } 4609 } 4610 4611 // Process has passed all conditions, kill it! 4612 if (!doit) { 4613 return true; 4614 } 4615 app.removed = true; 4616 procs.add(app); 4617 } 4618 } 4619 4620 int N = procs.size(); 4621 for (int i=0; i<N; i++) { 4622 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4623 } 4624 updateOomAdjLocked(); 4625 return N > 0; 4626 } 4627 4628 private final boolean forceStopPackageLocked(String name, int appId, 4629 boolean callerWillRestart, boolean purgeCache, boolean doit, 4630 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4631 int i; 4632 int N; 4633 4634 if (userId == UserHandle.USER_ALL && name == null) { 4635 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4636 } 4637 4638 if (appId < 0 && name != null) { 4639 try { 4640 appId = UserHandle.getAppId( 4641 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4642 } catch (RemoteException e) { 4643 } 4644 } 4645 4646 if (doit) { 4647 if (name != null) { 4648 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4649 + " user=" + userId + ": " + reason); 4650 } else { 4651 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4652 } 4653 4654 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4655 for (int ip=pmap.size()-1; ip>=0; ip--) { 4656 SparseArray<Long> ba = pmap.valueAt(ip); 4657 for (i=ba.size()-1; i>=0; i--) { 4658 boolean remove = false; 4659 final int entUid = ba.keyAt(i); 4660 if (name != null) { 4661 if (userId == UserHandle.USER_ALL) { 4662 if (UserHandle.getAppId(entUid) == appId) { 4663 remove = true; 4664 } 4665 } else { 4666 if (entUid == UserHandle.getUid(userId, appId)) { 4667 remove = true; 4668 } 4669 } 4670 } else if (UserHandle.getUserId(entUid) == userId) { 4671 remove = true; 4672 } 4673 if (remove) { 4674 ba.removeAt(i); 4675 } 4676 } 4677 if (ba.size() == 0) { 4678 pmap.removeAt(ip); 4679 } 4680 } 4681 } 4682 4683 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4684 -100, callerWillRestart, true, doit, evenPersistent, 4685 name == null ? ("stop user " + userId) : ("stop " + name)); 4686 4687 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4688 if (!doit) { 4689 return true; 4690 } 4691 didSomething = true; 4692 } 4693 4694 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4695 if (!doit) { 4696 return true; 4697 } 4698 didSomething = true; 4699 } 4700 4701 if (name == null) { 4702 // Remove all sticky broadcasts from this user. 4703 mStickyBroadcasts.remove(userId); 4704 } 4705 4706 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4707 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4708 userId, providers)) { 4709 if (!doit) { 4710 return true; 4711 } 4712 didSomething = true; 4713 } 4714 N = providers.size(); 4715 for (i=0; i<N; i++) { 4716 removeDyingProviderLocked(null, providers.get(i), true); 4717 } 4718 4719 // Remove transient permissions granted from/to this package/user 4720 removeUriPermissionsForPackageLocked(name, userId, false); 4721 4722 if (name == null || uninstalling) { 4723 // Remove pending intents. For now we only do this when force 4724 // stopping users, because we have some problems when doing this 4725 // for packages -- app widgets are not currently cleaned up for 4726 // such packages, so they can be left with bad pending intents. 4727 if (mIntentSenderRecords.size() > 0) { 4728 Iterator<WeakReference<PendingIntentRecord>> it 4729 = mIntentSenderRecords.values().iterator(); 4730 while (it.hasNext()) { 4731 WeakReference<PendingIntentRecord> wpir = it.next(); 4732 if (wpir == null) { 4733 it.remove(); 4734 continue; 4735 } 4736 PendingIntentRecord pir = wpir.get(); 4737 if (pir == null) { 4738 it.remove(); 4739 continue; 4740 } 4741 if (name == null) { 4742 // Stopping user, remove all objects for the user. 4743 if (pir.key.userId != userId) { 4744 // Not the same user, skip it. 4745 continue; 4746 } 4747 } else { 4748 if (UserHandle.getAppId(pir.uid) != appId) { 4749 // Different app id, skip it. 4750 continue; 4751 } 4752 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4753 // Different user, skip it. 4754 continue; 4755 } 4756 if (!pir.key.packageName.equals(name)) { 4757 // Different package, skip it. 4758 continue; 4759 } 4760 } 4761 if (!doit) { 4762 return true; 4763 } 4764 didSomething = true; 4765 it.remove(); 4766 pir.canceled = true; 4767 if (pir.key.activity != null) { 4768 pir.key.activity.pendingResults.remove(pir.ref); 4769 } 4770 } 4771 } 4772 } 4773 4774 if (doit) { 4775 if (purgeCache && name != null) { 4776 AttributeCache ac = AttributeCache.instance(); 4777 if (ac != null) { 4778 ac.removePackage(name); 4779 } 4780 } 4781 if (mBooted) { 4782 mStackSupervisor.resumeTopActivitiesLocked(); 4783 mStackSupervisor.scheduleIdleLocked(); 4784 } 4785 } 4786 4787 return didSomething; 4788 } 4789 4790 private final boolean removeProcessLocked(ProcessRecord app, 4791 boolean callerWillRestart, boolean allowRestart, String reason) { 4792 final String name = app.processName; 4793 final int uid = app.uid; 4794 if (DEBUG_PROCESSES) Slog.d( 4795 TAG, "Force removing proc " + app.toShortString() + " (" + name 4796 + "/" + uid + ")"); 4797 4798 mProcessNames.remove(name, uid); 4799 mIsolatedProcesses.remove(app.uid); 4800 if (mHeavyWeightProcess == app) { 4801 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4802 mHeavyWeightProcess.userId, 0)); 4803 mHeavyWeightProcess = null; 4804 } 4805 boolean needRestart = false; 4806 if (app.pid > 0 && app.pid != MY_PID) { 4807 int pid = app.pid; 4808 synchronized (mPidsSelfLocked) { 4809 mPidsSelfLocked.remove(pid); 4810 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4811 } 4812 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4813 app.processName, app.info.uid); 4814 if (app.isolated) { 4815 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4816 } 4817 killUnneededProcessLocked(app, reason); 4818 handleAppDiedLocked(app, true, allowRestart); 4819 removeLruProcessLocked(app); 4820 4821 if (app.persistent && !app.isolated) { 4822 if (!callerWillRestart) { 4823 addAppLocked(app.info, false); 4824 } else { 4825 needRestart = true; 4826 } 4827 } 4828 } else { 4829 mRemovedProcesses.add(app); 4830 } 4831 4832 return needRestart; 4833 } 4834 4835 private final void processStartTimedOutLocked(ProcessRecord app) { 4836 final int pid = app.pid; 4837 boolean gone = false; 4838 synchronized (mPidsSelfLocked) { 4839 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4840 if (knownApp != null && knownApp.thread == null) { 4841 mPidsSelfLocked.remove(pid); 4842 gone = true; 4843 } 4844 } 4845 4846 if (gone) { 4847 Slog.w(TAG, "Process " + app + " failed to attach"); 4848 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4849 pid, app.uid, app.processName); 4850 mProcessNames.remove(app.processName, app.uid); 4851 mIsolatedProcesses.remove(app.uid); 4852 if (mHeavyWeightProcess == app) { 4853 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4854 mHeavyWeightProcess.userId, 0)); 4855 mHeavyWeightProcess = null; 4856 } 4857 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4858 app.processName, app.info.uid); 4859 if (app.isolated) { 4860 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4861 } 4862 // Take care of any launching providers waiting for this process. 4863 checkAppInLaunchingProvidersLocked(app, true); 4864 // Take care of any services that are waiting for the process. 4865 mServices.processStartTimedOutLocked(app); 4866 killUnneededProcessLocked(app, "start timeout"); 4867 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4868 Slog.w(TAG, "Unattached app died before backup, skipping"); 4869 try { 4870 IBackupManager bm = IBackupManager.Stub.asInterface( 4871 ServiceManager.getService(Context.BACKUP_SERVICE)); 4872 bm.agentDisconnected(app.info.packageName); 4873 } catch (RemoteException e) { 4874 // Can't happen; the backup manager is local 4875 } 4876 } 4877 if (isPendingBroadcastProcessLocked(pid)) { 4878 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4879 skipPendingBroadcastLocked(pid); 4880 } 4881 } else { 4882 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4883 } 4884 } 4885 4886 private final boolean attachApplicationLocked(IApplicationThread thread, 4887 int pid) { 4888 4889 // Find the application record that is being attached... either via 4890 // the pid if we are running in multiple processes, or just pull the 4891 // next app record if we are emulating process with anonymous threads. 4892 ProcessRecord app; 4893 if (pid != MY_PID && pid >= 0) { 4894 synchronized (mPidsSelfLocked) { 4895 app = mPidsSelfLocked.get(pid); 4896 } 4897 } else { 4898 app = null; 4899 } 4900 4901 if (app == null) { 4902 Slog.w(TAG, "No pending application record for pid " + pid 4903 + " (IApplicationThread " + thread + "); dropping process"); 4904 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4905 if (pid > 0 && pid != MY_PID) { 4906 Process.killProcessQuiet(pid); 4907 } else { 4908 try { 4909 thread.scheduleExit(); 4910 } catch (Exception e) { 4911 // Ignore exceptions. 4912 } 4913 } 4914 return false; 4915 } 4916 4917 // If this application record is still attached to a previous 4918 // process, clean it up now. 4919 if (app.thread != null) { 4920 handleAppDiedLocked(app, true, true); 4921 } 4922 4923 // Tell the process all about itself. 4924 4925 if (localLOGV) Slog.v( 4926 TAG, "Binding process pid " + pid + " to record " + app); 4927 4928 final String processName = app.processName; 4929 try { 4930 AppDeathRecipient adr = new AppDeathRecipient( 4931 app, pid, thread); 4932 thread.asBinder().linkToDeath(adr, 0); 4933 app.deathRecipient = adr; 4934 } catch (RemoteException e) { 4935 app.resetPackageList(mProcessStats); 4936 startProcessLocked(app, "link fail", processName); 4937 return false; 4938 } 4939 4940 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4941 4942 app.makeActive(thread, mProcessStats); 4943 app.curAdj = app.setAdj = -100; 4944 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4945 app.forcingToForeground = null; 4946 updateProcessForegroundLocked(app, false, false); 4947 app.hasShownUi = false; 4948 app.debugging = false; 4949 app.cached = false; 4950 4951 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4952 4953 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4954 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4955 4956 if (!normalMode) { 4957 Slog.i(TAG, "Launching preboot mode app: " + app); 4958 } 4959 4960 if (localLOGV) Slog.v( 4961 TAG, "New app record " + app 4962 + " thread=" + thread.asBinder() + " pid=" + pid); 4963 try { 4964 int testMode = IApplicationThread.DEBUG_OFF; 4965 if (mDebugApp != null && mDebugApp.equals(processName)) { 4966 testMode = mWaitForDebugger 4967 ? IApplicationThread.DEBUG_WAIT 4968 : IApplicationThread.DEBUG_ON; 4969 app.debugging = true; 4970 if (mDebugTransient) { 4971 mDebugApp = mOrigDebugApp; 4972 mWaitForDebugger = mOrigWaitForDebugger; 4973 } 4974 } 4975 String profileFile = app.instrumentationProfileFile; 4976 ParcelFileDescriptor profileFd = null; 4977 boolean profileAutoStop = false; 4978 if (mProfileApp != null && mProfileApp.equals(processName)) { 4979 mProfileProc = app; 4980 profileFile = mProfileFile; 4981 profileFd = mProfileFd; 4982 profileAutoStop = mAutoStopProfiler; 4983 } 4984 boolean enableOpenGlTrace = false; 4985 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4986 enableOpenGlTrace = true; 4987 mOpenGlTraceApp = null; 4988 } 4989 4990 // If the app is being launched for restore or full backup, set it up specially 4991 boolean isRestrictedBackupMode = false; 4992 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4993 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4994 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4995 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4996 } 4997 4998 ensurePackageDexOpt(app.instrumentationInfo != null 4999 ? app.instrumentationInfo.packageName 5000 : app.info.packageName); 5001 if (app.instrumentationClass != null) { 5002 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5003 } 5004 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5005 + processName + " with config " + mConfiguration); 5006 ApplicationInfo appInfo = app.instrumentationInfo != null 5007 ? app.instrumentationInfo : app.info; 5008 app.compat = compatibilityInfoForPackageLocked(appInfo); 5009 if (profileFd != null) { 5010 profileFd = profileFd.dup(); 5011 } 5012 thread.bindApplication(processName, appInfo, providers, 5013 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5014 app.instrumentationArguments, app.instrumentationWatcher, 5015 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5016 isRestrictedBackupMode || !normalMode, app.persistent, 5017 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5018 mCoreSettingsObserver.getCoreSettingsLocked()); 5019 updateLruProcessLocked(app, false, null); 5020 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5021 } catch (Exception e) { 5022 // todo: Yikes! What should we do? For now we will try to 5023 // start another process, but that could easily get us in 5024 // an infinite loop of restarting processes... 5025 Slog.w(TAG, "Exception thrown during bind!", e); 5026 5027 app.resetPackageList(mProcessStats); 5028 app.unlinkDeathRecipient(); 5029 startProcessLocked(app, "bind fail", processName); 5030 return false; 5031 } 5032 5033 // Remove this record from the list of starting applications. 5034 mPersistentStartingProcesses.remove(app); 5035 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5036 "Attach application locked removing on hold: " + app); 5037 mProcessesOnHold.remove(app); 5038 5039 boolean badApp = false; 5040 boolean didSomething = false; 5041 5042 // See if the top visible activity is waiting to run in this process... 5043 if (normalMode) { 5044 try { 5045 if (mStackSupervisor.attachApplicationLocked(app)) { 5046 didSomething = true; 5047 } 5048 } catch (Exception e) { 5049 badApp = true; 5050 } 5051 } 5052 5053 // Find any services that should be running in this process... 5054 if (!badApp) { 5055 try { 5056 didSomething |= mServices.attachApplicationLocked(app, processName); 5057 } catch (Exception e) { 5058 badApp = true; 5059 } 5060 } 5061 5062 // Check if a next-broadcast receiver is in this process... 5063 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5064 try { 5065 didSomething |= sendPendingBroadcastsLocked(app); 5066 } catch (Exception e) { 5067 // If the app died trying to launch the receiver we declare it 'bad' 5068 badApp = true; 5069 } 5070 } 5071 5072 // Check whether the next backup agent is in this process... 5073 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5074 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5075 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5076 try { 5077 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5078 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5079 mBackupTarget.backupMode); 5080 } catch (Exception e) { 5081 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5082 e.printStackTrace(); 5083 } 5084 } 5085 5086 if (badApp) { 5087 // todo: Also need to kill application to deal with all 5088 // kinds of exceptions. 5089 handleAppDiedLocked(app, false, true); 5090 return false; 5091 } 5092 5093 if (!didSomething) { 5094 updateOomAdjLocked(); 5095 } 5096 5097 return true; 5098 } 5099 5100 @Override 5101 public final void attachApplication(IApplicationThread thread) { 5102 synchronized (this) { 5103 int callingPid = Binder.getCallingPid(); 5104 final long origId = Binder.clearCallingIdentity(); 5105 attachApplicationLocked(thread, callingPid); 5106 Binder.restoreCallingIdentity(origId); 5107 } 5108 } 5109 5110 @Override 5111 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5112 final long origId = Binder.clearCallingIdentity(); 5113 synchronized (this) { 5114 ActivityStack stack = ActivityRecord.getStackLocked(token); 5115 if (stack != null) { 5116 ActivityRecord r = 5117 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5118 if (stopProfiling) { 5119 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5120 try { 5121 mProfileFd.close(); 5122 } catch (IOException e) { 5123 } 5124 clearProfilerLocked(); 5125 } 5126 } 5127 } 5128 } 5129 Binder.restoreCallingIdentity(origId); 5130 } 5131 5132 void enableScreenAfterBoot() { 5133 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5134 SystemClock.uptimeMillis()); 5135 mWindowManager.enableScreenAfterBoot(); 5136 5137 synchronized (this) { 5138 updateEventDispatchingLocked(); 5139 } 5140 } 5141 5142 @Override 5143 public void showBootMessage(final CharSequence msg, final boolean always) { 5144 enforceNotIsolatedCaller("showBootMessage"); 5145 mWindowManager.showBootMessage(msg, always); 5146 } 5147 5148 @Override 5149 public void dismissKeyguardOnNextActivity() { 5150 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5151 final long token = Binder.clearCallingIdentity(); 5152 try { 5153 synchronized (this) { 5154 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5155 if (mLockScreenShown) { 5156 mLockScreenShown = false; 5157 comeOutOfSleepIfNeededLocked(); 5158 } 5159 mStackSupervisor.setDismissKeyguard(true); 5160 } 5161 } finally { 5162 Binder.restoreCallingIdentity(token); 5163 } 5164 } 5165 5166 final void finishBooting() { 5167 IntentFilter pkgFilter = new IntentFilter(); 5168 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5169 pkgFilter.addDataScheme("package"); 5170 mContext.registerReceiver(new BroadcastReceiver() { 5171 @Override 5172 public void onReceive(Context context, Intent intent) { 5173 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5174 if (pkgs != null) { 5175 for (String pkg : pkgs) { 5176 synchronized (ActivityManagerService.this) { 5177 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5178 "finished booting")) { 5179 setResultCode(Activity.RESULT_OK); 5180 return; 5181 } 5182 } 5183 } 5184 } 5185 } 5186 }, pkgFilter); 5187 5188 synchronized (this) { 5189 // Ensure that any processes we had put on hold are now started 5190 // up. 5191 final int NP = mProcessesOnHold.size(); 5192 if (NP > 0) { 5193 ArrayList<ProcessRecord> procs = 5194 new ArrayList<ProcessRecord>(mProcessesOnHold); 5195 for (int ip=0; ip<NP; ip++) { 5196 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5197 + procs.get(ip)); 5198 startProcessLocked(procs.get(ip), "on-hold", null); 5199 } 5200 } 5201 5202 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5203 // Start looking for apps that are abusing wake locks. 5204 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5205 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5206 // Tell anyone interested that we are done booting! 5207 SystemProperties.set("sys.boot_completed", "1"); 5208 SystemProperties.set("dev.bootcomplete", "1"); 5209 for (int i=0; i<mStartedUsers.size(); i++) { 5210 UserStartedState uss = mStartedUsers.valueAt(i); 5211 if (uss.mState == UserStartedState.STATE_BOOTING) { 5212 uss.mState = UserStartedState.STATE_RUNNING; 5213 final int userId = mStartedUsers.keyAt(i); 5214 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5215 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5216 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5217 broadcastIntentLocked(null, null, intent, null, 5218 new IIntentReceiver.Stub() { 5219 @Override 5220 public void performReceive(Intent intent, int resultCode, 5221 String data, Bundle extras, boolean ordered, 5222 boolean sticky, int sendingUser) { 5223 synchronized (ActivityManagerService.this) { 5224 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5225 true, false); 5226 } 5227 } 5228 }, 5229 0, null, null, 5230 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5231 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5232 userId); 5233 } 5234 } 5235 scheduleStartProfilesLocked(); 5236 } 5237 } 5238 } 5239 5240 final void ensureBootCompleted() { 5241 boolean booting; 5242 boolean enableScreen; 5243 synchronized (this) { 5244 booting = mBooting; 5245 mBooting = false; 5246 enableScreen = !mBooted; 5247 mBooted = true; 5248 } 5249 5250 if (booting) { 5251 finishBooting(); 5252 } 5253 5254 if (enableScreen) { 5255 enableScreenAfterBoot(); 5256 } 5257 } 5258 5259 @Override 5260 public final void activityResumed(IBinder token) { 5261 final long origId = Binder.clearCallingIdentity(); 5262 synchronized(this) { 5263 ActivityStack stack = ActivityRecord.getStackLocked(token); 5264 if (stack != null) { 5265 ActivityRecord.activityResumedLocked(token); 5266 } 5267 } 5268 Binder.restoreCallingIdentity(origId); 5269 } 5270 5271 @Override 5272 public final void activityPaused(IBinder token) { 5273 final long origId = Binder.clearCallingIdentity(); 5274 synchronized(this) { 5275 ActivityStack stack = ActivityRecord.getStackLocked(token); 5276 if (stack != null) { 5277 stack.activityPausedLocked(token, false); 5278 } 5279 } 5280 Binder.restoreCallingIdentity(origId); 5281 } 5282 5283 @Override 5284 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5285 CharSequence description) { 5286 if (localLOGV) Slog.v( 5287 TAG, "Activity stopped: token=" + token); 5288 5289 // Refuse possible leaked file descriptors 5290 if (icicle != null && icicle.hasFileDescriptors()) { 5291 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5292 } 5293 5294 ActivityRecord r = null; 5295 5296 final long origId = Binder.clearCallingIdentity(); 5297 5298 synchronized (this) { 5299 r = ActivityRecord.isInStackLocked(token); 5300 if (r != null) { 5301 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5302 } 5303 } 5304 5305 if (r != null) { 5306 sendPendingThumbnail(r, null, null, null, false); 5307 } 5308 5309 trimApplications(); 5310 5311 Binder.restoreCallingIdentity(origId); 5312 } 5313 5314 @Override 5315 public final void activityDestroyed(IBinder token) { 5316 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5317 synchronized (this) { 5318 ActivityStack stack = ActivityRecord.getStackLocked(token); 5319 if (stack != null) { 5320 stack.activityDestroyedLocked(token); 5321 } 5322 } 5323 } 5324 5325 @Override 5326 public String getCallingPackage(IBinder token) { 5327 synchronized (this) { 5328 ActivityRecord r = getCallingRecordLocked(token); 5329 return r != null ? r.info.packageName : null; 5330 } 5331 } 5332 5333 @Override 5334 public ComponentName getCallingActivity(IBinder token) { 5335 synchronized (this) { 5336 ActivityRecord r = getCallingRecordLocked(token); 5337 return r != null ? r.intent.getComponent() : null; 5338 } 5339 } 5340 5341 private ActivityRecord getCallingRecordLocked(IBinder token) { 5342 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5343 if (r == null) { 5344 return null; 5345 } 5346 return r.resultTo; 5347 } 5348 5349 @Override 5350 public ComponentName getActivityClassForToken(IBinder token) { 5351 synchronized(this) { 5352 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5353 if (r == null) { 5354 return null; 5355 } 5356 return r.intent.getComponent(); 5357 } 5358 } 5359 5360 @Override 5361 public String getPackageForToken(IBinder token) { 5362 synchronized(this) { 5363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5364 if (r == null) { 5365 return null; 5366 } 5367 return r.packageName; 5368 } 5369 } 5370 5371 @Override 5372 public IIntentSender getIntentSender(int type, 5373 String packageName, IBinder token, String resultWho, 5374 int requestCode, Intent[] intents, String[] resolvedTypes, 5375 int flags, Bundle options, int userId) { 5376 enforceNotIsolatedCaller("getIntentSender"); 5377 // Refuse possible leaked file descriptors 5378 if (intents != null) { 5379 if (intents.length < 1) { 5380 throw new IllegalArgumentException("Intents array length must be >= 1"); 5381 } 5382 for (int i=0; i<intents.length; i++) { 5383 Intent intent = intents[i]; 5384 if (intent != null) { 5385 if (intent.hasFileDescriptors()) { 5386 throw new IllegalArgumentException("File descriptors passed in Intent"); 5387 } 5388 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5389 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5390 throw new IllegalArgumentException( 5391 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5392 } 5393 intents[i] = new Intent(intent); 5394 } 5395 } 5396 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5397 throw new IllegalArgumentException( 5398 "Intent array length does not match resolvedTypes length"); 5399 } 5400 } 5401 if (options != null) { 5402 if (options.hasFileDescriptors()) { 5403 throw new IllegalArgumentException("File descriptors passed in options"); 5404 } 5405 } 5406 5407 synchronized(this) { 5408 int callingUid = Binder.getCallingUid(); 5409 int origUserId = userId; 5410 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5411 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5412 "getIntentSender", null); 5413 if (origUserId == UserHandle.USER_CURRENT) { 5414 // We don't want to evaluate this until the pending intent is 5415 // actually executed. However, we do want to always do the 5416 // security checking for it above. 5417 userId = UserHandle.USER_CURRENT; 5418 } 5419 try { 5420 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5421 int uid = AppGlobals.getPackageManager() 5422 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5423 if (!UserHandle.isSameApp(callingUid, uid)) { 5424 String msg = "Permission Denial: getIntentSender() from pid=" 5425 + Binder.getCallingPid() 5426 + ", uid=" + Binder.getCallingUid() 5427 + ", (need uid=" + uid + ")" 5428 + " is not allowed to send as package " + packageName; 5429 Slog.w(TAG, msg); 5430 throw new SecurityException(msg); 5431 } 5432 } 5433 5434 return getIntentSenderLocked(type, packageName, callingUid, userId, 5435 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5436 5437 } catch (RemoteException e) { 5438 throw new SecurityException(e); 5439 } 5440 } 5441 } 5442 5443 IIntentSender getIntentSenderLocked(int type, String packageName, 5444 int callingUid, int userId, IBinder token, String resultWho, 5445 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5446 Bundle options) { 5447 if (DEBUG_MU) 5448 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5449 ActivityRecord activity = null; 5450 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5451 activity = ActivityRecord.isInStackLocked(token); 5452 if (activity == null) { 5453 return null; 5454 } 5455 if (activity.finishing) { 5456 return null; 5457 } 5458 } 5459 5460 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5461 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5462 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5463 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5464 |PendingIntent.FLAG_UPDATE_CURRENT); 5465 5466 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5467 type, packageName, activity, resultWho, 5468 requestCode, intents, resolvedTypes, flags, options, userId); 5469 WeakReference<PendingIntentRecord> ref; 5470 ref = mIntentSenderRecords.get(key); 5471 PendingIntentRecord rec = ref != null ? ref.get() : null; 5472 if (rec != null) { 5473 if (!cancelCurrent) { 5474 if (updateCurrent) { 5475 if (rec.key.requestIntent != null) { 5476 rec.key.requestIntent.replaceExtras(intents != null ? 5477 intents[intents.length - 1] : null); 5478 } 5479 if (intents != null) { 5480 intents[intents.length-1] = rec.key.requestIntent; 5481 rec.key.allIntents = intents; 5482 rec.key.allResolvedTypes = resolvedTypes; 5483 } else { 5484 rec.key.allIntents = null; 5485 rec.key.allResolvedTypes = null; 5486 } 5487 } 5488 return rec; 5489 } 5490 rec.canceled = true; 5491 mIntentSenderRecords.remove(key); 5492 } 5493 if (noCreate) { 5494 return rec; 5495 } 5496 rec = new PendingIntentRecord(this, key, callingUid); 5497 mIntentSenderRecords.put(key, rec.ref); 5498 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5499 if (activity.pendingResults == null) { 5500 activity.pendingResults 5501 = new HashSet<WeakReference<PendingIntentRecord>>(); 5502 } 5503 activity.pendingResults.add(rec.ref); 5504 } 5505 return rec; 5506 } 5507 5508 @Override 5509 public void cancelIntentSender(IIntentSender sender) { 5510 if (!(sender instanceof PendingIntentRecord)) { 5511 return; 5512 } 5513 synchronized(this) { 5514 PendingIntentRecord rec = (PendingIntentRecord)sender; 5515 try { 5516 int uid = AppGlobals.getPackageManager() 5517 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5518 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5519 String msg = "Permission Denial: cancelIntentSender() from pid=" 5520 + Binder.getCallingPid() 5521 + ", uid=" + Binder.getCallingUid() 5522 + " is not allowed to cancel packges " 5523 + rec.key.packageName; 5524 Slog.w(TAG, msg); 5525 throw new SecurityException(msg); 5526 } 5527 } catch (RemoteException e) { 5528 throw new SecurityException(e); 5529 } 5530 cancelIntentSenderLocked(rec, true); 5531 } 5532 } 5533 5534 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5535 rec.canceled = true; 5536 mIntentSenderRecords.remove(rec.key); 5537 if (cleanActivity && rec.key.activity != null) { 5538 rec.key.activity.pendingResults.remove(rec.ref); 5539 } 5540 } 5541 5542 @Override 5543 public String getPackageForIntentSender(IIntentSender pendingResult) { 5544 if (!(pendingResult instanceof PendingIntentRecord)) { 5545 return null; 5546 } 5547 try { 5548 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5549 return res.key.packageName; 5550 } catch (ClassCastException e) { 5551 } 5552 return null; 5553 } 5554 5555 @Override 5556 public int getUidForIntentSender(IIntentSender sender) { 5557 if (sender instanceof PendingIntentRecord) { 5558 try { 5559 PendingIntentRecord res = (PendingIntentRecord)sender; 5560 return res.uid; 5561 } catch (ClassCastException e) { 5562 } 5563 } 5564 return -1; 5565 } 5566 5567 @Override 5568 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5569 if (!(pendingResult instanceof PendingIntentRecord)) { 5570 return false; 5571 } 5572 try { 5573 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5574 if (res.key.allIntents == null) { 5575 return false; 5576 } 5577 for (int i=0; i<res.key.allIntents.length; i++) { 5578 Intent intent = res.key.allIntents[i]; 5579 if (intent.getPackage() != null && intent.getComponent() != null) { 5580 return false; 5581 } 5582 } 5583 return true; 5584 } catch (ClassCastException e) { 5585 } 5586 return false; 5587 } 5588 5589 @Override 5590 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5591 if (!(pendingResult instanceof PendingIntentRecord)) { 5592 return false; 5593 } 5594 try { 5595 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5596 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5597 return true; 5598 } 5599 return false; 5600 } catch (ClassCastException e) { 5601 } 5602 return false; 5603 } 5604 5605 @Override 5606 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5607 if (!(pendingResult instanceof PendingIntentRecord)) { 5608 return null; 5609 } 5610 try { 5611 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5612 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5613 } catch (ClassCastException e) { 5614 } 5615 return null; 5616 } 5617 5618 @Override 5619 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5620 if (!(pendingResult instanceof PendingIntentRecord)) { 5621 return null; 5622 } 5623 try { 5624 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5625 Intent intent = res.key.requestIntent; 5626 if (intent != null) { 5627 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5628 || res.lastTagPrefix.equals(prefix))) { 5629 return res.lastTag; 5630 } 5631 res.lastTagPrefix = prefix; 5632 StringBuilder sb = new StringBuilder(128); 5633 if (prefix != null) { 5634 sb.append(prefix); 5635 } 5636 if (intent.getAction() != null) { 5637 sb.append(intent.getAction()); 5638 } else if (intent.getComponent() != null) { 5639 intent.getComponent().appendShortString(sb); 5640 } else { 5641 sb.append("?"); 5642 } 5643 return res.lastTag = sb.toString(); 5644 } 5645 } catch (ClassCastException e) { 5646 } 5647 return null; 5648 } 5649 5650 @Override 5651 public void setProcessLimit(int max) { 5652 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5653 "setProcessLimit()"); 5654 synchronized (this) { 5655 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5656 mProcessLimitOverride = max; 5657 } 5658 trimApplications(); 5659 } 5660 5661 @Override 5662 public int getProcessLimit() { 5663 synchronized (this) { 5664 return mProcessLimitOverride; 5665 } 5666 } 5667 5668 void foregroundTokenDied(ForegroundToken token) { 5669 synchronized (ActivityManagerService.this) { 5670 synchronized (mPidsSelfLocked) { 5671 ForegroundToken cur 5672 = mForegroundProcesses.get(token.pid); 5673 if (cur != token) { 5674 return; 5675 } 5676 mForegroundProcesses.remove(token.pid); 5677 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5678 if (pr == null) { 5679 return; 5680 } 5681 pr.forcingToForeground = null; 5682 updateProcessForegroundLocked(pr, false, false); 5683 } 5684 updateOomAdjLocked(); 5685 } 5686 } 5687 5688 @Override 5689 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5690 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5691 "setProcessForeground()"); 5692 synchronized(this) { 5693 boolean changed = false; 5694 5695 synchronized (mPidsSelfLocked) { 5696 ProcessRecord pr = mPidsSelfLocked.get(pid); 5697 if (pr == null && isForeground) { 5698 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5699 return; 5700 } 5701 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5702 if (oldToken != null) { 5703 oldToken.token.unlinkToDeath(oldToken, 0); 5704 mForegroundProcesses.remove(pid); 5705 if (pr != null) { 5706 pr.forcingToForeground = null; 5707 } 5708 changed = true; 5709 } 5710 if (isForeground && token != null) { 5711 ForegroundToken newToken = new ForegroundToken() { 5712 @Override 5713 public void binderDied() { 5714 foregroundTokenDied(this); 5715 } 5716 }; 5717 newToken.pid = pid; 5718 newToken.token = token; 5719 try { 5720 token.linkToDeath(newToken, 0); 5721 mForegroundProcesses.put(pid, newToken); 5722 pr.forcingToForeground = token; 5723 changed = true; 5724 } catch (RemoteException e) { 5725 // If the process died while doing this, we will later 5726 // do the cleanup with the process death link. 5727 } 5728 } 5729 } 5730 5731 if (changed) { 5732 updateOomAdjLocked(); 5733 } 5734 } 5735 } 5736 5737 // ========================================================= 5738 // PERMISSIONS 5739 // ========================================================= 5740 5741 static class PermissionController extends IPermissionController.Stub { 5742 ActivityManagerService mActivityManagerService; 5743 PermissionController(ActivityManagerService activityManagerService) { 5744 mActivityManagerService = activityManagerService; 5745 } 5746 5747 @Override 5748 public boolean checkPermission(String permission, int pid, int uid) { 5749 return mActivityManagerService.checkPermission(permission, pid, 5750 uid) == PackageManager.PERMISSION_GRANTED; 5751 } 5752 } 5753 5754 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5755 @Override 5756 public int checkComponentPermission(String permission, int pid, int uid, 5757 int owningUid, boolean exported) { 5758 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5759 owningUid, exported); 5760 } 5761 5762 @Override 5763 public Object getAMSLock() { 5764 return ActivityManagerService.this; 5765 } 5766 } 5767 5768 /** 5769 * This can be called with or without the global lock held. 5770 */ 5771 int checkComponentPermission(String permission, int pid, int uid, 5772 int owningUid, boolean exported) { 5773 // We might be performing an operation on behalf of an indirect binder 5774 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5775 // client identity accordingly before proceeding. 5776 Identity tlsIdentity = sCallerIdentity.get(); 5777 if (tlsIdentity != null) { 5778 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5779 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5780 uid = tlsIdentity.uid; 5781 pid = tlsIdentity.pid; 5782 } 5783 5784 if (pid == MY_PID) { 5785 return PackageManager.PERMISSION_GRANTED; 5786 } 5787 5788 return ActivityManager.checkComponentPermission(permission, uid, 5789 owningUid, exported); 5790 } 5791 5792 /** 5793 * As the only public entry point for permissions checking, this method 5794 * can enforce the semantic that requesting a check on a null global 5795 * permission is automatically denied. (Internally a null permission 5796 * string is used when calling {@link #checkComponentPermission} in cases 5797 * when only uid-based security is needed.) 5798 * 5799 * This can be called with or without the global lock held. 5800 */ 5801 @Override 5802 public int checkPermission(String permission, int pid, int uid) { 5803 if (permission == null) { 5804 return PackageManager.PERMISSION_DENIED; 5805 } 5806 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5807 } 5808 5809 /** 5810 * Binder IPC calls go through the public entry point. 5811 * This can be called with or without the global lock held. 5812 */ 5813 int checkCallingPermission(String permission) { 5814 return checkPermission(permission, 5815 Binder.getCallingPid(), 5816 UserHandle.getAppId(Binder.getCallingUid())); 5817 } 5818 5819 /** 5820 * This can be called with or without the global lock held. 5821 */ 5822 void enforceCallingPermission(String permission, String func) { 5823 if (checkCallingPermission(permission) 5824 == PackageManager.PERMISSION_GRANTED) { 5825 return; 5826 } 5827 5828 String msg = "Permission Denial: " + func + " from pid=" 5829 + Binder.getCallingPid() 5830 + ", uid=" + Binder.getCallingUid() 5831 + " requires " + permission; 5832 Slog.w(TAG, msg); 5833 throw new SecurityException(msg); 5834 } 5835 5836 /** 5837 * Determine if UID is holding permissions required to access {@link Uri} in 5838 * the given {@link ProviderInfo}. Final permission checking is always done 5839 * in {@link ContentProvider}. 5840 */ 5841 private final boolean checkHoldingPermissionsLocked( 5842 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5843 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5844 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5845 5846 if (pi.applicationInfo.uid == uid) { 5847 return true; 5848 } else if (!pi.exported) { 5849 return false; 5850 } 5851 5852 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5853 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5854 try { 5855 // check if target holds top-level <provider> permissions 5856 if (!readMet && pi.readPermission != null 5857 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5858 readMet = true; 5859 } 5860 if (!writeMet && pi.writePermission != null 5861 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5862 writeMet = true; 5863 } 5864 5865 // track if unprotected read/write is allowed; any denied 5866 // <path-permission> below removes this ability 5867 boolean allowDefaultRead = pi.readPermission == null; 5868 boolean allowDefaultWrite = pi.writePermission == null; 5869 5870 // check if target holds any <path-permission> that match uri 5871 final PathPermission[] pps = pi.pathPermissions; 5872 if (pps != null) { 5873 final String path = uri.getPath(); 5874 int i = pps.length; 5875 while (i > 0 && (!readMet || !writeMet)) { 5876 i--; 5877 PathPermission pp = pps[i]; 5878 if (pp.match(path)) { 5879 if (!readMet) { 5880 final String pprperm = pp.getReadPermission(); 5881 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5882 + pprperm + " for " + pp.getPath() 5883 + ": match=" + pp.match(path) 5884 + " check=" + pm.checkUidPermission(pprperm, uid)); 5885 if (pprperm != null) { 5886 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5887 readMet = true; 5888 } else { 5889 allowDefaultRead = false; 5890 } 5891 } 5892 } 5893 if (!writeMet) { 5894 final String ppwperm = pp.getWritePermission(); 5895 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5896 + ppwperm + " for " + pp.getPath() 5897 + ": match=" + pp.match(path) 5898 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5899 if (ppwperm != null) { 5900 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5901 writeMet = true; 5902 } else { 5903 allowDefaultWrite = false; 5904 } 5905 } 5906 } 5907 } 5908 } 5909 } 5910 5911 // grant unprotected <provider> read/write, if not blocked by 5912 // <path-permission> above 5913 if (allowDefaultRead) readMet = true; 5914 if (allowDefaultWrite) writeMet = true; 5915 5916 } catch (RemoteException e) { 5917 return false; 5918 } 5919 5920 return readMet && writeMet; 5921 } 5922 5923 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5924 ProviderInfo pi = null; 5925 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5926 if (cpr != null) { 5927 pi = cpr.info; 5928 } else { 5929 try { 5930 pi = AppGlobals.getPackageManager().resolveContentProvider( 5931 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5932 } catch (RemoteException ex) { 5933 } 5934 } 5935 return pi; 5936 } 5937 5938 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5939 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5940 if (targetUris != null) { 5941 return targetUris.get(uri); 5942 } else { 5943 return null; 5944 } 5945 } 5946 5947 private UriPermission findOrCreateUriPermissionLocked( 5948 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5949 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5950 if (targetUris == null) { 5951 targetUris = Maps.newArrayMap(); 5952 mGrantedUriPermissions.put(targetUid, targetUris); 5953 } 5954 5955 UriPermission perm = targetUris.get(uri); 5956 if (perm == null) { 5957 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5958 targetUris.put(uri, perm); 5959 } 5960 5961 return perm; 5962 } 5963 5964 private final boolean checkUriPermissionLocked( 5965 Uri uri, int uid, int modeFlags, int minStrength) { 5966 // Root gets to do everything. 5967 if (uid == 0) { 5968 return true; 5969 } 5970 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5971 if (perms == null) return false; 5972 UriPermission perm = perms.get(uri); 5973 if (perm == null) return false; 5974 return perm.getStrength(modeFlags) >= minStrength; 5975 } 5976 5977 @Override 5978 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5979 enforceNotIsolatedCaller("checkUriPermission"); 5980 5981 // Another redirected-binder-call permissions check as in 5982 // {@link checkComponentPermission}. 5983 Identity tlsIdentity = sCallerIdentity.get(); 5984 if (tlsIdentity != null) { 5985 uid = tlsIdentity.uid; 5986 pid = tlsIdentity.pid; 5987 } 5988 5989 // Our own process gets to do everything. 5990 if (pid == MY_PID) { 5991 return PackageManager.PERMISSION_GRANTED; 5992 } 5993 synchronized(this) { 5994 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5995 ? PackageManager.PERMISSION_GRANTED 5996 : PackageManager.PERMISSION_DENIED; 5997 } 5998 } 5999 6000 /** 6001 * Check if the targetPkg can be granted permission to access uri by 6002 * the callingUid using the given modeFlags. Throws a security exception 6003 * if callingUid is not allowed to do this. Returns the uid of the target 6004 * if the URI permission grant should be performed; returns -1 if it is not 6005 * needed (for example targetPkg already has permission to access the URI). 6006 * If you already know the uid of the target, you can supply it in 6007 * lastTargetUid else set that to -1. 6008 */ 6009 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6010 Uri uri, int modeFlags, int lastTargetUid) { 6011 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6012 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6013 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6014 if (modeFlags == 0) { 6015 return -1; 6016 } 6017 6018 if (targetPkg != null) { 6019 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6020 "Checking grant " + targetPkg + " permission to " + uri); 6021 } 6022 6023 final IPackageManager pm = AppGlobals.getPackageManager(); 6024 6025 // If this is not a content: uri, we can't do anything with it. 6026 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6027 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6028 "Can't grant URI permission for non-content URI: " + uri); 6029 return -1; 6030 } 6031 6032 final String authority = uri.getAuthority(); 6033 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6034 if (pi == null) { 6035 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6036 return -1; 6037 } 6038 6039 int targetUid = lastTargetUid; 6040 if (targetUid < 0 && targetPkg != null) { 6041 try { 6042 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6043 if (targetUid < 0) { 6044 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6045 "Can't grant URI permission no uid for: " + targetPkg); 6046 return -1; 6047 } 6048 } catch (RemoteException ex) { 6049 return -1; 6050 } 6051 } 6052 6053 if (targetUid >= 0) { 6054 // First... does the target actually need this permission? 6055 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6056 // No need to grant the target this permission. 6057 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6058 "Target " + targetPkg + " already has full permission to " + uri); 6059 return -1; 6060 } 6061 } else { 6062 // First... there is no target package, so can anyone access it? 6063 boolean allowed = pi.exported; 6064 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6065 if (pi.readPermission != null) { 6066 allowed = false; 6067 } 6068 } 6069 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6070 if (pi.writePermission != null) { 6071 allowed = false; 6072 } 6073 } 6074 if (allowed) { 6075 return -1; 6076 } 6077 } 6078 6079 // Second... is the provider allowing granting of URI permissions? 6080 if (!pi.grantUriPermissions) { 6081 throw new SecurityException("Provider " + pi.packageName 6082 + "/" + pi.name 6083 + " does not allow granting of Uri permissions (uri " 6084 + uri + ")"); 6085 } 6086 if (pi.uriPermissionPatterns != null) { 6087 final int N = pi.uriPermissionPatterns.length; 6088 boolean allowed = false; 6089 for (int i=0; i<N; i++) { 6090 if (pi.uriPermissionPatterns[i] != null 6091 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6092 allowed = true; 6093 break; 6094 } 6095 } 6096 if (!allowed) { 6097 throw new SecurityException("Provider " + pi.packageName 6098 + "/" + pi.name 6099 + " does not allow granting of permission to path of Uri " 6100 + uri); 6101 } 6102 } 6103 6104 // Third... does the caller itself have permission to access 6105 // this uri? 6106 if (callingUid != Process.myUid()) { 6107 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6108 // Require they hold a strong enough Uri permission 6109 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6110 : UriPermission.STRENGTH_OWNED; 6111 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6112 throw new SecurityException("Uid " + callingUid 6113 + " does not have permission to uri " + uri); 6114 } 6115 } 6116 } 6117 6118 return targetUid; 6119 } 6120 6121 @Override 6122 public int checkGrantUriPermission(int callingUid, String targetPkg, 6123 Uri uri, int modeFlags) { 6124 enforceNotIsolatedCaller("checkGrantUriPermission"); 6125 synchronized(this) { 6126 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6127 } 6128 } 6129 6130 void grantUriPermissionUncheckedLocked( 6131 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6132 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6133 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6134 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6135 if (modeFlags == 0) { 6136 return; 6137 } 6138 6139 // So here we are: the caller has the assumed permission 6140 // to the uri, and the target doesn't. Let's now give this to 6141 // the target. 6142 6143 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6144 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6145 6146 final String authority = uri.getAuthority(); 6147 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6148 if (pi == null) { 6149 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6150 return; 6151 } 6152 6153 final UriPermission perm = findOrCreateUriPermissionLocked( 6154 pi.packageName, targetPkg, targetUid, uri); 6155 perm.grantModes(modeFlags, persistable, owner); 6156 } 6157 6158 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6159 int modeFlags, UriPermissionOwner owner) { 6160 if (targetPkg == null) { 6161 throw new NullPointerException("targetPkg"); 6162 } 6163 6164 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6165 if (targetUid < 0) { 6166 return; 6167 } 6168 6169 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6170 } 6171 6172 static class NeededUriGrants extends ArrayList<Uri> { 6173 final String targetPkg; 6174 final int targetUid; 6175 final int flags; 6176 6177 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6178 this.targetPkg = targetPkg; 6179 this.targetUid = targetUid; 6180 this.flags = flags; 6181 } 6182 } 6183 6184 /** 6185 * Like checkGrantUriPermissionLocked, but takes an Intent. 6186 */ 6187 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6188 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6189 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6190 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6191 + " clip=" + (intent != null ? intent.getClipData() : null) 6192 + " from " + intent + "; flags=0x" 6193 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6194 6195 if (targetPkg == null) { 6196 throw new NullPointerException("targetPkg"); 6197 } 6198 6199 if (intent == null) { 6200 return null; 6201 } 6202 Uri data = intent.getData(); 6203 ClipData clip = intent.getClipData(); 6204 if (data == null && clip == null) { 6205 return null; 6206 } 6207 6208 if (data != null) { 6209 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6210 mode, needed != null ? needed.targetUid : -1); 6211 if (targetUid > 0) { 6212 if (needed == null) { 6213 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6214 } 6215 needed.add(data); 6216 } 6217 } 6218 if (clip != null) { 6219 for (int i=0; i<clip.getItemCount(); i++) { 6220 Uri uri = clip.getItemAt(i).getUri(); 6221 if (uri != null) { 6222 int targetUid = -1; 6223 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6224 mode, needed != null ? needed.targetUid : -1); 6225 if (targetUid > 0) { 6226 if (needed == null) { 6227 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6228 } 6229 needed.add(uri); 6230 } 6231 } else { 6232 Intent clipIntent = clip.getItemAt(i).getIntent(); 6233 if (clipIntent != null) { 6234 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6235 callingUid, targetPkg, clipIntent, mode, needed); 6236 if (newNeeded != null) { 6237 needed = newNeeded; 6238 } 6239 } 6240 } 6241 } 6242 } 6243 6244 return needed; 6245 } 6246 6247 /** 6248 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6249 */ 6250 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6251 UriPermissionOwner owner) { 6252 if (needed != null) { 6253 for (int i=0; i<needed.size(); i++) { 6254 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6255 needed.get(i), needed.flags, owner); 6256 } 6257 } 6258 } 6259 6260 void grantUriPermissionFromIntentLocked(int callingUid, 6261 String targetPkg, Intent intent, UriPermissionOwner owner) { 6262 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6263 intent, intent != null ? intent.getFlags() : 0, null); 6264 if (needed == null) { 6265 return; 6266 } 6267 6268 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6269 } 6270 6271 @Override 6272 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6273 Uri uri, int modeFlags) { 6274 enforceNotIsolatedCaller("grantUriPermission"); 6275 synchronized(this) { 6276 final ProcessRecord r = getRecordForAppLocked(caller); 6277 if (r == null) { 6278 throw new SecurityException("Unable to find app for caller " 6279 + caller 6280 + " when granting permission to uri " + uri); 6281 } 6282 if (targetPkg == null) { 6283 throw new IllegalArgumentException("null target"); 6284 } 6285 if (uri == null) { 6286 throw new IllegalArgumentException("null uri"); 6287 } 6288 6289 // Persistable only supported through Intents 6290 Preconditions.checkFlagsArgument(modeFlags, 6291 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6292 6293 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6294 null); 6295 } 6296 } 6297 6298 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6299 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6300 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6301 ArrayMap<Uri, UriPermission> perms 6302 = mGrantedUriPermissions.get(perm.targetUid); 6303 if (perms != null) { 6304 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6305 "Removing " + perm.targetUid + " permission to " + perm.uri); 6306 perms.remove(perm.uri); 6307 if (perms.size() == 0) { 6308 mGrantedUriPermissions.remove(perm.targetUid); 6309 } 6310 } 6311 } 6312 } 6313 6314 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6315 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6316 6317 final IPackageManager pm = AppGlobals.getPackageManager(); 6318 final String authority = uri.getAuthority(); 6319 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6320 if (pi == null) { 6321 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6322 return; 6323 } 6324 6325 // Does the caller have this permission on the URI? 6326 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6327 // Right now, if you are not the original owner of the permission, 6328 // you are not allowed to revoke it. 6329 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6330 throw new SecurityException("Uid " + callingUid 6331 + " does not have permission to uri " + uri); 6332 //} 6333 } 6334 6335 boolean persistChanged = false; 6336 6337 // Go through all of the permissions and remove any that match. 6338 final List<String> SEGMENTS = uri.getPathSegments(); 6339 if (SEGMENTS != null) { 6340 final int NS = SEGMENTS.size(); 6341 int N = mGrantedUriPermissions.size(); 6342 for (int i=0; i<N; i++) { 6343 ArrayMap<Uri, UriPermission> perms 6344 = mGrantedUriPermissions.valueAt(i); 6345 Iterator<UriPermission> it = perms.values().iterator(); 6346 toploop: 6347 while (it.hasNext()) { 6348 UriPermission perm = it.next(); 6349 Uri targetUri = perm.uri; 6350 if (!authority.equals(targetUri.getAuthority())) { 6351 continue; 6352 } 6353 List<String> targetSegments = targetUri.getPathSegments(); 6354 if (targetSegments == null) { 6355 continue; 6356 } 6357 if (targetSegments.size() < NS) { 6358 continue; 6359 } 6360 for (int j=0; j<NS; j++) { 6361 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6362 continue toploop; 6363 } 6364 } 6365 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6366 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6367 persistChanged |= perm.clearModes(modeFlags, true); 6368 if (perm.modeFlags == 0) { 6369 it.remove(); 6370 } 6371 } 6372 if (perms.size() == 0) { 6373 mGrantedUriPermissions.remove( 6374 mGrantedUriPermissions.keyAt(i)); 6375 N--; 6376 i--; 6377 } 6378 } 6379 } 6380 6381 if (persistChanged) { 6382 schedulePersistUriGrants(); 6383 } 6384 } 6385 6386 @Override 6387 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6388 int modeFlags) { 6389 enforceNotIsolatedCaller("revokeUriPermission"); 6390 synchronized(this) { 6391 final ProcessRecord r = getRecordForAppLocked(caller); 6392 if (r == null) { 6393 throw new SecurityException("Unable to find app for caller " 6394 + caller 6395 + " when revoking permission to uri " + uri); 6396 } 6397 if (uri == null) { 6398 Slog.w(TAG, "revokeUriPermission: null uri"); 6399 return; 6400 } 6401 6402 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6403 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6404 if (modeFlags == 0) { 6405 return; 6406 } 6407 6408 final IPackageManager pm = AppGlobals.getPackageManager(); 6409 final String authority = uri.getAuthority(); 6410 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6411 if (pi == null) { 6412 Slog.w(TAG, "No content provider found for permission revoke: " 6413 + uri.toSafeString()); 6414 return; 6415 } 6416 6417 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6418 } 6419 } 6420 6421 /** 6422 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6423 * given package. 6424 * 6425 * @param packageName Package name to match, or {@code null} to apply to all 6426 * packages. 6427 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6428 * to all users. 6429 * @param persistable If persistable grants should be removed. 6430 */ 6431 private void removeUriPermissionsForPackageLocked( 6432 String packageName, int userHandle, boolean persistable) { 6433 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6434 throw new IllegalArgumentException("Must narrow by either package or user"); 6435 } 6436 6437 boolean persistChanged = false; 6438 6439 final int size = mGrantedUriPermissions.size(); 6440 for (int i = 0; i < size; i++) { 6441 // Only inspect grants matching user 6442 if (userHandle == UserHandle.USER_ALL 6443 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6444 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6445 .values().iterator(); 6446 while (it.hasNext()) { 6447 final UriPermission perm = it.next(); 6448 6449 // Only inspect grants matching package 6450 if (packageName == null || perm.sourcePkg.equals(packageName) 6451 || perm.targetPkg.equals(packageName)) { 6452 persistChanged |= perm.clearModes(~0, persistable); 6453 6454 // Only remove when no modes remain; any persisted grants 6455 // will keep this alive. 6456 if (perm.modeFlags == 0) { 6457 it.remove(); 6458 } 6459 } 6460 } 6461 } 6462 } 6463 6464 if (persistChanged) { 6465 schedulePersistUriGrants(); 6466 } 6467 } 6468 6469 @Override 6470 public IBinder newUriPermissionOwner(String name) { 6471 enforceNotIsolatedCaller("newUriPermissionOwner"); 6472 synchronized(this) { 6473 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6474 return owner.getExternalTokenLocked(); 6475 } 6476 } 6477 6478 @Override 6479 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6480 Uri uri, int modeFlags) { 6481 synchronized(this) { 6482 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6483 if (owner == null) { 6484 throw new IllegalArgumentException("Unknown owner: " + token); 6485 } 6486 if (fromUid != Binder.getCallingUid()) { 6487 if (Binder.getCallingUid() != Process.myUid()) { 6488 // Only system code can grant URI permissions on behalf 6489 // of other users. 6490 throw new SecurityException("nice try"); 6491 } 6492 } 6493 if (targetPkg == null) { 6494 throw new IllegalArgumentException("null target"); 6495 } 6496 if (uri == null) { 6497 throw new IllegalArgumentException("null uri"); 6498 } 6499 6500 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6501 } 6502 } 6503 6504 @Override 6505 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6506 synchronized(this) { 6507 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6508 if (owner == null) { 6509 throw new IllegalArgumentException("Unknown owner: " + token); 6510 } 6511 6512 if (uri == null) { 6513 owner.removeUriPermissionsLocked(mode); 6514 } else { 6515 owner.removeUriPermissionLocked(uri, mode); 6516 } 6517 } 6518 } 6519 6520 private void schedulePersistUriGrants() { 6521 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6522 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6523 10 * DateUtils.SECOND_IN_MILLIS); 6524 } 6525 } 6526 6527 private void writeGrantedUriPermissions() { 6528 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6529 6530 // Snapshot permissions so we can persist without lock 6531 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6532 synchronized (this) { 6533 final int size = mGrantedUriPermissions.size(); 6534 for (int i = 0 ; i < size; i++) { 6535 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6536 if (perm.persistedModeFlags != 0) { 6537 persist.add(perm.snapshot()); 6538 } 6539 } 6540 } 6541 } 6542 6543 FileOutputStream fos = null; 6544 try { 6545 fos = mGrantFile.startWrite(); 6546 6547 XmlSerializer out = new FastXmlSerializer(); 6548 out.setOutput(fos, "utf-8"); 6549 out.startDocument(null, true); 6550 out.startTag(null, TAG_URI_GRANTS); 6551 for (UriPermission.Snapshot perm : persist) { 6552 out.startTag(null, TAG_URI_GRANT); 6553 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6554 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6555 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6556 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6557 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6558 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6559 out.endTag(null, TAG_URI_GRANT); 6560 } 6561 out.endTag(null, TAG_URI_GRANTS); 6562 out.endDocument(); 6563 6564 mGrantFile.finishWrite(fos); 6565 } catch (IOException e) { 6566 if (fos != null) { 6567 mGrantFile.failWrite(fos); 6568 } 6569 } 6570 } 6571 6572 private void readGrantedUriPermissionsLocked() { 6573 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6574 6575 final long now = System.currentTimeMillis(); 6576 6577 FileInputStream fis = null; 6578 try { 6579 fis = mGrantFile.openRead(); 6580 final XmlPullParser in = Xml.newPullParser(); 6581 in.setInput(fis, null); 6582 6583 int type; 6584 while ((type = in.next()) != END_DOCUMENT) { 6585 final String tag = in.getName(); 6586 if (type == START_TAG) { 6587 if (TAG_URI_GRANT.equals(tag)) { 6588 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6589 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6590 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6591 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6592 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6593 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6594 6595 // Sanity check that provider still belongs to source package 6596 final ProviderInfo pi = getProviderInfoLocked( 6597 uri.getAuthority(), userHandle); 6598 if (pi != null && sourcePkg.equals(pi.packageName)) { 6599 int targetUid = -1; 6600 try { 6601 targetUid = AppGlobals.getPackageManager() 6602 .getPackageUid(targetPkg, userHandle); 6603 } catch (RemoteException e) { 6604 } 6605 if (targetUid != -1) { 6606 final UriPermission perm = findOrCreateUriPermissionLocked( 6607 sourcePkg, targetPkg, targetUid, uri); 6608 perm.initPersistedModes(modeFlags, createdTime); 6609 } 6610 } else { 6611 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6612 + " but instead found " + pi); 6613 } 6614 } 6615 } 6616 } 6617 } catch (FileNotFoundException e) { 6618 // Missing grants is okay 6619 } catch (IOException e) { 6620 Log.wtf(TAG, "Failed reading Uri grants", e); 6621 } catch (XmlPullParserException e) { 6622 Log.wtf(TAG, "Failed reading Uri grants", e); 6623 } finally { 6624 IoUtils.closeQuietly(fis); 6625 } 6626 } 6627 6628 @Override 6629 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6630 enforceNotIsolatedCaller("takePersistableUriPermission"); 6631 6632 Preconditions.checkFlagsArgument(modeFlags, 6633 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6634 6635 synchronized (this) { 6636 final int callingUid = Binder.getCallingUid(); 6637 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6638 if (perm == null) { 6639 throw new SecurityException("No permission grant found for UID " + callingUid 6640 + " and Uri " + uri.toSafeString()); 6641 } 6642 6643 boolean persistChanged = perm.takePersistableModes(modeFlags); 6644 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6645 6646 if (persistChanged) { 6647 schedulePersistUriGrants(); 6648 } 6649 } 6650 } 6651 6652 @Override 6653 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6654 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6655 6656 Preconditions.checkFlagsArgument(modeFlags, 6657 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6658 6659 synchronized (this) { 6660 final int callingUid = Binder.getCallingUid(); 6661 6662 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6663 if (perm == null) { 6664 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6665 + uri.toSafeString()); 6666 return; 6667 } 6668 6669 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6670 removeUriPermissionIfNeededLocked(perm); 6671 if (persistChanged) { 6672 schedulePersistUriGrants(); 6673 } 6674 } 6675 } 6676 6677 /** 6678 * Prune any older {@link UriPermission} for the given UID until outstanding 6679 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6680 * 6681 * @return if any mutations occured that require persisting. 6682 */ 6683 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6684 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6685 if (perms == null) return false; 6686 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6687 6688 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6689 for (UriPermission perm : perms.values()) { 6690 if (perm.persistedModeFlags != 0) { 6691 persisted.add(perm); 6692 } 6693 } 6694 6695 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6696 if (trimCount <= 0) return false; 6697 6698 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6699 for (int i = 0; i < trimCount; i++) { 6700 final UriPermission perm = persisted.get(i); 6701 6702 if (DEBUG_URI_PERMISSION) { 6703 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6704 } 6705 6706 perm.releasePersistableModes(~0); 6707 removeUriPermissionIfNeededLocked(perm); 6708 } 6709 6710 return true; 6711 } 6712 6713 @Override 6714 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6715 String packageName, boolean incoming) { 6716 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6717 Preconditions.checkNotNull(packageName, "packageName"); 6718 6719 final int callingUid = Binder.getCallingUid(); 6720 final IPackageManager pm = AppGlobals.getPackageManager(); 6721 try { 6722 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6723 if (packageUid != callingUid) { 6724 throw new SecurityException( 6725 "Package " + packageName + " does not belong to calling UID " + callingUid); 6726 } 6727 } catch (RemoteException e) { 6728 throw new SecurityException("Failed to verify package name ownership"); 6729 } 6730 6731 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6732 synchronized (this) { 6733 if (incoming) { 6734 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6735 if (perms == null) { 6736 Slog.w(TAG, "No permission grants found for " + packageName); 6737 } else { 6738 final int size = perms.size(); 6739 for (int i = 0; i < size; i++) { 6740 final UriPermission perm = perms.valueAt(i); 6741 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6742 result.add(perm.buildPersistedPublicApiObject()); 6743 } 6744 } 6745 } 6746 } else { 6747 final int size = mGrantedUriPermissions.size(); 6748 for (int i = 0; i < size; i++) { 6749 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6750 final int permsSize = perms.size(); 6751 for (int j = 0; j < permsSize; j++) { 6752 final UriPermission perm = perms.valueAt(j); 6753 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6754 result.add(perm.buildPersistedPublicApiObject()); 6755 } 6756 } 6757 } 6758 } 6759 } 6760 return new ParceledListSlice<android.content.UriPermission>(result); 6761 } 6762 6763 @Override 6764 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6765 synchronized (this) { 6766 ProcessRecord app = 6767 who != null ? getRecordForAppLocked(who) : null; 6768 if (app == null) return; 6769 6770 Message msg = Message.obtain(); 6771 msg.what = WAIT_FOR_DEBUGGER_MSG; 6772 msg.obj = app; 6773 msg.arg1 = waiting ? 1 : 0; 6774 mHandler.sendMessage(msg); 6775 } 6776 } 6777 6778 @Override 6779 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6780 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6781 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6782 outInfo.availMem = Process.getFreeMemory(); 6783 outInfo.totalMem = Process.getTotalMemory(); 6784 outInfo.threshold = homeAppMem; 6785 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6786 outInfo.hiddenAppThreshold = cachedAppMem; 6787 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6788 ProcessList.SERVICE_ADJ); 6789 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6790 ProcessList.VISIBLE_APP_ADJ); 6791 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6792 ProcessList.FOREGROUND_APP_ADJ); 6793 } 6794 6795 // ========================================================= 6796 // TASK MANAGEMENT 6797 // ========================================================= 6798 6799 @Override 6800 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6801 IThumbnailReceiver receiver) { 6802 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6803 6804 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6805 ActivityRecord topRecord = null; 6806 6807 synchronized(this) { 6808 if (localLOGV) Slog.v( 6809 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6810 + ", receiver=" + receiver); 6811 6812 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6813 != PackageManager.PERMISSION_GRANTED) { 6814 if (receiver != null) { 6815 // If the caller wants to wait for pending thumbnails, 6816 // it ain't gonna get them. 6817 try { 6818 receiver.finished(); 6819 } catch (RemoteException ex) { 6820 } 6821 } 6822 String msg = "Permission Denial: getTasks() from pid=" 6823 + Binder.getCallingPid() 6824 + ", uid=" + Binder.getCallingUid() 6825 + " requires " + android.Manifest.permission.GET_TASKS; 6826 Slog.w(TAG, msg); 6827 throw new SecurityException(msg); 6828 } 6829 6830 // TODO: Improve with MRU list from all ActivityStacks. 6831 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6832 6833 if (!pending.pendingRecords.isEmpty()) { 6834 mPendingThumbnails.add(pending); 6835 } 6836 } 6837 6838 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6839 6840 if (topRecord != null) { 6841 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6842 try { 6843 IApplicationThread topThumbnail = topRecord.app.thread; 6844 topThumbnail.requestThumbnail(topRecord.appToken); 6845 } catch (Exception e) { 6846 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6847 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6848 } 6849 } 6850 6851 if (pending.pendingRecords.isEmpty() && receiver != null) { 6852 // In this case all thumbnails were available and the client 6853 // is being asked to be told when the remaining ones come in... 6854 // which is unusually, since the top-most currently running 6855 // activity should never have a canned thumbnail! Oh well. 6856 try { 6857 receiver.finished(); 6858 } catch (RemoteException ex) { 6859 } 6860 } 6861 6862 return list; 6863 } 6864 6865 TaskRecord getMostRecentTask() { 6866 return mRecentTasks.get(0); 6867 } 6868 6869 @Override 6870 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6871 int flags, int userId) { 6872 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6873 false, true, "getRecentTasks", null); 6874 6875 synchronized (this) { 6876 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6877 "getRecentTasks()"); 6878 final boolean detailed = checkCallingPermission( 6879 android.Manifest.permission.GET_DETAILED_TASKS) 6880 == PackageManager.PERMISSION_GRANTED; 6881 6882 IPackageManager pm = AppGlobals.getPackageManager(); 6883 6884 final int N = mRecentTasks.size(); 6885 ArrayList<ActivityManager.RecentTaskInfo> res 6886 = new ArrayList<ActivityManager.RecentTaskInfo>( 6887 maxNum < N ? maxNum : N); 6888 6889 final Set<Integer> includedUsers; 6890 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 6891 includedUsers = getProfileIdsLocked(userId); 6892 } else { 6893 includedUsers = new HashSet<Integer>(); 6894 } 6895 includedUsers.add(Integer.valueOf(userId)); 6896 for (int i=0; i<N && maxNum > 0; i++) { 6897 TaskRecord tr = mRecentTasks.get(i); 6898 // Only add calling user or related users recent tasks 6899 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 6900 6901 // Return the entry if desired by the caller. We always return 6902 // the first entry, because callers always expect this to be the 6903 // foreground app. We may filter others if the caller has 6904 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6905 // we should exclude the entry. 6906 6907 if (i == 0 6908 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6909 || (tr.intent == null) 6910 || ((tr.intent.getFlags() 6911 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6912 ActivityManager.RecentTaskInfo rti 6913 = new ActivityManager.RecentTaskInfo(); 6914 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6915 rti.persistentId = tr.taskId; 6916 rti.baseIntent = new Intent( 6917 tr.intent != null ? tr.intent : tr.affinityIntent); 6918 if (!detailed) { 6919 rti.baseIntent.replaceExtras((Bundle)null); 6920 } 6921 rti.origActivity = tr.origActivity; 6922 rti.description = tr.lastDescription; 6923 rti.stackId = tr.stack.mStackId; 6924 rti.userId = tr.userId; 6925 6926 // Traverse upwards looking for any break between main task activities and 6927 // utility activities. 6928 final ArrayList<ActivityRecord> activities = tr.mActivities; 6929 int activityNdx; 6930 final int numActivities = activities.size(); 6931 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 6932 ++activityNdx) { 6933 final ActivityRecord r = activities.get(activityNdx); 6934 if (r.intent != null && 6935 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 6936 != 0) { 6937 break; 6938 } 6939 } 6940 // Traverse downwards starting below break looking for set label and icon. 6941 for (--activityNdx; activityNdx >= 0; --activityNdx) { 6942 final ActivityRecord r = activities.get(activityNdx); 6943 if (r.activityLabel != null || r.activityIcon != null) { 6944 rti.activityLabel = r.activityLabel; 6945 rti.activityIcon = r.activityIcon; 6946 break; 6947 } 6948 } 6949 6950 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6951 // Check whether this activity is currently available. 6952 try { 6953 if (rti.origActivity != null) { 6954 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6955 == null) { 6956 continue; 6957 } 6958 } else if (rti.baseIntent != null) { 6959 if (pm.queryIntentActivities(rti.baseIntent, 6960 null, 0, userId) == null) { 6961 continue; 6962 } 6963 } 6964 } catch (RemoteException e) { 6965 // Will never happen. 6966 } 6967 } 6968 6969 res.add(rti); 6970 maxNum--; 6971 } 6972 } 6973 return res; 6974 } 6975 } 6976 6977 private TaskRecord recentTaskForIdLocked(int id) { 6978 final int N = mRecentTasks.size(); 6979 for (int i=0; i<N; i++) { 6980 TaskRecord tr = mRecentTasks.get(i); 6981 if (tr.taskId == id) { 6982 return tr; 6983 } 6984 } 6985 return null; 6986 } 6987 6988 @Override 6989 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6990 synchronized (this) { 6991 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6992 "getTaskThumbnails()"); 6993 TaskRecord tr = recentTaskForIdLocked(id); 6994 if (tr != null) { 6995 return tr.getTaskThumbnailsLocked(); 6996 } 6997 } 6998 return null; 6999 } 7000 7001 @Override 7002 public Bitmap getTaskTopThumbnail(int id) { 7003 synchronized (this) { 7004 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7005 "getTaskTopThumbnail()"); 7006 TaskRecord tr = recentTaskForIdLocked(id); 7007 if (tr != null) { 7008 return tr.getTaskTopThumbnailLocked(); 7009 } 7010 } 7011 return null; 7012 } 7013 7014 @Override 7015 public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel, 7016 Bitmap activityIcon) { 7017 synchronized (this) { 7018 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7019 if (r != null) { 7020 r.activityLabel = activityLabel.toString(); 7021 r.activityIcon = activityIcon; 7022 } 7023 } 7024 } 7025 7026 @Override 7027 public boolean removeSubTask(int taskId, int subTaskIndex) { 7028 synchronized (this) { 7029 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7030 "removeSubTask()"); 7031 long ident = Binder.clearCallingIdentity(); 7032 try { 7033 TaskRecord tr = recentTaskForIdLocked(taskId); 7034 if (tr != null) { 7035 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7036 } 7037 return false; 7038 } finally { 7039 Binder.restoreCallingIdentity(ident); 7040 } 7041 } 7042 } 7043 7044 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7045 if (!pr.killedByAm) { 7046 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7047 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7048 pr.processName, pr.setAdj, reason); 7049 pr.killedByAm = true; 7050 Process.killProcessQuiet(pr.pid); 7051 } 7052 } 7053 7054 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7055 tr.disposeThumbnail(); 7056 mRecentTasks.remove(tr); 7057 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7058 Intent baseIntent = new Intent( 7059 tr.intent != null ? tr.intent : tr.affinityIntent); 7060 ComponentName component = baseIntent.getComponent(); 7061 if (component == null) { 7062 Slog.w(TAG, "Now component for base intent of task: " + tr); 7063 return; 7064 } 7065 7066 // Find any running services associated with this app. 7067 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7068 7069 if (killProcesses) { 7070 // Find any running processes associated with this app. 7071 final String pkg = component.getPackageName(); 7072 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7073 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7074 for (int i=0; i<pmap.size(); i++) { 7075 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7076 for (int j=0; j<uids.size(); j++) { 7077 ProcessRecord proc = uids.valueAt(j); 7078 if (proc.userId != tr.userId) { 7079 continue; 7080 } 7081 if (!proc.pkgList.containsKey(pkg)) { 7082 continue; 7083 } 7084 procs.add(proc); 7085 } 7086 } 7087 7088 // Kill the running processes. 7089 for (int i=0; i<procs.size(); i++) { 7090 ProcessRecord pr = procs.get(i); 7091 if (pr == mHomeProcess) { 7092 // Don't kill the home process along with tasks from the same package. 7093 continue; 7094 } 7095 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7096 killUnneededProcessLocked(pr, "remove task"); 7097 } else { 7098 pr.waitingToKill = "remove task"; 7099 } 7100 } 7101 } 7102 } 7103 7104 /** 7105 * Removes the task with the specified task id. 7106 * 7107 * @param taskId Identifier of the task to be removed. 7108 * @param flags Additional operational flags. May be 0 or 7109 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7110 * @return Returns true if the given task was found and removed. 7111 */ 7112 private boolean removeTaskByIdLocked(int taskId, int flags) { 7113 TaskRecord tr = recentTaskForIdLocked(taskId); 7114 if (tr != null) { 7115 tr.removeTaskActivitiesLocked(-1, false); 7116 cleanUpRemovedTaskLocked(tr, flags); 7117 return true; 7118 } 7119 return false; 7120 } 7121 7122 @Override 7123 public boolean removeTask(int taskId, int flags) { 7124 synchronized (this) { 7125 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7126 "removeTask()"); 7127 long ident = Binder.clearCallingIdentity(); 7128 try { 7129 return removeTaskByIdLocked(taskId, flags); 7130 } finally { 7131 Binder.restoreCallingIdentity(ident); 7132 } 7133 } 7134 } 7135 7136 /** 7137 * TODO: Add mController hook 7138 */ 7139 @Override 7140 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7141 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7142 "moveTaskToFront()"); 7143 7144 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7145 synchronized(this) { 7146 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7147 Binder.getCallingUid(), "Task to front")) { 7148 ActivityOptions.abort(options); 7149 return; 7150 } 7151 final long origId = Binder.clearCallingIdentity(); 7152 try { 7153 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7154 if (task == null) { 7155 return; 7156 } 7157 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7158 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7159 return; 7160 } 7161 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7162 } finally { 7163 Binder.restoreCallingIdentity(origId); 7164 } 7165 ActivityOptions.abort(options); 7166 } 7167 } 7168 7169 @Override 7170 public void moveTaskToBack(int taskId) { 7171 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7172 "moveTaskToBack()"); 7173 7174 synchronized(this) { 7175 TaskRecord tr = recentTaskForIdLocked(taskId); 7176 if (tr != null) { 7177 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7178 ActivityStack stack = tr.stack; 7179 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7180 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7181 Binder.getCallingUid(), "Task to back")) { 7182 return; 7183 } 7184 } 7185 final long origId = Binder.clearCallingIdentity(); 7186 try { 7187 stack.moveTaskToBackLocked(taskId, null); 7188 } finally { 7189 Binder.restoreCallingIdentity(origId); 7190 } 7191 } 7192 } 7193 } 7194 7195 /** 7196 * Moves an activity, and all of the other activities within the same task, to the bottom 7197 * of the history stack. The activity's order within the task is unchanged. 7198 * 7199 * @param token A reference to the activity we wish to move 7200 * @param nonRoot If false then this only works if the activity is the root 7201 * of a task; if true it will work for any activity in a task. 7202 * @return Returns true if the move completed, false if not. 7203 */ 7204 @Override 7205 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7206 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7207 synchronized(this) { 7208 final long origId = Binder.clearCallingIdentity(); 7209 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7210 if (taskId >= 0) { 7211 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7212 } 7213 Binder.restoreCallingIdentity(origId); 7214 } 7215 return false; 7216 } 7217 7218 @Override 7219 public void moveTaskBackwards(int task) { 7220 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7221 "moveTaskBackwards()"); 7222 7223 synchronized(this) { 7224 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7225 Binder.getCallingUid(), "Task backwards")) { 7226 return; 7227 } 7228 final long origId = Binder.clearCallingIdentity(); 7229 moveTaskBackwardsLocked(task); 7230 Binder.restoreCallingIdentity(origId); 7231 } 7232 } 7233 7234 private final void moveTaskBackwardsLocked(int task) { 7235 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7236 } 7237 7238 @Override 7239 public IBinder getHomeActivityToken() throws RemoteException { 7240 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7241 "getHomeActivityToken()"); 7242 synchronized (this) { 7243 return mStackSupervisor.getHomeActivityToken(); 7244 } 7245 } 7246 7247 @Override 7248 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7249 IActivityContainerCallback callback) throws RemoteException { 7250 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7251 "createActivityContainer()"); 7252 synchronized (this) { 7253 if (parentActivityToken == null) { 7254 throw new IllegalArgumentException("parent token must not be null"); 7255 } 7256 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7257 if (r == null) { 7258 return null; 7259 } 7260 if (callback == null) { 7261 throw new IllegalArgumentException("callback must not be null"); 7262 } 7263 return mStackSupervisor.createActivityContainer(r, callback); 7264 } 7265 } 7266 7267 @Override 7268 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7269 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7270 "deleteActivityContainer()"); 7271 synchronized (this) { 7272 mStackSupervisor.deleteActivityContainer(container); 7273 } 7274 } 7275 7276 @Override 7277 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7278 throws RemoteException { 7279 synchronized (this) { 7280 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7281 if (stack != null) { 7282 return stack.mActivityContainer; 7283 } 7284 return null; 7285 } 7286 } 7287 7288 @Override 7289 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7290 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7291 "moveTaskToStack()"); 7292 if (stackId == HOME_STACK_ID) { 7293 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7294 new RuntimeException("here").fillInStackTrace()); 7295 } 7296 synchronized (this) { 7297 long ident = Binder.clearCallingIdentity(); 7298 try { 7299 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7300 + stackId + " toTop=" + toTop); 7301 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7302 } finally { 7303 Binder.restoreCallingIdentity(ident); 7304 } 7305 } 7306 } 7307 7308 @Override 7309 public void resizeStack(int stackBoxId, Rect bounds) { 7310 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7311 "resizeStackBox()"); 7312 long ident = Binder.clearCallingIdentity(); 7313 try { 7314 mWindowManager.resizeStack(stackBoxId, bounds); 7315 } finally { 7316 Binder.restoreCallingIdentity(ident); 7317 } 7318 } 7319 7320 @Override 7321 public List<StackInfo> getAllStackInfos() { 7322 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7323 "getAllStackInfos()"); 7324 long ident = Binder.clearCallingIdentity(); 7325 try { 7326 synchronized (this) { 7327 return mStackSupervisor.getAllStackInfosLocked(); 7328 } 7329 } finally { 7330 Binder.restoreCallingIdentity(ident); 7331 } 7332 } 7333 7334 @Override 7335 public StackInfo getStackInfo(int stackId) { 7336 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7337 "getStackInfo()"); 7338 long ident = Binder.clearCallingIdentity(); 7339 try { 7340 synchronized (this) { 7341 return mStackSupervisor.getStackInfoLocked(stackId); 7342 } 7343 } finally { 7344 Binder.restoreCallingIdentity(ident); 7345 } 7346 } 7347 7348 @Override 7349 public boolean isInHomeStack(int taskId) { 7350 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7351 "getStackInfo()"); 7352 long ident = Binder.clearCallingIdentity(); 7353 try { 7354 synchronized (this) { 7355 TaskRecord tr = recentTaskForIdLocked(taskId); 7356 if (tr != null) { 7357 return tr.stack.isHomeStack(); 7358 } 7359 } 7360 } finally { 7361 Binder.restoreCallingIdentity(ident); 7362 } 7363 return false; 7364 } 7365 7366 @Override 7367 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7368 synchronized(this) { 7369 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7370 } 7371 } 7372 7373 private boolean isLockTaskAuthorized(ComponentName name) { 7374// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7375// "startLockTaskMode()"); 7376// DevicePolicyManager dpm = (DevicePolicyManager) 7377// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7378// return dpm != null && dpm.isLockTaskPermitted(name); 7379 return true; 7380 } 7381 7382 private void startLockTaskMode(TaskRecord task) { 7383 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7384 return; 7385 } 7386 long ident = Binder.clearCallingIdentity(); 7387 try { 7388 synchronized (this) { 7389 // Since we lost lock on task, make sure it is still there. 7390 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7391 if (task != null) { 7392 mStackSupervisor.setLockTaskModeLocked(task); 7393 } 7394 } 7395 } finally { 7396 Binder.restoreCallingIdentity(ident); 7397 } 7398 } 7399 7400 @Override 7401 public void startLockTaskMode(int taskId) { 7402 long ident = Binder.clearCallingIdentity(); 7403 try { 7404 final TaskRecord task; 7405 synchronized (this) { 7406 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7407 } 7408 if (task != null) { 7409 startLockTaskMode(task); 7410 } 7411 } finally { 7412 Binder.restoreCallingIdentity(ident); 7413 } 7414 } 7415 7416 @Override 7417 public void startLockTaskMode(IBinder token) { 7418 long ident = Binder.clearCallingIdentity(); 7419 try { 7420 final TaskRecord task; 7421 synchronized (this) { 7422 final ActivityRecord r = ActivityRecord.forToken(token); 7423 if (r == null) { 7424 return; 7425 } 7426 task = r.task; 7427 } 7428 if (task != null) { 7429 startLockTaskMode(task); 7430 } 7431 } finally { 7432 Binder.restoreCallingIdentity(ident); 7433 } 7434 } 7435 7436 @Override 7437 public void stopLockTaskMode() { 7438// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7439// "stopLockTaskMode()"); 7440 synchronized (this) { 7441 mStackSupervisor.setLockTaskModeLocked(null); 7442 } 7443 } 7444 7445 @Override 7446 public boolean isInLockTaskMode() { 7447 synchronized (this) { 7448 return mStackSupervisor.isInLockTaskMode(); 7449 } 7450 } 7451 7452 // ========================================================= 7453 // THUMBNAILS 7454 // ========================================================= 7455 7456 public void reportThumbnail(IBinder token, 7457 Bitmap thumbnail, CharSequence description) { 7458 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7459 final long origId = Binder.clearCallingIdentity(); 7460 sendPendingThumbnail(null, token, thumbnail, description, true); 7461 Binder.restoreCallingIdentity(origId); 7462 } 7463 7464 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7465 Bitmap thumbnail, CharSequence description, boolean always) { 7466 TaskRecord task; 7467 ArrayList<PendingThumbnailsRecord> receivers = null; 7468 7469 //System.out.println("Send pending thumbnail: " + r); 7470 7471 synchronized(this) { 7472 if (r == null) { 7473 r = ActivityRecord.isInStackLocked(token); 7474 if (r == null) { 7475 return; 7476 } 7477 } 7478 if (thumbnail == null && r.thumbHolder != null) { 7479 thumbnail = r.thumbHolder.lastThumbnail; 7480 description = r.thumbHolder.lastDescription; 7481 } 7482 if (thumbnail == null && !always) { 7483 // If there is no thumbnail, and this entry is not actually 7484 // going away, then abort for now and pick up the next 7485 // thumbnail we get. 7486 return; 7487 } 7488 task = r.task; 7489 7490 int N = mPendingThumbnails.size(); 7491 int i=0; 7492 while (i<N) { 7493 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7494 //System.out.println("Looking in " + pr.pendingRecords); 7495 if (pr.pendingRecords.remove(r)) { 7496 if (receivers == null) { 7497 receivers = new ArrayList<PendingThumbnailsRecord>(); 7498 } 7499 receivers.add(pr); 7500 if (pr.pendingRecords.size() == 0) { 7501 pr.finished = true; 7502 mPendingThumbnails.remove(i); 7503 N--; 7504 continue; 7505 } 7506 } 7507 i++; 7508 } 7509 } 7510 7511 if (receivers != null) { 7512 final int N = receivers.size(); 7513 for (int i=0; i<N; i++) { 7514 try { 7515 PendingThumbnailsRecord pr = receivers.get(i); 7516 pr.receiver.newThumbnail( 7517 task != null ? task.taskId : -1, thumbnail, description); 7518 if (pr.finished) { 7519 pr.receiver.finished(); 7520 } 7521 } catch (Exception e) { 7522 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7523 } 7524 } 7525 } 7526 } 7527 7528 // ========================================================= 7529 // CONTENT PROVIDERS 7530 // ========================================================= 7531 7532 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7533 List<ProviderInfo> providers = null; 7534 try { 7535 providers = AppGlobals.getPackageManager(). 7536 queryContentProviders(app.processName, app.uid, 7537 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7538 } catch (RemoteException ex) { 7539 } 7540 if (DEBUG_MU) 7541 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7542 int userId = app.userId; 7543 if (providers != null) { 7544 int N = providers.size(); 7545 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7546 for (int i=0; i<N; i++) { 7547 ProviderInfo cpi = 7548 (ProviderInfo)providers.get(i); 7549 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7550 cpi.name, cpi.flags); 7551 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7552 // This is a singleton provider, but a user besides the 7553 // default user is asking to initialize a process it runs 7554 // in... well, no, it doesn't actually run in this process, 7555 // it runs in the process of the default user. Get rid of it. 7556 providers.remove(i); 7557 N--; 7558 i--; 7559 continue; 7560 } 7561 7562 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7563 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7564 if (cpr == null) { 7565 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7566 mProviderMap.putProviderByClass(comp, cpr); 7567 } 7568 if (DEBUG_MU) 7569 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7570 app.pubProviders.put(cpi.name, cpr); 7571 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7572 // Don't add this if it is a platform component that is marked 7573 // to run in multiple processes, because this is actually 7574 // part of the framework so doesn't make sense to track as a 7575 // separate apk in the process. 7576 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7577 } 7578 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7579 } 7580 } 7581 return providers; 7582 } 7583 7584 /** 7585 * Check if {@link ProcessRecord} has a possible chance at accessing the 7586 * given {@link ProviderInfo}. Final permission checking is always done 7587 * in {@link ContentProvider}. 7588 */ 7589 private final String checkContentProviderPermissionLocked( 7590 ProviderInfo cpi, ProcessRecord r) { 7591 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7592 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7593 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7594 cpi.applicationInfo.uid, cpi.exported) 7595 == PackageManager.PERMISSION_GRANTED) { 7596 return null; 7597 } 7598 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7599 cpi.applicationInfo.uid, cpi.exported) 7600 == PackageManager.PERMISSION_GRANTED) { 7601 return null; 7602 } 7603 7604 PathPermission[] pps = cpi.pathPermissions; 7605 if (pps != null) { 7606 int i = pps.length; 7607 while (i > 0) { 7608 i--; 7609 PathPermission pp = pps[i]; 7610 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7611 cpi.applicationInfo.uid, cpi.exported) 7612 == PackageManager.PERMISSION_GRANTED) { 7613 return null; 7614 } 7615 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7616 cpi.applicationInfo.uid, cpi.exported) 7617 == PackageManager.PERMISSION_GRANTED) { 7618 return null; 7619 } 7620 } 7621 } 7622 7623 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7624 if (perms != null) { 7625 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7626 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7627 return null; 7628 } 7629 } 7630 } 7631 7632 String msg; 7633 if (!cpi.exported) { 7634 msg = "Permission Denial: opening provider " + cpi.name 7635 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7636 + ", uid=" + callingUid + ") that is not exported from uid " 7637 + cpi.applicationInfo.uid; 7638 } else { 7639 msg = "Permission Denial: opening provider " + cpi.name 7640 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7641 + ", uid=" + callingUid + ") requires " 7642 + cpi.readPermission + " or " + cpi.writePermission; 7643 } 7644 Slog.w(TAG, msg); 7645 return msg; 7646 } 7647 7648 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7649 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7650 if (r != null) { 7651 for (int i=0; i<r.conProviders.size(); i++) { 7652 ContentProviderConnection conn = r.conProviders.get(i); 7653 if (conn.provider == cpr) { 7654 if (DEBUG_PROVIDER) Slog.v(TAG, 7655 "Adding provider requested by " 7656 + r.processName + " from process " 7657 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7658 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7659 if (stable) { 7660 conn.stableCount++; 7661 conn.numStableIncs++; 7662 } else { 7663 conn.unstableCount++; 7664 conn.numUnstableIncs++; 7665 } 7666 return conn; 7667 } 7668 } 7669 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7670 if (stable) { 7671 conn.stableCount = 1; 7672 conn.numStableIncs = 1; 7673 } else { 7674 conn.unstableCount = 1; 7675 conn.numUnstableIncs = 1; 7676 } 7677 cpr.connections.add(conn); 7678 r.conProviders.add(conn); 7679 return conn; 7680 } 7681 cpr.addExternalProcessHandleLocked(externalProcessToken); 7682 return null; 7683 } 7684 7685 boolean decProviderCountLocked(ContentProviderConnection conn, 7686 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7687 if (conn != null) { 7688 cpr = conn.provider; 7689 if (DEBUG_PROVIDER) Slog.v(TAG, 7690 "Removing provider requested by " 7691 + conn.client.processName + " from process " 7692 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7693 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7694 if (stable) { 7695 conn.stableCount--; 7696 } else { 7697 conn.unstableCount--; 7698 } 7699 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7700 cpr.connections.remove(conn); 7701 conn.client.conProviders.remove(conn); 7702 return true; 7703 } 7704 return false; 7705 } 7706 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7707 return false; 7708 } 7709 7710 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7711 String name, IBinder token, boolean stable, int userId) { 7712 ContentProviderRecord cpr; 7713 ContentProviderConnection conn = null; 7714 ProviderInfo cpi = null; 7715 7716 synchronized(this) { 7717 ProcessRecord r = null; 7718 if (caller != null) { 7719 r = getRecordForAppLocked(caller); 7720 if (r == null) { 7721 throw new SecurityException( 7722 "Unable to find app for caller " + caller 7723 + " (pid=" + Binder.getCallingPid() 7724 + ") when getting content provider " + name); 7725 } 7726 } 7727 7728 // First check if this content provider has been published... 7729 cpr = mProviderMap.getProviderByName(name, userId); 7730 boolean providerRunning = cpr != null; 7731 if (providerRunning) { 7732 cpi = cpr.info; 7733 String msg; 7734 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7735 throw new SecurityException(msg); 7736 } 7737 7738 if (r != null && cpr.canRunHere(r)) { 7739 // This provider has been published or is in the process 7740 // of being published... but it is also allowed to run 7741 // in the caller's process, so don't make a connection 7742 // and just let the caller instantiate its own instance. 7743 ContentProviderHolder holder = cpr.newHolder(null); 7744 // don't give caller the provider object, it needs 7745 // to make its own. 7746 holder.provider = null; 7747 return holder; 7748 } 7749 7750 final long origId = Binder.clearCallingIdentity(); 7751 7752 // In this case the provider instance already exists, so we can 7753 // return it right away. 7754 conn = incProviderCountLocked(r, cpr, token, stable); 7755 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7756 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7757 // If this is a perceptible app accessing the provider, 7758 // make sure to count it as being accessed and thus 7759 // back up on the LRU list. This is good because 7760 // content providers are often expensive to start. 7761 updateLruProcessLocked(cpr.proc, false, null); 7762 } 7763 } 7764 7765 if (cpr.proc != null) { 7766 if (false) { 7767 if (cpr.name.flattenToShortString().equals( 7768 "com.android.providers.calendar/.CalendarProvider2")) { 7769 Slog.v(TAG, "****************** KILLING " 7770 + cpr.name.flattenToShortString()); 7771 Process.killProcess(cpr.proc.pid); 7772 } 7773 } 7774 boolean success = updateOomAdjLocked(cpr.proc); 7775 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7776 // NOTE: there is still a race here where a signal could be 7777 // pending on the process even though we managed to update its 7778 // adj level. Not sure what to do about this, but at least 7779 // the race is now smaller. 7780 if (!success) { 7781 // Uh oh... it looks like the provider's process 7782 // has been killed on us. We need to wait for a new 7783 // process to be started, and make sure its death 7784 // doesn't kill our process. 7785 Slog.i(TAG, 7786 "Existing provider " + cpr.name.flattenToShortString() 7787 + " is crashing; detaching " + r); 7788 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7789 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7790 if (!lastRef) { 7791 // This wasn't the last ref our process had on 7792 // the provider... we have now been killed, bail. 7793 return null; 7794 } 7795 providerRunning = false; 7796 conn = null; 7797 } 7798 } 7799 7800 Binder.restoreCallingIdentity(origId); 7801 } 7802 7803 boolean singleton; 7804 if (!providerRunning) { 7805 try { 7806 cpi = AppGlobals.getPackageManager(). 7807 resolveContentProvider(name, 7808 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7809 } catch (RemoteException ex) { 7810 } 7811 if (cpi == null) { 7812 return null; 7813 } 7814 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7815 cpi.name, cpi.flags); 7816 if (singleton) { 7817 userId = 0; 7818 } 7819 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7820 7821 String msg; 7822 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7823 throw new SecurityException(msg); 7824 } 7825 7826 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7827 && !cpi.processName.equals("system")) { 7828 // If this content provider does not run in the system 7829 // process, and the system is not yet ready to run other 7830 // processes, then fail fast instead of hanging. 7831 throw new IllegalArgumentException( 7832 "Attempt to launch content provider before system ready"); 7833 } 7834 7835 // Make sure that the user who owns this provider is started. If not, 7836 // we don't want to allow it to run. 7837 if (mStartedUsers.get(userId) == null) { 7838 Slog.w(TAG, "Unable to launch app " 7839 + cpi.applicationInfo.packageName + "/" 7840 + cpi.applicationInfo.uid + " for provider " 7841 + name + ": user " + userId + " is stopped"); 7842 return null; 7843 } 7844 7845 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7846 cpr = mProviderMap.getProviderByClass(comp, userId); 7847 final boolean firstClass = cpr == null; 7848 if (firstClass) { 7849 try { 7850 ApplicationInfo ai = 7851 AppGlobals.getPackageManager(). 7852 getApplicationInfo( 7853 cpi.applicationInfo.packageName, 7854 STOCK_PM_FLAGS, userId); 7855 if (ai == null) { 7856 Slog.w(TAG, "No package info for content provider " 7857 + cpi.name); 7858 return null; 7859 } 7860 ai = getAppInfoForUser(ai, userId); 7861 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7862 } catch (RemoteException ex) { 7863 // pm is in same process, this will never happen. 7864 } 7865 } 7866 7867 if (r != null && cpr.canRunHere(r)) { 7868 // If this is a multiprocess provider, then just return its 7869 // info and allow the caller to instantiate it. Only do 7870 // this if the provider is the same user as the caller's 7871 // process, or can run as root (so can be in any process). 7872 return cpr.newHolder(null); 7873 } 7874 7875 if (DEBUG_PROVIDER) { 7876 RuntimeException e = new RuntimeException("here"); 7877 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7878 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7879 } 7880 7881 // This is single process, and our app is now connecting to it. 7882 // See if we are already in the process of launching this 7883 // provider. 7884 final int N = mLaunchingProviders.size(); 7885 int i; 7886 for (i=0; i<N; i++) { 7887 if (mLaunchingProviders.get(i) == cpr) { 7888 break; 7889 } 7890 } 7891 7892 // If the provider is not already being launched, then get it 7893 // started. 7894 if (i >= N) { 7895 final long origId = Binder.clearCallingIdentity(); 7896 7897 try { 7898 // Content provider is now in use, its package can't be stopped. 7899 try { 7900 AppGlobals.getPackageManager().setPackageStoppedState( 7901 cpr.appInfo.packageName, false, userId); 7902 } catch (RemoteException e) { 7903 } catch (IllegalArgumentException e) { 7904 Slog.w(TAG, "Failed trying to unstop package " 7905 + cpr.appInfo.packageName + ": " + e); 7906 } 7907 7908 // Use existing process if already started 7909 ProcessRecord proc = getProcessRecordLocked( 7910 cpi.processName, cpr.appInfo.uid, false); 7911 if (proc != null && proc.thread != null) { 7912 if (DEBUG_PROVIDER) { 7913 Slog.d(TAG, "Installing in existing process " + proc); 7914 } 7915 proc.pubProviders.put(cpi.name, cpr); 7916 try { 7917 proc.thread.scheduleInstallProvider(cpi); 7918 } catch (RemoteException e) { 7919 } 7920 } else { 7921 proc = startProcessLocked(cpi.processName, 7922 cpr.appInfo, false, 0, "content provider", 7923 new ComponentName(cpi.applicationInfo.packageName, 7924 cpi.name), false, false, false); 7925 if (proc == null) { 7926 Slog.w(TAG, "Unable to launch app " 7927 + cpi.applicationInfo.packageName + "/" 7928 + cpi.applicationInfo.uid + " for provider " 7929 + name + ": process is bad"); 7930 return null; 7931 } 7932 } 7933 cpr.launchingApp = proc; 7934 mLaunchingProviders.add(cpr); 7935 } finally { 7936 Binder.restoreCallingIdentity(origId); 7937 } 7938 } 7939 7940 // Make sure the provider is published (the same provider class 7941 // may be published under multiple names). 7942 if (firstClass) { 7943 mProviderMap.putProviderByClass(comp, cpr); 7944 } 7945 7946 mProviderMap.putProviderByName(name, cpr); 7947 conn = incProviderCountLocked(r, cpr, token, stable); 7948 if (conn != null) { 7949 conn.waiting = true; 7950 } 7951 } 7952 } 7953 7954 // Wait for the provider to be published... 7955 synchronized (cpr) { 7956 while (cpr.provider == null) { 7957 if (cpr.launchingApp == null) { 7958 Slog.w(TAG, "Unable to launch app " 7959 + cpi.applicationInfo.packageName + "/" 7960 + cpi.applicationInfo.uid + " for provider " 7961 + name + ": launching app became null"); 7962 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7963 UserHandle.getUserId(cpi.applicationInfo.uid), 7964 cpi.applicationInfo.packageName, 7965 cpi.applicationInfo.uid, name); 7966 return null; 7967 } 7968 try { 7969 if (DEBUG_MU) { 7970 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7971 + cpr.launchingApp); 7972 } 7973 if (conn != null) { 7974 conn.waiting = true; 7975 } 7976 cpr.wait(); 7977 } catch (InterruptedException ex) { 7978 } finally { 7979 if (conn != null) { 7980 conn.waiting = false; 7981 } 7982 } 7983 } 7984 } 7985 return cpr != null ? cpr.newHolder(conn) : null; 7986 } 7987 7988 public final ContentProviderHolder getContentProvider( 7989 IApplicationThread caller, String name, int userId, boolean stable) { 7990 enforceNotIsolatedCaller("getContentProvider"); 7991 if (caller == null) { 7992 String msg = "null IApplicationThread when getting content provider " 7993 + name; 7994 Slog.w(TAG, msg); 7995 throw new SecurityException(msg); 7996 } 7997 7998 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7999 false, true, "getContentProvider", null); 8000 return getContentProviderImpl(caller, name, null, stable, userId); 8001 } 8002 8003 public ContentProviderHolder getContentProviderExternal( 8004 String name, int userId, IBinder token) { 8005 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8006 "Do not have permission in call getContentProviderExternal()"); 8007 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8008 false, true, "getContentProvider", null); 8009 return getContentProviderExternalUnchecked(name, token, userId); 8010 } 8011 8012 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8013 IBinder token, int userId) { 8014 return getContentProviderImpl(null, name, token, true, userId); 8015 } 8016 8017 /** 8018 * Drop a content provider from a ProcessRecord's bookkeeping 8019 */ 8020 public void removeContentProvider(IBinder connection, boolean stable) { 8021 enforceNotIsolatedCaller("removeContentProvider"); 8022 long ident = Binder.clearCallingIdentity(); 8023 try { 8024 synchronized (this) { 8025 ContentProviderConnection conn; 8026 try { 8027 conn = (ContentProviderConnection)connection; 8028 } catch (ClassCastException e) { 8029 String msg ="removeContentProvider: " + connection 8030 + " not a ContentProviderConnection"; 8031 Slog.w(TAG, msg); 8032 throw new IllegalArgumentException(msg); 8033 } 8034 if (conn == null) { 8035 throw new NullPointerException("connection is null"); 8036 } 8037 if (decProviderCountLocked(conn, null, null, stable)) { 8038 updateOomAdjLocked(); 8039 } 8040 } 8041 } finally { 8042 Binder.restoreCallingIdentity(ident); 8043 } 8044 } 8045 8046 public void removeContentProviderExternal(String name, IBinder token) { 8047 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8048 "Do not have permission in call removeContentProviderExternal()"); 8049 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8050 } 8051 8052 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8053 synchronized (this) { 8054 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8055 if(cpr == null) { 8056 //remove from mProvidersByClass 8057 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8058 return; 8059 } 8060 8061 //update content provider record entry info 8062 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8063 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8064 if (localCpr.hasExternalProcessHandles()) { 8065 if (localCpr.removeExternalProcessHandleLocked(token)) { 8066 updateOomAdjLocked(); 8067 } else { 8068 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8069 + " with no external reference for token: " 8070 + token + "."); 8071 } 8072 } else { 8073 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8074 + " with no external references."); 8075 } 8076 } 8077 } 8078 8079 public final void publishContentProviders(IApplicationThread caller, 8080 List<ContentProviderHolder> providers) { 8081 if (providers == null) { 8082 return; 8083 } 8084 8085 enforceNotIsolatedCaller("publishContentProviders"); 8086 synchronized (this) { 8087 final ProcessRecord r = getRecordForAppLocked(caller); 8088 if (DEBUG_MU) 8089 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8090 if (r == null) { 8091 throw new SecurityException( 8092 "Unable to find app for caller " + caller 8093 + " (pid=" + Binder.getCallingPid() 8094 + ") when publishing content providers"); 8095 } 8096 8097 final long origId = Binder.clearCallingIdentity(); 8098 8099 final int N = providers.size(); 8100 for (int i=0; i<N; i++) { 8101 ContentProviderHolder src = providers.get(i); 8102 if (src == null || src.info == null || src.provider == null) { 8103 continue; 8104 } 8105 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8106 if (DEBUG_MU) 8107 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8108 if (dst != null) { 8109 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8110 mProviderMap.putProviderByClass(comp, dst); 8111 String names[] = dst.info.authority.split(";"); 8112 for (int j = 0; j < names.length; j++) { 8113 mProviderMap.putProviderByName(names[j], dst); 8114 } 8115 8116 int NL = mLaunchingProviders.size(); 8117 int j; 8118 for (j=0; j<NL; j++) { 8119 if (mLaunchingProviders.get(j) == dst) { 8120 mLaunchingProviders.remove(j); 8121 j--; 8122 NL--; 8123 } 8124 } 8125 synchronized (dst) { 8126 dst.provider = src.provider; 8127 dst.proc = r; 8128 dst.notifyAll(); 8129 } 8130 updateOomAdjLocked(r); 8131 } 8132 } 8133 8134 Binder.restoreCallingIdentity(origId); 8135 } 8136 } 8137 8138 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8139 ContentProviderConnection conn; 8140 try { 8141 conn = (ContentProviderConnection)connection; 8142 } catch (ClassCastException e) { 8143 String msg ="refContentProvider: " + connection 8144 + " not a ContentProviderConnection"; 8145 Slog.w(TAG, msg); 8146 throw new IllegalArgumentException(msg); 8147 } 8148 if (conn == null) { 8149 throw new NullPointerException("connection is null"); 8150 } 8151 8152 synchronized (this) { 8153 if (stable > 0) { 8154 conn.numStableIncs += stable; 8155 } 8156 stable = conn.stableCount + stable; 8157 if (stable < 0) { 8158 throw new IllegalStateException("stableCount < 0: " + stable); 8159 } 8160 8161 if (unstable > 0) { 8162 conn.numUnstableIncs += unstable; 8163 } 8164 unstable = conn.unstableCount + unstable; 8165 if (unstable < 0) { 8166 throw new IllegalStateException("unstableCount < 0: " + unstable); 8167 } 8168 8169 if ((stable+unstable) <= 0) { 8170 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8171 + stable + " unstable=" + unstable); 8172 } 8173 conn.stableCount = stable; 8174 conn.unstableCount = unstable; 8175 return !conn.dead; 8176 } 8177 } 8178 8179 public void unstableProviderDied(IBinder connection) { 8180 ContentProviderConnection conn; 8181 try { 8182 conn = (ContentProviderConnection)connection; 8183 } catch (ClassCastException e) { 8184 String msg ="refContentProvider: " + connection 8185 + " not a ContentProviderConnection"; 8186 Slog.w(TAG, msg); 8187 throw new IllegalArgumentException(msg); 8188 } 8189 if (conn == null) { 8190 throw new NullPointerException("connection is null"); 8191 } 8192 8193 // Safely retrieve the content provider associated with the connection. 8194 IContentProvider provider; 8195 synchronized (this) { 8196 provider = conn.provider.provider; 8197 } 8198 8199 if (provider == null) { 8200 // Um, yeah, we're way ahead of you. 8201 return; 8202 } 8203 8204 // Make sure the caller is being honest with us. 8205 if (provider.asBinder().pingBinder()) { 8206 // Er, no, still looks good to us. 8207 synchronized (this) { 8208 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8209 + " says " + conn + " died, but we don't agree"); 8210 return; 8211 } 8212 } 8213 8214 // Well look at that! It's dead! 8215 synchronized (this) { 8216 if (conn.provider.provider != provider) { 8217 // But something changed... good enough. 8218 return; 8219 } 8220 8221 ProcessRecord proc = conn.provider.proc; 8222 if (proc == null || proc.thread == null) { 8223 // Seems like the process is already cleaned up. 8224 return; 8225 } 8226 8227 // As far as we're concerned, this is just like receiving a 8228 // death notification... just a bit prematurely. 8229 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8230 + ") early provider death"); 8231 final long ident = Binder.clearCallingIdentity(); 8232 try { 8233 appDiedLocked(proc, proc.pid, proc.thread); 8234 } finally { 8235 Binder.restoreCallingIdentity(ident); 8236 } 8237 } 8238 } 8239 8240 @Override 8241 public void appNotRespondingViaProvider(IBinder connection) { 8242 enforceCallingPermission( 8243 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8244 8245 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8246 if (conn == null) { 8247 Slog.w(TAG, "ContentProviderConnection is null"); 8248 return; 8249 } 8250 8251 final ProcessRecord host = conn.provider.proc; 8252 if (host == null) { 8253 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8254 return; 8255 } 8256 8257 final long token = Binder.clearCallingIdentity(); 8258 try { 8259 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8260 } finally { 8261 Binder.restoreCallingIdentity(token); 8262 } 8263 } 8264 8265 public final void installSystemProviders() { 8266 List<ProviderInfo> providers; 8267 synchronized (this) { 8268 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8269 providers = generateApplicationProvidersLocked(app); 8270 if (providers != null) { 8271 for (int i=providers.size()-1; i>=0; i--) { 8272 ProviderInfo pi = (ProviderInfo)providers.get(i); 8273 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8274 Slog.w(TAG, "Not installing system proc provider " + pi.name 8275 + ": not system .apk"); 8276 providers.remove(i); 8277 } 8278 } 8279 } 8280 } 8281 if (providers != null) { 8282 mSystemThread.installSystemProviders(providers); 8283 } 8284 8285 mCoreSettingsObserver = new CoreSettingsObserver(this); 8286 8287 mUsageStatsService.monitorPackages(); 8288 } 8289 8290 /** 8291 * Allows app to retrieve the MIME type of a URI without having permission 8292 * to access its content provider. 8293 * 8294 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8295 * 8296 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8297 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8298 */ 8299 public String getProviderMimeType(Uri uri, int userId) { 8300 enforceNotIsolatedCaller("getProviderMimeType"); 8301 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8302 userId, false, true, "getProviderMimeType", null); 8303 final String name = uri.getAuthority(); 8304 final long ident = Binder.clearCallingIdentity(); 8305 ContentProviderHolder holder = null; 8306 8307 try { 8308 holder = getContentProviderExternalUnchecked(name, null, userId); 8309 if (holder != null) { 8310 return holder.provider.getType(uri); 8311 } 8312 } catch (RemoteException e) { 8313 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8314 return null; 8315 } finally { 8316 if (holder != null) { 8317 removeContentProviderExternalUnchecked(name, null, userId); 8318 } 8319 Binder.restoreCallingIdentity(ident); 8320 } 8321 8322 return null; 8323 } 8324 8325 // ========================================================= 8326 // GLOBAL MANAGEMENT 8327 // ========================================================= 8328 8329 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8330 boolean isolated) { 8331 String proc = customProcess != null ? customProcess : info.processName; 8332 BatteryStatsImpl.Uid.Proc ps = null; 8333 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8334 int uid = info.uid; 8335 if (isolated) { 8336 int userId = UserHandle.getUserId(uid); 8337 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8338 while (true) { 8339 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8340 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8341 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8342 } 8343 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8344 mNextIsolatedProcessUid++; 8345 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8346 // No process for this uid, use it. 8347 break; 8348 } 8349 stepsLeft--; 8350 if (stepsLeft <= 0) { 8351 return null; 8352 } 8353 } 8354 } 8355 return new ProcessRecord(stats, info, proc, uid); 8356 } 8357 8358 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8359 ProcessRecord app; 8360 if (!isolated) { 8361 app = getProcessRecordLocked(info.processName, info.uid, true); 8362 } else { 8363 app = null; 8364 } 8365 8366 if (app == null) { 8367 app = newProcessRecordLocked(info, null, isolated); 8368 mProcessNames.put(info.processName, app.uid, app); 8369 if (isolated) { 8370 mIsolatedProcesses.put(app.uid, app); 8371 } 8372 updateLruProcessLocked(app, false, null); 8373 updateOomAdjLocked(); 8374 } 8375 8376 // This package really, really can not be stopped. 8377 try { 8378 AppGlobals.getPackageManager().setPackageStoppedState( 8379 info.packageName, false, UserHandle.getUserId(app.uid)); 8380 } catch (RemoteException e) { 8381 } catch (IllegalArgumentException e) { 8382 Slog.w(TAG, "Failed trying to unstop package " 8383 + info.packageName + ": " + e); 8384 } 8385 8386 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8387 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8388 app.persistent = true; 8389 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8390 } 8391 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8392 mPersistentStartingProcesses.add(app); 8393 startProcessLocked(app, "added application", app.processName); 8394 } 8395 8396 return app; 8397 } 8398 8399 public void unhandledBack() { 8400 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8401 "unhandledBack()"); 8402 8403 synchronized(this) { 8404 final long origId = Binder.clearCallingIdentity(); 8405 try { 8406 getFocusedStack().unhandledBackLocked(); 8407 } finally { 8408 Binder.restoreCallingIdentity(origId); 8409 } 8410 } 8411 } 8412 8413 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8414 enforceNotIsolatedCaller("openContentUri"); 8415 final int userId = UserHandle.getCallingUserId(); 8416 String name = uri.getAuthority(); 8417 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8418 ParcelFileDescriptor pfd = null; 8419 if (cph != null) { 8420 // We record the binder invoker's uid in thread-local storage before 8421 // going to the content provider to open the file. Later, in the code 8422 // that handles all permissions checks, we look for this uid and use 8423 // that rather than the Activity Manager's own uid. The effect is that 8424 // we do the check against the caller's permissions even though it looks 8425 // to the content provider like the Activity Manager itself is making 8426 // the request. 8427 sCallerIdentity.set(new Identity( 8428 Binder.getCallingPid(), Binder.getCallingUid())); 8429 try { 8430 pfd = cph.provider.openFile(null, uri, "r", null); 8431 } catch (FileNotFoundException e) { 8432 // do nothing; pfd will be returned null 8433 } finally { 8434 // Ensure that whatever happens, we clean up the identity state 8435 sCallerIdentity.remove(); 8436 } 8437 8438 // We've got the fd now, so we're done with the provider. 8439 removeContentProviderExternalUnchecked(name, null, userId); 8440 } else { 8441 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8442 } 8443 return pfd; 8444 } 8445 8446 // Actually is sleeping or shutting down or whatever else in the future 8447 // is an inactive state. 8448 public boolean isSleepingOrShuttingDown() { 8449 return mSleeping || mShuttingDown; 8450 } 8451 8452 void goingToSleep() { 8453 synchronized(this) { 8454 mWentToSleep = true; 8455 updateEventDispatchingLocked(); 8456 8457 if (!mSleeping) { 8458 mSleeping = true; 8459 mStackSupervisor.goingToSleepLocked(); 8460 8461 // Initialize the wake times of all processes. 8462 checkExcessivePowerUsageLocked(false); 8463 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8464 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8465 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8466 } 8467 } 8468 } 8469 8470 @Override 8471 public boolean shutdown(int timeout) { 8472 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8473 != PackageManager.PERMISSION_GRANTED) { 8474 throw new SecurityException("Requires permission " 8475 + android.Manifest.permission.SHUTDOWN); 8476 } 8477 8478 boolean timedout = false; 8479 8480 synchronized(this) { 8481 mShuttingDown = true; 8482 updateEventDispatchingLocked(); 8483 timedout = mStackSupervisor.shutdownLocked(timeout); 8484 } 8485 8486 mAppOpsService.shutdown(); 8487 mUsageStatsService.shutdown(); 8488 mBatteryStatsService.shutdown(); 8489 synchronized (this) { 8490 mProcessStats.shutdownLocked(); 8491 } 8492 8493 return timedout; 8494 } 8495 8496 public final void activitySlept(IBinder token) { 8497 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8498 8499 final long origId = Binder.clearCallingIdentity(); 8500 8501 synchronized (this) { 8502 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8503 if (r != null) { 8504 mStackSupervisor.activitySleptLocked(r); 8505 } 8506 } 8507 8508 Binder.restoreCallingIdentity(origId); 8509 } 8510 8511 void logLockScreen(String msg) { 8512 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8513 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8514 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8515 mStackSupervisor.mDismissKeyguardOnNextActivity); 8516 } 8517 8518 private void comeOutOfSleepIfNeededLocked() { 8519 if (!mWentToSleep && !mLockScreenShown) { 8520 if (mSleeping) { 8521 mSleeping = false; 8522 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8523 } 8524 } 8525 } 8526 8527 void wakingUp() { 8528 synchronized(this) { 8529 mWentToSleep = false; 8530 updateEventDispatchingLocked(); 8531 comeOutOfSleepIfNeededLocked(); 8532 } 8533 } 8534 8535 private void updateEventDispatchingLocked() { 8536 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8537 } 8538 8539 public void setLockScreenShown(boolean shown) { 8540 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8541 != PackageManager.PERMISSION_GRANTED) { 8542 throw new SecurityException("Requires permission " 8543 + android.Manifest.permission.DEVICE_POWER); 8544 } 8545 8546 synchronized(this) { 8547 long ident = Binder.clearCallingIdentity(); 8548 try { 8549 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8550 mLockScreenShown = shown; 8551 comeOutOfSleepIfNeededLocked(); 8552 } finally { 8553 Binder.restoreCallingIdentity(ident); 8554 } 8555 } 8556 } 8557 8558 public void stopAppSwitches() { 8559 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8560 != PackageManager.PERMISSION_GRANTED) { 8561 throw new SecurityException("Requires permission " 8562 + android.Manifest.permission.STOP_APP_SWITCHES); 8563 } 8564 8565 synchronized(this) { 8566 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8567 + APP_SWITCH_DELAY_TIME; 8568 mDidAppSwitch = false; 8569 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8570 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8571 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8572 } 8573 } 8574 8575 public void resumeAppSwitches() { 8576 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8577 != PackageManager.PERMISSION_GRANTED) { 8578 throw new SecurityException("Requires permission " 8579 + android.Manifest.permission.STOP_APP_SWITCHES); 8580 } 8581 8582 synchronized(this) { 8583 // Note that we don't execute any pending app switches... we will 8584 // let those wait until either the timeout, or the next start 8585 // activity request. 8586 mAppSwitchesAllowedTime = 0; 8587 } 8588 } 8589 8590 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8591 String name) { 8592 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8593 return true; 8594 } 8595 8596 final int perm = checkComponentPermission( 8597 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8598 callingUid, -1, true); 8599 if (perm == PackageManager.PERMISSION_GRANTED) { 8600 return true; 8601 } 8602 8603 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8604 return false; 8605 } 8606 8607 public void setDebugApp(String packageName, boolean waitForDebugger, 8608 boolean persistent) { 8609 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8610 "setDebugApp()"); 8611 8612 long ident = Binder.clearCallingIdentity(); 8613 try { 8614 // Note that this is not really thread safe if there are multiple 8615 // callers into it at the same time, but that's not a situation we 8616 // care about. 8617 if (persistent) { 8618 final ContentResolver resolver = mContext.getContentResolver(); 8619 Settings.Global.putString( 8620 resolver, Settings.Global.DEBUG_APP, 8621 packageName); 8622 Settings.Global.putInt( 8623 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8624 waitForDebugger ? 1 : 0); 8625 } 8626 8627 synchronized (this) { 8628 if (!persistent) { 8629 mOrigDebugApp = mDebugApp; 8630 mOrigWaitForDebugger = mWaitForDebugger; 8631 } 8632 mDebugApp = packageName; 8633 mWaitForDebugger = waitForDebugger; 8634 mDebugTransient = !persistent; 8635 if (packageName != null) { 8636 forceStopPackageLocked(packageName, -1, false, false, true, true, 8637 false, UserHandle.USER_ALL, "set debug app"); 8638 } 8639 } 8640 } finally { 8641 Binder.restoreCallingIdentity(ident); 8642 } 8643 } 8644 8645 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8646 synchronized (this) { 8647 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8648 if (!isDebuggable) { 8649 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8650 throw new SecurityException("Process not debuggable: " + app.packageName); 8651 } 8652 } 8653 8654 mOpenGlTraceApp = processName; 8655 } 8656 } 8657 8658 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8659 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8660 synchronized (this) { 8661 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8662 if (!isDebuggable) { 8663 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8664 throw new SecurityException("Process not debuggable: " + app.packageName); 8665 } 8666 } 8667 mProfileApp = processName; 8668 mProfileFile = profileFile; 8669 if (mProfileFd != null) { 8670 try { 8671 mProfileFd.close(); 8672 } catch (IOException e) { 8673 } 8674 mProfileFd = null; 8675 } 8676 mProfileFd = profileFd; 8677 mProfileType = 0; 8678 mAutoStopProfiler = autoStopProfiler; 8679 } 8680 } 8681 8682 @Override 8683 public void setAlwaysFinish(boolean enabled) { 8684 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8685 "setAlwaysFinish()"); 8686 8687 Settings.Global.putInt( 8688 mContext.getContentResolver(), 8689 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8690 8691 synchronized (this) { 8692 mAlwaysFinishActivities = enabled; 8693 } 8694 } 8695 8696 @Override 8697 public void setActivityController(IActivityController controller) { 8698 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8699 "setActivityController()"); 8700 synchronized (this) { 8701 mController = controller; 8702 Watchdog.getInstance().setActivityController(controller); 8703 } 8704 } 8705 8706 @Override 8707 public void setUserIsMonkey(boolean userIsMonkey) { 8708 synchronized (this) { 8709 synchronized (mPidsSelfLocked) { 8710 final int callingPid = Binder.getCallingPid(); 8711 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8712 if (precessRecord == null) { 8713 throw new SecurityException("Unknown process: " + callingPid); 8714 } 8715 if (precessRecord.instrumentationUiAutomationConnection == null) { 8716 throw new SecurityException("Only an instrumentation process " 8717 + "with a UiAutomation can call setUserIsMonkey"); 8718 } 8719 } 8720 mUserIsMonkey = userIsMonkey; 8721 } 8722 } 8723 8724 @Override 8725 public boolean isUserAMonkey() { 8726 synchronized (this) { 8727 // If there is a controller also implies the user is a monkey. 8728 return (mUserIsMonkey || mController != null); 8729 } 8730 } 8731 8732 public void requestBugReport() { 8733 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8734 SystemProperties.set("ctl.start", "bugreport"); 8735 } 8736 8737 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8738 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8739 } 8740 8741 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8742 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8743 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8744 } 8745 return KEY_DISPATCHING_TIMEOUT; 8746 } 8747 8748 @Override 8749 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8750 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8751 != PackageManager.PERMISSION_GRANTED) { 8752 throw new SecurityException("Requires permission " 8753 + android.Manifest.permission.FILTER_EVENTS); 8754 } 8755 ProcessRecord proc; 8756 long timeout; 8757 synchronized (this) { 8758 synchronized (mPidsSelfLocked) { 8759 proc = mPidsSelfLocked.get(pid); 8760 } 8761 timeout = getInputDispatchingTimeoutLocked(proc); 8762 } 8763 8764 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8765 return -1; 8766 } 8767 8768 return timeout; 8769 } 8770 8771 /** 8772 * Handle input dispatching timeouts. 8773 * Returns whether input dispatching should be aborted or not. 8774 */ 8775 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8776 final ActivityRecord activity, final ActivityRecord parent, 8777 final boolean aboveSystem, String reason) { 8778 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8779 != PackageManager.PERMISSION_GRANTED) { 8780 throw new SecurityException("Requires permission " 8781 + android.Manifest.permission.FILTER_EVENTS); 8782 } 8783 8784 final String annotation; 8785 if (reason == null) { 8786 annotation = "Input dispatching timed out"; 8787 } else { 8788 annotation = "Input dispatching timed out (" + reason + ")"; 8789 } 8790 8791 if (proc != null) { 8792 synchronized (this) { 8793 if (proc.debugging) { 8794 return false; 8795 } 8796 8797 if (mDidDexOpt) { 8798 // Give more time since we were dexopting. 8799 mDidDexOpt = false; 8800 return false; 8801 } 8802 8803 if (proc.instrumentationClass != null) { 8804 Bundle info = new Bundle(); 8805 info.putString("shortMsg", "keyDispatchingTimedOut"); 8806 info.putString("longMsg", annotation); 8807 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8808 return true; 8809 } 8810 } 8811 mHandler.post(new Runnable() { 8812 @Override 8813 public void run() { 8814 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8815 } 8816 }); 8817 } 8818 8819 return true; 8820 } 8821 8822 public Bundle getAssistContextExtras(int requestType) { 8823 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8824 "getAssistContextExtras()"); 8825 PendingAssistExtras pae; 8826 Bundle extras = new Bundle(); 8827 synchronized (this) { 8828 ActivityRecord activity = getFocusedStack().mResumedActivity; 8829 if (activity == null) { 8830 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8831 return null; 8832 } 8833 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8834 if (activity.app == null || activity.app.thread == null) { 8835 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8836 return extras; 8837 } 8838 if (activity.app.pid == Binder.getCallingPid()) { 8839 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8840 return extras; 8841 } 8842 pae = new PendingAssistExtras(activity); 8843 try { 8844 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8845 requestType); 8846 mPendingAssistExtras.add(pae); 8847 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8848 } catch (RemoteException e) { 8849 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8850 return extras; 8851 } 8852 } 8853 synchronized (pae) { 8854 while (!pae.haveResult) { 8855 try { 8856 pae.wait(); 8857 } catch (InterruptedException e) { 8858 } 8859 } 8860 if (pae.result != null) { 8861 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8862 } 8863 } 8864 synchronized (this) { 8865 mPendingAssistExtras.remove(pae); 8866 mHandler.removeCallbacks(pae); 8867 } 8868 return extras; 8869 } 8870 8871 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8872 PendingAssistExtras pae = (PendingAssistExtras)token; 8873 synchronized (pae) { 8874 pae.result = extras; 8875 pae.haveResult = true; 8876 pae.notifyAll(); 8877 } 8878 } 8879 8880 public void registerProcessObserver(IProcessObserver observer) { 8881 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8882 "registerProcessObserver()"); 8883 synchronized (this) { 8884 mProcessObservers.register(observer); 8885 } 8886 } 8887 8888 @Override 8889 public void unregisterProcessObserver(IProcessObserver observer) { 8890 synchronized (this) { 8891 mProcessObservers.unregister(observer); 8892 } 8893 } 8894 8895 @Override 8896 public boolean convertFromTranslucent(IBinder token) { 8897 final long origId = Binder.clearCallingIdentity(); 8898 try { 8899 synchronized (this) { 8900 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8901 if (r == null) { 8902 return false; 8903 } 8904 if (r.changeWindowTranslucency(true)) { 8905 mWindowManager.setAppFullscreen(token, true); 8906 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8907 return true; 8908 } 8909 return false; 8910 } 8911 } finally { 8912 Binder.restoreCallingIdentity(origId); 8913 } 8914 } 8915 8916 @Override 8917 public boolean convertToTranslucent(IBinder token) { 8918 final long origId = Binder.clearCallingIdentity(); 8919 try { 8920 synchronized (this) { 8921 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8922 if (r == null) { 8923 return false; 8924 } 8925 if (r.changeWindowTranslucency(false)) { 8926 r.task.stack.convertToTranslucent(r); 8927 mWindowManager.setAppFullscreen(token, false); 8928 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8929 return true; 8930 } 8931 return false; 8932 } 8933 } finally { 8934 Binder.restoreCallingIdentity(origId); 8935 } 8936 } 8937 8938 @Override 8939 public void setImmersive(IBinder token, boolean immersive) { 8940 synchronized(this) { 8941 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8942 if (r == null) { 8943 throw new IllegalArgumentException(); 8944 } 8945 r.immersive = immersive; 8946 8947 // update associated state if we're frontmost 8948 if (r == mFocusedActivity) { 8949 if (DEBUG_IMMERSIVE) { 8950 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8951 } 8952 applyUpdateLockStateLocked(r); 8953 } 8954 } 8955 } 8956 8957 @Override 8958 public boolean isImmersive(IBinder token) { 8959 synchronized (this) { 8960 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8961 if (r == null) { 8962 throw new IllegalArgumentException(); 8963 } 8964 return r.immersive; 8965 } 8966 } 8967 8968 public boolean isTopActivityImmersive() { 8969 enforceNotIsolatedCaller("startActivity"); 8970 synchronized (this) { 8971 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8972 return (r != null) ? r.immersive : false; 8973 } 8974 } 8975 8976 public final void enterSafeMode() { 8977 synchronized(this) { 8978 // It only makes sense to do this before the system is ready 8979 // and started launching other packages. 8980 if (!mSystemReady) { 8981 try { 8982 AppGlobals.getPackageManager().enterSafeMode(); 8983 } catch (RemoteException e) { 8984 } 8985 } 8986 8987 mSafeMode = true; 8988 } 8989 } 8990 8991 public final void showSafeModeOverlay() { 8992 View v = LayoutInflater.from(mContext).inflate( 8993 com.android.internal.R.layout.safe_mode, null); 8994 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8995 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8996 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8997 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8998 lp.gravity = Gravity.BOTTOM | Gravity.START; 8999 lp.format = v.getBackground().getOpacity(); 9000 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9001 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9002 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9003 ((WindowManager)mContext.getSystemService( 9004 Context.WINDOW_SERVICE)).addView(v, lp); 9005 } 9006 9007 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9008 if (!(sender instanceof PendingIntentRecord)) { 9009 return; 9010 } 9011 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9012 synchronized (stats) { 9013 if (mBatteryStatsService.isOnBattery()) { 9014 mBatteryStatsService.enforceCallingPermission(); 9015 PendingIntentRecord rec = (PendingIntentRecord)sender; 9016 int MY_UID = Binder.getCallingUid(); 9017 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9018 BatteryStatsImpl.Uid.Pkg pkg = 9019 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9020 sourcePkg != null ? sourcePkg : rec.key.packageName); 9021 pkg.incWakeupsLocked(); 9022 } 9023 } 9024 } 9025 9026 public boolean killPids(int[] pids, String pReason, boolean secure) { 9027 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9028 throw new SecurityException("killPids only available to the system"); 9029 } 9030 String reason = (pReason == null) ? "Unknown" : pReason; 9031 // XXX Note: don't acquire main activity lock here, because the window 9032 // manager calls in with its locks held. 9033 9034 boolean killed = false; 9035 synchronized (mPidsSelfLocked) { 9036 int[] types = new int[pids.length]; 9037 int worstType = 0; 9038 for (int i=0; i<pids.length; i++) { 9039 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9040 if (proc != null) { 9041 int type = proc.setAdj; 9042 types[i] = type; 9043 if (type > worstType) { 9044 worstType = type; 9045 } 9046 } 9047 } 9048 9049 // If the worst oom_adj is somewhere in the cached proc LRU range, 9050 // then constrain it so we will kill all cached procs. 9051 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9052 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9053 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9054 } 9055 9056 // If this is not a secure call, don't let it kill processes that 9057 // are important. 9058 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9059 worstType = ProcessList.SERVICE_ADJ; 9060 } 9061 9062 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9063 for (int i=0; i<pids.length; i++) { 9064 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9065 if (proc == null) { 9066 continue; 9067 } 9068 int adj = proc.setAdj; 9069 if (adj >= worstType && !proc.killedByAm) { 9070 killUnneededProcessLocked(proc, reason); 9071 killed = true; 9072 } 9073 } 9074 } 9075 return killed; 9076 } 9077 9078 @Override 9079 public void killUid(int uid, String reason) { 9080 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9081 throw new SecurityException("killUid only available to the system"); 9082 } 9083 synchronized (this) { 9084 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9085 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9086 reason != null ? reason : "kill uid"); 9087 } 9088 } 9089 9090 @Override 9091 public boolean killProcessesBelowForeground(String reason) { 9092 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9093 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9094 } 9095 9096 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9097 } 9098 9099 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9100 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9101 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9102 } 9103 9104 boolean killed = false; 9105 synchronized (mPidsSelfLocked) { 9106 final int size = mPidsSelfLocked.size(); 9107 for (int i = 0; i < size; i++) { 9108 final int pid = mPidsSelfLocked.keyAt(i); 9109 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9110 if (proc == null) continue; 9111 9112 final int adj = proc.setAdj; 9113 if (adj > belowAdj && !proc.killedByAm) { 9114 killUnneededProcessLocked(proc, reason); 9115 killed = true; 9116 } 9117 } 9118 } 9119 return killed; 9120 } 9121 9122 @Override 9123 public void hang(final IBinder who, boolean allowRestart) { 9124 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9125 != PackageManager.PERMISSION_GRANTED) { 9126 throw new SecurityException("Requires permission " 9127 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9128 } 9129 9130 final IBinder.DeathRecipient death = new DeathRecipient() { 9131 @Override 9132 public void binderDied() { 9133 synchronized (this) { 9134 notifyAll(); 9135 } 9136 } 9137 }; 9138 9139 try { 9140 who.linkToDeath(death, 0); 9141 } catch (RemoteException e) { 9142 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9143 return; 9144 } 9145 9146 synchronized (this) { 9147 Watchdog.getInstance().setAllowRestart(allowRestart); 9148 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9149 synchronized (death) { 9150 while (who.isBinderAlive()) { 9151 try { 9152 death.wait(); 9153 } catch (InterruptedException e) { 9154 } 9155 } 9156 } 9157 Watchdog.getInstance().setAllowRestart(true); 9158 } 9159 } 9160 9161 @Override 9162 public void restart() { 9163 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9164 != PackageManager.PERMISSION_GRANTED) { 9165 throw new SecurityException("Requires permission " 9166 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9167 } 9168 9169 Log.i(TAG, "Sending shutdown broadcast..."); 9170 9171 BroadcastReceiver br = new BroadcastReceiver() { 9172 @Override public void onReceive(Context context, Intent intent) { 9173 // Now the broadcast is done, finish up the low-level shutdown. 9174 Log.i(TAG, "Shutting down activity manager..."); 9175 shutdown(10000); 9176 Log.i(TAG, "Shutdown complete, restarting!"); 9177 Process.killProcess(Process.myPid()); 9178 System.exit(10); 9179 } 9180 }; 9181 9182 // First send the high-level shut down broadcast. 9183 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9184 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9185 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9186 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9187 mContext.sendOrderedBroadcastAsUser(intent, 9188 UserHandle.ALL, null, br, mHandler, 0, null, null); 9189 */ 9190 br.onReceive(mContext, intent); 9191 } 9192 9193 private long getLowRamTimeSinceIdle(long now) { 9194 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9195 } 9196 9197 @Override 9198 public void performIdleMaintenance() { 9199 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9200 != PackageManager.PERMISSION_GRANTED) { 9201 throw new SecurityException("Requires permission " 9202 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9203 } 9204 9205 synchronized (this) { 9206 final long now = SystemClock.uptimeMillis(); 9207 final long timeSinceLastIdle = now - mLastIdleTime; 9208 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9209 mLastIdleTime = now; 9210 mLowRamTimeSinceLastIdle = 0; 9211 if (mLowRamStartTime != 0) { 9212 mLowRamStartTime = now; 9213 } 9214 9215 StringBuilder sb = new StringBuilder(128); 9216 sb.append("Idle maintenance over "); 9217 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9218 sb.append(" low RAM for "); 9219 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9220 Slog.i(TAG, sb.toString()); 9221 9222 // If at least 1/3 of our time since the last idle period has been spent 9223 // with RAM low, then we want to kill processes. 9224 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9225 9226 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9227 ProcessRecord proc = mLruProcesses.get(i); 9228 if (proc.notCachedSinceIdle) { 9229 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9230 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9231 if (doKilling && proc.initialIdlePss != 0 9232 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9233 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9234 + " from " + proc.initialIdlePss + ")"); 9235 } 9236 } 9237 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9238 proc.notCachedSinceIdle = true; 9239 proc.initialIdlePss = 0; 9240 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9241 mSleeping, now); 9242 } 9243 } 9244 9245 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9246 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9247 } 9248 } 9249 9250 private void retrieveSettings() { 9251 final ContentResolver resolver = mContext.getContentResolver(); 9252 String debugApp = Settings.Global.getString( 9253 resolver, Settings.Global.DEBUG_APP); 9254 boolean waitForDebugger = Settings.Global.getInt( 9255 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9256 boolean alwaysFinishActivities = Settings.Global.getInt( 9257 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9258 boolean forceRtl = Settings.Global.getInt( 9259 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9260 // Transfer any global setting for forcing RTL layout, into a System Property 9261 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9262 9263 Configuration configuration = new Configuration(); 9264 Settings.System.getConfiguration(resolver, configuration); 9265 if (forceRtl) { 9266 // This will take care of setting the correct layout direction flags 9267 configuration.setLayoutDirection(configuration.locale); 9268 } 9269 9270 synchronized (this) { 9271 mDebugApp = mOrigDebugApp = debugApp; 9272 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9273 mAlwaysFinishActivities = alwaysFinishActivities; 9274 // This happens before any activities are started, so we can 9275 // change mConfiguration in-place. 9276 updateConfigurationLocked(configuration, null, false, true); 9277 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9278 } 9279 } 9280 9281 public boolean testIsSystemReady() { 9282 // no need to synchronize(this) just to read & return the value 9283 return mSystemReady; 9284 } 9285 9286 private static File getCalledPreBootReceiversFile() { 9287 File dataDir = Environment.getDataDirectory(); 9288 File systemDir = new File(dataDir, "system"); 9289 File fname = new File(systemDir, "called_pre_boots.dat"); 9290 return fname; 9291 } 9292 9293 static final int LAST_DONE_VERSION = 10000; 9294 9295 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9296 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9297 File file = getCalledPreBootReceiversFile(); 9298 FileInputStream fis = null; 9299 try { 9300 fis = new FileInputStream(file); 9301 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9302 int fvers = dis.readInt(); 9303 if (fvers == LAST_DONE_VERSION) { 9304 String vers = dis.readUTF(); 9305 String codename = dis.readUTF(); 9306 String build = dis.readUTF(); 9307 if (android.os.Build.VERSION.RELEASE.equals(vers) 9308 && android.os.Build.VERSION.CODENAME.equals(codename) 9309 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9310 int num = dis.readInt(); 9311 while (num > 0) { 9312 num--; 9313 String pkg = dis.readUTF(); 9314 String cls = dis.readUTF(); 9315 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9316 } 9317 } 9318 } 9319 } catch (FileNotFoundException e) { 9320 } catch (IOException e) { 9321 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9322 } finally { 9323 if (fis != null) { 9324 try { 9325 fis.close(); 9326 } catch (IOException e) { 9327 } 9328 } 9329 } 9330 return lastDoneReceivers; 9331 } 9332 9333 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9334 File file = getCalledPreBootReceiversFile(); 9335 FileOutputStream fos = null; 9336 DataOutputStream dos = null; 9337 try { 9338 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9339 fos = new FileOutputStream(file); 9340 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9341 dos.writeInt(LAST_DONE_VERSION); 9342 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9343 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9344 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9345 dos.writeInt(list.size()); 9346 for (int i=0; i<list.size(); i++) { 9347 dos.writeUTF(list.get(i).getPackageName()); 9348 dos.writeUTF(list.get(i).getClassName()); 9349 } 9350 } catch (IOException e) { 9351 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9352 file.delete(); 9353 } finally { 9354 FileUtils.sync(fos); 9355 if (dos != null) { 9356 try { 9357 dos.close(); 9358 } catch (IOException e) { 9359 // TODO Auto-generated catch block 9360 e.printStackTrace(); 9361 } 9362 } 9363 } 9364 } 9365 9366 public void systemReady(final Runnable goingCallback) { 9367 synchronized(this) { 9368 if (mSystemReady) { 9369 if (goingCallback != null) goingCallback.run(); 9370 return; 9371 } 9372 9373 // Check to see if there are any update receivers to run. 9374 if (!mDidUpdate) { 9375 if (mWaitingUpdate) { 9376 return; 9377 } 9378 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9379 List<ResolveInfo> ris = null; 9380 try { 9381 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9382 intent, null, 0, 0); 9383 } catch (RemoteException e) { 9384 } 9385 if (ris != null) { 9386 for (int i=ris.size()-1; i>=0; i--) { 9387 if ((ris.get(i).activityInfo.applicationInfo.flags 9388 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9389 ris.remove(i); 9390 } 9391 } 9392 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9393 9394 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9395 9396 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9397 for (int i=0; i<ris.size(); i++) { 9398 ActivityInfo ai = ris.get(i).activityInfo; 9399 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9400 if (lastDoneReceivers.contains(comp)) { 9401 // We already did the pre boot receiver for this app with the current 9402 // platform version, so don't do it again... 9403 ris.remove(i); 9404 i--; 9405 // ...however, do keep it as one that has been done, so we don't 9406 // forget about it when rewriting the file of last done receivers. 9407 doneReceivers.add(comp); 9408 } 9409 } 9410 9411 final int[] users = getUsersLocked(); 9412 for (int i=0; i<ris.size(); i++) { 9413 ActivityInfo ai = ris.get(i).activityInfo; 9414 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9415 doneReceivers.add(comp); 9416 intent.setComponent(comp); 9417 for (int j=0; j<users.length; j++) { 9418 IIntentReceiver finisher = null; 9419 if (i == ris.size()-1 && j == users.length-1) { 9420 finisher = new IIntentReceiver.Stub() { 9421 public void performReceive(Intent intent, int resultCode, 9422 String data, Bundle extras, boolean ordered, 9423 boolean sticky, int sendingUser) { 9424 // The raw IIntentReceiver interface is called 9425 // with the AM lock held, so redispatch to 9426 // execute our code without the lock. 9427 mHandler.post(new Runnable() { 9428 public void run() { 9429 synchronized (ActivityManagerService.this) { 9430 mDidUpdate = true; 9431 } 9432 writeLastDonePreBootReceivers(doneReceivers); 9433 showBootMessage(mContext.getText( 9434 R.string.android_upgrading_complete), 9435 false); 9436 systemReady(goingCallback); 9437 } 9438 }); 9439 } 9440 }; 9441 } 9442 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9443 + " for user " + users[j]); 9444 broadcastIntentLocked(null, null, intent, null, finisher, 9445 0, null, null, null, AppOpsManager.OP_NONE, 9446 true, false, MY_PID, Process.SYSTEM_UID, 9447 users[j]); 9448 if (finisher != null) { 9449 mWaitingUpdate = true; 9450 } 9451 } 9452 } 9453 } 9454 if (mWaitingUpdate) { 9455 return; 9456 } 9457 mDidUpdate = true; 9458 } 9459 9460 mAppOpsService.systemReady(); 9461 mSystemReady = true; 9462 } 9463 9464 ArrayList<ProcessRecord> procsToKill = null; 9465 synchronized(mPidsSelfLocked) { 9466 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9467 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9468 if (!isAllowedWhileBooting(proc.info)){ 9469 if (procsToKill == null) { 9470 procsToKill = new ArrayList<ProcessRecord>(); 9471 } 9472 procsToKill.add(proc); 9473 } 9474 } 9475 } 9476 9477 synchronized(this) { 9478 if (procsToKill != null) { 9479 for (int i=procsToKill.size()-1; i>=0; i--) { 9480 ProcessRecord proc = procsToKill.get(i); 9481 Slog.i(TAG, "Removing system update proc: " + proc); 9482 removeProcessLocked(proc, true, false, "system update done"); 9483 } 9484 } 9485 9486 // Now that we have cleaned up any update processes, we 9487 // are ready to start launching real processes and know that 9488 // we won't trample on them any more. 9489 mProcessesReady = true; 9490 } 9491 9492 Slog.i(TAG, "System now ready"); 9493 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9494 SystemClock.uptimeMillis()); 9495 9496 synchronized(this) { 9497 // Make sure we have no pre-ready processes sitting around. 9498 9499 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9500 ResolveInfo ri = mContext.getPackageManager() 9501 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9502 STOCK_PM_FLAGS); 9503 CharSequence errorMsg = null; 9504 if (ri != null) { 9505 ActivityInfo ai = ri.activityInfo; 9506 ApplicationInfo app = ai.applicationInfo; 9507 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9508 mTopAction = Intent.ACTION_FACTORY_TEST; 9509 mTopData = null; 9510 mTopComponent = new ComponentName(app.packageName, 9511 ai.name); 9512 } else { 9513 errorMsg = mContext.getResources().getText( 9514 com.android.internal.R.string.factorytest_not_system); 9515 } 9516 } else { 9517 errorMsg = mContext.getResources().getText( 9518 com.android.internal.R.string.factorytest_no_action); 9519 } 9520 if (errorMsg != null) { 9521 mTopAction = null; 9522 mTopData = null; 9523 mTopComponent = null; 9524 Message msg = Message.obtain(); 9525 msg.what = SHOW_FACTORY_ERROR_MSG; 9526 msg.getData().putCharSequence("msg", errorMsg); 9527 mHandler.sendMessage(msg); 9528 } 9529 } 9530 } 9531 9532 retrieveSettings(); 9533 9534 synchronized (this) { 9535 readGrantedUriPermissionsLocked(); 9536 } 9537 9538 if (goingCallback != null) goingCallback.run(); 9539 9540 synchronized (this) { 9541 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9542 try { 9543 List apps = AppGlobals.getPackageManager(). 9544 getPersistentApplications(STOCK_PM_FLAGS); 9545 if (apps != null) { 9546 int N = apps.size(); 9547 int i; 9548 for (i=0; i<N; i++) { 9549 ApplicationInfo info 9550 = (ApplicationInfo)apps.get(i); 9551 if (info != null && 9552 !info.packageName.equals("android")) { 9553 addAppLocked(info, false); 9554 } 9555 } 9556 } 9557 } catch (RemoteException ex) { 9558 // pm is in same process, this will never happen. 9559 } 9560 } 9561 9562 // Start up initial activity. 9563 mBooting = true; 9564 9565 try { 9566 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9567 Message msg = Message.obtain(); 9568 msg.what = SHOW_UID_ERROR_MSG; 9569 mHandler.sendMessage(msg); 9570 } 9571 } catch (RemoteException e) { 9572 } 9573 9574 long ident = Binder.clearCallingIdentity(); 9575 try { 9576 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9577 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9578 | Intent.FLAG_RECEIVER_FOREGROUND); 9579 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9580 broadcastIntentLocked(null, null, intent, 9581 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9582 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9583 intent = new Intent(Intent.ACTION_USER_STARTING); 9584 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9585 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9586 broadcastIntentLocked(null, null, intent, 9587 null, new IIntentReceiver.Stub() { 9588 @Override 9589 public void performReceive(Intent intent, int resultCode, String data, 9590 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9591 throws RemoteException { 9592 } 9593 }, 0, null, null, 9594 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9595 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9596 } finally { 9597 Binder.restoreCallingIdentity(ident); 9598 } 9599 mStackSupervisor.resumeTopActivitiesLocked(); 9600 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9601 } 9602 } 9603 9604 private boolean makeAppCrashingLocked(ProcessRecord app, 9605 String shortMsg, String longMsg, String stackTrace) { 9606 app.crashing = true; 9607 app.crashingReport = generateProcessError(app, 9608 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9609 startAppProblemLocked(app); 9610 app.stopFreezingAllLocked(); 9611 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9612 } 9613 9614 private void makeAppNotRespondingLocked(ProcessRecord app, 9615 String activity, String shortMsg, String longMsg) { 9616 app.notResponding = true; 9617 app.notRespondingReport = generateProcessError(app, 9618 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9619 activity, shortMsg, longMsg, null); 9620 startAppProblemLocked(app); 9621 app.stopFreezingAllLocked(); 9622 } 9623 9624 /** 9625 * Generate a process error record, suitable for attachment to a ProcessRecord. 9626 * 9627 * @param app The ProcessRecord in which the error occurred. 9628 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9629 * ActivityManager.AppErrorStateInfo 9630 * @param activity The activity associated with the crash, if known. 9631 * @param shortMsg Short message describing the crash. 9632 * @param longMsg Long message describing the crash. 9633 * @param stackTrace Full crash stack trace, may be null. 9634 * 9635 * @return Returns a fully-formed AppErrorStateInfo record. 9636 */ 9637 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9638 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9639 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9640 9641 report.condition = condition; 9642 report.processName = app.processName; 9643 report.pid = app.pid; 9644 report.uid = app.info.uid; 9645 report.tag = activity; 9646 report.shortMsg = shortMsg; 9647 report.longMsg = longMsg; 9648 report.stackTrace = stackTrace; 9649 9650 return report; 9651 } 9652 9653 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9654 synchronized (this) { 9655 app.crashing = false; 9656 app.crashingReport = null; 9657 app.notResponding = false; 9658 app.notRespondingReport = null; 9659 if (app.anrDialog == fromDialog) { 9660 app.anrDialog = null; 9661 } 9662 if (app.waitDialog == fromDialog) { 9663 app.waitDialog = null; 9664 } 9665 if (app.pid > 0 && app.pid != MY_PID) { 9666 handleAppCrashLocked(app, null, null, null); 9667 killUnneededProcessLocked(app, "user request after error"); 9668 } 9669 } 9670 } 9671 9672 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9673 String stackTrace) { 9674 long now = SystemClock.uptimeMillis(); 9675 9676 Long crashTime; 9677 if (!app.isolated) { 9678 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9679 } else { 9680 crashTime = null; 9681 } 9682 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9683 // This process loses! 9684 Slog.w(TAG, "Process " + app.info.processName 9685 + " has crashed too many times: killing!"); 9686 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9687 app.userId, app.info.processName, app.uid); 9688 mStackSupervisor.handleAppCrashLocked(app); 9689 if (!app.persistent) { 9690 // We don't want to start this process again until the user 9691 // explicitly does so... but for persistent process, we really 9692 // need to keep it running. If a persistent process is actually 9693 // repeatedly crashing, then badness for everyone. 9694 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9695 app.info.processName); 9696 if (!app.isolated) { 9697 // XXX We don't have a way to mark isolated processes 9698 // as bad, since they don't have a peristent identity. 9699 mBadProcesses.put(app.info.processName, app.uid, 9700 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9701 mProcessCrashTimes.remove(app.info.processName, app.uid); 9702 } 9703 app.bad = true; 9704 app.removed = true; 9705 // Don't let services in this process be restarted and potentially 9706 // annoy the user repeatedly. Unless it is persistent, since those 9707 // processes run critical code. 9708 removeProcessLocked(app, false, false, "crash"); 9709 mStackSupervisor.resumeTopActivitiesLocked(); 9710 return false; 9711 } 9712 mStackSupervisor.resumeTopActivitiesLocked(); 9713 } else { 9714 mStackSupervisor.finishTopRunningActivityLocked(app); 9715 } 9716 9717 // Bump up the crash count of any services currently running in the proc. 9718 for (int i=app.services.size()-1; i>=0; i--) { 9719 // Any services running in the application need to be placed 9720 // back in the pending list. 9721 ServiceRecord sr = app.services.valueAt(i); 9722 sr.crashCount++; 9723 } 9724 9725 // If the crashing process is what we consider to be the "home process" and it has been 9726 // replaced by a third-party app, clear the package preferred activities from packages 9727 // with a home activity running in the process to prevent a repeatedly crashing app 9728 // from blocking the user to manually clear the list. 9729 final ArrayList<ActivityRecord> activities = app.activities; 9730 if (app == mHomeProcess && activities.size() > 0 9731 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9732 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9733 final ActivityRecord r = activities.get(activityNdx); 9734 if (r.isHomeActivity()) { 9735 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9736 try { 9737 ActivityThread.getPackageManager() 9738 .clearPackagePreferredActivities(r.packageName); 9739 } catch (RemoteException c) { 9740 // pm is in same process, this will never happen. 9741 } 9742 } 9743 } 9744 } 9745 9746 if (!app.isolated) { 9747 // XXX Can't keep track of crash times for isolated processes, 9748 // because they don't have a perisistent identity. 9749 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9750 } 9751 9752 return true; 9753 } 9754 9755 void startAppProblemLocked(ProcessRecord app) { 9756 if (app.userId == mCurrentUserId) { 9757 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9758 mContext, app.info.packageName, app.info.flags); 9759 } else { 9760 // If this app is not running under the current user, then we 9761 // can't give it a report button because that would require 9762 // launching the report UI under a different user. 9763 app.errorReportReceiver = null; 9764 } 9765 skipCurrentReceiverLocked(app); 9766 } 9767 9768 void skipCurrentReceiverLocked(ProcessRecord app) { 9769 for (BroadcastQueue queue : mBroadcastQueues) { 9770 queue.skipCurrentReceiverLocked(app); 9771 } 9772 } 9773 9774 /** 9775 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9776 * The application process will exit immediately after this call returns. 9777 * @param app object of the crashing app, null for the system server 9778 * @param crashInfo describing the exception 9779 */ 9780 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9781 ProcessRecord r = findAppProcess(app, "Crash"); 9782 final String processName = app == null ? "system_server" 9783 : (r == null ? "unknown" : r.processName); 9784 9785 handleApplicationCrashInner("crash", r, processName, crashInfo); 9786 } 9787 9788 /* Native crash reporting uses this inner version because it needs to be somewhat 9789 * decoupled from the AM-managed cleanup lifecycle 9790 */ 9791 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9792 ApplicationErrorReport.CrashInfo crashInfo) { 9793 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9794 UserHandle.getUserId(Binder.getCallingUid()), processName, 9795 r == null ? -1 : r.info.flags, 9796 crashInfo.exceptionClassName, 9797 crashInfo.exceptionMessage, 9798 crashInfo.throwFileName, 9799 crashInfo.throwLineNumber); 9800 9801 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9802 9803 crashApplication(r, crashInfo); 9804 } 9805 9806 public void handleApplicationStrictModeViolation( 9807 IBinder app, 9808 int violationMask, 9809 StrictMode.ViolationInfo info) { 9810 ProcessRecord r = findAppProcess(app, "StrictMode"); 9811 if (r == null) { 9812 return; 9813 } 9814 9815 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9816 Integer stackFingerprint = info.hashCode(); 9817 boolean logIt = true; 9818 synchronized (mAlreadyLoggedViolatedStacks) { 9819 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9820 logIt = false; 9821 // TODO: sub-sample into EventLog for these, with 9822 // the info.durationMillis? Then we'd get 9823 // the relative pain numbers, without logging all 9824 // the stack traces repeatedly. We'd want to do 9825 // likewise in the client code, which also does 9826 // dup suppression, before the Binder call. 9827 } else { 9828 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9829 mAlreadyLoggedViolatedStacks.clear(); 9830 } 9831 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9832 } 9833 } 9834 if (logIt) { 9835 logStrictModeViolationToDropBox(r, info); 9836 } 9837 } 9838 9839 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9840 AppErrorResult result = new AppErrorResult(); 9841 synchronized (this) { 9842 final long origId = Binder.clearCallingIdentity(); 9843 9844 Message msg = Message.obtain(); 9845 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9846 HashMap<String, Object> data = new HashMap<String, Object>(); 9847 data.put("result", result); 9848 data.put("app", r); 9849 data.put("violationMask", violationMask); 9850 data.put("info", info); 9851 msg.obj = data; 9852 mHandler.sendMessage(msg); 9853 9854 Binder.restoreCallingIdentity(origId); 9855 } 9856 int res = result.get(); 9857 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9858 } 9859 } 9860 9861 // Depending on the policy in effect, there could be a bunch of 9862 // these in quick succession so we try to batch these together to 9863 // minimize disk writes, number of dropbox entries, and maximize 9864 // compression, by having more fewer, larger records. 9865 private void logStrictModeViolationToDropBox( 9866 ProcessRecord process, 9867 StrictMode.ViolationInfo info) { 9868 if (info == null) { 9869 return; 9870 } 9871 final boolean isSystemApp = process == null || 9872 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9873 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9874 final String processName = process == null ? "unknown" : process.processName; 9875 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9876 final DropBoxManager dbox = (DropBoxManager) 9877 mContext.getSystemService(Context.DROPBOX_SERVICE); 9878 9879 // Exit early if the dropbox isn't configured to accept this report type. 9880 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9881 9882 boolean bufferWasEmpty; 9883 boolean needsFlush; 9884 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9885 synchronized (sb) { 9886 bufferWasEmpty = sb.length() == 0; 9887 appendDropBoxProcessHeaders(process, processName, sb); 9888 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9889 sb.append("System-App: ").append(isSystemApp).append("\n"); 9890 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9891 if (info.violationNumThisLoop != 0) { 9892 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9893 } 9894 if (info.numAnimationsRunning != 0) { 9895 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9896 } 9897 if (info.broadcastIntentAction != null) { 9898 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9899 } 9900 if (info.durationMillis != -1) { 9901 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9902 } 9903 if (info.numInstances != -1) { 9904 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9905 } 9906 if (info.tags != null) { 9907 for (String tag : info.tags) { 9908 sb.append("Span-Tag: ").append(tag).append("\n"); 9909 } 9910 } 9911 sb.append("\n"); 9912 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9913 sb.append(info.crashInfo.stackTrace); 9914 } 9915 sb.append("\n"); 9916 9917 // Only buffer up to ~64k. Various logging bits truncate 9918 // things at 128k. 9919 needsFlush = (sb.length() > 64 * 1024); 9920 } 9921 9922 // Flush immediately if the buffer's grown too large, or this 9923 // is a non-system app. Non-system apps are isolated with a 9924 // different tag & policy and not batched. 9925 // 9926 // Batching is useful during internal testing with 9927 // StrictMode settings turned up high. Without batching, 9928 // thousands of separate files could be created on boot. 9929 if (!isSystemApp || needsFlush) { 9930 new Thread("Error dump: " + dropboxTag) { 9931 @Override 9932 public void run() { 9933 String report; 9934 synchronized (sb) { 9935 report = sb.toString(); 9936 sb.delete(0, sb.length()); 9937 sb.trimToSize(); 9938 } 9939 if (report.length() != 0) { 9940 dbox.addText(dropboxTag, report); 9941 } 9942 } 9943 }.start(); 9944 return; 9945 } 9946 9947 // System app batching: 9948 if (!bufferWasEmpty) { 9949 // An existing dropbox-writing thread is outstanding, so 9950 // we don't need to start it up. The existing thread will 9951 // catch the buffer appends we just did. 9952 return; 9953 } 9954 9955 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9956 // (After this point, we shouldn't access AMS internal data structures.) 9957 new Thread("Error dump: " + dropboxTag) { 9958 @Override 9959 public void run() { 9960 // 5 second sleep to let stacks arrive and be batched together 9961 try { 9962 Thread.sleep(5000); // 5 seconds 9963 } catch (InterruptedException e) {} 9964 9965 String errorReport; 9966 synchronized (mStrictModeBuffer) { 9967 errorReport = mStrictModeBuffer.toString(); 9968 if (errorReport.length() == 0) { 9969 return; 9970 } 9971 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9972 mStrictModeBuffer.trimToSize(); 9973 } 9974 dbox.addText(dropboxTag, errorReport); 9975 } 9976 }.start(); 9977 } 9978 9979 /** 9980 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9981 * @param app object of the crashing app, null for the system server 9982 * @param tag reported by the caller 9983 * @param crashInfo describing the context of the error 9984 * @return true if the process should exit immediately (WTF is fatal) 9985 */ 9986 public boolean handleApplicationWtf(IBinder app, String tag, 9987 ApplicationErrorReport.CrashInfo crashInfo) { 9988 ProcessRecord r = findAppProcess(app, "WTF"); 9989 final String processName = app == null ? "system_server" 9990 : (r == null ? "unknown" : r.processName); 9991 9992 EventLog.writeEvent(EventLogTags.AM_WTF, 9993 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9994 processName, 9995 r == null ? -1 : r.info.flags, 9996 tag, crashInfo.exceptionMessage); 9997 9998 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9999 10000 if (r != null && r.pid != Process.myPid() && 10001 Settings.Global.getInt(mContext.getContentResolver(), 10002 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10003 crashApplication(r, crashInfo); 10004 return true; 10005 } else { 10006 return false; 10007 } 10008 } 10009 10010 /** 10011 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10012 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10013 */ 10014 private ProcessRecord findAppProcess(IBinder app, String reason) { 10015 if (app == null) { 10016 return null; 10017 } 10018 10019 synchronized (this) { 10020 final int NP = mProcessNames.getMap().size(); 10021 for (int ip=0; ip<NP; ip++) { 10022 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10023 final int NA = apps.size(); 10024 for (int ia=0; ia<NA; ia++) { 10025 ProcessRecord p = apps.valueAt(ia); 10026 if (p.thread != null && p.thread.asBinder() == app) { 10027 return p; 10028 } 10029 } 10030 } 10031 10032 Slog.w(TAG, "Can't find mystery application for " + reason 10033 + " from pid=" + Binder.getCallingPid() 10034 + " uid=" + Binder.getCallingUid() + ": " + app); 10035 return null; 10036 } 10037 } 10038 10039 /** 10040 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10041 * to append various headers to the dropbox log text. 10042 */ 10043 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10044 StringBuilder sb) { 10045 // Watchdog thread ends up invoking this function (with 10046 // a null ProcessRecord) to add the stack file to dropbox. 10047 // Do not acquire a lock on this (am) in such cases, as it 10048 // could cause a potential deadlock, if and when watchdog 10049 // is invoked due to unavailability of lock on am and it 10050 // would prevent watchdog from killing system_server. 10051 if (process == null) { 10052 sb.append("Process: ").append(processName).append("\n"); 10053 return; 10054 } 10055 // Note: ProcessRecord 'process' is guarded by the service 10056 // instance. (notably process.pkgList, which could otherwise change 10057 // concurrently during execution of this method) 10058 synchronized (this) { 10059 sb.append("Process: ").append(processName).append("\n"); 10060 int flags = process.info.flags; 10061 IPackageManager pm = AppGlobals.getPackageManager(); 10062 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10063 for (int ip=0; ip<process.pkgList.size(); ip++) { 10064 String pkg = process.pkgList.keyAt(ip); 10065 sb.append("Package: ").append(pkg); 10066 try { 10067 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10068 if (pi != null) { 10069 sb.append(" v").append(pi.versionCode); 10070 if (pi.versionName != null) { 10071 sb.append(" (").append(pi.versionName).append(")"); 10072 } 10073 } 10074 } catch (RemoteException e) { 10075 Slog.e(TAG, "Error getting package info: " + pkg, e); 10076 } 10077 sb.append("\n"); 10078 } 10079 } 10080 } 10081 10082 private static String processClass(ProcessRecord process) { 10083 if (process == null || process.pid == MY_PID) { 10084 return "system_server"; 10085 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10086 return "system_app"; 10087 } else { 10088 return "data_app"; 10089 } 10090 } 10091 10092 /** 10093 * Write a description of an error (crash, WTF, ANR) to the drop box. 10094 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10095 * @param process which caused the error, null means the system server 10096 * @param activity which triggered the error, null if unknown 10097 * @param parent activity related to the error, null if unknown 10098 * @param subject line related to the error, null if absent 10099 * @param report in long form describing the error, null if absent 10100 * @param logFile to include in the report, null if none 10101 * @param crashInfo giving an application stack trace, null if absent 10102 */ 10103 public void addErrorToDropBox(String eventType, 10104 ProcessRecord process, String processName, ActivityRecord activity, 10105 ActivityRecord parent, String subject, 10106 final String report, final File logFile, 10107 final ApplicationErrorReport.CrashInfo crashInfo) { 10108 // NOTE -- this must never acquire the ActivityManagerService lock, 10109 // otherwise the watchdog may be prevented from resetting the system. 10110 10111 final String dropboxTag = processClass(process) + "_" + eventType; 10112 final DropBoxManager dbox = (DropBoxManager) 10113 mContext.getSystemService(Context.DROPBOX_SERVICE); 10114 10115 // Exit early if the dropbox isn't configured to accept this report type. 10116 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10117 10118 final StringBuilder sb = new StringBuilder(1024); 10119 appendDropBoxProcessHeaders(process, processName, sb); 10120 if (activity != null) { 10121 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10122 } 10123 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10124 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10125 } 10126 if (parent != null && parent != activity) { 10127 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10128 } 10129 if (subject != null) { 10130 sb.append("Subject: ").append(subject).append("\n"); 10131 } 10132 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10133 if (Debug.isDebuggerConnected()) { 10134 sb.append("Debugger: Connected\n"); 10135 } 10136 sb.append("\n"); 10137 10138 // Do the rest in a worker thread to avoid blocking the caller on I/O 10139 // (After this point, we shouldn't access AMS internal data structures.) 10140 Thread worker = new Thread("Error dump: " + dropboxTag) { 10141 @Override 10142 public void run() { 10143 if (report != null) { 10144 sb.append(report); 10145 } 10146 if (logFile != null) { 10147 try { 10148 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10149 "\n\n[[TRUNCATED]]")); 10150 } catch (IOException e) { 10151 Slog.e(TAG, "Error reading " + logFile, e); 10152 } 10153 } 10154 if (crashInfo != null && crashInfo.stackTrace != null) { 10155 sb.append(crashInfo.stackTrace); 10156 } 10157 10158 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10159 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10160 if (lines > 0) { 10161 sb.append("\n"); 10162 10163 // Merge several logcat streams, and take the last N lines 10164 InputStreamReader input = null; 10165 try { 10166 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10167 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10168 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10169 10170 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10171 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10172 input = new InputStreamReader(logcat.getInputStream()); 10173 10174 int num; 10175 char[] buf = new char[8192]; 10176 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10177 } catch (IOException e) { 10178 Slog.e(TAG, "Error running logcat", e); 10179 } finally { 10180 if (input != null) try { input.close(); } catch (IOException e) {} 10181 } 10182 } 10183 10184 dbox.addText(dropboxTag, sb.toString()); 10185 } 10186 }; 10187 10188 if (process == null) { 10189 // If process is null, we are being called from some internal code 10190 // and may be about to die -- run this synchronously. 10191 worker.run(); 10192 } else { 10193 worker.start(); 10194 } 10195 } 10196 10197 /** 10198 * Bring up the "unexpected error" dialog box for a crashing app. 10199 * Deal with edge cases (intercepts from instrumented applications, 10200 * ActivityController, error intent receivers, that sort of thing). 10201 * @param r the application crashing 10202 * @param crashInfo describing the failure 10203 */ 10204 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10205 long timeMillis = System.currentTimeMillis(); 10206 String shortMsg = crashInfo.exceptionClassName; 10207 String longMsg = crashInfo.exceptionMessage; 10208 String stackTrace = crashInfo.stackTrace; 10209 if (shortMsg != null && longMsg != null) { 10210 longMsg = shortMsg + ": " + longMsg; 10211 } else if (shortMsg != null) { 10212 longMsg = shortMsg; 10213 } 10214 10215 AppErrorResult result = new AppErrorResult(); 10216 synchronized (this) { 10217 if (mController != null) { 10218 try { 10219 String name = r != null ? r.processName : null; 10220 int pid = r != null ? r.pid : Binder.getCallingPid(); 10221 if (!mController.appCrashed(name, pid, 10222 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10223 Slog.w(TAG, "Force-killing crashed app " + name 10224 + " at watcher's request"); 10225 Process.killProcess(pid); 10226 return; 10227 } 10228 } catch (RemoteException e) { 10229 mController = null; 10230 Watchdog.getInstance().setActivityController(null); 10231 } 10232 } 10233 10234 final long origId = Binder.clearCallingIdentity(); 10235 10236 // If this process is running instrumentation, finish it. 10237 if (r != null && r.instrumentationClass != null) { 10238 Slog.w(TAG, "Error in app " + r.processName 10239 + " running instrumentation " + r.instrumentationClass + ":"); 10240 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10241 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10242 Bundle info = new Bundle(); 10243 info.putString("shortMsg", shortMsg); 10244 info.putString("longMsg", longMsg); 10245 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10246 Binder.restoreCallingIdentity(origId); 10247 return; 10248 } 10249 10250 // If we can't identify the process or it's already exceeded its crash quota, 10251 // quit right away without showing a crash dialog. 10252 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10253 Binder.restoreCallingIdentity(origId); 10254 return; 10255 } 10256 10257 Message msg = Message.obtain(); 10258 msg.what = SHOW_ERROR_MSG; 10259 HashMap data = new HashMap(); 10260 data.put("result", result); 10261 data.put("app", r); 10262 msg.obj = data; 10263 mHandler.sendMessage(msg); 10264 10265 Binder.restoreCallingIdentity(origId); 10266 } 10267 10268 int res = result.get(); 10269 10270 Intent appErrorIntent = null; 10271 synchronized (this) { 10272 if (r != null && !r.isolated) { 10273 // XXX Can't keep track of crash time for isolated processes, 10274 // since they don't have a persistent identity. 10275 mProcessCrashTimes.put(r.info.processName, r.uid, 10276 SystemClock.uptimeMillis()); 10277 } 10278 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10279 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10280 } 10281 } 10282 10283 if (appErrorIntent != null) { 10284 try { 10285 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10286 } catch (ActivityNotFoundException e) { 10287 Slog.w(TAG, "bug report receiver dissappeared", e); 10288 } 10289 } 10290 } 10291 10292 Intent createAppErrorIntentLocked(ProcessRecord r, 10293 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10294 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10295 if (report == null) { 10296 return null; 10297 } 10298 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10299 result.setComponent(r.errorReportReceiver); 10300 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10301 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10302 return result; 10303 } 10304 10305 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10306 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10307 if (r.errorReportReceiver == null) { 10308 return null; 10309 } 10310 10311 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10312 return null; 10313 } 10314 10315 ApplicationErrorReport report = new ApplicationErrorReport(); 10316 report.packageName = r.info.packageName; 10317 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10318 report.processName = r.processName; 10319 report.time = timeMillis; 10320 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10321 10322 if (r.crashing || r.forceCrashReport) { 10323 report.type = ApplicationErrorReport.TYPE_CRASH; 10324 report.crashInfo = crashInfo; 10325 } else if (r.notResponding) { 10326 report.type = ApplicationErrorReport.TYPE_ANR; 10327 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10328 10329 report.anrInfo.activity = r.notRespondingReport.tag; 10330 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10331 report.anrInfo.info = r.notRespondingReport.longMsg; 10332 } 10333 10334 return report; 10335 } 10336 10337 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10338 enforceNotIsolatedCaller("getProcessesInErrorState"); 10339 // assume our apps are happy - lazy create the list 10340 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10341 10342 final boolean allUsers = ActivityManager.checkUidPermission( 10343 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10344 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10345 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10346 10347 synchronized (this) { 10348 10349 // iterate across all processes 10350 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10351 ProcessRecord app = mLruProcesses.get(i); 10352 if (!allUsers && app.userId != userId) { 10353 continue; 10354 } 10355 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10356 // This one's in trouble, so we'll generate a report for it 10357 // crashes are higher priority (in case there's a crash *and* an anr) 10358 ActivityManager.ProcessErrorStateInfo report = null; 10359 if (app.crashing) { 10360 report = app.crashingReport; 10361 } else if (app.notResponding) { 10362 report = app.notRespondingReport; 10363 } 10364 10365 if (report != null) { 10366 if (errList == null) { 10367 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10368 } 10369 errList.add(report); 10370 } else { 10371 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10372 " crashing = " + app.crashing + 10373 " notResponding = " + app.notResponding); 10374 } 10375 } 10376 } 10377 } 10378 10379 return errList; 10380 } 10381 10382 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10383 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10384 if (currApp != null) { 10385 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10386 } 10387 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10388 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10389 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10390 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10391 if (currApp != null) { 10392 currApp.lru = 0; 10393 } 10394 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10395 } else if (adj >= ProcessList.SERVICE_ADJ) { 10396 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10397 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10398 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10399 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10400 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10401 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10402 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10403 } else { 10404 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10405 } 10406 } 10407 10408 private void fillInProcMemInfo(ProcessRecord app, 10409 ActivityManager.RunningAppProcessInfo outInfo) { 10410 outInfo.pid = app.pid; 10411 outInfo.uid = app.info.uid; 10412 if (mHeavyWeightProcess == app) { 10413 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10414 } 10415 if (app.persistent) { 10416 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10417 } 10418 if (app.activities.size() > 0) { 10419 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10420 } 10421 outInfo.lastTrimLevel = app.trimMemoryLevel; 10422 int adj = app.curAdj; 10423 outInfo.importance = oomAdjToImportance(adj, outInfo); 10424 outInfo.importanceReasonCode = app.adjTypeCode; 10425 } 10426 10427 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10428 enforceNotIsolatedCaller("getRunningAppProcesses"); 10429 // Lazy instantiation of list 10430 List<ActivityManager.RunningAppProcessInfo> runList = null; 10431 final boolean allUsers = ActivityManager.checkUidPermission( 10432 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10433 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10434 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10435 synchronized (this) { 10436 // Iterate across all processes 10437 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10438 ProcessRecord app = mLruProcesses.get(i); 10439 if (!allUsers && app.userId != userId) { 10440 continue; 10441 } 10442 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10443 // Generate process state info for running application 10444 ActivityManager.RunningAppProcessInfo currApp = 10445 new ActivityManager.RunningAppProcessInfo(app.processName, 10446 app.pid, app.getPackageList()); 10447 fillInProcMemInfo(app, currApp); 10448 if (app.adjSource instanceof ProcessRecord) { 10449 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10450 currApp.importanceReasonImportance = oomAdjToImportance( 10451 app.adjSourceOom, null); 10452 } else if (app.adjSource instanceof ActivityRecord) { 10453 ActivityRecord r = (ActivityRecord)app.adjSource; 10454 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10455 } 10456 if (app.adjTarget instanceof ComponentName) { 10457 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10458 } 10459 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10460 // + " lru=" + currApp.lru); 10461 if (runList == null) { 10462 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10463 } 10464 runList.add(currApp); 10465 } 10466 } 10467 } 10468 return runList; 10469 } 10470 10471 public List<ApplicationInfo> getRunningExternalApplications() { 10472 enforceNotIsolatedCaller("getRunningExternalApplications"); 10473 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10474 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10475 if (runningApps != null && runningApps.size() > 0) { 10476 Set<String> extList = new HashSet<String>(); 10477 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10478 if (app.pkgList != null) { 10479 for (String pkg : app.pkgList) { 10480 extList.add(pkg); 10481 } 10482 } 10483 } 10484 IPackageManager pm = AppGlobals.getPackageManager(); 10485 for (String pkg : extList) { 10486 try { 10487 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10488 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10489 retList.add(info); 10490 } 10491 } catch (RemoteException e) { 10492 } 10493 } 10494 } 10495 return retList; 10496 } 10497 10498 @Override 10499 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10500 enforceNotIsolatedCaller("getMyMemoryState"); 10501 synchronized (this) { 10502 ProcessRecord proc; 10503 synchronized (mPidsSelfLocked) { 10504 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10505 } 10506 fillInProcMemInfo(proc, outInfo); 10507 } 10508 } 10509 10510 @Override 10511 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10512 if (checkCallingPermission(android.Manifest.permission.DUMP) 10513 != PackageManager.PERMISSION_GRANTED) { 10514 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10515 + Binder.getCallingPid() 10516 + ", uid=" + Binder.getCallingUid() 10517 + " without permission " 10518 + android.Manifest.permission.DUMP); 10519 return; 10520 } 10521 10522 boolean dumpAll = false; 10523 boolean dumpClient = false; 10524 String dumpPackage = null; 10525 10526 int opti = 0; 10527 while (opti < args.length) { 10528 String opt = args[opti]; 10529 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10530 break; 10531 } 10532 opti++; 10533 if ("-a".equals(opt)) { 10534 dumpAll = true; 10535 } else if ("-c".equals(opt)) { 10536 dumpClient = true; 10537 } else if ("-h".equals(opt)) { 10538 pw.println("Activity manager dump options:"); 10539 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10540 pw.println(" cmd may be one of:"); 10541 pw.println(" a[ctivities]: activity stack state"); 10542 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10543 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10544 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10545 pw.println(" o[om]: out of memory management"); 10546 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10547 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10548 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10549 pw.println(" service [COMP_SPEC]: service client-side state"); 10550 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10551 pw.println(" all: dump all activities"); 10552 pw.println(" top: dump the top activity"); 10553 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10554 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10555 pw.println(" a partial substring in a component name, a"); 10556 pw.println(" hex object identifier."); 10557 pw.println(" -a: include all available server state."); 10558 pw.println(" -c: include client state."); 10559 return; 10560 } else { 10561 pw.println("Unknown argument: " + opt + "; use -h for help"); 10562 } 10563 } 10564 10565 long origId = Binder.clearCallingIdentity(); 10566 boolean more = false; 10567 // Is the caller requesting to dump a particular piece of data? 10568 if (opti < args.length) { 10569 String cmd = args[opti]; 10570 opti++; 10571 if ("activities".equals(cmd) || "a".equals(cmd)) { 10572 synchronized (this) { 10573 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10574 } 10575 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10576 String[] newArgs; 10577 String name; 10578 if (opti >= args.length) { 10579 name = null; 10580 newArgs = EMPTY_STRING_ARRAY; 10581 } else { 10582 name = args[opti]; 10583 opti++; 10584 newArgs = new String[args.length - opti]; 10585 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10586 args.length - opti); 10587 } 10588 synchronized (this) { 10589 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10590 } 10591 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10592 String[] newArgs; 10593 String name; 10594 if (opti >= args.length) { 10595 name = null; 10596 newArgs = EMPTY_STRING_ARRAY; 10597 } else { 10598 name = args[opti]; 10599 opti++; 10600 newArgs = new String[args.length - opti]; 10601 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10602 args.length - opti); 10603 } 10604 synchronized (this) { 10605 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10606 } 10607 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10608 String[] newArgs; 10609 String name; 10610 if (opti >= args.length) { 10611 name = null; 10612 newArgs = EMPTY_STRING_ARRAY; 10613 } else { 10614 name = args[opti]; 10615 opti++; 10616 newArgs = new String[args.length - opti]; 10617 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10618 args.length - opti); 10619 } 10620 synchronized (this) { 10621 dumpProcessesLocked(fd, pw, args, opti, true, name); 10622 } 10623 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10624 synchronized (this) { 10625 dumpOomLocked(fd, pw, args, opti, true); 10626 } 10627 } else if ("provider".equals(cmd)) { 10628 String[] newArgs; 10629 String name; 10630 if (opti >= args.length) { 10631 name = null; 10632 newArgs = EMPTY_STRING_ARRAY; 10633 } else { 10634 name = args[opti]; 10635 opti++; 10636 newArgs = new String[args.length - opti]; 10637 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10638 } 10639 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10640 pw.println("No providers match: " + name); 10641 pw.println("Use -h for help."); 10642 } 10643 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10644 synchronized (this) { 10645 dumpProvidersLocked(fd, pw, args, opti, true, null); 10646 } 10647 } else if ("service".equals(cmd)) { 10648 String[] newArgs; 10649 String name; 10650 if (opti >= args.length) { 10651 name = null; 10652 newArgs = EMPTY_STRING_ARRAY; 10653 } else { 10654 name = args[opti]; 10655 opti++; 10656 newArgs = new String[args.length - opti]; 10657 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10658 args.length - opti); 10659 } 10660 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10661 pw.println("No services match: " + name); 10662 pw.println("Use -h for help."); 10663 } 10664 } else if ("package".equals(cmd)) { 10665 String[] newArgs; 10666 if (opti >= args.length) { 10667 pw.println("package: no package name specified"); 10668 pw.println("Use -h for help."); 10669 } else { 10670 dumpPackage = args[opti]; 10671 opti++; 10672 newArgs = new String[args.length - opti]; 10673 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10674 args.length - opti); 10675 args = newArgs; 10676 opti = 0; 10677 more = true; 10678 } 10679 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10680 synchronized (this) { 10681 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10682 } 10683 } else { 10684 // Dumping a single activity? 10685 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10686 pw.println("Bad activity command, or no activities match: " + cmd); 10687 pw.println("Use -h for help."); 10688 } 10689 } 10690 if (!more) { 10691 Binder.restoreCallingIdentity(origId); 10692 return; 10693 } 10694 } 10695 10696 // No piece of data specified, dump everything. 10697 synchronized (this) { 10698 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10699 pw.println(); 10700 if (dumpAll) { 10701 pw.println("-------------------------------------------------------------------------------"); 10702 } 10703 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10704 pw.println(); 10705 if (dumpAll) { 10706 pw.println("-------------------------------------------------------------------------------"); 10707 } 10708 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10709 pw.println(); 10710 if (dumpAll) { 10711 pw.println("-------------------------------------------------------------------------------"); 10712 } 10713 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10714 pw.println(); 10715 if (dumpAll) { 10716 pw.println("-------------------------------------------------------------------------------"); 10717 } 10718 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10719 pw.println(); 10720 if (dumpAll) { 10721 pw.println("-------------------------------------------------------------------------------"); 10722 } 10723 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10724 } 10725 Binder.restoreCallingIdentity(origId); 10726 } 10727 10728 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10729 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10730 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10731 10732 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10733 dumpPackage); 10734 boolean needSep = printedAnything; 10735 10736 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10737 dumpPackage, needSep, " mFocusedActivity: "); 10738 if (printed) { 10739 printedAnything = true; 10740 needSep = false; 10741 } 10742 10743 if (dumpPackage == null) { 10744 if (needSep) { 10745 pw.println(); 10746 } 10747 needSep = true; 10748 printedAnything = true; 10749 mStackSupervisor.dump(pw, " "); 10750 } 10751 10752 if (mRecentTasks.size() > 0) { 10753 boolean printedHeader = false; 10754 10755 final int N = mRecentTasks.size(); 10756 for (int i=0; i<N; i++) { 10757 TaskRecord tr = mRecentTasks.get(i); 10758 if (dumpPackage != null) { 10759 if (tr.realActivity == null || 10760 !dumpPackage.equals(tr.realActivity)) { 10761 continue; 10762 } 10763 } 10764 if (!printedHeader) { 10765 if (needSep) { 10766 pw.println(); 10767 } 10768 pw.println(" Recent tasks:"); 10769 printedHeader = true; 10770 printedAnything = true; 10771 } 10772 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10773 pw.println(tr); 10774 if (dumpAll) { 10775 mRecentTasks.get(i).dump(pw, " "); 10776 } 10777 } 10778 } 10779 10780 if (!printedAnything) { 10781 pw.println(" (nothing)"); 10782 } 10783 } 10784 10785 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10786 int opti, boolean dumpAll, String dumpPackage) { 10787 boolean needSep = false; 10788 boolean printedAnything = false; 10789 int numPers = 0; 10790 10791 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10792 10793 if (dumpAll) { 10794 final int NP = mProcessNames.getMap().size(); 10795 for (int ip=0; ip<NP; ip++) { 10796 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10797 final int NA = procs.size(); 10798 for (int ia=0; ia<NA; ia++) { 10799 ProcessRecord r = procs.valueAt(ia); 10800 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10801 continue; 10802 } 10803 if (!needSep) { 10804 pw.println(" All known processes:"); 10805 needSep = true; 10806 printedAnything = true; 10807 } 10808 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10809 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10810 pw.print(" "); pw.println(r); 10811 r.dump(pw, " "); 10812 if (r.persistent) { 10813 numPers++; 10814 } 10815 } 10816 } 10817 } 10818 10819 if (mIsolatedProcesses.size() > 0) { 10820 boolean printed = false; 10821 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10822 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10823 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10824 continue; 10825 } 10826 if (!printed) { 10827 if (needSep) { 10828 pw.println(); 10829 } 10830 pw.println(" Isolated process list (sorted by uid):"); 10831 printedAnything = true; 10832 printed = true; 10833 needSep = true; 10834 } 10835 pw.println(String.format("%sIsolated #%2d: %s", 10836 " ", i, r.toString())); 10837 } 10838 } 10839 10840 if (mLruProcesses.size() > 0) { 10841 if (needSep) { 10842 pw.println(); 10843 } 10844 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10845 pw.print(" total, non-act at "); 10846 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10847 pw.print(", non-svc at "); 10848 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10849 pw.println("):"); 10850 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10851 needSep = true; 10852 printedAnything = true; 10853 } 10854 10855 if (dumpAll || dumpPackage != null) { 10856 synchronized (mPidsSelfLocked) { 10857 boolean printed = false; 10858 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10859 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10860 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10861 continue; 10862 } 10863 if (!printed) { 10864 if (needSep) pw.println(); 10865 needSep = true; 10866 pw.println(" PID mappings:"); 10867 printed = true; 10868 printedAnything = true; 10869 } 10870 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10871 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10872 } 10873 } 10874 } 10875 10876 if (mForegroundProcesses.size() > 0) { 10877 synchronized (mPidsSelfLocked) { 10878 boolean printed = false; 10879 for (int i=0; i<mForegroundProcesses.size(); i++) { 10880 ProcessRecord r = mPidsSelfLocked.get( 10881 mForegroundProcesses.valueAt(i).pid); 10882 if (dumpPackage != null && (r == null 10883 || !r.pkgList.containsKey(dumpPackage))) { 10884 continue; 10885 } 10886 if (!printed) { 10887 if (needSep) pw.println(); 10888 needSep = true; 10889 pw.println(" Foreground Processes:"); 10890 printed = true; 10891 printedAnything = true; 10892 } 10893 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10894 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10895 } 10896 } 10897 } 10898 10899 if (mPersistentStartingProcesses.size() > 0) { 10900 if (needSep) pw.println(); 10901 needSep = true; 10902 printedAnything = true; 10903 pw.println(" Persisent processes that are starting:"); 10904 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10905 "Starting Norm", "Restarting PERS", dumpPackage); 10906 } 10907 10908 if (mRemovedProcesses.size() > 0) { 10909 if (needSep) pw.println(); 10910 needSep = true; 10911 printedAnything = true; 10912 pw.println(" Processes that are being removed:"); 10913 dumpProcessList(pw, this, mRemovedProcesses, " ", 10914 "Removed Norm", "Removed PERS", dumpPackage); 10915 } 10916 10917 if (mProcessesOnHold.size() > 0) { 10918 if (needSep) pw.println(); 10919 needSep = true; 10920 printedAnything = true; 10921 pw.println(" Processes that are on old until the system is ready:"); 10922 dumpProcessList(pw, this, mProcessesOnHold, " ", 10923 "OnHold Norm", "OnHold PERS", dumpPackage); 10924 } 10925 10926 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10927 10928 if (mProcessCrashTimes.getMap().size() > 0) { 10929 boolean printed = false; 10930 long now = SystemClock.uptimeMillis(); 10931 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10932 final int NP = pmap.size(); 10933 for (int ip=0; ip<NP; ip++) { 10934 String pname = pmap.keyAt(ip); 10935 SparseArray<Long> uids = pmap.valueAt(ip); 10936 final int N = uids.size(); 10937 for (int i=0; i<N; i++) { 10938 int puid = uids.keyAt(i); 10939 ProcessRecord r = mProcessNames.get(pname, puid); 10940 if (dumpPackage != null && (r == null 10941 || !r.pkgList.containsKey(dumpPackage))) { 10942 continue; 10943 } 10944 if (!printed) { 10945 if (needSep) pw.println(); 10946 needSep = true; 10947 pw.println(" Time since processes crashed:"); 10948 printed = true; 10949 printedAnything = true; 10950 } 10951 pw.print(" Process "); pw.print(pname); 10952 pw.print(" uid "); pw.print(puid); 10953 pw.print(": last crashed "); 10954 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10955 pw.println(" ago"); 10956 } 10957 } 10958 } 10959 10960 if (mBadProcesses.getMap().size() > 0) { 10961 boolean printed = false; 10962 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10963 final int NP = pmap.size(); 10964 for (int ip=0; ip<NP; ip++) { 10965 String pname = pmap.keyAt(ip); 10966 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10967 final int N = uids.size(); 10968 for (int i=0; i<N; i++) { 10969 int puid = uids.keyAt(i); 10970 ProcessRecord r = mProcessNames.get(pname, puid); 10971 if (dumpPackage != null && (r == null 10972 || !r.pkgList.containsKey(dumpPackage))) { 10973 continue; 10974 } 10975 if (!printed) { 10976 if (needSep) pw.println(); 10977 needSep = true; 10978 pw.println(" Bad processes:"); 10979 printedAnything = true; 10980 } 10981 BadProcessInfo info = uids.valueAt(i); 10982 pw.print(" Bad process "); pw.print(pname); 10983 pw.print(" uid "); pw.print(puid); 10984 pw.print(": crashed at time "); pw.println(info.time); 10985 if (info.shortMsg != null) { 10986 pw.print(" Short msg: "); pw.println(info.shortMsg); 10987 } 10988 if (info.longMsg != null) { 10989 pw.print(" Long msg: "); pw.println(info.longMsg); 10990 } 10991 if (info.stack != null) { 10992 pw.println(" Stack:"); 10993 int lastPos = 0; 10994 for (int pos=0; pos<info.stack.length(); pos++) { 10995 if (info.stack.charAt(pos) == '\n') { 10996 pw.print(" "); 10997 pw.write(info.stack, lastPos, pos-lastPos); 10998 pw.println(); 10999 lastPos = pos+1; 11000 } 11001 } 11002 if (lastPos < info.stack.length()) { 11003 pw.print(" "); 11004 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11005 pw.println(); 11006 } 11007 } 11008 } 11009 } 11010 } 11011 11012 if (dumpPackage == null) { 11013 pw.println(); 11014 needSep = false; 11015 pw.println(" mStartedUsers:"); 11016 for (int i=0; i<mStartedUsers.size(); i++) { 11017 UserStartedState uss = mStartedUsers.valueAt(i); 11018 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11019 pw.print(": "); uss.dump("", pw); 11020 } 11021 pw.print(" mStartedUserArray: ["); 11022 for (int i=0; i<mStartedUserArray.length; i++) { 11023 if (i > 0) pw.print(", "); 11024 pw.print(mStartedUserArray[i]); 11025 } 11026 pw.println("]"); 11027 pw.print(" mUserLru: ["); 11028 for (int i=0; i<mUserLru.size(); i++) { 11029 if (i > 0) pw.print(", "); 11030 pw.print(mUserLru.get(i)); 11031 } 11032 pw.println("]"); 11033 if (dumpAll) { 11034 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11035 } 11036 } 11037 if (mHomeProcess != null && (dumpPackage == null 11038 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11039 if (needSep) { 11040 pw.println(); 11041 needSep = false; 11042 } 11043 pw.println(" mHomeProcess: " + mHomeProcess); 11044 } 11045 if (mPreviousProcess != null && (dumpPackage == null 11046 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11047 if (needSep) { 11048 pw.println(); 11049 needSep = false; 11050 } 11051 pw.println(" mPreviousProcess: " + mPreviousProcess); 11052 } 11053 if (dumpAll) { 11054 StringBuilder sb = new StringBuilder(128); 11055 sb.append(" mPreviousProcessVisibleTime: "); 11056 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11057 pw.println(sb); 11058 } 11059 if (mHeavyWeightProcess != null && (dumpPackage == null 11060 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11061 if (needSep) { 11062 pw.println(); 11063 needSep = false; 11064 } 11065 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11066 } 11067 if (dumpPackage == null) { 11068 pw.println(" mConfiguration: " + mConfiguration); 11069 } 11070 if (dumpAll) { 11071 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11072 if (mCompatModePackages.getPackages().size() > 0) { 11073 boolean printed = false; 11074 for (Map.Entry<String, Integer> entry 11075 : mCompatModePackages.getPackages().entrySet()) { 11076 String pkg = entry.getKey(); 11077 int mode = entry.getValue(); 11078 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11079 continue; 11080 } 11081 if (!printed) { 11082 pw.println(" mScreenCompatPackages:"); 11083 printed = true; 11084 } 11085 pw.print(" "); pw.print(pkg); pw.print(": "); 11086 pw.print(mode); pw.println(); 11087 } 11088 } 11089 } 11090 if (dumpPackage == null) { 11091 if (mSleeping || mWentToSleep || mLockScreenShown) { 11092 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11093 + " mLockScreenShown " + mLockScreenShown); 11094 } 11095 if (mShuttingDown) { 11096 pw.println(" mShuttingDown=" + mShuttingDown); 11097 } 11098 } 11099 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11100 || mOrigWaitForDebugger) { 11101 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11102 || dumpPackage.equals(mOrigDebugApp)) { 11103 if (needSep) { 11104 pw.println(); 11105 needSep = false; 11106 } 11107 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11108 + " mDebugTransient=" + mDebugTransient 11109 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11110 } 11111 } 11112 if (mOpenGlTraceApp != null) { 11113 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11114 if (needSep) { 11115 pw.println(); 11116 needSep = false; 11117 } 11118 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11119 } 11120 } 11121 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11122 || mProfileFd != null) { 11123 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11124 if (needSep) { 11125 pw.println(); 11126 needSep = false; 11127 } 11128 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11129 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11130 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11131 + mAutoStopProfiler); 11132 } 11133 } 11134 if (dumpPackage == null) { 11135 if (mAlwaysFinishActivities || mController != null) { 11136 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11137 + " mController=" + mController); 11138 } 11139 if (dumpAll) { 11140 pw.println(" Total persistent processes: " + numPers); 11141 pw.println(" mProcessesReady=" + mProcessesReady 11142 + " mSystemReady=" + mSystemReady); 11143 pw.println(" mBooting=" + mBooting 11144 + " mBooted=" + mBooted 11145 + " mFactoryTest=" + mFactoryTest); 11146 pw.print(" mLastPowerCheckRealtime="); 11147 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11148 pw.println(""); 11149 pw.print(" mLastPowerCheckUptime="); 11150 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11151 pw.println(""); 11152 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11153 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11154 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11155 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11156 + " (" + mLruProcesses.size() + " total)" 11157 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11158 + " mNumServiceProcs=" + mNumServiceProcs 11159 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11160 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11161 + " mLastMemoryLevel" + mLastMemoryLevel 11162 + " mLastNumProcesses" + mLastNumProcesses); 11163 long now = SystemClock.uptimeMillis(); 11164 pw.print(" mLastIdleTime="); 11165 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11166 pw.print(" mLowRamSinceLastIdle="); 11167 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11168 pw.println(); 11169 } 11170 } 11171 11172 if (!printedAnything) { 11173 pw.println(" (nothing)"); 11174 } 11175 } 11176 11177 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11178 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11179 if (mProcessesToGc.size() > 0) { 11180 boolean printed = false; 11181 long now = SystemClock.uptimeMillis(); 11182 for (int i=0; i<mProcessesToGc.size(); i++) { 11183 ProcessRecord proc = mProcessesToGc.get(i); 11184 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11185 continue; 11186 } 11187 if (!printed) { 11188 if (needSep) pw.println(); 11189 needSep = true; 11190 pw.println(" Processes that are waiting to GC:"); 11191 printed = true; 11192 } 11193 pw.print(" Process "); pw.println(proc); 11194 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11195 pw.print(", last gced="); 11196 pw.print(now-proc.lastRequestedGc); 11197 pw.print(" ms ago, last lowMem="); 11198 pw.print(now-proc.lastLowMemory); 11199 pw.println(" ms ago"); 11200 11201 } 11202 } 11203 return needSep; 11204 } 11205 11206 void printOomLevel(PrintWriter pw, String name, int adj) { 11207 pw.print(" "); 11208 if (adj >= 0) { 11209 pw.print(' '); 11210 if (adj < 10) pw.print(' '); 11211 } else { 11212 if (adj > -10) pw.print(' '); 11213 } 11214 pw.print(adj); 11215 pw.print(": "); 11216 pw.print(name); 11217 pw.print(" ("); 11218 pw.print(mProcessList.getMemLevel(adj)/1024); 11219 pw.println(" kB)"); 11220 } 11221 11222 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11223 int opti, boolean dumpAll) { 11224 boolean needSep = false; 11225 11226 if (mLruProcesses.size() > 0) { 11227 if (needSep) pw.println(); 11228 needSep = true; 11229 pw.println(" OOM levels:"); 11230 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11231 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11232 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11233 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11234 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11235 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11236 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11237 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11238 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11239 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11240 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11241 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11242 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11243 11244 if (needSep) pw.println(); 11245 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11246 pw.print(" total, non-act at "); 11247 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11248 pw.print(", non-svc at "); 11249 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11250 pw.println("):"); 11251 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11252 needSep = true; 11253 } 11254 11255 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11256 11257 pw.println(); 11258 pw.println(" mHomeProcess: " + mHomeProcess); 11259 pw.println(" mPreviousProcess: " + mPreviousProcess); 11260 if (mHeavyWeightProcess != null) { 11261 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11262 } 11263 11264 return true; 11265 } 11266 11267 /** 11268 * There are three ways to call this: 11269 * - no provider specified: dump all the providers 11270 * - a flattened component name that matched an existing provider was specified as the 11271 * first arg: dump that one provider 11272 * - the first arg isn't the flattened component name of an existing provider: 11273 * dump all providers whose component contains the first arg as a substring 11274 */ 11275 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11276 int opti, boolean dumpAll) { 11277 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11278 } 11279 11280 static class ItemMatcher { 11281 ArrayList<ComponentName> components; 11282 ArrayList<String> strings; 11283 ArrayList<Integer> objects; 11284 boolean all; 11285 11286 ItemMatcher() { 11287 all = true; 11288 } 11289 11290 void build(String name) { 11291 ComponentName componentName = ComponentName.unflattenFromString(name); 11292 if (componentName != null) { 11293 if (components == null) { 11294 components = new ArrayList<ComponentName>(); 11295 } 11296 components.add(componentName); 11297 all = false; 11298 } else { 11299 int objectId = 0; 11300 // Not a '/' separated full component name; maybe an object ID? 11301 try { 11302 objectId = Integer.parseInt(name, 16); 11303 if (objects == null) { 11304 objects = new ArrayList<Integer>(); 11305 } 11306 objects.add(objectId); 11307 all = false; 11308 } catch (RuntimeException e) { 11309 // Not an integer; just do string match. 11310 if (strings == null) { 11311 strings = new ArrayList<String>(); 11312 } 11313 strings.add(name); 11314 all = false; 11315 } 11316 } 11317 } 11318 11319 int build(String[] args, int opti) { 11320 for (; opti<args.length; opti++) { 11321 String name = args[opti]; 11322 if ("--".equals(name)) { 11323 return opti+1; 11324 } 11325 build(name); 11326 } 11327 return opti; 11328 } 11329 11330 boolean match(Object object, ComponentName comp) { 11331 if (all) { 11332 return true; 11333 } 11334 if (components != null) { 11335 for (int i=0; i<components.size(); i++) { 11336 if (components.get(i).equals(comp)) { 11337 return true; 11338 } 11339 } 11340 } 11341 if (objects != null) { 11342 for (int i=0; i<objects.size(); i++) { 11343 if (System.identityHashCode(object) == objects.get(i)) { 11344 return true; 11345 } 11346 } 11347 } 11348 if (strings != null) { 11349 String flat = comp.flattenToString(); 11350 for (int i=0; i<strings.size(); i++) { 11351 if (flat.contains(strings.get(i))) { 11352 return true; 11353 } 11354 } 11355 } 11356 return false; 11357 } 11358 } 11359 11360 /** 11361 * There are three things that cmd can be: 11362 * - a flattened component name that matches an existing activity 11363 * - the cmd arg isn't the flattened component name of an existing activity: 11364 * dump all activity whose component contains the cmd as a substring 11365 * - A hex number of the ActivityRecord object instance. 11366 */ 11367 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11368 int opti, boolean dumpAll) { 11369 ArrayList<ActivityRecord> activities; 11370 11371 synchronized (this) { 11372 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11373 } 11374 11375 if (activities.size() <= 0) { 11376 return false; 11377 } 11378 11379 String[] newArgs = new String[args.length - opti]; 11380 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11381 11382 TaskRecord lastTask = null; 11383 boolean needSep = false; 11384 for (int i=activities.size()-1; i>=0; i--) { 11385 ActivityRecord r = activities.get(i); 11386 if (needSep) { 11387 pw.println(); 11388 } 11389 needSep = true; 11390 synchronized (this) { 11391 if (lastTask != r.task) { 11392 lastTask = r.task; 11393 pw.print("TASK "); pw.print(lastTask.affinity); 11394 pw.print(" id="); pw.println(lastTask.taskId); 11395 if (dumpAll) { 11396 lastTask.dump(pw, " "); 11397 } 11398 } 11399 } 11400 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11401 } 11402 return true; 11403 } 11404 11405 /** 11406 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11407 * there is a thread associated with the activity. 11408 */ 11409 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11410 final ActivityRecord r, String[] args, boolean dumpAll) { 11411 String innerPrefix = prefix + " "; 11412 synchronized (this) { 11413 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11414 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11415 pw.print(" pid="); 11416 if (r.app != null) pw.println(r.app.pid); 11417 else pw.println("(not running)"); 11418 if (dumpAll) { 11419 r.dump(pw, innerPrefix); 11420 } 11421 } 11422 if (r.app != null && r.app.thread != null) { 11423 // flush anything that is already in the PrintWriter since the thread is going 11424 // to write to the file descriptor directly 11425 pw.flush(); 11426 try { 11427 TransferPipe tp = new TransferPipe(); 11428 try { 11429 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11430 r.appToken, innerPrefix, args); 11431 tp.go(fd); 11432 } finally { 11433 tp.kill(); 11434 } 11435 } catch (IOException e) { 11436 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11437 } catch (RemoteException e) { 11438 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11439 } 11440 } 11441 } 11442 11443 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11444 int opti, boolean dumpAll, String dumpPackage) { 11445 boolean needSep = false; 11446 boolean onlyHistory = false; 11447 boolean printedAnything = false; 11448 11449 if ("history".equals(dumpPackage)) { 11450 if (opti < args.length && "-s".equals(args[opti])) { 11451 dumpAll = false; 11452 } 11453 onlyHistory = true; 11454 dumpPackage = null; 11455 } 11456 11457 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11458 if (!onlyHistory && dumpAll) { 11459 if (mRegisteredReceivers.size() > 0) { 11460 boolean printed = false; 11461 Iterator it = mRegisteredReceivers.values().iterator(); 11462 while (it.hasNext()) { 11463 ReceiverList r = (ReceiverList)it.next(); 11464 if (dumpPackage != null && (r.app == null || 11465 !dumpPackage.equals(r.app.info.packageName))) { 11466 continue; 11467 } 11468 if (!printed) { 11469 pw.println(" Registered Receivers:"); 11470 needSep = true; 11471 printed = true; 11472 printedAnything = true; 11473 } 11474 pw.print(" * "); pw.println(r); 11475 r.dump(pw, " "); 11476 } 11477 } 11478 11479 if (mReceiverResolver.dump(pw, needSep ? 11480 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11481 " ", dumpPackage, false)) { 11482 needSep = true; 11483 printedAnything = true; 11484 } 11485 } 11486 11487 for (BroadcastQueue q : mBroadcastQueues) { 11488 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11489 printedAnything |= needSep; 11490 } 11491 11492 needSep = true; 11493 11494 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11495 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11496 if (needSep) { 11497 pw.println(); 11498 } 11499 needSep = true; 11500 printedAnything = true; 11501 pw.print(" Sticky broadcasts for user "); 11502 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11503 StringBuilder sb = new StringBuilder(128); 11504 for (Map.Entry<String, ArrayList<Intent>> ent 11505 : mStickyBroadcasts.valueAt(user).entrySet()) { 11506 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11507 if (dumpAll) { 11508 pw.println(":"); 11509 ArrayList<Intent> intents = ent.getValue(); 11510 final int N = intents.size(); 11511 for (int i=0; i<N; i++) { 11512 sb.setLength(0); 11513 sb.append(" Intent: "); 11514 intents.get(i).toShortString(sb, false, true, false, false); 11515 pw.println(sb.toString()); 11516 Bundle bundle = intents.get(i).getExtras(); 11517 if (bundle != null) { 11518 pw.print(" "); 11519 pw.println(bundle.toString()); 11520 } 11521 } 11522 } else { 11523 pw.println(""); 11524 } 11525 } 11526 } 11527 } 11528 11529 if (!onlyHistory && dumpAll) { 11530 pw.println(); 11531 for (BroadcastQueue queue : mBroadcastQueues) { 11532 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11533 + queue.mBroadcastsScheduled); 11534 } 11535 pw.println(" mHandler:"); 11536 mHandler.dump(new PrintWriterPrinter(pw), " "); 11537 needSep = true; 11538 printedAnything = true; 11539 } 11540 11541 if (!printedAnything) { 11542 pw.println(" (nothing)"); 11543 } 11544 } 11545 11546 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11547 int opti, boolean dumpAll, String dumpPackage) { 11548 boolean needSep; 11549 boolean printedAnything = false; 11550 11551 ItemMatcher matcher = new ItemMatcher(); 11552 matcher.build(args, opti); 11553 11554 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11555 11556 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11557 printedAnything |= needSep; 11558 11559 if (mLaunchingProviders.size() > 0) { 11560 boolean printed = false; 11561 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11562 ContentProviderRecord r = mLaunchingProviders.get(i); 11563 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11564 continue; 11565 } 11566 if (!printed) { 11567 if (needSep) pw.println(); 11568 needSep = true; 11569 pw.println(" Launching content providers:"); 11570 printed = true; 11571 printedAnything = true; 11572 } 11573 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11574 pw.println(r); 11575 } 11576 } 11577 11578 if (mGrantedUriPermissions.size() > 0) { 11579 boolean printed = false; 11580 int dumpUid = -2; 11581 if (dumpPackage != null) { 11582 try { 11583 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11584 } catch (NameNotFoundException e) { 11585 dumpUid = -1; 11586 } 11587 } 11588 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11589 int uid = mGrantedUriPermissions.keyAt(i); 11590 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11591 continue; 11592 } 11593 ArrayMap<Uri, UriPermission> perms 11594 = mGrantedUriPermissions.valueAt(i); 11595 if (!printed) { 11596 if (needSep) pw.println(); 11597 needSep = true; 11598 pw.println(" Granted Uri Permissions:"); 11599 printed = true; 11600 printedAnything = true; 11601 } 11602 pw.print(" * UID "); pw.print(uid); 11603 pw.println(" holds:"); 11604 for (UriPermission perm : perms.values()) { 11605 pw.print(" "); pw.println(perm); 11606 if (dumpAll) { 11607 perm.dump(pw, " "); 11608 } 11609 } 11610 } 11611 } 11612 11613 if (!printedAnything) { 11614 pw.println(" (nothing)"); 11615 } 11616 } 11617 11618 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11619 int opti, boolean dumpAll, String dumpPackage) { 11620 boolean printed = false; 11621 11622 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11623 11624 if (mIntentSenderRecords.size() > 0) { 11625 Iterator<WeakReference<PendingIntentRecord>> it 11626 = mIntentSenderRecords.values().iterator(); 11627 while (it.hasNext()) { 11628 WeakReference<PendingIntentRecord> ref = it.next(); 11629 PendingIntentRecord rec = ref != null ? ref.get(): null; 11630 if (dumpPackage != null && (rec == null 11631 || !dumpPackage.equals(rec.key.packageName))) { 11632 continue; 11633 } 11634 printed = true; 11635 if (rec != null) { 11636 pw.print(" * "); pw.println(rec); 11637 if (dumpAll) { 11638 rec.dump(pw, " "); 11639 } 11640 } else { 11641 pw.print(" * "); pw.println(ref); 11642 } 11643 } 11644 } 11645 11646 if (!printed) { 11647 pw.println(" (nothing)"); 11648 } 11649 } 11650 11651 private static final int dumpProcessList(PrintWriter pw, 11652 ActivityManagerService service, List list, 11653 String prefix, String normalLabel, String persistentLabel, 11654 String dumpPackage) { 11655 int numPers = 0; 11656 final int N = list.size()-1; 11657 for (int i=N; i>=0; i--) { 11658 ProcessRecord r = (ProcessRecord)list.get(i); 11659 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11660 continue; 11661 } 11662 pw.println(String.format("%s%s #%2d: %s", 11663 prefix, (r.persistent ? persistentLabel : normalLabel), 11664 i, r.toString())); 11665 if (r.persistent) { 11666 numPers++; 11667 } 11668 } 11669 return numPers; 11670 } 11671 11672 private static final boolean dumpProcessOomList(PrintWriter pw, 11673 ActivityManagerService service, List<ProcessRecord> origList, 11674 String prefix, String normalLabel, String persistentLabel, 11675 boolean inclDetails, String dumpPackage) { 11676 11677 ArrayList<Pair<ProcessRecord, Integer>> list 11678 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11679 for (int i=0; i<origList.size(); i++) { 11680 ProcessRecord r = origList.get(i); 11681 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11682 continue; 11683 } 11684 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11685 } 11686 11687 if (list.size() <= 0) { 11688 return false; 11689 } 11690 11691 Comparator<Pair<ProcessRecord, Integer>> comparator 11692 = new Comparator<Pair<ProcessRecord, Integer>>() { 11693 @Override 11694 public int compare(Pair<ProcessRecord, Integer> object1, 11695 Pair<ProcessRecord, Integer> object2) { 11696 if (object1.first.setAdj != object2.first.setAdj) { 11697 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11698 } 11699 if (object1.second.intValue() != object2.second.intValue()) { 11700 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11701 } 11702 return 0; 11703 } 11704 }; 11705 11706 Collections.sort(list, comparator); 11707 11708 final long curRealtime = SystemClock.elapsedRealtime(); 11709 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11710 final long curUptime = SystemClock.uptimeMillis(); 11711 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11712 11713 for (int i=list.size()-1; i>=0; i--) { 11714 ProcessRecord r = list.get(i).first; 11715 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11716 char schedGroup; 11717 switch (r.setSchedGroup) { 11718 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11719 schedGroup = 'B'; 11720 break; 11721 case Process.THREAD_GROUP_DEFAULT: 11722 schedGroup = 'F'; 11723 break; 11724 default: 11725 schedGroup = '?'; 11726 break; 11727 } 11728 char foreground; 11729 if (r.foregroundActivities) { 11730 foreground = 'A'; 11731 } else if (r.foregroundServices) { 11732 foreground = 'S'; 11733 } else { 11734 foreground = ' '; 11735 } 11736 String procState = ProcessList.makeProcStateString(r.curProcState); 11737 pw.print(prefix); 11738 pw.print(r.persistent ? persistentLabel : normalLabel); 11739 pw.print(" #"); 11740 int num = (origList.size()-1)-list.get(i).second; 11741 if (num < 10) pw.print(' '); 11742 pw.print(num); 11743 pw.print(": "); 11744 pw.print(oomAdj); 11745 pw.print(' '); 11746 pw.print(schedGroup); 11747 pw.print('/'); 11748 pw.print(foreground); 11749 pw.print('/'); 11750 pw.print(procState); 11751 pw.print(" trm:"); 11752 if (r.trimMemoryLevel < 10) pw.print(' '); 11753 pw.print(r.trimMemoryLevel); 11754 pw.print(' '); 11755 pw.print(r.toShortString()); 11756 pw.print(" ("); 11757 pw.print(r.adjType); 11758 pw.println(')'); 11759 if (r.adjSource != null || r.adjTarget != null) { 11760 pw.print(prefix); 11761 pw.print(" "); 11762 if (r.adjTarget instanceof ComponentName) { 11763 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11764 } else if (r.adjTarget != null) { 11765 pw.print(r.adjTarget.toString()); 11766 } else { 11767 pw.print("{null}"); 11768 } 11769 pw.print("<="); 11770 if (r.adjSource instanceof ProcessRecord) { 11771 pw.print("Proc{"); 11772 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11773 pw.println("}"); 11774 } else if (r.adjSource != null) { 11775 pw.println(r.adjSource.toString()); 11776 } else { 11777 pw.println("{null}"); 11778 } 11779 } 11780 if (inclDetails) { 11781 pw.print(prefix); 11782 pw.print(" "); 11783 pw.print("oom: max="); pw.print(r.maxAdj); 11784 pw.print(" curRaw="); pw.print(r.curRawAdj); 11785 pw.print(" setRaw="); pw.print(r.setRawAdj); 11786 pw.print(" cur="); pw.print(r.curAdj); 11787 pw.print(" set="); pw.println(r.setAdj); 11788 pw.print(prefix); 11789 pw.print(" "); 11790 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11791 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11792 pw.print(" lastPss="); pw.print(r.lastPss); 11793 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11794 pw.print(prefix); 11795 pw.print(" "); 11796 pw.print("keeping="); pw.print(r.keeping); 11797 pw.print(" cached="); pw.print(r.cached); 11798 pw.print(" empty="); pw.print(r.empty); 11799 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11800 11801 if (!r.keeping) { 11802 if (r.lastWakeTime != 0) { 11803 long wtime; 11804 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11805 synchronized (stats) { 11806 wtime = stats.getProcessWakeTime(r.info.uid, 11807 r.pid, curRealtime); 11808 } 11809 long timeUsed = wtime - r.lastWakeTime; 11810 pw.print(prefix); 11811 pw.print(" "); 11812 pw.print("keep awake over "); 11813 TimeUtils.formatDuration(realtimeSince, pw); 11814 pw.print(" used "); 11815 TimeUtils.formatDuration(timeUsed, pw); 11816 pw.print(" ("); 11817 pw.print((timeUsed*100)/realtimeSince); 11818 pw.println("%)"); 11819 } 11820 if (r.lastCpuTime != 0) { 11821 long timeUsed = r.curCpuTime - r.lastCpuTime; 11822 pw.print(prefix); 11823 pw.print(" "); 11824 pw.print("run cpu over "); 11825 TimeUtils.formatDuration(uptimeSince, pw); 11826 pw.print(" used "); 11827 TimeUtils.formatDuration(timeUsed, pw); 11828 pw.print(" ("); 11829 pw.print((timeUsed*100)/uptimeSince); 11830 pw.println("%)"); 11831 } 11832 } 11833 } 11834 } 11835 return true; 11836 } 11837 11838 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11839 ArrayList<ProcessRecord> procs; 11840 synchronized (this) { 11841 if (args != null && args.length > start 11842 && args[start].charAt(0) != '-') { 11843 procs = new ArrayList<ProcessRecord>(); 11844 int pid = -1; 11845 try { 11846 pid = Integer.parseInt(args[start]); 11847 } catch (NumberFormatException e) { 11848 } 11849 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11850 ProcessRecord proc = mLruProcesses.get(i); 11851 if (proc.pid == pid) { 11852 procs.add(proc); 11853 } else if (proc.processName.equals(args[start])) { 11854 procs.add(proc); 11855 } 11856 } 11857 if (procs.size() <= 0) { 11858 return null; 11859 } 11860 } else { 11861 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11862 } 11863 } 11864 return procs; 11865 } 11866 11867 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11868 PrintWriter pw, String[] args) { 11869 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11870 if (procs == null) { 11871 pw.println("No process found for: " + args[0]); 11872 return; 11873 } 11874 11875 long uptime = SystemClock.uptimeMillis(); 11876 long realtime = SystemClock.elapsedRealtime(); 11877 pw.println("Applications Graphics Acceleration Info:"); 11878 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11879 11880 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11881 ProcessRecord r = procs.get(i); 11882 if (r.thread != null) { 11883 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11884 pw.flush(); 11885 try { 11886 TransferPipe tp = new TransferPipe(); 11887 try { 11888 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11889 tp.go(fd); 11890 } finally { 11891 tp.kill(); 11892 } 11893 } catch (IOException e) { 11894 pw.println("Failure while dumping the app: " + r); 11895 pw.flush(); 11896 } catch (RemoteException e) { 11897 pw.println("Got a RemoteException while dumping the app " + r); 11898 pw.flush(); 11899 } 11900 } 11901 } 11902 } 11903 11904 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11905 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11906 if (procs == null) { 11907 pw.println("No process found for: " + args[0]); 11908 return; 11909 } 11910 11911 pw.println("Applications Database Info:"); 11912 11913 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11914 ProcessRecord r = procs.get(i); 11915 if (r.thread != null) { 11916 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11917 pw.flush(); 11918 try { 11919 TransferPipe tp = new TransferPipe(); 11920 try { 11921 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11922 tp.go(fd); 11923 } finally { 11924 tp.kill(); 11925 } 11926 } catch (IOException e) { 11927 pw.println("Failure while dumping the app: " + r); 11928 pw.flush(); 11929 } catch (RemoteException e) { 11930 pw.println("Got a RemoteException while dumping the app " + r); 11931 pw.flush(); 11932 } 11933 } 11934 } 11935 } 11936 11937 final static class MemItem { 11938 final boolean isProc; 11939 final String label; 11940 final String shortLabel; 11941 final long pss; 11942 final int id; 11943 final boolean hasActivities; 11944 ArrayList<MemItem> subitems; 11945 11946 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11947 boolean _hasActivities) { 11948 isProc = true; 11949 label = _label; 11950 shortLabel = _shortLabel; 11951 pss = _pss; 11952 id = _id; 11953 hasActivities = _hasActivities; 11954 } 11955 11956 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11957 isProc = false; 11958 label = _label; 11959 shortLabel = _shortLabel; 11960 pss = _pss; 11961 id = _id; 11962 hasActivities = false; 11963 } 11964 } 11965 11966 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11967 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11968 if (sort && !isCompact) { 11969 Collections.sort(items, new Comparator<MemItem>() { 11970 @Override 11971 public int compare(MemItem lhs, MemItem rhs) { 11972 if (lhs.pss < rhs.pss) { 11973 return 1; 11974 } else if (lhs.pss > rhs.pss) { 11975 return -1; 11976 } 11977 return 0; 11978 } 11979 }); 11980 } 11981 11982 for (int i=0; i<items.size(); i++) { 11983 MemItem mi = items.get(i); 11984 if (!isCompact) { 11985 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11986 } else if (mi.isProc) { 11987 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11988 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11989 pw.println(mi.hasActivities ? ",a" : ",e"); 11990 } else { 11991 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11992 pw.println(mi.pss); 11993 } 11994 if (mi.subitems != null) { 11995 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11996 true, isCompact); 11997 } 11998 } 11999 } 12000 12001 // These are in KB. 12002 static final long[] DUMP_MEM_BUCKETS = new long[] { 12003 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12004 120*1024, 160*1024, 200*1024, 12005 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12006 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12007 }; 12008 12009 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12010 boolean stackLike) { 12011 int start = label.lastIndexOf('.'); 12012 if (start >= 0) start++; 12013 else start = 0; 12014 int end = label.length(); 12015 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12016 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12017 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12018 out.append(bucket); 12019 out.append(stackLike ? "MB." : "MB "); 12020 out.append(label, start, end); 12021 return; 12022 } 12023 } 12024 out.append(memKB/1024); 12025 out.append(stackLike ? "MB." : "MB "); 12026 out.append(label, start, end); 12027 } 12028 12029 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12030 ProcessList.NATIVE_ADJ, 12031 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12032 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12033 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12034 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12035 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12036 }; 12037 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12038 "Native", 12039 "System", "Persistent", "Foreground", 12040 "Visible", "Perceptible", 12041 "Heavy Weight", "Backup", 12042 "A Services", "Home", 12043 "Previous", "B Services", "Cached" 12044 }; 12045 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12046 "native", 12047 "sys", "pers", "fore", 12048 "vis", "percept", 12049 "heavy", "backup", 12050 "servicea", "home", 12051 "prev", "serviceb", "cached" 12052 }; 12053 12054 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12055 long realtime, boolean isCheckinRequest, boolean isCompact) { 12056 if (isCheckinRequest || isCompact) { 12057 // short checkin version 12058 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12059 } else { 12060 pw.println("Applications Memory Usage (kB):"); 12061 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12062 } 12063 } 12064 12065 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12066 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12067 boolean dumpDetails = false; 12068 boolean dumpFullDetails = false; 12069 boolean dumpDalvik = false; 12070 boolean oomOnly = false; 12071 boolean isCompact = false; 12072 boolean localOnly = false; 12073 12074 int opti = 0; 12075 while (opti < args.length) { 12076 String opt = args[opti]; 12077 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12078 break; 12079 } 12080 opti++; 12081 if ("-a".equals(opt)) { 12082 dumpDetails = true; 12083 dumpFullDetails = true; 12084 dumpDalvik = true; 12085 } else if ("-d".equals(opt)) { 12086 dumpDalvik = true; 12087 } else if ("-c".equals(opt)) { 12088 isCompact = true; 12089 } else if ("--oom".equals(opt)) { 12090 oomOnly = true; 12091 } else if ("--local".equals(opt)) { 12092 localOnly = true; 12093 } else if ("-h".equals(opt)) { 12094 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12095 pw.println(" -a: include all available information for each process."); 12096 pw.println(" -d: include dalvik details when dumping process details."); 12097 pw.println(" -c: dump in a compact machine-parseable representation."); 12098 pw.println(" --oom: only show processes organized by oom adj."); 12099 pw.println(" --local: only collect details locally, don't call process."); 12100 pw.println("If [process] is specified it can be the name or "); 12101 pw.println("pid of a specific process to dump."); 12102 return; 12103 } else { 12104 pw.println("Unknown argument: " + opt + "; use -h for help"); 12105 } 12106 } 12107 12108 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12109 long uptime = SystemClock.uptimeMillis(); 12110 long realtime = SystemClock.elapsedRealtime(); 12111 final long[] tmpLong = new long[1]; 12112 12113 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12114 if (procs == null) { 12115 // No Java processes. Maybe they want to print a native process. 12116 if (args != null && args.length > opti 12117 && args[opti].charAt(0) != '-') { 12118 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12119 = new ArrayList<ProcessCpuTracker.Stats>(); 12120 updateCpuStatsNow(); 12121 int findPid = -1; 12122 try { 12123 findPid = Integer.parseInt(args[opti]); 12124 } catch (NumberFormatException e) { 12125 } 12126 synchronized (mProcessCpuThread) { 12127 final int N = mProcessCpuTracker.countStats(); 12128 for (int i=0; i<N; i++) { 12129 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12130 if (st.pid == findPid || (st.baseName != null 12131 && st.baseName.equals(args[opti]))) { 12132 nativeProcs.add(st); 12133 } 12134 } 12135 } 12136 if (nativeProcs.size() > 0) { 12137 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12138 isCompact); 12139 Debug.MemoryInfo mi = null; 12140 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12141 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12142 final int pid = r.pid; 12143 if (!isCheckinRequest && dumpDetails) { 12144 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12145 } 12146 if (mi == null) { 12147 mi = new Debug.MemoryInfo(); 12148 } 12149 if (dumpDetails || (!brief && !oomOnly)) { 12150 Debug.getMemoryInfo(pid, mi); 12151 } else { 12152 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12153 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12154 } 12155 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12156 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12157 if (isCheckinRequest) { 12158 pw.println(); 12159 } 12160 } 12161 return; 12162 } 12163 } 12164 pw.println("No process found for: " + args[opti]); 12165 return; 12166 } 12167 12168 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12169 dumpDetails = true; 12170 } 12171 12172 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12173 12174 String[] innerArgs = new String[args.length-opti]; 12175 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12176 12177 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12178 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12179 long nativePss=0, dalvikPss=0, otherPss=0; 12180 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12181 12182 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12183 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12184 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12185 12186 long totalPss = 0; 12187 long cachedPss = 0; 12188 12189 Debug.MemoryInfo mi = null; 12190 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12191 final ProcessRecord r = procs.get(i); 12192 final IApplicationThread thread; 12193 final int pid; 12194 final int oomAdj; 12195 final boolean hasActivities; 12196 synchronized (this) { 12197 thread = r.thread; 12198 pid = r.pid; 12199 oomAdj = r.getSetAdjWithServices(); 12200 hasActivities = r.activities.size() > 0; 12201 } 12202 if (thread != null) { 12203 if (!isCheckinRequest && dumpDetails) { 12204 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12205 } 12206 if (mi == null) { 12207 mi = new Debug.MemoryInfo(); 12208 } 12209 if (dumpDetails || (!brief && !oomOnly)) { 12210 Debug.getMemoryInfo(pid, mi); 12211 } else { 12212 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12213 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12214 } 12215 if (dumpDetails) { 12216 if (localOnly) { 12217 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12218 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12219 if (isCheckinRequest) { 12220 pw.println(); 12221 } 12222 } else { 12223 try { 12224 pw.flush(); 12225 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12226 dumpDalvik, innerArgs); 12227 } catch (RemoteException e) { 12228 if (!isCheckinRequest) { 12229 pw.println("Got RemoteException!"); 12230 pw.flush(); 12231 } 12232 } 12233 } 12234 } 12235 12236 final long myTotalPss = mi.getTotalPss(); 12237 final long myTotalUss = mi.getTotalUss(); 12238 12239 synchronized (this) { 12240 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12241 // Record this for posterity if the process has been stable. 12242 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12243 } 12244 } 12245 12246 if (!isCheckinRequest && mi != null) { 12247 totalPss += myTotalPss; 12248 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12249 (hasActivities ? " / activities)" : ")"), 12250 r.processName, myTotalPss, pid, hasActivities); 12251 procMems.add(pssItem); 12252 procMemsMap.put(pid, pssItem); 12253 12254 nativePss += mi.nativePss; 12255 dalvikPss += mi.dalvikPss; 12256 otherPss += mi.otherPss; 12257 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12258 long mem = mi.getOtherPss(j); 12259 miscPss[j] += mem; 12260 otherPss -= mem; 12261 } 12262 12263 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12264 cachedPss += myTotalPss; 12265 } 12266 12267 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12268 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12269 || oomIndex == (oomPss.length-1)) { 12270 oomPss[oomIndex] += myTotalPss; 12271 if (oomProcs[oomIndex] == null) { 12272 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12273 } 12274 oomProcs[oomIndex].add(pssItem); 12275 break; 12276 } 12277 } 12278 } 12279 } 12280 } 12281 12282 if (!isCheckinRequest && procs.size() > 1) { 12283 // If we are showing aggregations, also look for native processes to 12284 // include so that our aggregations are more accurate. 12285 updateCpuStatsNow(); 12286 synchronized (mProcessCpuThread) { 12287 final int N = mProcessCpuTracker.countStats(); 12288 for (int i=0; i<N; i++) { 12289 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12290 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12291 if (mi == null) { 12292 mi = new Debug.MemoryInfo(); 12293 } 12294 if (!brief && !oomOnly) { 12295 Debug.getMemoryInfo(st.pid, mi); 12296 } else { 12297 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12298 mi.nativePrivateDirty = (int)tmpLong[0]; 12299 } 12300 12301 final long myTotalPss = mi.getTotalPss(); 12302 totalPss += myTotalPss; 12303 12304 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12305 st.name, myTotalPss, st.pid, false); 12306 procMems.add(pssItem); 12307 12308 nativePss += mi.nativePss; 12309 dalvikPss += mi.dalvikPss; 12310 otherPss += mi.otherPss; 12311 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12312 long mem = mi.getOtherPss(j); 12313 miscPss[j] += mem; 12314 otherPss -= mem; 12315 } 12316 oomPss[0] += myTotalPss; 12317 if (oomProcs[0] == null) { 12318 oomProcs[0] = new ArrayList<MemItem>(); 12319 } 12320 oomProcs[0].add(pssItem); 12321 } 12322 } 12323 } 12324 12325 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12326 12327 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12328 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12329 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12330 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12331 String label = Debug.MemoryInfo.getOtherLabel(j); 12332 catMems.add(new MemItem(label, label, miscPss[j], j)); 12333 } 12334 12335 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12336 for (int j=0; j<oomPss.length; j++) { 12337 if (oomPss[j] != 0) { 12338 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12339 : DUMP_MEM_OOM_LABEL[j]; 12340 MemItem item = new MemItem(label, label, oomPss[j], 12341 DUMP_MEM_OOM_ADJ[j]); 12342 item.subitems = oomProcs[j]; 12343 oomMems.add(item); 12344 } 12345 } 12346 12347 if (!brief && !oomOnly && !isCompact) { 12348 pw.println(); 12349 pw.println("Total PSS by process:"); 12350 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12351 pw.println(); 12352 } 12353 if (!isCompact) { 12354 pw.println("Total PSS by OOM adjustment:"); 12355 } 12356 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12357 if (!brief && !oomOnly) { 12358 PrintWriter out = categoryPw != null ? categoryPw : pw; 12359 if (!isCompact) { 12360 out.println(); 12361 out.println("Total PSS by category:"); 12362 } 12363 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12364 } 12365 if (!isCompact) { 12366 pw.println(); 12367 } 12368 MemInfoReader memInfo = new MemInfoReader(); 12369 memInfo.readMemInfo(); 12370 if (!brief) { 12371 if (!isCompact) { 12372 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12373 pw.print(" kB (status "); 12374 switch (mLastMemoryLevel) { 12375 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12376 pw.println("normal)"); 12377 break; 12378 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12379 pw.println("moderate)"); 12380 break; 12381 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12382 pw.println("low)"); 12383 break; 12384 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12385 pw.println("critical)"); 12386 break; 12387 default: 12388 pw.print(mLastMemoryLevel); 12389 pw.println(")"); 12390 break; 12391 } 12392 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12393 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12394 pw.print(cachedPss); pw.print(" cached pss + "); 12395 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12396 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12397 } else { 12398 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12399 pw.print(cachedPss + memInfo.getCachedSizeKb() 12400 + memInfo.getFreeSizeKb()); pw.print(","); 12401 pw.println(totalPss - cachedPss); 12402 } 12403 } 12404 if (!isCompact) { 12405 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12406 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12407 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12408 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12409 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12410 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12411 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12412 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12413 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12414 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12415 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12416 } 12417 if (!brief) { 12418 if (memInfo.getZramTotalSizeKb() != 0) { 12419 if (!isCompact) { 12420 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12421 pw.print(" kB physical used for "); 12422 pw.print(memInfo.getSwapTotalSizeKb() 12423 - memInfo.getSwapFreeSizeKb()); 12424 pw.print(" kB in swap ("); 12425 pw.print(memInfo.getSwapTotalSizeKb()); 12426 pw.println(" kB total swap)"); 12427 } else { 12428 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12429 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12430 pw.println(memInfo.getSwapFreeSizeKb()); 12431 } 12432 } 12433 final int[] SINGLE_LONG_FORMAT = new int[] { 12434 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12435 }; 12436 long[] longOut = new long[1]; 12437 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12438 SINGLE_LONG_FORMAT, null, longOut, null); 12439 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12440 longOut[0] = 0; 12441 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12442 SINGLE_LONG_FORMAT, null, longOut, null); 12443 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12444 longOut[0] = 0; 12445 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12446 SINGLE_LONG_FORMAT, null, longOut, null); 12447 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12448 longOut[0] = 0; 12449 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12450 SINGLE_LONG_FORMAT, null, longOut, null); 12451 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12452 if (!isCompact) { 12453 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12454 pw.print(" KSM: "); pw.print(sharing); 12455 pw.print(" kB saved from shared "); 12456 pw.print(shared); pw.println(" kB"); 12457 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12458 pw.print(voltile); pw.println(" kB volatile"); 12459 } 12460 pw.print(" Tuning: "); 12461 pw.print(ActivityManager.staticGetMemoryClass()); 12462 pw.print(" (large "); 12463 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12464 pw.print("), oom "); 12465 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12466 pw.print(" kB"); 12467 pw.print(", restore limit "); 12468 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12469 pw.print(" kB"); 12470 if (ActivityManager.isLowRamDeviceStatic()) { 12471 pw.print(" (low-ram)"); 12472 } 12473 if (ActivityManager.isHighEndGfx()) { 12474 pw.print(" (high-end-gfx)"); 12475 } 12476 pw.println(); 12477 } else { 12478 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12479 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12480 pw.println(voltile); 12481 pw.print("tuning,"); 12482 pw.print(ActivityManager.staticGetMemoryClass()); 12483 pw.print(','); 12484 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12485 pw.print(','); 12486 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12487 if (ActivityManager.isLowRamDeviceStatic()) { 12488 pw.print(",low-ram"); 12489 } 12490 if (ActivityManager.isHighEndGfx()) { 12491 pw.print(",high-end-gfx"); 12492 } 12493 pw.println(); 12494 } 12495 } 12496 } 12497 } 12498 12499 /** 12500 * Searches array of arguments for the specified string 12501 * @param args array of argument strings 12502 * @param value value to search for 12503 * @return true if the value is contained in the array 12504 */ 12505 private static boolean scanArgs(String[] args, String value) { 12506 if (args != null) { 12507 for (String arg : args) { 12508 if (value.equals(arg)) { 12509 return true; 12510 } 12511 } 12512 } 12513 return false; 12514 } 12515 12516 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12517 ContentProviderRecord cpr, boolean always) { 12518 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12519 12520 if (!inLaunching || always) { 12521 synchronized (cpr) { 12522 cpr.launchingApp = null; 12523 cpr.notifyAll(); 12524 } 12525 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12526 String names[] = cpr.info.authority.split(";"); 12527 for (int j = 0; j < names.length; j++) { 12528 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12529 } 12530 } 12531 12532 for (int i=0; i<cpr.connections.size(); i++) { 12533 ContentProviderConnection conn = cpr.connections.get(i); 12534 if (conn.waiting) { 12535 // If this connection is waiting for the provider, then we don't 12536 // need to mess with its process unless we are always removing 12537 // or for some reason the provider is not currently launching. 12538 if (inLaunching && !always) { 12539 continue; 12540 } 12541 } 12542 ProcessRecord capp = conn.client; 12543 conn.dead = true; 12544 if (conn.stableCount > 0) { 12545 if (!capp.persistent && capp.thread != null 12546 && capp.pid != 0 12547 && capp.pid != MY_PID) { 12548 killUnneededProcessLocked(capp, "depends on provider " 12549 + cpr.name.flattenToShortString() 12550 + " in dying proc " + (proc != null ? proc.processName : "??")); 12551 } 12552 } else if (capp.thread != null && conn.provider.provider != null) { 12553 try { 12554 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12555 } catch (RemoteException e) { 12556 } 12557 // In the protocol here, we don't expect the client to correctly 12558 // clean up this connection, we'll just remove it. 12559 cpr.connections.remove(i); 12560 conn.client.conProviders.remove(conn); 12561 } 12562 } 12563 12564 if (inLaunching && always) { 12565 mLaunchingProviders.remove(cpr); 12566 } 12567 return inLaunching; 12568 } 12569 12570 /** 12571 * Main code for cleaning up a process when it has gone away. This is 12572 * called both as a result of the process dying, or directly when stopping 12573 * a process when running in single process mode. 12574 */ 12575 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12576 boolean restarting, boolean allowRestart, int index) { 12577 if (index >= 0) { 12578 removeLruProcessLocked(app); 12579 ProcessList.remove(app.pid); 12580 } 12581 12582 mProcessesToGc.remove(app); 12583 mPendingPssProcesses.remove(app); 12584 12585 // Dismiss any open dialogs. 12586 if (app.crashDialog != null && !app.forceCrashReport) { 12587 app.crashDialog.dismiss(); 12588 app.crashDialog = null; 12589 } 12590 if (app.anrDialog != null) { 12591 app.anrDialog.dismiss(); 12592 app.anrDialog = null; 12593 } 12594 if (app.waitDialog != null) { 12595 app.waitDialog.dismiss(); 12596 app.waitDialog = null; 12597 } 12598 12599 app.crashing = false; 12600 app.notResponding = false; 12601 12602 app.resetPackageList(mProcessStats); 12603 app.unlinkDeathRecipient(); 12604 app.makeInactive(mProcessStats); 12605 app.forcingToForeground = null; 12606 updateProcessForegroundLocked(app, false, false); 12607 app.foregroundActivities = false; 12608 app.hasShownUi = false; 12609 app.treatLikeActivity = false; 12610 app.hasAboveClient = false; 12611 app.hasClientActivities = false; 12612 12613 mServices.killServicesLocked(app, allowRestart); 12614 12615 boolean restart = false; 12616 12617 // Remove published content providers. 12618 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12619 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12620 final boolean always = app.bad || !allowRestart; 12621 if (removeDyingProviderLocked(app, cpr, always) || always) { 12622 // We left the provider in the launching list, need to 12623 // restart it. 12624 restart = true; 12625 } 12626 12627 cpr.provider = null; 12628 cpr.proc = null; 12629 } 12630 app.pubProviders.clear(); 12631 12632 // Take care of any launching providers waiting for this process. 12633 if (checkAppInLaunchingProvidersLocked(app, false)) { 12634 restart = true; 12635 } 12636 12637 // Unregister from connected content providers. 12638 if (!app.conProviders.isEmpty()) { 12639 for (int i=0; i<app.conProviders.size(); i++) { 12640 ContentProviderConnection conn = app.conProviders.get(i); 12641 conn.provider.connections.remove(conn); 12642 } 12643 app.conProviders.clear(); 12644 } 12645 12646 // At this point there may be remaining entries in mLaunchingProviders 12647 // where we were the only one waiting, so they are no longer of use. 12648 // Look for these and clean up if found. 12649 // XXX Commented out for now. Trying to figure out a way to reproduce 12650 // the actual situation to identify what is actually going on. 12651 if (false) { 12652 for (int i=0; i<mLaunchingProviders.size(); i++) { 12653 ContentProviderRecord cpr = (ContentProviderRecord) 12654 mLaunchingProviders.get(i); 12655 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12656 synchronized (cpr) { 12657 cpr.launchingApp = null; 12658 cpr.notifyAll(); 12659 } 12660 } 12661 } 12662 } 12663 12664 skipCurrentReceiverLocked(app); 12665 12666 // Unregister any receivers. 12667 for (int i=app.receivers.size()-1; i>=0; i--) { 12668 removeReceiverLocked(app.receivers.valueAt(i)); 12669 } 12670 app.receivers.clear(); 12671 12672 // If the app is undergoing backup, tell the backup manager about it 12673 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12674 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12675 + mBackupTarget.appInfo + " died during backup"); 12676 try { 12677 IBackupManager bm = IBackupManager.Stub.asInterface( 12678 ServiceManager.getService(Context.BACKUP_SERVICE)); 12679 bm.agentDisconnected(app.info.packageName); 12680 } catch (RemoteException e) { 12681 // can't happen; backup manager is local 12682 } 12683 } 12684 12685 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12686 ProcessChangeItem item = mPendingProcessChanges.get(i); 12687 if (item.pid == app.pid) { 12688 mPendingProcessChanges.remove(i); 12689 mAvailProcessChanges.add(item); 12690 } 12691 } 12692 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12693 12694 // If the caller is restarting this app, then leave it in its 12695 // current lists and let the caller take care of it. 12696 if (restarting) { 12697 return; 12698 } 12699 12700 if (!app.persistent || app.isolated) { 12701 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12702 "Removing non-persistent process during cleanup: " + app); 12703 mProcessNames.remove(app.processName, app.uid); 12704 mIsolatedProcesses.remove(app.uid); 12705 if (mHeavyWeightProcess == app) { 12706 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12707 mHeavyWeightProcess.userId, 0)); 12708 mHeavyWeightProcess = null; 12709 } 12710 } else if (!app.removed) { 12711 // This app is persistent, so we need to keep its record around. 12712 // If it is not already on the pending app list, add it there 12713 // and start a new process for it. 12714 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12715 mPersistentStartingProcesses.add(app); 12716 restart = true; 12717 } 12718 } 12719 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12720 "Clean-up removing on hold: " + app); 12721 mProcessesOnHold.remove(app); 12722 12723 if (app == mHomeProcess) { 12724 mHomeProcess = null; 12725 } 12726 if (app == mPreviousProcess) { 12727 mPreviousProcess = null; 12728 } 12729 12730 if (restart && !app.isolated) { 12731 // We have components that still need to be running in the 12732 // process, so re-launch it. 12733 mProcessNames.put(app.processName, app.uid, app); 12734 startProcessLocked(app, "restart", app.processName); 12735 } else if (app.pid > 0 && app.pid != MY_PID) { 12736 // Goodbye! 12737 boolean removed; 12738 synchronized (mPidsSelfLocked) { 12739 mPidsSelfLocked.remove(app.pid); 12740 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12741 } 12742 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12743 app.processName, app.info.uid); 12744 if (app.isolated) { 12745 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12746 } 12747 app.setPid(0); 12748 } 12749 } 12750 12751 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12752 // Look through the content providers we are waiting to have launched, 12753 // and if any run in this process then either schedule a restart of 12754 // the process or kill the client waiting for it if this process has 12755 // gone bad. 12756 int NL = mLaunchingProviders.size(); 12757 boolean restart = false; 12758 for (int i=0; i<NL; i++) { 12759 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12760 if (cpr.launchingApp == app) { 12761 if (!alwaysBad && !app.bad) { 12762 restart = true; 12763 } else { 12764 removeDyingProviderLocked(app, cpr, true); 12765 // cpr should have been removed from mLaunchingProviders 12766 NL = mLaunchingProviders.size(); 12767 i--; 12768 } 12769 } 12770 } 12771 return restart; 12772 } 12773 12774 // ========================================================= 12775 // SERVICES 12776 // ========================================================= 12777 12778 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12779 int flags) { 12780 enforceNotIsolatedCaller("getServices"); 12781 synchronized (this) { 12782 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12783 } 12784 } 12785 12786 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12787 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12788 synchronized (this) { 12789 return mServices.getRunningServiceControlPanelLocked(name); 12790 } 12791 } 12792 12793 public ComponentName startService(IApplicationThread caller, Intent service, 12794 String resolvedType, int userId) { 12795 enforceNotIsolatedCaller("startService"); 12796 // Refuse possible leaked file descriptors 12797 if (service != null && service.hasFileDescriptors() == true) { 12798 throw new IllegalArgumentException("File descriptors passed in Intent"); 12799 } 12800 12801 if (DEBUG_SERVICE) 12802 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12803 synchronized(this) { 12804 final int callingPid = Binder.getCallingPid(); 12805 final int callingUid = Binder.getCallingUid(); 12806 final long origId = Binder.clearCallingIdentity(); 12807 ComponentName res = mServices.startServiceLocked(caller, service, 12808 resolvedType, callingPid, callingUid, userId); 12809 Binder.restoreCallingIdentity(origId); 12810 return res; 12811 } 12812 } 12813 12814 ComponentName startServiceInPackage(int uid, 12815 Intent service, String resolvedType, int userId) { 12816 synchronized(this) { 12817 if (DEBUG_SERVICE) 12818 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12819 final long origId = Binder.clearCallingIdentity(); 12820 ComponentName res = mServices.startServiceLocked(null, service, 12821 resolvedType, -1, uid, userId); 12822 Binder.restoreCallingIdentity(origId); 12823 return res; 12824 } 12825 } 12826 12827 public int stopService(IApplicationThread caller, Intent service, 12828 String resolvedType, int userId) { 12829 enforceNotIsolatedCaller("stopService"); 12830 // Refuse possible leaked file descriptors 12831 if (service != null && service.hasFileDescriptors() == true) { 12832 throw new IllegalArgumentException("File descriptors passed in Intent"); 12833 } 12834 12835 synchronized(this) { 12836 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12837 } 12838 } 12839 12840 public IBinder peekService(Intent service, String resolvedType) { 12841 enforceNotIsolatedCaller("peekService"); 12842 // Refuse possible leaked file descriptors 12843 if (service != null && service.hasFileDescriptors() == true) { 12844 throw new IllegalArgumentException("File descriptors passed in Intent"); 12845 } 12846 synchronized(this) { 12847 return mServices.peekServiceLocked(service, resolvedType); 12848 } 12849 } 12850 12851 public boolean stopServiceToken(ComponentName className, IBinder token, 12852 int startId) { 12853 synchronized(this) { 12854 return mServices.stopServiceTokenLocked(className, token, startId); 12855 } 12856 } 12857 12858 public void setServiceForeground(ComponentName className, IBinder token, 12859 int id, Notification notification, boolean removeNotification) { 12860 synchronized(this) { 12861 mServices.setServiceForegroundLocked(className, token, id, notification, 12862 removeNotification); 12863 } 12864 } 12865 12866 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12867 boolean requireFull, String name, String callerPackage) { 12868 final int callingUserId = UserHandle.getUserId(callingUid); 12869 if (callingUserId != userId) { 12870 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12871 if ((requireFull || checkComponentPermission( 12872 android.Manifest.permission.INTERACT_ACROSS_USERS, 12873 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12874 && checkComponentPermission( 12875 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12876 callingPid, callingUid, -1, true) 12877 != PackageManager.PERMISSION_GRANTED) { 12878 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12879 // In this case, they would like to just execute as their 12880 // owner user instead of failing. 12881 userId = callingUserId; 12882 } else { 12883 StringBuilder builder = new StringBuilder(128); 12884 builder.append("Permission Denial: "); 12885 builder.append(name); 12886 if (callerPackage != null) { 12887 builder.append(" from "); 12888 builder.append(callerPackage); 12889 } 12890 builder.append(" asks to run as user "); 12891 builder.append(userId); 12892 builder.append(" but is calling from user "); 12893 builder.append(UserHandle.getUserId(callingUid)); 12894 builder.append("; this requires "); 12895 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12896 if (!requireFull) { 12897 builder.append(" or "); 12898 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12899 } 12900 String msg = builder.toString(); 12901 Slog.w(TAG, msg); 12902 throw new SecurityException(msg); 12903 } 12904 } 12905 } 12906 if (userId == UserHandle.USER_CURRENT 12907 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12908 // Note that we may be accessing this outside of a lock... 12909 // shouldn't be a big deal, if this is being called outside 12910 // of a locked context there is intrinsically a race with 12911 // the value the caller will receive and someone else changing it. 12912 userId = mCurrentUserId; 12913 } 12914 if (!allowAll && userId < 0) { 12915 throw new IllegalArgumentException( 12916 "Call does not support special user #" + userId); 12917 } 12918 } 12919 return userId; 12920 } 12921 12922 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12923 String className, int flags) { 12924 boolean result = false; 12925 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12926 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12927 if (ActivityManager.checkUidPermission( 12928 android.Manifest.permission.INTERACT_ACROSS_USERS, 12929 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12930 ComponentName comp = new ComponentName(aInfo.packageName, className); 12931 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12932 + " requests FLAG_SINGLE_USER, but app does not hold " 12933 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12934 Slog.w(TAG, msg); 12935 throw new SecurityException(msg); 12936 } 12937 result = true; 12938 } 12939 } else if (componentProcessName == aInfo.packageName) { 12940 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12941 } else if ("system".equals(componentProcessName)) { 12942 result = true; 12943 } 12944 if (DEBUG_MU) { 12945 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12946 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12947 } 12948 return result; 12949 } 12950 12951 public int bindService(IApplicationThread caller, IBinder token, 12952 Intent service, String resolvedType, 12953 IServiceConnection connection, int flags, int userId) { 12954 enforceNotIsolatedCaller("bindService"); 12955 // Refuse possible leaked file descriptors 12956 if (service != null && service.hasFileDescriptors() == true) { 12957 throw new IllegalArgumentException("File descriptors passed in Intent"); 12958 } 12959 12960 synchronized(this) { 12961 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12962 connection, flags, userId); 12963 } 12964 } 12965 12966 public boolean unbindService(IServiceConnection connection) { 12967 synchronized (this) { 12968 return mServices.unbindServiceLocked(connection); 12969 } 12970 } 12971 12972 public void publishService(IBinder token, Intent intent, IBinder service) { 12973 // Refuse possible leaked file descriptors 12974 if (intent != null && intent.hasFileDescriptors() == true) { 12975 throw new IllegalArgumentException("File descriptors passed in Intent"); 12976 } 12977 12978 synchronized(this) { 12979 if (!(token instanceof ServiceRecord)) { 12980 throw new IllegalArgumentException("Invalid service token"); 12981 } 12982 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12983 } 12984 } 12985 12986 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12987 // Refuse possible leaked file descriptors 12988 if (intent != null && intent.hasFileDescriptors() == true) { 12989 throw new IllegalArgumentException("File descriptors passed in Intent"); 12990 } 12991 12992 synchronized(this) { 12993 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12994 } 12995 } 12996 12997 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12998 synchronized(this) { 12999 if (!(token instanceof ServiceRecord)) { 13000 throw new IllegalArgumentException("Invalid service token"); 13001 } 13002 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13003 } 13004 } 13005 13006 // ========================================================= 13007 // BACKUP AND RESTORE 13008 // ========================================================= 13009 13010 // Cause the target app to be launched if necessary and its backup agent 13011 // instantiated. The backup agent will invoke backupAgentCreated() on the 13012 // activity manager to announce its creation. 13013 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13014 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13015 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13016 13017 synchronized(this) { 13018 // !!! TODO: currently no check here that we're already bound 13019 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13020 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13021 synchronized (stats) { 13022 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13023 } 13024 13025 // Backup agent is now in use, its package can't be stopped. 13026 try { 13027 AppGlobals.getPackageManager().setPackageStoppedState( 13028 app.packageName, false, UserHandle.getUserId(app.uid)); 13029 } catch (RemoteException e) { 13030 } catch (IllegalArgumentException e) { 13031 Slog.w(TAG, "Failed trying to unstop package " 13032 + app.packageName + ": " + e); 13033 } 13034 13035 BackupRecord r = new BackupRecord(ss, app, backupMode); 13036 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13037 ? new ComponentName(app.packageName, app.backupAgentName) 13038 : new ComponentName("android", "FullBackupAgent"); 13039 // startProcessLocked() returns existing proc's record if it's already running 13040 ProcessRecord proc = startProcessLocked(app.processName, app, 13041 false, 0, "backup", hostingName, false, false, false); 13042 if (proc == null) { 13043 Slog.e(TAG, "Unable to start backup agent process " + r); 13044 return false; 13045 } 13046 13047 r.app = proc; 13048 mBackupTarget = r; 13049 mBackupAppName = app.packageName; 13050 13051 // Try not to kill the process during backup 13052 updateOomAdjLocked(proc); 13053 13054 // If the process is already attached, schedule the creation of the backup agent now. 13055 // If it is not yet live, this will be done when it attaches to the framework. 13056 if (proc.thread != null) { 13057 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13058 try { 13059 proc.thread.scheduleCreateBackupAgent(app, 13060 compatibilityInfoForPackageLocked(app), backupMode); 13061 } catch (RemoteException e) { 13062 // Will time out on the backup manager side 13063 } 13064 } else { 13065 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13066 } 13067 // Invariants: at this point, the target app process exists and the application 13068 // is either already running or in the process of coming up. mBackupTarget and 13069 // mBackupAppName describe the app, so that when it binds back to the AM we 13070 // know that it's scheduled for a backup-agent operation. 13071 } 13072 13073 return true; 13074 } 13075 13076 @Override 13077 public void clearPendingBackup() { 13078 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13079 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13080 13081 synchronized (this) { 13082 mBackupTarget = null; 13083 mBackupAppName = null; 13084 } 13085 } 13086 13087 // A backup agent has just come up 13088 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13089 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13090 + " = " + agent); 13091 13092 synchronized(this) { 13093 if (!agentPackageName.equals(mBackupAppName)) { 13094 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13095 return; 13096 } 13097 } 13098 13099 long oldIdent = Binder.clearCallingIdentity(); 13100 try { 13101 IBackupManager bm = IBackupManager.Stub.asInterface( 13102 ServiceManager.getService(Context.BACKUP_SERVICE)); 13103 bm.agentConnected(agentPackageName, agent); 13104 } catch (RemoteException e) { 13105 // can't happen; the backup manager service is local 13106 } catch (Exception e) { 13107 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13108 e.printStackTrace(); 13109 } finally { 13110 Binder.restoreCallingIdentity(oldIdent); 13111 } 13112 } 13113 13114 // done with this agent 13115 public void unbindBackupAgent(ApplicationInfo appInfo) { 13116 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13117 if (appInfo == null) { 13118 Slog.w(TAG, "unbind backup agent for null app"); 13119 return; 13120 } 13121 13122 synchronized(this) { 13123 try { 13124 if (mBackupAppName == null) { 13125 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13126 return; 13127 } 13128 13129 if (!mBackupAppName.equals(appInfo.packageName)) { 13130 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13131 return; 13132 } 13133 13134 // Not backing this app up any more; reset its OOM adjustment 13135 final ProcessRecord proc = mBackupTarget.app; 13136 updateOomAdjLocked(proc); 13137 13138 // If the app crashed during backup, 'thread' will be null here 13139 if (proc.thread != null) { 13140 try { 13141 proc.thread.scheduleDestroyBackupAgent(appInfo, 13142 compatibilityInfoForPackageLocked(appInfo)); 13143 } catch (Exception e) { 13144 Slog.e(TAG, "Exception when unbinding backup agent:"); 13145 e.printStackTrace(); 13146 } 13147 } 13148 } finally { 13149 mBackupTarget = null; 13150 mBackupAppName = null; 13151 } 13152 } 13153 } 13154 // ========================================================= 13155 // BROADCASTS 13156 // ========================================================= 13157 13158 private final List getStickiesLocked(String action, IntentFilter filter, 13159 List cur, int userId) { 13160 final ContentResolver resolver = mContext.getContentResolver(); 13161 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13162 if (stickies == null) { 13163 return cur; 13164 } 13165 final ArrayList<Intent> list = stickies.get(action); 13166 if (list == null) { 13167 return cur; 13168 } 13169 int N = list.size(); 13170 for (int i=0; i<N; i++) { 13171 Intent intent = list.get(i); 13172 if (filter.match(resolver, intent, true, TAG) >= 0) { 13173 if (cur == null) { 13174 cur = new ArrayList<Intent>(); 13175 } 13176 cur.add(intent); 13177 } 13178 } 13179 return cur; 13180 } 13181 13182 boolean isPendingBroadcastProcessLocked(int pid) { 13183 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13184 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13185 } 13186 13187 void skipPendingBroadcastLocked(int pid) { 13188 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13189 for (BroadcastQueue queue : mBroadcastQueues) { 13190 queue.skipPendingBroadcastLocked(pid); 13191 } 13192 } 13193 13194 // The app just attached; send any pending broadcasts that it should receive 13195 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13196 boolean didSomething = false; 13197 for (BroadcastQueue queue : mBroadcastQueues) { 13198 didSomething |= queue.sendPendingBroadcastsLocked(app); 13199 } 13200 return didSomething; 13201 } 13202 13203 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13204 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13205 enforceNotIsolatedCaller("registerReceiver"); 13206 int callingUid; 13207 int callingPid; 13208 synchronized(this) { 13209 ProcessRecord callerApp = null; 13210 if (caller != null) { 13211 callerApp = getRecordForAppLocked(caller); 13212 if (callerApp == null) { 13213 throw new SecurityException( 13214 "Unable to find app for caller " + caller 13215 + " (pid=" + Binder.getCallingPid() 13216 + ") when registering receiver " + receiver); 13217 } 13218 if (callerApp.info.uid != Process.SYSTEM_UID && 13219 !callerApp.pkgList.containsKey(callerPackage) && 13220 !"android".equals(callerPackage)) { 13221 throw new SecurityException("Given caller package " + callerPackage 13222 + " is not running in process " + callerApp); 13223 } 13224 callingUid = callerApp.info.uid; 13225 callingPid = callerApp.pid; 13226 } else { 13227 callerPackage = null; 13228 callingUid = Binder.getCallingUid(); 13229 callingPid = Binder.getCallingPid(); 13230 } 13231 13232 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13233 true, true, "registerReceiver", callerPackage); 13234 13235 List allSticky = null; 13236 13237 // Look for any matching sticky broadcasts... 13238 Iterator actions = filter.actionsIterator(); 13239 if (actions != null) { 13240 while (actions.hasNext()) { 13241 String action = (String)actions.next(); 13242 allSticky = getStickiesLocked(action, filter, allSticky, 13243 UserHandle.USER_ALL); 13244 allSticky = getStickiesLocked(action, filter, allSticky, 13245 UserHandle.getUserId(callingUid)); 13246 } 13247 } else { 13248 allSticky = getStickiesLocked(null, filter, allSticky, 13249 UserHandle.USER_ALL); 13250 allSticky = getStickiesLocked(null, filter, allSticky, 13251 UserHandle.getUserId(callingUid)); 13252 } 13253 13254 // The first sticky in the list is returned directly back to 13255 // the client. 13256 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13257 13258 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13259 + ": " + sticky); 13260 13261 if (receiver == null) { 13262 return sticky; 13263 } 13264 13265 ReceiverList rl 13266 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13267 if (rl == null) { 13268 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13269 userId, receiver); 13270 if (rl.app != null) { 13271 rl.app.receivers.add(rl); 13272 } else { 13273 try { 13274 receiver.asBinder().linkToDeath(rl, 0); 13275 } catch (RemoteException e) { 13276 return sticky; 13277 } 13278 rl.linkedToDeath = true; 13279 } 13280 mRegisteredReceivers.put(receiver.asBinder(), rl); 13281 } else if (rl.uid != callingUid) { 13282 throw new IllegalArgumentException( 13283 "Receiver requested to register for uid " + callingUid 13284 + " was previously registered for uid " + rl.uid); 13285 } else if (rl.pid != callingPid) { 13286 throw new IllegalArgumentException( 13287 "Receiver requested to register for pid " + callingPid 13288 + " was previously registered for pid " + rl.pid); 13289 } else if (rl.userId != userId) { 13290 throw new IllegalArgumentException( 13291 "Receiver requested to register for user " + userId 13292 + " was previously registered for user " + rl.userId); 13293 } 13294 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13295 permission, callingUid, userId); 13296 rl.add(bf); 13297 if (!bf.debugCheck()) { 13298 Slog.w(TAG, "==> For Dynamic broadast"); 13299 } 13300 mReceiverResolver.addFilter(bf); 13301 13302 // Enqueue broadcasts for all existing stickies that match 13303 // this filter. 13304 if (allSticky != null) { 13305 ArrayList receivers = new ArrayList(); 13306 receivers.add(bf); 13307 13308 int N = allSticky.size(); 13309 for (int i=0; i<N; i++) { 13310 Intent intent = (Intent)allSticky.get(i); 13311 BroadcastQueue queue = broadcastQueueForIntent(intent); 13312 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13313 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13314 null, null, false, true, true, -1); 13315 queue.enqueueParallelBroadcastLocked(r); 13316 queue.scheduleBroadcastsLocked(); 13317 } 13318 } 13319 13320 return sticky; 13321 } 13322 } 13323 13324 public void unregisterReceiver(IIntentReceiver receiver) { 13325 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13326 13327 final long origId = Binder.clearCallingIdentity(); 13328 try { 13329 boolean doTrim = false; 13330 13331 synchronized(this) { 13332 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13333 if (rl != null) { 13334 if (rl.curBroadcast != null) { 13335 BroadcastRecord r = rl.curBroadcast; 13336 final boolean doNext = finishReceiverLocked( 13337 receiver.asBinder(), r.resultCode, r.resultData, 13338 r.resultExtras, r.resultAbort); 13339 if (doNext) { 13340 doTrim = true; 13341 r.queue.processNextBroadcast(false); 13342 } 13343 } 13344 13345 if (rl.app != null) { 13346 rl.app.receivers.remove(rl); 13347 } 13348 removeReceiverLocked(rl); 13349 if (rl.linkedToDeath) { 13350 rl.linkedToDeath = false; 13351 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13352 } 13353 } 13354 } 13355 13356 // If we actually concluded any broadcasts, we might now be able 13357 // to trim the recipients' apps from our working set 13358 if (doTrim) { 13359 trimApplications(); 13360 return; 13361 } 13362 13363 } finally { 13364 Binder.restoreCallingIdentity(origId); 13365 } 13366 } 13367 13368 void removeReceiverLocked(ReceiverList rl) { 13369 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13370 int N = rl.size(); 13371 for (int i=0; i<N; i++) { 13372 mReceiverResolver.removeFilter(rl.get(i)); 13373 } 13374 } 13375 13376 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13377 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13378 ProcessRecord r = mLruProcesses.get(i); 13379 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13380 try { 13381 r.thread.dispatchPackageBroadcast(cmd, packages); 13382 } catch (RemoteException ex) { 13383 } 13384 } 13385 } 13386 } 13387 13388 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13389 int[] users) { 13390 List<ResolveInfo> receivers = null; 13391 try { 13392 HashSet<ComponentName> singleUserReceivers = null; 13393 boolean scannedFirstReceivers = false; 13394 for (int user : users) { 13395 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13396 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13397 if (user != 0 && newReceivers != null) { 13398 // If this is not the primary user, we need to check for 13399 // any receivers that should be filtered out. 13400 for (int i=0; i<newReceivers.size(); i++) { 13401 ResolveInfo ri = newReceivers.get(i); 13402 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13403 newReceivers.remove(i); 13404 i--; 13405 } 13406 } 13407 } 13408 if (newReceivers != null && newReceivers.size() == 0) { 13409 newReceivers = null; 13410 } 13411 if (receivers == null) { 13412 receivers = newReceivers; 13413 } else if (newReceivers != null) { 13414 // We need to concatenate the additional receivers 13415 // found with what we have do far. This would be easy, 13416 // but we also need to de-dup any receivers that are 13417 // singleUser. 13418 if (!scannedFirstReceivers) { 13419 // Collect any single user receivers we had already retrieved. 13420 scannedFirstReceivers = true; 13421 for (int i=0; i<receivers.size(); i++) { 13422 ResolveInfo ri = receivers.get(i); 13423 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13424 ComponentName cn = new ComponentName( 13425 ri.activityInfo.packageName, ri.activityInfo.name); 13426 if (singleUserReceivers == null) { 13427 singleUserReceivers = new HashSet<ComponentName>(); 13428 } 13429 singleUserReceivers.add(cn); 13430 } 13431 } 13432 } 13433 // Add the new results to the existing results, tracking 13434 // and de-dupping single user receivers. 13435 for (int i=0; i<newReceivers.size(); i++) { 13436 ResolveInfo ri = newReceivers.get(i); 13437 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13438 ComponentName cn = new ComponentName( 13439 ri.activityInfo.packageName, ri.activityInfo.name); 13440 if (singleUserReceivers == null) { 13441 singleUserReceivers = new HashSet<ComponentName>(); 13442 } 13443 if (!singleUserReceivers.contains(cn)) { 13444 singleUserReceivers.add(cn); 13445 receivers.add(ri); 13446 } 13447 } else { 13448 receivers.add(ri); 13449 } 13450 } 13451 } 13452 } 13453 } catch (RemoteException ex) { 13454 // pm is in same process, this will never happen. 13455 } 13456 return receivers; 13457 } 13458 13459 private final int broadcastIntentLocked(ProcessRecord callerApp, 13460 String callerPackage, Intent intent, String resolvedType, 13461 IIntentReceiver resultTo, int resultCode, String resultData, 13462 Bundle map, String requiredPermission, int appOp, 13463 boolean ordered, boolean sticky, int callingPid, int callingUid, 13464 int userId) { 13465 intent = new Intent(intent); 13466 13467 // By default broadcasts do not go to stopped apps. 13468 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13469 13470 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13471 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13472 + " ordered=" + ordered + " userid=" + userId); 13473 if ((resultTo != null) && !ordered) { 13474 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13475 } 13476 13477 userId = handleIncomingUser(callingPid, callingUid, userId, 13478 true, false, "broadcast", callerPackage); 13479 13480 // Make sure that the user who is receiving this broadcast is started. 13481 // If not, we will just skip it. 13482 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13483 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13484 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13485 Slog.w(TAG, "Skipping broadcast of " + intent 13486 + ": user " + userId + " is stopped"); 13487 return ActivityManager.BROADCAST_SUCCESS; 13488 } 13489 } 13490 13491 /* 13492 * Prevent non-system code (defined here to be non-persistent 13493 * processes) from sending protected broadcasts. 13494 */ 13495 int callingAppId = UserHandle.getAppId(callingUid); 13496 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13497 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13498 callingUid == 0) { 13499 // Always okay. 13500 } else if (callerApp == null || !callerApp.persistent) { 13501 try { 13502 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13503 intent.getAction())) { 13504 String msg = "Permission Denial: not allowed to send broadcast " 13505 + intent.getAction() + " from pid=" 13506 + callingPid + ", uid=" + callingUid; 13507 Slog.w(TAG, msg); 13508 throw new SecurityException(msg); 13509 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13510 // Special case for compatibility: we don't want apps to send this, 13511 // but historically it has not been protected and apps may be using it 13512 // to poke their own app widget. So, instead of making it protected, 13513 // just limit it to the caller. 13514 if (callerApp == null) { 13515 String msg = "Permission Denial: not allowed to send broadcast " 13516 + intent.getAction() + " from unknown caller."; 13517 Slog.w(TAG, msg); 13518 throw new SecurityException(msg); 13519 } else if (intent.getComponent() != null) { 13520 // They are good enough to send to an explicit component... verify 13521 // it is being sent to the calling app. 13522 if (!intent.getComponent().getPackageName().equals( 13523 callerApp.info.packageName)) { 13524 String msg = "Permission Denial: not allowed to send broadcast " 13525 + intent.getAction() + " to " 13526 + intent.getComponent().getPackageName() + " from " 13527 + callerApp.info.packageName; 13528 Slog.w(TAG, msg); 13529 throw new SecurityException(msg); 13530 } 13531 } else { 13532 // Limit broadcast to their own package. 13533 intent.setPackage(callerApp.info.packageName); 13534 } 13535 } 13536 } catch (RemoteException e) { 13537 Slog.w(TAG, "Remote exception", e); 13538 return ActivityManager.BROADCAST_SUCCESS; 13539 } 13540 } 13541 13542 // Handle special intents: if this broadcast is from the package 13543 // manager about a package being removed, we need to remove all of 13544 // its activities from the history stack. 13545 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13546 intent.getAction()); 13547 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13548 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13549 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13550 || uidRemoved) { 13551 if (checkComponentPermission( 13552 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13553 callingPid, callingUid, -1, true) 13554 == PackageManager.PERMISSION_GRANTED) { 13555 if (uidRemoved) { 13556 final Bundle intentExtras = intent.getExtras(); 13557 final int uid = intentExtras != null 13558 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13559 if (uid >= 0) { 13560 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13561 synchronized (bs) { 13562 bs.removeUidStatsLocked(uid); 13563 } 13564 mAppOpsService.uidRemoved(uid); 13565 } 13566 } else { 13567 // If resources are unavailable just force stop all 13568 // those packages and flush the attribute cache as well. 13569 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13570 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13571 if (list != null && (list.length > 0)) { 13572 for (String pkg : list) { 13573 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13574 "storage unmount"); 13575 } 13576 sendPackageBroadcastLocked( 13577 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13578 } 13579 } else { 13580 Uri data = intent.getData(); 13581 String ssp; 13582 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13583 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13584 intent.getAction()); 13585 boolean fullUninstall = removed && 13586 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13587 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13588 forceStopPackageLocked(ssp, UserHandle.getAppId( 13589 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13590 false, fullUninstall, userId, 13591 removed ? "pkg removed" : "pkg changed"); 13592 } 13593 if (removed) { 13594 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13595 new String[] {ssp}, userId); 13596 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13597 mAppOpsService.packageRemoved( 13598 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13599 13600 // Remove all permissions granted from/to this package 13601 removeUriPermissionsForPackageLocked(ssp, userId, true); 13602 } 13603 } 13604 } 13605 } 13606 } 13607 } else { 13608 String msg = "Permission Denial: " + intent.getAction() 13609 + " broadcast from " + callerPackage + " (pid=" + callingPid 13610 + ", uid=" + callingUid + ")" 13611 + " requires " 13612 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13613 Slog.w(TAG, msg); 13614 throw new SecurityException(msg); 13615 } 13616 13617 // Special case for adding a package: by default turn on compatibility 13618 // mode. 13619 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13620 Uri data = intent.getData(); 13621 String ssp; 13622 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13623 mCompatModePackages.handlePackageAddedLocked(ssp, 13624 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13625 } 13626 } 13627 13628 /* 13629 * If this is the time zone changed action, queue up a message that will reset the timezone 13630 * of all currently running processes. This message will get queued up before the broadcast 13631 * happens. 13632 */ 13633 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13634 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13635 } 13636 13637 /* 13638 * If the user set the time, let all running processes know. 13639 */ 13640 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13641 final int is24Hour = intent.getBooleanExtra( 13642 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13643 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13644 } 13645 13646 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13647 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13648 } 13649 13650 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13651 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13652 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13653 } 13654 13655 // Add to the sticky list if requested. 13656 if (sticky) { 13657 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13658 callingPid, callingUid) 13659 != PackageManager.PERMISSION_GRANTED) { 13660 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13661 + callingPid + ", uid=" + callingUid 13662 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13663 Slog.w(TAG, msg); 13664 throw new SecurityException(msg); 13665 } 13666 if (requiredPermission != null) { 13667 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13668 + " and enforce permission " + requiredPermission); 13669 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13670 } 13671 if (intent.getComponent() != null) { 13672 throw new SecurityException( 13673 "Sticky broadcasts can't target a specific component"); 13674 } 13675 // We use userId directly here, since the "all" target is maintained 13676 // as a separate set of sticky broadcasts. 13677 if (userId != UserHandle.USER_ALL) { 13678 // But first, if this is not a broadcast to all users, then 13679 // make sure it doesn't conflict with an existing broadcast to 13680 // all users. 13681 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13682 UserHandle.USER_ALL); 13683 if (stickies != null) { 13684 ArrayList<Intent> list = stickies.get(intent.getAction()); 13685 if (list != null) { 13686 int N = list.size(); 13687 int i; 13688 for (i=0; i<N; i++) { 13689 if (intent.filterEquals(list.get(i))) { 13690 throw new IllegalArgumentException( 13691 "Sticky broadcast " + intent + " for user " 13692 + userId + " conflicts with existing global broadcast"); 13693 } 13694 } 13695 } 13696 } 13697 } 13698 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13699 if (stickies == null) { 13700 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13701 mStickyBroadcasts.put(userId, stickies); 13702 } 13703 ArrayList<Intent> list = stickies.get(intent.getAction()); 13704 if (list == null) { 13705 list = new ArrayList<Intent>(); 13706 stickies.put(intent.getAction(), list); 13707 } 13708 int N = list.size(); 13709 int i; 13710 for (i=0; i<N; i++) { 13711 if (intent.filterEquals(list.get(i))) { 13712 // This sticky already exists, replace it. 13713 list.set(i, new Intent(intent)); 13714 break; 13715 } 13716 } 13717 if (i >= N) { 13718 list.add(new Intent(intent)); 13719 } 13720 } 13721 13722 int[] users; 13723 if (userId == UserHandle.USER_ALL) { 13724 // Caller wants broadcast to go to all started users. 13725 users = mStartedUserArray; 13726 } else { 13727 // Caller wants broadcast to go to one specific user. 13728 users = new int[] {userId}; 13729 } 13730 13731 // Figure out who all will receive this broadcast. 13732 List receivers = null; 13733 List<BroadcastFilter> registeredReceivers = null; 13734 // Need to resolve the intent to interested receivers... 13735 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13736 == 0) { 13737 receivers = collectReceiverComponents(intent, resolvedType, users); 13738 } 13739 if (intent.getComponent() == null) { 13740 registeredReceivers = mReceiverResolver.queryIntent(intent, 13741 resolvedType, false, userId); 13742 } 13743 13744 final boolean replacePending = 13745 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13746 13747 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13748 + " replacePending=" + replacePending); 13749 13750 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13751 if (!ordered && NR > 0) { 13752 // If we are not serializing this broadcast, then send the 13753 // registered receivers separately so they don't wait for the 13754 // components to be launched. 13755 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13756 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13757 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13758 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13759 ordered, sticky, false, userId); 13760 if (DEBUG_BROADCAST) Slog.v( 13761 TAG, "Enqueueing parallel broadcast " + r); 13762 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13763 if (!replaced) { 13764 queue.enqueueParallelBroadcastLocked(r); 13765 queue.scheduleBroadcastsLocked(); 13766 } 13767 registeredReceivers = null; 13768 NR = 0; 13769 } 13770 13771 // Merge into one list. 13772 int ir = 0; 13773 if (receivers != null) { 13774 // A special case for PACKAGE_ADDED: do not allow the package 13775 // being added to see this broadcast. This prevents them from 13776 // using this as a back door to get run as soon as they are 13777 // installed. Maybe in the future we want to have a special install 13778 // broadcast or such for apps, but we'd like to deliberately make 13779 // this decision. 13780 String skipPackages[] = null; 13781 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13782 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13783 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13784 Uri data = intent.getData(); 13785 if (data != null) { 13786 String pkgName = data.getSchemeSpecificPart(); 13787 if (pkgName != null) { 13788 skipPackages = new String[] { pkgName }; 13789 } 13790 } 13791 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13792 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13793 } 13794 if (skipPackages != null && (skipPackages.length > 0)) { 13795 for (String skipPackage : skipPackages) { 13796 if (skipPackage != null) { 13797 int NT = receivers.size(); 13798 for (int it=0; it<NT; it++) { 13799 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13800 if (curt.activityInfo.packageName.equals(skipPackage)) { 13801 receivers.remove(it); 13802 it--; 13803 NT--; 13804 } 13805 } 13806 } 13807 } 13808 } 13809 13810 int NT = receivers != null ? receivers.size() : 0; 13811 int it = 0; 13812 ResolveInfo curt = null; 13813 BroadcastFilter curr = null; 13814 while (it < NT && ir < NR) { 13815 if (curt == null) { 13816 curt = (ResolveInfo)receivers.get(it); 13817 } 13818 if (curr == null) { 13819 curr = registeredReceivers.get(ir); 13820 } 13821 if (curr.getPriority() >= curt.priority) { 13822 // Insert this broadcast record into the final list. 13823 receivers.add(it, curr); 13824 ir++; 13825 curr = null; 13826 it++; 13827 NT++; 13828 } else { 13829 // Skip to the next ResolveInfo in the final list. 13830 it++; 13831 curt = null; 13832 } 13833 } 13834 } 13835 while (ir < NR) { 13836 if (receivers == null) { 13837 receivers = new ArrayList(); 13838 } 13839 receivers.add(registeredReceivers.get(ir)); 13840 ir++; 13841 } 13842 13843 if ((receivers != null && receivers.size() > 0) 13844 || resultTo != null) { 13845 BroadcastQueue queue = broadcastQueueForIntent(intent); 13846 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13847 callerPackage, callingPid, callingUid, resolvedType, 13848 requiredPermission, appOp, receivers, resultTo, resultCode, 13849 resultData, map, ordered, sticky, false, userId); 13850 if (DEBUG_BROADCAST) Slog.v( 13851 TAG, "Enqueueing ordered broadcast " + r 13852 + ": prev had " + queue.mOrderedBroadcasts.size()); 13853 if (DEBUG_BROADCAST) { 13854 int seq = r.intent.getIntExtra("seq", -1); 13855 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13856 } 13857 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13858 if (!replaced) { 13859 queue.enqueueOrderedBroadcastLocked(r); 13860 queue.scheduleBroadcastsLocked(); 13861 } 13862 } 13863 13864 return ActivityManager.BROADCAST_SUCCESS; 13865 } 13866 13867 final Intent verifyBroadcastLocked(Intent intent) { 13868 // Refuse possible leaked file descriptors 13869 if (intent != null && intent.hasFileDescriptors() == true) { 13870 throw new IllegalArgumentException("File descriptors passed in Intent"); 13871 } 13872 13873 int flags = intent.getFlags(); 13874 13875 if (!mProcessesReady) { 13876 // if the caller really truly claims to know what they're doing, go 13877 // ahead and allow the broadcast without launching any receivers 13878 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13879 intent = new Intent(intent); 13880 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13881 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13882 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13883 + " before boot completion"); 13884 throw new IllegalStateException("Cannot broadcast before boot completed"); 13885 } 13886 } 13887 13888 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13889 throw new IllegalArgumentException( 13890 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13891 } 13892 13893 return intent; 13894 } 13895 13896 public final int broadcastIntent(IApplicationThread caller, 13897 Intent intent, String resolvedType, IIntentReceiver resultTo, 13898 int resultCode, String resultData, Bundle map, 13899 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13900 enforceNotIsolatedCaller("broadcastIntent"); 13901 synchronized(this) { 13902 intent = verifyBroadcastLocked(intent); 13903 13904 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13905 final int callingPid = Binder.getCallingPid(); 13906 final int callingUid = Binder.getCallingUid(); 13907 final long origId = Binder.clearCallingIdentity(); 13908 int res = broadcastIntentLocked(callerApp, 13909 callerApp != null ? callerApp.info.packageName : null, 13910 intent, resolvedType, resultTo, 13911 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13912 callingPid, callingUid, userId); 13913 Binder.restoreCallingIdentity(origId); 13914 return res; 13915 } 13916 } 13917 13918 int broadcastIntentInPackage(String packageName, int uid, 13919 Intent intent, String resolvedType, IIntentReceiver resultTo, 13920 int resultCode, String resultData, Bundle map, 13921 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13922 synchronized(this) { 13923 intent = verifyBroadcastLocked(intent); 13924 13925 final long origId = Binder.clearCallingIdentity(); 13926 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13927 resultTo, resultCode, resultData, map, requiredPermission, 13928 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13929 Binder.restoreCallingIdentity(origId); 13930 return res; 13931 } 13932 } 13933 13934 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13935 // Refuse possible leaked file descriptors 13936 if (intent != null && intent.hasFileDescriptors() == true) { 13937 throw new IllegalArgumentException("File descriptors passed in Intent"); 13938 } 13939 13940 userId = handleIncomingUser(Binder.getCallingPid(), 13941 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13942 13943 synchronized(this) { 13944 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13945 != PackageManager.PERMISSION_GRANTED) { 13946 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13947 + Binder.getCallingPid() 13948 + ", uid=" + Binder.getCallingUid() 13949 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13950 Slog.w(TAG, msg); 13951 throw new SecurityException(msg); 13952 } 13953 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13954 if (stickies != null) { 13955 ArrayList<Intent> list = stickies.get(intent.getAction()); 13956 if (list != null) { 13957 int N = list.size(); 13958 int i; 13959 for (i=0; i<N; i++) { 13960 if (intent.filterEquals(list.get(i))) { 13961 list.remove(i); 13962 break; 13963 } 13964 } 13965 if (list.size() <= 0) { 13966 stickies.remove(intent.getAction()); 13967 } 13968 } 13969 if (stickies.size() <= 0) { 13970 mStickyBroadcasts.remove(userId); 13971 } 13972 } 13973 } 13974 } 13975 13976 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13977 String resultData, Bundle resultExtras, boolean resultAbort) { 13978 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13979 if (r == null) { 13980 Slog.w(TAG, "finishReceiver called but not found on queue"); 13981 return false; 13982 } 13983 13984 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13985 } 13986 13987 void backgroundServicesFinishedLocked(int userId) { 13988 for (BroadcastQueue queue : mBroadcastQueues) { 13989 queue.backgroundServicesFinishedLocked(userId); 13990 } 13991 } 13992 13993 public void finishReceiver(IBinder who, int resultCode, String resultData, 13994 Bundle resultExtras, boolean resultAbort) { 13995 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13996 13997 // Refuse possible leaked file descriptors 13998 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13999 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14000 } 14001 14002 final long origId = Binder.clearCallingIdentity(); 14003 try { 14004 boolean doNext = false; 14005 BroadcastRecord r; 14006 14007 synchronized(this) { 14008 r = broadcastRecordForReceiverLocked(who); 14009 if (r != null) { 14010 doNext = r.queue.finishReceiverLocked(r, resultCode, 14011 resultData, resultExtras, resultAbort, true); 14012 } 14013 } 14014 14015 if (doNext) { 14016 r.queue.processNextBroadcast(false); 14017 } 14018 trimApplications(); 14019 } finally { 14020 Binder.restoreCallingIdentity(origId); 14021 } 14022 } 14023 14024 // ========================================================= 14025 // INSTRUMENTATION 14026 // ========================================================= 14027 14028 public boolean startInstrumentation(ComponentName className, 14029 String profileFile, int flags, Bundle arguments, 14030 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14031 int userId) { 14032 enforceNotIsolatedCaller("startInstrumentation"); 14033 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14034 userId, false, true, "startInstrumentation", null); 14035 // Refuse possible leaked file descriptors 14036 if (arguments != null && arguments.hasFileDescriptors()) { 14037 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14038 } 14039 14040 synchronized(this) { 14041 InstrumentationInfo ii = null; 14042 ApplicationInfo ai = null; 14043 try { 14044 ii = mContext.getPackageManager().getInstrumentationInfo( 14045 className, STOCK_PM_FLAGS); 14046 ai = AppGlobals.getPackageManager().getApplicationInfo( 14047 ii.targetPackage, STOCK_PM_FLAGS, userId); 14048 } catch (PackageManager.NameNotFoundException e) { 14049 } catch (RemoteException e) { 14050 } 14051 if (ii == null) { 14052 reportStartInstrumentationFailure(watcher, className, 14053 "Unable to find instrumentation info for: " + className); 14054 return false; 14055 } 14056 if (ai == null) { 14057 reportStartInstrumentationFailure(watcher, className, 14058 "Unable to find instrumentation target package: " + ii.targetPackage); 14059 return false; 14060 } 14061 14062 int match = mContext.getPackageManager().checkSignatures( 14063 ii.targetPackage, ii.packageName); 14064 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14065 String msg = "Permission Denial: starting instrumentation " 14066 + className + " from pid=" 14067 + Binder.getCallingPid() 14068 + ", uid=" + Binder.getCallingPid() 14069 + " not allowed because package " + ii.packageName 14070 + " does not have a signature matching the target " 14071 + ii.targetPackage; 14072 reportStartInstrumentationFailure(watcher, className, msg); 14073 throw new SecurityException(msg); 14074 } 14075 14076 final long origId = Binder.clearCallingIdentity(); 14077 // Instrumentation can kill and relaunch even persistent processes 14078 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14079 "start instr"); 14080 ProcessRecord app = addAppLocked(ai, false); 14081 app.instrumentationClass = className; 14082 app.instrumentationInfo = ai; 14083 app.instrumentationProfileFile = profileFile; 14084 app.instrumentationArguments = arguments; 14085 app.instrumentationWatcher = watcher; 14086 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14087 app.instrumentationResultClass = className; 14088 Binder.restoreCallingIdentity(origId); 14089 } 14090 14091 return true; 14092 } 14093 14094 /** 14095 * Report errors that occur while attempting to start Instrumentation. Always writes the 14096 * error to the logs, but if somebody is watching, send the report there too. This enables 14097 * the "am" command to report errors with more information. 14098 * 14099 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14100 * @param cn The component name of the instrumentation. 14101 * @param report The error report. 14102 */ 14103 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14104 ComponentName cn, String report) { 14105 Slog.w(TAG, report); 14106 try { 14107 if (watcher != null) { 14108 Bundle results = new Bundle(); 14109 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14110 results.putString("Error", report); 14111 watcher.instrumentationStatus(cn, -1, results); 14112 } 14113 } catch (RemoteException e) { 14114 Slog.w(TAG, e); 14115 } 14116 } 14117 14118 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14119 if (app.instrumentationWatcher != null) { 14120 try { 14121 // NOTE: IInstrumentationWatcher *must* be oneway here 14122 app.instrumentationWatcher.instrumentationFinished( 14123 app.instrumentationClass, 14124 resultCode, 14125 results); 14126 } catch (RemoteException e) { 14127 } 14128 } 14129 if (app.instrumentationUiAutomationConnection != null) { 14130 try { 14131 app.instrumentationUiAutomationConnection.shutdown(); 14132 } catch (RemoteException re) { 14133 /* ignore */ 14134 } 14135 // Only a UiAutomation can set this flag and now that 14136 // it is finished we make sure it is reset to its default. 14137 mUserIsMonkey = false; 14138 } 14139 app.instrumentationWatcher = null; 14140 app.instrumentationUiAutomationConnection = null; 14141 app.instrumentationClass = null; 14142 app.instrumentationInfo = null; 14143 app.instrumentationProfileFile = null; 14144 app.instrumentationArguments = null; 14145 14146 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14147 "finished inst"); 14148 } 14149 14150 public void finishInstrumentation(IApplicationThread target, 14151 int resultCode, Bundle results) { 14152 int userId = UserHandle.getCallingUserId(); 14153 // Refuse possible leaked file descriptors 14154 if (results != null && results.hasFileDescriptors()) { 14155 throw new IllegalArgumentException("File descriptors passed in Intent"); 14156 } 14157 14158 synchronized(this) { 14159 ProcessRecord app = getRecordForAppLocked(target); 14160 if (app == null) { 14161 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14162 return; 14163 } 14164 final long origId = Binder.clearCallingIdentity(); 14165 finishInstrumentationLocked(app, resultCode, results); 14166 Binder.restoreCallingIdentity(origId); 14167 } 14168 } 14169 14170 // ========================================================= 14171 // CONFIGURATION 14172 // ========================================================= 14173 14174 public ConfigurationInfo getDeviceConfigurationInfo() { 14175 ConfigurationInfo config = new ConfigurationInfo(); 14176 synchronized (this) { 14177 config.reqTouchScreen = mConfiguration.touchscreen; 14178 config.reqKeyboardType = mConfiguration.keyboard; 14179 config.reqNavigation = mConfiguration.navigation; 14180 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14181 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14182 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14183 } 14184 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14185 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14186 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14187 } 14188 config.reqGlEsVersion = GL_ES_VERSION; 14189 } 14190 return config; 14191 } 14192 14193 ActivityStack getFocusedStack() { 14194 return mStackSupervisor.getFocusedStack(); 14195 } 14196 14197 public Configuration getConfiguration() { 14198 Configuration ci; 14199 synchronized(this) { 14200 ci = new Configuration(mConfiguration); 14201 } 14202 return ci; 14203 } 14204 14205 public void updatePersistentConfiguration(Configuration values) { 14206 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14207 "updateConfiguration()"); 14208 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14209 "updateConfiguration()"); 14210 if (values == null) { 14211 throw new NullPointerException("Configuration must not be null"); 14212 } 14213 14214 synchronized(this) { 14215 final long origId = Binder.clearCallingIdentity(); 14216 updateConfigurationLocked(values, null, true, false); 14217 Binder.restoreCallingIdentity(origId); 14218 } 14219 } 14220 14221 public void updateConfiguration(Configuration values) { 14222 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14223 "updateConfiguration()"); 14224 14225 synchronized(this) { 14226 if (values == null && mWindowManager != null) { 14227 // sentinel: fetch the current configuration from the window manager 14228 values = mWindowManager.computeNewConfiguration(); 14229 } 14230 14231 if (mWindowManager != null) { 14232 mProcessList.applyDisplaySize(mWindowManager); 14233 } 14234 14235 final long origId = Binder.clearCallingIdentity(); 14236 if (values != null) { 14237 Settings.System.clearConfiguration(values); 14238 } 14239 updateConfigurationLocked(values, null, false, false); 14240 Binder.restoreCallingIdentity(origId); 14241 } 14242 } 14243 14244 /** 14245 * Do either or both things: (1) change the current configuration, and (2) 14246 * make sure the given activity is running with the (now) current 14247 * configuration. Returns true if the activity has been left running, or 14248 * false if <var>starting</var> is being destroyed to match the new 14249 * configuration. 14250 * @param persistent TODO 14251 */ 14252 boolean updateConfigurationLocked(Configuration values, 14253 ActivityRecord starting, boolean persistent, boolean initLocale) { 14254 int changes = 0; 14255 14256 if (values != null) { 14257 Configuration newConfig = new Configuration(mConfiguration); 14258 changes = newConfig.updateFrom(values); 14259 if (changes != 0) { 14260 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14261 Slog.i(TAG, "Updating configuration to: " + values); 14262 } 14263 14264 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14265 14266 if (values.locale != null && !initLocale) { 14267 saveLocaleLocked(values.locale, 14268 !values.locale.equals(mConfiguration.locale), 14269 values.userSetLocale); 14270 } 14271 14272 mConfigurationSeq++; 14273 if (mConfigurationSeq <= 0) { 14274 mConfigurationSeq = 1; 14275 } 14276 newConfig.seq = mConfigurationSeq; 14277 mConfiguration = newConfig; 14278 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14279 14280 final Configuration configCopy = new Configuration(mConfiguration); 14281 14282 // TODO: If our config changes, should we auto dismiss any currently 14283 // showing dialogs? 14284 mShowDialogs = shouldShowDialogs(newConfig); 14285 14286 AttributeCache ac = AttributeCache.instance(); 14287 if (ac != null) { 14288 ac.updateConfiguration(configCopy); 14289 } 14290 14291 // Make sure all resources in our process are updated 14292 // right now, so that anyone who is going to retrieve 14293 // resource values after we return will be sure to get 14294 // the new ones. This is especially important during 14295 // boot, where the first config change needs to guarantee 14296 // all resources have that config before following boot 14297 // code is executed. 14298 mSystemThread.applyConfigurationToResources(configCopy); 14299 14300 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14301 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14302 msg.obj = new Configuration(configCopy); 14303 mHandler.sendMessage(msg); 14304 } 14305 14306 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14307 ProcessRecord app = mLruProcesses.get(i); 14308 try { 14309 if (app.thread != null) { 14310 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14311 + app.processName + " new config " + mConfiguration); 14312 app.thread.scheduleConfigurationChanged(configCopy); 14313 } 14314 } catch (Exception e) { 14315 } 14316 } 14317 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14318 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14319 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14320 | Intent.FLAG_RECEIVER_FOREGROUND); 14321 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14322 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14323 Process.SYSTEM_UID, UserHandle.USER_ALL); 14324 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14325 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14326 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14327 broadcastIntentLocked(null, null, intent, 14328 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14329 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14330 } 14331 } 14332 } 14333 14334 boolean kept = true; 14335 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14336 // mainStack is null during startup. 14337 if (mainStack != null) { 14338 if (changes != 0 && starting == null) { 14339 // If the configuration changed, and the caller is not already 14340 // in the process of starting an activity, then find the top 14341 // activity to check if its configuration needs to change. 14342 starting = mainStack.topRunningActivityLocked(null); 14343 } 14344 14345 if (starting != null) { 14346 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14347 // And we need to make sure at this point that all other activities 14348 // are made visible with the correct configuration. 14349 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14350 } 14351 } 14352 14353 if (values != null && mWindowManager != null) { 14354 mWindowManager.setNewConfiguration(mConfiguration); 14355 } 14356 14357 return kept; 14358 } 14359 14360 /** 14361 * Decide based on the configuration whether we should shouw the ANR, 14362 * crash, etc dialogs. The idea is that if there is no affordnace to 14363 * press the on-screen buttons, we shouldn't show the dialog. 14364 * 14365 * A thought: SystemUI might also want to get told about this, the Power 14366 * dialog / global actions also might want different behaviors. 14367 */ 14368 private static final boolean shouldShowDialogs(Configuration config) { 14369 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14370 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14371 } 14372 14373 /** 14374 * Save the locale. You must be inside a synchronized (this) block. 14375 */ 14376 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14377 if(isDiff) { 14378 SystemProperties.set("user.language", l.getLanguage()); 14379 SystemProperties.set("user.region", l.getCountry()); 14380 } 14381 14382 if(isPersist) { 14383 SystemProperties.set("persist.sys.language", l.getLanguage()); 14384 SystemProperties.set("persist.sys.country", l.getCountry()); 14385 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14386 } 14387 } 14388 14389 @Override 14390 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14391 ActivityRecord srec = ActivityRecord.forToken(token); 14392 return srec != null && srec.task.affinity != null && 14393 srec.task.affinity.equals(destAffinity); 14394 } 14395 14396 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14397 Intent resultData) { 14398 14399 synchronized (this) { 14400 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14401 if (stack != null) { 14402 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14403 } 14404 return false; 14405 } 14406 } 14407 14408 public int getLaunchedFromUid(IBinder activityToken) { 14409 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14410 if (srec == null) { 14411 return -1; 14412 } 14413 return srec.launchedFromUid; 14414 } 14415 14416 public String getLaunchedFromPackage(IBinder activityToken) { 14417 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14418 if (srec == null) { 14419 return null; 14420 } 14421 return srec.launchedFromPackage; 14422 } 14423 14424 // ========================================================= 14425 // LIFETIME MANAGEMENT 14426 // ========================================================= 14427 14428 // Returns which broadcast queue the app is the current [or imminent] receiver 14429 // on, or 'null' if the app is not an active broadcast recipient. 14430 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14431 BroadcastRecord r = app.curReceiver; 14432 if (r != null) { 14433 return r.queue; 14434 } 14435 14436 // It's not the current receiver, but it might be starting up to become one 14437 synchronized (this) { 14438 for (BroadcastQueue queue : mBroadcastQueues) { 14439 r = queue.mPendingBroadcast; 14440 if (r != null && r.curApp == app) { 14441 // found it; report which queue it's in 14442 return queue; 14443 } 14444 } 14445 } 14446 14447 return null; 14448 } 14449 14450 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14451 boolean doingAll, long now) { 14452 if (mAdjSeq == app.adjSeq) { 14453 // This adjustment has already been computed. 14454 return app.curRawAdj; 14455 } 14456 14457 if (app.thread == null) { 14458 app.adjSeq = mAdjSeq; 14459 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14460 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14461 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14462 } 14463 14464 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14465 app.adjSource = null; 14466 app.adjTarget = null; 14467 app.empty = false; 14468 app.cached = false; 14469 14470 final int activitiesSize = app.activities.size(); 14471 14472 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14473 // The max adjustment doesn't allow this app to be anything 14474 // below foreground, so it is not worth doing work for it. 14475 app.adjType = "fixed"; 14476 app.adjSeq = mAdjSeq; 14477 app.curRawAdj = app.maxAdj; 14478 app.foregroundActivities = false; 14479 app.keeping = true; 14480 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14481 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14482 // System process can do UI, and when they do we want to have 14483 // them trim their memory after the user leaves the UI. To 14484 // facilitate this, here we need to determine whether or not it 14485 // is currently showing UI. 14486 app.systemNoUi = true; 14487 if (app == TOP_APP) { 14488 app.systemNoUi = false; 14489 } else if (activitiesSize > 0) { 14490 for (int j = 0; j < activitiesSize; j++) { 14491 final ActivityRecord r = app.activities.get(j); 14492 if (r.visible) { 14493 app.systemNoUi = false; 14494 } 14495 } 14496 } 14497 if (!app.systemNoUi) { 14498 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14499 } 14500 return (app.curAdj=app.maxAdj); 14501 } 14502 14503 app.keeping = false; 14504 app.systemNoUi = false; 14505 14506 // Determine the importance of the process, starting with most 14507 // important to least, and assign an appropriate OOM adjustment. 14508 int adj; 14509 int schedGroup; 14510 int procState; 14511 boolean foregroundActivities = false; 14512 boolean interesting = false; 14513 BroadcastQueue queue; 14514 if (app == TOP_APP) { 14515 // The last app on the list is the foreground app. 14516 adj = ProcessList.FOREGROUND_APP_ADJ; 14517 schedGroup = Process.THREAD_GROUP_DEFAULT; 14518 app.adjType = "top-activity"; 14519 foregroundActivities = true; 14520 interesting = true; 14521 procState = ActivityManager.PROCESS_STATE_TOP; 14522 } else if (app.instrumentationClass != null) { 14523 // Don't want to kill running instrumentation. 14524 adj = ProcessList.FOREGROUND_APP_ADJ; 14525 schedGroup = Process.THREAD_GROUP_DEFAULT; 14526 app.adjType = "instrumentation"; 14527 interesting = true; 14528 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14529 } else if ((queue = isReceivingBroadcast(app)) != null) { 14530 // An app that is currently receiving a broadcast also 14531 // counts as being in the foreground for OOM killer purposes. 14532 // It's placed in a sched group based on the nature of the 14533 // broadcast as reflected by which queue it's active in. 14534 adj = ProcessList.FOREGROUND_APP_ADJ; 14535 schedGroup = (queue == mFgBroadcastQueue) 14536 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14537 app.adjType = "broadcast"; 14538 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14539 } else if (app.executingServices.size() > 0) { 14540 // An app that is currently executing a service callback also 14541 // counts as being in the foreground. 14542 adj = ProcessList.FOREGROUND_APP_ADJ; 14543 schedGroup = app.execServicesFg ? 14544 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14545 app.adjType = "exec-service"; 14546 procState = ActivityManager.PROCESS_STATE_SERVICE; 14547 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14548 } else { 14549 // As far as we know the process is empty. We may change our mind later. 14550 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14551 // At this point we don't actually know the adjustment. Use the cached adj 14552 // value that the caller wants us to. 14553 adj = cachedAdj; 14554 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14555 app.cached = true; 14556 app.empty = true; 14557 app.adjType = "cch-empty"; 14558 } 14559 14560 // Examine all activities if not already foreground. 14561 if (!foregroundActivities && activitiesSize > 0) { 14562 for (int j = 0; j < activitiesSize; j++) { 14563 final ActivityRecord r = app.activities.get(j); 14564 if (r.app != app) { 14565 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14566 + app + "?!?"); 14567 continue; 14568 } 14569 if (r.visible) { 14570 // App has a visible activity; only upgrade adjustment. 14571 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14572 adj = ProcessList.VISIBLE_APP_ADJ; 14573 app.adjType = "visible"; 14574 } 14575 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14576 procState = ActivityManager.PROCESS_STATE_TOP; 14577 } 14578 schedGroup = Process.THREAD_GROUP_DEFAULT; 14579 app.cached = false; 14580 app.empty = false; 14581 foregroundActivities = true; 14582 break; 14583 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14584 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14585 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14586 app.adjType = "pausing"; 14587 } 14588 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14589 procState = ActivityManager.PROCESS_STATE_TOP; 14590 } 14591 schedGroup = Process.THREAD_GROUP_DEFAULT; 14592 app.cached = false; 14593 app.empty = false; 14594 foregroundActivities = true; 14595 } else if (r.state == ActivityState.STOPPING) { 14596 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14597 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14598 app.adjType = "stopping"; 14599 } 14600 // For the process state, we will at this point consider the 14601 // process to be cached. It will be cached either as an activity 14602 // or empty depending on whether the activity is finishing. We do 14603 // this so that we can treat the process as cached for purposes of 14604 // memory trimming (determing current memory level, trim command to 14605 // send to process) since there can be an arbitrary number of stopping 14606 // processes and they should soon all go into the cached state. 14607 if (!r.finishing) { 14608 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14609 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14610 } 14611 } 14612 app.cached = false; 14613 app.empty = false; 14614 foregroundActivities = true; 14615 } else { 14616 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14617 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14618 app.adjType = "cch-act"; 14619 } 14620 } 14621 } 14622 } 14623 14624 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14625 if (app.foregroundServices) { 14626 // The user is aware of this app, so make it visible. 14627 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14628 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14629 app.cached = false; 14630 app.adjType = "fg-service"; 14631 schedGroup = Process.THREAD_GROUP_DEFAULT; 14632 } else if (app.forcingToForeground != null) { 14633 // The user is aware of this app, so make it visible. 14634 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14635 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14636 app.cached = false; 14637 app.adjType = "force-fg"; 14638 app.adjSource = app.forcingToForeground; 14639 schedGroup = Process.THREAD_GROUP_DEFAULT; 14640 } 14641 } 14642 14643 if (app.foregroundServices) { 14644 interesting = true; 14645 } 14646 14647 if (app == mHeavyWeightProcess) { 14648 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14649 // We don't want to kill the current heavy-weight process. 14650 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14651 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14652 app.cached = false; 14653 app.adjType = "heavy"; 14654 } 14655 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14656 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14657 } 14658 } 14659 14660 if (app == mHomeProcess) { 14661 if (adj > ProcessList.HOME_APP_ADJ) { 14662 // This process is hosting what we currently consider to be the 14663 // home app, so we don't want to let it go into the background. 14664 adj = ProcessList.HOME_APP_ADJ; 14665 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14666 app.cached = false; 14667 app.adjType = "home"; 14668 } 14669 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14670 procState = ActivityManager.PROCESS_STATE_HOME; 14671 } 14672 } 14673 14674 if (app == mPreviousProcess && app.activities.size() > 0) { 14675 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14676 // This was the previous process that showed UI to the user. 14677 // We want to try to keep it around more aggressively, to give 14678 // a good experience around switching between two apps. 14679 adj = ProcessList.PREVIOUS_APP_ADJ; 14680 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14681 app.cached = false; 14682 app.adjType = "previous"; 14683 } 14684 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14685 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14686 } 14687 } 14688 14689 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14690 + " reason=" + app.adjType); 14691 14692 // By default, we use the computed adjustment. It may be changed if 14693 // there are applications dependent on our services or providers, but 14694 // this gives us a baseline and makes sure we don't get into an 14695 // infinite recursion. 14696 app.adjSeq = mAdjSeq; 14697 app.curRawAdj = adj; 14698 app.hasStartedServices = false; 14699 14700 if (mBackupTarget != null && app == mBackupTarget.app) { 14701 // If possible we want to avoid killing apps while they're being backed up 14702 if (adj > ProcessList.BACKUP_APP_ADJ) { 14703 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14704 adj = ProcessList.BACKUP_APP_ADJ; 14705 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14706 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14707 } 14708 app.adjType = "backup"; 14709 app.cached = false; 14710 } 14711 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14712 procState = ActivityManager.PROCESS_STATE_BACKUP; 14713 } 14714 } 14715 14716 boolean mayBeTop = false; 14717 14718 for (int is = app.services.size()-1; 14719 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14720 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14721 || procState > ActivityManager.PROCESS_STATE_TOP); 14722 is--) { 14723 ServiceRecord s = app.services.valueAt(is); 14724 if (s.startRequested) { 14725 app.hasStartedServices = true; 14726 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14727 procState = ActivityManager.PROCESS_STATE_SERVICE; 14728 } 14729 if (app.hasShownUi && app != mHomeProcess) { 14730 // If this process has shown some UI, let it immediately 14731 // go to the LRU list because it may be pretty heavy with 14732 // UI stuff. We'll tag it with a label just to help 14733 // debug and understand what is going on. 14734 if (adj > ProcessList.SERVICE_ADJ) { 14735 app.adjType = "cch-started-ui-services"; 14736 } 14737 } else { 14738 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14739 // This service has seen some activity within 14740 // recent memory, so we will keep its process ahead 14741 // of the background processes. 14742 if (adj > ProcessList.SERVICE_ADJ) { 14743 adj = ProcessList.SERVICE_ADJ; 14744 app.adjType = "started-services"; 14745 app.cached = false; 14746 } 14747 } 14748 // If we have let the service slide into the background 14749 // state, still have some text describing what it is doing 14750 // even though the service no longer has an impact. 14751 if (adj > ProcessList.SERVICE_ADJ) { 14752 app.adjType = "cch-started-services"; 14753 } 14754 } 14755 // Don't kill this process because it is doing work; it 14756 // has said it is doing work. 14757 app.keeping = true; 14758 } 14759 for (int conni = s.connections.size()-1; 14760 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14761 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14762 || procState > ActivityManager.PROCESS_STATE_TOP); 14763 conni--) { 14764 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14765 for (int i = 0; 14766 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14767 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14768 || procState > ActivityManager.PROCESS_STATE_TOP); 14769 i++) { 14770 // XXX should compute this based on the max of 14771 // all connected clients. 14772 ConnectionRecord cr = clist.get(i); 14773 if (cr.binding.client == app) { 14774 // Binding to ourself is not interesting. 14775 continue; 14776 } 14777 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14778 ProcessRecord client = cr.binding.client; 14779 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14780 TOP_APP, doingAll, now); 14781 int clientProcState = client.curProcState; 14782 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14783 // If the other app is cached for any reason, for purposes here 14784 // we are going to consider it empty. The specific cached state 14785 // doesn't propagate except under certain conditions. 14786 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14787 } 14788 String adjType = null; 14789 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14790 // Not doing bind OOM management, so treat 14791 // this guy more like a started service. 14792 if (app.hasShownUi && app != mHomeProcess) { 14793 // If this process has shown some UI, let it immediately 14794 // go to the LRU list because it may be pretty heavy with 14795 // UI stuff. We'll tag it with a label just to help 14796 // debug and understand what is going on. 14797 if (adj > clientAdj) { 14798 adjType = "cch-bound-ui-services"; 14799 } 14800 app.cached = false; 14801 clientAdj = adj; 14802 clientProcState = procState; 14803 } else { 14804 if (now >= (s.lastActivity 14805 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14806 // This service has not seen activity within 14807 // recent memory, so allow it to drop to the 14808 // LRU list if there is no other reason to keep 14809 // it around. We'll also tag it with a label just 14810 // to help debug and undertand what is going on. 14811 if (adj > clientAdj) { 14812 adjType = "cch-bound-services"; 14813 } 14814 clientAdj = adj; 14815 } 14816 } 14817 } 14818 if (adj > clientAdj) { 14819 // If this process has recently shown UI, and 14820 // the process that is binding to it is less 14821 // important than being visible, then we don't 14822 // care about the binding as much as we care 14823 // about letting this process get into the LRU 14824 // list to be killed and restarted if needed for 14825 // memory. 14826 if (app.hasShownUi && app != mHomeProcess 14827 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14828 adjType = "cch-bound-ui-services"; 14829 } else { 14830 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14831 |Context.BIND_IMPORTANT)) != 0) { 14832 adj = clientAdj; 14833 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14834 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14835 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14836 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14837 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14838 adj = clientAdj; 14839 } else { 14840 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14841 adj = ProcessList.VISIBLE_APP_ADJ; 14842 } 14843 } 14844 if (!client.cached) { 14845 app.cached = false; 14846 } 14847 if (client.keeping) { 14848 app.keeping = true; 14849 } 14850 adjType = "service"; 14851 } 14852 } 14853 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14854 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14855 schedGroup = Process.THREAD_GROUP_DEFAULT; 14856 } 14857 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14858 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14859 // Special handling of clients who are in the top state. 14860 // We *may* want to consider this process to be in the 14861 // top state as well, but only if there is not another 14862 // reason for it to be running. Being on the top is a 14863 // special state, meaning you are specifically running 14864 // for the current top app. If the process is already 14865 // running in the background for some other reason, it 14866 // is more important to continue considering it to be 14867 // in the background state. 14868 mayBeTop = true; 14869 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14870 } else { 14871 // Special handling for above-top states (persistent 14872 // processes). These should not bring the current process 14873 // into the top state, since they are not on top. Instead 14874 // give them the best state after that. 14875 clientProcState = 14876 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14877 } 14878 } 14879 } else { 14880 if (clientProcState < 14881 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14882 clientProcState = 14883 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14884 } 14885 } 14886 if (procState > clientProcState) { 14887 procState = clientProcState; 14888 } 14889 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14890 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14891 app.pendingUiClean = true; 14892 } 14893 if (adjType != null) { 14894 app.adjType = adjType; 14895 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14896 .REASON_SERVICE_IN_USE; 14897 app.adjSource = cr.binding.client; 14898 app.adjSourceOom = clientAdj; 14899 app.adjTarget = s.name; 14900 } 14901 } 14902 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 14903 app.treatLikeActivity = true; 14904 } 14905 final ActivityRecord a = cr.activity; 14906 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14907 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14908 (a.visible || a.state == ActivityState.RESUMED 14909 || a.state == ActivityState.PAUSING)) { 14910 adj = ProcessList.FOREGROUND_APP_ADJ; 14911 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14912 schedGroup = Process.THREAD_GROUP_DEFAULT; 14913 } 14914 app.cached = false; 14915 app.adjType = "service"; 14916 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14917 .REASON_SERVICE_IN_USE; 14918 app.adjSource = a; 14919 app.adjSourceOom = adj; 14920 app.adjTarget = s.name; 14921 } 14922 } 14923 } 14924 } 14925 } 14926 14927 for (int provi = app.pubProviders.size()-1; 14928 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14929 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14930 || procState > ActivityManager.PROCESS_STATE_TOP); 14931 provi--) { 14932 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14933 for (int i = cpr.connections.size()-1; 14934 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14935 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14936 || procState > ActivityManager.PROCESS_STATE_TOP); 14937 i--) { 14938 ContentProviderConnection conn = cpr.connections.get(i); 14939 ProcessRecord client = conn.client; 14940 if (client == app) { 14941 // Being our own client is not interesting. 14942 continue; 14943 } 14944 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14945 int clientProcState = client.curProcState; 14946 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14947 // If the other app is cached for any reason, for purposes here 14948 // we are going to consider it empty. 14949 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14950 } 14951 if (adj > clientAdj) { 14952 if (app.hasShownUi && app != mHomeProcess 14953 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14954 app.adjType = "cch-ui-provider"; 14955 } else { 14956 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14957 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14958 app.adjType = "provider"; 14959 } 14960 app.cached &= client.cached; 14961 app.keeping |= client.keeping; 14962 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14963 .REASON_PROVIDER_IN_USE; 14964 app.adjSource = client; 14965 app.adjSourceOom = clientAdj; 14966 app.adjTarget = cpr.name; 14967 } 14968 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14969 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14970 // Special handling of clients who are in the top state. 14971 // We *may* want to consider this process to be in the 14972 // top state as well, but only if there is not another 14973 // reason for it to be running. Being on the top is a 14974 // special state, meaning you are specifically running 14975 // for the current top app. If the process is already 14976 // running in the background for some other reason, it 14977 // is more important to continue considering it to be 14978 // in the background state. 14979 mayBeTop = true; 14980 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14981 } else { 14982 // Special handling for above-top states (persistent 14983 // processes). These should not bring the current process 14984 // into the top state, since they are not on top. Instead 14985 // give them the best state after that. 14986 clientProcState = 14987 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14988 } 14989 } 14990 if (procState > clientProcState) { 14991 procState = clientProcState; 14992 } 14993 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14994 schedGroup = Process.THREAD_GROUP_DEFAULT; 14995 } 14996 } 14997 // If the provider has external (non-framework) process 14998 // dependencies, ensure that its adjustment is at least 14999 // FOREGROUND_APP_ADJ. 15000 if (cpr.hasExternalProcessHandles()) { 15001 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15002 adj = ProcessList.FOREGROUND_APP_ADJ; 15003 schedGroup = Process.THREAD_GROUP_DEFAULT; 15004 app.cached = false; 15005 app.keeping = true; 15006 app.adjType = "provider"; 15007 app.adjTarget = cpr.name; 15008 } 15009 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15010 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15011 } 15012 } 15013 } 15014 15015 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15016 // A client of one of our services or providers is in the top state. We 15017 // *may* want to be in the top state, but not if we are already running in 15018 // the background for some other reason. For the decision here, we are going 15019 // to pick out a few specific states that we want to remain in when a client 15020 // is top (states that tend to be longer-term) and otherwise allow it to go 15021 // to the top state. 15022 switch (procState) { 15023 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15024 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15025 case ActivityManager.PROCESS_STATE_SERVICE: 15026 // These all are longer-term states, so pull them up to the top 15027 // of the background states, but not all the way to the top state. 15028 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15029 break; 15030 default: 15031 // Otherwise, top is a better choice, so take it. 15032 procState = ActivityManager.PROCESS_STATE_TOP; 15033 break; 15034 } 15035 } 15036 15037 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15038 if (app.hasClientActivities) { 15039 // This is a cached process, but with client activities. Mark it so. 15040 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15041 app.adjType = "cch-client-act"; 15042 } else if (app.treatLikeActivity) { 15043 // This is a cached process, but somebody wants us to treat it like it has 15044 // an activity, okay! 15045 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15046 app.adjType = "cch-as-act"; 15047 } 15048 } 15049 15050 if (adj == ProcessList.SERVICE_ADJ) { 15051 if (doingAll) { 15052 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15053 mNewNumServiceProcs++; 15054 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15055 if (!app.serviceb) { 15056 // This service isn't far enough down on the LRU list to 15057 // normally be a B service, but if we are low on RAM and it 15058 // is large we want to force it down since we would prefer to 15059 // keep launcher over it. 15060 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15061 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15062 app.serviceHighRam = true; 15063 app.serviceb = true; 15064 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15065 } else { 15066 mNewNumAServiceProcs++; 15067 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15068 } 15069 } else { 15070 app.serviceHighRam = false; 15071 } 15072 } 15073 if (app.serviceb) { 15074 adj = ProcessList.SERVICE_B_ADJ; 15075 } 15076 } 15077 15078 app.curRawAdj = adj; 15079 15080 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15081 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15082 if (adj > app.maxAdj) { 15083 adj = app.maxAdj; 15084 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15085 schedGroup = Process.THREAD_GROUP_DEFAULT; 15086 } 15087 } 15088 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15089 app.keeping = true; 15090 } 15091 15092 // Do final modification to adj. Everything we do between here and applying 15093 // the final setAdj must be done in this function, because we will also use 15094 // it when computing the final cached adj later. Note that we don't need to 15095 // worry about this for max adj above, since max adj will always be used to 15096 // keep it out of the cached vaues. 15097 adj = app.modifyRawOomAdj(adj); 15098 15099 app.curProcState = procState; 15100 15101 int importance = app.memImportance; 15102 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15103 app.curAdj = adj; 15104 app.curSchedGroup = schedGroup; 15105 if (!interesting) { 15106 // For this reporting, if there is not something explicitly 15107 // interesting in this process then we will push it to the 15108 // background importance. 15109 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15110 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15111 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15112 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15113 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15114 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15115 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15116 } else if (adj >= ProcessList.SERVICE_ADJ) { 15117 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15118 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15119 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15120 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15121 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15122 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15123 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15124 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15125 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15126 } else { 15127 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15128 } 15129 } 15130 15131 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15132 if (foregroundActivities != app.foregroundActivities) { 15133 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15134 } 15135 if (changes != 0) { 15136 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15137 app.memImportance = importance; 15138 app.foregroundActivities = foregroundActivities; 15139 int i = mPendingProcessChanges.size()-1; 15140 ProcessChangeItem item = null; 15141 while (i >= 0) { 15142 item = mPendingProcessChanges.get(i); 15143 if (item.pid == app.pid) { 15144 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15145 break; 15146 } 15147 i--; 15148 } 15149 if (i < 0) { 15150 // No existing item in pending changes; need a new one. 15151 final int NA = mAvailProcessChanges.size(); 15152 if (NA > 0) { 15153 item = mAvailProcessChanges.remove(NA-1); 15154 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15155 } else { 15156 item = new ProcessChangeItem(); 15157 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15158 } 15159 item.changes = 0; 15160 item.pid = app.pid; 15161 item.uid = app.info.uid; 15162 if (mPendingProcessChanges.size() == 0) { 15163 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15164 "*** Enqueueing dispatch processes changed!"); 15165 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15166 } 15167 mPendingProcessChanges.add(item); 15168 } 15169 item.changes |= changes; 15170 item.importance = importance; 15171 item.foregroundActivities = foregroundActivities; 15172 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15173 + Integer.toHexString(System.identityHashCode(item)) 15174 + " " + app.toShortString() + ": changes=" + item.changes 15175 + " importance=" + item.importance 15176 + " foreground=" + item.foregroundActivities 15177 + " type=" + app.adjType + " source=" + app.adjSource 15178 + " target=" + app.adjTarget); 15179 } 15180 15181 return app.curRawAdj; 15182 } 15183 15184 /** 15185 * Schedule PSS collection of a process. 15186 */ 15187 void requestPssLocked(ProcessRecord proc, int procState) { 15188 if (mPendingPssProcesses.contains(proc)) { 15189 return; 15190 } 15191 if (mPendingPssProcesses.size() == 0) { 15192 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15193 } 15194 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15195 proc.pssProcState = procState; 15196 mPendingPssProcesses.add(proc); 15197 } 15198 15199 /** 15200 * Schedule PSS collection of all processes. 15201 */ 15202 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15203 if (!always) { 15204 if (now < (mLastFullPssTime + 15205 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15206 return; 15207 } 15208 } 15209 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15210 mLastFullPssTime = now; 15211 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15212 mPendingPssProcesses.clear(); 15213 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15214 ProcessRecord app = mLruProcesses.get(i); 15215 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15216 app.pssProcState = app.setProcState; 15217 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15218 mSleeping, now); 15219 mPendingPssProcesses.add(app); 15220 } 15221 } 15222 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15223 } 15224 15225 /** 15226 * Ask a given process to GC right now. 15227 */ 15228 final void performAppGcLocked(ProcessRecord app) { 15229 try { 15230 app.lastRequestedGc = SystemClock.uptimeMillis(); 15231 if (app.thread != null) { 15232 if (app.reportLowMemory) { 15233 app.reportLowMemory = false; 15234 app.thread.scheduleLowMemory(); 15235 } else { 15236 app.thread.processInBackground(); 15237 } 15238 } 15239 } catch (Exception e) { 15240 // whatever. 15241 } 15242 } 15243 15244 /** 15245 * Returns true if things are idle enough to perform GCs. 15246 */ 15247 private final boolean canGcNowLocked() { 15248 boolean processingBroadcasts = false; 15249 for (BroadcastQueue q : mBroadcastQueues) { 15250 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15251 processingBroadcasts = true; 15252 } 15253 } 15254 return !processingBroadcasts 15255 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15256 } 15257 15258 /** 15259 * Perform GCs on all processes that are waiting for it, but only 15260 * if things are idle. 15261 */ 15262 final void performAppGcsLocked() { 15263 final int N = mProcessesToGc.size(); 15264 if (N <= 0) { 15265 return; 15266 } 15267 if (canGcNowLocked()) { 15268 while (mProcessesToGc.size() > 0) { 15269 ProcessRecord proc = mProcessesToGc.remove(0); 15270 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15271 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15272 <= SystemClock.uptimeMillis()) { 15273 // To avoid spamming the system, we will GC processes one 15274 // at a time, waiting a few seconds between each. 15275 performAppGcLocked(proc); 15276 scheduleAppGcsLocked(); 15277 return; 15278 } else { 15279 // It hasn't been long enough since we last GCed this 15280 // process... put it in the list to wait for its time. 15281 addProcessToGcListLocked(proc); 15282 break; 15283 } 15284 } 15285 } 15286 15287 scheduleAppGcsLocked(); 15288 } 15289 } 15290 15291 /** 15292 * If all looks good, perform GCs on all processes waiting for them. 15293 */ 15294 final void performAppGcsIfAppropriateLocked() { 15295 if (canGcNowLocked()) { 15296 performAppGcsLocked(); 15297 return; 15298 } 15299 // Still not idle, wait some more. 15300 scheduleAppGcsLocked(); 15301 } 15302 15303 /** 15304 * Schedule the execution of all pending app GCs. 15305 */ 15306 final void scheduleAppGcsLocked() { 15307 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15308 15309 if (mProcessesToGc.size() > 0) { 15310 // Schedule a GC for the time to the next process. 15311 ProcessRecord proc = mProcessesToGc.get(0); 15312 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15313 15314 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15315 long now = SystemClock.uptimeMillis(); 15316 if (when < (now+GC_TIMEOUT)) { 15317 when = now + GC_TIMEOUT; 15318 } 15319 mHandler.sendMessageAtTime(msg, when); 15320 } 15321 } 15322 15323 /** 15324 * Add a process to the array of processes waiting to be GCed. Keeps the 15325 * list in sorted order by the last GC time. The process can't already be 15326 * on the list. 15327 */ 15328 final void addProcessToGcListLocked(ProcessRecord proc) { 15329 boolean added = false; 15330 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15331 if (mProcessesToGc.get(i).lastRequestedGc < 15332 proc.lastRequestedGc) { 15333 added = true; 15334 mProcessesToGc.add(i+1, proc); 15335 break; 15336 } 15337 } 15338 if (!added) { 15339 mProcessesToGc.add(0, proc); 15340 } 15341 } 15342 15343 /** 15344 * Set up to ask a process to GC itself. This will either do it 15345 * immediately, or put it on the list of processes to gc the next 15346 * time things are idle. 15347 */ 15348 final void scheduleAppGcLocked(ProcessRecord app) { 15349 long now = SystemClock.uptimeMillis(); 15350 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15351 return; 15352 } 15353 if (!mProcessesToGc.contains(app)) { 15354 addProcessToGcListLocked(app); 15355 scheduleAppGcsLocked(); 15356 } 15357 } 15358 15359 final void checkExcessivePowerUsageLocked(boolean doKills) { 15360 updateCpuStatsNow(); 15361 15362 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15363 boolean doWakeKills = doKills; 15364 boolean doCpuKills = doKills; 15365 if (mLastPowerCheckRealtime == 0) { 15366 doWakeKills = false; 15367 } 15368 if (mLastPowerCheckUptime == 0) { 15369 doCpuKills = false; 15370 } 15371 if (stats.isScreenOn()) { 15372 doWakeKills = false; 15373 } 15374 final long curRealtime = SystemClock.elapsedRealtime(); 15375 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15376 final long curUptime = SystemClock.uptimeMillis(); 15377 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15378 mLastPowerCheckRealtime = curRealtime; 15379 mLastPowerCheckUptime = curUptime; 15380 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15381 doWakeKills = false; 15382 } 15383 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15384 doCpuKills = false; 15385 } 15386 int i = mLruProcesses.size(); 15387 while (i > 0) { 15388 i--; 15389 ProcessRecord app = mLruProcesses.get(i); 15390 if (!app.keeping) { 15391 long wtime; 15392 synchronized (stats) { 15393 wtime = stats.getProcessWakeTime(app.info.uid, 15394 app.pid, curRealtime); 15395 } 15396 long wtimeUsed = wtime - app.lastWakeTime; 15397 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15398 if (DEBUG_POWER) { 15399 StringBuilder sb = new StringBuilder(128); 15400 sb.append("Wake for "); 15401 app.toShortString(sb); 15402 sb.append(": over "); 15403 TimeUtils.formatDuration(realtimeSince, sb); 15404 sb.append(" used "); 15405 TimeUtils.formatDuration(wtimeUsed, sb); 15406 sb.append(" ("); 15407 sb.append((wtimeUsed*100)/realtimeSince); 15408 sb.append("%)"); 15409 Slog.i(TAG, sb.toString()); 15410 sb.setLength(0); 15411 sb.append("CPU for "); 15412 app.toShortString(sb); 15413 sb.append(": over "); 15414 TimeUtils.formatDuration(uptimeSince, sb); 15415 sb.append(" used "); 15416 TimeUtils.formatDuration(cputimeUsed, sb); 15417 sb.append(" ("); 15418 sb.append((cputimeUsed*100)/uptimeSince); 15419 sb.append("%)"); 15420 Slog.i(TAG, sb.toString()); 15421 } 15422 // If a process has held a wake lock for more 15423 // than 50% of the time during this period, 15424 // that sounds bad. Kill! 15425 if (doWakeKills && realtimeSince > 0 15426 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15427 synchronized (stats) { 15428 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15429 realtimeSince, wtimeUsed); 15430 } 15431 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15432 + " during " + realtimeSince); 15433 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15434 } else if (doCpuKills && uptimeSince > 0 15435 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15436 synchronized (stats) { 15437 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15438 uptimeSince, cputimeUsed); 15439 } 15440 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15441 + " during " + uptimeSince); 15442 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15443 } else { 15444 app.lastWakeTime = wtime; 15445 app.lastCpuTime = app.curCpuTime; 15446 } 15447 } 15448 } 15449 } 15450 15451 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15452 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15453 boolean success = true; 15454 15455 if (app.curRawAdj != app.setRawAdj) { 15456 if (wasKeeping && !app.keeping) { 15457 // This app is no longer something we want to keep. Note 15458 // its current wake lock time to later know to kill it if 15459 // it is not behaving well. 15460 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15461 synchronized (stats) { 15462 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15463 app.pid, SystemClock.elapsedRealtime()); 15464 } 15465 app.lastCpuTime = app.curCpuTime; 15466 } 15467 15468 app.setRawAdj = app.curRawAdj; 15469 } 15470 15471 if (app.curAdj != app.setAdj) { 15472 ProcessList.setOomAdj(app.pid, app.curAdj); 15473 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15474 TAG, "Set " + app.pid + " " + app.processName + 15475 " adj " + app.curAdj + ": " + app.adjType); 15476 app.setAdj = app.curAdj; 15477 } 15478 15479 if (app.setSchedGroup != app.curSchedGroup) { 15480 app.setSchedGroup = app.curSchedGroup; 15481 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15482 "Setting process group of " + app.processName 15483 + " to " + app.curSchedGroup); 15484 if (app.waitingToKill != null && 15485 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15486 killUnneededProcessLocked(app, app.waitingToKill); 15487 success = false; 15488 } else { 15489 if (true) { 15490 long oldId = Binder.clearCallingIdentity(); 15491 try { 15492 Process.setProcessGroup(app.pid, app.curSchedGroup); 15493 } catch (Exception e) { 15494 Slog.w(TAG, "Failed setting process group of " + app.pid 15495 + " to " + app.curSchedGroup); 15496 e.printStackTrace(); 15497 } finally { 15498 Binder.restoreCallingIdentity(oldId); 15499 } 15500 } else { 15501 if (app.thread != null) { 15502 try { 15503 app.thread.setSchedulingGroup(app.curSchedGroup); 15504 } catch (RemoteException e) { 15505 } 15506 } 15507 } 15508 Process.setSwappiness(app.pid, 15509 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15510 } 15511 } 15512 if (app.repProcState != app.curProcState) { 15513 app.repProcState = app.curProcState; 15514 if (!reportingProcessState && app.thread != null) { 15515 try { 15516 if (false) { 15517 //RuntimeException h = new RuntimeException("here"); 15518 Slog.i(TAG, "Sending new process state " + app.repProcState 15519 + " to " + app /*, h*/); 15520 } 15521 app.thread.setProcessState(app.repProcState); 15522 } catch (RemoteException e) { 15523 } 15524 } 15525 } 15526 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15527 app.setProcState)) { 15528 app.lastStateTime = now; 15529 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15530 mSleeping, now); 15531 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15532 + ProcessList.makeProcStateString(app.setProcState) + " to " 15533 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15534 + (app.nextPssTime-now) + ": " + app); 15535 } else { 15536 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15537 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15538 requestPssLocked(app, app.setProcState); 15539 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15540 mSleeping, now); 15541 } else if (false && DEBUG_PSS) { 15542 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15543 } 15544 } 15545 if (app.setProcState != app.curProcState) { 15546 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15547 "Proc state change of " + app.processName 15548 + " to " + app.curProcState); 15549 app.setProcState = app.curProcState; 15550 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15551 app.notCachedSinceIdle = false; 15552 } 15553 if (!doingAll) { 15554 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15555 } else { 15556 app.procStateChanged = true; 15557 } 15558 } 15559 return success; 15560 } 15561 15562 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15563 if (proc.thread != null && proc.baseProcessTracker != null) { 15564 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15565 } 15566 } 15567 15568 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15569 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15570 if (app.thread == null) { 15571 return false; 15572 } 15573 15574 final boolean wasKeeping = app.keeping; 15575 15576 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15577 15578 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15579 reportingProcessState, now); 15580 } 15581 15582 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15583 boolean oomAdj) { 15584 if (isForeground != proc.foregroundServices) { 15585 proc.foregroundServices = isForeground; 15586 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15587 proc.info.uid); 15588 if (isForeground) { 15589 if (curProcs == null) { 15590 curProcs = new ArrayList<ProcessRecord>(); 15591 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15592 } 15593 if (!curProcs.contains(proc)) { 15594 curProcs.add(proc); 15595 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15596 proc.info.packageName, proc.info.uid); 15597 } 15598 } else { 15599 if (curProcs != null) { 15600 if (curProcs.remove(proc)) { 15601 mBatteryStatsService.noteEvent( 15602 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15603 proc.info.packageName, proc.info.uid); 15604 if (curProcs.size() <= 0) { 15605 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15606 } 15607 } 15608 } 15609 } 15610 if (oomAdj) { 15611 updateOomAdjLocked(); 15612 } 15613 } 15614 } 15615 15616 private final ActivityRecord resumedAppLocked() { 15617 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15618 String pkg; 15619 int uid; 15620 if (act != null && !act.sleeping) { 15621 pkg = act.packageName; 15622 uid = act.info.applicationInfo.uid; 15623 } else { 15624 pkg = null; 15625 uid = -1; 15626 } 15627 // Has the UID or resumed package name changed? 15628 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15629 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15630 if (mCurResumedPackage != null) { 15631 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15632 mCurResumedPackage, mCurResumedUid); 15633 } 15634 mCurResumedPackage = pkg; 15635 mCurResumedUid = uid; 15636 if (mCurResumedPackage != null) { 15637 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15638 mCurResumedPackage, mCurResumedUid); 15639 } 15640 } 15641 return act; 15642 } 15643 15644 final boolean updateOomAdjLocked(ProcessRecord app) { 15645 return updateOomAdjLocked(app, false); 15646 } 15647 15648 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15649 final ActivityRecord TOP_ACT = resumedAppLocked(); 15650 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15651 final boolean wasCached = app.cached; 15652 15653 mAdjSeq++; 15654 15655 // This is the desired cached adjusment we want to tell it to use. 15656 // If our app is currently cached, we know it, and that is it. Otherwise, 15657 // we don't know it yet, and it needs to now be cached we will then 15658 // need to do a complete oom adj. 15659 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15660 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15661 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15662 SystemClock.uptimeMillis()); 15663 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15664 // Changed to/from cached state, so apps after it in the LRU 15665 // list may also be changed. 15666 updateOomAdjLocked(); 15667 } 15668 return success; 15669 } 15670 15671 final void updateOomAdjLocked() { 15672 final ActivityRecord TOP_ACT = resumedAppLocked(); 15673 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15674 final long now = SystemClock.uptimeMillis(); 15675 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15676 final int N = mLruProcesses.size(); 15677 15678 if (false) { 15679 RuntimeException e = new RuntimeException(); 15680 e.fillInStackTrace(); 15681 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15682 } 15683 15684 mAdjSeq++; 15685 mNewNumServiceProcs = 0; 15686 mNewNumAServiceProcs = 0; 15687 15688 final int emptyProcessLimit; 15689 final int cachedProcessLimit; 15690 if (mProcessLimit <= 0) { 15691 emptyProcessLimit = cachedProcessLimit = 0; 15692 } else if (mProcessLimit == 1) { 15693 emptyProcessLimit = 1; 15694 cachedProcessLimit = 0; 15695 } else { 15696 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15697 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15698 } 15699 15700 // Let's determine how many processes we have running vs. 15701 // how many slots we have for background processes; we may want 15702 // to put multiple processes in a slot of there are enough of 15703 // them. 15704 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15705 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15706 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15707 if (numEmptyProcs > cachedProcessLimit) { 15708 // If there are more empty processes than our limit on cached 15709 // processes, then use the cached process limit for the factor. 15710 // This ensures that the really old empty processes get pushed 15711 // down to the bottom, so if we are running low on memory we will 15712 // have a better chance at keeping around more cached processes 15713 // instead of a gazillion empty processes. 15714 numEmptyProcs = cachedProcessLimit; 15715 } 15716 int emptyFactor = numEmptyProcs/numSlots; 15717 if (emptyFactor < 1) emptyFactor = 1; 15718 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15719 if (cachedFactor < 1) cachedFactor = 1; 15720 int stepCached = 0; 15721 int stepEmpty = 0; 15722 int numCached = 0; 15723 int numEmpty = 0; 15724 int numTrimming = 0; 15725 15726 mNumNonCachedProcs = 0; 15727 mNumCachedHiddenProcs = 0; 15728 15729 // First update the OOM adjustment for each of the 15730 // application processes based on their current state. 15731 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15732 int nextCachedAdj = curCachedAdj+1; 15733 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15734 int nextEmptyAdj = curEmptyAdj+2; 15735 for (int i=N-1; i>=0; i--) { 15736 ProcessRecord app = mLruProcesses.get(i); 15737 if (!app.killedByAm && app.thread != null) { 15738 app.procStateChanged = false; 15739 final boolean wasKeeping = app.keeping; 15740 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15741 15742 // If we haven't yet assigned the final cached adj 15743 // to the process, do that now. 15744 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15745 switch (app.curProcState) { 15746 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15747 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15748 // This process is a cached process holding activities... 15749 // assign it the next cached value for that type, and then 15750 // step that cached level. 15751 app.curRawAdj = curCachedAdj; 15752 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15753 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15754 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15755 + ")"); 15756 if (curCachedAdj != nextCachedAdj) { 15757 stepCached++; 15758 if (stepCached >= cachedFactor) { 15759 stepCached = 0; 15760 curCachedAdj = nextCachedAdj; 15761 nextCachedAdj += 2; 15762 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15763 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15764 } 15765 } 15766 } 15767 break; 15768 default: 15769 // For everything else, assign next empty cached process 15770 // level and bump that up. Note that this means that 15771 // long-running services that have dropped down to the 15772 // cached level will be treated as empty (since their process 15773 // state is still as a service), which is what we want. 15774 app.curRawAdj = curEmptyAdj; 15775 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15776 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15777 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15778 + ")"); 15779 if (curEmptyAdj != nextEmptyAdj) { 15780 stepEmpty++; 15781 if (stepEmpty >= emptyFactor) { 15782 stepEmpty = 0; 15783 curEmptyAdj = nextEmptyAdj; 15784 nextEmptyAdj += 2; 15785 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15786 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15787 } 15788 } 15789 } 15790 break; 15791 } 15792 } 15793 15794 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15795 15796 // Count the number of process types. 15797 switch (app.curProcState) { 15798 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15799 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15800 mNumCachedHiddenProcs++; 15801 numCached++; 15802 if (numCached > cachedProcessLimit) { 15803 killUnneededProcessLocked(app, "cached #" + numCached); 15804 } 15805 break; 15806 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15807 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15808 && app.lastActivityTime < oldTime) { 15809 killUnneededProcessLocked(app, "empty for " 15810 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15811 / 1000) + "s"); 15812 } else { 15813 numEmpty++; 15814 if (numEmpty > emptyProcessLimit) { 15815 killUnneededProcessLocked(app, "empty #" + numEmpty); 15816 } 15817 } 15818 break; 15819 default: 15820 mNumNonCachedProcs++; 15821 break; 15822 } 15823 15824 if (app.isolated && app.services.size() <= 0) { 15825 // If this is an isolated process, and there are no 15826 // services running in it, then the process is no longer 15827 // needed. We agressively kill these because we can by 15828 // definition not re-use the same process again, and it is 15829 // good to avoid having whatever code was running in them 15830 // left sitting around after no longer needed. 15831 killUnneededProcessLocked(app, "isolated not needed"); 15832 } 15833 15834 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15835 && !app.killedByAm) { 15836 numTrimming++; 15837 } 15838 } 15839 } 15840 15841 mNumServiceProcs = mNewNumServiceProcs; 15842 15843 // Now determine the memory trimming level of background processes. 15844 // Unfortunately we need to start at the back of the list to do this 15845 // properly. We only do this if the number of background apps we 15846 // are managing to keep around is less than half the maximum we desire; 15847 // if we are keeping a good number around, we'll let them use whatever 15848 // memory they want. 15849 final int numCachedAndEmpty = numCached + numEmpty; 15850 int memFactor; 15851 if (numCached <= ProcessList.TRIM_CACHED_APPS 15852 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15853 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15854 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15855 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15856 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15857 } else { 15858 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15859 } 15860 } else { 15861 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15862 } 15863 // We always allow the memory level to go up (better). We only allow it to go 15864 // down if we are in a state where that is allowed, *and* the total number of processes 15865 // has gone down since last time. 15866 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15867 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15868 + " last=" + mLastNumProcesses); 15869 if (memFactor > mLastMemoryLevel) { 15870 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15871 memFactor = mLastMemoryLevel; 15872 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15873 } 15874 } 15875 mLastMemoryLevel = memFactor; 15876 mLastNumProcesses = mLruProcesses.size(); 15877 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15878 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15879 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15880 if (mLowRamStartTime == 0) { 15881 mLowRamStartTime = now; 15882 } 15883 int step = 0; 15884 int fgTrimLevel; 15885 switch (memFactor) { 15886 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15887 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15888 break; 15889 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15890 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15891 break; 15892 default: 15893 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15894 break; 15895 } 15896 int factor = numTrimming/3; 15897 int minFactor = 2; 15898 if (mHomeProcess != null) minFactor++; 15899 if (mPreviousProcess != null) minFactor++; 15900 if (factor < minFactor) factor = minFactor; 15901 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15902 for (int i=N-1; i>=0; i--) { 15903 ProcessRecord app = mLruProcesses.get(i); 15904 if (allChanged || app.procStateChanged) { 15905 setProcessTrackerState(app, trackerMemFactor, now); 15906 app.procStateChanged = false; 15907 } 15908 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15909 && !app.killedByAm) { 15910 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15911 try { 15912 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15913 "Trimming memory of " + app.processName 15914 + " to " + curLevel); 15915 app.thread.scheduleTrimMemory(curLevel); 15916 } catch (RemoteException e) { 15917 } 15918 if (false) { 15919 // For now we won't do this; our memory trimming seems 15920 // to be good enough at this point that destroying 15921 // activities causes more harm than good. 15922 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15923 && app != mHomeProcess && app != mPreviousProcess) { 15924 // Need to do this on its own message because the stack may not 15925 // be in a consistent state at this point. 15926 // For these apps we will also finish their activities 15927 // to help them free memory. 15928 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15929 } 15930 } 15931 } 15932 app.trimMemoryLevel = curLevel; 15933 step++; 15934 if (step >= factor) { 15935 step = 0; 15936 switch (curLevel) { 15937 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15938 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15939 break; 15940 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15941 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15942 break; 15943 } 15944 } 15945 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15946 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15947 && app.thread != null) { 15948 try { 15949 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15950 "Trimming memory of heavy-weight " + app.processName 15951 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15952 app.thread.scheduleTrimMemory( 15953 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15954 } catch (RemoteException e) { 15955 } 15956 } 15957 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15958 } else { 15959 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15960 || app.systemNoUi) && app.pendingUiClean) { 15961 // If this application is now in the background and it 15962 // had done UI, then give it the special trim level to 15963 // have it free UI resources. 15964 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15965 if (app.trimMemoryLevel < level && app.thread != null) { 15966 try { 15967 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15968 "Trimming memory of bg-ui " + app.processName 15969 + " to " + level); 15970 app.thread.scheduleTrimMemory(level); 15971 } catch (RemoteException e) { 15972 } 15973 } 15974 app.pendingUiClean = false; 15975 } 15976 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15977 try { 15978 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15979 "Trimming memory of fg " + app.processName 15980 + " to " + fgTrimLevel); 15981 app.thread.scheduleTrimMemory(fgTrimLevel); 15982 } catch (RemoteException e) { 15983 } 15984 } 15985 app.trimMemoryLevel = fgTrimLevel; 15986 } 15987 } 15988 } else { 15989 if (mLowRamStartTime != 0) { 15990 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15991 mLowRamStartTime = 0; 15992 } 15993 for (int i=N-1; i>=0; i--) { 15994 ProcessRecord app = mLruProcesses.get(i); 15995 if (allChanged || app.procStateChanged) { 15996 setProcessTrackerState(app, trackerMemFactor, now); 15997 app.procStateChanged = false; 15998 } 15999 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16000 || app.systemNoUi) && app.pendingUiClean) { 16001 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16002 && app.thread != null) { 16003 try { 16004 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16005 "Trimming memory of ui hidden " + app.processName 16006 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16007 app.thread.scheduleTrimMemory( 16008 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16009 } catch (RemoteException e) { 16010 } 16011 } 16012 app.pendingUiClean = false; 16013 } 16014 app.trimMemoryLevel = 0; 16015 } 16016 } 16017 16018 if (mAlwaysFinishActivities) { 16019 // Need to do this on its own message because the stack may not 16020 // be in a consistent state at this point. 16021 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16022 } 16023 16024 if (allChanged) { 16025 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16026 } 16027 16028 if (mProcessStats.shouldWriteNowLocked(now)) { 16029 mHandler.post(new Runnable() { 16030 @Override public void run() { 16031 synchronized (ActivityManagerService.this) { 16032 mProcessStats.writeStateAsyncLocked(); 16033 } 16034 } 16035 }); 16036 } 16037 16038 if (DEBUG_OOM_ADJ) { 16039 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16040 } 16041 } 16042 16043 final void trimApplications() { 16044 synchronized (this) { 16045 int i; 16046 16047 // First remove any unused application processes whose package 16048 // has been removed. 16049 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16050 final ProcessRecord app = mRemovedProcesses.get(i); 16051 if (app.activities.size() == 0 16052 && app.curReceiver == null && app.services.size() == 0) { 16053 Slog.i( 16054 TAG, "Exiting empty application process " 16055 + app.processName + " (" 16056 + (app.thread != null ? app.thread.asBinder() : null) 16057 + ")\n"); 16058 if (app.pid > 0 && app.pid != MY_PID) { 16059 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16060 app.processName, app.setAdj, "empty"); 16061 app.killedByAm = true; 16062 Process.killProcessQuiet(app.pid); 16063 } else { 16064 try { 16065 app.thread.scheduleExit(); 16066 } catch (Exception e) { 16067 // Ignore exceptions. 16068 } 16069 } 16070 cleanUpApplicationRecordLocked(app, false, true, -1); 16071 mRemovedProcesses.remove(i); 16072 16073 if (app.persistent) { 16074 if (app.persistent) { 16075 addAppLocked(app.info, false); 16076 } 16077 } 16078 } 16079 } 16080 16081 // Now update the oom adj for all processes. 16082 updateOomAdjLocked(); 16083 } 16084 } 16085 16086 /** This method sends the specified signal to each of the persistent apps */ 16087 public void signalPersistentProcesses(int sig) throws RemoteException { 16088 if (sig != Process.SIGNAL_USR1) { 16089 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16090 } 16091 16092 synchronized (this) { 16093 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16094 != PackageManager.PERMISSION_GRANTED) { 16095 throw new SecurityException("Requires permission " 16096 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16097 } 16098 16099 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16100 ProcessRecord r = mLruProcesses.get(i); 16101 if (r.thread != null && r.persistent) { 16102 Process.sendSignal(r.pid, sig); 16103 } 16104 } 16105 } 16106 } 16107 16108 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16109 if (proc == null || proc == mProfileProc) { 16110 proc = mProfileProc; 16111 path = mProfileFile; 16112 profileType = mProfileType; 16113 clearProfilerLocked(); 16114 } 16115 if (proc == null) { 16116 return; 16117 } 16118 try { 16119 proc.thread.profilerControl(false, path, null, profileType); 16120 } catch (RemoteException e) { 16121 throw new IllegalStateException("Process disappeared"); 16122 } 16123 } 16124 16125 private void clearProfilerLocked() { 16126 if (mProfileFd != null) { 16127 try { 16128 mProfileFd.close(); 16129 } catch (IOException e) { 16130 } 16131 } 16132 mProfileApp = null; 16133 mProfileProc = null; 16134 mProfileFile = null; 16135 mProfileType = 0; 16136 mAutoStopProfiler = false; 16137 } 16138 16139 public boolean profileControl(String process, int userId, boolean start, 16140 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16141 16142 try { 16143 synchronized (this) { 16144 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16145 // its own permission. 16146 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16147 != PackageManager.PERMISSION_GRANTED) { 16148 throw new SecurityException("Requires permission " 16149 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16150 } 16151 16152 if (start && fd == null) { 16153 throw new IllegalArgumentException("null fd"); 16154 } 16155 16156 ProcessRecord proc = null; 16157 if (process != null) { 16158 proc = findProcessLocked(process, userId, "profileControl"); 16159 } 16160 16161 if (start && (proc == null || proc.thread == null)) { 16162 throw new IllegalArgumentException("Unknown process: " + process); 16163 } 16164 16165 if (start) { 16166 stopProfilerLocked(null, null, 0); 16167 setProfileApp(proc.info, proc.processName, path, fd, false); 16168 mProfileProc = proc; 16169 mProfileType = profileType; 16170 try { 16171 fd = fd.dup(); 16172 } catch (IOException e) { 16173 fd = null; 16174 } 16175 proc.thread.profilerControl(start, path, fd, profileType); 16176 fd = null; 16177 mProfileFd = null; 16178 } else { 16179 stopProfilerLocked(proc, path, profileType); 16180 if (fd != null) { 16181 try { 16182 fd.close(); 16183 } catch (IOException e) { 16184 } 16185 } 16186 } 16187 16188 return true; 16189 } 16190 } catch (RemoteException e) { 16191 throw new IllegalStateException("Process disappeared"); 16192 } finally { 16193 if (fd != null) { 16194 try { 16195 fd.close(); 16196 } catch (IOException e) { 16197 } 16198 } 16199 } 16200 } 16201 16202 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16203 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16204 userId, true, true, callName, null); 16205 ProcessRecord proc = null; 16206 try { 16207 int pid = Integer.parseInt(process); 16208 synchronized (mPidsSelfLocked) { 16209 proc = mPidsSelfLocked.get(pid); 16210 } 16211 } catch (NumberFormatException e) { 16212 } 16213 16214 if (proc == null) { 16215 ArrayMap<String, SparseArray<ProcessRecord>> all 16216 = mProcessNames.getMap(); 16217 SparseArray<ProcessRecord> procs = all.get(process); 16218 if (procs != null && procs.size() > 0) { 16219 proc = procs.valueAt(0); 16220 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16221 for (int i=1; i<procs.size(); i++) { 16222 ProcessRecord thisProc = procs.valueAt(i); 16223 if (thisProc.userId == userId) { 16224 proc = thisProc; 16225 break; 16226 } 16227 } 16228 } 16229 } 16230 } 16231 16232 return proc; 16233 } 16234 16235 public boolean dumpHeap(String process, int userId, boolean managed, 16236 String path, ParcelFileDescriptor fd) throws RemoteException { 16237 16238 try { 16239 synchronized (this) { 16240 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16241 // its own permission (same as profileControl). 16242 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16243 != PackageManager.PERMISSION_GRANTED) { 16244 throw new SecurityException("Requires permission " 16245 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16246 } 16247 16248 if (fd == null) { 16249 throw new IllegalArgumentException("null fd"); 16250 } 16251 16252 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16253 if (proc == null || proc.thread == null) { 16254 throw new IllegalArgumentException("Unknown process: " + process); 16255 } 16256 16257 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16258 if (!isDebuggable) { 16259 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16260 throw new SecurityException("Process not debuggable: " + proc); 16261 } 16262 } 16263 16264 proc.thread.dumpHeap(managed, path, fd); 16265 fd = null; 16266 return true; 16267 } 16268 } catch (RemoteException e) { 16269 throw new IllegalStateException("Process disappeared"); 16270 } finally { 16271 if (fd != null) { 16272 try { 16273 fd.close(); 16274 } catch (IOException e) { 16275 } 16276 } 16277 } 16278 } 16279 16280 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16281 public void monitor() { 16282 synchronized (this) { } 16283 } 16284 16285 void onCoreSettingsChange(Bundle settings) { 16286 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16287 ProcessRecord processRecord = mLruProcesses.get(i); 16288 try { 16289 if (processRecord.thread != null) { 16290 processRecord.thread.setCoreSettings(settings); 16291 } 16292 } catch (RemoteException re) { 16293 /* ignore */ 16294 } 16295 } 16296 } 16297 16298 // Multi-user methods 16299 16300 /** 16301 * Start user, if its not already running, but don't bring it to foreground. 16302 */ 16303 @Override 16304 public boolean startUserInBackground(final int userId) { 16305 return startUser(userId, /* foreground */ false); 16306 } 16307 16308 /** 16309 * Refreshes the list of users related to the current user when either a 16310 * user switch happens or when a new related user is started in the 16311 * background. 16312 */ 16313 private void updateCurrentProfileIdsLocked() { 16314 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId); 16315 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16316 for (int i = 0; i < currentProfileIds.length; i++) { 16317 currentProfileIds[i] = profiles.get(i).id; 16318 } 16319 mCurrentProfileIds = currentProfileIds; 16320 } 16321 16322 private Set getProfileIdsLocked(int userId) { 16323 Set userIds = new HashSet<Integer>(); 16324 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(userId); 16325 for (UserInfo user : profiles) { 16326 userIds.add(Integer.valueOf(user.id)); 16327 } 16328 return userIds; 16329 } 16330 16331 @Override 16332 public boolean switchUser(final int userId) { 16333 return startUser(userId, /* foregound */ true); 16334 } 16335 16336 private boolean startUser(final int userId, boolean foreground) { 16337 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16338 != PackageManager.PERMISSION_GRANTED) { 16339 String msg = "Permission Denial: switchUser() from pid=" 16340 + Binder.getCallingPid() 16341 + ", uid=" + Binder.getCallingUid() 16342 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16343 Slog.w(TAG, msg); 16344 throw new SecurityException(msg); 16345 } 16346 16347 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16348 16349 final long ident = Binder.clearCallingIdentity(); 16350 try { 16351 synchronized (this) { 16352 final int oldUserId = mCurrentUserId; 16353 if (oldUserId == userId) { 16354 return true; 16355 } 16356 16357 mStackSupervisor.setLockTaskModeLocked(null); 16358 16359 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16360 if (userInfo == null) { 16361 Slog.w(TAG, "No user info for user #" + userId); 16362 return false; 16363 } 16364 16365 if (foreground) { 16366 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16367 R.anim.screen_user_enter); 16368 } 16369 16370 boolean needStart = false; 16371 16372 // If the user we are switching to is not currently started, then 16373 // we need to start it now. 16374 if (mStartedUsers.get(userId) == null) { 16375 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16376 updateStartedUserArrayLocked(); 16377 needStart = true; 16378 } 16379 16380 final Integer userIdInt = Integer.valueOf(userId); 16381 mUserLru.remove(userIdInt); 16382 mUserLru.add(userIdInt); 16383 16384 if (foreground) { 16385 mCurrentUserId = userId; 16386 updateCurrentProfileIdsLocked(); 16387 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16388 // Once the internal notion of the active user has switched, we lock the device 16389 // with the option to show the user switcher on the keyguard. 16390 mWindowManager.lockNow(null); 16391 } else { 16392 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16393 updateCurrentProfileIdsLocked(); 16394 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16395 mUserLru.remove(currentUserIdInt); 16396 mUserLru.add(currentUserIdInt); 16397 } 16398 16399 final UserStartedState uss = mStartedUsers.get(userId); 16400 16401 // Make sure user is in the started state. If it is currently 16402 // stopping, we need to knock that off. 16403 if (uss.mState == UserStartedState.STATE_STOPPING) { 16404 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16405 // so we can just fairly silently bring the user back from 16406 // the almost-dead. 16407 uss.mState = UserStartedState.STATE_RUNNING; 16408 updateStartedUserArrayLocked(); 16409 needStart = true; 16410 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16411 // This means ACTION_SHUTDOWN has been sent, so we will 16412 // need to treat this as a new boot of the user. 16413 uss.mState = UserStartedState.STATE_BOOTING; 16414 updateStartedUserArrayLocked(); 16415 needStart = true; 16416 } 16417 16418 if (foreground) { 16419 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16420 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16421 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16422 oldUserId, userId, uss)); 16423 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16424 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16425 } 16426 16427 if (needStart) { 16428 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16429 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16430 | Intent.FLAG_RECEIVER_FOREGROUND); 16431 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16432 broadcastIntentLocked(null, null, intent, 16433 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16434 false, false, MY_PID, Process.SYSTEM_UID, userId); 16435 } 16436 16437 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16438 if (userId != 0) { 16439 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16440 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16441 broadcastIntentLocked(null, null, intent, null, 16442 new IIntentReceiver.Stub() { 16443 public void performReceive(Intent intent, int resultCode, 16444 String data, Bundle extras, boolean ordered, 16445 boolean sticky, int sendingUser) { 16446 userInitialized(uss, userId); 16447 } 16448 }, 0, null, null, null, AppOpsManager.OP_NONE, 16449 true, false, MY_PID, Process.SYSTEM_UID, 16450 userId); 16451 uss.initializing = true; 16452 } else { 16453 getUserManagerLocked().makeInitialized(userInfo.id); 16454 } 16455 } 16456 16457 if (foreground) { 16458 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16459 if (homeInFront) { 16460 startHomeActivityLocked(userId); 16461 } else { 16462 mStackSupervisor.resumeTopActivitiesLocked(); 16463 } 16464 EventLogTags.writeAmSwitchUser(userId); 16465 getUserManagerLocked().userForeground(userId); 16466 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16467 } 16468 16469 if (needStart) { 16470 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16471 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16472 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16473 broadcastIntentLocked(null, null, intent, 16474 null, new IIntentReceiver.Stub() { 16475 @Override 16476 public void performReceive(Intent intent, int resultCode, String data, 16477 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16478 throws RemoteException { 16479 } 16480 }, 0, null, null, 16481 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16482 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16483 } 16484 } 16485 } finally { 16486 Binder.restoreCallingIdentity(ident); 16487 } 16488 16489 return true; 16490 } 16491 16492 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16493 long ident = Binder.clearCallingIdentity(); 16494 try { 16495 Intent intent; 16496 if (oldUserId >= 0) { 16497 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16498 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16499 | Intent.FLAG_RECEIVER_FOREGROUND); 16500 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16501 broadcastIntentLocked(null, null, intent, 16502 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16503 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16504 } 16505 if (newUserId >= 0) { 16506 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16507 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16508 | Intent.FLAG_RECEIVER_FOREGROUND); 16509 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16510 broadcastIntentLocked(null, null, intent, 16511 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16512 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16513 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16514 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16515 | Intent.FLAG_RECEIVER_FOREGROUND); 16516 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16517 broadcastIntentLocked(null, null, intent, 16518 null, null, 0, null, null, 16519 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16520 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16521 } 16522 } finally { 16523 Binder.restoreCallingIdentity(ident); 16524 } 16525 } 16526 16527 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16528 final int newUserId) { 16529 final int N = mUserSwitchObservers.beginBroadcast(); 16530 if (N > 0) { 16531 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16532 int mCount = 0; 16533 @Override 16534 public void sendResult(Bundle data) throws RemoteException { 16535 synchronized (ActivityManagerService.this) { 16536 if (mCurUserSwitchCallback == this) { 16537 mCount++; 16538 if (mCount == N) { 16539 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16540 } 16541 } 16542 } 16543 } 16544 }; 16545 synchronized (this) { 16546 uss.switching = true; 16547 mCurUserSwitchCallback = callback; 16548 } 16549 for (int i=0; i<N; i++) { 16550 try { 16551 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16552 newUserId, callback); 16553 } catch (RemoteException e) { 16554 } 16555 } 16556 } else { 16557 synchronized (this) { 16558 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16559 } 16560 } 16561 mUserSwitchObservers.finishBroadcast(); 16562 } 16563 16564 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16565 synchronized (this) { 16566 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16567 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16568 } 16569 } 16570 16571 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16572 mCurUserSwitchCallback = null; 16573 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16574 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16575 oldUserId, newUserId, uss)); 16576 } 16577 16578 void userInitialized(UserStartedState uss, int newUserId) { 16579 completeSwitchAndInitalize(uss, newUserId, true, false); 16580 } 16581 16582 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16583 completeSwitchAndInitalize(uss, newUserId, false, true); 16584 } 16585 16586 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16587 boolean clearInitializing, boolean clearSwitching) { 16588 boolean unfrozen = false; 16589 synchronized (this) { 16590 if (clearInitializing) { 16591 uss.initializing = false; 16592 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16593 } 16594 if (clearSwitching) { 16595 uss.switching = false; 16596 } 16597 if (!uss.switching && !uss.initializing) { 16598 mWindowManager.stopFreezingScreen(); 16599 unfrozen = true; 16600 } 16601 } 16602 if (unfrozen) { 16603 final int N = mUserSwitchObservers.beginBroadcast(); 16604 for (int i=0; i<N; i++) { 16605 try { 16606 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16607 } catch (RemoteException e) { 16608 } 16609 } 16610 mUserSwitchObservers.finishBroadcast(); 16611 } 16612 } 16613 16614 void scheduleStartProfilesLocked() { 16615 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16616 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16617 DateUtils.SECOND_IN_MILLIS); 16618 } 16619 } 16620 16621 void startProfilesLocked() { 16622 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16623 List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId); 16624 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16625 for (UserInfo user : profiles) { 16626 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16627 && user.id != mCurrentUserId) { 16628 toStart.add(user); 16629 } 16630 } 16631 final int n = toStart.size(); 16632 int i = 0; 16633 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16634 startUserInBackground(toStart.get(i).id); 16635 } 16636 if (i < n) { 16637 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16638 } 16639 } 16640 16641 void finishUserSwitch(UserStartedState uss) { 16642 synchronized (this) { 16643 if (uss.mState == UserStartedState.STATE_BOOTING 16644 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16645 uss.mState = UserStartedState.STATE_RUNNING; 16646 final int userId = uss.mHandle.getIdentifier(); 16647 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16648 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16649 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16650 broadcastIntentLocked(null, null, intent, 16651 null, null, 0, null, null, 16652 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16653 true, false, MY_PID, Process.SYSTEM_UID, userId); 16654 } 16655 16656 startProfilesLocked(); 16657 16658 int num = mUserLru.size(); 16659 int i = 0; 16660 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16661 Integer oldUserId = mUserLru.get(i); 16662 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16663 if (oldUss == null) { 16664 // Shouldn't happen, but be sane if it does. 16665 mUserLru.remove(i); 16666 num--; 16667 continue; 16668 } 16669 if (oldUss.mState == UserStartedState.STATE_STOPPING 16670 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16671 // This user is already stopping, doesn't count. 16672 num--; 16673 i++; 16674 continue; 16675 } 16676 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16677 // Owner and current can't be stopped, but count as running. 16678 i++; 16679 continue; 16680 } 16681 // This is a user to be stopped. 16682 stopUserLocked(oldUserId, null); 16683 num--; 16684 i++; 16685 } 16686 } 16687 } 16688 16689 @Override 16690 public int stopUser(final int userId, final IStopUserCallback callback) { 16691 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16692 != PackageManager.PERMISSION_GRANTED) { 16693 String msg = "Permission Denial: switchUser() from pid=" 16694 + Binder.getCallingPid() 16695 + ", uid=" + Binder.getCallingUid() 16696 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16697 Slog.w(TAG, msg); 16698 throw new SecurityException(msg); 16699 } 16700 if (userId <= 0) { 16701 throw new IllegalArgumentException("Can't stop primary user " + userId); 16702 } 16703 synchronized (this) { 16704 return stopUserLocked(userId, callback); 16705 } 16706 } 16707 16708 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16709 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16710 if (mCurrentUserId == userId) { 16711 return ActivityManager.USER_OP_IS_CURRENT; 16712 } 16713 16714 final UserStartedState uss = mStartedUsers.get(userId); 16715 if (uss == null) { 16716 // User is not started, nothing to do... but we do need to 16717 // callback if requested. 16718 if (callback != null) { 16719 mHandler.post(new Runnable() { 16720 @Override 16721 public void run() { 16722 try { 16723 callback.userStopped(userId); 16724 } catch (RemoteException e) { 16725 } 16726 } 16727 }); 16728 } 16729 return ActivityManager.USER_OP_SUCCESS; 16730 } 16731 16732 if (callback != null) { 16733 uss.mStopCallbacks.add(callback); 16734 } 16735 16736 if (uss.mState != UserStartedState.STATE_STOPPING 16737 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16738 uss.mState = UserStartedState.STATE_STOPPING; 16739 updateStartedUserArrayLocked(); 16740 16741 long ident = Binder.clearCallingIdentity(); 16742 try { 16743 // We are going to broadcast ACTION_USER_STOPPING and then 16744 // once that is done send a final ACTION_SHUTDOWN and then 16745 // stop the user. 16746 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16747 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16748 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16749 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16750 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16751 // This is the result receiver for the final shutdown broadcast. 16752 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16753 @Override 16754 public void performReceive(Intent intent, int resultCode, String data, 16755 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16756 finishUserStop(uss); 16757 } 16758 }; 16759 // This is the result receiver for the initial stopping broadcast. 16760 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16761 @Override 16762 public void performReceive(Intent intent, int resultCode, String data, 16763 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16764 // On to the next. 16765 synchronized (ActivityManagerService.this) { 16766 if (uss.mState != UserStartedState.STATE_STOPPING) { 16767 // Whoops, we are being started back up. Abort, abort! 16768 return; 16769 } 16770 uss.mState = UserStartedState.STATE_SHUTDOWN; 16771 } 16772 broadcastIntentLocked(null, null, shutdownIntent, 16773 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16774 true, false, MY_PID, Process.SYSTEM_UID, userId); 16775 } 16776 }; 16777 // Kick things off. 16778 broadcastIntentLocked(null, null, stoppingIntent, 16779 null, stoppingReceiver, 0, null, null, 16780 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16781 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16782 } finally { 16783 Binder.restoreCallingIdentity(ident); 16784 } 16785 } 16786 16787 return ActivityManager.USER_OP_SUCCESS; 16788 } 16789 16790 void finishUserStop(UserStartedState uss) { 16791 final int userId = uss.mHandle.getIdentifier(); 16792 boolean stopped; 16793 ArrayList<IStopUserCallback> callbacks; 16794 synchronized (this) { 16795 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16796 if (mStartedUsers.get(userId) != uss) { 16797 stopped = false; 16798 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16799 stopped = false; 16800 } else { 16801 stopped = true; 16802 // User can no longer run. 16803 mStartedUsers.remove(userId); 16804 mUserLru.remove(Integer.valueOf(userId)); 16805 updateStartedUserArrayLocked(); 16806 16807 // Clean up all state and processes associated with the user. 16808 // Kill all the processes for the user. 16809 forceStopUserLocked(userId, "finish user"); 16810 } 16811 } 16812 16813 for (int i=0; i<callbacks.size(); i++) { 16814 try { 16815 if (stopped) callbacks.get(i).userStopped(userId); 16816 else callbacks.get(i).userStopAborted(userId); 16817 } catch (RemoteException e) { 16818 } 16819 } 16820 16821 mStackSupervisor.removeUserLocked(userId); 16822 } 16823 16824 @Override 16825 public UserInfo getCurrentUser() { 16826 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16827 != PackageManager.PERMISSION_GRANTED) && ( 16828 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16829 != PackageManager.PERMISSION_GRANTED)) { 16830 String msg = "Permission Denial: getCurrentUser() from pid=" 16831 + Binder.getCallingPid() 16832 + ", uid=" + Binder.getCallingUid() 16833 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16834 Slog.w(TAG, msg); 16835 throw new SecurityException(msg); 16836 } 16837 synchronized (this) { 16838 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16839 } 16840 } 16841 16842 int getCurrentUserIdLocked() { 16843 return mCurrentUserId; 16844 } 16845 16846 @Override 16847 public boolean isUserRunning(int userId, boolean orStopped) { 16848 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16849 != PackageManager.PERMISSION_GRANTED) { 16850 String msg = "Permission Denial: isUserRunning() from pid=" 16851 + Binder.getCallingPid() 16852 + ", uid=" + Binder.getCallingUid() 16853 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16854 Slog.w(TAG, msg); 16855 throw new SecurityException(msg); 16856 } 16857 synchronized (this) { 16858 return isUserRunningLocked(userId, orStopped); 16859 } 16860 } 16861 16862 boolean isUserRunningLocked(int userId, boolean orStopped) { 16863 UserStartedState state = mStartedUsers.get(userId); 16864 if (state == null) { 16865 return false; 16866 } 16867 if (orStopped) { 16868 return true; 16869 } 16870 return state.mState != UserStartedState.STATE_STOPPING 16871 && state.mState != UserStartedState.STATE_SHUTDOWN; 16872 } 16873 16874 @Override 16875 public int[] getRunningUserIds() { 16876 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16877 != PackageManager.PERMISSION_GRANTED) { 16878 String msg = "Permission Denial: isUserRunning() from pid=" 16879 + Binder.getCallingPid() 16880 + ", uid=" + Binder.getCallingUid() 16881 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16882 Slog.w(TAG, msg); 16883 throw new SecurityException(msg); 16884 } 16885 synchronized (this) { 16886 return mStartedUserArray; 16887 } 16888 } 16889 16890 private void updateStartedUserArrayLocked() { 16891 int num = 0; 16892 for (int i=0; i<mStartedUsers.size(); i++) { 16893 UserStartedState uss = mStartedUsers.valueAt(i); 16894 // This list does not include stopping users. 16895 if (uss.mState != UserStartedState.STATE_STOPPING 16896 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16897 num++; 16898 } 16899 } 16900 mStartedUserArray = new int[num]; 16901 num = 0; 16902 for (int i=0; i<mStartedUsers.size(); i++) { 16903 UserStartedState uss = mStartedUsers.valueAt(i); 16904 if (uss.mState != UserStartedState.STATE_STOPPING 16905 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16906 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16907 num++; 16908 } 16909 } 16910 } 16911 16912 @Override 16913 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16914 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16915 != PackageManager.PERMISSION_GRANTED) { 16916 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16917 + Binder.getCallingPid() 16918 + ", uid=" + Binder.getCallingUid() 16919 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16920 Slog.w(TAG, msg); 16921 throw new SecurityException(msg); 16922 } 16923 16924 mUserSwitchObservers.register(observer); 16925 } 16926 16927 @Override 16928 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16929 mUserSwitchObservers.unregister(observer); 16930 } 16931 16932 private boolean userExists(int userId) { 16933 if (userId == 0) { 16934 return true; 16935 } 16936 UserManagerService ums = getUserManagerLocked(); 16937 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16938 } 16939 16940 int[] getUsersLocked() { 16941 UserManagerService ums = getUserManagerLocked(); 16942 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16943 } 16944 16945 UserManagerService getUserManagerLocked() { 16946 if (mUserManager == null) { 16947 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16948 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16949 } 16950 return mUserManager; 16951 } 16952 16953 private int applyUserId(int uid, int userId) { 16954 return UserHandle.getUid(userId, uid); 16955 } 16956 16957 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16958 if (info == null) return null; 16959 ApplicationInfo newInfo = new ApplicationInfo(info); 16960 newInfo.uid = applyUserId(info.uid, userId); 16961 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16962 + info.packageName; 16963 return newInfo; 16964 } 16965 16966 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16967 if (aInfo == null 16968 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16969 return aInfo; 16970 } 16971 16972 ActivityInfo info = new ActivityInfo(aInfo); 16973 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16974 return info; 16975 } 16976 16977 private final class LocalService extends ActivityManagerInternal { 16978 @Override 16979 public void goingToSleep() { 16980 ActivityManagerService.this.goingToSleep(); 16981 } 16982 16983 @Override 16984 public void wakingUp() { 16985 ActivityManagerService.this.wakingUp(); 16986 } 16987 } 16988} 16989