ActivityManagerService.java revision f4824a06884e096beef921646cba4be29d7f36fc
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30import android.app.AppOpsManager; 31import android.app.IActivityContainer; 32import android.app.IActivityContainerCallback; 33import android.appwidget.AppWidgetManager; 34import android.graphics.Rect; 35import android.os.BatteryStats; 36import android.util.ArrayMap; 37import com.android.internal.R; 38import com.android.internal.annotations.GuardedBy; 39import com.android.internal.app.IAppOpsService; 40import com.android.internal.app.ProcessMap; 41import com.android.internal.app.ProcessStats; 42import com.android.internal.os.BackgroundThread; 43import com.android.internal.os.BatteryStatsImpl; 44import com.android.internal.os.ProcessCpuTracker; 45import com.android.internal.os.TransferPipe; 46import com.android.internal.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.ServiceThread; 55import com.android.server.SystemService; 56import com.android.server.Watchdog; 57import com.android.server.am.ActivityStack.ActivityState; 58import com.android.server.firewall.IntentFirewall; 59import com.android.server.pm.UserManagerService; 60import com.android.server.wm.AppTransition; 61import com.android.server.wm.WindowManagerService; 62import com.google.android.collect.Lists; 63import com.google.android.collect.Maps; 64 65import libcore.io.IoUtils; 66 67import org.xmlpull.v1.XmlPullParser; 68import org.xmlpull.v1.XmlPullParserException; 69import org.xmlpull.v1.XmlSerializer; 70 71import android.app.Activity; 72import android.app.ActivityManager; 73import android.app.ActivityManager.RunningTaskInfo; 74import android.app.ActivityManager.StackInfo; 75import android.app.ActivityManagerNative; 76import android.app.ActivityOptions; 77import android.app.ActivityThread; 78import android.app.AlertDialog; 79import android.app.AppGlobals; 80import android.app.ApplicationErrorReport; 81import android.app.Dialog; 82import android.app.IActivityController; 83import android.app.IApplicationThread; 84import android.app.IInstrumentationWatcher; 85import android.app.INotificationManager; 86import android.app.IProcessObserver; 87import android.app.IServiceConnection; 88import android.app.IStopUserCallback; 89import android.app.IThumbnailReceiver; 90import android.app.IUiAutomationConnection; 91import android.app.IUserSwitchObserver; 92import android.app.Instrumentation; 93import android.app.Notification; 94import android.app.NotificationManager; 95import android.app.PendingIntent; 96import android.app.backup.IBackupManager; 97import android.content.ActivityNotFoundException; 98import android.content.BroadcastReceiver; 99import android.content.ClipData; 100import android.content.ComponentCallbacks2; 101import android.content.ComponentName; 102import android.content.ContentProvider; 103import android.content.ContentResolver; 104import android.content.Context; 105import android.content.DialogInterface; 106import android.content.IContentProvider; 107import android.content.IIntentReceiver; 108import android.content.IIntentSender; 109import android.content.Intent; 110import android.content.IntentFilter; 111import android.content.IntentSender; 112import android.content.pm.ActivityInfo; 113import android.content.pm.ApplicationInfo; 114import android.content.pm.ConfigurationInfo; 115import android.content.pm.IPackageDataObserver; 116import android.content.pm.IPackageManager; 117import android.content.pm.InstrumentationInfo; 118import android.content.pm.PackageInfo; 119import android.content.pm.PackageManager; 120import android.content.pm.ParceledListSlice; 121import android.content.pm.UserInfo; 122import android.content.pm.PackageManager.NameNotFoundException; 123import android.content.pm.PathPermission; 124import android.content.pm.ProviderInfo; 125import android.content.pm.ResolveInfo; 126import android.content.pm.ServiceInfo; 127import android.content.res.CompatibilityInfo; 128import android.content.res.Configuration; 129import android.graphics.Bitmap; 130import android.net.Proxy; 131import android.net.ProxyProperties; 132import android.net.Uri; 133import android.os.Binder; 134import android.os.Build; 135import android.os.Bundle; 136import android.os.Debug; 137import android.os.DropBoxManager; 138import android.os.Environment; 139import android.os.FactoryTest; 140import android.os.FileObserver; 141import android.os.FileUtils; 142import android.os.Handler; 143import android.os.IBinder; 144import android.os.IPermissionController; 145import android.os.IRemoteCallback; 146import android.os.IUserManager; 147import android.os.Looper; 148import android.os.Message; 149import android.os.Parcel; 150import android.os.ParcelFileDescriptor; 151import android.os.Process; 152import android.os.RemoteCallbackList; 153import android.os.RemoteException; 154import android.os.SELinux; 155import android.os.ServiceManager; 156import android.os.StrictMode; 157import android.os.SystemClock; 158import android.os.SystemProperties; 159import android.os.UpdateLock; 160import android.os.UserHandle; 161import android.provider.Settings; 162import android.text.format.DateUtils; 163import android.text.format.Time; 164import android.util.AtomicFile; 165import android.util.EventLog; 166import android.util.Log; 167import android.util.Pair; 168import android.util.PrintWriterPrinter; 169import android.util.Slog; 170import android.util.SparseArray; 171import android.util.TimeUtils; 172import android.util.Xml; 173import android.view.Gravity; 174import android.view.LayoutInflater; 175import android.view.View; 176import android.view.WindowManager; 177 178import java.io.BufferedInputStream; 179import java.io.BufferedOutputStream; 180import java.io.DataInputStream; 181import java.io.DataOutputStream; 182import java.io.File; 183import java.io.FileDescriptor; 184import java.io.FileInputStream; 185import java.io.FileNotFoundException; 186import java.io.FileOutputStream; 187import java.io.IOException; 188import java.io.InputStreamReader; 189import java.io.PrintWriter; 190import java.io.StringWriter; 191import java.lang.ref.WeakReference; 192import java.util.ArrayList; 193import java.util.Arrays; 194import java.util.Collections; 195import java.util.Comparator; 196import java.util.HashMap; 197import java.util.HashSet; 198import java.util.Iterator; 199import java.util.List; 200import java.util.Locale; 201import java.util.Map; 202import java.util.Set; 203import java.util.concurrent.atomic.AtomicBoolean; 204import java.util.concurrent.atomic.AtomicLong; 205 206public final class ActivityManagerService extends ActivityManagerNative 207 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 208 private static final String USER_DATA_DIR = "/data/user/"; 209 static final String TAG = "ActivityManager"; 210 static final String TAG_MU = "ActivityManagerServiceMU"; 211 static final boolean DEBUG = false; 212 static final boolean localLOGV = DEBUG; 213 static final boolean DEBUG_BACKUP = localLOGV || false; 214 static final boolean DEBUG_BROADCAST = localLOGV || false; 215 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 216 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_CLEANUP = localLOGV || false; 218 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 219 static final boolean DEBUG_FOCUS = false; 220 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 221 static final boolean DEBUG_MU = localLOGV || false; 222 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 223 static final boolean DEBUG_LRU = localLOGV || false; 224 static final boolean DEBUG_PAUSE = localLOGV || false; 225 static final boolean DEBUG_POWER = localLOGV || false; 226 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 227 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 228 static final boolean DEBUG_PROCESSES = localLOGV || false; 229 static final boolean DEBUG_PROVIDER = localLOGV || false; 230 static final boolean DEBUG_RESULTS = localLOGV || false; 231 static final boolean DEBUG_SERVICE = localLOGV || false; 232 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 233 static final boolean DEBUG_STACK = localLOGV || false; 234 static final boolean DEBUG_SWITCH = localLOGV || false; 235 static final boolean DEBUG_TASKS = localLOGV || false; 236 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 237 static final boolean DEBUG_TRANSITION = localLOGV || false; 238 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 239 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 240 static final boolean DEBUG_VISBILITY = localLOGV || false; 241 static final boolean DEBUG_PSS = localLOGV || false; 242 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 243 static final boolean VALIDATE_TOKENS = false; 244 static final boolean SHOW_ACTIVITY_START_TIME = true; 245 246 // Control over CPU and battery monitoring. 247 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 248 static final boolean MONITOR_CPU_USAGE = true; 249 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 250 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 251 static final boolean MONITOR_THREAD_CPU_USAGE = false; 252 253 // The flags that are set for all calls we make to the package manager. 254 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 255 256 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 257 258 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 259 260 // Maximum number of recent tasks that we can remember. 261 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 262 263 // Amount of time after a call to stopAppSwitches() during which we will 264 // prevent further untrusted switches from happening. 265 static final long APP_SWITCH_DELAY_TIME = 5*1000; 266 267 // How long we wait for a launched process to attach to the activity manager 268 // before we decide it's never going to come up for real. 269 static final int PROC_START_TIMEOUT = 10*1000; 270 271 // How long we wait for a launched process to attach to the activity manager 272 // before we decide it's never going to come up for real, when the process was 273 // started with a wrapper for instrumentation (such as Valgrind) because it 274 // could take much longer than usual. 275 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 276 277 // How long to wait after going idle before forcing apps to GC. 278 static final int GC_TIMEOUT = 5*1000; 279 280 // The minimum amount of time between successive GC requests for a process. 281 static final int GC_MIN_INTERVAL = 60*1000; 282 283 // The minimum amount of time between successive PSS requests for a process. 284 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 285 286 // The minimum amount of time between successive PSS requests for a process 287 // when the request is due to the memory state being lowered. 288 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 289 290 // The rate at which we check for apps using excessive power -- 15 mins. 291 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 292 293 // The minimum sample duration we will allow before deciding we have 294 // enough data on wake locks to start killing things. 295 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 296 297 // The minimum sample duration we will allow before deciding we have 298 // enough data on CPU usage to start killing things. 299 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 300 301 // How long we allow a receiver to run before giving up on it. 302 static final int BROADCAST_FG_TIMEOUT = 10*1000; 303 static final int BROADCAST_BG_TIMEOUT = 60*1000; 304 305 // How long we wait until we timeout on key dispatching. 306 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 307 308 // How long we wait until we timeout on key dispatching during instrumentation. 309 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 310 311 // Amount of time we wait for observers to handle a user switch before 312 // giving up on them and unfreezing the screen. 313 static final int USER_SWITCH_TIMEOUT = 2*1000; 314 315 // Maximum number of users we allow to be running at a time. 316 static final int MAX_RUNNING_USERS = 3; 317 318 // How long to wait in getAssistContextExtras for the activity and foreground services 319 // to respond with the result. 320 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 321 322 // Maximum number of persisted Uri grants a package is allowed 323 static final int MAX_PERSISTED_URI_GRANTS = 128; 324 325 static final int MY_PID = Process.myPid(); 326 327 static final String[] EMPTY_STRING_ARRAY = new String[0]; 328 329 // How many bytes to write into the dropbox log before truncating 330 static final int DROPBOX_MAX_SIZE = 256 * 1024; 331 332 /** Run all ActivityStacks through this */ 333 ActivityStackSupervisor mStackSupervisor; 334 335 public IntentFirewall mIntentFirewall; 336 337 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 338 // default actuion automatically. Important for devices without direct input 339 // devices. 340 private boolean mShowDialogs = true; 341 342 /** 343 * Description of a request to start a new activity, which has been held 344 * due to app switches being disabled. 345 */ 346 static class PendingActivityLaunch { 347 final ActivityRecord r; 348 final ActivityRecord sourceRecord; 349 final int startFlags; 350 final ActivityStack stack; 351 352 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 353 int _startFlags, ActivityStack _stack) { 354 r = _r; 355 sourceRecord = _sourceRecord; 356 startFlags = _startFlags; 357 stack = _stack; 358 } 359 } 360 361 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 362 = new ArrayList<PendingActivityLaunch>(); 363 364 BroadcastQueue mFgBroadcastQueue; 365 BroadcastQueue mBgBroadcastQueue; 366 // Convenient for easy iteration over the queues. Foreground is first 367 // so that dispatch of foreground broadcasts gets precedence. 368 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 369 370 BroadcastQueue broadcastQueueForIntent(Intent intent) { 371 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 372 if (DEBUG_BACKGROUND_BROADCAST) { 373 Slog.i(TAG, "Broadcast intent " + intent + " on " 374 + (isFg ? "foreground" : "background") 375 + " queue"); 376 } 377 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 378 } 379 380 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 381 for (BroadcastQueue queue : mBroadcastQueues) { 382 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 383 if (r != null) { 384 return r; 385 } 386 } 387 return null; 388 } 389 390 /** 391 * Activity we have told the window manager to have key focus. 392 */ 393 ActivityRecord mFocusedActivity = null; 394 395 /** 396 * List of intents that were used to start the most recent tasks. 397 */ 398 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 399 400 public class PendingAssistExtras extends Binder implements Runnable { 401 public final ActivityRecord activity; 402 public boolean haveResult = false; 403 public Bundle result = null; 404 public PendingAssistExtras(ActivityRecord _activity) { 405 activity = _activity; 406 } 407 @Override 408 public void run() { 409 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 410 synchronized (this) { 411 haveResult = true; 412 notifyAll(); 413 } 414 } 415 } 416 417 final ArrayList<PendingAssistExtras> mPendingAssistExtras 418 = new ArrayList<PendingAssistExtras>(); 419 420 /** 421 * Process management. 422 */ 423 final ProcessList mProcessList = new ProcessList(); 424 425 /** 426 * All of the applications we currently have running organized by name. 427 * The keys are strings of the application package name (as 428 * returned by the package manager), and the keys are ApplicationRecord 429 * objects. 430 */ 431 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 432 433 /** 434 * Tracking long-term execution of processes to look for abuse and other 435 * bad app behavior. 436 */ 437 final ProcessStatsService mProcessStats; 438 439 /** 440 * The currently running isolated processes. 441 */ 442 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 443 444 /** 445 * Counter for assigning isolated process uids, to avoid frequently reusing the 446 * same ones. 447 */ 448 int mNextIsolatedProcessUid = 0; 449 450 /** 451 * The currently running heavy-weight process, if any. 452 */ 453 ProcessRecord mHeavyWeightProcess = null; 454 455 /** 456 * The last time that various processes have crashed. 457 */ 458 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 459 460 /** 461 * Information about a process that is currently marked as bad. 462 */ 463 static final class BadProcessInfo { 464 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 465 this.time = time; 466 this.shortMsg = shortMsg; 467 this.longMsg = longMsg; 468 this.stack = stack; 469 } 470 471 final long time; 472 final String shortMsg; 473 final String longMsg; 474 final String stack; 475 } 476 477 /** 478 * Set of applications that we consider to be bad, and will reject 479 * incoming broadcasts from (which the user has no control over). 480 * Processes are added to this set when they have crashed twice within 481 * a minimum amount of time; they are removed from it when they are 482 * later restarted (hopefully due to some user action). The value is the 483 * time it was added to the list. 484 */ 485 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 486 487 /** 488 * All of the processes we currently have running organized by pid. 489 * The keys are the pid running the application. 490 * 491 * <p>NOTE: This object is protected by its own lock, NOT the global 492 * activity manager lock! 493 */ 494 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 495 496 /** 497 * All of the processes that have been forced to be foreground. The key 498 * is the pid of the caller who requested it (we hold a death 499 * link on it). 500 */ 501 abstract class ForegroundToken implements IBinder.DeathRecipient { 502 int pid; 503 IBinder token; 504 } 505 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 506 507 /** 508 * List of records for processes that someone had tried to start before the 509 * system was ready. We don't start them at that point, but ensure they 510 * are started by the time booting is complete. 511 */ 512 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 513 514 /** 515 * List of persistent applications that are in the process 516 * of being started. 517 */ 518 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 519 520 /** 521 * Processes that are being forcibly torn down. 522 */ 523 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 524 525 /** 526 * List of running applications, sorted by recent usage. 527 * The first entry in the list is the least recently used. 528 */ 529 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 530 531 /** 532 * Where in mLruProcesses that the processes hosting activities start. 533 */ 534 int mLruProcessActivityStart = 0; 535 536 /** 537 * Where in mLruProcesses that the processes hosting services start. 538 * This is after (lower index) than mLruProcessesActivityStart. 539 */ 540 int mLruProcessServiceStart = 0; 541 542 /** 543 * List of processes that should gc as soon as things are idle. 544 */ 545 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 546 547 /** 548 * Processes we want to collect PSS data from. 549 */ 550 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 551 552 /** 553 * Last time we requested PSS data of all processes. 554 */ 555 long mLastFullPssTime = SystemClock.uptimeMillis(); 556 557 /** 558 * This is the process holding what we currently consider to be 559 * the "home" activity. 560 */ 561 ProcessRecord mHomeProcess; 562 563 /** 564 * This is the process holding the activity the user last visited that 565 * is in a different process from the one they are currently in. 566 */ 567 ProcessRecord mPreviousProcess; 568 569 /** 570 * The time at which the previous process was last visible. 571 */ 572 long mPreviousProcessVisibleTime; 573 574 /** 575 * Which uses have been started, so are allowed to run code. 576 */ 577 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 578 579 /** 580 * LRU list of history of current users. Most recently current is at the end. 581 */ 582 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 583 584 /** 585 * Constant array of the users that are currently started. 586 */ 587 int[] mStartedUserArray = new int[] { 0 }; 588 589 /** 590 * Registered observers of the user switching mechanics. 591 */ 592 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 593 = new RemoteCallbackList<IUserSwitchObserver>(); 594 595 /** 596 * Currently active user switch. 597 */ 598 Object mCurUserSwitchCallback; 599 600 /** 601 * Packages that the user has asked to have run in screen size 602 * compatibility mode instead of filling the screen. 603 */ 604 final CompatModePackages mCompatModePackages; 605 606 /** 607 * Set of IntentSenderRecord objects that are currently active. 608 */ 609 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 610 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 611 612 /** 613 * Fingerprints (hashCode()) of stack traces that we've 614 * already logged DropBox entries for. Guarded by itself. If 615 * something (rogue user app) forces this over 616 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 617 */ 618 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 619 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 620 621 /** 622 * Strict Mode background batched logging state. 623 * 624 * The string buffer is guarded by itself, and its lock is also 625 * used to determine if another batched write is already 626 * in-flight. 627 */ 628 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 629 630 /** 631 * Keeps track of all IIntentReceivers that have been registered for 632 * broadcasts. Hash keys are the receiver IBinder, hash value is 633 * a ReceiverList. 634 */ 635 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 636 new HashMap<IBinder, ReceiverList>(); 637 638 /** 639 * Resolver for broadcast intents to registered receivers. 640 * Holds BroadcastFilter (subclass of IntentFilter). 641 */ 642 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 643 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 644 @Override 645 protected boolean allowFilterResult( 646 BroadcastFilter filter, List<BroadcastFilter> dest) { 647 IBinder target = filter.receiverList.receiver.asBinder(); 648 for (int i=dest.size()-1; i>=0; i--) { 649 if (dest.get(i).receiverList.receiver.asBinder() == target) { 650 return false; 651 } 652 } 653 return true; 654 } 655 656 @Override 657 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 658 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 659 || userId == filter.owningUserId) { 660 return super.newResult(filter, match, userId); 661 } 662 return null; 663 } 664 665 @Override 666 protected BroadcastFilter[] newArray(int size) { 667 return new BroadcastFilter[size]; 668 } 669 670 @Override 671 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 672 return packageName.equals(filter.packageName); 673 } 674 }; 675 676 /** 677 * State of all active sticky broadcasts per user. Keys are the action of the 678 * sticky Intent, values are an ArrayList of all broadcasted intents with 679 * that action (which should usually be one). The SparseArray is keyed 680 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 681 * for stickies that are sent to all users. 682 */ 683 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 684 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 685 686 final ActiveServices mServices; 687 688 /** 689 * Backup/restore process management 690 */ 691 String mBackupAppName = null; 692 BackupRecord mBackupTarget = null; 693 694 /** 695 * List of PendingThumbnailsRecord objects of clients who are still 696 * waiting to receive all of the thumbnails for a task. 697 */ 698 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 699 new ArrayList<PendingThumbnailsRecord>(); 700 701 final ProviderMap mProviderMap; 702 703 /** 704 * List of content providers who have clients waiting for them. The 705 * application is currently being launched and the provider will be 706 * removed from this list once it is published. 707 */ 708 final ArrayList<ContentProviderRecord> mLaunchingProviders 709 = new ArrayList<ContentProviderRecord>(); 710 711 /** 712 * File storing persisted {@link #mGrantedUriPermissions}. 713 */ 714 private final AtomicFile mGrantFile; 715 716 /** XML constants used in {@link #mGrantFile} */ 717 private static final String TAG_URI_GRANTS = "uri-grants"; 718 private static final String TAG_URI_GRANT = "uri-grant"; 719 private static final String ATTR_USER_HANDLE = "userHandle"; 720 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 721 private static final String ATTR_TARGET_PKG = "targetPkg"; 722 private static final String ATTR_URI = "uri"; 723 private static final String ATTR_MODE_FLAGS = "modeFlags"; 724 private static final String ATTR_CREATED_TIME = "createdTime"; 725 726 /** 727 * Global set of specific {@link Uri} permissions that have been granted. 728 * This optimized lookup structure maps from {@link UriPermission#targetUid} 729 * to {@link UriPermission#uri} to {@link UriPermission}. 730 */ 731 @GuardedBy("this") 732 private final SparseArray<ArrayMap<Uri, UriPermission>> 733 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 734 735 CoreSettingsObserver mCoreSettingsObserver; 736 737 /** 738 * Thread-local storage used to carry caller permissions over through 739 * indirect content-provider access. 740 */ 741 private class Identity { 742 public int pid; 743 public int uid; 744 745 Identity(int _pid, int _uid) { 746 pid = _pid; 747 uid = _uid; 748 } 749 } 750 751 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 752 753 /** 754 * All information we have collected about the runtime performance of 755 * any user id that can impact battery performance. 756 */ 757 final BatteryStatsService mBatteryStatsService; 758 759 /** 760 * Information about component usage 761 */ 762 final UsageStatsService mUsageStatsService; 763 764 /** 765 * Information about and control over application operations 766 */ 767 final AppOpsService mAppOpsService; 768 769 /** 770 * Current configuration information. HistoryRecord objects are given 771 * a reference to this object to indicate which configuration they are 772 * currently running in, so this object must be kept immutable. 773 */ 774 Configuration mConfiguration = new Configuration(); 775 776 /** 777 * Current sequencing integer of the configuration, for skipping old 778 * configurations. 779 */ 780 int mConfigurationSeq = 0; 781 782 /** 783 * Hardware-reported OpenGLES version. 784 */ 785 final int GL_ES_VERSION; 786 787 /** 788 * List of initialization arguments to pass to all processes when binding applications to them. 789 * For example, references to the commonly used services. 790 */ 791 HashMap<String, IBinder> mAppBindArgs; 792 793 /** 794 * Temporary to avoid allocations. Protected by main lock. 795 */ 796 final StringBuilder mStringBuilder = new StringBuilder(256); 797 798 /** 799 * Used to control how we initialize the service. 800 */ 801 boolean mStartRunning = false; 802 ComponentName mTopComponent; 803 String mTopAction; 804 String mTopData; 805 boolean mProcessesReady = false; 806 boolean mSystemReady = false; 807 boolean mBooting = false; 808 boolean mWaitingUpdate = false; 809 boolean mDidUpdate = false; 810 boolean mOnBattery = false; 811 boolean mLaunchWarningShown = false; 812 813 Context mContext; 814 815 int mFactoryTest; 816 817 boolean mCheckedForSetup; 818 819 /** 820 * The time at which we will allow normal application switches again, 821 * after a call to {@link #stopAppSwitches()}. 822 */ 823 long mAppSwitchesAllowedTime; 824 825 /** 826 * This is set to true after the first switch after mAppSwitchesAllowedTime 827 * is set; any switches after that will clear the time. 828 */ 829 boolean mDidAppSwitch; 830 831 /** 832 * Last time (in realtime) at which we checked for power usage. 833 */ 834 long mLastPowerCheckRealtime; 835 836 /** 837 * Last time (in uptime) at which we checked for power usage. 838 */ 839 long mLastPowerCheckUptime; 840 841 /** 842 * Set while we are wanting to sleep, to prevent any 843 * activities from being started/resumed. 844 */ 845 boolean mSleeping = false; 846 847 /** 848 * State of external calls telling us if the device is asleep. 849 */ 850 boolean mWentToSleep = false; 851 852 /** 853 * State of external call telling us if the lock screen is shown. 854 */ 855 boolean mLockScreenShown = false; 856 857 /** 858 * Set if we are shutting down the system, similar to sleeping. 859 */ 860 boolean mShuttingDown = false; 861 862 /** 863 * Current sequence id for oom_adj computation traversal. 864 */ 865 int mAdjSeq = 0; 866 867 /** 868 * Current sequence id for process LRU updating. 869 */ 870 int mLruSeq = 0; 871 872 /** 873 * Keep track of the non-cached/empty process we last found, to help 874 * determine how to distribute cached/empty processes next time. 875 */ 876 int mNumNonCachedProcs = 0; 877 878 /** 879 * Keep track of the number of cached hidden procs, to balance oom adj 880 * distribution between those and empty procs. 881 */ 882 int mNumCachedHiddenProcs = 0; 883 884 /** 885 * Keep track of the number of service processes we last found, to 886 * determine on the next iteration which should be B services. 887 */ 888 int mNumServiceProcs = 0; 889 int mNewNumAServiceProcs = 0; 890 int mNewNumServiceProcs = 0; 891 892 /** 893 * Allow the current computed overall memory level of the system to go down? 894 * This is set to false when we are killing processes for reasons other than 895 * memory management, so that the now smaller process list will not be taken as 896 * an indication that memory is tighter. 897 */ 898 boolean mAllowLowerMemLevel = false; 899 900 /** 901 * The last computed memory level, for holding when we are in a state that 902 * processes are going away for other reasons. 903 */ 904 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 905 906 /** 907 * The last total number of process we have, to determine if changes actually look 908 * like a shrinking number of process due to lower RAM. 909 */ 910 int mLastNumProcesses; 911 912 /** 913 * The uptime of the last time we performed idle maintenance. 914 */ 915 long mLastIdleTime = SystemClock.uptimeMillis(); 916 917 /** 918 * Total time spent with RAM that has been added in the past since the last idle time. 919 */ 920 long mLowRamTimeSinceLastIdle = 0; 921 922 /** 923 * If RAM is currently low, when that horrible situation started. 924 */ 925 long mLowRamStartTime = 0; 926 927 /** 928 * For reporting to battery stats the current top application. 929 */ 930 private String mCurResumedPackage = null; 931 private int mCurResumedUid = -1; 932 933 /** 934 * For reporting to battery stats the apps currently running foreground 935 * service. The ProcessMap is package/uid tuples; each of these contain 936 * an array of the currently foreground processes. 937 */ 938 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 939 = new ProcessMap<ArrayList<ProcessRecord>>(); 940 941 /** 942 * This is set if we had to do a delayed dexopt of an app before launching 943 * it, to increasing the ANR timeouts in that case. 944 */ 945 boolean mDidDexOpt; 946 947 /** 948 * Set if the systemServer made a call to enterSafeMode. 949 */ 950 boolean mSafeMode; 951 952 String mDebugApp = null; 953 boolean mWaitForDebugger = false; 954 boolean mDebugTransient = false; 955 String mOrigDebugApp = null; 956 boolean mOrigWaitForDebugger = false; 957 boolean mAlwaysFinishActivities = false; 958 IActivityController mController = null; 959 String mProfileApp = null; 960 ProcessRecord mProfileProc = null; 961 String mProfileFile; 962 ParcelFileDescriptor mProfileFd; 963 int mProfileType = 0; 964 boolean mAutoStopProfiler = false; 965 String mOpenGlTraceApp = null; 966 967 static class ProcessChangeItem { 968 static final int CHANGE_ACTIVITIES = 1<<0; 969 static final int CHANGE_IMPORTANCE= 1<<1; 970 int changes; 971 int uid; 972 int pid; 973 int importance; 974 boolean foregroundActivities; 975 } 976 977 final RemoteCallbackList<IProcessObserver> mProcessObservers 978 = new RemoteCallbackList<IProcessObserver>(); 979 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 980 981 final ArrayList<ProcessChangeItem> mPendingProcessChanges 982 = new ArrayList<ProcessChangeItem>(); 983 final ArrayList<ProcessChangeItem> mAvailProcessChanges 984 = new ArrayList<ProcessChangeItem>(); 985 986 /** 987 * Runtime CPU use collection thread. This object's lock is used to 988 * protect all related state. 989 */ 990 final Thread mProcessCpuThread; 991 992 /** 993 * Used to collect process stats when showing not responding dialog. 994 * Protected by mProcessCpuThread. 995 */ 996 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 997 MONITOR_THREAD_CPU_USAGE); 998 final AtomicLong mLastCpuTime = new AtomicLong(0); 999 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1000 1001 long mLastWriteTime = 0; 1002 1003 /** 1004 * Used to retain an update lock when the foreground activity is in 1005 * immersive mode. 1006 */ 1007 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1008 1009 /** 1010 * Set to true after the system has finished booting. 1011 */ 1012 boolean mBooted = false; 1013 1014 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1015 int mProcessLimitOverride = -1; 1016 1017 WindowManagerService mWindowManager; 1018 1019 final ActivityThread mSystemThread; 1020 1021 int mCurrentUserId = 0; 1022 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1023 private UserManagerService mUserManager; 1024 1025 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1026 final ProcessRecord mApp; 1027 final int mPid; 1028 final IApplicationThread mAppThread; 1029 1030 AppDeathRecipient(ProcessRecord app, int pid, 1031 IApplicationThread thread) { 1032 if (localLOGV) Slog.v( 1033 TAG, "New death recipient " + this 1034 + " for thread " + thread.asBinder()); 1035 mApp = app; 1036 mPid = pid; 1037 mAppThread = thread; 1038 } 1039 1040 @Override 1041 public void binderDied() { 1042 if (localLOGV) Slog.v( 1043 TAG, "Death received in " + this 1044 + " for thread " + mAppThread.asBinder()); 1045 synchronized(ActivityManagerService.this) { 1046 appDiedLocked(mApp, mPid, mAppThread); 1047 } 1048 } 1049 } 1050 1051 static final int SHOW_ERROR_MSG = 1; 1052 static final int SHOW_NOT_RESPONDING_MSG = 2; 1053 static final int SHOW_FACTORY_ERROR_MSG = 3; 1054 static final int UPDATE_CONFIGURATION_MSG = 4; 1055 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1056 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1057 static final int SERVICE_TIMEOUT_MSG = 12; 1058 static final int UPDATE_TIME_ZONE = 13; 1059 static final int SHOW_UID_ERROR_MSG = 14; 1060 static final int IM_FEELING_LUCKY_MSG = 15; 1061 static final int PROC_START_TIMEOUT_MSG = 20; 1062 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1063 static final int KILL_APPLICATION_MSG = 22; 1064 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1065 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1066 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1067 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1068 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1069 static final int CLEAR_DNS_CACHE_MSG = 28; 1070 static final int UPDATE_HTTP_PROXY_MSG = 29; 1071 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1072 static final int DISPATCH_PROCESSES_CHANGED = 31; 1073 static final int DISPATCH_PROCESS_DIED = 32; 1074 static final int REPORT_MEM_USAGE_MSG = 33; 1075 static final int REPORT_USER_SWITCH_MSG = 34; 1076 static final int CONTINUE_USER_SWITCH_MSG = 35; 1077 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1078 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1079 static final int PERSIST_URI_GRANTS_MSG = 38; 1080 static final int REQUEST_ALL_PSS_MSG = 39; 1081 static final int START_PROFILES_MSG = 40; 1082 static final int UPDATE_TIME = 41; 1083 1084 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1085 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1086 static final int FIRST_COMPAT_MODE_MSG = 300; 1087 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1088 1089 AlertDialog mUidAlert; 1090 CompatModeDialog mCompatModeDialog; 1091 long mLastMemUsageReportTime = 0; 1092 1093 /** 1094 * Flag whether the current user is a "monkey", i.e. whether 1095 * the UI is driven by a UI automation tool. 1096 */ 1097 private boolean mUserIsMonkey; 1098 1099 final ServiceThread mHandlerThread; 1100 final MainHandler mHandler; 1101 1102 final class MainHandler extends Handler { 1103 public MainHandler(Looper looper) { 1104 super(looper, null, true); 1105 } 1106 1107 @Override 1108 public void handleMessage(Message msg) { 1109 switch (msg.what) { 1110 case SHOW_ERROR_MSG: { 1111 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1112 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1113 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1114 synchronized (ActivityManagerService.this) { 1115 ProcessRecord proc = (ProcessRecord)data.get("app"); 1116 AppErrorResult res = (AppErrorResult) data.get("result"); 1117 if (proc != null && proc.crashDialog != null) { 1118 Slog.e(TAG, "App already has crash dialog: " + proc); 1119 if (res != null) { 1120 res.set(0); 1121 } 1122 return; 1123 } 1124 if (!showBackground && UserHandle.getAppId(proc.uid) 1125 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1126 && proc.pid != MY_PID) { 1127 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1128 if (res != null) { 1129 res.set(0); 1130 } 1131 return; 1132 } 1133 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1134 Dialog d = new AppErrorDialog(mContext, 1135 ActivityManagerService.this, res, proc); 1136 d.show(); 1137 proc.crashDialog = d; 1138 } else { 1139 // The device is asleep, so just pretend that the user 1140 // saw a crash dialog and hit "force quit". 1141 if (res != null) { 1142 res.set(0); 1143 } 1144 } 1145 } 1146 1147 ensureBootCompleted(); 1148 } break; 1149 case SHOW_NOT_RESPONDING_MSG: { 1150 synchronized (ActivityManagerService.this) { 1151 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1152 ProcessRecord proc = (ProcessRecord)data.get("app"); 1153 if (proc != null && proc.anrDialog != null) { 1154 Slog.e(TAG, "App already has anr dialog: " + proc); 1155 return; 1156 } 1157 1158 Intent intent = new Intent("android.intent.action.ANR"); 1159 if (!mProcessesReady) { 1160 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1161 | Intent.FLAG_RECEIVER_FOREGROUND); 1162 } 1163 broadcastIntentLocked(null, null, intent, 1164 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1165 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1166 1167 if (mShowDialogs) { 1168 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1169 mContext, proc, (ActivityRecord)data.get("activity"), 1170 msg.arg1 != 0); 1171 d.show(); 1172 proc.anrDialog = d; 1173 } else { 1174 // Just kill the app if there is no dialog to be shown. 1175 killAppAtUsersRequest(proc, null); 1176 } 1177 } 1178 1179 ensureBootCompleted(); 1180 } break; 1181 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1182 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1183 synchronized (ActivityManagerService.this) { 1184 ProcessRecord proc = (ProcessRecord) data.get("app"); 1185 if (proc == null) { 1186 Slog.e(TAG, "App not found when showing strict mode dialog."); 1187 break; 1188 } 1189 if (proc.crashDialog != null) { 1190 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1191 return; 1192 } 1193 AppErrorResult res = (AppErrorResult) data.get("result"); 1194 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1195 Dialog d = new StrictModeViolationDialog(mContext, 1196 ActivityManagerService.this, res, proc); 1197 d.show(); 1198 proc.crashDialog = d; 1199 } else { 1200 // The device is asleep, so just pretend that the user 1201 // saw a crash dialog and hit "force quit". 1202 res.set(0); 1203 } 1204 } 1205 ensureBootCompleted(); 1206 } break; 1207 case SHOW_FACTORY_ERROR_MSG: { 1208 Dialog d = new FactoryErrorDialog( 1209 mContext, msg.getData().getCharSequence("msg")); 1210 d.show(); 1211 ensureBootCompleted(); 1212 } break; 1213 case UPDATE_CONFIGURATION_MSG: { 1214 final ContentResolver resolver = mContext.getContentResolver(); 1215 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1216 } break; 1217 case GC_BACKGROUND_PROCESSES_MSG: { 1218 synchronized (ActivityManagerService.this) { 1219 performAppGcsIfAppropriateLocked(); 1220 } 1221 } break; 1222 case WAIT_FOR_DEBUGGER_MSG: { 1223 synchronized (ActivityManagerService.this) { 1224 ProcessRecord app = (ProcessRecord)msg.obj; 1225 if (msg.arg1 != 0) { 1226 if (!app.waitedForDebugger) { 1227 Dialog d = new AppWaitingForDebuggerDialog( 1228 ActivityManagerService.this, 1229 mContext, app); 1230 app.waitDialog = d; 1231 app.waitedForDebugger = true; 1232 d.show(); 1233 } 1234 } else { 1235 if (app.waitDialog != null) { 1236 app.waitDialog.dismiss(); 1237 app.waitDialog = null; 1238 } 1239 } 1240 } 1241 } break; 1242 case SERVICE_TIMEOUT_MSG: { 1243 if (mDidDexOpt) { 1244 mDidDexOpt = false; 1245 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1246 nmsg.obj = msg.obj; 1247 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1248 return; 1249 } 1250 mServices.serviceTimeout((ProcessRecord)msg.obj); 1251 } break; 1252 case UPDATE_TIME_ZONE: { 1253 synchronized (ActivityManagerService.this) { 1254 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1255 ProcessRecord r = mLruProcesses.get(i); 1256 if (r.thread != null) { 1257 try { 1258 r.thread.updateTimeZone(); 1259 } catch (RemoteException ex) { 1260 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1261 } 1262 } 1263 } 1264 } 1265 } break; 1266 case CLEAR_DNS_CACHE_MSG: { 1267 synchronized (ActivityManagerService.this) { 1268 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1269 ProcessRecord r = mLruProcesses.get(i); 1270 if (r.thread != null) { 1271 try { 1272 r.thread.clearDnsCache(); 1273 } catch (RemoteException ex) { 1274 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1275 } 1276 } 1277 } 1278 } 1279 } break; 1280 case UPDATE_HTTP_PROXY_MSG: { 1281 ProxyProperties proxy = (ProxyProperties)msg.obj; 1282 String host = ""; 1283 String port = ""; 1284 String exclList = ""; 1285 String pacFileUrl = null; 1286 if (proxy != null) { 1287 host = proxy.getHost(); 1288 port = Integer.toString(proxy.getPort()); 1289 exclList = proxy.getExclusionList(); 1290 pacFileUrl = proxy.getPacFileUrl(); 1291 } 1292 synchronized (ActivityManagerService.this) { 1293 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1294 ProcessRecord r = mLruProcesses.get(i); 1295 if (r.thread != null) { 1296 try { 1297 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1298 } catch (RemoteException ex) { 1299 Slog.w(TAG, "Failed to update http proxy for: " + 1300 r.info.processName); 1301 } 1302 } 1303 } 1304 } 1305 } break; 1306 case SHOW_UID_ERROR_MSG: { 1307 String title = "System UIDs Inconsistent"; 1308 String text = "UIDs on the system are inconsistent, you need to wipe your" 1309 + " data partition or your device will be unstable."; 1310 Log.e(TAG, title + ": " + text); 1311 if (mShowDialogs) { 1312 // XXX This is a temporary dialog, no need to localize. 1313 AlertDialog d = new BaseErrorDialog(mContext); 1314 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1315 d.setCancelable(false); 1316 d.setTitle(title); 1317 d.setMessage(text); 1318 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1319 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1320 mUidAlert = d; 1321 d.show(); 1322 } 1323 } break; 1324 case IM_FEELING_LUCKY_MSG: { 1325 if (mUidAlert != null) { 1326 mUidAlert.dismiss(); 1327 mUidAlert = null; 1328 } 1329 } break; 1330 case PROC_START_TIMEOUT_MSG: { 1331 if (mDidDexOpt) { 1332 mDidDexOpt = false; 1333 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1334 nmsg.obj = msg.obj; 1335 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1336 return; 1337 } 1338 ProcessRecord app = (ProcessRecord)msg.obj; 1339 synchronized (ActivityManagerService.this) { 1340 processStartTimedOutLocked(app); 1341 } 1342 } break; 1343 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1344 synchronized (ActivityManagerService.this) { 1345 doPendingActivityLaunchesLocked(true); 1346 } 1347 } break; 1348 case KILL_APPLICATION_MSG: { 1349 synchronized (ActivityManagerService.this) { 1350 int appid = msg.arg1; 1351 boolean restart = (msg.arg2 == 1); 1352 Bundle bundle = (Bundle)msg.obj; 1353 String pkg = bundle.getString("pkg"); 1354 String reason = bundle.getString("reason"); 1355 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1356 false, UserHandle.USER_ALL, reason); 1357 } 1358 } break; 1359 case FINALIZE_PENDING_INTENT_MSG: { 1360 ((PendingIntentRecord)msg.obj).completeFinalize(); 1361 } break; 1362 case POST_HEAVY_NOTIFICATION_MSG: { 1363 INotificationManager inm = NotificationManager.getService(); 1364 if (inm == null) { 1365 return; 1366 } 1367 1368 ActivityRecord root = (ActivityRecord)msg.obj; 1369 ProcessRecord process = root.app; 1370 if (process == null) { 1371 return; 1372 } 1373 1374 try { 1375 Context context = mContext.createPackageContext(process.info.packageName, 0); 1376 String text = mContext.getString(R.string.heavy_weight_notification, 1377 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1378 Notification notification = new Notification(); 1379 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1380 notification.when = 0; 1381 notification.flags = Notification.FLAG_ONGOING_EVENT; 1382 notification.tickerText = text; 1383 notification.defaults = 0; // please be quiet 1384 notification.sound = null; 1385 notification.vibrate = null; 1386 notification.setLatestEventInfo(context, text, 1387 mContext.getText(R.string.heavy_weight_notification_detail), 1388 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1389 PendingIntent.FLAG_CANCEL_CURRENT, null, 1390 new UserHandle(root.userId))); 1391 1392 try { 1393 int[] outId = new int[1]; 1394 inm.enqueueNotificationWithTag("android", "android", null, 1395 R.string.heavy_weight_notification, 1396 notification, outId, root.userId); 1397 } catch (RuntimeException e) { 1398 Slog.w(ActivityManagerService.TAG, 1399 "Error showing notification for heavy-weight app", e); 1400 } catch (RemoteException e) { 1401 } 1402 } catch (NameNotFoundException e) { 1403 Slog.w(TAG, "Unable to create context for heavy notification", e); 1404 } 1405 } break; 1406 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1407 INotificationManager inm = NotificationManager.getService(); 1408 if (inm == null) { 1409 return; 1410 } 1411 try { 1412 inm.cancelNotificationWithTag("android", null, 1413 R.string.heavy_weight_notification, msg.arg1); 1414 } catch (RuntimeException e) { 1415 Slog.w(ActivityManagerService.TAG, 1416 "Error canceling notification for service", e); 1417 } catch (RemoteException e) { 1418 } 1419 } break; 1420 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1421 synchronized (ActivityManagerService.this) { 1422 checkExcessivePowerUsageLocked(true); 1423 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1424 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1425 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1426 } 1427 } break; 1428 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1429 synchronized (ActivityManagerService.this) { 1430 ActivityRecord ar = (ActivityRecord)msg.obj; 1431 if (mCompatModeDialog != null) { 1432 if (mCompatModeDialog.mAppInfo.packageName.equals( 1433 ar.info.applicationInfo.packageName)) { 1434 return; 1435 } 1436 mCompatModeDialog.dismiss(); 1437 mCompatModeDialog = null; 1438 } 1439 if (ar != null && false) { 1440 if (mCompatModePackages.getPackageAskCompatModeLocked( 1441 ar.packageName)) { 1442 int mode = mCompatModePackages.computeCompatModeLocked( 1443 ar.info.applicationInfo); 1444 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1445 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1446 mCompatModeDialog = new CompatModeDialog( 1447 ActivityManagerService.this, mContext, 1448 ar.info.applicationInfo); 1449 mCompatModeDialog.show(); 1450 } 1451 } 1452 } 1453 } 1454 break; 1455 } 1456 case DISPATCH_PROCESSES_CHANGED: { 1457 dispatchProcessesChanged(); 1458 break; 1459 } 1460 case DISPATCH_PROCESS_DIED: { 1461 final int pid = msg.arg1; 1462 final int uid = msg.arg2; 1463 dispatchProcessDied(pid, uid); 1464 break; 1465 } 1466 case REPORT_MEM_USAGE_MSG: { 1467 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1468 Thread thread = new Thread() { 1469 @Override public void run() { 1470 final SparseArray<ProcessMemInfo> infoMap 1471 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1472 for (int i=0, N=memInfos.size(); i<N; i++) { 1473 ProcessMemInfo mi = memInfos.get(i); 1474 infoMap.put(mi.pid, mi); 1475 } 1476 updateCpuStatsNow(); 1477 synchronized (mProcessCpuThread) { 1478 final int N = mProcessCpuTracker.countStats(); 1479 for (int i=0; i<N; i++) { 1480 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1481 if (st.vsize > 0) { 1482 long pss = Debug.getPss(st.pid, null); 1483 if (pss > 0) { 1484 if (infoMap.indexOfKey(st.pid) < 0) { 1485 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1486 ProcessList.NATIVE_ADJ, -1, "native", null); 1487 mi.pss = pss; 1488 memInfos.add(mi); 1489 } 1490 } 1491 } 1492 } 1493 } 1494 1495 long totalPss = 0; 1496 for (int i=0, N=memInfos.size(); i<N; i++) { 1497 ProcessMemInfo mi = memInfos.get(i); 1498 if (mi.pss == 0) { 1499 mi.pss = Debug.getPss(mi.pid, null); 1500 } 1501 totalPss += mi.pss; 1502 } 1503 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1504 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1505 if (lhs.oomAdj != rhs.oomAdj) { 1506 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1507 } 1508 if (lhs.pss != rhs.pss) { 1509 return lhs.pss < rhs.pss ? 1 : -1; 1510 } 1511 return 0; 1512 } 1513 }); 1514 1515 StringBuilder tag = new StringBuilder(128); 1516 StringBuilder stack = new StringBuilder(128); 1517 tag.append("Low on memory -- "); 1518 appendMemBucket(tag, totalPss, "total", false); 1519 appendMemBucket(stack, totalPss, "total", true); 1520 1521 StringBuilder logBuilder = new StringBuilder(1024); 1522 logBuilder.append("Low on memory:\n"); 1523 1524 boolean firstLine = true; 1525 int lastOomAdj = Integer.MIN_VALUE; 1526 for (int i=0, N=memInfos.size(); i<N; i++) { 1527 ProcessMemInfo mi = memInfos.get(i); 1528 1529 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1530 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1531 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1532 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1533 if (lastOomAdj != mi.oomAdj) { 1534 lastOomAdj = mi.oomAdj; 1535 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1536 tag.append(" / "); 1537 } 1538 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1539 if (firstLine) { 1540 stack.append(":"); 1541 firstLine = false; 1542 } 1543 stack.append("\n\t at "); 1544 } else { 1545 stack.append("$"); 1546 } 1547 } else { 1548 tag.append(" "); 1549 stack.append("$"); 1550 } 1551 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1552 appendMemBucket(tag, mi.pss, mi.name, false); 1553 } 1554 appendMemBucket(stack, mi.pss, mi.name, true); 1555 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1556 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1557 stack.append("("); 1558 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1559 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1560 stack.append(DUMP_MEM_OOM_LABEL[k]); 1561 stack.append(":"); 1562 stack.append(DUMP_MEM_OOM_ADJ[k]); 1563 } 1564 } 1565 stack.append(")"); 1566 } 1567 } 1568 1569 logBuilder.append(" "); 1570 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1571 logBuilder.append(' '); 1572 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1573 logBuilder.append(' '); 1574 ProcessList.appendRamKb(logBuilder, mi.pss); 1575 logBuilder.append(" kB: "); 1576 logBuilder.append(mi.name); 1577 logBuilder.append(" ("); 1578 logBuilder.append(mi.pid); 1579 logBuilder.append(") "); 1580 logBuilder.append(mi.adjType); 1581 logBuilder.append('\n'); 1582 if (mi.adjReason != null) { 1583 logBuilder.append(" "); 1584 logBuilder.append(mi.adjReason); 1585 logBuilder.append('\n'); 1586 } 1587 } 1588 1589 logBuilder.append(" "); 1590 ProcessList.appendRamKb(logBuilder, totalPss); 1591 logBuilder.append(" kB: TOTAL\n"); 1592 1593 long[] infos = new long[Debug.MEMINFO_COUNT]; 1594 Debug.getMemInfo(infos); 1595 logBuilder.append(" MemInfo: "); 1596 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1597 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1598 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1599 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1600 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1601 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1602 logBuilder.append(" ZRAM: "); 1603 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1604 logBuilder.append(" kB RAM, "); 1605 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1606 logBuilder.append(" kB swap total, "); 1607 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1608 logBuilder.append(" kB swap free\n"); 1609 } 1610 Slog.i(TAG, logBuilder.toString()); 1611 1612 StringBuilder dropBuilder = new StringBuilder(1024); 1613 /* 1614 StringWriter oomSw = new StringWriter(); 1615 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1616 StringWriter catSw = new StringWriter(); 1617 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1618 String[] emptyArgs = new String[] { }; 1619 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1620 oomPw.flush(); 1621 String oomString = oomSw.toString(); 1622 */ 1623 dropBuilder.append(stack); 1624 dropBuilder.append('\n'); 1625 dropBuilder.append('\n'); 1626 dropBuilder.append(logBuilder); 1627 dropBuilder.append('\n'); 1628 /* 1629 dropBuilder.append(oomString); 1630 dropBuilder.append('\n'); 1631 */ 1632 StringWriter catSw = new StringWriter(); 1633 synchronized (ActivityManagerService.this) { 1634 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1635 String[] emptyArgs = new String[] { }; 1636 catPw.println(); 1637 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1638 catPw.println(); 1639 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1640 false, false, null); 1641 catPw.println(); 1642 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1643 catPw.flush(); 1644 } 1645 dropBuilder.append(catSw.toString()); 1646 addErrorToDropBox("lowmem", null, "system_server", null, 1647 null, tag.toString(), dropBuilder.toString(), null, null); 1648 //Slog.i(TAG, "Sent to dropbox:"); 1649 //Slog.i(TAG, dropBuilder.toString()); 1650 synchronized (ActivityManagerService.this) { 1651 long now = SystemClock.uptimeMillis(); 1652 if (mLastMemUsageReportTime < now) { 1653 mLastMemUsageReportTime = now; 1654 } 1655 } 1656 } 1657 }; 1658 thread.start(); 1659 break; 1660 } 1661 case REPORT_USER_SWITCH_MSG: { 1662 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1663 break; 1664 } 1665 case CONTINUE_USER_SWITCH_MSG: { 1666 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1667 break; 1668 } 1669 case USER_SWITCH_TIMEOUT_MSG: { 1670 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1671 break; 1672 } 1673 case IMMERSIVE_MODE_LOCK_MSG: { 1674 final boolean nextState = (msg.arg1 != 0); 1675 if (mUpdateLock.isHeld() != nextState) { 1676 if (DEBUG_IMMERSIVE) { 1677 final ActivityRecord r = (ActivityRecord) msg.obj; 1678 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1679 } 1680 if (nextState) { 1681 mUpdateLock.acquire(); 1682 } else { 1683 mUpdateLock.release(); 1684 } 1685 } 1686 break; 1687 } 1688 case PERSIST_URI_GRANTS_MSG: { 1689 writeGrantedUriPermissions(); 1690 break; 1691 } 1692 case REQUEST_ALL_PSS_MSG: { 1693 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1694 break; 1695 } 1696 case START_PROFILES_MSG: { 1697 synchronized (ActivityManagerService.this) { 1698 startProfilesLocked(); 1699 } 1700 break; 1701 } 1702 case UPDATE_TIME: { 1703 synchronized (ActivityManagerService.this) { 1704 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1705 ProcessRecord r = mLruProcesses.get(i); 1706 if (r.thread != null) { 1707 try { 1708 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1709 } catch (RemoteException ex) { 1710 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1711 } 1712 } 1713 } 1714 } 1715 break; 1716 } 1717 } 1718 } 1719 }; 1720 1721 static final int COLLECT_PSS_BG_MSG = 1; 1722 1723 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1724 @Override 1725 public void handleMessage(Message msg) { 1726 switch (msg.what) { 1727 case COLLECT_PSS_BG_MSG: { 1728 int i=0, num=0; 1729 long start = SystemClock.uptimeMillis(); 1730 long[] tmp = new long[1]; 1731 do { 1732 ProcessRecord proc; 1733 int procState; 1734 int pid; 1735 synchronized (ActivityManagerService.this) { 1736 if (i >= mPendingPssProcesses.size()) { 1737 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1738 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1739 mPendingPssProcesses.clear(); 1740 return; 1741 } 1742 proc = mPendingPssProcesses.get(i); 1743 procState = proc.pssProcState; 1744 if (proc.thread != null && procState == proc.setProcState) { 1745 pid = proc.pid; 1746 } else { 1747 proc = null; 1748 pid = 0; 1749 } 1750 i++; 1751 } 1752 if (proc != null) { 1753 long pss = Debug.getPss(pid, tmp); 1754 synchronized (ActivityManagerService.this) { 1755 if (proc.thread != null && proc.setProcState == procState 1756 && proc.pid == pid) { 1757 num++; 1758 proc.lastPssTime = SystemClock.uptimeMillis(); 1759 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1760 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1761 + ": " + pss + " lastPss=" + proc.lastPss 1762 + " state=" + ProcessList.makeProcStateString(procState)); 1763 if (proc.initialIdlePss == 0) { 1764 proc.initialIdlePss = pss; 1765 } 1766 proc.lastPss = pss; 1767 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1768 proc.lastCachedPss = pss; 1769 } 1770 } 1771 } 1772 } 1773 } while (true); 1774 } 1775 } 1776 } 1777 }; 1778 1779 public void setSystemProcess() { 1780 try { 1781 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1782 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1783 ServiceManager.addService("meminfo", new MemBinder(this)); 1784 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1785 ServiceManager.addService("dbinfo", new DbBinder(this)); 1786 if (MONITOR_CPU_USAGE) { 1787 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1788 } 1789 ServiceManager.addService("permission", new PermissionController(this)); 1790 1791 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1792 "android", STOCK_PM_FLAGS); 1793 mSystemThread.installSystemApplicationInfo(info); 1794 1795 synchronized (this) { 1796 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1797 app.persistent = true; 1798 app.pid = MY_PID; 1799 app.maxAdj = ProcessList.SYSTEM_ADJ; 1800 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1801 mProcessNames.put(app.processName, app.uid, app); 1802 synchronized (mPidsSelfLocked) { 1803 mPidsSelfLocked.put(app.pid, app); 1804 } 1805 updateLruProcessLocked(app, false, null); 1806 updateOomAdjLocked(); 1807 } 1808 } catch (PackageManager.NameNotFoundException e) { 1809 throw new RuntimeException( 1810 "Unable to find android system package", e); 1811 } 1812 } 1813 1814 public void setWindowManager(WindowManagerService wm) { 1815 mWindowManager = wm; 1816 mStackSupervisor.setWindowManager(wm); 1817 } 1818 1819 public void startObservingNativeCrashes() { 1820 final NativeCrashListener ncl = new NativeCrashListener(this); 1821 ncl.start(); 1822 } 1823 1824 public IAppOpsService getAppOpsService() { 1825 return mAppOpsService; 1826 } 1827 1828 static class MemBinder extends Binder { 1829 ActivityManagerService mActivityManagerService; 1830 MemBinder(ActivityManagerService activityManagerService) { 1831 mActivityManagerService = activityManagerService; 1832 } 1833 1834 @Override 1835 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1836 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1837 != PackageManager.PERMISSION_GRANTED) { 1838 pw.println("Permission Denial: can't dump meminfo from from pid=" 1839 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1840 + " without permission " + android.Manifest.permission.DUMP); 1841 return; 1842 } 1843 1844 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1845 } 1846 } 1847 1848 static class GraphicsBinder extends Binder { 1849 ActivityManagerService mActivityManagerService; 1850 GraphicsBinder(ActivityManagerService activityManagerService) { 1851 mActivityManagerService = activityManagerService; 1852 } 1853 1854 @Override 1855 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1856 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1857 != PackageManager.PERMISSION_GRANTED) { 1858 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1859 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1860 + " without permission " + android.Manifest.permission.DUMP); 1861 return; 1862 } 1863 1864 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1865 } 1866 } 1867 1868 static class DbBinder extends Binder { 1869 ActivityManagerService mActivityManagerService; 1870 DbBinder(ActivityManagerService activityManagerService) { 1871 mActivityManagerService = activityManagerService; 1872 } 1873 1874 @Override 1875 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1876 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1877 != PackageManager.PERMISSION_GRANTED) { 1878 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1879 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1880 + " without permission " + android.Manifest.permission.DUMP); 1881 return; 1882 } 1883 1884 mActivityManagerService.dumpDbInfo(fd, pw, args); 1885 } 1886 } 1887 1888 static class CpuBinder extends Binder { 1889 ActivityManagerService mActivityManagerService; 1890 CpuBinder(ActivityManagerService activityManagerService) { 1891 mActivityManagerService = activityManagerService; 1892 } 1893 1894 @Override 1895 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1896 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1897 != PackageManager.PERMISSION_GRANTED) { 1898 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1899 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1900 + " without permission " + android.Manifest.permission.DUMP); 1901 return; 1902 } 1903 1904 synchronized (mActivityManagerService.mProcessCpuThread) { 1905 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1906 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1907 SystemClock.uptimeMillis())); 1908 } 1909 } 1910 } 1911 1912 public static final class Lifecycle extends SystemService { 1913 private final ActivityManagerService mService; 1914 1915 public Lifecycle(Context context) { 1916 super(context); 1917 mService = new ActivityManagerService(context); 1918 } 1919 1920 @Override 1921 public void onStart() { 1922 mService.start(); 1923 } 1924 1925 public ActivityManagerService getService() { 1926 return mService; 1927 } 1928 } 1929 1930 // Note: This method is invoked on the main thread but may need to attach various 1931 // handlers to other threads. So take care to be explicit about the looper. 1932 public ActivityManagerService(Context systemContext) { 1933 mContext = systemContext; 1934 mFactoryTest = FactoryTest.getMode(); 1935 mSystemThread = ActivityThread.currentActivityThread(); 1936 1937 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1938 1939 mHandlerThread = new ServiceThread(TAG, 1940 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1941 mHandlerThread.start(); 1942 mHandler = new MainHandler(mHandlerThread.getLooper()); 1943 1944 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1945 "foreground", BROADCAST_FG_TIMEOUT, false); 1946 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1947 "background", BROADCAST_BG_TIMEOUT, true); 1948 mBroadcastQueues[0] = mFgBroadcastQueue; 1949 mBroadcastQueues[1] = mBgBroadcastQueue; 1950 1951 mServices = new ActiveServices(this); 1952 mProviderMap = new ProviderMap(this); 1953 1954 // TODO: Move creation of battery stats service outside of activity manager service. 1955 File dataDir = Environment.getDataDirectory(); 1956 File systemDir = new File(dataDir, "system"); 1957 systemDir.mkdirs(); 1958 mBatteryStatsService = new BatteryStatsService(new File( 1959 systemDir, "batterystats.bin").toString(), mHandler); 1960 mBatteryStatsService.getActiveStatistics().readLocked(); 1961 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1962 mOnBattery = DEBUG_POWER ? true 1963 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1964 mBatteryStatsService.getActiveStatistics().setCallback(this); 1965 1966 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1967 1968 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1969 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1970 1971 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1972 1973 // User 0 is the first and only user that runs at boot. 1974 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1975 mUserLru.add(Integer.valueOf(0)); 1976 updateStartedUserArrayLocked(); 1977 1978 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1979 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1980 1981 mConfiguration.setToDefaults(); 1982 mConfiguration.setLocale(Locale.getDefault()); 1983 1984 mConfigurationSeq = mConfiguration.seq = 1; 1985 mProcessCpuTracker.init(); 1986 1987 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1988 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1989 mStackSupervisor = new ActivityStackSupervisor(this); 1990 1991 mProcessCpuThread = new Thread("CpuTracker") { 1992 @Override 1993 public void run() { 1994 while (true) { 1995 try { 1996 try { 1997 synchronized(this) { 1998 final long now = SystemClock.uptimeMillis(); 1999 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2000 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2001 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2002 // + ", write delay=" + nextWriteDelay); 2003 if (nextWriteDelay < nextCpuDelay) { 2004 nextCpuDelay = nextWriteDelay; 2005 } 2006 if (nextCpuDelay > 0) { 2007 mProcessCpuMutexFree.set(true); 2008 this.wait(nextCpuDelay); 2009 } 2010 } 2011 } catch (InterruptedException e) { 2012 } 2013 updateCpuStatsNow(); 2014 } catch (Exception e) { 2015 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2016 } 2017 } 2018 } 2019 }; 2020 2021 Watchdog.getInstance().addMonitor(this); 2022 Watchdog.getInstance().addThread(mHandler); 2023 } 2024 2025 private void start() { 2026 mProcessCpuThread.start(); 2027 2028 mBatteryStatsService.publish(mContext); 2029 mUsageStatsService.publish(mContext); 2030 mAppOpsService.publish(mContext); 2031 startRunning(null, null, null, null); 2032 } 2033 2034 @Override 2035 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2036 throws RemoteException { 2037 if (code == SYSPROPS_TRANSACTION) { 2038 // We need to tell all apps about the system property change. 2039 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2040 synchronized(this) { 2041 final int NP = mProcessNames.getMap().size(); 2042 for (int ip=0; ip<NP; ip++) { 2043 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2044 final int NA = apps.size(); 2045 for (int ia=0; ia<NA; ia++) { 2046 ProcessRecord app = apps.valueAt(ia); 2047 if (app.thread != null) { 2048 procs.add(app.thread.asBinder()); 2049 } 2050 } 2051 } 2052 } 2053 2054 int N = procs.size(); 2055 for (int i=0; i<N; i++) { 2056 Parcel data2 = Parcel.obtain(); 2057 try { 2058 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2059 } catch (RemoteException e) { 2060 } 2061 data2.recycle(); 2062 } 2063 } 2064 try { 2065 return super.onTransact(code, data, reply, flags); 2066 } catch (RuntimeException e) { 2067 // The activity manager only throws security exceptions, so let's 2068 // log all others. 2069 if (!(e instanceof SecurityException)) { 2070 Slog.wtf(TAG, "Activity Manager Crash", e); 2071 } 2072 throw e; 2073 } 2074 } 2075 2076 void updateCpuStats() { 2077 final long now = SystemClock.uptimeMillis(); 2078 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2079 return; 2080 } 2081 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2082 synchronized (mProcessCpuThread) { 2083 mProcessCpuThread.notify(); 2084 } 2085 } 2086 } 2087 2088 void updateCpuStatsNow() { 2089 synchronized (mProcessCpuThread) { 2090 mProcessCpuMutexFree.set(false); 2091 final long now = SystemClock.uptimeMillis(); 2092 boolean haveNewCpuStats = false; 2093 2094 if (MONITOR_CPU_USAGE && 2095 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2096 mLastCpuTime.set(now); 2097 haveNewCpuStats = true; 2098 mProcessCpuTracker.update(); 2099 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2100 //Slog.i(TAG, "Total CPU usage: " 2101 // + mProcessCpu.getTotalCpuPercent() + "%"); 2102 2103 // Slog the cpu usage if the property is set. 2104 if ("true".equals(SystemProperties.get("events.cpu"))) { 2105 int user = mProcessCpuTracker.getLastUserTime(); 2106 int system = mProcessCpuTracker.getLastSystemTime(); 2107 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2108 int irq = mProcessCpuTracker.getLastIrqTime(); 2109 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2110 int idle = mProcessCpuTracker.getLastIdleTime(); 2111 2112 int total = user + system + iowait + irq + softIrq + idle; 2113 if (total == 0) total = 1; 2114 2115 EventLog.writeEvent(EventLogTags.CPU, 2116 ((user+system+iowait+irq+softIrq) * 100) / total, 2117 (user * 100) / total, 2118 (system * 100) / total, 2119 (iowait * 100) / total, 2120 (irq * 100) / total, 2121 (softIrq * 100) / total); 2122 } 2123 } 2124 2125 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2126 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2127 synchronized(bstats) { 2128 synchronized(mPidsSelfLocked) { 2129 if (haveNewCpuStats) { 2130 if (mOnBattery) { 2131 int perc = bstats.startAddingCpuLocked(); 2132 int totalUTime = 0; 2133 int totalSTime = 0; 2134 final int N = mProcessCpuTracker.countStats(); 2135 for (int i=0; i<N; i++) { 2136 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2137 if (!st.working) { 2138 continue; 2139 } 2140 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2141 int otherUTime = (st.rel_utime*perc)/100; 2142 int otherSTime = (st.rel_stime*perc)/100; 2143 totalUTime += otherUTime; 2144 totalSTime += otherSTime; 2145 if (pr != null) { 2146 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2147 if (ps == null || !ps.isActive()) { 2148 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2149 pr.info.uid, pr.processName); 2150 } 2151 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2152 st.rel_stime-otherSTime); 2153 ps.addSpeedStepTimes(cpuSpeedTimes); 2154 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2155 } else { 2156 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2157 if (ps == null || !ps.isActive()) { 2158 st.batteryStats = ps = bstats.getProcessStatsLocked( 2159 bstats.mapUid(st.uid), st.name); 2160 } 2161 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2162 st.rel_stime-otherSTime); 2163 ps.addSpeedStepTimes(cpuSpeedTimes); 2164 } 2165 } 2166 bstats.finishAddingCpuLocked(perc, totalUTime, 2167 totalSTime, cpuSpeedTimes); 2168 } 2169 } 2170 } 2171 2172 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2173 mLastWriteTime = now; 2174 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2175 } 2176 } 2177 } 2178 } 2179 2180 @Override 2181 public void batteryNeedsCpuUpdate() { 2182 updateCpuStatsNow(); 2183 } 2184 2185 @Override 2186 public void batteryPowerChanged(boolean onBattery) { 2187 // When plugging in, update the CPU stats first before changing 2188 // the plug state. 2189 updateCpuStatsNow(); 2190 synchronized (this) { 2191 synchronized(mPidsSelfLocked) { 2192 mOnBattery = DEBUG_POWER ? true : onBattery; 2193 } 2194 } 2195 } 2196 2197 /** 2198 * Initialize the application bind args. These are passed to each 2199 * process when the bindApplication() IPC is sent to the process. They're 2200 * lazily setup to make sure the services are running when they're asked for. 2201 */ 2202 private HashMap<String, IBinder> getCommonServicesLocked() { 2203 if (mAppBindArgs == null) { 2204 mAppBindArgs = new HashMap<String, IBinder>(); 2205 2206 // Setup the application init args 2207 mAppBindArgs.put("package", ServiceManager.getService("package")); 2208 mAppBindArgs.put("window", ServiceManager.getService("window")); 2209 mAppBindArgs.put(Context.ALARM_SERVICE, 2210 ServiceManager.getService(Context.ALARM_SERVICE)); 2211 } 2212 return mAppBindArgs; 2213 } 2214 2215 final void setFocusedActivityLocked(ActivityRecord r) { 2216 if (mFocusedActivity != r) { 2217 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2218 mFocusedActivity = r; 2219 mStackSupervisor.setFocusedStack(r); 2220 if (r != null) { 2221 mWindowManager.setFocusedApp(r.appToken, true); 2222 } 2223 applyUpdateLockStateLocked(r); 2224 } 2225 } 2226 2227 @Override 2228 public void setFocusedStack(int stackId) { 2229 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2230 synchronized (ActivityManagerService.this) { 2231 ActivityStack stack = mStackSupervisor.getStack(stackId); 2232 if (stack != null) { 2233 ActivityRecord r = stack.topRunningActivityLocked(null); 2234 if (r != null) { 2235 setFocusedActivityLocked(r); 2236 } 2237 } 2238 } 2239 } 2240 2241 @Override 2242 public void notifyActivityDrawn(IBinder token) { 2243 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2244 synchronized (this) { 2245 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2246 if (r != null) { 2247 r.task.stack.notifyActivityDrawnLocked(r); 2248 } 2249 } 2250 } 2251 2252 final void applyUpdateLockStateLocked(ActivityRecord r) { 2253 // Modifications to the UpdateLock state are done on our handler, outside 2254 // the activity manager's locks. The new state is determined based on the 2255 // state *now* of the relevant activity record. The object is passed to 2256 // the handler solely for logging detail, not to be consulted/modified. 2257 final boolean nextState = r != null && r.immersive; 2258 mHandler.sendMessage( 2259 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2260 } 2261 2262 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2263 Message msg = Message.obtain(); 2264 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2265 msg.obj = r.task.askedCompatMode ? null : r; 2266 mHandler.sendMessage(msg); 2267 } 2268 2269 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2270 String what, Object obj, ProcessRecord srcApp) { 2271 app.lastActivityTime = now; 2272 2273 if (app.activities.size() > 0) { 2274 // Don't want to touch dependent processes that are hosting activities. 2275 return index; 2276 } 2277 2278 int lrui = mLruProcesses.lastIndexOf(app); 2279 if (lrui < 0) { 2280 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2281 + what + " " + obj + " from " + srcApp); 2282 return index; 2283 } 2284 2285 if (lrui >= index) { 2286 // Don't want to cause this to move dependent processes *back* in the 2287 // list as if they were less frequently used. 2288 return index; 2289 } 2290 2291 if (lrui >= mLruProcessActivityStart) { 2292 // Don't want to touch dependent processes that are hosting activities. 2293 return index; 2294 } 2295 2296 mLruProcesses.remove(lrui); 2297 if (index > 0) { 2298 index--; 2299 } 2300 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2301 + " in LRU list: " + app); 2302 mLruProcesses.add(index, app); 2303 return index; 2304 } 2305 2306 final void removeLruProcessLocked(ProcessRecord app) { 2307 int lrui = mLruProcesses.lastIndexOf(app); 2308 if (lrui >= 0) { 2309 if (lrui <= mLruProcessActivityStart) { 2310 mLruProcessActivityStart--; 2311 } 2312 if (lrui <= mLruProcessServiceStart) { 2313 mLruProcessServiceStart--; 2314 } 2315 mLruProcesses.remove(lrui); 2316 } 2317 } 2318 2319 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2320 ProcessRecord client) { 2321 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2322 || app.treatLikeActivity; 2323 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2324 if (!activityChange && hasActivity) { 2325 // The process has activities, so we are only allowing activity-based adjustments 2326 // to move it. It should be kept in the front of the list with other 2327 // processes that have activities, and we don't want those to change their 2328 // order except due to activity operations. 2329 return; 2330 } 2331 2332 mLruSeq++; 2333 final long now = SystemClock.uptimeMillis(); 2334 app.lastActivityTime = now; 2335 2336 // First a quick reject: if the app is already at the position we will 2337 // put it, then there is nothing to do. 2338 if (hasActivity) { 2339 final int N = mLruProcesses.size(); 2340 if (N > 0 && mLruProcesses.get(N-1) == app) { 2341 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2342 return; 2343 } 2344 } else { 2345 if (mLruProcessServiceStart > 0 2346 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2347 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2348 return; 2349 } 2350 } 2351 2352 int lrui = mLruProcesses.lastIndexOf(app); 2353 2354 if (app.persistent && lrui >= 0) { 2355 // We don't care about the position of persistent processes, as long as 2356 // they are in the list. 2357 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2358 return; 2359 } 2360 2361 /* In progress: compute new position first, so we can avoid doing work 2362 if the process is not actually going to move. Not yet working. 2363 int addIndex; 2364 int nextIndex; 2365 boolean inActivity = false, inService = false; 2366 if (hasActivity) { 2367 // Process has activities, put it at the very tipsy-top. 2368 addIndex = mLruProcesses.size(); 2369 nextIndex = mLruProcessServiceStart; 2370 inActivity = true; 2371 } else if (hasService) { 2372 // Process has services, put it at the top of the service list. 2373 addIndex = mLruProcessActivityStart; 2374 nextIndex = mLruProcessServiceStart; 2375 inActivity = true; 2376 inService = true; 2377 } else { 2378 // Process not otherwise of interest, it goes to the top of the non-service area. 2379 addIndex = mLruProcessServiceStart; 2380 if (client != null) { 2381 int clientIndex = mLruProcesses.lastIndexOf(client); 2382 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2383 + app); 2384 if (clientIndex >= 0 && addIndex > clientIndex) { 2385 addIndex = clientIndex; 2386 } 2387 } 2388 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2389 } 2390 2391 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2392 + mLruProcessActivityStart + "): " + app); 2393 */ 2394 2395 if (lrui >= 0) { 2396 if (lrui < mLruProcessActivityStart) { 2397 mLruProcessActivityStart--; 2398 } 2399 if (lrui < mLruProcessServiceStart) { 2400 mLruProcessServiceStart--; 2401 } 2402 /* 2403 if (addIndex > lrui) { 2404 addIndex--; 2405 } 2406 if (nextIndex > lrui) { 2407 nextIndex--; 2408 } 2409 */ 2410 mLruProcesses.remove(lrui); 2411 } 2412 2413 /* 2414 mLruProcesses.add(addIndex, app); 2415 if (inActivity) { 2416 mLruProcessActivityStart++; 2417 } 2418 if (inService) { 2419 mLruProcessActivityStart++; 2420 } 2421 */ 2422 2423 int nextIndex; 2424 if (hasActivity) { 2425 final int N = mLruProcesses.size(); 2426 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2427 // Process doesn't have activities, but has clients with 2428 // activities... move it up, but one below the top (the top 2429 // should always have a real activity). 2430 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2431 mLruProcesses.add(N-1, app); 2432 // To keep it from spamming the LRU list (by making a bunch of clients), 2433 // we will push down any other entries owned by the app. 2434 final int uid = app.info.uid; 2435 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2436 ProcessRecord subProc = mLruProcesses.get(i); 2437 if (subProc.info.uid == uid) { 2438 // We want to push this one down the list. If the process after 2439 // it is for the same uid, however, don't do so, because we don't 2440 // want them internally to be re-ordered. 2441 if (mLruProcesses.get(i-1).info.uid != uid) { 2442 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2443 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2444 ProcessRecord tmp = mLruProcesses.get(i); 2445 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2446 mLruProcesses.set(i-1, tmp); 2447 i--; 2448 } 2449 } else { 2450 // A gap, we can stop here. 2451 break; 2452 } 2453 } 2454 } else { 2455 // Process has activities, put it at the very tipsy-top. 2456 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2457 mLruProcesses.add(app); 2458 } 2459 nextIndex = mLruProcessServiceStart; 2460 } else if (hasService) { 2461 // Process has services, put it at the top of the service list. 2462 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2463 mLruProcesses.add(mLruProcessActivityStart, app); 2464 nextIndex = mLruProcessServiceStart; 2465 mLruProcessActivityStart++; 2466 } else { 2467 // Process not otherwise of interest, it goes to the top of the non-service area. 2468 int index = mLruProcessServiceStart; 2469 if (client != null) { 2470 // If there is a client, don't allow the process to be moved up higher 2471 // in the list than that client. 2472 int clientIndex = mLruProcesses.lastIndexOf(client); 2473 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2474 + " when updating " + app); 2475 if (clientIndex <= lrui) { 2476 // Don't allow the client index restriction to push it down farther in the 2477 // list than it already is. 2478 clientIndex = lrui; 2479 } 2480 if (clientIndex >= 0 && index > clientIndex) { 2481 index = clientIndex; 2482 } 2483 } 2484 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2485 mLruProcesses.add(index, app); 2486 nextIndex = index-1; 2487 mLruProcessActivityStart++; 2488 mLruProcessServiceStart++; 2489 } 2490 2491 // If the app is currently using a content provider or service, 2492 // bump those processes as well. 2493 for (int j=app.connections.size()-1; j>=0; j--) { 2494 ConnectionRecord cr = app.connections.valueAt(j); 2495 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2496 && cr.binding.service.app != null 2497 && cr.binding.service.app.lruSeq != mLruSeq 2498 && !cr.binding.service.app.persistent) { 2499 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2500 "service connection", cr, app); 2501 } 2502 } 2503 for (int j=app.conProviders.size()-1; j>=0; j--) { 2504 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2505 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2506 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2507 "provider reference", cpr, app); 2508 } 2509 } 2510 } 2511 2512 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2513 if (uid == Process.SYSTEM_UID) { 2514 // The system gets to run in any process. If there are multiple 2515 // processes with the same uid, just pick the first (this 2516 // should never happen). 2517 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2518 if (procs == null) return null; 2519 final int N = procs.size(); 2520 for (int i = 0; i < N; i++) { 2521 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2522 } 2523 } 2524 ProcessRecord proc = mProcessNames.get(processName, uid); 2525 if (false && proc != null && !keepIfLarge 2526 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2527 && proc.lastCachedPss >= 4000) { 2528 // Turn this condition on to cause killing to happen regularly, for testing. 2529 if (proc.baseProcessTracker != null) { 2530 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2531 } 2532 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2533 + "k from cached"); 2534 } else if (proc != null && !keepIfLarge 2535 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2536 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2537 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2538 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2539 if (proc.baseProcessTracker != null) { 2540 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2541 } 2542 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2543 + "k from cached"); 2544 } 2545 } 2546 return proc; 2547 } 2548 2549 void ensurePackageDexOpt(String packageName) { 2550 IPackageManager pm = AppGlobals.getPackageManager(); 2551 try { 2552 if (pm.performDexOpt(packageName)) { 2553 mDidDexOpt = true; 2554 } 2555 } catch (RemoteException e) { 2556 } 2557 } 2558 2559 boolean isNextTransitionForward() { 2560 int transit = mWindowManager.getPendingAppTransition(); 2561 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2562 || transit == AppTransition.TRANSIT_TASK_OPEN 2563 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2564 } 2565 2566 final ProcessRecord startProcessLocked(String processName, 2567 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2568 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2569 boolean isolated, boolean keepIfLarge) { 2570 ProcessRecord app; 2571 if (!isolated) { 2572 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2573 } else { 2574 // If this is an isolated process, it can't re-use an existing process. 2575 app = null; 2576 } 2577 // We don't have to do anything more if: 2578 // (1) There is an existing application record; and 2579 // (2) The caller doesn't think it is dead, OR there is no thread 2580 // object attached to it so we know it couldn't have crashed; and 2581 // (3) There is a pid assigned to it, so it is either starting or 2582 // already running. 2583 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2584 + " app=" + app + " knownToBeDead=" + knownToBeDead 2585 + " thread=" + (app != null ? app.thread : null) 2586 + " pid=" + (app != null ? app.pid : -1)); 2587 if (app != null && app.pid > 0) { 2588 if (!knownToBeDead || app.thread == null) { 2589 // We already have the app running, or are waiting for it to 2590 // come up (we have a pid but not yet its thread), so keep it. 2591 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2592 // If this is a new package in the process, add the package to the list 2593 app.addPackage(info.packageName, mProcessStats); 2594 return app; 2595 } 2596 2597 // An application record is attached to a previous process, 2598 // clean it up now. 2599 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2600 handleAppDiedLocked(app, true, true); 2601 } 2602 2603 String hostingNameStr = hostingName != null 2604 ? hostingName.flattenToShortString() : null; 2605 2606 if (!isolated) { 2607 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2608 // If we are in the background, then check to see if this process 2609 // is bad. If so, we will just silently fail. 2610 if (mBadProcesses.get(info.processName, info.uid) != null) { 2611 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2612 + "/" + info.processName); 2613 return null; 2614 } 2615 } else { 2616 // When the user is explicitly starting a process, then clear its 2617 // crash count so that we won't make it bad until they see at 2618 // least one crash dialog again, and make the process good again 2619 // if it had been bad. 2620 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2621 + "/" + info.processName); 2622 mProcessCrashTimes.remove(info.processName, info.uid); 2623 if (mBadProcesses.get(info.processName, info.uid) != null) { 2624 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2625 UserHandle.getUserId(info.uid), info.uid, 2626 info.processName); 2627 mBadProcesses.remove(info.processName, info.uid); 2628 if (app != null) { 2629 app.bad = false; 2630 } 2631 } 2632 } 2633 } 2634 2635 if (app == null) { 2636 app = newProcessRecordLocked(info, processName, isolated); 2637 if (app == null) { 2638 Slog.w(TAG, "Failed making new process record for " 2639 + processName + "/" + info.uid + " isolated=" + isolated); 2640 return null; 2641 } 2642 mProcessNames.put(processName, app.uid, app); 2643 if (isolated) { 2644 mIsolatedProcesses.put(app.uid, app); 2645 } 2646 } else { 2647 // If this is a new package in the process, add the package to the list 2648 app.addPackage(info.packageName, mProcessStats); 2649 } 2650 2651 // If the system is not ready yet, then hold off on starting this 2652 // process until it is. 2653 if (!mProcessesReady 2654 && !isAllowedWhileBooting(info) 2655 && !allowWhileBooting) { 2656 if (!mProcessesOnHold.contains(app)) { 2657 mProcessesOnHold.add(app); 2658 } 2659 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2660 return app; 2661 } 2662 2663 startProcessLocked(app, hostingType, hostingNameStr); 2664 return (app.pid != 0) ? app : null; 2665 } 2666 2667 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2668 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2669 } 2670 2671 private final void startProcessLocked(ProcessRecord app, 2672 String hostingType, String hostingNameStr) { 2673 if (app.pid > 0 && app.pid != MY_PID) { 2674 synchronized (mPidsSelfLocked) { 2675 mPidsSelfLocked.remove(app.pid); 2676 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2677 } 2678 app.setPid(0); 2679 } 2680 2681 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2682 "startProcessLocked removing on hold: " + app); 2683 mProcessesOnHold.remove(app); 2684 2685 updateCpuStats(); 2686 2687 try { 2688 int uid = app.uid; 2689 2690 int[] gids = null; 2691 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2692 if (!app.isolated) { 2693 int[] permGids = null; 2694 try { 2695 final PackageManager pm = mContext.getPackageManager(); 2696 permGids = pm.getPackageGids(app.info.packageName); 2697 2698 if (Environment.isExternalStorageEmulated()) { 2699 if (pm.checkPermission( 2700 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2701 app.info.packageName) == PERMISSION_GRANTED) { 2702 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2703 } else { 2704 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2705 } 2706 } 2707 } catch (PackageManager.NameNotFoundException e) { 2708 Slog.w(TAG, "Unable to retrieve gids", e); 2709 } 2710 2711 /* 2712 * Add shared application GID so applications can share some 2713 * resources like shared libraries 2714 */ 2715 if (permGids == null) { 2716 gids = new int[1]; 2717 } else { 2718 gids = new int[permGids.length + 1]; 2719 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2720 } 2721 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2722 } 2723 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2724 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2725 && mTopComponent != null 2726 && app.processName.equals(mTopComponent.getPackageName())) { 2727 uid = 0; 2728 } 2729 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2730 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2731 uid = 0; 2732 } 2733 } 2734 int debugFlags = 0; 2735 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2736 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2737 // Also turn on CheckJNI for debuggable apps. It's quite 2738 // awkward to turn on otherwise. 2739 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2740 } 2741 // Run the app in safe mode if its manifest requests so or the 2742 // system is booted in safe mode. 2743 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2744 mSafeMode == true) { 2745 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2746 } 2747 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2748 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2749 } 2750 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2751 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2752 } 2753 if ("1".equals(SystemProperties.get("debug.assert"))) { 2754 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2755 } 2756 2757 // Start the process. It will either succeed and return a result containing 2758 // the PID of the new process, or else throw a RuntimeException. 2759 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2760 app.processName, uid, uid, gids, debugFlags, mountExternal, 2761 app.info.targetSdkVersion, app.info.seinfo, null); 2762 2763 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2764 synchronized (bs) { 2765 if (bs.isOnBattery()) { 2766 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2767 } 2768 } 2769 2770 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2771 UserHandle.getUserId(uid), startResult.pid, uid, 2772 app.processName, hostingType, 2773 hostingNameStr != null ? hostingNameStr : ""); 2774 2775 if (app.persistent) { 2776 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2777 } 2778 2779 StringBuilder buf = mStringBuilder; 2780 buf.setLength(0); 2781 buf.append("Start proc "); 2782 buf.append(app.processName); 2783 buf.append(" for "); 2784 buf.append(hostingType); 2785 if (hostingNameStr != null) { 2786 buf.append(" "); 2787 buf.append(hostingNameStr); 2788 } 2789 buf.append(": pid="); 2790 buf.append(startResult.pid); 2791 buf.append(" uid="); 2792 buf.append(uid); 2793 buf.append(" gids={"); 2794 if (gids != null) { 2795 for (int gi=0; gi<gids.length; gi++) { 2796 if (gi != 0) buf.append(", "); 2797 buf.append(gids[gi]); 2798 2799 } 2800 } 2801 buf.append("}"); 2802 Slog.i(TAG, buf.toString()); 2803 app.setPid(startResult.pid); 2804 app.usingWrapper = startResult.usingWrapper; 2805 app.removed = false; 2806 synchronized (mPidsSelfLocked) { 2807 this.mPidsSelfLocked.put(startResult.pid, app); 2808 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2809 msg.obj = app; 2810 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2811 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2812 } 2813 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2814 app.processName, app.info.uid); 2815 if (app.isolated) { 2816 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2817 } 2818 } catch (RuntimeException e) { 2819 // XXX do better error recovery. 2820 app.setPid(0); 2821 Slog.e(TAG, "Failure starting process " + app.processName, e); 2822 } 2823 } 2824 2825 void updateUsageStats(ActivityRecord component, boolean resumed) { 2826 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2827 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2828 if (resumed) { 2829 mUsageStatsService.noteResumeComponent(component.realActivity); 2830 synchronized (stats) { 2831 stats.noteActivityResumedLocked(component.app.uid); 2832 } 2833 } else { 2834 mUsageStatsService.notePauseComponent(component.realActivity); 2835 synchronized (stats) { 2836 stats.noteActivityPausedLocked(component.app.uid); 2837 } 2838 } 2839 } 2840 2841 Intent getHomeIntent() { 2842 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2843 intent.setComponent(mTopComponent); 2844 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2845 intent.addCategory(Intent.CATEGORY_HOME); 2846 } 2847 return intent; 2848 } 2849 2850 boolean startHomeActivityLocked(int userId) { 2851 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2852 && mTopAction == null) { 2853 // We are running in factory test mode, but unable to find 2854 // the factory test app, so just sit around displaying the 2855 // error message and don't try to start anything. 2856 return false; 2857 } 2858 Intent intent = getHomeIntent(); 2859 ActivityInfo aInfo = 2860 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2861 if (aInfo != null) { 2862 intent.setComponent(new ComponentName( 2863 aInfo.applicationInfo.packageName, aInfo.name)); 2864 // Don't do this if the home app is currently being 2865 // instrumented. 2866 aInfo = new ActivityInfo(aInfo); 2867 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2868 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2869 aInfo.applicationInfo.uid, true); 2870 if (app == null || app.instrumentationClass == null) { 2871 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2872 mStackSupervisor.startHomeActivity(intent, aInfo); 2873 } 2874 } 2875 2876 return true; 2877 } 2878 2879 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2880 ActivityInfo ai = null; 2881 ComponentName comp = intent.getComponent(); 2882 try { 2883 if (comp != null) { 2884 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2885 } else { 2886 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2887 intent, 2888 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2889 flags, userId); 2890 2891 if (info != null) { 2892 ai = info.activityInfo; 2893 } 2894 } 2895 } catch (RemoteException e) { 2896 // ignore 2897 } 2898 2899 return ai; 2900 } 2901 2902 /** 2903 * Starts the "new version setup screen" if appropriate. 2904 */ 2905 void startSetupActivityLocked() { 2906 // Only do this once per boot. 2907 if (mCheckedForSetup) { 2908 return; 2909 } 2910 2911 // We will show this screen if the current one is a different 2912 // version than the last one shown, and we are not running in 2913 // low-level factory test mode. 2914 final ContentResolver resolver = mContext.getContentResolver(); 2915 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2916 Settings.Global.getInt(resolver, 2917 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2918 mCheckedForSetup = true; 2919 2920 // See if we should be showing the platform update setup UI. 2921 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2922 List<ResolveInfo> ris = mContext.getPackageManager() 2923 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2924 2925 // We don't allow third party apps to replace this. 2926 ResolveInfo ri = null; 2927 for (int i=0; ris != null && i<ris.size(); i++) { 2928 if ((ris.get(i).activityInfo.applicationInfo.flags 2929 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2930 ri = ris.get(i); 2931 break; 2932 } 2933 } 2934 2935 if (ri != null) { 2936 String vers = ri.activityInfo.metaData != null 2937 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2938 : null; 2939 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2940 vers = ri.activityInfo.applicationInfo.metaData.getString( 2941 Intent.METADATA_SETUP_VERSION); 2942 } 2943 String lastVers = Settings.Secure.getString( 2944 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2945 if (vers != null && !vers.equals(lastVers)) { 2946 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2947 intent.setComponent(new ComponentName( 2948 ri.activityInfo.packageName, ri.activityInfo.name)); 2949 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2950 null, null, 0, 0, 0, null, 0, null, false, null, null); 2951 } 2952 } 2953 } 2954 } 2955 2956 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2957 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2958 } 2959 2960 void enforceNotIsolatedCaller(String caller) { 2961 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2962 throw new SecurityException("Isolated process not allowed to call " + caller); 2963 } 2964 } 2965 2966 @Override 2967 public int getFrontActivityScreenCompatMode() { 2968 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2969 synchronized (this) { 2970 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2971 } 2972 } 2973 2974 @Override 2975 public void setFrontActivityScreenCompatMode(int mode) { 2976 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2977 "setFrontActivityScreenCompatMode"); 2978 synchronized (this) { 2979 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2980 } 2981 } 2982 2983 @Override 2984 public int getPackageScreenCompatMode(String packageName) { 2985 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2986 synchronized (this) { 2987 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2988 } 2989 } 2990 2991 @Override 2992 public void setPackageScreenCompatMode(String packageName, int mode) { 2993 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2994 "setPackageScreenCompatMode"); 2995 synchronized (this) { 2996 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2997 } 2998 } 2999 3000 @Override 3001 public boolean getPackageAskScreenCompat(String packageName) { 3002 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3003 synchronized (this) { 3004 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3005 } 3006 } 3007 3008 @Override 3009 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3010 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3011 "setPackageAskScreenCompat"); 3012 synchronized (this) { 3013 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3014 } 3015 } 3016 3017 private void dispatchProcessesChanged() { 3018 int N; 3019 synchronized (this) { 3020 N = mPendingProcessChanges.size(); 3021 if (mActiveProcessChanges.length < N) { 3022 mActiveProcessChanges = new ProcessChangeItem[N]; 3023 } 3024 mPendingProcessChanges.toArray(mActiveProcessChanges); 3025 mAvailProcessChanges.addAll(mPendingProcessChanges); 3026 mPendingProcessChanges.clear(); 3027 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3028 } 3029 3030 int i = mProcessObservers.beginBroadcast(); 3031 while (i > 0) { 3032 i--; 3033 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3034 if (observer != null) { 3035 try { 3036 for (int j=0; j<N; j++) { 3037 ProcessChangeItem item = mActiveProcessChanges[j]; 3038 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3039 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3040 + item.pid + " uid=" + item.uid + ": " 3041 + item.foregroundActivities); 3042 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3043 item.foregroundActivities); 3044 } 3045 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3046 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3047 + item.pid + " uid=" + item.uid + ": " + item.importance); 3048 observer.onImportanceChanged(item.pid, item.uid, 3049 item.importance); 3050 } 3051 } 3052 } catch (RemoteException e) { 3053 } 3054 } 3055 } 3056 mProcessObservers.finishBroadcast(); 3057 } 3058 3059 private void dispatchProcessDied(int pid, int uid) { 3060 int i = mProcessObservers.beginBroadcast(); 3061 while (i > 0) { 3062 i--; 3063 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3064 if (observer != null) { 3065 try { 3066 observer.onProcessDied(pid, uid); 3067 } catch (RemoteException e) { 3068 } 3069 } 3070 } 3071 mProcessObservers.finishBroadcast(); 3072 } 3073 3074 final void doPendingActivityLaunchesLocked(boolean doResume) { 3075 final int N = mPendingActivityLaunches.size(); 3076 if (N <= 0) { 3077 return; 3078 } 3079 for (int i=0; i<N; i++) { 3080 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3081 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3082 doResume && i == (N-1), null); 3083 } 3084 mPendingActivityLaunches.clear(); 3085 } 3086 3087 @Override 3088 public final int startActivity(IApplicationThread caller, String callingPackage, 3089 Intent intent, String resolvedType, IBinder resultTo, 3090 String resultWho, int requestCode, int startFlags, 3091 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3092 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3093 resultWho, requestCode, 3094 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3095 } 3096 3097 @Override 3098 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3099 Intent intent, String resolvedType, IBinder resultTo, 3100 String resultWho, int requestCode, int startFlags, 3101 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3102 enforceNotIsolatedCaller("startActivity"); 3103 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3104 false, true, "startActivity", null); 3105 // TODO: Switch to user app stacks here. 3106 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3107 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3108 null, null, options, userId, null); 3109 } 3110 3111 @Override 3112 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3113 Intent intent, String resolvedType, IBinder resultTo, 3114 String resultWho, int requestCode, int startFlags, String profileFile, 3115 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3116 enforceNotIsolatedCaller("startActivityAndWait"); 3117 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3118 false, true, "startActivityAndWait", null); 3119 WaitResult res = new WaitResult(); 3120 // TODO: Switch to user app stacks here. 3121 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3122 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3123 res, null, options, UserHandle.getCallingUserId(), null); 3124 return res; 3125 } 3126 3127 @Override 3128 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3129 Intent intent, String resolvedType, IBinder resultTo, 3130 String resultWho, int requestCode, int startFlags, Configuration config, 3131 Bundle options, int userId) { 3132 enforceNotIsolatedCaller("startActivityWithConfig"); 3133 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3134 false, true, "startActivityWithConfig", null); 3135 // TODO: Switch to user app stacks here. 3136 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3137 resolvedType, resultTo, resultWho, requestCode, startFlags, 3138 null, null, null, config, options, userId, null); 3139 return ret; 3140 } 3141 3142 @Override 3143 public int startActivityIntentSender(IApplicationThread caller, 3144 IntentSender intent, Intent fillInIntent, String resolvedType, 3145 IBinder resultTo, String resultWho, int requestCode, 3146 int flagsMask, int flagsValues, Bundle options) { 3147 enforceNotIsolatedCaller("startActivityIntentSender"); 3148 // Refuse possible leaked file descriptors 3149 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3150 throw new IllegalArgumentException("File descriptors passed in Intent"); 3151 } 3152 3153 IIntentSender sender = intent.getTarget(); 3154 if (!(sender instanceof PendingIntentRecord)) { 3155 throw new IllegalArgumentException("Bad PendingIntent object"); 3156 } 3157 3158 PendingIntentRecord pir = (PendingIntentRecord)sender; 3159 3160 synchronized (this) { 3161 // If this is coming from the currently resumed activity, it is 3162 // effectively saying that app switches are allowed at this point. 3163 final ActivityStack stack = getFocusedStack(); 3164 if (stack.mResumedActivity != null && 3165 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3166 mAppSwitchesAllowedTime = 0; 3167 } 3168 } 3169 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3170 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3171 return ret; 3172 } 3173 3174 @Override 3175 public boolean startNextMatchingActivity(IBinder callingActivity, 3176 Intent intent, Bundle options) { 3177 // Refuse possible leaked file descriptors 3178 if (intent != null && intent.hasFileDescriptors() == true) { 3179 throw new IllegalArgumentException("File descriptors passed in Intent"); 3180 } 3181 3182 synchronized (this) { 3183 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3184 if (r == null) { 3185 ActivityOptions.abort(options); 3186 return false; 3187 } 3188 if (r.app == null || r.app.thread == null) { 3189 // The caller is not running... d'oh! 3190 ActivityOptions.abort(options); 3191 return false; 3192 } 3193 intent = new Intent(intent); 3194 // The caller is not allowed to change the data. 3195 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3196 // And we are resetting to find the next component... 3197 intent.setComponent(null); 3198 3199 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3200 3201 ActivityInfo aInfo = null; 3202 try { 3203 List<ResolveInfo> resolves = 3204 AppGlobals.getPackageManager().queryIntentActivities( 3205 intent, r.resolvedType, 3206 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3207 UserHandle.getCallingUserId()); 3208 3209 // Look for the original activity in the list... 3210 final int N = resolves != null ? resolves.size() : 0; 3211 for (int i=0; i<N; i++) { 3212 ResolveInfo rInfo = resolves.get(i); 3213 if (rInfo.activityInfo.packageName.equals(r.packageName) 3214 && rInfo.activityInfo.name.equals(r.info.name)) { 3215 // We found the current one... the next matching is 3216 // after it. 3217 i++; 3218 if (i<N) { 3219 aInfo = resolves.get(i).activityInfo; 3220 } 3221 if (debug) { 3222 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3223 + "/" + r.info.name); 3224 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3225 + "/" + aInfo.name); 3226 } 3227 break; 3228 } 3229 } 3230 } catch (RemoteException e) { 3231 } 3232 3233 if (aInfo == null) { 3234 // Nobody who is next! 3235 ActivityOptions.abort(options); 3236 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3237 return false; 3238 } 3239 3240 intent.setComponent(new ComponentName( 3241 aInfo.applicationInfo.packageName, aInfo.name)); 3242 intent.setFlags(intent.getFlags()&~( 3243 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3244 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3245 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3246 Intent.FLAG_ACTIVITY_NEW_TASK)); 3247 3248 // Okay now we need to start the new activity, replacing the 3249 // currently running activity. This is a little tricky because 3250 // we want to start the new one as if the current one is finished, 3251 // but not finish the current one first so that there is no flicker. 3252 // And thus... 3253 final boolean wasFinishing = r.finishing; 3254 r.finishing = true; 3255 3256 // Propagate reply information over to the new activity. 3257 final ActivityRecord resultTo = r.resultTo; 3258 final String resultWho = r.resultWho; 3259 final int requestCode = r.requestCode; 3260 r.resultTo = null; 3261 if (resultTo != null) { 3262 resultTo.removeResultsLocked(r, resultWho, requestCode); 3263 } 3264 3265 final long origId = Binder.clearCallingIdentity(); 3266 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3267 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3268 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3269 options, false, null, null); 3270 Binder.restoreCallingIdentity(origId); 3271 3272 r.finishing = wasFinishing; 3273 if (res != ActivityManager.START_SUCCESS) { 3274 return false; 3275 } 3276 return true; 3277 } 3278 } 3279 3280 final int startActivityInPackage(int uid, String callingPackage, 3281 Intent intent, String resolvedType, IBinder resultTo, 3282 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3283 IActivityContainer container) { 3284 3285 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3286 false, true, "startActivityInPackage", null); 3287 3288 // TODO: Switch to user app stacks here. 3289 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3290 resultTo, resultWho, requestCode, startFlags, 3291 null, null, null, null, options, userId, container); 3292 return ret; 3293 } 3294 3295 @Override 3296 public final int startActivities(IApplicationThread caller, String callingPackage, 3297 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3298 int userId) { 3299 enforceNotIsolatedCaller("startActivities"); 3300 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3301 false, true, "startActivity", null); 3302 // TODO: Switch to user app stacks here. 3303 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3304 resolvedTypes, resultTo, options, userId); 3305 return ret; 3306 } 3307 3308 final int startActivitiesInPackage(int uid, String callingPackage, 3309 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3310 Bundle options, int userId) { 3311 3312 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3313 false, true, "startActivityInPackage", null); 3314 // TODO: Switch to user app stacks here. 3315 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3316 resultTo, options, userId); 3317 return ret; 3318 } 3319 3320 final void addRecentTaskLocked(TaskRecord task) { 3321 int N = mRecentTasks.size(); 3322 // Quick case: check if the top-most recent task is the same. 3323 if (N > 0 && mRecentTasks.get(0) == task) { 3324 return; 3325 } 3326 // Remove any existing entries that are the same kind of task. 3327 final Intent intent = task.intent; 3328 final boolean document = intent != null && intent.isDocument(); 3329 for (int i=0; i<N; i++) { 3330 TaskRecord tr = mRecentTasks.get(i); 3331 if (task != tr) { 3332 if (task.userId != tr.userId) { 3333 continue; 3334 } 3335 final Intent trIntent = tr.intent; 3336 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3337 (intent == null || !intent.filterEquals(trIntent))) { 3338 continue; 3339 } 3340 if (document || trIntent != null && trIntent.isDocument()) { 3341 // Document tasks do not match other tasks. 3342 continue; 3343 } 3344 } 3345 3346 // Either task and tr are the same or, their affinities match or their intents match 3347 // and neither of them is a document. 3348 tr.disposeThumbnail(); 3349 mRecentTasks.remove(i); 3350 i--; 3351 N--; 3352 if (task.intent == null) { 3353 // If the new recent task we are adding is not fully 3354 // specified, then replace it with the existing recent task. 3355 task = tr; 3356 } 3357 } 3358 if (N >= MAX_RECENT_TASKS) { 3359 mRecentTasks.remove(N-1).disposeThumbnail(); 3360 } 3361 mRecentTasks.add(0, task); 3362 } 3363 3364 @Override 3365 public void reportActivityFullyDrawn(IBinder token) { 3366 synchronized (this) { 3367 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3368 if (r == null) { 3369 return; 3370 } 3371 r.reportFullyDrawnLocked(); 3372 } 3373 } 3374 3375 @Override 3376 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3377 synchronized (this) { 3378 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3379 if (r == null) { 3380 return; 3381 } 3382 final long origId = Binder.clearCallingIdentity(); 3383 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3384 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3385 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3386 if (config != null) { 3387 r.frozenBeforeDestroy = true; 3388 if (!updateConfigurationLocked(config, r, false, false)) { 3389 mStackSupervisor.resumeTopActivitiesLocked(); 3390 } 3391 } 3392 Binder.restoreCallingIdentity(origId); 3393 } 3394 } 3395 3396 @Override 3397 public int getRequestedOrientation(IBinder token) { 3398 synchronized (this) { 3399 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3400 if (r == null) { 3401 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3402 } 3403 return mWindowManager.getAppOrientation(r.appToken); 3404 } 3405 } 3406 3407 /** 3408 * This is the internal entry point for handling Activity.finish(). 3409 * 3410 * @param token The Binder token referencing the Activity we want to finish. 3411 * @param resultCode Result code, if any, from this Activity. 3412 * @param resultData Result data (Intent), if any, from this Activity. 3413 * 3414 * @return Returns true if the activity successfully finished, or false if it is still running. 3415 */ 3416 @Override 3417 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3418 // Refuse possible leaked file descriptors 3419 if (resultData != null && resultData.hasFileDescriptors() == true) { 3420 throw new IllegalArgumentException("File descriptors passed in Intent"); 3421 } 3422 3423 synchronized(this) { 3424 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3425 if (r == null) { 3426 return true; 3427 } 3428 if (mController != null) { 3429 // Find the first activity that is not finishing. 3430 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3431 if (next != null) { 3432 // ask watcher if this is allowed 3433 boolean resumeOK = true; 3434 try { 3435 resumeOK = mController.activityResuming(next.packageName); 3436 } catch (RemoteException e) { 3437 mController = null; 3438 Watchdog.getInstance().setActivityController(null); 3439 } 3440 3441 if (!resumeOK) { 3442 return false; 3443 } 3444 } 3445 } 3446 final long origId = Binder.clearCallingIdentity(); 3447 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3448 resultData, "app-request", true); 3449 Binder.restoreCallingIdentity(origId); 3450 return res; 3451 } 3452 } 3453 3454 @Override 3455 public final void finishHeavyWeightApp() { 3456 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3457 != PackageManager.PERMISSION_GRANTED) { 3458 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3459 + Binder.getCallingPid() 3460 + ", uid=" + Binder.getCallingUid() 3461 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3462 Slog.w(TAG, msg); 3463 throw new SecurityException(msg); 3464 } 3465 3466 synchronized(this) { 3467 if (mHeavyWeightProcess == null) { 3468 return; 3469 } 3470 3471 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3472 mHeavyWeightProcess.activities); 3473 for (int i=0; i<activities.size(); i++) { 3474 ActivityRecord r = activities.get(i); 3475 if (!r.finishing) { 3476 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3477 null, "finish-heavy", true); 3478 } 3479 } 3480 3481 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3482 mHeavyWeightProcess.userId, 0)); 3483 mHeavyWeightProcess = null; 3484 } 3485 } 3486 3487 @Override 3488 public void crashApplication(int uid, int initialPid, String packageName, 3489 String message) { 3490 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3491 != PackageManager.PERMISSION_GRANTED) { 3492 String msg = "Permission Denial: crashApplication() from pid=" 3493 + Binder.getCallingPid() 3494 + ", uid=" + Binder.getCallingUid() 3495 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3496 Slog.w(TAG, msg); 3497 throw new SecurityException(msg); 3498 } 3499 3500 synchronized(this) { 3501 ProcessRecord proc = null; 3502 3503 // Figure out which process to kill. We don't trust that initialPid 3504 // still has any relation to current pids, so must scan through the 3505 // list. 3506 synchronized (mPidsSelfLocked) { 3507 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3508 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3509 if (p.uid != uid) { 3510 continue; 3511 } 3512 if (p.pid == initialPid) { 3513 proc = p; 3514 break; 3515 } 3516 if (p.pkgList.containsKey(packageName)) { 3517 proc = p; 3518 } 3519 } 3520 } 3521 3522 if (proc == null) { 3523 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3524 + " initialPid=" + initialPid 3525 + " packageName=" + packageName); 3526 return; 3527 } 3528 3529 if (proc.thread != null) { 3530 if (proc.pid == Process.myPid()) { 3531 Log.w(TAG, "crashApplication: trying to crash self!"); 3532 return; 3533 } 3534 long ident = Binder.clearCallingIdentity(); 3535 try { 3536 proc.thread.scheduleCrash(message); 3537 } catch (RemoteException e) { 3538 } 3539 Binder.restoreCallingIdentity(ident); 3540 } 3541 } 3542 } 3543 3544 @Override 3545 public final void finishSubActivity(IBinder token, String resultWho, 3546 int requestCode) { 3547 synchronized(this) { 3548 final long origId = Binder.clearCallingIdentity(); 3549 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3550 if (r != null) { 3551 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3552 } 3553 Binder.restoreCallingIdentity(origId); 3554 } 3555 } 3556 3557 @Override 3558 public boolean finishActivityAffinity(IBinder token) { 3559 synchronized(this) { 3560 final long origId = Binder.clearCallingIdentity(); 3561 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3562 boolean res = false; 3563 if (r != null) { 3564 res = r.task.stack.finishActivityAffinityLocked(r); 3565 } 3566 Binder.restoreCallingIdentity(origId); 3567 return res; 3568 } 3569 } 3570 3571 @Override 3572 public boolean willActivityBeVisible(IBinder token) { 3573 synchronized(this) { 3574 ActivityStack stack = ActivityRecord.getStackLocked(token); 3575 if (stack != null) { 3576 return stack.willActivityBeVisibleLocked(token); 3577 } 3578 return false; 3579 } 3580 } 3581 3582 @Override 3583 public void overridePendingTransition(IBinder token, String packageName, 3584 int enterAnim, int exitAnim) { 3585 synchronized(this) { 3586 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3587 if (self == null) { 3588 return; 3589 } 3590 3591 final long origId = Binder.clearCallingIdentity(); 3592 3593 if (self.state == ActivityState.RESUMED 3594 || self.state == ActivityState.PAUSING) { 3595 mWindowManager.overridePendingAppTransition(packageName, 3596 enterAnim, exitAnim, null); 3597 } 3598 3599 Binder.restoreCallingIdentity(origId); 3600 } 3601 } 3602 3603 /** 3604 * Main function for removing an existing process from the activity manager 3605 * as a result of that process going away. Clears out all connections 3606 * to the process. 3607 */ 3608 private final void handleAppDiedLocked(ProcessRecord app, 3609 boolean restarting, boolean allowRestart) { 3610 int pid = app.pid; 3611 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3612 if (!restarting) { 3613 removeLruProcessLocked(app); 3614 if (pid > 0) { 3615 ProcessList.remove(pid); 3616 } 3617 } 3618 3619 if (mProfileProc == app) { 3620 clearProfilerLocked(); 3621 } 3622 3623 // Remove this application's activities from active lists. 3624 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3625 3626 app.activities.clear(); 3627 3628 if (app.instrumentationClass != null) { 3629 Slog.w(TAG, "Crash of app " + app.processName 3630 + " running instrumentation " + app.instrumentationClass); 3631 Bundle info = new Bundle(); 3632 info.putString("shortMsg", "Process crashed."); 3633 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3634 } 3635 3636 if (!restarting) { 3637 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3638 // If there was nothing to resume, and we are not already 3639 // restarting this process, but there is a visible activity that 3640 // is hosted by the process... then make sure all visible 3641 // activities are running, taking care of restarting this 3642 // process. 3643 if (hasVisibleActivities) { 3644 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3645 } 3646 } 3647 } 3648 } 3649 3650 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3651 IBinder threadBinder = thread.asBinder(); 3652 // Find the application record. 3653 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3654 ProcessRecord rec = mLruProcesses.get(i); 3655 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3656 return i; 3657 } 3658 } 3659 return -1; 3660 } 3661 3662 final ProcessRecord getRecordForAppLocked( 3663 IApplicationThread thread) { 3664 if (thread == null) { 3665 return null; 3666 } 3667 3668 int appIndex = getLRURecordIndexForAppLocked(thread); 3669 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3670 } 3671 3672 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3673 // If there are no longer any background processes running, 3674 // and the app that died was not running instrumentation, 3675 // then tell everyone we are now low on memory. 3676 boolean haveBg = false; 3677 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3678 ProcessRecord rec = mLruProcesses.get(i); 3679 if (rec.thread != null 3680 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3681 haveBg = true; 3682 break; 3683 } 3684 } 3685 3686 if (!haveBg) { 3687 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3688 if (doReport) { 3689 long now = SystemClock.uptimeMillis(); 3690 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3691 doReport = false; 3692 } else { 3693 mLastMemUsageReportTime = now; 3694 } 3695 } 3696 final ArrayList<ProcessMemInfo> memInfos 3697 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3698 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3699 long now = SystemClock.uptimeMillis(); 3700 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3701 ProcessRecord rec = mLruProcesses.get(i); 3702 if (rec == dyingProc || rec.thread == null) { 3703 continue; 3704 } 3705 if (doReport) { 3706 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3707 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3708 } 3709 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3710 // The low memory report is overriding any current 3711 // state for a GC request. Make sure to do 3712 // heavy/important/visible/foreground processes first. 3713 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3714 rec.lastRequestedGc = 0; 3715 } else { 3716 rec.lastRequestedGc = rec.lastLowMemory; 3717 } 3718 rec.reportLowMemory = true; 3719 rec.lastLowMemory = now; 3720 mProcessesToGc.remove(rec); 3721 addProcessToGcListLocked(rec); 3722 } 3723 } 3724 if (doReport) { 3725 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3726 mHandler.sendMessage(msg); 3727 } 3728 scheduleAppGcsLocked(); 3729 } 3730 } 3731 3732 final void appDiedLocked(ProcessRecord app, int pid, 3733 IApplicationThread thread) { 3734 3735 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3736 synchronized (stats) { 3737 stats.noteProcessDiedLocked(app.info.uid, pid); 3738 } 3739 3740 // Clean up already done if the process has been re-started. 3741 if (app.pid == pid && app.thread != null && 3742 app.thread.asBinder() == thread.asBinder()) { 3743 boolean doLowMem = app.instrumentationClass == null; 3744 boolean doOomAdj = doLowMem; 3745 if (!app.killedByAm) { 3746 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3747 + ") has died."); 3748 mAllowLowerMemLevel = true; 3749 } else { 3750 // Note that we always want to do oom adj to update our state with the 3751 // new number of procs. 3752 mAllowLowerMemLevel = false; 3753 doLowMem = false; 3754 } 3755 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3756 if (DEBUG_CLEANUP) Slog.v( 3757 TAG, "Dying app: " + app + ", pid: " + pid 3758 + ", thread: " + thread.asBinder()); 3759 handleAppDiedLocked(app, false, true); 3760 3761 if (doOomAdj) { 3762 updateOomAdjLocked(); 3763 } 3764 if (doLowMem) { 3765 doLowMemReportIfNeededLocked(app); 3766 } 3767 } else if (app.pid != pid) { 3768 // A new process has already been started. 3769 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3770 + ") has died and restarted (pid " + app.pid + ")."); 3771 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3772 } else if (DEBUG_PROCESSES) { 3773 Slog.d(TAG, "Received spurious death notification for thread " 3774 + thread.asBinder()); 3775 } 3776 } 3777 3778 /** 3779 * If a stack trace dump file is configured, dump process stack traces. 3780 * @param clearTraces causes the dump file to be erased prior to the new 3781 * traces being written, if true; when false, the new traces will be 3782 * appended to any existing file content. 3783 * @param firstPids of dalvik VM processes to dump stack traces for first 3784 * @param lastPids of dalvik VM processes to dump stack traces for last 3785 * @param nativeProcs optional list of native process names to dump stack crawls 3786 * @return file containing stack traces, or null if no dump file is configured 3787 */ 3788 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3789 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3790 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3791 if (tracesPath == null || tracesPath.length() == 0) { 3792 return null; 3793 } 3794 3795 File tracesFile = new File(tracesPath); 3796 try { 3797 File tracesDir = tracesFile.getParentFile(); 3798 if (!tracesDir.exists()) { 3799 tracesFile.mkdirs(); 3800 if (!SELinux.restorecon(tracesDir)) { 3801 return null; 3802 } 3803 } 3804 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3805 3806 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3807 tracesFile.createNewFile(); 3808 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3809 } catch (IOException e) { 3810 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3811 return null; 3812 } 3813 3814 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3815 return tracesFile; 3816 } 3817 3818 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3819 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3820 // Use a FileObserver to detect when traces finish writing. 3821 // The order of traces is considered important to maintain for legibility. 3822 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3823 @Override 3824 public synchronized void onEvent(int event, String path) { notify(); } 3825 }; 3826 3827 try { 3828 observer.startWatching(); 3829 3830 // First collect all of the stacks of the most important pids. 3831 if (firstPids != null) { 3832 try { 3833 int num = firstPids.size(); 3834 for (int i = 0; i < num; i++) { 3835 synchronized (observer) { 3836 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3837 observer.wait(200); // Wait for write-close, give up after 200msec 3838 } 3839 } 3840 } catch (InterruptedException e) { 3841 Log.wtf(TAG, e); 3842 } 3843 } 3844 3845 // Next collect the stacks of the native pids 3846 if (nativeProcs != null) { 3847 int[] pids = Process.getPidsForCommands(nativeProcs); 3848 if (pids != null) { 3849 for (int pid : pids) { 3850 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3851 } 3852 } 3853 } 3854 3855 // Lastly, measure CPU usage. 3856 if (processCpuTracker != null) { 3857 processCpuTracker.init(); 3858 System.gc(); 3859 processCpuTracker.update(); 3860 try { 3861 synchronized (processCpuTracker) { 3862 processCpuTracker.wait(500); // measure over 1/2 second. 3863 } 3864 } catch (InterruptedException e) { 3865 } 3866 processCpuTracker.update(); 3867 3868 // We'll take the stack crawls of just the top apps using CPU. 3869 final int N = processCpuTracker.countWorkingStats(); 3870 int numProcs = 0; 3871 for (int i=0; i<N && numProcs<5; i++) { 3872 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3873 if (lastPids.indexOfKey(stats.pid) >= 0) { 3874 numProcs++; 3875 try { 3876 synchronized (observer) { 3877 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3878 observer.wait(200); // Wait for write-close, give up after 200msec 3879 } 3880 } catch (InterruptedException e) { 3881 Log.wtf(TAG, e); 3882 } 3883 3884 } 3885 } 3886 } 3887 } finally { 3888 observer.stopWatching(); 3889 } 3890 } 3891 3892 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3893 if (true || IS_USER_BUILD) { 3894 return; 3895 } 3896 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3897 if (tracesPath == null || tracesPath.length() == 0) { 3898 return; 3899 } 3900 3901 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3902 StrictMode.allowThreadDiskWrites(); 3903 try { 3904 final File tracesFile = new File(tracesPath); 3905 final File tracesDir = tracesFile.getParentFile(); 3906 final File tracesTmp = new File(tracesDir, "__tmp__"); 3907 try { 3908 if (!tracesDir.exists()) { 3909 tracesFile.mkdirs(); 3910 if (!SELinux.restorecon(tracesDir.getPath())) { 3911 return; 3912 } 3913 } 3914 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3915 3916 if (tracesFile.exists()) { 3917 tracesTmp.delete(); 3918 tracesFile.renameTo(tracesTmp); 3919 } 3920 StringBuilder sb = new StringBuilder(); 3921 Time tobj = new Time(); 3922 tobj.set(System.currentTimeMillis()); 3923 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3924 sb.append(": "); 3925 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3926 sb.append(" since "); 3927 sb.append(msg); 3928 FileOutputStream fos = new FileOutputStream(tracesFile); 3929 fos.write(sb.toString().getBytes()); 3930 if (app == null) { 3931 fos.write("\n*** No application process!".getBytes()); 3932 } 3933 fos.close(); 3934 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3935 } catch (IOException e) { 3936 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3937 return; 3938 } 3939 3940 if (app != null) { 3941 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3942 firstPids.add(app.pid); 3943 dumpStackTraces(tracesPath, firstPids, null, null, null); 3944 } 3945 3946 File lastTracesFile = null; 3947 File curTracesFile = null; 3948 for (int i=9; i>=0; i--) { 3949 String name = String.format(Locale.US, "slow%02d.txt", i); 3950 curTracesFile = new File(tracesDir, name); 3951 if (curTracesFile.exists()) { 3952 if (lastTracesFile != null) { 3953 curTracesFile.renameTo(lastTracesFile); 3954 } else { 3955 curTracesFile.delete(); 3956 } 3957 } 3958 lastTracesFile = curTracesFile; 3959 } 3960 tracesFile.renameTo(curTracesFile); 3961 if (tracesTmp.exists()) { 3962 tracesTmp.renameTo(tracesFile); 3963 } 3964 } finally { 3965 StrictMode.setThreadPolicy(oldPolicy); 3966 } 3967 } 3968 3969 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3970 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3971 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3972 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3973 3974 if (mController != null) { 3975 try { 3976 // 0 == continue, -1 = kill process immediately 3977 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3978 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3979 } catch (RemoteException e) { 3980 mController = null; 3981 Watchdog.getInstance().setActivityController(null); 3982 } 3983 } 3984 3985 long anrTime = SystemClock.uptimeMillis(); 3986 if (MONITOR_CPU_USAGE) { 3987 updateCpuStatsNow(); 3988 } 3989 3990 synchronized (this) { 3991 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3992 if (mShuttingDown) { 3993 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3994 return; 3995 } else if (app.notResponding) { 3996 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3997 return; 3998 } else if (app.crashing) { 3999 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4000 return; 4001 } 4002 4003 // In case we come through here for the same app before completing 4004 // this one, mark as anring now so we will bail out. 4005 app.notResponding = true; 4006 4007 // Log the ANR to the event log. 4008 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4009 app.processName, app.info.flags, annotation); 4010 4011 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4012 firstPids.add(app.pid); 4013 4014 int parentPid = app.pid; 4015 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4016 if (parentPid != app.pid) firstPids.add(parentPid); 4017 4018 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4019 4020 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4021 ProcessRecord r = mLruProcesses.get(i); 4022 if (r != null && r.thread != null) { 4023 int pid = r.pid; 4024 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4025 if (r.persistent) { 4026 firstPids.add(pid); 4027 } else { 4028 lastPids.put(pid, Boolean.TRUE); 4029 } 4030 } 4031 } 4032 } 4033 } 4034 4035 // Log the ANR to the main log. 4036 StringBuilder info = new StringBuilder(); 4037 info.setLength(0); 4038 info.append("ANR in ").append(app.processName); 4039 if (activity != null && activity.shortComponentName != null) { 4040 info.append(" (").append(activity.shortComponentName).append(")"); 4041 } 4042 info.append("\n"); 4043 info.append("PID: ").append(app.pid).append("\n"); 4044 if (annotation != null) { 4045 info.append("Reason: ").append(annotation).append("\n"); 4046 } 4047 if (parent != null && parent != activity) { 4048 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4049 } 4050 4051 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4052 4053 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4054 NATIVE_STACKS_OF_INTEREST); 4055 4056 String cpuInfo = null; 4057 if (MONITOR_CPU_USAGE) { 4058 updateCpuStatsNow(); 4059 synchronized (mProcessCpuThread) { 4060 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4061 } 4062 info.append(processCpuTracker.printCurrentLoad()); 4063 info.append(cpuInfo); 4064 } 4065 4066 info.append(processCpuTracker.printCurrentState(anrTime)); 4067 4068 Slog.e(TAG, info.toString()); 4069 if (tracesFile == null) { 4070 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4071 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4072 } 4073 4074 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4075 cpuInfo, tracesFile, null); 4076 4077 if (mController != null) { 4078 try { 4079 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4080 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4081 if (res != 0) { 4082 if (res < 0 && app.pid != MY_PID) { 4083 Process.killProcess(app.pid); 4084 } else { 4085 synchronized (this) { 4086 mServices.scheduleServiceTimeoutLocked(app); 4087 } 4088 } 4089 return; 4090 } 4091 } catch (RemoteException e) { 4092 mController = null; 4093 Watchdog.getInstance().setActivityController(null); 4094 } 4095 } 4096 4097 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4098 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4099 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4100 4101 synchronized (this) { 4102 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4103 killUnneededProcessLocked(app, "background ANR"); 4104 return; 4105 } 4106 4107 // Set the app's notResponding state, and look up the errorReportReceiver 4108 makeAppNotRespondingLocked(app, 4109 activity != null ? activity.shortComponentName : null, 4110 annotation != null ? "ANR " + annotation : "ANR", 4111 info.toString()); 4112 4113 // Bring up the infamous App Not Responding dialog 4114 Message msg = Message.obtain(); 4115 HashMap<String, Object> map = new HashMap<String, Object>(); 4116 msg.what = SHOW_NOT_RESPONDING_MSG; 4117 msg.obj = map; 4118 msg.arg1 = aboveSystem ? 1 : 0; 4119 map.put("app", app); 4120 if (activity != null) { 4121 map.put("activity", activity); 4122 } 4123 4124 mHandler.sendMessage(msg); 4125 } 4126 } 4127 4128 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4129 if (!mLaunchWarningShown) { 4130 mLaunchWarningShown = true; 4131 mHandler.post(new Runnable() { 4132 @Override 4133 public void run() { 4134 synchronized (ActivityManagerService.this) { 4135 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4136 d.show(); 4137 mHandler.postDelayed(new Runnable() { 4138 @Override 4139 public void run() { 4140 synchronized (ActivityManagerService.this) { 4141 d.dismiss(); 4142 mLaunchWarningShown = false; 4143 } 4144 } 4145 }, 4000); 4146 } 4147 } 4148 }); 4149 } 4150 } 4151 4152 @Override 4153 public boolean clearApplicationUserData(final String packageName, 4154 final IPackageDataObserver observer, int userId) { 4155 enforceNotIsolatedCaller("clearApplicationUserData"); 4156 int uid = Binder.getCallingUid(); 4157 int pid = Binder.getCallingPid(); 4158 userId = handleIncomingUser(pid, uid, 4159 userId, false, true, "clearApplicationUserData", null); 4160 long callingId = Binder.clearCallingIdentity(); 4161 try { 4162 IPackageManager pm = AppGlobals.getPackageManager(); 4163 int pkgUid = -1; 4164 synchronized(this) { 4165 try { 4166 pkgUid = pm.getPackageUid(packageName, userId); 4167 } catch (RemoteException e) { 4168 } 4169 if (pkgUid == -1) { 4170 Slog.w(TAG, "Invalid packageName: " + packageName); 4171 if (observer != null) { 4172 try { 4173 observer.onRemoveCompleted(packageName, false); 4174 } catch (RemoteException e) { 4175 Slog.i(TAG, "Observer no longer exists."); 4176 } 4177 } 4178 return false; 4179 } 4180 if (uid == pkgUid || checkComponentPermission( 4181 android.Manifest.permission.CLEAR_APP_USER_DATA, 4182 pid, uid, -1, true) 4183 == PackageManager.PERMISSION_GRANTED) { 4184 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4185 } else { 4186 throw new SecurityException("PID " + pid + " does not have permission " 4187 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4188 + " of package " + packageName); 4189 } 4190 } 4191 4192 try { 4193 // Clear application user data 4194 pm.clearApplicationUserData(packageName, observer, userId); 4195 4196 // Remove all permissions granted from/to this package 4197 removeUriPermissionsForPackageLocked(packageName, userId, true); 4198 4199 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4200 Uri.fromParts("package", packageName, null)); 4201 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4202 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4203 null, null, 0, null, null, null, false, false, userId); 4204 } catch (RemoteException e) { 4205 } 4206 } finally { 4207 Binder.restoreCallingIdentity(callingId); 4208 } 4209 return true; 4210 } 4211 4212 @Override 4213 public void killBackgroundProcesses(final String packageName, int userId) { 4214 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4215 != PackageManager.PERMISSION_GRANTED && 4216 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4217 != PackageManager.PERMISSION_GRANTED) { 4218 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4219 + Binder.getCallingPid() 4220 + ", uid=" + Binder.getCallingUid() 4221 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4222 Slog.w(TAG, msg); 4223 throw new SecurityException(msg); 4224 } 4225 4226 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4227 userId, true, true, "killBackgroundProcesses", null); 4228 long callingId = Binder.clearCallingIdentity(); 4229 try { 4230 IPackageManager pm = AppGlobals.getPackageManager(); 4231 synchronized(this) { 4232 int appId = -1; 4233 try { 4234 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4235 } catch (RemoteException e) { 4236 } 4237 if (appId == -1) { 4238 Slog.w(TAG, "Invalid packageName: " + packageName); 4239 return; 4240 } 4241 killPackageProcessesLocked(packageName, appId, userId, 4242 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4243 } 4244 } finally { 4245 Binder.restoreCallingIdentity(callingId); 4246 } 4247 } 4248 4249 @Override 4250 public void killAllBackgroundProcesses() { 4251 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4252 != PackageManager.PERMISSION_GRANTED) { 4253 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4254 + Binder.getCallingPid() 4255 + ", uid=" + Binder.getCallingUid() 4256 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4257 Slog.w(TAG, msg); 4258 throw new SecurityException(msg); 4259 } 4260 4261 long callingId = Binder.clearCallingIdentity(); 4262 try { 4263 synchronized(this) { 4264 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4265 final int NP = mProcessNames.getMap().size(); 4266 for (int ip=0; ip<NP; ip++) { 4267 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4268 final int NA = apps.size(); 4269 for (int ia=0; ia<NA; ia++) { 4270 ProcessRecord app = apps.valueAt(ia); 4271 if (app.persistent) { 4272 // we don't kill persistent processes 4273 continue; 4274 } 4275 if (app.removed) { 4276 procs.add(app); 4277 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4278 app.removed = true; 4279 procs.add(app); 4280 } 4281 } 4282 } 4283 4284 int N = procs.size(); 4285 for (int i=0; i<N; i++) { 4286 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4287 } 4288 mAllowLowerMemLevel = true; 4289 updateOomAdjLocked(); 4290 doLowMemReportIfNeededLocked(null); 4291 } 4292 } finally { 4293 Binder.restoreCallingIdentity(callingId); 4294 } 4295 } 4296 4297 @Override 4298 public void forceStopPackage(final String packageName, int userId) { 4299 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4300 != PackageManager.PERMISSION_GRANTED) { 4301 String msg = "Permission Denial: forceStopPackage() from pid=" 4302 + Binder.getCallingPid() 4303 + ", uid=" + Binder.getCallingUid() 4304 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4305 Slog.w(TAG, msg); 4306 throw new SecurityException(msg); 4307 } 4308 final int callingPid = Binder.getCallingPid(); 4309 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4310 userId, true, true, "forceStopPackage", null); 4311 long callingId = Binder.clearCallingIdentity(); 4312 try { 4313 IPackageManager pm = AppGlobals.getPackageManager(); 4314 synchronized(this) { 4315 int[] users = userId == UserHandle.USER_ALL 4316 ? getUsersLocked() : new int[] { userId }; 4317 for (int user : users) { 4318 int pkgUid = -1; 4319 try { 4320 pkgUid = pm.getPackageUid(packageName, user); 4321 } catch (RemoteException e) { 4322 } 4323 if (pkgUid == -1) { 4324 Slog.w(TAG, "Invalid packageName: " + packageName); 4325 continue; 4326 } 4327 try { 4328 pm.setPackageStoppedState(packageName, true, user); 4329 } catch (RemoteException e) { 4330 } catch (IllegalArgumentException e) { 4331 Slog.w(TAG, "Failed trying to unstop package " 4332 + packageName + ": " + e); 4333 } 4334 if (isUserRunningLocked(user, false)) { 4335 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4336 } 4337 } 4338 } 4339 } finally { 4340 Binder.restoreCallingIdentity(callingId); 4341 } 4342 } 4343 4344 /* 4345 * The pkg name and app id have to be specified. 4346 */ 4347 @Override 4348 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4349 if (pkg == null) { 4350 return; 4351 } 4352 // Make sure the uid is valid. 4353 if (appid < 0) { 4354 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4355 return; 4356 } 4357 int callerUid = Binder.getCallingUid(); 4358 // Only the system server can kill an application 4359 if (callerUid == Process.SYSTEM_UID) { 4360 // Post an aysnc message to kill the application 4361 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4362 msg.arg1 = appid; 4363 msg.arg2 = 0; 4364 Bundle bundle = new Bundle(); 4365 bundle.putString("pkg", pkg); 4366 bundle.putString("reason", reason); 4367 msg.obj = bundle; 4368 mHandler.sendMessage(msg); 4369 } else { 4370 throw new SecurityException(callerUid + " cannot kill pkg: " + 4371 pkg); 4372 } 4373 } 4374 4375 @Override 4376 public void closeSystemDialogs(String reason) { 4377 enforceNotIsolatedCaller("closeSystemDialogs"); 4378 4379 final int pid = Binder.getCallingPid(); 4380 final int uid = Binder.getCallingUid(); 4381 final long origId = Binder.clearCallingIdentity(); 4382 try { 4383 synchronized (this) { 4384 // Only allow this from foreground processes, so that background 4385 // applications can't abuse it to prevent system UI from being shown. 4386 if (uid >= Process.FIRST_APPLICATION_UID) { 4387 ProcessRecord proc; 4388 synchronized (mPidsSelfLocked) { 4389 proc = mPidsSelfLocked.get(pid); 4390 } 4391 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4392 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4393 + " from background process " + proc); 4394 return; 4395 } 4396 } 4397 closeSystemDialogsLocked(reason); 4398 } 4399 } finally { 4400 Binder.restoreCallingIdentity(origId); 4401 } 4402 } 4403 4404 void closeSystemDialogsLocked(String reason) { 4405 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4406 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4407 | Intent.FLAG_RECEIVER_FOREGROUND); 4408 if (reason != null) { 4409 intent.putExtra("reason", reason); 4410 } 4411 mWindowManager.closeSystemDialogs(reason); 4412 4413 mStackSupervisor.closeSystemDialogsLocked(); 4414 4415 broadcastIntentLocked(null, null, intent, null, 4416 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4417 Process.SYSTEM_UID, UserHandle.USER_ALL); 4418 } 4419 4420 @Override 4421 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4422 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4423 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4424 for (int i=pids.length-1; i>=0; i--) { 4425 ProcessRecord proc; 4426 int oomAdj; 4427 synchronized (this) { 4428 synchronized (mPidsSelfLocked) { 4429 proc = mPidsSelfLocked.get(pids[i]); 4430 oomAdj = proc != null ? proc.setAdj : 0; 4431 } 4432 } 4433 infos[i] = new Debug.MemoryInfo(); 4434 Debug.getMemoryInfo(pids[i], infos[i]); 4435 if (proc != null) { 4436 synchronized (this) { 4437 if (proc.thread != null && proc.setAdj == oomAdj) { 4438 // Record this for posterity if the process has been stable. 4439 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4440 infos[i].getTotalUss(), false, proc.pkgList); 4441 } 4442 } 4443 } 4444 } 4445 return infos; 4446 } 4447 4448 @Override 4449 public long[] getProcessPss(int[] pids) { 4450 enforceNotIsolatedCaller("getProcessPss"); 4451 long[] pss = new long[pids.length]; 4452 for (int i=pids.length-1; i>=0; i--) { 4453 ProcessRecord proc; 4454 int oomAdj; 4455 synchronized (this) { 4456 synchronized (mPidsSelfLocked) { 4457 proc = mPidsSelfLocked.get(pids[i]); 4458 oomAdj = proc != null ? proc.setAdj : 0; 4459 } 4460 } 4461 long[] tmpUss = new long[1]; 4462 pss[i] = Debug.getPss(pids[i], tmpUss); 4463 if (proc != null) { 4464 synchronized (this) { 4465 if (proc.thread != null && proc.setAdj == oomAdj) { 4466 // Record this for posterity if the process has been stable. 4467 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4468 } 4469 } 4470 } 4471 } 4472 return pss; 4473 } 4474 4475 @Override 4476 public void killApplicationProcess(String processName, int uid) { 4477 if (processName == null) { 4478 return; 4479 } 4480 4481 int callerUid = Binder.getCallingUid(); 4482 // Only the system server can kill an application 4483 if (callerUid == Process.SYSTEM_UID) { 4484 synchronized (this) { 4485 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4486 if (app != null && app.thread != null) { 4487 try { 4488 app.thread.scheduleSuicide(); 4489 } catch (RemoteException e) { 4490 // If the other end already died, then our work here is done. 4491 } 4492 } else { 4493 Slog.w(TAG, "Process/uid not found attempting kill of " 4494 + processName + " / " + uid); 4495 } 4496 } 4497 } else { 4498 throw new SecurityException(callerUid + " cannot kill app process: " + 4499 processName); 4500 } 4501 } 4502 4503 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4504 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4505 false, true, false, false, UserHandle.getUserId(uid), reason); 4506 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4507 Uri.fromParts("package", packageName, null)); 4508 if (!mProcessesReady) { 4509 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4510 | Intent.FLAG_RECEIVER_FOREGROUND); 4511 } 4512 intent.putExtra(Intent.EXTRA_UID, uid); 4513 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4514 broadcastIntentLocked(null, null, intent, 4515 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4516 false, false, 4517 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4518 } 4519 4520 private void forceStopUserLocked(int userId, String reason) { 4521 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4522 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4523 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4524 | Intent.FLAG_RECEIVER_FOREGROUND); 4525 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4526 broadcastIntentLocked(null, null, intent, 4527 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4528 false, false, 4529 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4530 } 4531 4532 private final boolean killPackageProcessesLocked(String packageName, int appId, 4533 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4534 boolean doit, boolean evenPersistent, String reason) { 4535 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4536 4537 // Remove all processes this package may have touched: all with the 4538 // same UID (except for the system or root user), and all whose name 4539 // matches the package name. 4540 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4541 final int NP = mProcessNames.getMap().size(); 4542 for (int ip=0; ip<NP; ip++) { 4543 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4544 final int NA = apps.size(); 4545 for (int ia=0; ia<NA; ia++) { 4546 ProcessRecord app = apps.valueAt(ia); 4547 if (app.persistent && !evenPersistent) { 4548 // we don't kill persistent processes 4549 continue; 4550 } 4551 if (app.removed) { 4552 if (doit) { 4553 procs.add(app); 4554 } 4555 continue; 4556 } 4557 4558 // Skip process if it doesn't meet our oom adj requirement. 4559 if (app.setAdj < minOomAdj) { 4560 continue; 4561 } 4562 4563 // If no package is specified, we call all processes under the 4564 // give user id. 4565 if (packageName == null) { 4566 if (app.userId != userId) { 4567 continue; 4568 } 4569 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4570 continue; 4571 } 4572 // Package has been specified, we want to hit all processes 4573 // that match it. We need to qualify this by the processes 4574 // that are running under the specified app and user ID. 4575 } else { 4576 if (UserHandle.getAppId(app.uid) != appId) { 4577 continue; 4578 } 4579 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4580 continue; 4581 } 4582 if (!app.pkgList.containsKey(packageName)) { 4583 continue; 4584 } 4585 } 4586 4587 // Process has passed all conditions, kill it! 4588 if (!doit) { 4589 return true; 4590 } 4591 app.removed = true; 4592 procs.add(app); 4593 } 4594 } 4595 4596 int N = procs.size(); 4597 for (int i=0; i<N; i++) { 4598 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4599 } 4600 updateOomAdjLocked(); 4601 return N > 0; 4602 } 4603 4604 private final boolean forceStopPackageLocked(String name, int appId, 4605 boolean callerWillRestart, boolean purgeCache, boolean doit, 4606 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4607 int i; 4608 int N; 4609 4610 if (userId == UserHandle.USER_ALL && name == null) { 4611 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4612 } 4613 4614 if (appId < 0 && name != null) { 4615 try { 4616 appId = UserHandle.getAppId( 4617 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4618 } catch (RemoteException e) { 4619 } 4620 } 4621 4622 if (doit) { 4623 if (name != null) { 4624 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4625 + " user=" + userId + ": " + reason); 4626 } else { 4627 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4628 } 4629 4630 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4631 for (int ip=pmap.size()-1; ip>=0; ip--) { 4632 SparseArray<Long> ba = pmap.valueAt(ip); 4633 for (i=ba.size()-1; i>=0; i--) { 4634 boolean remove = false; 4635 final int entUid = ba.keyAt(i); 4636 if (name != null) { 4637 if (userId == UserHandle.USER_ALL) { 4638 if (UserHandle.getAppId(entUid) == appId) { 4639 remove = true; 4640 } 4641 } else { 4642 if (entUid == UserHandle.getUid(userId, appId)) { 4643 remove = true; 4644 } 4645 } 4646 } else if (UserHandle.getUserId(entUid) == userId) { 4647 remove = true; 4648 } 4649 if (remove) { 4650 ba.removeAt(i); 4651 } 4652 } 4653 if (ba.size() == 0) { 4654 pmap.removeAt(ip); 4655 } 4656 } 4657 } 4658 4659 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4660 -100, callerWillRestart, true, doit, evenPersistent, 4661 name == null ? ("stop user " + userId) : ("stop " + name)); 4662 4663 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4664 if (!doit) { 4665 return true; 4666 } 4667 didSomething = true; 4668 } 4669 4670 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4671 if (!doit) { 4672 return true; 4673 } 4674 didSomething = true; 4675 } 4676 4677 if (name == null) { 4678 // Remove all sticky broadcasts from this user. 4679 mStickyBroadcasts.remove(userId); 4680 } 4681 4682 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4683 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4684 userId, providers)) { 4685 if (!doit) { 4686 return true; 4687 } 4688 didSomething = true; 4689 } 4690 N = providers.size(); 4691 for (i=0; i<N; i++) { 4692 removeDyingProviderLocked(null, providers.get(i), true); 4693 } 4694 4695 // Remove transient permissions granted from/to this package/user 4696 removeUriPermissionsForPackageLocked(name, userId, false); 4697 4698 if (name == null || uninstalling) { 4699 // Remove pending intents. For now we only do this when force 4700 // stopping users, because we have some problems when doing this 4701 // for packages -- app widgets are not currently cleaned up for 4702 // such packages, so they can be left with bad pending intents. 4703 if (mIntentSenderRecords.size() > 0) { 4704 Iterator<WeakReference<PendingIntentRecord>> it 4705 = mIntentSenderRecords.values().iterator(); 4706 while (it.hasNext()) { 4707 WeakReference<PendingIntentRecord> wpir = it.next(); 4708 if (wpir == null) { 4709 it.remove(); 4710 continue; 4711 } 4712 PendingIntentRecord pir = wpir.get(); 4713 if (pir == null) { 4714 it.remove(); 4715 continue; 4716 } 4717 if (name == null) { 4718 // Stopping user, remove all objects for the user. 4719 if (pir.key.userId != userId) { 4720 // Not the same user, skip it. 4721 continue; 4722 } 4723 } else { 4724 if (UserHandle.getAppId(pir.uid) != appId) { 4725 // Different app id, skip it. 4726 continue; 4727 } 4728 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4729 // Different user, skip it. 4730 continue; 4731 } 4732 if (!pir.key.packageName.equals(name)) { 4733 // Different package, skip it. 4734 continue; 4735 } 4736 } 4737 if (!doit) { 4738 return true; 4739 } 4740 didSomething = true; 4741 it.remove(); 4742 pir.canceled = true; 4743 if (pir.key.activity != null) { 4744 pir.key.activity.pendingResults.remove(pir.ref); 4745 } 4746 } 4747 } 4748 } 4749 4750 if (doit) { 4751 if (purgeCache && name != null) { 4752 AttributeCache ac = AttributeCache.instance(); 4753 if (ac != null) { 4754 ac.removePackage(name); 4755 } 4756 } 4757 if (mBooted) { 4758 mStackSupervisor.resumeTopActivitiesLocked(); 4759 mStackSupervisor.scheduleIdleLocked(); 4760 } 4761 } 4762 4763 return didSomething; 4764 } 4765 4766 private final boolean removeProcessLocked(ProcessRecord app, 4767 boolean callerWillRestart, boolean allowRestart, String reason) { 4768 final String name = app.processName; 4769 final int uid = app.uid; 4770 if (DEBUG_PROCESSES) Slog.d( 4771 TAG, "Force removing proc " + app.toShortString() + " (" + name 4772 + "/" + uid + ")"); 4773 4774 mProcessNames.remove(name, uid); 4775 mIsolatedProcesses.remove(app.uid); 4776 if (mHeavyWeightProcess == app) { 4777 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4778 mHeavyWeightProcess.userId, 0)); 4779 mHeavyWeightProcess = null; 4780 } 4781 boolean needRestart = false; 4782 if (app.pid > 0 && app.pid != MY_PID) { 4783 int pid = app.pid; 4784 synchronized (mPidsSelfLocked) { 4785 mPidsSelfLocked.remove(pid); 4786 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4787 } 4788 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4789 app.processName, app.info.uid); 4790 if (app.isolated) { 4791 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4792 } 4793 killUnneededProcessLocked(app, reason); 4794 handleAppDiedLocked(app, true, allowRestart); 4795 removeLruProcessLocked(app); 4796 4797 if (app.persistent && !app.isolated) { 4798 if (!callerWillRestart) { 4799 addAppLocked(app.info, false); 4800 } else { 4801 needRestart = true; 4802 } 4803 } 4804 } else { 4805 mRemovedProcesses.add(app); 4806 } 4807 4808 return needRestart; 4809 } 4810 4811 private final void processStartTimedOutLocked(ProcessRecord app) { 4812 final int pid = app.pid; 4813 boolean gone = false; 4814 synchronized (mPidsSelfLocked) { 4815 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4816 if (knownApp != null && knownApp.thread == null) { 4817 mPidsSelfLocked.remove(pid); 4818 gone = true; 4819 } 4820 } 4821 4822 if (gone) { 4823 Slog.w(TAG, "Process " + app + " failed to attach"); 4824 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4825 pid, app.uid, app.processName); 4826 mProcessNames.remove(app.processName, app.uid); 4827 mIsolatedProcesses.remove(app.uid); 4828 if (mHeavyWeightProcess == app) { 4829 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4830 mHeavyWeightProcess.userId, 0)); 4831 mHeavyWeightProcess = null; 4832 } 4833 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4834 app.processName, app.info.uid); 4835 if (app.isolated) { 4836 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4837 } 4838 // Take care of any launching providers waiting for this process. 4839 checkAppInLaunchingProvidersLocked(app, true); 4840 // Take care of any services that are waiting for the process. 4841 mServices.processStartTimedOutLocked(app); 4842 killUnneededProcessLocked(app, "start timeout"); 4843 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4844 Slog.w(TAG, "Unattached app died before backup, skipping"); 4845 try { 4846 IBackupManager bm = IBackupManager.Stub.asInterface( 4847 ServiceManager.getService(Context.BACKUP_SERVICE)); 4848 bm.agentDisconnected(app.info.packageName); 4849 } catch (RemoteException e) { 4850 // Can't happen; the backup manager is local 4851 } 4852 } 4853 if (isPendingBroadcastProcessLocked(pid)) { 4854 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4855 skipPendingBroadcastLocked(pid); 4856 } 4857 } else { 4858 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4859 } 4860 } 4861 4862 private final boolean attachApplicationLocked(IApplicationThread thread, 4863 int pid) { 4864 4865 // Find the application record that is being attached... either via 4866 // the pid if we are running in multiple processes, or just pull the 4867 // next app record if we are emulating process with anonymous threads. 4868 ProcessRecord app; 4869 if (pid != MY_PID && pid >= 0) { 4870 synchronized (mPidsSelfLocked) { 4871 app = mPidsSelfLocked.get(pid); 4872 } 4873 } else { 4874 app = null; 4875 } 4876 4877 if (app == null) { 4878 Slog.w(TAG, "No pending application record for pid " + pid 4879 + " (IApplicationThread " + thread + "); dropping process"); 4880 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4881 if (pid > 0 && pid != MY_PID) { 4882 Process.killProcessQuiet(pid); 4883 } else { 4884 try { 4885 thread.scheduleExit(); 4886 } catch (Exception e) { 4887 // Ignore exceptions. 4888 } 4889 } 4890 return false; 4891 } 4892 4893 // If this application record is still attached to a previous 4894 // process, clean it up now. 4895 if (app.thread != null) { 4896 handleAppDiedLocked(app, true, true); 4897 } 4898 4899 // Tell the process all about itself. 4900 4901 if (localLOGV) Slog.v( 4902 TAG, "Binding process pid " + pid + " to record " + app); 4903 4904 final String processName = app.processName; 4905 try { 4906 AppDeathRecipient adr = new AppDeathRecipient( 4907 app, pid, thread); 4908 thread.asBinder().linkToDeath(adr, 0); 4909 app.deathRecipient = adr; 4910 } catch (RemoteException e) { 4911 app.resetPackageList(mProcessStats); 4912 startProcessLocked(app, "link fail", processName); 4913 return false; 4914 } 4915 4916 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4917 4918 app.makeActive(thread, mProcessStats); 4919 app.curAdj = app.setAdj = -100; 4920 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4921 app.forcingToForeground = null; 4922 updateProcessForegroundLocked(app, false, false); 4923 app.hasShownUi = false; 4924 app.debugging = false; 4925 app.cached = false; 4926 4927 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4928 4929 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4930 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4931 4932 if (!normalMode) { 4933 Slog.i(TAG, "Launching preboot mode app: " + app); 4934 } 4935 4936 if (localLOGV) Slog.v( 4937 TAG, "New app record " + app 4938 + " thread=" + thread.asBinder() + " pid=" + pid); 4939 try { 4940 int testMode = IApplicationThread.DEBUG_OFF; 4941 if (mDebugApp != null && mDebugApp.equals(processName)) { 4942 testMode = mWaitForDebugger 4943 ? IApplicationThread.DEBUG_WAIT 4944 : IApplicationThread.DEBUG_ON; 4945 app.debugging = true; 4946 if (mDebugTransient) { 4947 mDebugApp = mOrigDebugApp; 4948 mWaitForDebugger = mOrigWaitForDebugger; 4949 } 4950 } 4951 String profileFile = app.instrumentationProfileFile; 4952 ParcelFileDescriptor profileFd = null; 4953 boolean profileAutoStop = false; 4954 if (mProfileApp != null && mProfileApp.equals(processName)) { 4955 mProfileProc = app; 4956 profileFile = mProfileFile; 4957 profileFd = mProfileFd; 4958 profileAutoStop = mAutoStopProfiler; 4959 } 4960 boolean enableOpenGlTrace = false; 4961 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4962 enableOpenGlTrace = true; 4963 mOpenGlTraceApp = null; 4964 } 4965 4966 // If the app is being launched for restore or full backup, set it up specially 4967 boolean isRestrictedBackupMode = false; 4968 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4969 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4970 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4971 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4972 } 4973 4974 ensurePackageDexOpt(app.instrumentationInfo != null 4975 ? app.instrumentationInfo.packageName 4976 : app.info.packageName); 4977 if (app.instrumentationClass != null) { 4978 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4979 } 4980 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4981 + processName + " with config " + mConfiguration); 4982 ApplicationInfo appInfo = app.instrumentationInfo != null 4983 ? app.instrumentationInfo : app.info; 4984 app.compat = compatibilityInfoForPackageLocked(appInfo); 4985 if (profileFd != null) { 4986 profileFd = profileFd.dup(); 4987 } 4988 thread.bindApplication(processName, appInfo, providers, 4989 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4990 app.instrumentationArguments, app.instrumentationWatcher, 4991 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4992 isRestrictedBackupMode || !normalMode, app.persistent, 4993 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4994 mCoreSettingsObserver.getCoreSettingsLocked()); 4995 updateLruProcessLocked(app, false, null); 4996 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4997 } catch (Exception e) { 4998 // todo: Yikes! What should we do? For now we will try to 4999 // start another process, but that could easily get us in 5000 // an infinite loop of restarting processes... 5001 Slog.w(TAG, "Exception thrown during bind!", e); 5002 5003 app.resetPackageList(mProcessStats); 5004 app.unlinkDeathRecipient(); 5005 startProcessLocked(app, "bind fail", processName); 5006 return false; 5007 } 5008 5009 // Remove this record from the list of starting applications. 5010 mPersistentStartingProcesses.remove(app); 5011 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5012 "Attach application locked removing on hold: " + app); 5013 mProcessesOnHold.remove(app); 5014 5015 boolean badApp = false; 5016 boolean didSomething = false; 5017 5018 // See if the top visible activity is waiting to run in this process... 5019 if (normalMode) { 5020 try { 5021 if (mStackSupervisor.attachApplicationLocked(app)) { 5022 didSomething = true; 5023 } 5024 } catch (Exception e) { 5025 badApp = true; 5026 } 5027 } 5028 5029 // Find any services that should be running in this process... 5030 if (!badApp) { 5031 try { 5032 didSomething |= mServices.attachApplicationLocked(app, processName); 5033 } catch (Exception e) { 5034 badApp = true; 5035 } 5036 } 5037 5038 // Check if a next-broadcast receiver is in this process... 5039 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5040 try { 5041 didSomething |= sendPendingBroadcastsLocked(app); 5042 } catch (Exception e) { 5043 // If the app died trying to launch the receiver we declare it 'bad' 5044 badApp = true; 5045 } 5046 } 5047 5048 // Check whether the next backup agent is in this process... 5049 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5050 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5051 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5052 try { 5053 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5054 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5055 mBackupTarget.backupMode); 5056 } catch (Exception e) { 5057 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5058 e.printStackTrace(); 5059 } 5060 } 5061 5062 if (badApp) { 5063 // todo: Also need to kill application to deal with all 5064 // kinds of exceptions. 5065 handleAppDiedLocked(app, false, true); 5066 return false; 5067 } 5068 5069 if (!didSomething) { 5070 updateOomAdjLocked(); 5071 } 5072 5073 return true; 5074 } 5075 5076 @Override 5077 public final void attachApplication(IApplicationThread thread) { 5078 synchronized (this) { 5079 int callingPid = Binder.getCallingPid(); 5080 final long origId = Binder.clearCallingIdentity(); 5081 attachApplicationLocked(thread, callingPid); 5082 Binder.restoreCallingIdentity(origId); 5083 } 5084 } 5085 5086 @Override 5087 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5088 final long origId = Binder.clearCallingIdentity(); 5089 synchronized (this) { 5090 ActivityStack stack = ActivityRecord.getStackLocked(token); 5091 if (stack != null) { 5092 ActivityRecord r = 5093 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5094 if (stopProfiling) { 5095 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5096 try { 5097 mProfileFd.close(); 5098 } catch (IOException e) { 5099 } 5100 clearProfilerLocked(); 5101 } 5102 } 5103 } 5104 } 5105 Binder.restoreCallingIdentity(origId); 5106 } 5107 5108 void enableScreenAfterBoot() { 5109 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5110 SystemClock.uptimeMillis()); 5111 mWindowManager.enableScreenAfterBoot(); 5112 5113 synchronized (this) { 5114 updateEventDispatchingLocked(); 5115 } 5116 } 5117 5118 @Override 5119 public void showBootMessage(final CharSequence msg, final boolean always) { 5120 enforceNotIsolatedCaller("showBootMessage"); 5121 mWindowManager.showBootMessage(msg, always); 5122 } 5123 5124 @Override 5125 public void dismissKeyguardOnNextActivity() { 5126 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5127 final long token = Binder.clearCallingIdentity(); 5128 try { 5129 synchronized (this) { 5130 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5131 if (mLockScreenShown) { 5132 mLockScreenShown = false; 5133 comeOutOfSleepIfNeededLocked(); 5134 } 5135 mStackSupervisor.setDismissKeyguard(true); 5136 } 5137 } finally { 5138 Binder.restoreCallingIdentity(token); 5139 } 5140 } 5141 5142 final void finishBooting() { 5143 IntentFilter pkgFilter = new IntentFilter(); 5144 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5145 pkgFilter.addDataScheme("package"); 5146 mContext.registerReceiver(new BroadcastReceiver() { 5147 @Override 5148 public void onReceive(Context context, Intent intent) { 5149 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5150 if (pkgs != null) { 5151 for (String pkg : pkgs) { 5152 synchronized (ActivityManagerService.this) { 5153 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5154 "finished booting")) { 5155 setResultCode(Activity.RESULT_OK); 5156 return; 5157 } 5158 } 5159 } 5160 } 5161 } 5162 }, pkgFilter); 5163 5164 synchronized (this) { 5165 // Ensure that any processes we had put on hold are now started 5166 // up. 5167 final int NP = mProcessesOnHold.size(); 5168 if (NP > 0) { 5169 ArrayList<ProcessRecord> procs = 5170 new ArrayList<ProcessRecord>(mProcessesOnHold); 5171 for (int ip=0; ip<NP; ip++) { 5172 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5173 + procs.get(ip)); 5174 startProcessLocked(procs.get(ip), "on-hold", null); 5175 } 5176 } 5177 5178 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5179 // Start looking for apps that are abusing wake locks. 5180 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5181 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5182 // Tell anyone interested that we are done booting! 5183 SystemProperties.set("sys.boot_completed", "1"); 5184 SystemProperties.set("dev.bootcomplete", "1"); 5185 for (int i=0; i<mStartedUsers.size(); i++) { 5186 UserStartedState uss = mStartedUsers.valueAt(i); 5187 if (uss.mState == UserStartedState.STATE_BOOTING) { 5188 uss.mState = UserStartedState.STATE_RUNNING; 5189 final int userId = mStartedUsers.keyAt(i); 5190 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5191 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5192 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5193 broadcastIntentLocked(null, null, intent, null, 5194 new IIntentReceiver.Stub() { 5195 @Override 5196 public void performReceive(Intent intent, int resultCode, 5197 String data, Bundle extras, boolean ordered, 5198 boolean sticky, int sendingUser) { 5199 synchronized (ActivityManagerService.this) { 5200 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5201 true, false); 5202 } 5203 } 5204 }, 5205 0, null, null, 5206 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5207 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5208 userId); 5209 } 5210 } 5211 scheduleStartProfilesLocked(); 5212 } 5213 } 5214 } 5215 5216 final void ensureBootCompleted() { 5217 boolean booting; 5218 boolean enableScreen; 5219 synchronized (this) { 5220 booting = mBooting; 5221 mBooting = false; 5222 enableScreen = !mBooted; 5223 mBooted = true; 5224 } 5225 5226 if (booting) { 5227 finishBooting(); 5228 } 5229 5230 if (enableScreen) { 5231 enableScreenAfterBoot(); 5232 } 5233 } 5234 5235 @Override 5236 public final void activityResumed(IBinder token) { 5237 final long origId = Binder.clearCallingIdentity(); 5238 synchronized(this) { 5239 ActivityStack stack = ActivityRecord.getStackLocked(token); 5240 if (stack != null) { 5241 ActivityRecord.activityResumedLocked(token); 5242 } 5243 } 5244 Binder.restoreCallingIdentity(origId); 5245 } 5246 5247 @Override 5248 public final void activityPaused(IBinder token) { 5249 final long origId = Binder.clearCallingIdentity(); 5250 synchronized(this) { 5251 ActivityStack stack = ActivityRecord.getStackLocked(token); 5252 if (stack != null) { 5253 stack.activityPausedLocked(token, false); 5254 } 5255 } 5256 Binder.restoreCallingIdentity(origId); 5257 } 5258 5259 @Override 5260 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5261 CharSequence description) { 5262 if (localLOGV) Slog.v( 5263 TAG, "Activity stopped: token=" + token); 5264 5265 // Refuse possible leaked file descriptors 5266 if (icicle != null && icicle.hasFileDescriptors()) { 5267 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5268 } 5269 5270 ActivityRecord r = null; 5271 5272 final long origId = Binder.clearCallingIdentity(); 5273 5274 synchronized (this) { 5275 r = ActivityRecord.isInStackLocked(token); 5276 if (r != null) { 5277 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5278 } 5279 } 5280 5281 if (r != null) { 5282 sendPendingThumbnail(r, null, null, null, false); 5283 } 5284 5285 trimApplications(); 5286 5287 Binder.restoreCallingIdentity(origId); 5288 } 5289 5290 @Override 5291 public final void activityDestroyed(IBinder token) { 5292 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5293 synchronized (this) { 5294 ActivityStack stack = ActivityRecord.getStackLocked(token); 5295 if (stack != null) { 5296 stack.activityDestroyedLocked(token); 5297 } 5298 } 5299 } 5300 5301 @Override 5302 public String getCallingPackage(IBinder token) { 5303 synchronized (this) { 5304 ActivityRecord r = getCallingRecordLocked(token); 5305 return r != null ? r.info.packageName : null; 5306 } 5307 } 5308 5309 @Override 5310 public ComponentName getCallingActivity(IBinder token) { 5311 synchronized (this) { 5312 ActivityRecord r = getCallingRecordLocked(token); 5313 return r != null ? r.intent.getComponent() : null; 5314 } 5315 } 5316 5317 private ActivityRecord getCallingRecordLocked(IBinder token) { 5318 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5319 if (r == null) { 5320 return null; 5321 } 5322 return r.resultTo; 5323 } 5324 5325 @Override 5326 public ComponentName getActivityClassForToken(IBinder token) { 5327 synchronized(this) { 5328 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5329 if (r == null) { 5330 return null; 5331 } 5332 return r.intent.getComponent(); 5333 } 5334 } 5335 5336 @Override 5337 public String getPackageForToken(IBinder token) { 5338 synchronized(this) { 5339 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5340 if (r == null) { 5341 return null; 5342 } 5343 return r.packageName; 5344 } 5345 } 5346 5347 @Override 5348 public IIntentSender getIntentSender(int type, 5349 String packageName, IBinder token, String resultWho, 5350 int requestCode, Intent[] intents, String[] resolvedTypes, 5351 int flags, Bundle options, int userId) { 5352 enforceNotIsolatedCaller("getIntentSender"); 5353 // Refuse possible leaked file descriptors 5354 if (intents != null) { 5355 if (intents.length < 1) { 5356 throw new IllegalArgumentException("Intents array length must be >= 1"); 5357 } 5358 for (int i=0; i<intents.length; i++) { 5359 Intent intent = intents[i]; 5360 if (intent != null) { 5361 if (intent.hasFileDescriptors()) { 5362 throw new IllegalArgumentException("File descriptors passed in Intent"); 5363 } 5364 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5365 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5366 throw new IllegalArgumentException( 5367 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5368 } 5369 intents[i] = new Intent(intent); 5370 } 5371 } 5372 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5373 throw new IllegalArgumentException( 5374 "Intent array length does not match resolvedTypes length"); 5375 } 5376 } 5377 if (options != null) { 5378 if (options.hasFileDescriptors()) { 5379 throw new IllegalArgumentException("File descriptors passed in options"); 5380 } 5381 } 5382 5383 synchronized(this) { 5384 int callingUid = Binder.getCallingUid(); 5385 int origUserId = userId; 5386 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5387 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5388 "getIntentSender", null); 5389 if (origUserId == UserHandle.USER_CURRENT) { 5390 // We don't want to evaluate this until the pending intent is 5391 // actually executed. However, we do want to always do the 5392 // security checking for it above. 5393 userId = UserHandle.USER_CURRENT; 5394 } 5395 try { 5396 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5397 int uid = AppGlobals.getPackageManager() 5398 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5399 if (!UserHandle.isSameApp(callingUid, uid)) { 5400 String msg = "Permission Denial: getIntentSender() from pid=" 5401 + Binder.getCallingPid() 5402 + ", uid=" + Binder.getCallingUid() 5403 + ", (need uid=" + uid + ")" 5404 + " is not allowed to send as package " + packageName; 5405 Slog.w(TAG, msg); 5406 throw new SecurityException(msg); 5407 } 5408 } 5409 5410 return getIntentSenderLocked(type, packageName, callingUid, userId, 5411 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5412 5413 } catch (RemoteException e) { 5414 throw new SecurityException(e); 5415 } 5416 } 5417 } 5418 5419 IIntentSender getIntentSenderLocked(int type, String packageName, 5420 int callingUid, int userId, IBinder token, String resultWho, 5421 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5422 Bundle options) { 5423 if (DEBUG_MU) 5424 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5425 ActivityRecord activity = null; 5426 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5427 activity = ActivityRecord.isInStackLocked(token); 5428 if (activity == null) { 5429 return null; 5430 } 5431 if (activity.finishing) { 5432 return null; 5433 } 5434 } 5435 5436 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5437 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5438 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5439 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5440 |PendingIntent.FLAG_UPDATE_CURRENT); 5441 5442 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5443 type, packageName, activity, resultWho, 5444 requestCode, intents, resolvedTypes, flags, options, userId); 5445 WeakReference<PendingIntentRecord> ref; 5446 ref = mIntentSenderRecords.get(key); 5447 PendingIntentRecord rec = ref != null ? ref.get() : null; 5448 if (rec != null) { 5449 if (!cancelCurrent) { 5450 if (updateCurrent) { 5451 if (rec.key.requestIntent != null) { 5452 rec.key.requestIntent.replaceExtras(intents != null ? 5453 intents[intents.length - 1] : null); 5454 } 5455 if (intents != null) { 5456 intents[intents.length-1] = rec.key.requestIntent; 5457 rec.key.allIntents = intents; 5458 rec.key.allResolvedTypes = resolvedTypes; 5459 } else { 5460 rec.key.allIntents = null; 5461 rec.key.allResolvedTypes = null; 5462 } 5463 } 5464 return rec; 5465 } 5466 rec.canceled = true; 5467 mIntentSenderRecords.remove(key); 5468 } 5469 if (noCreate) { 5470 return rec; 5471 } 5472 rec = new PendingIntentRecord(this, key, callingUid); 5473 mIntentSenderRecords.put(key, rec.ref); 5474 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5475 if (activity.pendingResults == null) { 5476 activity.pendingResults 5477 = new HashSet<WeakReference<PendingIntentRecord>>(); 5478 } 5479 activity.pendingResults.add(rec.ref); 5480 } 5481 return rec; 5482 } 5483 5484 @Override 5485 public void cancelIntentSender(IIntentSender sender) { 5486 if (!(sender instanceof PendingIntentRecord)) { 5487 return; 5488 } 5489 synchronized(this) { 5490 PendingIntentRecord rec = (PendingIntentRecord)sender; 5491 try { 5492 int uid = AppGlobals.getPackageManager() 5493 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5494 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5495 String msg = "Permission Denial: cancelIntentSender() from pid=" 5496 + Binder.getCallingPid() 5497 + ", uid=" + Binder.getCallingUid() 5498 + " is not allowed to cancel packges " 5499 + rec.key.packageName; 5500 Slog.w(TAG, msg); 5501 throw new SecurityException(msg); 5502 } 5503 } catch (RemoteException e) { 5504 throw new SecurityException(e); 5505 } 5506 cancelIntentSenderLocked(rec, true); 5507 } 5508 } 5509 5510 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5511 rec.canceled = true; 5512 mIntentSenderRecords.remove(rec.key); 5513 if (cleanActivity && rec.key.activity != null) { 5514 rec.key.activity.pendingResults.remove(rec.ref); 5515 } 5516 } 5517 5518 @Override 5519 public String getPackageForIntentSender(IIntentSender pendingResult) { 5520 if (!(pendingResult instanceof PendingIntentRecord)) { 5521 return null; 5522 } 5523 try { 5524 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5525 return res.key.packageName; 5526 } catch (ClassCastException e) { 5527 } 5528 return null; 5529 } 5530 5531 @Override 5532 public int getUidForIntentSender(IIntentSender sender) { 5533 if (sender instanceof PendingIntentRecord) { 5534 try { 5535 PendingIntentRecord res = (PendingIntentRecord)sender; 5536 return res.uid; 5537 } catch (ClassCastException e) { 5538 } 5539 } 5540 return -1; 5541 } 5542 5543 @Override 5544 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5545 if (!(pendingResult instanceof PendingIntentRecord)) { 5546 return false; 5547 } 5548 try { 5549 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5550 if (res.key.allIntents == null) { 5551 return false; 5552 } 5553 for (int i=0; i<res.key.allIntents.length; i++) { 5554 Intent intent = res.key.allIntents[i]; 5555 if (intent.getPackage() != null && intent.getComponent() != null) { 5556 return false; 5557 } 5558 } 5559 return true; 5560 } catch (ClassCastException e) { 5561 } 5562 return false; 5563 } 5564 5565 @Override 5566 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5567 if (!(pendingResult instanceof PendingIntentRecord)) { 5568 return false; 5569 } 5570 try { 5571 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5572 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5573 return true; 5574 } 5575 return false; 5576 } catch (ClassCastException e) { 5577 } 5578 return false; 5579 } 5580 5581 @Override 5582 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5583 if (!(pendingResult instanceof PendingIntentRecord)) { 5584 return null; 5585 } 5586 try { 5587 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5588 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5589 } catch (ClassCastException e) { 5590 } 5591 return null; 5592 } 5593 5594 @Override 5595 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5596 if (!(pendingResult instanceof PendingIntentRecord)) { 5597 return null; 5598 } 5599 try { 5600 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5601 Intent intent = res.key.requestIntent; 5602 if (intent != null) { 5603 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5604 || res.lastTagPrefix.equals(prefix))) { 5605 return res.lastTag; 5606 } 5607 res.lastTagPrefix = prefix; 5608 StringBuilder sb = new StringBuilder(128); 5609 if (prefix != null) { 5610 sb.append(prefix); 5611 } 5612 if (intent.getAction() != null) { 5613 sb.append(intent.getAction()); 5614 } else if (intent.getComponent() != null) { 5615 intent.getComponent().appendShortString(sb); 5616 } else { 5617 sb.append("?"); 5618 } 5619 return res.lastTag = sb.toString(); 5620 } 5621 } catch (ClassCastException e) { 5622 } 5623 return null; 5624 } 5625 5626 @Override 5627 public void setProcessLimit(int max) { 5628 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5629 "setProcessLimit()"); 5630 synchronized (this) { 5631 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5632 mProcessLimitOverride = max; 5633 } 5634 trimApplications(); 5635 } 5636 5637 @Override 5638 public int getProcessLimit() { 5639 synchronized (this) { 5640 return mProcessLimitOverride; 5641 } 5642 } 5643 5644 void foregroundTokenDied(ForegroundToken token) { 5645 synchronized (ActivityManagerService.this) { 5646 synchronized (mPidsSelfLocked) { 5647 ForegroundToken cur 5648 = mForegroundProcesses.get(token.pid); 5649 if (cur != token) { 5650 return; 5651 } 5652 mForegroundProcesses.remove(token.pid); 5653 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5654 if (pr == null) { 5655 return; 5656 } 5657 pr.forcingToForeground = null; 5658 updateProcessForegroundLocked(pr, false, false); 5659 } 5660 updateOomAdjLocked(); 5661 } 5662 } 5663 5664 @Override 5665 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5666 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5667 "setProcessForeground()"); 5668 synchronized(this) { 5669 boolean changed = false; 5670 5671 synchronized (mPidsSelfLocked) { 5672 ProcessRecord pr = mPidsSelfLocked.get(pid); 5673 if (pr == null && isForeground) { 5674 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5675 return; 5676 } 5677 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5678 if (oldToken != null) { 5679 oldToken.token.unlinkToDeath(oldToken, 0); 5680 mForegroundProcesses.remove(pid); 5681 if (pr != null) { 5682 pr.forcingToForeground = null; 5683 } 5684 changed = true; 5685 } 5686 if (isForeground && token != null) { 5687 ForegroundToken newToken = new ForegroundToken() { 5688 @Override 5689 public void binderDied() { 5690 foregroundTokenDied(this); 5691 } 5692 }; 5693 newToken.pid = pid; 5694 newToken.token = token; 5695 try { 5696 token.linkToDeath(newToken, 0); 5697 mForegroundProcesses.put(pid, newToken); 5698 pr.forcingToForeground = token; 5699 changed = true; 5700 } catch (RemoteException e) { 5701 // If the process died while doing this, we will later 5702 // do the cleanup with the process death link. 5703 } 5704 } 5705 } 5706 5707 if (changed) { 5708 updateOomAdjLocked(); 5709 } 5710 } 5711 } 5712 5713 // ========================================================= 5714 // PERMISSIONS 5715 // ========================================================= 5716 5717 static class PermissionController extends IPermissionController.Stub { 5718 ActivityManagerService mActivityManagerService; 5719 PermissionController(ActivityManagerService activityManagerService) { 5720 mActivityManagerService = activityManagerService; 5721 } 5722 5723 @Override 5724 public boolean checkPermission(String permission, int pid, int uid) { 5725 return mActivityManagerService.checkPermission(permission, pid, 5726 uid) == PackageManager.PERMISSION_GRANTED; 5727 } 5728 } 5729 5730 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5731 @Override 5732 public int checkComponentPermission(String permission, int pid, int uid, 5733 int owningUid, boolean exported) { 5734 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5735 owningUid, exported); 5736 } 5737 5738 @Override 5739 public Object getAMSLock() { 5740 return ActivityManagerService.this; 5741 } 5742 } 5743 5744 /** 5745 * This can be called with or without the global lock held. 5746 */ 5747 int checkComponentPermission(String permission, int pid, int uid, 5748 int owningUid, boolean exported) { 5749 // We might be performing an operation on behalf of an indirect binder 5750 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5751 // client identity accordingly before proceeding. 5752 Identity tlsIdentity = sCallerIdentity.get(); 5753 if (tlsIdentity != null) { 5754 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5755 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5756 uid = tlsIdentity.uid; 5757 pid = tlsIdentity.pid; 5758 } 5759 5760 if (pid == MY_PID) { 5761 return PackageManager.PERMISSION_GRANTED; 5762 } 5763 5764 return ActivityManager.checkComponentPermission(permission, uid, 5765 owningUid, exported); 5766 } 5767 5768 /** 5769 * As the only public entry point for permissions checking, this method 5770 * can enforce the semantic that requesting a check on a null global 5771 * permission is automatically denied. (Internally a null permission 5772 * string is used when calling {@link #checkComponentPermission} in cases 5773 * when only uid-based security is needed.) 5774 * 5775 * This can be called with or without the global lock held. 5776 */ 5777 @Override 5778 public int checkPermission(String permission, int pid, int uid) { 5779 if (permission == null) { 5780 return PackageManager.PERMISSION_DENIED; 5781 } 5782 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5783 } 5784 5785 /** 5786 * Binder IPC calls go through the public entry point. 5787 * This can be called with or without the global lock held. 5788 */ 5789 int checkCallingPermission(String permission) { 5790 return checkPermission(permission, 5791 Binder.getCallingPid(), 5792 UserHandle.getAppId(Binder.getCallingUid())); 5793 } 5794 5795 /** 5796 * This can be called with or without the global lock held. 5797 */ 5798 void enforceCallingPermission(String permission, String func) { 5799 if (checkCallingPermission(permission) 5800 == PackageManager.PERMISSION_GRANTED) { 5801 return; 5802 } 5803 5804 String msg = "Permission Denial: " + func + " from pid=" 5805 + Binder.getCallingPid() 5806 + ", uid=" + Binder.getCallingUid() 5807 + " requires " + permission; 5808 Slog.w(TAG, msg); 5809 throw new SecurityException(msg); 5810 } 5811 5812 /** 5813 * Determine if UID is holding permissions required to access {@link Uri} in 5814 * the given {@link ProviderInfo}. Final permission checking is always done 5815 * in {@link ContentProvider}. 5816 */ 5817 private final boolean checkHoldingPermissionsLocked( 5818 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5819 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5820 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5821 5822 if (pi.applicationInfo.uid == uid) { 5823 return true; 5824 } else if (!pi.exported) { 5825 return false; 5826 } 5827 5828 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5829 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5830 try { 5831 // check if target holds top-level <provider> permissions 5832 if (!readMet && pi.readPermission != null 5833 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5834 readMet = true; 5835 } 5836 if (!writeMet && pi.writePermission != null 5837 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5838 writeMet = true; 5839 } 5840 5841 // track if unprotected read/write is allowed; any denied 5842 // <path-permission> below removes this ability 5843 boolean allowDefaultRead = pi.readPermission == null; 5844 boolean allowDefaultWrite = pi.writePermission == null; 5845 5846 // check if target holds any <path-permission> that match uri 5847 final PathPermission[] pps = pi.pathPermissions; 5848 if (pps != null) { 5849 final String path = uri.getPath(); 5850 int i = pps.length; 5851 while (i > 0 && (!readMet || !writeMet)) { 5852 i--; 5853 PathPermission pp = pps[i]; 5854 if (pp.match(path)) { 5855 if (!readMet) { 5856 final String pprperm = pp.getReadPermission(); 5857 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5858 + pprperm + " for " + pp.getPath() 5859 + ": match=" + pp.match(path) 5860 + " check=" + pm.checkUidPermission(pprperm, uid)); 5861 if (pprperm != null) { 5862 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5863 readMet = true; 5864 } else { 5865 allowDefaultRead = false; 5866 } 5867 } 5868 } 5869 if (!writeMet) { 5870 final String ppwperm = pp.getWritePermission(); 5871 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5872 + ppwperm + " for " + pp.getPath() 5873 + ": match=" + pp.match(path) 5874 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5875 if (ppwperm != null) { 5876 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5877 writeMet = true; 5878 } else { 5879 allowDefaultWrite = false; 5880 } 5881 } 5882 } 5883 } 5884 } 5885 } 5886 5887 // grant unprotected <provider> read/write, if not blocked by 5888 // <path-permission> above 5889 if (allowDefaultRead) readMet = true; 5890 if (allowDefaultWrite) writeMet = true; 5891 5892 } catch (RemoteException e) { 5893 return false; 5894 } 5895 5896 return readMet && writeMet; 5897 } 5898 5899 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5900 ProviderInfo pi = null; 5901 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5902 if (cpr != null) { 5903 pi = cpr.info; 5904 } else { 5905 try { 5906 pi = AppGlobals.getPackageManager().resolveContentProvider( 5907 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5908 } catch (RemoteException ex) { 5909 } 5910 } 5911 return pi; 5912 } 5913 5914 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5915 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5916 if (targetUris != null) { 5917 return targetUris.get(uri); 5918 } else { 5919 return null; 5920 } 5921 } 5922 5923 private UriPermission findOrCreateUriPermissionLocked( 5924 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5925 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5926 if (targetUris == null) { 5927 targetUris = Maps.newArrayMap(); 5928 mGrantedUriPermissions.put(targetUid, targetUris); 5929 } 5930 5931 UriPermission perm = targetUris.get(uri); 5932 if (perm == null) { 5933 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5934 targetUris.put(uri, perm); 5935 } 5936 5937 return perm; 5938 } 5939 5940 private final boolean checkUriPermissionLocked( 5941 Uri uri, int uid, int modeFlags, int minStrength) { 5942 // Root gets to do everything. 5943 if (uid == 0) { 5944 return true; 5945 } 5946 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5947 if (perms == null) return false; 5948 UriPermission perm = perms.get(uri); 5949 if (perm == null) return false; 5950 return perm.getStrength(modeFlags) >= minStrength; 5951 } 5952 5953 @Override 5954 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5955 enforceNotIsolatedCaller("checkUriPermission"); 5956 5957 // Another redirected-binder-call permissions check as in 5958 // {@link checkComponentPermission}. 5959 Identity tlsIdentity = sCallerIdentity.get(); 5960 if (tlsIdentity != null) { 5961 uid = tlsIdentity.uid; 5962 pid = tlsIdentity.pid; 5963 } 5964 5965 // Our own process gets to do everything. 5966 if (pid == MY_PID) { 5967 return PackageManager.PERMISSION_GRANTED; 5968 } 5969 synchronized(this) { 5970 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5971 ? PackageManager.PERMISSION_GRANTED 5972 : PackageManager.PERMISSION_DENIED; 5973 } 5974 } 5975 5976 /** 5977 * Check if the targetPkg can be granted permission to access uri by 5978 * the callingUid using the given modeFlags. Throws a security exception 5979 * if callingUid is not allowed to do this. Returns the uid of the target 5980 * if the URI permission grant should be performed; returns -1 if it is not 5981 * needed (for example targetPkg already has permission to access the URI). 5982 * If you already know the uid of the target, you can supply it in 5983 * lastTargetUid else set that to -1. 5984 */ 5985 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5986 Uri uri, int modeFlags, int lastTargetUid) { 5987 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5988 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5989 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5990 if (modeFlags == 0) { 5991 return -1; 5992 } 5993 5994 if (targetPkg != null) { 5995 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5996 "Checking grant " + targetPkg + " permission to " + uri); 5997 } 5998 5999 final IPackageManager pm = AppGlobals.getPackageManager(); 6000 6001 // If this is not a content: uri, we can't do anything with it. 6002 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6003 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6004 "Can't grant URI permission for non-content URI: " + uri); 6005 return -1; 6006 } 6007 6008 final String authority = uri.getAuthority(); 6009 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6010 if (pi == null) { 6011 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6012 return -1; 6013 } 6014 6015 int targetUid = lastTargetUid; 6016 if (targetUid < 0 && targetPkg != null) { 6017 try { 6018 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6019 if (targetUid < 0) { 6020 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6021 "Can't grant URI permission no uid for: " + targetPkg); 6022 return -1; 6023 } 6024 } catch (RemoteException ex) { 6025 return -1; 6026 } 6027 } 6028 6029 if (targetUid >= 0) { 6030 // First... does the target actually need this permission? 6031 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6032 // No need to grant the target this permission. 6033 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6034 "Target " + targetPkg + " already has full permission to " + uri); 6035 return -1; 6036 } 6037 } else { 6038 // First... there is no target package, so can anyone access it? 6039 boolean allowed = pi.exported; 6040 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6041 if (pi.readPermission != null) { 6042 allowed = false; 6043 } 6044 } 6045 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6046 if (pi.writePermission != null) { 6047 allowed = false; 6048 } 6049 } 6050 if (allowed) { 6051 return -1; 6052 } 6053 } 6054 6055 // Second... is the provider allowing granting of URI permissions? 6056 if (!pi.grantUriPermissions) { 6057 throw new SecurityException("Provider " + pi.packageName 6058 + "/" + pi.name 6059 + " does not allow granting of Uri permissions (uri " 6060 + uri + ")"); 6061 } 6062 if (pi.uriPermissionPatterns != null) { 6063 final int N = pi.uriPermissionPatterns.length; 6064 boolean allowed = false; 6065 for (int i=0; i<N; i++) { 6066 if (pi.uriPermissionPatterns[i] != null 6067 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6068 allowed = true; 6069 break; 6070 } 6071 } 6072 if (!allowed) { 6073 throw new SecurityException("Provider " + pi.packageName 6074 + "/" + pi.name 6075 + " does not allow granting of permission to path of Uri " 6076 + uri); 6077 } 6078 } 6079 6080 // Third... does the caller itself have permission to access 6081 // this uri? 6082 if (callingUid != Process.myUid()) { 6083 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6084 // Require they hold a strong enough Uri permission 6085 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6086 : UriPermission.STRENGTH_OWNED; 6087 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6088 throw new SecurityException("Uid " + callingUid 6089 + " does not have permission to uri " + uri); 6090 } 6091 } 6092 } 6093 6094 return targetUid; 6095 } 6096 6097 @Override 6098 public int checkGrantUriPermission(int callingUid, String targetPkg, 6099 Uri uri, int modeFlags) { 6100 enforceNotIsolatedCaller("checkGrantUriPermission"); 6101 synchronized(this) { 6102 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6103 } 6104 } 6105 6106 void grantUriPermissionUncheckedLocked( 6107 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6108 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6109 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6110 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6111 if (modeFlags == 0) { 6112 return; 6113 } 6114 6115 // So here we are: the caller has the assumed permission 6116 // to the uri, and the target doesn't. Let's now give this to 6117 // the target. 6118 6119 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6120 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6121 6122 final String authority = uri.getAuthority(); 6123 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6124 if (pi == null) { 6125 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6126 return; 6127 } 6128 6129 final UriPermission perm = findOrCreateUriPermissionLocked( 6130 pi.packageName, targetPkg, targetUid, uri); 6131 perm.grantModes(modeFlags, persistable, owner); 6132 } 6133 6134 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6135 int modeFlags, UriPermissionOwner owner) { 6136 if (targetPkg == null) { 6137 throw new NullPointerException("targetPkg"); 6138 } 6139 6140 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6141 if (targetUid < 0) { 6142 return; 6143 } 6144 6145 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6146 } 6147 6148 static class NeededUriGrants extends ArrayList<Uri> { 6149 final String targetPkg; 6150 final int targetUid; 6151 final int flags; 6152 6153 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6154 this.targetPkg = targetPkg; 6155 this.targetUid = targetUid; 6156 this.flags = flags; 6157 } 6158 } 6159 6160 /** 6161 * Like checkGrantUriPermissionLocked, but takes an Intent. 6162 */ 6163 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6164 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6165 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6166 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6167 + " clip=" + (intent != null ? intent.getClipData() : null) 6168 + " from " + intent + "; flags=0x" 6169 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6170 6171 if (targetPkg == null) { 6172 throw new NullPointerException("targetPkg"); 6173 } 6174 6175 if (intent == null) { 6176 return null; 6177 } 6178 Uri data = intent.getData(); 6179 ClipData clip = intent.getClipData(); 6180 if (data == null && clip == null) { 6181 return null; 6182 } 6183 6184 if (data != null) { 6185 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6186 mode, needed != null ? needed.targetUid : -1); 6187 if (targetUid > 0) { 6188 if (needed == null) { 6189 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6190 } 6191 needed.add(data); 6192 } 6193 } 6194 if (clip != null) { 6195 for (int i=0; i<clip.getItemCount(); i++) { 6196 Uri uri = clip.getItemAt(i).getUri(); 6197 if (uri != null) { 6198 int targetUid = -1; 6199 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6200 mode, needed != null ? needed.targetUid : -1); 6201 if (targetUid > 0) { 6202 if (needed == null) { 6203 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6204 } 6205 needed.add(uri); 6206 } 6207 } else { 6208 Intent clipIntent = clip.getItemAt(i).getIntent(); 6209 if (clipIntent != null) { 6210 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6211 callingUid, targetPkg, clipIntent, mode, needed); 6212 if (newNeeded != null) { 6213 needed = newNeeded; 6214 } 6215 } 6216 } 6217 } 6218 } 6219 6220 return needed; 6221 } 6222 6223 /** 6224 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6225 */ 6226 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6227 UriPermissionOwner owner) { 6228 if (needed != null) { 6229 for (int i=0; i<needed.size(); i++) { 6230 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6231 needed.get(i), needed.flags, owner); 6232 } 6233 } 6234 } 6235 6236 void grantUriPermissionFromIntentLocked(int callingUid, 6237 String targetPkg, Intent intent, UriPermissionOwner owner) { 6238 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6239 intent, intent != null ? intent.getFlags() : 0, null); 6240 if (needed == null) { 6241 return; 6242 } 6243 6244 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6245 } 6246 6247 @Override 6248 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6249 Uri uri, int modeFlags) { 6250 enforceNotIsolatedCaller("grantUriPermission"); 6251 synchronized(this) { 6252 final ProcessRecord r = getRecordForAppLocked(caller); 6253 if (r == null) { 6254 throw new SecurityException("Unable to find app for caller " 6255 + caller 6256 + " when granting permission to uri " + uri); 6257 } 6258 if (targetPkg == null) { 6259 throw new IllegalArgumentException("null target"); 6260 } 6261 if (uri == null) { 6262 throw new IllegalArgumentException("null uri"); 6263 } 6264 6265 // Persistable only supported through Intents 6266 Preconditions.checkFlagsArgument(modeFlags, 6267 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6268 6269 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6270 null); 6271 } 6272 } 6273 6274 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6275 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6276 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6277 ArrayMap<Uri, UriPermission> perms 6278 = mGrantedUriPermissions.get(perm.targetUid); 6279 if (perms != null) { 6280 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6281 "Removing " + perm.targetUid + " permission to " + perm.uri); 6282 perms.remove(perm.uri); 6283 if (perms.size() == 0) { 6284 mGrantedUriPermissions.remove(perm.targetUid); 6285 } 6286 } 6287 } 6288 } 6289 6290 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6291 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6292 6293 final IPackageManager pm = AppGlobals.getPackageManager(); 6294 final String authority = uri.getAuthority(); 6295 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6296 if (pi == null) { 6297 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6298 return; 6299 } 6300 6301 // Does the caller have this permission on the URI? 6302 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6303 // Right now, if you are not the original owner of the permission, 6304 // you are not allowed to revoke it. 6305 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6306 throw new SecurityException("Uid " + callingUid 6307 + " does not have permission to uri " + uri); 6308 //} 6309 } 6310 6311 boolean persistChanged = false; 6312 6313 // Go through all of the permissions and remove any that match. 6314 final List<String> SEGMENTS = uri.getPathSegments(); 6315 if (SEGMENTS != null) { 6316 final int NS = SEGMENTS.size(); 6317 int N = mGrantedUriPermissions.size(); 6318 for (int i=0; i<N; i++) { 6319 ArrayMap<Uri, UriPermission> perms 6320 = mGrantedUriPermissions.valueAt(i); 6321 Iterator<UriPermission> it = perms.values().iterator(); 6322 toploop: 6323 while (it.hasNext()) { 6324 UriPermission perm = it.next(); 6325 Uri targetUri = perm.uri; 6326 if (!authority.equals(targetUri.getAuthority())) { 6327 continue; 6328 } 6329 List<String> targetSegments = targetUri.getPathSegments(); 6330 if (targetSegments == null) { 6331 continue; 6332 } 6333 if (targetSegments.size() < NS) { 6334 continue; 6335 } 6336 for (int j=0; j<NS; j++) { 6337 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6338 continue toploop; 6339 } 6340 } 6341 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6342 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6343 persistChanged |= perm.clearModes(modeFlags, true); 6344 if (perm.modeFlags == 0) { 6345 it.remove(); 6346 } 6347 } 6348 if (perms.size() == 0) { 6349 mGrantedUriPermissions.remove( 6350 mGrantedUriPermissions.keyAt(i)); 6351 N--; 6352 i--; 6353 } 6354 } 6355 } 6356 6357 if (persistChanged) { 6358 schedulePersistUriGrants(); 6359 } 6360 } 6361 6362 @Override 6363 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6364 int modeFlags) { 6365 enforceNotIsolatedCaller("revokeUriPermission"); 6366 synchronized(this) { 6367 final ProcessRecord r = getRecordForAppLocked(caller); 6368 if (r == null) { 6369 throw new SecurityException("Unable to find app for caller " 6370 + caller 6371 + " when revoking permission to uri " + uri); 6372 } 6373 if (uri == null) { 6374 Slog.w(TAG, "revokeUriPermission: null uri"); 6375 return; 6376 } 6377 6378 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6379 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6380 if (modeFlags == 0) { 6381 return; 6382 } 6383 6384 final IPackageManager pm = AppGlobals.getPackageManager(); 6385 final String authority = uri.getAuthority(); 6386 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6387 if (pi == null) { 6388 Slog.w(TAG, "No content provider found for permission revoke: " 6389 + uri.toSafeString()); 6390 return; 6391 } 6392 6393 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6394 } 6395 } 6396 6397 /** 6398 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6399 * given package. 6400 * 6401 * @param packageName Package name to match, or {@code null} to apply to all 6402 * packages. 6403 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6404 * to all users. 6405 * @param persistable If persistable grants should be removed. 6406 */ 6407 private void removeUriPermissionsForPackageLocked( 6408 String packageName, int userHandle, boolean persistable) { 6409 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6410 throw new IllegalArgumentException("Must narrow by either package or user"); 6411 } 6412 6413 boolean persistChanged = false; 6414 6415 final int size = mGrantedUriPermissions.size(); 6416 for (int i = 0; i < size; i++) { 6417 // Only inspect grants matching user 6418 if (userHandle == UserHandle.USER_ALL 6419 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6420 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6421 .values().iterator(); 6422 while (it.hasNext()) { 6423 final UriPermission perm = it.next(); 6424 6425 // Only inspect grants matching package 6426 if (packageName == null || perm.sourcePkg.equals(packageName) 6427 || perm.targetPkg.equals(packageName)) { 6428 persistChanged |= perm.clearModes(~0, persistable); 6429 6430 // Only remove when no modes remain; any persisted grants 6431 // will keep this alive. 6432 if (perm.modeFlags == 0) { 6433 it.remove(); 6434 } 6435 } 6436 } 6437 } 6438 } 6439 6440 if (persistChanged) { 6441 schedulePersistUriGrants(); 6442 } 6443 } 6444 6445 @Override 6446 public IBinder newUriPermissionOwner(String name) { 6447 enforceNotIsolatedCaller("newUriPermissionOwner"); 6448 synchronized(this) { 6449 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6450 return owner.getExternalTokenLocked(); 6451 } 6452 } 6453 6454 @Override 6455 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6456 Uri uri, int modeFlags) { 6457 synchronized(this) { 6458 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6459 if (owner == null) { 6460 throw new IllegalArgumentException("Unknown owner: " + token); 6461 } 6462 if (fromUid != Binder.getCallingUid()) { 6463 if (Binder.getCallingUid() != Process.myUid()) { 6464 // Only system code can grant URI permissions on behalf 6465 // of other users. 6466 throw new SecurityException("nice try"); 6467 } 6468 } 6469 if (targetPkg == null) { 6470 throw new IllegalArgumentException("null target"); 6471 } 6472 if (uri == null) { 6473 throw new IllegalArgumentException("null uri"); 6474 } 6475 6476 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6477 } 6478 } 6479 6480 @Override 6481 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6482 synchronized(this) { 6483 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6484 if (owner == null) { 6485 throw new IllegalArgumentException("Unknown owner: " + token); 6486 } 6487 6488 if (uri == null) { 6489 owner.removeUriPermissionsLocked(mode); 6490 } else { 6491 owner.removeUriPermissionLocked(uri, mode); 6492 } 6493 } 6494 } 6495 6496 private void schedulePersistUriGrants() { 6497 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6498 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6499 10 * DateUtils.SECOND_IN_MILLIS); 6500 } 6501 } 6502 6503 private void writeGrantedUriPermissions() { 6504 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6505 6506 // Snapshot permissions so we can persist without lock 6507 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6508 synchronized (this) { 6509 final int size = mGrantedUriPermissions.size(); 6510 for (int i = 0 ; i < size; i++) { 6511 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6512 if (perm.persistedModeFlags != 0) { 6513 persist.add(perm.snapshot()); 6514 } 6515 } 6516 } 6517 } 6518 6519 FileOutputStream fos = null; 6520 try { 6521 fos = mGrantFile.startWrite(); 6522 6523 XmlSerializer out = new FastXmlSerializer(); 6524 out.setOutput(fos, "utf-8"); 6525 out.startDocument(null, true); 6526 out.startTag(null, TAG_URI_GRANTS); 6527 for (UriPermission.Snapshot perm : persist) { 6528 out.startTag(null, TAG_URI_GRANT); 6529 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6530 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6531 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6532 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6533 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6534 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6535 out.endTag(null, TAG_URI_GRANT); 6536 } 6537 out.endTag(null, TAG_URI_GRANTS); 6538 out.endDocument(); 6539 6540 mGrantFile.finishWrite(fos); 6541 } catch (IOException e) { 6542 if (fos != null) { 6543 mGrantFile.failWrite(fos); 6544 } 6545 } 6546 } 6547 6548 private void readGrantedUriPermissionsLocked() { 6549 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6550 6551 final long now = System.currentTimeMillis(); 6552 6553 FileInputStream fis = null; 6554 try { 6555 fis = mGrantFile.openRead(); 6556 final XmlPullParser in = Xml.newPullParser(); 6557 in.setInput(fis, null); 6558 6559 int type; 6560 while ((type = in.next()) != END_DOCUMENT) { 6561 final String tag = in.getName(); 6562 if (type == START_TAG) { 6563 if (TAG_URI_GRANT.equals(tag)) { 6564 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6565 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6566 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6567 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6568 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6569 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6570 6571 // Sanity check that provider still belongs to source package 6572 final ProviderInfo pi = getProviderInfoLocked( 6573 uri.getAuthority(), userHandle); 6574 if (pi != null && sourcePkg.equals(pi.packageName)) { 6575 int targetUid = -1; 6576 try { 6577 targetUid = AppGlobals.getPackageManager() 6578 .getPackageUid(targetPkg, userHandle); 6579 } catch (RemoteException e) { 6580 } 6581 if (targetUid != -1) { 6582 final UriPermission perm = findOrCreateUriPermissionLocked( 6583 sourcePkg, targetPkg, targetUid, uri); 6584 perm.initPersistedModes(modeFlags, createdTime); 6585 } 6586 } else { 6587 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6588 + " but instead found " + pi); 6589 } 6590 } 6591 } 6592 } 6593 } catch (FileNotFoundException e) { 6594 // Missing grants is okay 6595 } catch (IOException e) { 6596 Log.wtf(TAG, "Failed reading Uri grants", e); 6597 } catch (XmlPullParserException e) { 6598 Log.wtf(TAG, "Failed reading Uri grants", e); 6599 } finally { 6600 IoUtils.closeQuietly(fis); 6601 } 6602 } 6603 6604 @Override 6605 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6606 enforceNotIsolatedCaller("takePersistableUriPermission"); 6607 6608 Preconditions.checkFlagsArgument(modeFlags, 6609 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6610 6611 synchronized (this) { 6612 final int callingUid = Binder.getCallingUid(); 6613 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6614 if (perm == null) { 6615 throw new SecurityException("No permission grant found for UID " + callingUid 6616 + " and Uri " + uri.toSafeString()); 6617 } 6618 6619 boolean persistChanged = perm.takePersistableModes(modeFlags); 6620 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6621 6622 if (persistChanged) { 6623 schedulePersistUriGrants(); 6624 } 6625 } 6626 } 6627 6628 @Override 6629 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6630 enforceNotIsolatedCaller("releasePersistableUriPermission"); 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 6638 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6639 if (perm == null) { 6640 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6641 + uri.toSafeString()); 6642 return; 6643 } 6644 6645 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6646 removeUriPermissionIfNeededLocked(perm); 6647 if (persistChanged) { 6648 schedulePersistUriGrants(); 6649 } 6650 } 6651 } 6652 6653 /** 6654 * Prune any older {@link UriPermission} for the given UID until outstanding 6655 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6656 * 6657 * @return if any mutations occured that require persisting. 6658 */ 6659 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6660 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6661 if (perms == null) return false; 6662 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6663 6664 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6665 for (UriPermission perm : perms.values()) { 6666 if (perm.persistedModeFlags != 0) { 6667 persisted.add(perm); 6668 } 6669 } 6670 6671 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6672 if (trimCount <= 0) return false; 6673 6674 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6675 for (int i = 0; i < trimCount; i++) { 6676 final UriPermission perm = persisted.get(i); 6677 6678 if (DEBUG_URI_PERMISSION) { 6679 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6680 } 6681 6682 perm.releasePersistableModes(~0); 6683 removeUriPermissionIfNeededLocked(perm); 6684 } 6685 6686 return true; 6687 } 6688 6689 @Override 6690 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6691 String packageName, boolean incoming) { 6692 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6693 Preconditions.checkNotNull(packageName, "packageName"); 6694 6695 final int callingUid = Binder.getCallingUid(); 6696 final IPackageManager pm = AppGlobals.getPackageManager(); 6697 try { 6698 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6699 if (packageUid != callingUid) { 6700 throw new SecurityException( 6701 "Package " + packageName + " does not belong to calling UID " + callingUid); 6702 } 6703 } catch (RemoteException e) { 6704 throw new SecurityException("Failed to verify package name ownership"); 6705 } 6706 6707 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6708 synchronized (this) { 6709 if (incoming) { 6710 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6711 if (perms == null) { 6712 Slog.w(TAG, "No permission grants found for " + packageName); 6713 } else { 6714 final int size = perms.size(); 6715 for (int i = 0; i < size; i++) { 6716 final UriPermission perm = perms.valueAt(i); 6717 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6718 result.add(perm.buildPersistedPublicApiObject()); 6719 } 6720 } 6721 } 6722 } else { 6723 final int size = mGrantedUriPermissions.size(); 6724 for (int i = 0; i < size; i++) { 6725 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6726 final int permsSize = perms.size(); 6727 for (int j = 0; j < permsSize; j++) { 6728 final UriPermission perm = perms.valueAt(j); 6729 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6730 result.add(perm.buildPersistedPublicApiObject()); 6731 } 6732 } 6733 } 6734 } 6735 } 6736 return new ParceledListSlice<android.content.UriPermission>(result); 6737 } 6738 6739 @Override 6740 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6741 synchronized (this) { 6742 ProcessRecord app = 6743 who != null ? getRecordForAppLocked(who) : null; 6744 if (app == null) return; 6745 6746 Message msg = Message.obtain(); 6747 msg.what = WAIT_FOR_DEBUGGER_MSG; 6748 msg.obj = app; 6749 msg.arg1 = waiting ? 1 : 0; 6750 mHandler.sendMessage(msg); 6751 } 6752 } 6753 6754 @Override 6755 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6756 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6757 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6758 outInfo.availMem = Process.getFreeMemory(); 6759 outInfo.totalMem = Process.getTotalMemory(); 6760 outInfo.threshold = homeAppMem; 6761 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6762 outInfo.hiddenAppThreshold = cachedAppMem; 6763 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6764 ProcessList.SERVICE_ADJ); 6765 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6766 ProcessList.VISIBLE_APP_ADJ); 6767 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6768 ProcessList.FOREGROUND_APP_ADJ); 6769 } 6770 6771 // ========================================================= 6772 // TASK MANAGEMENT 6773 // ========================================================= 6774 6775 @Override 6776 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6777 IThumbnailReceiver receiver) { 6778 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6779 6780 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6781 ActivityRecord topRecord = null; 6782 6783 synchronized(this) { 6784 if (localLOGV) Slog.v( 6785 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6786 + ", receiver=" + receiver); 6787 6788 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6789 != PackageManager.PERMISSION_GRANTED) { 6790 if (receiver != null) { 6791 // If the caller wants to wait for pending thumbnails, 6792 // it ain't gonna get them. 6793 try { 6794 receiver.finished(); 6795 } catch (RemoteException ex) { 6796 } 6797 } 6798 String msg = "Permission Denial: getTasks() from pid=" 6799 + Binder.getCallingPid() 6800 + ", uid=" + Binder.getCallingUid() 6801 + " requires " + android.Manifest.permission.GET_TASKS; 6802 Slog.w(TAG, msg); 6803 throw new SecurityException(msg); 6804 } 6805 6806 // TODO: Improve with MRU list from all ActivityStacks. 6807 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6808 6809 if (!pending.pendingRecords.isEmpty()) { 6810 mPendingThumbnails.add(pending); 6811 } 6812 } 6813 6814 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6815 6816 if (topRecord != null) { 6817 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6818 try { 6819 IApplicationThread topThumbnail = topRecord.app.thread; 6820 topThumbnail.requestThumbnail(topRecord.appToken); 6821 } catch (Exception e) { 6822 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6823 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6824 } 6825 } 6826 6827 if (pending.pendingRecords.isEmpty() && receiver != null) { 6828 // In this case all thumbnails were available and the client 6829 // is being asked to be told when the remaining ones come in... 6830 // which is unusually, since the top-most currently running 6831 // activity should never have a canned thumbnail! Oh well. 6832 try { 6833 receiver.finished(); 6834 } catch (RemoteException ex) { 6835 } 6836 } 6837 6838 return list; 6839 } 6840 6841 TaskRecord getMostRecentTask() { 6842 return mRecentTasks.get(0); 6843 } 6844 6845 @Override 6846 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6847 int flags, int userId) { 6848 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6849 false, true, "getRecentTasks", null); 6850 6851 synchronized (this) { 6852 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6853 "getRecentTasks()"); 6854 final boolean detailed = checkCallingPermission( 6855 android.Manifest.permission.GET_DETAILED_TASKS) 6856 == PackageManager.PERMISSION_GRANTED; 6857 6858 IPackageManager pm = AppGlobals.getPackageManager(); 6859 6860 final int N = mRecentTasks.size(); 6861 ArrayList<ActivityManager.RecentTaskInfo> res 6862 = new ArrayList<ActivityManager.RecentTaskInfo>( 6863 maxNum < N ? maxNum : N); 6864 6865 final Set<Integer> includedUsers; 6866 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 6867 includedUsers = getProfileIdsLocked(userId); 6868 } else { 6869 includedUsers = new HashSet<Integer>(); 6870 } 6871 includedUsers.add(Integer.valueOf(userId)); 6872 for (int i=0; i<N && maxNum > 0; i++) { 6873 TaskRecord tr = mRecentTasks.get(i); 6874 // Only add calling user or related users recent tasks 6875 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 6876 6877 // Return the entry if desired by the caller. We always return 6878 // the first entry, because callers always expect this to be the 6879 // foreground app. We may filter others if the caller has 6880 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6881 // we should exclude the entry. 6882 6883 if (i == 0 6884 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6885 || (tr.intent == null) 6886 || ((tr.intent.getFlags() 6887 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6888 ActivityManager.RecentTaskInfo rti 6889 = new ActivityManager.RecentTaskInfo(); 6890 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6891 rti.persistentId = tr.taskId; 6892 rti.baseIntent = new Intent( 6893 tr.intent != null ? tr.intent : tr.affinityIntent); 6894 if (!detailed) { 6895 rti.baseIntent.replaceExtras((Bundle)null); 6896 } 6897 rti.origActivity = tr.origActivity; 6898 rti.description = tr.lastDescription; 6899 rti.stackId = tr.stack.mStackId; 6900 rti.userId = tr.userId; 6901 6902 final ArrayList<ActivityRecord> activities = tr.mActivities; 6903 int numSet = 0; 6904 for (int activityNdx = activities.size() - 1; activityNdx >= 0 && numSet < 2; 6905 --activityNdx) { 6906 final ActivityRecord r = activities.get(activityNdx); 6907 if (rti.activityLabel == null && r.recentsLabel != null) { 6908 rti.activityLabel = r.recentsLabel; 6909 ++numSet; 6910 } 6911 if (rti.activityIcon == null && r.recentsIcon != null) { 6912 rti.activityIcon = r.recentsIcon; 6913 ++numSet; 6914 } 6915 } 6916 6917 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6918 // Check whether this activity is currently available. 6919 try { 6920 if (rti.origActivity != null) { 6921 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6922 == null) { 6923 continue; 6924 } 6925 } else if (rti.baseIntent != null) { 6926 if (pm.queryIntentActivities(rti.baseIntent, 6927 null, 0, userId) == null) { 6928 continue; 6929 } 6930 } 6931 } catch (RemoteException e) { 6932 // Will never happen. 6933 } 6934 } 6935 6936 res.add(rti); 6937 maxNum--; 6938 } 6939 } 6940 return res; 6941 } 6942 } 6943 6944 private TaskRecord recentTaskForIdLocked(int id) { 6945 final int N = mRecentTasks.size(); 6946 for (int i=0; i<N; i++) { 6947 TaskRecord tr = mRecentTasks.get(i); 6948 if (tr.taskId == id) { 6949 return tr; 6950 } 6951 } 6952 return null; 6953 } 6954 6955 @Override 6956 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6957 synchronized (this) { 6958 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6959 "getTaskThumbnails()"); 6960 TaskRecord tr = recentTaskForIdLocked(id); 6961 if (tr != null) { 6962 return tr.getTaskThumbnailsLocked(); 6963 } 6964 } 6965 return null; 6966 } 6967 6968 @Override 6969 public Bitmap getTaskTopThumbnail(int id) { 6970 synchronized (this) { 6971 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6972 "getTaskTopThumbnail()"); 6973 TaskRecord tr = recentTaskForIdLocked(id); 6974 if (tr != null) { 6975 return tr.getTaskTopThumbnailLocked(); 6976 } 6977 } 6978 return null; 6979 } 6980 6981 @Override 6982 public void setRecentsLabel(IBinder token, CharSequence recentsLabel) { 6983 synchronized (this) { 6984 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6985 if (r != null) { 6986 r.recentsLabel = recentsLabel.toString(); 6987 } 6988 } 6989 } 6990 6991 @Override 6992 public void setRecentsIcon(IBinder token, Bitmap recentsIcon) { 6993 synchronized (this) { 6994 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6995 if (r != null) { 6996 r.recentsIcon = recentsIcon; 6997 } 6998 } 6999 } 7000 7001 @Override 7002 public boolean removeSubTask(int taskId, int subTaskIndex) { 7003 synchronized (this) { 7004 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7005 "removeSubTask()"); 7006 long ident = Binder.clearCallingIdentity(); 7007 try { 7008 TaskRecord tr = recentTaskForIdLocked(taskId); 7009 if (tr != null) { 7010 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7011 } 7012 return false; 7013 } finally { 7014 Binder.restoreCallingIdentity(ident); 7015 } 7016 } 7017 } 7018 7019 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7020 if (!pr.killedByAm) { 7021 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7022 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7023 pr.processName, pr.setAdj, reason); 7024 pr.killedByAm = true; 7025 Process.killProcessQuiet(pr.pid); 7026 } 7027 } 7028 7029 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7030 tr.disposeThumbnail(); 7031 mRecentTasks.remove(tr); 7032 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7033 Intent baseIntent = new Intent( 7034 tr.intent != null ? tr.intent : tr.affinityIntent); 7035 ComponentName component = baseIntent.getComponent(); 7036 if (component == null) { 7037 Slog.w(TAG, "Now component for base intent of task: " + tr); 7038 return; 7039 } 7040 7041 // Find any running services associated with this app. 7042 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7043 7044 if (killProcesses) { 7045 // Find any running processes associated with this app. 7046 final String pkg = component.getPackageName(); 7047 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7048 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7049 for (int i=0; i<pmap.size(); i++) { 7050 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7051 for (int j=0; j<uids.size(); j++) { 7052 ProcessRecord proc = uids.valueAt(j); 7053 if (proc.userId != tr.userId) { 7054 continue; 7055 } 7056 if (!proc.pkgList.containsKey(pkg)) { 7057 continue; 7058 } 7059 procs.add(proc); 7060 } 7061 } 7062 7063 // Kill the running processes. 7064 for (int i=0; i<procs.size(); i++) { 7065 ProcessRecord pr = procs.get(i); 7066 if (pr == mHomeProcess) { 7067 // Don't kill the home process along with tasks from the same package. 7068 continue; 7069 } 7070 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7071 killUnneededProcessLocked(pr, "remove task"); 7072 } else { 7073 pr.waitingToKill = "remove task"; 7074 } 7075 } 7076 } 7077 } 7078 7079 @Override 7080 public boolean removeTask(int taskId, int flags) { 7081 synchronized (this) { 7082 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7083 "removeTask()"); 7084 long ident = Binder.clearCallingIdentity(); 7085 try { 7086 TaskRecord tr = recentTaskForIdLocked(taskId); 7087 if (tr != null) { 7088 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7089 if (r != null) { 7090 cleanUpRemovedTaskLocked(tr, flags); 7091 return true; 7092 } 7093 if (tr.mActivities.size() == 0) { 7094 // Caller is just removing a recent task that is 7095 // not actively running. That is easy! 7096 cleanUpRemovedTaskLocked(tr, flags); 7097 return true; 7098 } 7099 Slog.w(TAG, "removeTask: task " + taskId 7100 + " does not have activities to remove, " 7101 + " but numActivities=" + tr.numActivities 7102 + ": " + tr); 7103 } 7104 } finally { 7105 Binder.restoreCallingIdentity(ident); 7106 } 7107 } 7108 return false; 7109 } 7110 7111 /** 7112 * TODO: Add mController hook 7113 */ 7114 @Override 7115 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7116 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7117 "moveTaskToFront()"); 7118 7119 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7120 synchronized(this) { 7121 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7122 Binder.getCallingUid(), "Task to front")) { 7123 ActivityOptions.abort(options); 7124 return; 7125 } 7126 final long origId = Binder.clearCallingIdentity(); 7127 try { 7128 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7129 if (task == null) { 7130 return; 7131 } 7132 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7133 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7134 return; 7135 } 7136 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7137 } finally { 7138 Binder.restoreCallingIdentity(origId); 7139 } 7140 ActivityOptions.abort(options); 7141 } 7142 } 7143 7144 @Override 7145 public void moveTaskToBack(int taskId) { 7146 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7147 "moveTaskToBack()"); 7148 7149 synchronized(this) { 7150 TaskRecord tr = recentTaskForIdLocked(taskId); 7151 if (tr != null) { 7152 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7153 ActivityStack stack = tr.stack; 7154 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7155 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7156 Binder.getCallingUid(), "Task to back")) { 7157 return; 7158 } 7159 } 7160 final long origId = Binder.clearCallingIdentity(); 7161 try { 7162 stack.moveTaskToBackLocked(taskId, null); 7163 } finally { 7164 Binder.restoreCallingIdentity(origId); 7165 } 7166 } 7167 } 7168 } 7169 7170 /** 7171 * Moves an activity, and all of the other activities within the same task, to the bottom 7172 * of the history stack. The activity's order within the task is unchanged. 7173 * 7174 * @param token A reference to the activity we wish to move 7175 * @param nonRoot If false then this only works if the activity is the root 7176 * of a task; if true it will work for any activity in a task. 7177 * @return Returns true if the move completed, false if not. 7178 */ 7179 @Override 7180 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7181 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7182 synchronized(this) { 7183 final long origId = Binder.clearCallingIdentity(); 7184 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7185 if (taskId >= 0) { 7186 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7187 } 7188 Binder.restoreCallingIdentity(origId); 7189 } 7190 return false; 7191 } 7192 7193 @Override 7194 public void moveTaskBackwards(int task) { 7195 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7196 "moveTaskBackwards()"); 7197 7198 synchronized(this) { 7199 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7200 Binder.getCallingUid(), "Task backwards")) { 7201 return; 7202 } 7203 final long origId = Binder.clearCallingIdentity(); 7204 moveTaskBackwardsLocked(task); 7205 Binder.restoreCallingIdentity(origId); 7206 } 7207 } 7208 7209 private final void moveTaskBackwardsLocked(int task) { 7210 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7211 } 7212 7213 @Override 7214 public IBinder getHomeActivityToken() throws RemoteException { 7215 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7216 "getHomeActivityToken()"); 7217 synchronized (this) { 7218 return mStackSupervisor.getHomeActivityToken(); 7219 } 7220 } 7221 7222 @Override 7223 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7224 IActivityContainerCallback callback) throws RemoteException { 7225 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7226 "createActivityContainer()"); 7227 synchronized (this) { 7228 if (parentActivityToken == null) { 7229 throw new IllegalArgumentException("parent token must not be null"); 7230 } 7231 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7232 if (r == null) { 7233 return null; 7234 } 7235 return mStackSupervisor.createActivityContainer(r, callback); 7236 } 7237 } 7238 7239 @Override 7240 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7241 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7242 "deleteActivityContainer()"); 7243 synchronized (this) { 7244 mStackSupervisor.deleteActivityContainer(container); 7245 } 7246 } 7247 7248 @Override 7249 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7250 throws RemoteException { 7251 synchronized (this) { 7252 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7253 if (stack != null) { 7254 return stack.mActivityContainer; 7255 } 7256 return null; 7257 } 7258 } 7259 7260 @Override 7261 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7262 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7263 "moveTaskToStack()"); 7264 if (stackId == HOME_STACK_ID) { 7265 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7266 new RuntimeException("here").fillInStackTrace()); 7267 } 7268 synchronized (this) { 7269 long ident = Binder.clearCallingIdentity(); 7270 try { 7271 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7272 + stackId + " toTop=" + toTop); 7273 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7274 } finally { 7275 Binder.restoreCallingIdentity(ident); 7276 } 7277 } 7278 } 7279 7280 @Override 7281 public void resizeStack(int stackBoxId, Rect bounds) { 7282 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7283 "resizeStackBox()"); 7284 long ident = Binder.clearCallingIdentity(); 7285 try { 7286 mWindowManager.resizeStack(stackBoxId, bounds); 7287 } finally { 7288 Binder.restoreCallingIdentity(ident); 7289 } 7290 } 7291 7292 @Override 7293 public List<StackInfo> getAllStackInfos() { 7294 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7295 "getAllStackInfos()"); 7296 long ident = Binder.clearCallingIdentity(); 7297 try { 7298 synchronized (this) { 7299 return mStackSupervisor.getAllStackInfosLocked(); 7300 } 7301 } finally { 7302 Binder.restoreCallingIdentity(ident); 7303 } 7304 } 7305 7306 @Override 7307 public StackInfo getStackInfo(int stackId) { 7308 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7309 "getStackInfo()"); 7310 long ident = Binder.clearCallingIdentity(); 7311 try { 7312 synchronized (this) { 7313 return mStackSupervisor.getStackInfoLocked(stackId); 7314 } 7315 } finally { 7316 Binder.restoreCallingIdentity(ident); 7317 } 7318 } 7319 7320 @Override 7321 public boolean isInHomeStack(int taskId) { 7322 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7323 "getStackInfo()"); 7324 long ident = Binder.clearCallingIdentity(); 7325 try { 7326 synchronized (this) { 7327 TaskRecord tr = recentTaskForIdLocked(taskId); 7328 if (tr != null) { 7329 return tr.stack.isHomeStack(); 7330 } 7331 } 7332 } finally { 7333 Binder.restoreCallingIdentity(ident); 7334 } 7335 return false; 7336 } 7337 7338 @Override 7339 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7340 synchronized(this) { 7341 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7342 } 7343 } 7344 7345 private boolean isLockTaskAuthorized(ComponentName name) { 7346// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7347// "startLockTaskMode()"); 7348// DevicePolicyManager dpm = (DevicePolicyManager) 7349// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7350// return dpm != null && dpm.isLockTaskPermitted(name); 7351 return true; 7352 } 7353 7354 private void startLockTaskMode(TaskRecord task) { 7355 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7356 return; 7357 } 7358 long ident = Binder.clearCallingIdentity(); 7359 try { 7360 synchronized (this) { 7361 // Since we lost lock on task, make sure it is still there. 7362 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7363 if (task != null) { 7364 mStackSupervisor.setLockTaskModeLocked(task); 7365 } 7366 } 7367 } finally { 7368 Binder.restoreCallingIdentity(ident); 7369 } 7370 } 7371 7372 @Override 7373 public void startLockTaskMode(int taskId) { 7374 long ident = Binder.clearCallingIdentity(); 7375 try { 7376 final TaskRecord task; 7377 synchronized (this) { 7378 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7379 } 7380 if (task != null) { 7381 startLockTaskMode(task); 7382 } 7383 } finally { 7384 Binder.restoreCallingIdentity(ident); 7385 } 7386 } 7387 7388 @Override 7389 public void startLockTaskMode(IBinder token) { 7390 long ident = Binder.clearCallingIdentity(); 7391 try { 7392 final TaskRecord task; 7393 synchronized (this) { 7394 final ActivityRecord r = ActivityRecord.forToken(token); 7395 if (r == null) { 7396 return; 7397 } 7398 task = r.task; 7399 } 7400 if (task != null) { 7401 startLockTaskMode(task); 7402 } 7403 } finally { 7404 Binder.restoreCallingIdentity(ident); 7405 } 7406 } 7407 7408 @Override 7409 public void stopLockTaskMode() { 7410// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7411// "stopLockTaskMode()"); 7412 synchronized (this) { 7413 mStackSupervisor.setLockTaskModeLocked(null); 7414 } 7415 } 7416 7417 @Override 7418 public boolean isInLockTaskMode() { 7419 synchronized (this) { 7420 return mStackSupervisor.isInLockTaskMode(); 7421 } 7422 } 7423 7424 // ========================================================= 7425 // THUMBNAILS 7426 // ========================================================= 7427 7428 public void reportThumbnail(IBinder token, 7429 Bitmap thumbnail, CharSequence description) { 7430 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7431 final long origId = Binder.clearCallingIdentity(); 7432 sendPendingThumbnail(null, token, thumbnail, description, true); 7433 Binder.restoreCallingIdentity(origId); 7434 } 7435 7436 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7437 Bitmap thumbnail, CharSequence description, boolean always) { 7438 TaskRecord task; 7439 ArrayList<PendingThumbnailsRecord> receivers = null; 7440 7441 //System.out.println("Send pending thumbnail: " + r); 7442 7443 synchronized(this) { 7444 if (r == null) { 7445 r = ActivityRecord.isInStackLocked(token); 7446 if (r == null) { 7447 return; 7448 } 7449 } 7450 if (thumbnail == null && r.thumbHolder != null) { 7451 thumbnail = r.thumbHolder.lastThumbnail; 7452 description = r.thumbHolder.lastDescription; 7453 } 7454 if (thumbnail == null && !always) { 7455 // If there is no thumbnail, and this entry is not actually 7456 // going away, then abort for now and pick up the next 7457 // thumbnail we get. 7458 return; 7459 } 7460 task = r.task; 7461 7462 int N = mPendingThumbnails.size(); 7463 int i=0; 7464 while (i<N) { 7465 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7466 //System.out.println("Looking in " + pr.pendingRecords); 7467 if (pr.pendingRecords.remove(r)) { 7468 if (receivers == null) { 7469 receivers = new ArrayList<PendingThumbnailsRecord>(); 7470 } 7471 receivers.add(pr); 7472 if (pr.pendingRecords.size() == 0) { 7473 pr.finished = true; 7474 mPendingThumbnails.remove(i); 7475 N--; 7476 continue; 7477 } 7478 } 7479 i++; 7480 } 7481 } 7482 7483 if (receivers != null) { 7484 final int N = receivers.size(); 7485 for (int i=0; i<N; i++) { 7486 try { 7487 PendingThumbnailsRecord pr = receivers.get(i); 7488 pr.receiver.newThumbnail( 7489 task != null ? task.taskId : -1, thumbnail, description); 7490 if (pr.finished) { 7491 pr.receiver.finished(); 7492 } 7493 } catch (Exception e) { 7494 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7495 } 7496 } 7497 } 7498 } 7499 7500 // ========================================================= 7501 // CONTENT PROVIDERS 7502 // ========================================================= 7503 7504 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7505 List<ProviderInfo> providers = null; 7506 try { 7507 providers = AppGlobals.getPackageManager(). 7508 queryContentProviders(app.processName, app.uid, 7509 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7510 } catch (RemoteException ex) { 7511 } 7512 if (DEBUG_MU) 7513 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7514 int userId = app.userId; 7515 if (providers != null) { 7516 int N = providers.size(); 7517 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7518 for (int i=0; i<N; i++) { 7519 ProviderInfo cpi = 7520 (ProviderInfo)providers.get(i); 7521 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7522 cpi.name, cpi.flags); 7523 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7524 // This is a singleton provider, but a user besides the 7525 // default user is asking to initialize a process it runs 7526 // in... well, no, it doesn't actually run in this process, 7527 // it runs in the process of the default user. Get rid of it. 7528 providers.remove(i); 7529 N--; 7530 i--; 7531 continue; 7532 } 7533 7534 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7535 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7536 if (cpr == null) { 7537 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7538 mProviderMap.putProviderByClass(comp, cpr); 7539 } 7540 if (DEBUG_MU) 7541 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7542 app.pubProviders.put(cpi.name, cpr); 7543 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7544 // Don't add this if it is a platform component that is marked 7545 // to run in multiple processes, because this is actually 7546 // part of the framework so doesn't make sense to track as a 7547 // separate apk in the process. 7548 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7549 } 7550 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7551 } 7552 } 7553 return providers; 7554 } 7555 7556 /** 7557 * Check if {@link ProcessRecord} has a possible chance at accessing the 7558 * given {@link ProviderInfo}. Final permission checking is always done 7559 * in {@link ContentProvider}. 7560 */ 7561 private final String checkContentProviderPermissionLocked( 7562 ProviderInfo cpi, ProcessRecord r) { 7563 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7564 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7565 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7566 cpi.applicationInfo.uid, cpi.exported) 7567 == PackageManager.PERMISSION_GRANTED) { 7568 return null; 7569 } 7570 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7571 cpi.applicationInfo.uid, cpi.exported) 7572 == PackageManager.PERMISSION_GRANTED) { 7573 return null; 7574 } 7575 7576 PathPermission[] pps = cpi.pathPermissions; 7577 if (pps != null) { 7578 int i = pps.length; 7579 while (i > 0) { 7580 i--; 7581 PathPermission pp = pps[i]; 7582 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7583 cpi.applicationInfo.uid, cpi.exported) 7584 == PackageManager.PERMISSION_GRANTED) { 7585 return null; 7586 } 7587 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7588 cpi.applicationInfo.uid, cpi.exported) 7589 == PackageManager.PERMISSION_GRANTED) { 7590 return null; 7591 } 7592 } 7593 } 7594 7595 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7596 if (perms != null) { 7597 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7598 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7599 return null; 7600 } 7601 } 7602 } 7603 7604 String msg; 7605 if (!cpi.exported) { 7606 msg = "Permission Denial: opening provider " + cpi.name 7607 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7608 + ", uid=" + callingUid + ") that is not exported from uid " 7609 + cpi.applicationInfo.uid; 7610 } else { 7611 msg = "Permission Denial: opening provider " + cpi.name 7612 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7613 + ", uid=" + callingUid + ") requires " 7614 + cpi.readPermission + " or " + cpi.writePermission; 7615 } 7616 Slog.w(TAG, msg); 7617 return msg; 7618 } 7619 7620 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7621 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7622 if (r != null) { 7623 for (int i=0; i<r.conProviders.size(); i++) { 7624 ContentProviderConnection conn = r.conProviders.get(i); 7625 if (conn.provider == cpr) { 7626 if (DEBUG_PROVIDER) Slog.v(TAG, 7627 "Adding provider requested by " 7628 + r.processName + " from process " 7629 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7630 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7631 if (stable) { 7632 conn.stableCount++; 7633 conn.numStableIncs++; 7634 } else { 7635 conn.unstableCount++; 7636 conn.numUnstableIncs++; 7637 } 7638 return conn; 7639 } 7640 } 7641 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7642 if (stable) { 7643 conn.stableCount = 1; 7644 conn.numStableIncs = 1; 7645 } else { 7646 conn.unstableCount = 1; 7647 conn.numUnstableIncs = 1; 7648 } 7649 cpr.connections.add(conn); 7650 r.conProviders.add(conn); 7651 return conn; 7652 } 7653 cpr.addExternalProcessHandleLocked(externalProcessToken); 7654 return null; 7655 } 7656 7657 boolean decProviderCountLocked(ContentProviderConnection conn, 7658 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7659 if (conn != null) { 7660 cpr = conn.provider; 7661 if (DEBUG_PROVIDER) Slog.v(TAG, 7662 "Removing provider requested by " 7663 + conn.client.processName + " from process " 7664 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7665 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7666 if (stable) { 7667 conn.stableCount--; 7668 } else { 7669 conn.unstableCount--; 7670 } 7671 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7672 cpr.connections.remove(conn); 7673 conn.client.conProviders.remove(conn); 7674 return true; 7675 } 7676 return false; 7677 } 7678 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7679 return false; 7680 } 7681 7682 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7683 String name, IBinder token, boolean stable, int userId) { 7684 ContentProviderRecord cpr; 7685 ContentProviderConnection conn = null; 7686 ProviderInfo cpi = null; 7687 7688 synchronized(this) { 7689 ProcessRecord r = null; 7690 if (caller != null) { 7691 r = getRecordForAppLocked(caller); 7692 if (r == null) { 7693 throw new SecurityException( 7694 "Unable to find app for caller " + caller 7695 + " (pid=" + Binder.getCallingPid() 7696 + ") when getting content provider " + name); 7697 } 7698 } 7699 7700 // First check if this content provider has been published... 7701 cpr = mProviderMap.getProviderByName(name, userId); 7702 boolean providerRunning = cpr != null; 7703 if (providerRunning) { 7704 cpi = cpr.info; 7705 String msg; 7706 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7707 throw new SecurityException(msg); 7708 } 7709 7710 if (r != null && cpr.canRunHere(r)) { 7711 // This provider has been published or is in the process 7712 // of being published... but it is also allowed to run 7713 // in the caller's process, so don't make a connection 7714 // and just let the caller instantiate its own instance. 7715 ContentProviderHolder holder = cpr.newHolder(null); 7716 // don't give caller the provider object, it needs 7717 // to make its own. 7718 holder.provider = null; 7719 return holder; 7720 } 7721 7722 final long origId = Binder.clearCallingIdentity(); 7723 7724 // In this case the provider instance already exists, so we can 7725 // return it right away. 7726 conn = incProviderCountLocked(r, cpr, token, stable); 7727 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7728 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7729 // If this is a perceptible app accessing the provider, 7730 // make sure to count it as being accessed and thus 7731 // back up on the LRU list. This is good because 7732 // content providers are often expensive to start. 7733 updateLruProcessLocked(cpr.proc, false, null); 7734 } 7735 } 7736 7737 if (cpr.proc != null) { 7738 if (false) { 7739 if (cpr.name.flattenToShortString().equals( 7740 "com.android.providers.calendar/.CalendarProvider2")) { 7741 Slog.v(TAG, "****************** KILLING " 7742 + cpr.name.flattenToShortString()); 7743 Process.killProcess(cpr.proc.pid); 7744 } 7745 } 7746 boolean success = updateOomAdjLocked(cpr.proc); 7747 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7748 // NOTE: there is still a race here where a signal could be 7749 // pending on the process even though we managed to update its 7750 // adj level. Not sure what to do about this, but at least 7751 // the race is now smaller. 7752 if (!success) { 7753 // Uh oh... it looks like the provider's process 7754 // has been killed on us. We need to wait for a new 7755 // process to be started, and make sure its death 7756 // doesn't kill our process. 7757 Slog.i(TAG, 7758 "Existing provider " + cpr.name.flattenToShortString() 7759 + " is crashing; detaching " + r); 7760 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7761 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7762 if (!lastRef) { 7763 // This wasn't the last ref our process had on 7764 // the provider... we have now been killed, bail. 7765 return null; 7766 } 7767 providerRunning = false; 7768 conn = null; 7769 } 7770 } 7771 7772 Binder.restoreCallingIdentity(origId); 7773 } 7774 7775 boolean singleton; 7776 if (!providerRunning) { 7777 try { 7778 cpi = AppGlobals.getPackageManager(). 7779 resolveContentProvider(name, 7780 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7781 } catch (RemoteException ex) { 7782 } 7783 if (cpi == null) { 7784 return null; 7785 } 7786 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7787 cpi.name, cpi.flags); 7788 if (singleton) { 7789 userId = 0; 7790 } 7791 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7792 7793 String msg; 7794 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7795 throw new SecurityException(msg); 7796 } 7797 7798 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7799 && !cpi.processName.equals("system")) { 7800 // If this content provider does not run in the system 7801 // process, and the system is not yet ready to run other 7802 // processes, then fail fast instead of hanging. 7803 throw new IllegalArgumentException( 7804 "Attempt to launch content provider before system ready"); 7805 } 7806 7807 // Make sure that the user who owns this provider is started. If not, 7808 // we don't want to allow it to run. 7809 if (mStartedUsers.get(userId) == null) { 7810 Slog.w(TAG, "Unable to launch app " 7811 + cpi.applicationInfo.packageName + "/" 7812 + cpi.applicationInfo.uid + " for provider " 7813 + name + ": user " + userId + " is stopped"); 7814 return null; 7815 } 7816 7817 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7818 cpr = mProviderMap.getProviderByClass(comp, userId); 7819 final boolean firstClass = cpr == null; 7820 if (firstClass) { 7821 try { 7822 ApplicationInfo ai = 7823 AppGlobals.getPackageManager(). 7824 getApplicationInfo( 7825 cpi.applicationInfo.packageName, 7826 STOCK_PM_FLAGS, userId); 7827 if (ai == null) { 7828 Slog.w(TAG, "No package info for content provider " 7829 + cpi.name); 7830 return null; 7831 } 7832 ai = getAppInfoForUser(ai, userId); 7833 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7834 } catch (RemoteException ex) { 7835 // pm is in same process, this will never happen. 7836 } 7837 } 7838 7839 if (r != null && cpr.canRunHere(r)) { 7840 // If this is a multiprocess provider, then just return its 7841 // info and allow the caller to instantiate it. Only do 7842 // this if the provider is the same user as the caller's 7843 // process, or can run as root (so can be in any process). 7844 return cpr.newHolder(null); 7845 } 7846 7847 if (DEBUG_PROVIDER) { 7848 RuntimeException e = new RuntimeException("here"); 7849 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7850 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7851 } 7852 7853 // This is single process, and our app is now connecting to it. 7854 // See if we are already in the process of launching this 7855 // provider. 7856 final int N = mLaunchingProviders.size(); 7857 int i; 7858 for (i=0; i<N; i++) { 7859 if (mLaunchingProviders.get(i) == cpr) { 7860 break; 7861 } 7862 } 7863 7864 // If the provider is not already being launched, then get it 7865 // started. 7866 if (i >= N) { 7867 final long origId = Binder.clearCallingIdentity(); 7868 7869 try { 7870 // Content provider is now in use, its package can't be stopped. 7871 try { 7872 AppGlobals.getPackageManager().setPackageStoppedState( 7873 cpr.appInfo.packageName, false, userId); 7874 } catch (RemoteException e) { 7875 } catch (IllegalArgumentException e) { 7876 Slog.w(TAG, "Failed trying to unstop package " 7877 + cpr.appInfo.packageName + ": " + e); 7878 } 7879 7880 // Use existing process if already started 7881 ProcessRecord proc = getProcessRecordLocked( 7882 cpi.processName, cpr.appInfo.uid, false); 7883 if (proc != null && proc.thread != null) { 7884 if (DEBUG_PROVIDER) { 7885 Slog.d(TAG, "Installing in existing process " + proc); 7886 } 7887 proc.pubProviders.put(cpi.name, cpr); 7888 try { 7889 proc.thread.scheduleInstallProvider(cpi); 7890 } catch (RemoteException e) { 7891 } 7892 } else { 7893 proc = startProcessLocked(cpi.processName, 7894 cpr.appInfo, false, 0, "content provider", 7895 new ComponentName(cpi.applicationInfo.packageName, 7896 cpi.name), false, false, false); 7897 if (proc == null) { 7898 Slog.w(TAG, "Unable to launch app " 7899 + cpi.applicationInfo.packageName + "/" 7900 + cpi.applicationInfo.uid + " for provider " 7901 + name + ": process is bad"); 7902 return null; 7903 } 7904 } 7905 cpr.launchingApp = proc; 7906 mLaunchingProviders.add(cpr); 7907 } finally { 7908 Binder.restoreCallingIdentity(origId); 7909 } 7910 } 7911 7912 // Make sure the provider is published (the same provider class 7913 // may be published under multiple names). 7914 if (firstClass) { 7915 mProviderMap.putProviderByClass(comp, cpr); 7916 } 7917 7918 mProviderMap.putProviderByName(name, cpr); 7919 conn = incProviderCountLocked(r, cpr, token, stable); 7920 if (conn != null) { 7921 conn.waiting = true; 7922 } 7923 } 7924 } 7925 7926 // Wait for the provider to be published... 7927 synchronized (cpr) { 7928 while (cpr.provider == null) { 7929 if (cpr.launchingApp == null) { 7930 Slog.w(TAG, "Unable to launch app " 7931 + cpi.applicationInfo.packageName + "/" 7932 + cpi.applicationInfo.uid + " for provider " 7933 + name + ": launching app became null"); 7934 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7935 UserHandle.getUserId(cpi.applicationInfo.uid), 7936 cpi.applicationInfo.packageName, 7937 cpi.applicationInfo.uid, name); 7938 return null; 7939 } 7940 try { 7941 if (DEBUG_MU) { 7942 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7943 + cpr.launchingApp); 7944 } 7945 if (conn != null) { 7946 conn.waiting = true; 7947 } 7948 cpr.wait(); 7949 } catch (InterruptedException ex) { 7950 } finally { 7951 if (conn != null) { 7952 conn.waiting = false; 7953 } 7954 } 7955 } 7956 } 7957 return cpr != null ? cpr.newHolder(conn) : null; 7958 } 7959 7960 public final ContentProviderHolder getContentProvider( 7961 IApplicationThread caller, String name, int userId, boolean stable) { 7962 enforceNotIsolatedCaller("getContentProvider"); 7963 if (caller == null) { 7964 String msg = "null IApplicationThread when getting content provider " 7965 + name; 7966 Slog.w(TAG, msg); 7967 throw new SecurityException(msg); 7968 } 7969 7970 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7971 false, true, "getContentProvider", null); 7972 return getContentProviderImpl(caller, name, null, stable, userId); 7973 } 7974 7975 public ContentProviderHolder getContentProviderExternal( 7976 String name, int userId, IBinder token) { 7977 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7978 "Do not have permission in call getContentProviderExternal()"); 7979 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7980 false, true, "getContentProvider", null); 7981 return getContentProviderExternalUnchecked(name, token, userId); 7982 } 7983 7984 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7985 IBinder token, int userId) { 7986 return getContentProviderImpl(null, name, token, true, userId); 7987 } 7988 7989 /** 7990 * Drop a content provider from a ProcessRecord's bookkeeping 7991 */ 7992 public void removeContentProvider(IBinder connection, boolean stable) { 7993 enforceNotIsolatedCaller("removeContentProvider"); 7994 long ident = Binder.clearCallingIdentity(); 7995 try { 7996 synchronized (this) { 7997 ContentProviderConnection conn; 7998 try { 7999 conn = (ContentProviderConnection)connection; 8000 } catch (ClassCastException e) { 8001 String msg ="removeContentProvider: " + connection 8002 + " not a ContentProviderConnection"; 8003 Slog.w(TAG, msg); 8004 throw new IllegalArgumentException(msg); 8005 } 8006 if (conn == null) { 8007 throw new NullPointerException("connection is null"); 8008 } 8009 if (decProviderCountLocked(conn, null, null, stable)) { 8010 updateOomAdjLocked(); 8011 } 8012 } 8013 } finally { 8014 Binder.restoreCallingIdentity(ident); 8015 } 8016 } 8017 8018 public void removeContentProviderExternal(String name, IBinder token) { 8019 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8020 "Do not have permission in call removeContentProviderExternal()"); 8021 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8022 } 8023 8024 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8025 synchronized (this) { 8026 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8027 if(cpr == null) { 8028 //remove from mProvidersByClass 8029 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8030 return; 8031 } 8032 8033 //update content provider record entry info 8034 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8035 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8036 if (localCpr.hasExternalProcessHandles()) { 8037 if (localCpr.removeExternalProcessHandleLocked(token)) { 8038 updateOomAdjLocked(); 8039 } else { 8040 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8041 + " with no external reference for token: " 8042 + token + "."); 8043 } 8044 } else { 8045 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8046 + " with no external references."); 8047 } 8048 } 8049 } 8050 8051 public final void publishContentProviders(IApplicationThread caller, 8052 List<ContentProviderHolder> providers) { 8053 if (providers == null) { 8054 return; 8055 } 8056 8057 enforceNotIsolatedCaller("publishContentProviders"); 8058 synchronized (this) { 8059 final ProcessRecord r = getRecordForAppLocked(caller); 8060 if (DEBUG_MU) 8061 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8062 if (r == null) { 8063 throw new SecurityException( 8064 "Unable to find app for caller " + caller 8065 + " (pid=" + Binder.getCallingPid() 8066 + ") when publishing content providers"); 8067 } 8068 8069 final long origId = Binder.clearCallingIdentity(); 8070 8071 final int N = providers.size(); 8072 for (int i=0; i<N; i++) { 8073 ContentProviderHolder src = providers.get(i); 8074 if (src == null || src.info == null || src.provider == null) { 8075 continue; 8076 } 8077 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8078 if (DEBUG_MU) 8079 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8080 if (dst != null) { 8081 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8082 mProviderMap.putProviderByClass(comp, dst); 8083 String names[] = dst.info.authority.split(";"); 8084 for (int j = 0; j < names.length; j++) { 8085 mProviderMap.putProviderByName(names[j], dst); 8086 } 8087 8088 int NL = mLaunchingProviders.size(); 8089 int j; 8090 for (j=0; j<NL; j++) { 8091 if (mLaunchingProviders.get(j) == dst) { 8092 mLaunchingProviders.remove(j); 8093 j--; 8094 NL--; 8095 } 8096 } 8097 synchronized (dst) { 8098 dst.provider = src.provider; 8099 dst.proc = r; 8100 dst.notifyAll(); 8101 } 8102 updateOomAdjLocked(r); 8103 } 8104 } 8105 8106 Binder.restoreCallingIdentity(origId); 8107 } 8108 } 8109 8110 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8111 ContentProviderConnection conn; 8112 try { 8113 conn = (ContentProviderConnection)connection; 8114 } catch (ClassCastException e) { 8115 String msg ="refContentProvider: " + connection 8116 + " not a ContentProviderConnection"; 8117 Slog.w(TAG, msg); 8118 throw new IllegalArgumentException(msg); 8119 } 8120 if (conn == null) { 8121 throw new NullPointerException("connection is null"); 8122 } 8123 8124 synchronized (this) { 8125 if (stable > 0) { 8126 conn.numStableIncs += stable; 8127 } 8128 stable = conn.stableCount + stable; 8129 if (stable < 0) { 8130 throw new IllegalStateException("stableCount < 0: " + stable); 8131 } 8132 8133 if (unstable > 0) { 8134 conn.numUnstableIncs += unstable; 8135 } 8136 unstable = conn.unstableCount + unstable; 8137 if (unstable < 0) { 8138 throw new IllegalStateException("unstableCount < 0: " + unstable); 8139 } 8140 8141 if ((stable+unstable) <= 0) { 8142 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8143 + stable + " unstable=" + unstable); 8144 } 8145 conn.stableCount = stable; 8146 conn.unstableCount = unstable; 8147 return !conn.dead; 8148 } 8149 } 8150 8151 public void unstableProviderDied(IBinder connection) { 8152 ContentProviderConnection conn; 8153 try { 8154 conn = (ContentProviderConnection)connection; 8155 } catch (ClassCastException e) { 8156 String msg ="refContentProvider: " + connection 8157 + " not a ContentProviderConnection"; 8158 Slog.w(TAG, msg); 8159 throw new IllegalArgumentException(msg); 8160 } 8161 if (conn == null) { 8162 throw new NullPointerException("connection is null"); 8163 } 8164 8165 // Safely retrieve the content provider associated with the connection. 8166 IContentProvider provider; 8167 synchronized (this) { 8168 provider = conn.provider.provider; 8169 } 8170 8171 if (provider == null) { 8172 // Um, yeah, we're way ahead of you. 8173 return; 8174 } 8175 8176 // Make sure the caller is being honest with us. 8177 if (provider.asBinder().pingBinder()) { 8178 // Er, no, still looks good to us. 8179 synchronized (this) { 8180 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8181 + " says " + conn + " died, but we don't agree"); 8182 return; 8183 } 8184 } 8185 8186 // Well look at that! It's dead! 8187 synchronized (this) { 8188 if (conn.provider.provider != provider) { 8189 // But something changed... good enough. 8190 return; 8191 } 8192 8193 ProcessRecord proc = conn.provider.proc; 8194 if (proc == null || proc.thread == null) { 8195 // Seems like the process is already cleaned up. 8196 return; 8197 } 8198 8199 // As far as we're concerned, this is just like receiving a 8200 // death notification... just a bit prematurely. 8201 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8202 + ") early provider death"); 8203 final long ident = Binder.clearCallingIdentity(); 8204 try { 8205 appDiedLocked(proc, proc.pid, proc.thread); 8206 } finally { 8207 Binder.restoreCallingIdentity(ident); 8208 } 8209 } 8210 } 8211 8212 @Override 8213 public void appNotRespondingViaProvider(IBinder connection) { 8214 enforceCallingPermission( 8215 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8216 8217 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8218 if (conn == null) { 8219 Slog.w(TAG, "ContentProviderConnection is null"); 8220 return; 8221 } 8222 8223 final ProcessRecord host = conn.provider.proc; 8224 if (host == null) { 8225 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8226 return; 8227 } 8228 8229 final long token = Binder.clearCallingIdentity(); 8230 try { 8231 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8232 } finally { 8233 Binder.restoreCallingIdentity(token); 8234 } 8235 } 8236 8237 public final void installSystemProviders() { 8238 List<ProviderInfo> providers; 8239 synchronized (this) { 8240 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8241 providers = generateApplicationProvidersLocked(app); 8242 if (providers != null) { 8243 for (int i=providers.size()-1; i>=0; i--) { 8244 ProviderInfo pi = (ProviderInfo)providers.get(i); 8245 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8246 Slog.w(TAG, "Not installing system proc provider " + pi.name 8247 + ": not system .apk"); 8248 providers.remove(i); 8249 } 8250 } 8251 } 8252 } 8253 if (providers != null) { 8254 mSystemThread.installSystemProviders(providers); 8255 } 8256 8257 mCoreSettingsObserver = new CoreSettingsObserver(this); 8258 8259 mUsageStatsService.monitorPackages(); 8260 } 8261 8262 /** 8263 * Allows app to retrieve the MIME type of a URI without having permission 8264 * to access its content provider. 8265 * 8266 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8267 * 8268 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8269 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8270 */ 8271 public String getProviderMimeType(Uri uri, int userId) { 8272 enforceNotIsolatedCaller("getProviderMimeType"); 8273 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8274 userId, false, true, "getProviderMimeType", null); 8275 final String name = uri.getAuthority(); 8276 final long ident = Binder.clearCallingIdentity(); 8277 ContentProviderHolder holder = null; 8278 8279 try { 8280 holder = getContentProviderExternalUnchecked(name, null, userId); 8281 if (holder != null) { 8282 return holder.provider.getType(uri); 8283 } 8284 } catch (RemoteException e) { 8285 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8286 return null; 8287 } finally { 8288 if (holder != null) { 8289 removeContentProviderExternalUnchecked(name, null, userId); 8290 } 8291 Binder.restoreCallingIdentity(ident); 8292 } 8293 8294 return null; 8295 } 8296 8297 // ========================================================= 8298 // GLOBAL MANAGEMENT 8299 // ========================================================= 8300 8301 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8302 boolean isolated) { 8303 String proc = customProcess != null ? customProcess : info.processName; 8304 BatteryStatsImpl.Uid.Proc ps = null; 8305 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8306 int uid = info.uid; 8307 if (isolated) { 8308 int userId = UserHandle.getUserId(uid); 8309 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8310 while (true) { 8311 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8312 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8313 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8314 } 8315 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8316 mNextIsolatedProcessUid++; 8317 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8318 // No process for this uid, use it. 8319 break; 8320 } 8321 stepsLeft--; 8322 if (stepsLeft <= 0) { 8323 return null; 8324 } 8325 } 8326 } 8327 return new ProcessRecord(stats, info, proc, uid); 8328 } 8329 8330 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8331 ProcessRecord app; 8332 if (!isolated) { 8333 app = getProcessRecordLocked(info.processName, info.uid, true); 8334 } else { 8335 app = null; 8336 } 8337 8338 if (app == null) { 8339 app = newProcessRecordLocked(info, null, isolated); 8340 mProcessNames.put(info.processName, app.uid, app); 8341 if (isolated) { 8342 mIsolatedProcesses.put(app.uid, app); 8343 } 8344 updateLruProcessLocked(app, false, null); 8345 updateOomAdjLocked(); 8346 } 8347 8348 // This package really, really can not be stopped. 8349 try { 8350 AppGlobals.getPackageManager().setPackageStoppedState( 8351 info.packageName, false, UserHandle.getUserId(app.uid)); 8352 } catch (RemoteException e) { 8353 } catch (IllegalArgumentException e) { 8354 Slog.w(TAG, "Failed trying to unstop package " 8355 + info.packageName + ": " + e); 8356 } 8357 8358 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8359 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8360 app.persistent = true; 8361 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8362 } 8363 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8364 mPersistentStartingProcesses.add(app); 8365 startProcessLocked(app, "added application", app.processName); 8366 } 8367 8368 return app; 8369 } 8370 8371 public void unhandledBack() { 8372 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8373 "unhandledBack()"); 8374 8375 synchronized(this) { 8376 final long origId = Binder.clearCallingIdentity(); 8377 try { 8378 getFocusedStack().unhandledBackLocked(); 8379 } finally { 8380 Binder.restoreCallingIdentity(origId); 8381 } 8382 } 8383 } 8384 8385 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8386 enforceNotIsolatedCaller("openContentUri"); 8387 final int userId = UserHandle.getCallingUserId(); 8388 String name = uri.getAuthority(); 8389 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8390 ParcelFileDescriptor pfd = null; 8391 if (cph != null) { 8392 // We record the binder invoker's uid in thread-local storage before 8393 // going to the content provider to open the file. Later, in the code 8394 // that handles all permissions checks, we look for this uid and use 8395 // that rather than the Activity Manager's own uid. The effect is that 8396 // we do the check against the caller's permissions even though it looks 8397 // to the content provider like the Activity Manager itself is making 8398 // the request. 8399 sCallerIdentity.set(new Identity( 8400 Binder.getCallingPid(), Binder.getCallingUid())); 8401 try { 8402 pfd = cph.provider.openFile(null, uri, "r", null); 8403 } catch (FileNotFoundException e) { 8404 // do nothing; pfd will be returned null 8405 } finally { 8406 // Ensure that whatever happens, we clean up the identity state 8407 sCallerIdentity.remove(); 8408 } 8409 8410 // We've got the fd now, so we're done with the provider. 8411 removeContentProviderExternalUnchecked(name, null, userId); 8412 } else { 8413 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8414 } 8415 return pfd; 8416 } 8417 8418 // Actually is sleeping or shutting down or whatever else in the future 8419 // is an inactive state. 8420 public boolean isSleepingOrShuttingDown() { 8421 return mSleeping || mShuttingDown; 8422 } 8423 8424 public void goingToSleep() { 8425 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8426 != PackageManager.PERMISSION_GRANTED) { 8427 throw new SecurityException("Requires permission " 8428 + android.Manifest.permission.DEVICE_POWER); 8429 } 8430 8431 synchronized(this) { 8432 mWentToSleep = true; 8433 updateEventDispatchingLocked(); 8434 8435 if (!mSleeping) { 8436 mSleeping = true; 8437 mStackSupervisor.goingToSleepLocked(); 8438 8439 // Initialize the wake times of all processes. 8440 checkExcessivePowerUsageLocked(false); 8441 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8442 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8443 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8444 } 8445 } 8446 } 8447 8448 @Override 8449 public boolean shutdown(int timeout) { 8450 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8451 != PackageManager.PERMISSION_GRANTED) { 8452 throw new SecurityException("Requires permission " 8453 + android.Manifest.permission.SHUTDOWN); 8454 } 8455 8456 boolean timedout = false; 8457 8458 synchronized(this) { 8459 mShuttingDown = true; 8460 updateEventDispatchingLocked(); 8461 timedout = mStackSupervisor.shutdownLocked(timeout); 8462 } 8463 8464 mAppOpsService.shutdown(); 8465 mUsageStatsService.shutdown(); 8466 mBatteryStatsService.shutdown(); 8467 synchronized (this) { 8468 mProcessStats.shutdownLocked(); 8469 } 8470 8471 return timedout; 8472 } 8473 8474 public final void activitySlept(IBinder token) { 8475 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8476 8477 final long origId = Binder.clearCallingIdentity(); 8478 8479 synchronized (this) { 8480 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8481 if (r != null) { 8482 mStackSupervisor.activitySleptLocked(r); 8483 } 8484 } 8485 8486 Binder.restoreCallingIdentity(origId); 8487 } 8488 8489 void logLockScreen(String msg) { 8490 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8491 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8492 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8493 mStackSupervisor.mDismissKeyguardOnNextActivity); 8494 } 8495 8496 private void comeOutOfSleepIfNeededLocked() { 8497 if (!mWentToSleep && !mLockScreenShown) { 8498 if (mSleeping) { 8499 mSleeping = false; 8500 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8501 } 8502 } 8503 } 8504 8505 public void wakingUp() { 8506 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8507 != PackageManager.PERMISSION_GRANTED) { 8508 throw new SecurityException("Requires permission " 8509 + android.Manifest.permission.DEVICE_POWER); 8510 } 8511 8512 synchronized(this) { 8513 mWentToSleep = false; 8514 updateEventDispatchingLocked(); 8515 comeOutOfSleepIfNeededLocked(); 8516 } 8517 } 8518 8519 private void updateEventDispatchingLocked() { 8520 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8521 } 8522 8523 public void setLockScreenShown(boolean shown) { 8524 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8525 != PackageManager.PERMISSION_GRANTED) { 8526 throw new SecurityException("Requires permission " 8527 + android.Manifest.permission.DEVICE_POWER); 8528 } 8529 8530 synchronized(this) { 8531 long ident = Binder.clearCallingIdentity(); 8532 try { 8533 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8534 mLockScreenShown = shown; 8535 comeOutOfSleepIfNeededLocked(); 8536 } finally { 8537 Binder.restoreCallingIdentity(ident); 8538 } 8539 } 8540 } 8541 8542 public void stopAppSwitches() { 8543 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8544 != PackageManager.PERMISSION_GRANTED) { 8545 throw new SecurityException("Requires permission " 8546 + android.Manifest.permission.STOP_APP_SWITCHES); 8547 } 8548 8549 synchronized(this) { 8550 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8551 + APP_SWITCH_DELAY_TIME; 8552 mDidAppSwitch = false; 8553 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8554 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8555 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8556 } 8557 } 8558 8559 public void resumeAppSwitches() { 8560 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8561 != PackageManager.PERMISSION_GRANTED) { 8562 throw new SecurityException("Requires permission " 8563 + android.Manifest.permission.STOP_APP_SWITCHES); 8564 } 8565 8566 synchronized(this) { 8567 // Note that we don't execute any pending app switches... we will 8568 // let those wait until either the timeout, or the next start 8569 // activity request. 8570 mAppSwitchesAllowedTime = 0; 8571 } 8572 } 8573 8574 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8575 String name) { 8576 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8577 return true; 8578 } 8579 8580 final int perm = checkComponentPermission( 8581 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8582 callingUid, -1, true); 8583 if (perm == PackageManager.PERMISSION_GRANTED) { 8584 return true; 8585 } 8586 8587 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8588 return false; 8589 } 8590 8591 public void setDebugApp(String packageName, boolean waitForDebugger, 8592 boolean persistent) { 8593 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8594 "setDebugApp()"); 8595 8596 long ident = Binder.clearCallingIdentity(); 8597 try { 8598 // Note that this is not really thread safe if there are multiple 8599 // callers into it at the same time, but that's not a situation we 8600 // care about. 8601 if (persistent) { 8602 final ContentResolver resolver = mContext.getContentResolver(); 8603 Settings.Global.putString( 8604 resolver, Settings.Global.DEBUG_APP, 8605 packageName); 8606 Settings.Global.putInt( 8607 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8608 waitForDebugger ? 1 : 0); 8609 } 8610 8611 synchronized (this) { 8612 if (!persistent) { 8613 mOrigDebugApp = mDebugApp; 8614 mOrigWaitForDebugger = mWaitForDebugger; 8615 } 8616 mDebugApp = packageName; 8617 mWaitForDebugger = waitForDebugger; 8618 mDebugTransient = !persistent; 8619 if (packageName != null) { 8620 forceStopPackageLocked(packageName, -1, false, false, true, true, 8621 false, UserHandle.USER_ALL, "set debug app"); 8622 } 8623 } 8624 } finally { 8625 Binder.restoreCallingIdentity(ident); 8626 } 8627 } 8628 8629 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8630 synchronized (this) { 8631 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8632 if (!isDebuggable) { 8633 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8634 throw new SecurityException("Process not debuggable: " + app.packageName); 8635 } 8636 } 8637 8638 mOpenGlTraceApp = processName; 8639 } 8640 } 8641 8642 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8643 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8644 synchronized (this) { 8645 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8646 if (!isDebuggable) { 8647 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8648 throw new SecurityException("Process not debuggable: " + app.packageName); 8649 } 8650 } 8651 mProfileApp = processName; 8652 mProfileFile = profileFile; 8653 if (mProfileFd != null) { 8654 try { 8655 mProfileFd.close(); 8656 } catch (IOException e) { 8657 } 8658 mProfileFd = null; 8659 } 8660 mProfileFd = profileFd; 8661 mProfileType = 0; 8662 mAutoStopProfiler = autoStopProfiler; 8663 } 8664 } 8665 8666 @Override 8667 public void setAlwaysFinish(boolean enabled) { 8668 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8669 "setAlwaysFinish()"); 8670 8671 Settings.Global.putInt( 8672 mContext.getContentResolver(), 8673 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8674 8675 synchronized (this) { 8676 mAlwaysFinishActivities = enabled; 8677 } 8678 } 8679 8680 @Override 8681 public void setActivityController(IActivityController controller) { 8682 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8683 "setActivityController()"); 8684 synchronized (this) { 8685 mController = controller; 8686 Watchdog.getInstance().setActivityController(controller); 8687 } 8688 } 8689 8690 @Override 8691 public void setUserIsMonkey(boolean userIsMonkey) { 8692 synchronized (this) { 8693 synchronized (mPidsSelfLocked) { 8694 final int callingPid = Binder.getCallingPid(); 8695 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8696 if (precessRecord == null) { 8697 throw new SecurityException("Unknown process: " + callingPid); 8698 } 8699 if (precessRecord.instrumentationUiAutomationConnection == null) { 8700 throw new SecurityException("Only an instrumentation process " 8701 + "with a UiAutomation can call setUserIsMonkey"); 8702 } 8703 } 8704 mUserIsMonkey = userIsMonkey; 8705 } 8706 } 8707 8708 @Override 8709 public boolean isUserAMonkey() { 8710 synchronized (this) { 8711 // If there is a controller also implies the user is a monkey. 8712 return (mUserIsMonkey || mController != null); 8713 } 8714 } 8715 8716 public void requestBugReport() { 8717 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8718 SystemProperties.set("ctl.start", "bugreport"); 8719 } 8720 8721 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8722 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8723 } 8724 8725 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8726 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8727 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8728 } 8729 return KEY_DISPATCHING_TIMEOUT; 8730 } 8731 8732 @Override 8733 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8734 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8735 != PackageManager.PERMISSION_GRANTED) { 8736 throw new SecurityException("Requires permission " 8737 + android.Manifest.permission.FILTER_EVENTS); 8738 } 8739 ProcessRecord proc; 8740 long timeout; 8741 synchronized (this) { 8742 synchronized (mPidsSelfLocked) { 8743 proc = mPidsSelfLocked.get(pid); 8744 } 8745 timeout = getInputDispatchingTimeoutLocked(proc); 8746 } 8747 8748 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8749 return -1; 8750 } 8751 8752 return timeout; 8753 } 8754 8755 /** 8756 * Handle input dispatching timeouts. 8757 * Returns whether input dispatching should be aborted or not. 8758 */ 8759 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8760 final ActivityRecord activity, final ActivityRecord parent, 8761 final boolean aboveSystem, String reason) { 8762 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8763 != PackageManager.PERMISSION_GRANTED) { 8764 throw new SecurityException("Requires permission " 8765 + android.Manifest.permission.FILTER_EVENTS); 8766 } 8767 8768 final String annotation; 8769 if (reason == null) { 8770 annotation = "Input dispatching timed out"; 8771 } else { 8772 annotation = "Input dispatching timed out (" + reason + ")"; 8773 } 8774 8775 if (proc != null) { 8776 synchronized (this) { 8777 if (proc.debugging) { 8778 return false; 8779 } 8780 8781 if (mDidDexOpt) { 8782 // Give more time since we were dexopting. 8783 mDidDexOpt = false; 8784 return false; 8785 } 8786 8787 if (proc.instrumentationClass != null) { 8788 Bundle info = new Bundle(); 8789 info.putString("shortMsg", "keyDispatchingTimedOut"); 8790 info.putString("longMsg", annotation); 8791 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8792 return true; 8793 } 8794 } 8795 mHandler.post(new Runnable() { 8796 @Override 8797 public void run() { 8798 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8799 } 8800 }); 8801 } 8802 8803 return true; 8804 } 8805 8806 public Bundle getAssistContextExtras(int requestType) { 8807 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8808 "getAssistContextExtras()"); 8809 PendingAssistExtras pae; 8810 Bundle extras = new Bundle(); 8811 synchronized (this) { 8812 ActivityRecord activity = getFocusedStack().mResumedActivity; 8813 if (activity == null) { 8814 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8815 return null; 8816 } 8817 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8818 if (activity.app == null || activity.app.thread == null) { 8819 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8820 return extras; 8821 } 8822 if (activity.app.pid == Binder.getCallingPid()) { 8823 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8824 return extras; 8825 } 8826 pae = new PendingAssistExtras(activity); 8827 try { 8828 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8829 requestType); 8830 mPendingAssistExtras.add(pae); 8831 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8832 } catch (RemoteException e) { 8833 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8834 return extras; 8835 } 8836 } 8837 synchronized (pae) { 8838 while (!pae.haveResult) { 8839 try { 8840 pae.wait(); 8841 } catch (InterruptedException e) { 8842 } 8843 } 8844 if (pae.result != null) { 8845 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8846 } 8847 } 8848 synchronized (this) { 8849 mPendingAssistExtras.remove(pae); 8850 mHandler.removeCallbacks(pae); 8851 } 8852 return extras; 8853 } 8854 8855 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8856 PendingAssistExtras pae = (PendingAssistExtras)token; 8857 synchronized (pae) { 8858 pae.result = extras; 8859 pae.haveResult = true; 8860 pae.notifyAll(); 8861 } 8862 } 8863 8864 public void registerProcessObserver(IProcessObserver observer) { 8865 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8866 "registerProcessObserver()"); 8867 synchronized (this) { 8868 mProcessObservers.register(observer); 8869 } 8870 } 8871 8872 @Override 8873 public void unregisterProcessObserver(IProcessObserver observer) { 8874 synchronized (this) { 8875 mProcessObservers.unregister(observer); 8876 } 8877 } 8878 8879 @Override 8880 public boolean convertFromTranslucent(IBinder token) { 8881 final long origId = Binder.clearCallingIdentity(); 8882 try { 8883 synchronized (this) { 8884 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8885 if (r == null) { 8886 return false; 8887 } 8888 if (r.changeWindowTranslucency(true)) { 8889 mWindowManager.setAppFullscreen(token, true); 8890 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8891 return true; 8892 } 8893 return false; 8894 } 8895 } finally { 8896 Binder.restoreCallingIdentity(origId); 8897 } 8898 } 8899 8900 @Override 8901 public boolean convertToTranslucent(IBinder token) { 8902 final long origId = Binder.clearCallingIdentity(); 8903 try { 8904 synchronized (this) { 8905 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8906 if (r == null) { 8907 return false; 8908 } 8909 if (r.changeWindowTranslucency(false)) { 8910 r.task.stack.convertToTranslucent(r); 8911 mWindowManager.setAppFullscreen(token, false); 8912 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8913 return true; 8914 } 8915 return false; 8916 } 8917 } finally { 8918 Binder.restoreCallingIdentity(origId); 8919 } 8920 } 8921 8922 @Override 8923 public void setImmersive(IBinder token, boolean immersive) { 8924 synchronized(this) { 8925 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8926 if (r == null) { 8927 throw new IllegalArgumentException(); 8928 } 8929 r.immersive = immersive; 8930 8931 // update associated state if we're frontmost 8932 if (r == mFocusedActivity) { 8933 if (DEBUG_IMMERSIVE) { 8934 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8935 } 8936 applyUpdateLockStateLocked(r); 8937 } 8938 } 8939 } 8940 8941 @Override 8942 public boolean isImmersive(IBinder token) { 8943 synchronized (this) { 8944 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8945 if (r == null) { 8946 throw new IllegalArgumentException(); 8947 } 8948 return r.immersive; 8949 } 8950 } 8951 8952 public boolean isTopActivityImmersive() { 8953 enforceNotIsolatedCaller("startActivity"); 8954 synchronized (this) { 8955 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8956 return (r != null) ? r.immersive : false; 8957 } 8958 } 8959 8960 public final void enterSafeMode() { 8961 synchronized(this) { 8962 // It only makes sense to do this before the system is ready 8963 // and started launching other packages. 8964 if (!mSystemReady) { 8965 try { 8966 AppGlobals.getPackageManager().enterSafeMode(); 8967 } catch (RemoteException e) { 8968 } 8969 } 8970 8971 mSafeMode = true; 8972 } 8973 } 8974 8975 public final void showSafeModeOverlay() { 8976 View v = LayoutInflater.from(mContext).inflate( 8977 com.android.internal.R.layout.safe_mode, null); 8978 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8979 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8980 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8981 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8982 lp.gravity = Gravity.BOTTOM | Gravity.START; 8983 lp.format = v.getBackground().getOpacity(); 8984 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8985 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8986 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8987 ((WindowManager)mContext.getSystemService( 8988 Context.WINDOW_SERVICE)).addView(v, lp); 8989 } 8990 8991 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8992 if (!(sender instanceof PendingIntentRecord)) { 8993 return; 8994 } 8995 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8996 synchronized (stats) { 8997 if (mBatteryStatsService.isOnBattery()) { 8998 mBatteryStatsService.enforceCallingPermission(); 8999 PendingIntentRecord rec = (PendingIntentRecord)sender; 9000 int MY_UID = Binder.getCallingUid(); 9001 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9002 BatteryStatsImpl.Uid.Pkg pkg = 9003 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9004 sourcePkg != null ? sourcePkg : rec.key.packageName); 9005 pkg.incWakeupsLocked(); 9006 } 9007 } 9008 } 9009 9010 public boolean killPids(int[] pids, String pReason, boolean secure) { 9011 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9012 throw new SecurityException("killPids only available to the system"); 9013 } 9014 String reason = (pReason == null) ? "Unknown" : pReason; 9015 // XXX Note: don't acquire main activity lock here, because the window 9016 // manager calls in with its locks held. 9017 9018 boolean killed = false; 9019 synchronized (mPidsSelfLocked) { 9020 int[] types = new int[pids.length]; 9021 int worstType = 0; 9022 for (int i=0; i<pids.length; i++) { 9023 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9024 if (proc != null) { 9025 int type = proc.setAdj; 9026 types[i] = type; 9027 if (type > worstType) { 9028 worstType = type; 9029 } 9030 } 9031 } 9032 9033 // If the worst oom_adj is somewhere in the cached proc LRU range, 9034 // then constrain it so we will kill all cached procs. 9035 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9036 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9037 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9038 } 9039 9040 // If this is not a secure call, don't let it kill processes that 9041 // are important. 9042 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9043 worstType = ProcessList.SERVICE_ADJ; 9044 } 9045 9046 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9047 for (int i=0; i<pids.length; i++) { 9048 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9049 if (proc == null) { 9050 continue; 9051 } 9052 int adj = proc.setAdj; 9053 if (adj >= worstType && !proc.killedByAm) { 9054 killUnneededProcessLocked(proc, reason); 9055 killed = true; 9056 } 9057 } 9058 } 9059 return killed; 9060 } 9061 9062 @Override 9063 public void killUid(int uid, String reason) { 9064 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9065 throw new SecurityException("killUid only available to the system"); 9066 } 9067 synchronized (this) { 9068 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9069 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9070 reason != null ? reason : "kill uid"); 9071 } 9072 } 9073 9074 @Override 9075 public boolean killProcessesBelowForeground(String reason) { 9076 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9077 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9078 } 9079 9080 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9081 } 9082 9083 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9084 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9085 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9086 } 9087 9088 boolean killed = false; 9089 synchronized (mPidsSelfLocked) { 9090 final int size = mPidsSelfLocked.size(); 9091 for (int i = 0; i < size; i++) { 9092 final int pid = mPidsSelfLocked.keyAt(i); 9093 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9094 if (proc == null) continue; 9095 9096 final int adj = proc.setAdj; 9097 if (adj > belowAdj && !proc.killedByAm) { 9098 killUnneededProcessLocked(proc, reason); 9099 killed = true; 9100 } 9101 } 9102 } 9103 return killed; 9104 } 9105 9106 @Override 9107 public void hang(final IBinder who, boolean allowRestart) { 9108 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9109 != PackageManager.PERMISSION_GRANTED) { 9110 throw new SecurityException("Requires permission " 9111 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9112 } 9113 9114 final IBinder.DeathRecipient death = new DeathRecipient() { 9115 @Override 9116 public void binderDied() { 9117 synchronized (this) { 9118 notifyAll(); 9119 } 9120 } 9121 }; 9122 9123 try { 9124 who.linkToDeath(death, 0); 9125 } catch (RemoteException e) { 9126 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9127 return; 9128 } 9129 9130 synchronized (this) { 9131 Watchdog.getInstance().setAllowRestart(allowRestart); 9132 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9133 synchronized (death) { 9134 while (who.isBinderAlive()) { 9135 try { 9136 death.wait(); 9137 } catch (InterruptedException e) { 9138 } 9139 } 9140 } 9141 Watchdog.getInstance().setAllowRestart(true); 9142 } 9143 } 9144 9145 @Override 9146 public void restart() { 9147 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9148 != PackageManager.PERMISSION_GRANTED) { 9149 throw new SecurityException("Requires permission " 9150 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9151 } 9152 9153 Log.i(TAG, "Sending shutdown broadcast..."); 9154 9155 BroadcastReceiver br = new BroadcastReceiver() { 9156 @Override public void onReceive(Context context, Intent intent) { 9157 // Now the broadcast is done, finish up the low-level shutdown. 9158 Log.i(TAG, "Shutting down activity manager..."); 9159 shutdown(10000); 9160 Log.i(TAG, "Shutdown complete, restarting!"); 9161 Process.killProcess(Process.myPid()); 9162 System.exit(10); 9163 } 9164 }; 9165 9166 // First send the high-level shut down broadcast. 9167 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9168 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9169 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9170 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9171 mContext.sendOrderedBroadcastAsUser(intent, 9172 UserHandle.ALL, null, br, mHandler, 0, null, null); 9173 */ 9174 br.onReceive(mContext, intent); 9175 } 9176 9177 private long getLowRamTimeSinceIdle(long now) { 9178 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9179 } 9180 9181 @Override 9182 public void performIdleMaintenance() { 9183 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9184 != PackageManager.PERMISSION_GRANTED) { 9185 throw new SecurityException("Requires permission " 9186 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9187 } 9188 9189 synchronized (this) { 9190 final long now = SystemClock.uptimeMillis(); 9191 final long timeSinceLastIdle = now - mLastIdleTime; 9192 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9193 mLastIdleTime = now; 9194 mLowRamTimeSinceLastIdle = 0; 9195 if (mLowRamStartTime != 0) { 9196 mLowRamStartTime = now; 9197 } 9198 9199 StringBuilder sb = new StringBuilder(128); 9200 sb.append("Idle maintenance over "); 9201 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9202 sb.append(" low RAM for "); 9203 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9204 Slog.i(TAG, sb.toString()); 9205 9206 // If at least 1/3 of our time since the last idle period has been spent 9207 // with RAM low, then we want to kill processes. 9208 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9209 9210 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9211 ProcessRecord proc = mLruProcesses.get(i); 9212 if (proc.notCachedSinceIdle) { 9213 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9214 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9215 if (doKilling && proc.initialIdlePss != 0 9216 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9217 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9218 + " from " + proc.initialIdlePss + ")"); 9219 } 9220 } 9221 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9222 proc.notCachedSinceIdle = true; 9223 proc.initialIdlePss = 0; 9224 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9225 mSleeping, now); 9226 } 9227 } 9228 9229 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9230 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9231 } 9232 } 9233 9234 public final void startRunning(String pkg, String cls, String action, 9235 String data) { 9236 synchronized(this) { 9237 if (mStartRunning) { 9238 return; 9239 } 9240 mStartRunning = true; 9241 mTopComponent = pkg != null && cls != null 9242 ? new ComponentName(pkg, cls) : null; 9243 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9244 mTopData = data; 9245 if (!mSystemReady) { 9246 return; 9247 } 9248 } 9249 9250 systemReady(null); 9251 } 9252 9253 private void retrieveSettings() { 9254 final ContentResolver resolver = mContext.getContentResolver(); 9255 String debugApp = Settings.Global.getString( 9256 resolver, Settings.Global.DEBUG_APP); 9257 boolean waitForDebugger = Settings.Global.getInt( 9258 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9259 boolean alwaysFinishActivities = Settings.Global.getInt( 9260 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9261 boolean forceRtl = Settings.Global.getInt( 9262 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9263 // Transfer any global setting for forcing RTL layout, into a System Property 9264 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9265 9266 Configuration configuration = new Configuration(); 9267 Settings.System.getConfiguration(resolver, configuration); 9268 if (forceRtl) { 9269 // This will take care of setting the correct layout direction flags 9270 configuration.setLayoutDirection(configuration.locale); 9271 } 9272 9273 synchronized (this) { 9274 mDebugApp = mOrigDebugApp = debugApp; 9275 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9276 mAlwaysFinishActivities = alwaysFinishActivities; 9277 // This happens before any activities are started, so we can 9278 // change mConfiguration in-place. 9279 updateConfigurationLocked(configuration, null, false, true); 9280 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9281 } 9282 } 9283 9284 public boolean testIsSystemReady() { 9285 // no need to synchronize(this) just to read & return the value 9286 return mSystemReady; 9287 } 9288 9289 private static File getCalledPreBootReceiversFile() { 9290 File dataDir = Environment.getDataDirectory(); 9291 File systemDir = new File(dataDir, "system"); 9292 File fname = new File(systemDir, "called_pre_boots.dat"); 9293 return fname; 9294 } 9295 9296 static final int LAST_DONE_VERSION = 10000; 9297 9298 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9299 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9300 File file = getCalledPreBootReceiversFile(); 9301 FileInputStream fis = null; 9302 try { 9303 fis = new FileInputStream(file); 9304 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9305 int fvers = dis.readInt(); 9306 if (fvers == LAST_DONE_VERSION) { 9307 String vers = dis.readUTF(); 9308 String codename = dis.readUTF(); 9309 String build = dis.readUTF(); 9310 if (android.os.Build.VERSION.RELEASE.equals(vers) 9311 && android.os.Build.VERSION.CODENAME.equals(codename) 9312 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9313 int num = dis.readInt(); 9314 while (num > 0) { 9315 num--; 9316 String pkg = dis.readUTF(); 9317 String cls = dis.readUTF(); 9318 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9319 } 9320 } 9321 } 9322 } catch (FileNotFoundException e) { 9323 } catch (IOException e) { 9324 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9325 } finally { 9326 if (fis != null) { 9327 try { 9328 fis.close(); 9329 } catch (IOException e) { 9330 } 9331 } 9332 } 9333 return lastDoneReceivers; 9334 } 9335 9336 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9337 File file = getCalledPreBootReceiversFile(); 9338 FileOutputStream fos = null; 9339 DataOutputStream dos = null; 9340 try { 9341 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9342 fos = new FileOutputStream(file); 9343 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9344 dos.writeInt(LAST_DONE_VERSION); 9345 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9346 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9347 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9348 dos.writeInt(list.size()); 9349 for (int i=0; i<list.size(); i++) { 9350 dos.writeUTF(list.get(i).getPackageName()); 9351 dos.writeUTF(list.get(i).getClassName()); 9352 } 9353 } catch (IOException e) { 9354 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9355 file.delete(); 9356 } finally { 9357 FileUtils.sync(fos); 9358 if (dos != null) { 9359 try { 9360 dos.close(); 9361 } catch (IOException e) { 9362 // TODO Auto-generated catch block 9363 e.printStackTrace(); 9364 } 9365 } 9366 } 9367 } 9368 9369 public void systemReady(final Runnable goingCallback) { 9370 synchronized(this) { 9371 if (mSystemReady) { 9372 if (goingCallback != null) goingCallback.run(); 9373 return; 9374 } 9375 9376 // Check to see if there are any update receivers to run. 9377 if (!mDidUpdate) { 9378 if (mWaitingUpdate) { 9379 return; 9380 } 9381 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9382 List<ResolveInfo> ris = null; 9383 try { 9384 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9385 intent, null, 0, 0); 9386 } catch (RemoteException e) { 9387 } 9388 if (ris != null) { 9389 for (int i=ris.size()-1; i>=0; i--) { 9390 if ((ris.get(i).activityInfo.applicationInfo.flags 9391 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9392 ris.remove(i); 9393 } 9394 } 9395 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9396 9397 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9398 9399 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9400 for (int i=0; i<ris.size(); i++) { 9401 ActivityInfo ai = ris.get(i).activityInfo; 9402 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9403 if (lastDoneReceivers.contains(comp)) { 9404 // We already did the pre boot receiver for this app with the current 9405 // platform version, so don't do it again... 9406 ris.remove(i); 9407 i--; 9408 // ...however, do keep it as one that has been done, so we don't 9409 // forget about it when rewriting the file of last done receivers. 9410 doneReceivers.add(comp); 9411 } 9412 } 9413 9414 final int[] users = getUsersLocked(); 9415 for (int i=0; i<ris.size(); i++) { 9416 ActivityInfo ai = ris.get(i).activityInfo; 9417 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9418 doneReceivers.add(comp); 9419 intent.setComponent(comp); 9420 for (int j=0; j<users.length; j++) { 9421 IIntentReceiver finisher = null; 9422 if (i == ris.size()-1 && j == users.length-1) { 9423 finisher = new IIntentReceiver.Stub() { 9424 public void performReceive(Intent intent, int resultCode, 9425 String data, Bundle extras, boolean ordered, 9426 boolean sticky, int sendingUser) { 9427 // The raw IIntentReceiver interface is called 9428 // with the AM lock held, so redispatch to 9429 // execute our code without the lock. 9430 mHandler.post(new Runnable() { 9431 public void run() { 9432 synchronized (ActivityManagerService.this) { 9433 mDidUpdate = true; 9434 } 9435 writeLastDonePreBootReceivers(doneReceivers); 9436 showBootMessage(mContext.getText( 9437 R.string.android_upgrading_complete), 9438 false); 9439 systemReady(goingCallback); 9440 } 9441 }); 9442 } 9443 }; 9444 } 9445 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9446 + " for user " + users[j]); 9447 broadcastIntentLocked(null, null, intent, null, finisher, 9448 0, null, null, null, AppOpsManager.OP_NONE, 9449 true, false, MY_PID, Process.SYSTEM_UID, 9450 users[j]); 9451 if (finisher != null) { 9452 mWaitingUpdate = true; 9453 } 9454 } 9455 } 9456 } 9457 if (mWaitingUpdate) { 9458 return; 9459 } 9460 mDidUpdate = true; 9461 } 9462 9463 mAppOpsService.systemReady(); 9464 mSystemReady = true; 9465 if (!mStartRunning) { 9466 return; 9467 } 9468 } 9469 9470 ArrayList<ProcessRecord> procsToKill = null; 9471 synchronized(mPidsSelfLocked) { 9472 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9473 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9474 if (!isAllowedWhileBooting(proc.info)){ 9475 if (procsToKill == null) { 9476 procsToKill = new ArrayList<ProcessRecord>(); 9477 } 9478 procsToKill.add(proc); 9479 } 9480 } 9481 } 9482 9483 synchronized(this) { 9484 if (procsToKill != null) { 9485 for (int i=procsToKill.size()-1; i>=0; i--) { 9486 ProcessRecord proc = procsToKill.get(i); 9487 Slog.i(TAG, "Removing system update proc: " + proc); 9488 removeProcessLocked(proc, true, false, "system update done"); 9489 } 9490 } 9491 9492 // Now that we have cleaned up any update processes, we 9493 // are ready to start launching real processes and know that 9494 // we won't trample on them any more. 9495 mProcessesReady = true; 9496 } 9497 9498 Slog.i(TAG, "System now ready"); 9499 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9500 SystemClock.uptimeMillis()); 9501 9502 synchronized(this) { 9503 // Make sure we have no pre-ready processes sitting around. 9504 9505 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9506 ResolveInfo ri = mContext.getPackageManager() 9507 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9508 STOCK_PM_FLAGS); 9509 CharSequence errorMsg = null; 9510 if (ri != null) { 9511 ActivityInfo ai = ri.activityInfo; 9512 ApplicationInfo app = ai.applicationInfo; 9513 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9514 mTopAction = Intent.ACTION_FACTORY_TEST; 9515 mTopData = null; 9516 mTopComponent = new ComponentName(app.packageName, 9517 ai.name); 9518 } else { 9519 errorMsg = mContext.getResources().getText( 9520 com.android.internal.R.string.factorytest_not_system); 9521 } 9522 } else { 9523 errorMsg = mContext.getResources().getText( 9524 com.android.internal.R.string.factorytest_no_action); 9525 } 9526 if (errorMsg != null) { 9527 mTopAction = null; 9528 mTopData = null; 9529 mTopComponent = null; 9530 Message msg = Message.obtain(); 9531 msg.what = SHOW_FACTORY_ERROR_MSG; 9532 msg.getData().putCharSequence("msg", errorMsg); 9533 mHandler.sendMessage(msg); 9534 } 9535 } 9536 } 9537 9538 retrieveSettings(); 9539 9540 synchronized (this) { 9541 readGrantedUriPermissionsLocked(); 9542 } 9543 9544 if (goingCallback != null) goingCallback.run(); 9545 9546 synchronized (this) { 9547 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9548 try { 9549 List apps = AppGlobals.getPackageManager(). 9550 getPersistentApplications(STOCK_PM_FLAGS); 9551 if (apps != null) { 9552 int N = apps.size(); 9553 int i; 9554 for (i=0; i<N; i++) { 9555 ApplicationInfo info 9556 = (ApplicationInfo)apps.get(i); 9557 if (info != null && 9558 !info.packageName.equals("android")) { 9559 addAppLocked(info, false); 9560 } 9561 } 9562 } 9563 } catch (RemoteException ex) { 9564 // pm is in same process, this will never happen. 9565 } 9566 } 9567 9568 // Start up initial activity. 9569 mBooting = true; 9570 9571 try { 9572 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9573 Message msg = Message.obtain(); 9574 msg.what = SHOW_UID_ERROR_MSG; 9575 mHandler.sendMessage(msg); 9576 } 9577 } catch (RemoteException e) { 9578 } 9579 9580 long ident = Binder.clearCallingIdentity(); 9581 try { 9582 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9583 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9584 | Intent.FLAG_RECEIVER_FOREGROUND); 9585 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9586 broadcastIntentLocked(null, null, intent, 9587 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9588 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9589 intent = new Intent(Intent.ACTION_USER_STARTING); 9590 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9591 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9592 broadcastIntentLocked(null, null, intent, 9593 null, new IIntentReceiver.Stub() { 9594 @Override 9595 public void performReceive(Intent intent, int resultCode, String data, 9596 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9597 throws RemoteException { 9598 } 9599 }, 0, null, null, 9600 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9601 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9602 } finally { 9603 Binder.restoreCallingIdentity(ident); 9604 } 9605 mStackSupervisor.resumeTopActivitiesLocked(); 9606 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9607 } 9608 } 9609 9610 private boolean makeAppCrashingLocked(ProcessRecord app, 9611 String shortMsg, String longMsg, String stackTrace) { 9612 app.crashing = true; 9613 app.crashingReport = generateProcessError(app, 9614 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9615 startAppProblemLocked(app); 9616 app.stopFreezingAllLocked(); 9617 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9618 } 9619 9620 private void makeAppNotRespondingLocked(ProcessRecord app, 9621 String activity, String shortMsg, String longMsg) { 9622 app.notResponding = true; 9623 app.notRespondingReport = generateProcessError(app, 9624 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9625 activity, shortMsg, longMsg, null); 9626 startAppProblemLocked(app); 9627 app.stopFreezingAllLocked(); 9628 } 9629 9630 /** 9631 * Generate a process error record, suitable for attachment to a ProcessRecord. 9632 * 9633 * @param app The ProcessRecord in which the error occurred. 9634 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9635 * ActivityManager.AppErrorStateInfo 9636 * @param activity The activity associated with the crash, if known. 9637 * @param shortMsg Short message describing the crash. 9638 * @param longMsg Long message describing the crash. 9639 * @param stackTrace Full crash stack trace, may be null. 9640 * 9641 * @return Returns a fully-formed AppErrorStateInfo record. 9642 */ 9643 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9644 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9645 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9646 9647 report.condition = condition; 9648 report.processName = app.processName; 9649 report.pid = app.pid; 9650 report.uid = app.info.uid; 9651 report.tag = activity; 9652 report.shortMsg = shortMsg; 9653 report.longMsg = longMsg; 9654 report.stackTrace = stackTrace; 9655 9656 return report; 9657 } 9658 9659 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9660 synchronized (this) { 9661 app.crashing = false; 9662 app.crashingReport = null; 9663 app.notResponding = false; 9664 app.notRespondingReport = null; 9665 if (app.anrDialog == fromDialog) { 9666 app.anrDialog = null; 9667 } 9668 if (app.waitDialog == fromDialog) { 9669 app.waitDialog = null; 9670 } 9671 if (app.pid > 0 && app.pid != MY_PID) { 9672 handleAppCrashLocked(app, null, null, null); 9673 killUnneededProcessLocked(app, "user request after error"); 9674 } 9675 } 9676 } 9677 9678 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9679 String stackTrace) { 9680 long now = SystemClock.uptimeMillis(); 9681 9682 Long crashTime; 9683 if (!app.isolated) { 9684 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9685 } else { 9686 crashTime = null; 9687 } 9688 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9689 // This process loses! 9690 Slog.w(TAG, "Process " + app.info.processName 9691 + " has crashed too many times: killing!"); 9692 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9693 app.userId, app.info.processName, app.uid); 9694 mStackSupervisor.handleAppCrashLocked(app); 9695 if (!app.persistent) { 9696 // We don't want to start this process again until the user 9697 // explicitly does so... but for persistent process, we really 9698 // need to keep it running. If a persistent process is actually 9699 // repeatedly crashing, then badness for everyone. 9700 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9701 app.info.processName); 9702 if (!app.isolated) { 9703 // XXX We don't have a way to mark isolated processes 9704 // as bad, since they don't have a peristent identity. 9705 mBadProcesses.put(app.info.processName, app.uid, 9706 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9707 mProcessCrashTimes.remove(app.info.processName, app.uid); 9708 } 9709 app.bad = true; 9710 app.removed = true; 9711 // Don't let services in this process be restarted and potentially 9712 // annoy the user repeatedly. Unless it is persistent, since those 9713 // processes run critical code. 9714 removeProcessLocked(app, false, false, "crash"); 9715 mStackSupervisor.resumeTopActivitiesLocked(); 9716 return false; 9717 } 9718 mStackSupervisor.resumeTopActivitiesLocked(); 9719 } else { 9720 mStackSupervisor.finishTopRunningActivityLocked(app); 9721 } 9722 9723 // Bump up the crash count of any services currently running in the proc. 9724 for (int i=app.services.size()-1; i>=0; i--) { 9725 // Any services running in the application need to be placed 9726 // back in the pending list. 9727 ServiceRecord sr = app.services.valueAt(i); 9728 sr.crashCount++; 9729 } 9730 9731 // If the crashing process is what we consider to be the "home process" and it has been 9732 // replaced by a third-party app, clear the package preferred activities from packages 9733 // with a home activity running in the process to prevent a repeatedly crashing app 9734 // from blocking the user to manually clear the list. 9735 final ArrayList<ActivityRecord> activities = app.activities; 9736 if (app == mHomeProcess && activities.size() > 0 9737 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9738 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9739 final ActivityRecord r = activities.get(activityNdx); 9740 if (r.isHomeActivity()) { 9741 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9742 try { 9743 ActivityThread.getPackageManager() 9744 .clearPackagePreferredActivities(r.packageName); 9745 } catch (RemoteException c) { 9746 // pm is in same process, this will never happen. 9747 } 9748 } 9749 } 9750 } 9751 9752 if (!app.isolated) { 9753 // XXX Can't keep track of crash times for isolated processes, 9754 // because they don't have a perisistent identity. 9755 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9756 } 9757 9758 return true; 9759 } 9760 9761 void startAppProblemLocked(ProcessRecord app) { 9762 if (app.userId == mCurrentUserId) { 9763 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9764 mContext, app.info.packageName, app.info.flags); 9765 } else { 9766 // If this app is not running under the current user, then we 9767 // can't give it a report button because that would require 9768 // launching the report UI under a different user. 9769 app.errorReportReceiver = null; 9770 } 9771 skipCurrentReceiverLocked(app); 9772 } 9773 9774 void skipCurrentReceiverLocked(ProcessRecord app) { 9775 for (BroadcastQueue queue : mBroadcastQueues) { 9776 queue.skipCurrentReceiverLocked(app); 9777 } 9778 } 9779 9780 /** 9781 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9782 * The application process will exit immediately after this call returns. 9783 * @param app object of the crashing app, null for the system server 9784 * @param crashInfo describing the exception 9785 */ 9786 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9787 ProcessRecord r = findAppProcess(app, "Crash"); 9788 final String processName = app == null ? "system_server" 9789 : (r == null ? "unknown" : r.processName); 9790 9791 handleApplicationCrashInner("crash", r, processName, crashInfo); 9792 } 9793 9794 /* Native crash reporting uses this inner version because it needs to be somewhat 9795 * decoupled from the AM-managed cleanup lifecycle 9796 */ 9797 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9798 ApplicationErrorReport.CrashInfo crashInfo) { 9799 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9800 UserHandle.getUserId(Binder.getCallingUid()), processName, 9801 r == null ? -1 : r.info.flags, 9802 crashInfo.exceptionClassName, 9803 crashInfo.exceptionMessage, 9804 crashInfo.throwFileName, 9805 crashInfo.throwLineNumber); 9806 9807 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9808 9809 crashApplication(r, crashInfo); 9810 } 9811 9812 public void handleApplicationStrictModeViolation( 9813 IBinder app, 9814 int violationMask, 9815 StrictMode.ViolationInfo info) { 9816 ProcessRecord r = findAppProcess(app, "StrictMode"); 9817 if (r == null) { 9818 return; 9819 } 9820 9821 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9822 Integer stackFingerprint = info.hashCode(); 9823 boolean logIt = true; 9824 synchronized (mAlreadyLoggedViolatedStacks) { 9825 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9826 logIt = false; 9827 // TODO: sub-sample into EventLog for these, with 9828 // the info.durationMillis? Then we'd get 9829 // the relative pain numbers, without logging all 9830 // the stack traces repeatedly. We'd want to do 9831 // likewise in the client code, which also does 9832 // dup suppression, before the Binder call. 9833 } else { 9834 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9835 mAlreadyLoggedViolatedStacks.clear(); 9836 } 9837 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9838 } 9839 } 9840 if (logIt) { 9841 logStrictModeViolationToDropBox(r, info); 9842 } 9843 } 9844 9845 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9846 AppErrorResult result = new AppErrorResult(); 9847 synchronized (this) { 9848 final long origId = Binder.clearCallingIdentity(); 9849 9850 Message msg = Message.obtain(); 9851 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9852 HashMap<String, Object> data = new HashMap<String, Object>(); 9853 data.put("result", result); 9854 data.put("app", r); 9855 data.put("violationMask", violationMask); 9856 data.put("info", info); 9857 msg.obj = data; 9858 mHandler.sendMessage(msg); 9859 9860 Binder.restoreCallingIdentity(origId); 9861 } 9862 int res = result.get(); 9863 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9864 } 9865 } 9866 9867 // Depending on the policy in effect, there could be a bunch of 9868 // these in quick succession so we try to batch these together to 9869 // minimize disk writes, number of dropbox entries, and maximize 9870 // compression, by having more fewer, larger records. 9871 private void logStrictModeViolationToDropBox( 9872 ProcessRecord process, 9873 StrictMode.ViolationInfo info) { 9874 if (info == null) { 9875 return; 9876 } 9877 final boolean isSystemApp = process == null || 9878 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9879 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9880 final String processName = process == null ? "unknown" : process.processName; 9881 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9882 final DropBoxManager dbox = (DropBoxManager) 9883 mContext.getSystemService(Context.DROPBOX_SERVICE); 9884 9885 // Exit early if the dropbox isn't configured to accept this report type. 9886 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9887 9888 boolean bufferWasEmpty; 9889 boolean needsFlush; 9890 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9891 synchronized (sb) { 9892 bufferWasEmpty = sb.length() == 0; 9893 appendDropBoxProcessHeaders(process, processName, sb); 9894 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9895 sb.append("System-App: ").append(isSystemApp).append("\n"); 9896 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9897 if (info.violationNumThisLoop != 0) { 9898 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9899 } 9900 if (info.numAnimationsRunning != 0) { 9901 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9902 } 9903 if (info.broadcastIntentAction != null) { 9904 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9905 } 9906 if (info.durationMillis != -1) { 9907 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9908 } 9909 if (info.numInstances != -1) { 9910 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9911 } 9912 if (info.tags != null) { 9913 for (String tag : info.tags) { 9914 sb.append("Span-Tag: ").append(tag).append("\n"); 9915 } 9916 } 9917 sb.append("\n"); 9918 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9919 sb.append(info.crashInfo.stackTrace); 9920 } 9921 sb.append("\n"); 9922 9923 // Only buffer up to ~64k. Various logging bits truncate 9924 // things at 128k. 9925 needsFlush = (sb.length() > 64 * 1024); 9926 } 9927 9928 // Flush immediately if the buffer's grown too large, or this 9929 // is a non-system app. Non-system apps are isolated with a 9930 // different tag & policy and not batched. 9931 // 9932 // Batching is useful during internal testing with 9933 // StrictMode settings turned up high. Without batching, 9934 // thousands of separate files could be created on boot. 9935 if (!isSystemApp || needsFlush) { 9936 new Thread("Error dump: " + dropboxTag) { 9937 @Override 9938 public void run() { 9939 String report; 9940 synchronized (sb) { 9941 report = sb.toString(); 9942 sb.delete(0, sb.length()); 9943 sb.trimToSize(); 9944 } 9945 if (report.length() != 0) { 9946 dbox.addText(dropboxTag, report); 9947 } 9948 } 9949 }.start(); 9950 return; 9951 } 9952 9953 // System app batching: 9954 if (!bufferWasEmpty) { 9955 // An existing dropbox-writing thread is outstanding, so 9956 // we don't need to start it up. The existing thread will 9957 // catch the buffer appends we just did. 9958 return; 9959 } 9960 9961 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9962 // (After this point, we shouldn't access AMS internal data structures.) 9963 new Thread("Error dump: " + dropboxTag) { 9964 @Override 9965 public void run() { 9966 // 5 second sleep to let stacks arrive and be batched together 9967 try { 9968 Thread.sleep(5000); // 5 seconds 9969 } catch (InterruptedException e) {} 9970 9971 String errorReport; 9972 synchronized (mStrictModeBuffer) { 9973 errorReport = mStrictModeBuffer.toString(); 9974 if (errorReport.length() == 0) { 9975 return; 9976 } 9977 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9978 mStrictModeBuffer.trimToSize(); 9979 } 9980 dbox.addText(dropboxTag, errorReport); 9981 } 9982 }.start(); 9983 } 9984 9985 /** 9986 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9987 * @param app object of the crashing app, null for the system server 9988 * @param tag reported by the caller 9989 * @param crashInfo describing the context of the error 9990 * @return true if the process should exit immediately (WTF is fatal) 9991 */ 9992 public boolean handleApplicationWtf(IBinder app, String tag, 9993 ApplicationErrorReport.CrashInfo crashInfo) { 9994 ProcessRecord r = findAppProcess(app, "WTF"); 9995 final String processName = app == null ? "system_server" 9996 : (r == null ? "unknown" : r.processName); 9997 9998 EventLog.writeEvent(EventLogTags.AM_WTF, 9999 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10000 processName, 10001 r == null ? -1 : r.info.flags, 10002 tag, crashInfo.exceptionMessage); 10003 10004 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10005 10006 if (r != null && r.pid != Process.myPid() && 10007 Settings.Global.getInt(mContext.getContentResolver(), 10008 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10009 crashApplication(r, crashInfo); 10010 return true; 10011 } else { 10012 return false; 10013 } 10014 } 10015 10016 /** 10017 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10018 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10019 */ 10020 private ProcessRecord findAppProcess(IBinder app, String reason) { 10021 if (app == null) { 10022 return null; 10023 } 10024 10025 synchronized (this) { 10026 final int NP = mProcessNames.getMap().size(); 10027 for (int ip=0; ip<NP; ip++) { 10028 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10029 final int NA = apps.size(); 10030 for (int ia=0; ia<NA; ia++) { 10031 ProcessRecord p = apps.valueAt(ia); 10032 if (p.thread != null && p.thread.asBinder() == app) { 10033 return p; 10034 } 10035 } 10036 } 10037 10038 Slog.w(TAG, "Can't find mystery application for " + reason 10039 + " from pid=" + Binder.getCallingPid() 10040 + " uid=" + Binder.getCallingUid() + ": " + app); 10041 return null; 10042 } 10043 } 10044 10045 /** 10046 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10047 * to append various headers to the dropbox log text. 10048 */ 10049 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10050 StringBuilder sb) { 10051 // Watchdog thread ends up invoking this function (with 10052 // a null ProcessRecord) to add the stack file to dropbox. 10053 // Do not acquire a lock on this (am) in such cases, as it 10054 // could cause a potential deadlock, if and when watchdog 10055 // is invoked due to unavailability of lock on am and it 10056 // would prevent watchdog from killing system_server. 10057 if (process == null) { 10058 sb.append("Process: ").append(processName).append("\n"); 10059 return; 10060 } 10061 // Note: ProcessRecord 'process' is guarded by the service 10062 // instance. (notably process.pkgList, which could otherwise change 10063 // concurrently during execution of this method) 10064 synchronized (this) { 10065 sb.append("Process: ").append(processName).append("\n"); 10066 int flags = process.info.flags; 10067 IPackageManager pm = AppGlobals.getPackageManager(); 10068 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10069 for (int ip=0; ip<process.pkgList.size(); ip++) { 10070 String pkg = process.pkgList.keyAt(ip); 10071 sb.append("Package: ").append(pkg); 10072 try { 10073 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10074 if (pi != null) { 10075 sb.append(" v").append(pi.versionCode); 10076 if (pi.versionName != null) { 10077 sb.append(" (").append(pi.versionName).append(")"); 10078 } 10079 } 10080 } catch (RemoteException e) { 10081 Slog.e(TAG, "Error getting package info: " + pkg, e); 10082 } 10083 sb.append("\n"); 10084 } 10085 } 10086 } 10087 10088 private static String processClass(ProcessRecord process) { 10089 if (process == null || process.pid == MY_PID) { 10090 return "system_server"; 10091 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10092 return "system_app"; 10093 } else { 10094 return "data_app"; 10095 } 10096 } 10097 10098 /** 10099 * Write a description of an error (crash, WTF, ANR) to the drop box. 10100 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10101 * @param process which caused the error, null means the system server 10102 * @param activity which triggered the error, null if unknown 10103 * @param parent activity related to the error, null if unknown 10104 * @param subject line related to the error, null if absent 10105 * @param report in long form describing the error, null if absent 10106 * @param logFile to include in the report, null if none 10107 * @param crashInfo giving an application stack trace, null if absent 10108 */ 10109 public void addErrorToDropBox(String eventType, 10110 ProcessRecord process, String processName, ActivityRecord activity, 10111 ActivityRecord parent, String subject, 10112 final String report, final File logFile, 10113 final ApplicationErrorReport.CrashInfo crashInfo) { 10114 // NOTE -- this must never acquire the ActivityManagerService lock, 10115 // otherwise the watchdog may be prevented from resetting the system. 10116 10117 final String dropboxTag = processClass(process) + "_" + eventType; 10118 final DropBoxManager dbox = (DropBoxManager) 10119 mContext.getSystemService(Context.DROPBOX_SERVICE); 10120 10121 // Exit early if the dropbox isn't configured to accept this report type. 10122 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10123 10124 final StringBuilder sb = new StringBuilder(1024); 10125 appendDropBoxProcessHeaders(process, processName, sb); 10126 if (activity != null) { 10127 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10128 } 10129 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10130 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10131 } 10132 if (parent != null && parent != activity) { 10133 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10134 } 10135 if (subject != null) { 10136 sb.append("Subject: ").append(subject).append("\n"); 10137 } 10138 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10139 if (Debug.isDebuggerConnected()) { 10140 sb.append("Debugger: Connected\n"); 10141 } 10142 sb.append("\n"); 10143 10144 // Do the rest in a worker thread to avoid blocking the caller on I/O 10145 // (After this point, we shouldn't access AMS internal data structures.) 10146 Thread worker = new Thread("Error dump: " + dropboxTag) { 10147 @Override 10148 public void run() { 10149 if (report != null) { 10150 sb.append(report); 10151 } 10152 if (logFile != null) { 10153 try { 10154 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10155 "\n\n[[TRUNCATED]]")); 10156 } catch (IOException e) { 10157 Slog.e(TAG, "Error reading " + logFile, e); 10158 } 10159 } 10160 if (crashInfo != null && crashInfo.stackTrace != null) { 10161 sb.append(crashInfo.stackTrace); 10162 } 10163 10164 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10165 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10166 if (lines > 0) { 10167 sb.append("\n"); 10168 10169 // Merge several logcat streams, and take the last N lines 10170 InputStreamReader input = null; 10171 try { 10172 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10173 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10174 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10175 10176 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10177 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10178 input = new InputStreamReader(logcat.getInputStream()); 10179 10180 int num; 10181 char[] buf = new char[8192]; 10182 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10183 } catch (IOException e) { 10184 Slog.e(TAG, "Error running logcat", e); 10185 } finally { 10186 if (input != null) try { input.close(); } catch (IOException e) {} 10187 } 10188 } 10189 10190 dbox.addText(dropboxTag, sb.toString()); 10191 } 10192 }; 10193 10194 if (process == null) { 10195 // If process is null, we are being called from some internal code 10196 // and may be about to die -- run this synchronously. 10197 worker.run(); 10198 } else { 10199 worker.start(); 10200 } 10201 } 10202 10203 /** 10204 * Bring up the "unexpected error" dialog box for a crashing app. 10205 * Deal with edge cases (intercepts from instrumented applications, 10206 * ActivityController, error intent receivers, that sort of thing). 10207 * @param r the application crashing 10208 * @param crashInfo describing the failure 10209 */ 10210 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10211 long timeMillis = System.currentTimeMillis(); 10212 String shortMsg = crashInfo.exceptionClassName; 10213 String longMsg = crashInfo.exceptionMessage; 10214 String stackTrace = crashInfo.stackTrace; 10215 if (shortMsg != null && longMsg != null) { 10216 longMsg = shortMsg + ": " + longMsg; 10217 } else if (shortMsg != null) { 10218 longMsg = shortMsg; 10219 } 10220 10221 AppErrorResult result = new AppErrorResult(); 10222 synchronized (this) { 10223 if (mController != null) { 10224 try { 10225 String name = r != null ? r.processName : null; 10226 int pid = r != null ? r.pid : Binder.getCallingPid(); 10227 if (!mController.appCrashed(name, pid, 10228 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10229 Slog.w(TAG, "Force-killing crashed app " + name 10230 + " at watcher's request"); 10231 Process.killProcess(pid); 10232 return; 10233 } 10234 } catch (RemoteException e) { 10235 mController = null; 10236 Watchdog.getInstance().setActivityController(null); 10237 } 10238 } 10239 10240 final long origId = Binder.clearCallingIdentity(); 10241 10242 // If this process is running instrumentation, finish it. 10243 if (r != null && r.instrumentationClass != null) { 10244 Slog.w(TAG, "Error in app " + r.processName 10245 + " running instrumentation " + r.instrumentationClass + ":"); 10246 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10247 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10248 Bundle info = new Bundle(); 10249 info.putString("shortMsg", shortMsg); 10250 info.putString("longMsg", longMsg); 10251 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10252 Binder.restoreCallingIdentity(origId); 10253 return; 10254 } 10255 10256 // If we can't identify the process or it's already exceeded its crash quota, 10257 // quit right away without showing a crash dialog. 10258 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10259 Binder.restoreCallingIdentity(origId); 10260 return; 10261 } 10262 10263 Message msg = Message.obtain(); 10264 msg.what = SHOW_ERROR_MSG; 10265 HashMap data = new HashMap(); 10266 data.put("result", result); 10267 data.put("app", r); 10268 msg.obj = data; 10269 mHandler.sendMessage(msg); 10270 10271 Binder.restoreCallingIdentity(origId); 10272 } 10273 10274 int res = result.get(); 10275 10276 Intent appErrorIntent = null; 10277 synchronized (this) { 10278 if (r != null && !r.isolated) { 10279 // XXX Can't keep track of crash time for isolated processes, 10280 // since they don't have a persistent identity. 10281 mProcessCrashTimes.put(r.info.processName, r.uid, 10282 SystemClock.uptimeMillis()); 10283 } 10284 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10285 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10286 } 10287 } 10288 10289 if (appErrorIntent != null) { 10290 try { 10291 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10292 } catch (ActivityNotFoundException e) { 10293 Slog.w(TAG, "bug report receiver dissappeared", e); 10294 } 10295 } 10296 } 10297 10298 Intent createAppErrorIntentLocked(ProcessRecord r, 10299 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10300 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10301 if (report == null) { 10302 return null; 10303 } 10304 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10305 result.setComponent(r.errorReportReceiver); 10306 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10307 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10308 return result; 10309 } 10310 10311 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10312 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10313 if (r.errorReportReceiver == null) { 10314 return null; 10315 } 10316 10317 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10318 return null; 10319 } 10320 10321 ApplicationErrorReport report = new ApplicationErrorReport(); 10322 report.packageName = r.info.packageName; 10323 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10324 report.processName = r.processName; 10325 report.time = timeMillis; 10326 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10327 10328 if (r.crashing || r.forceCrashReport) { 10329 report.type = ApplicationErrorReport.TYPE_CRASH; 10330 report.crashInfo = crashInfo; 10331 } else if (r.notResponding) { 10332 report.type = ApplicationErrorReport.TYPE_ANR; 10333 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10334 10335 report.anrInfo.activity = r.notRespondingReport.tag; 10336 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10337 report.anrInfo.info = r.notRespondingReport.longMsg; 10338 } 10339 10340 return report; 10341 } 10342 10343 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10344 enforceNotIsolatedCaller("getProcessesInErrorState"); 10345 // assume our apps are happy - lazy create the list 10346 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10347 10348 final boolean allUsers = ActivityManager.checkUidPermission( 10349 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10350 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10351 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10352 10353 synchronized (this) { 10354 10355 // iterate across all processes 10356 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10357 ProcessRecord app = mLruProcesses.get(i); 10358 if (!allUsers && app.userId != userId) { 10359 continue; 10360 } 10361 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10362 // This one's in trouble, so we'll generate a report for it 10363 // crashes are higher priority (in case there's a crash *and* an anr) 10364 ActivityManager.ProcessErrorStateInfo report = null; 10365 if (app.crashing) { 10366 report = app.crashingReport; 10367 } else if (app.notResponding) { 10368 report = app.notRespondingReport; 10369 } 10370 10371 if (report != null) { 10372 if (errList == null) { 10373 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10374 } 10375 errList.add(report); 10376 } else { 10377 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10378 " crashing = " + app.crashing + 10379 " notResponding = " + app.notResponding); 10380 } 10381 } 10382 } 10383 } 10384 10385 return errList; 10386 } 10387 10388 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10389 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10390 if (currApp != null) { 10391 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10392 } 10393 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10394 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10395 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10396 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10397 if (currApp != null) { 10398 currApp.lru = 0; 10399 } 10400 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10401 } else if (adj >= ProcessList.SERVICE_ADJ) { 10402 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10403 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10404 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10405 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10406 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10407 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10408 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10409 } else { 10410 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10411 } 10412 } 10413 10414 private void fillInProcMemInfo(ProcessRecord app, 10415 ActivityManager.RunningAppProcessInfo outInfo) { 10416 outInfo.pid = app.pid; 10417 outInfo.uid = app.info.uid; 10418 if (mHeavyWeightProcess == app) { 10419 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10420 } 10421 if (app.persistent) { 10422 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10423 } 10424 if (app.activities.size() > 0) { 10425 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10426 } 10427 outInfo.lastTrimLevel = app.trimMemoryLevel; 10428 int adj = app.curAdj; 10429 outInfo.importance = oomAdjToImportance(adj, outInfo); 10430 outInfo.importanceReasonCode = app.adjTypeCode; 10431 } 10432 10433 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10434 enforceNotIsolatedCaller("getRunningAppProcesses"); 10435 // Lazy instantiation of list 10436 List<ActivityManager.RunningAppProcessInfo> runList = null; 10437 final boolean allUsers = ActivityManager.checkUidPermission( 10438 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10439 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10440 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10441 synchronized (this) { 10442 // Iterate across all processes 10443 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10444 ProcessRecord app = mLruProcesses.get(i); 10445 if (!allUsers && app.userId != userId) { 10446 continue; 10447 } 10448 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10449 // Generate process state info for running application 10450 ActivityManager.RunningAppProcessInfo currApp = 10451 new ActivityManager.RunningAppProcessInfo(app.processName, 10452 app.pid, app.getPackageList()); 10453 fillInProcMemInfo(app, currApp); 10454 if (app.adjSource instanceof ProcessRecord) { 10455 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10456 currApp.importanceReasonImportance = oomAdjToImportance( 10457 app.adjSourceOom, null); 10458 } else if (app.adjSource instanceof ActivityRecord) { 10459 ActivityRecord r = (ActivityRecord)app.adjSource; 10460 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10461 } 10462 if (app.adjTarget instanceof ComponentName) { 10463 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10464 } 10465 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10466 // + " lru=" + currApp.lru); 10467 if (runList == null) { 10468 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10469 } 10470 runList.add(currApp); 10471 } 10472 } 10473 } 10474 return runList; 10475 } 10476 10477 public List<ApplicationInfo> getRunningExternalApplications() { 10478 enforceNotIsolatedCaller("getRunningExternalApplications"); 10479 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10480 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10481 if (runningApps != null && runningApps.size() > 0) { 10482 Set<String> extList = new HashSet<String>(); 10483 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10484 if (app.pkgList != null) { 10485 for (String pkg : app.pkgList) { 10486 extList.add(pkg); 10487 } 10488 } 10489 } 10490 IPackageManager pm = AppGlobals.getPackageManager(); 10491 for (String pkg : extList) { 10492 try { 10493 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10494 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10495 retList.add(info); 10496 } 10497 } catch (RemoteException e) { 10498 } 10499 } 10500 } 10501 return retList; 10502 } 10503 10504 @Override 10505 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10506 enforceNotIsolatedCaller("getMyMemoryState"); 10507 synchronized (this) { 10508 ProcessRecord proc; 10509 synchronized (mPidsSelfLocked) { 10510 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10511 } 10512 fillInProcMemInfo(proc, outInfo); 10513 } 10514 } 10515 10516 @Override 10517 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10518 if (checkCallingPermission(android.Manifest.permission.DUMP) 10519 != PackageManager.PERMISSION_GRANTED) { 10520 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10521 + Binder.getCallingPid() 10522 + ", uid=" + Binder.getCallingUid() 10523 + " without permission " 10524 + android.Manifest.permission.DUMP); 10525 return; 10526 } 10527 10528 boolean dumpAll = false; 10529 boolean dumpClient = false; 10530 String dumpPackage = null; 10531 10532 int opti = 0; 10533 while (opti < args.length) { 10534 String opt = args[opti]; 10535 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10536 break; 10537 } 10538 opti++; 10539 if ("-a".equals(opt)) { 10540 dumpAll = true; 10541 } else if ("-c".equals(opt)) { 10542 dumpClient = true; 10543 } else if ("-h".equals(opt)) { 10544 pw.println("Activity manager dump options:"); 10545 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10546 pw.println(" cmd may be one of:"); 10547 pw.println(" a[ctivities]: activity stack state"); 10548 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10549 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10550 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10551 pw.println(" o[om]: out of memory management"); 10552 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10553 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10554 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10555 pw.println(" service [COMP_SPEC]: service client-side state"); 10556 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10557 pw.println(" all: dump all activities"); 10558 pw.println(" top: dump the top activity"); 10559 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10560 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10561 pw.println(" a partial substring in a component name, a"); 10562 pw.println(" hex object identifier."); 10563 pw.println(" -a: include all available server state."); 10564 pw.println(" -c: include client state."); 10565 return; 10566 } else { 10567 pw.println("Unknown argument: " + opt + "; use -h for help"); 10568 } 10569 } 10570 10571 long origId = Binder.clearCallingIdentity(); 10572 boolean more = false; 10573 // Is the caller requesting to dump a particular piece of data? 10574 if (opti < args.length) { 10575 String cmd = args[opti]; 10576 opti++; 10577 if ("activities".equals(cmd) || "a".equals(cmd)) { 10578 synchronized (this) { 10579 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10580 } 10581 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10582 String[] newArgs; 10583 String name; 10584 if (opti >= args.length) { 10585 name = null; 10586 newArgs = EMPTY_STRING_ARRAY; 10587 } else { 10588 name = args[opti]; 10589 opti++; 10590 newArgs = new String[args.length - opti]; 10591 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10592 args.length - opti); 10593 } 10594 synchronized (this) { 10595 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10596 } 10597 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10598 String[] newArgs; 10599 String name; 10600 if (opti >= args.length) { 10601 name = null; 10602 newArgs = EMPTY_STRING_ARRAY; 10603 } else { 10604 name = args[opti]; 10605 opti++; 10606 newArgs = new String[args.length - opti]; 10607 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10608 args.length - opti); 10609 } 10610 synchronized (this) { 10611 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10612 } 10613 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10614 String[] newArgs; 10615 String name; 10616 if (opti >= args.length) { 10617 name = null; 10618 newArgs = EMPTY_STRING_ARRAY; 10619 } else { 10620 name = args[opti]; 10621 opti++; 10622 newArgs = new String[args.length - opti]; 10623 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10624 args.length - opti); 10625 } 10626 synchronized (this) { 10627 dumpProcessesLocked(fd, pw, args, opti, true, name); 10628 } 10629 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10630 synchronized (this) { 10631 dumpOomLocked(fd, pw, args, opti, true); 10632 } 10633 } else if ("provider".equals(cmd)) { 10634 String[] newArgs; 10635 String name; 10636 if (opti >= args.length) { 10637 name = null; 10638 newArgs = EMPTY_STRING_ARRAY; 10639 } else { 10640 name = args[opti]; 10641 opti++; 10642 newArgs = new String[args.length - opti]; 10643 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10644 } 10645 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10646 pw.println("No providers match: " + name); 10647 pw.println("Use -h for help."); 10648 } 10649 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10650 synchronized (this) { 10651 dumpProvidersLocked(fd, pw, args, opti, true, null); 10652 } 10653 } else if ("service".equals(cmd)) { 10654 String[] newArgs; 10655 String name; 10656 if (opti >= args.length) { 10657 name = null; 10658 newArgs = EMPTY_STRING_ARRAY; 10659 } else { 10660 name = args[opti]; 10661 opti++; 10662 newArgs = new String[args.length - opti]; 10663 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10664 args.length - opti); 10665 } 10666 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10667 pw.println("No services match: " + name); 10668 pw.println("Use -h for help."); 10669 } 10670 } else if ("package".equals(cmd)) { 10671 String[] newArgs; 10672 if (opti >= args.length) { 10673 pw.println("package: no package name specified"); 10674 pw.println("Use -h for help."); 10675 } else { 10676 dumpPackage = args[opti]; 10677 opti++; 10678 newArgs = new String[args.length - opti]; 10679 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10680 args.length - opti); 10681 args = newArgs; 10682 opti = 0; 10683 more = true; 10684 } 10685 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10686 synchronized (this) { 10687 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10688 } 10689 } else { 10690 // Dumping a single activity? 10691 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10692 pw.println("Bad activity command, or no activities match: " + cmd); 10693 pw.println("Use -h for help."); 10694 } 10695 } 10696 if (!more) { 10697 Binder.restoreCallingIdentity(origId); 10698 return; 10699 } 10700 } 10701 10702 // No piece of data specified, dump everything. 10703 synchronized (this) { 10704 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10705 pw.println(); 10706 if (dumpAll) { 10707 pw.println("-------------------------------------------------------------------------------"); 10708 } 10709 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10710 pw.println(); 10711 if (dumpAll) { 10712 pw.println("-------------------------------------------------------------------------------"); 10713 } 10714 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10715 pw.println(); 10716 if (dumpAll) { 10717 pw.println("-------------------------------------------------------------------------------"); 10718 } 10719 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10720 pw.println(); 10721 if (dumpAll) { 10722 pw.println("-------------------------------------------------------------------------------"); 10723 } 10724 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10725 pw.println(); 10726 if (dumpAll) { 10727 pw.println("-------------------------------------------------------------------------------"); 10728 } 10729 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10730 } 10731 Binder.restoreCallingIdentity(origId); 10732 } 10733 10734 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10735 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10736 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10737 10738 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10739 dumpPackage); 10740 boolean needSep = printedAnything; 10741 10742 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10743 dumpPackage, needSep, " mFocusedActivity: "); 10744 if (printed) { 10745 printedAnything = true; 10746 needSep = false; 10747 } 10748 10749 if (dumpPackage == null) { 10750 if (needSep) { 10751 pw.println(); 10752 } 10753 needSep = true; 10754 printedAnything = true; 10755 mStackSupervisor.dump(pw, " "); 10756 } 10757 10758 if (mRecentTasks.size() > 0) { 10759 boolean printedHeader = false; 10760 10761 final int N = mRecentTasks.size(); 10762 for (int i=0; i<N; i++) { 10763 TaskRecord tr = mRecentTasks.get(i); 10764 if (dumpPackage != null) { 10765 if (tr.realActivity == null || 10766 !dumpPackage.equals(tr.realActivity)) { 10767 continue; 10768 } 10769 } 10770 if (!printedHeader) { 10771 if (needSep) { 10772 pw.println(); 10773 } 10774 pw.println(" Recent tasks:"); 10775 printedHeader = true; 10776 printedAnything = true; 10777 } 10778 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10779 pw.println(tr); 10780 if (dumpAll) { 10781 mRecentTasks.get(i).dump(pw, " "); 10782 } 10783 } 10784 } 10785 10786 if (!printedAnything) { 10787 pw.println(" (nothing)"); 10788 } 10789 } 10790 10791 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10792 int opti, boolean dumpAll, String dumpPackage) { 10793 boolean needSep = false; 10794 boolean printedAnything = false; 10795 int numPers = 0; 10796 10797 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10798 10799 if (dumpAll) { 10800 final int NP = mProcessNames.getMap().size(); 10801 for (int ip=0; ip<NP; ip++) { 10802 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10803 final int NA = procs.size(); 10804 for (int ia=0; ia<NA; ia++) { 10805 ProcessRecord r = procs.valueAt(ia); 10806 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10807 continue; 10808 } 10809 if (!needSep) { 10810 pw.println(" All known processes:"); 10811 needSep = true; 10812 printedAnything = true; 10813 } 10814 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10815 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10816 pw.print(" "); pw.println(r); 10817 r.dump(pw, " "); 10818 if (r.persistent) { 10819 numPers++; 10820 } 10821 } 10822 } 10823 } 10824 10825 if (mIsolatedProcesses.size() > 0) { 10826 boolean printed = false; 10827 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10828 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10829 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10830 continue; 10831 } 10832 if (!printed) { 10833 if (needSep) { 10834 pw.println(); 10835 } 10836 pw.println(" Isolated process list (sorted by uid):"); 10837 printedAnything = true; 10838 printed = true; 10839 needSep = true; 10840 } 10841 pw.println(String.format("%sIsolated #%2d: %s", 10842 " ", i, r.toString())); 10843 } 10844 } 10845 10846 if (mLruProcesses.size() > 0) { 10847 if (needSep) { 10848 pw.println(); 10849 } 10850 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10851 pw.print(" total, non-act at "); 10852 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10853 pw.print(", non-svc at "); 10854 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10855 pw.println("):"); 10856 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10857 needSep = true; 10858 printedAnything = true; 10859 } 10860 10861 if (dumpAll || dumpPackage != null) { 10862 synchronized (mPidsSelfLocked) { 10863 boolean printed = false; 10864 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10865 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10866 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10867 continue; 10868 } 10869 if (!printed) { 10870 if (needSep) pw.println(); 10871 needSep = true; 10872 pw.println(" PID mappings:"); 10873 printed = true; 10874 printedAnything = true; 10875 } 10876 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10877 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10878 } 10879 } 10880 } 10881 10882 if (mForegroundProcesses.size() > 0) { 10883 synchronized (mPidsSelfLocked) { 10884 boolean printed = false; 10885 for (int i=0; i<mForegroundProcesses.size(); i++) { 10886 ProcessRecord r = mPidsSelfLocked.get( 10887 mForegroundProcesses.valueAt(i).pid); 10888 if (dumpPackage != null && (r == null 10889 || !r.pkgList.containsKey(dumpPackage))) { 10890 continue; 10891 } 10892 if (!printed) { 10893 if (needSep) pw.println(); 10894 needSep = true; 10895 pw.println(" Foreground Processes:"); 10896 printed = true; 10897 printedAnything = true; 10898 } 10899 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10900 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10901 } 10902 } 10903 } 10904 10905 if (mPersistentStartingProcesses.size() > 0) { 10906 if (needSep) pw.println(); 10907 needSep = true; 10908 printedAnything = true; 10909 pw.println(" Persisent processes that are starting:"); 10910 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10911 "Starting Norm", "Restarting PERS", dumpPackage); 10912 } 10913 10914 if (mRemovedProcesses.size() > 0) { 10915 if (needSep) pw.println(); 10916 needSep = true; 10917 printedAnything = true; 10918 pw.println(" Processes that are being removed:"); 10919 dumpProcessList(pw, this, mRemovedProcesses, " ", 10920 "Removed Norm", "Removed PERS", dumpPackage); 10921 } 10922 10923 if (mProcessesOnHold.size() > 0) { 10924 if (needSep) pw.println(); 10925 needSep = true; 10926 printedAnything = true; 10927 pw.println(" Processes that are on old until the system is ready:"); 10928 dumpProcessList(pw, this, mProcessesOnHold, " ", 10929 "OnHold Norm", "OnHold PERS", dumpPackage); 10930 } 10931 10932 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10933 10934 if (mProcessCrashTimes.getMap().size() > 0) { 10935 boolean printed = false; 10936 long now = SystemClock.uptimeMillis(); 10937 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10938 final int NP = pmap.size(); 10939 for (int ip=0; ip<NP; ip++) { 10940 String pname = pmap.keyAt(ip); 10941 SparseArray<Long> uids = pmap.valueAt(ip); 10942 final int N = uids.size(); 10943 for (int i=0; i<N; i++) { 10944 int puid = uids.keyAt(i); 10945 ProcessRecord r = mProcessNames.get(pname, puid); 10946 if (dumpPackage != null && (r == null 10947 || !r.pkgList.containsKey(dumpPackage))) { 10948 continue; 10949 } 10950 if (!printed) { 10951 if (needSep) pw.println(); 10952 needSep = true; 10953 pw.println(" Time since processes crashed:"); 10954 printed = true; 10955 printedAnything = true; 10956 } 10957 pw.print(" Process "); pw.print(pname); 10958 pw.print(" uid "); pw.print(puid); 10959 pw.print(": last crashed "); 10960 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10961 pw.println(" ago"); 10962 } 10963 } 10964 } 10965 10966 if (mBadProcesses.getMap().size() > 0) { 10967 boolean printed = false; 10968 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10969 final int NP = pmap.size(); 10970 for (int ip=0; ip<NP; ip++) { 10971 String pname = pmap.keyAt(ip); 10972 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10973 final int N = uids.size(); 10974 for (int i=0; i<N; i++) { 10975 int puid = uids.keyAt(i); 10976 ProcessRecord r = mProcessNames.get(pname, puid); 10977 if (dumpPackage != null && (r == null 10978 || !r.pkgList.containsKey(dumpPackage))) { 10979 continue; 10980 } 10981 if (!printed) { 10982 if (needSep) pw.println(); 10983 needSep = true; 10984 pw.println(" Bad processes:"); 10985 printedAnything = true; 10986 } 10987 BadProcessInfo info = uids.valueAt(i); 10988 pw.print(" Bad process "); pw.print(pname); 10989 pw.print(" uid "); pw.print(puid); 10990 pw.print(": crashed at time "); pw.println(info.time); 10991 if (info.shortMsg != null) { 10992 pw.print(" Short msg: "); pw.println(info.shortMsg); 10993 } 10994 if (info.longMsg != null) { 10995 pw.print(" Long msg: "); pw.println(info.longMsg); 10996 } 10997 if (info.stack != null) { 10998 pw.println(" Stack:"); 10999 int lastPos = 0; 11000 for (int pos=0; pos<info.stack.length(); pos++) { 11001 if (info.stack.charAt(pos) == '\n') { 11002 pw.print(" "); 11003 pw.write(info.stack, lastPos, pos-lastPos); 11004 pw.println(); 11005 lastPos = pos+1; 11006 } 11007 } 11008 if (lastPos < info.stack.length()) { 11009 pw.print(" "); 11010 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11011 pw.println(); 11012 } 11013 } 11014 } 11015 } 11016 } 11017 11018 if (dumpPackage == null) { 11019 pw.println(); 11020 needSep = false; 11021 pw.println(" mStartedUsers:"); 11022 for (int i=0; i<mStartedUsers.size(); i++) { 11023 UserStartedState uss = mStartedUsers.valueAt(i); 11024 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11025 pw.print(": "); uss.dump("", pw); 11026 } 11027 pw.print(" mStartedUserArray: ["); 11028 for (int i=0; i<mStartedUserArray.length; i++) { 11029 if (i > 0) pw.print(", "); 11030 pw.print(mStartedUserArray[i]); 11031 } 11032 pw.println("]"); 11033 pw.print(" mUserLru: ["); 11034 for (int i=0; i<mUserLru.size(); i++) { 11035 if (i > 0) pw.print(", "); 11036 pw.print(mUserLru.get(i)); 11037 } 11038 pw.println("]"); 11039 if (dumpAll) { 11040 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11041 } 11042 } 11043 if (mHomeProcess != null && (dumpPackage == null 11044 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11045 if (needSep) { 11046 pw.println(); 11047 needSep = false; 11048 } 11049 pw.println(" mHomeProcess: " + mHomeProcess); 11050 } 11051 if (mPreviousProcess != null && (dumpPackage == null 11052 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11053 if (needSep) { 11054 pw.println(); 11055 needSep = false; 11056 } 11057 pw.println(" mPreviousProcess: " + mPreviousProcess); 11058 } 11059 if (dumpAll) { 11060 StringBuilder sb = new StringBuilder(128); 11061 sb.append(" mPreviousProcessVisibleTime: "); 11062 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11063 pw.println(sb); 11064 } 11065 if (mHeavyWeightProcess != null && (dumpPackage == null 11066 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11067 if (needSep) { 11068 pw.println(); 11069 needSep = false; 11070 } 11071 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11072 } 11073 if (dumpPackage == null) { 11074 pw.println(" mConfiguration: " + mConfiguration); 11075 } 11076 if (dumpAll) { 11077 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11078 if (mCompatModePackages.getPackages().size() > 0) { 11079 boolean printed = false; 11080 for (Map.Entry<String, Integer> entry 11081 : mCompatModePackages.getPackages().entrySet()) { 11082 String pkg = entry.getKey(); 11083 int mode = entry.getValue(); 11084 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11085 continue; 11086 } 11087 if (!printed) { 11088 pw.println(" mScreenCompatPackages:"); 11089 printed = true; 11090 } 11091 pw.print(" "); pw.print(pkg); pw.print(": "); 11092 pw.print(mode); pw.println(); 11093 } 11094 } 11095 } 11096 if (dumpPackage == null) { 11097 if (mSleeping || mWentToSleep || mLockScreenShown) { 11098 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11099 + " mLockScreenShown " + mLockScreenShown); 11100 } 11101 if (mShuttingDown) { 11102 pw.println(" mShuttingDown=" + mShuttingDown); 11103 } 11104 } 11105 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11106 || mOrigWaitForDebugger) { 11107 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11108 || dumpPackage.equals(mOrigDebugApp)) { 11109 if (needSep) { 11110 pw.println(); 11111 needSep = false; 11112 } 11113 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11114 + " mDebugTransient=" + mDebugTransient 11115 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11116 } 11117 } 11118 if (mOpenGlTraceApp != null) { 11119 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11120 if (needSep) { 11121 pw.println(); 11122 needSep = false; 11123 } 11124 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11125 } 11126 } 11127 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11128 || mProfileFd != null) { 11129 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11130 if (needSep) { 11131 pw.println(); 11132 needSep = false; 11133 } 11134 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11135 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11136 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11137 + mAutoStopProfiler); 11138 } 11139 } 11140 if (dumpPackage == null) { 11141 if (mAlwaysFinishActivities || mController != null) { 11142 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11143 + " mController=" + mController); 11144 } 11145 if (dumpAll) { 11146 pw.println(" Total persistent processes: " + numPers); 11147 pw.println(" mStartRunning=" + mStartRunning 11148 + " mProcessesReady=" + mProcessesReady 11149 + " mSystemReady=" + mSystemReady); 11150 pw.println(" mBooting=" + mBooting 11151 + " mBooted=" + mBooted 11152 + " mFactoryTest=" + mFactoryTest); 11153 pw.print(" mLastPowerCheckRealtime="); 11154 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11155 pw.println(""); 11156 pw.print(" mLastPowerCheckUptime="); 11157 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11158 pw.println(""); 11159 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11160 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11161 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11162 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11163 + " (" + mLruProcesses.size() + " total)" 11164 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11165 + " mNumServiceProcs=" + mNumServiceProcs 11166 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11167 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11168 + " mLastMemoryLevel" + mLastMemoryLevel 11169 + " mLastNumProcesses" + mLastNumProcesses); 11170 long now = SystemClock.uptimeMillis(); 11171 pw.print(" mLastIdleTime="); 11172 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11173 pw.print(" mLowRamSinceLastIdle="); 11174 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11175 pw.println(); 11176 } 11177 } 11178 11179 if (!printedAnything) { 11180 pw.println(" (nothing)"); 11181 } 11182 } 11183 11184 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11185 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11186 if (mProcessesToGc.size() > 0) { 11187 boolean printed = false; 11188 long now = SystemClock.uptimeMillis(); 11189 for (int i=0; i<mProcessesToGc.size(); i++) { 11190 ProcessRecord proc = mProcessesToGc.get(i); 11191 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11192 continue; 11193 } 11194 if (!printed) { 11195 if (needSep) pw.println(); 11196 needSep = true; 11197 pw.println(" Processes that are waiting to GC:"); 11198 printed = true; 11199 } 11200 pw.print(" Process "); pw.println(proc); 11201 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11202 pw.print(", last gced="); 11203 pw.print(now-proc.lastRequestedGc); 11204 pw.print(" ms ago, last lowMem="); 11205 pw.print(now-proc.lastLowMemory); 11206 pw.println(" ms ago"); 11207 11208 } 11209 } 11210 return needSep; 11211 } 11212 11213 void printOomLevel(PrintWriter pw, String name, int adj) { 11214 pw.print(" "); 11215 if (adj >= 0) { 11216 pw.print(' '); 11217 if (adj < 10) pw.print(' '); 11218 } else { 11219 if (adj > -10) pw.print(' '); 11220 } 11221 pw.print(adj); 11222 pw.print(": "); 11223 pw.print(name); 11224 pw.print(" ("); 11225 pw.print(mProcessList.getMemLevel(adj)/1024); 11226 pw.println(" kB)"); 11227 } 11228 11229 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11230 int opti, boolean dumpAll) { 11231 boolean needSep = false; 11232 11233 if (mLruProcesses.size() > 0) { 11234 if (needSep) pw.println(); 11235 needSep = true; 11236 pw.println(" OOM levels:"); 11237 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11238 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11239 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11240 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11241 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11242 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11243 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11244 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11245 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11246 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11247 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11248 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11249 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11250 11251 if (needSep) pw.println(); 11252 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11253 pw.print(" total, non-act at "); 11254 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11255 pw.print(", non-svc at "); 11256 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11257 pw.println("):"); 11258 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11259 needSep = true; 11260 } 11261 11262 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11263 11264 pw.println(); 11265 pw.println(" mHomeProcess: " + mHomeProcess); 11266 pw.println(" mPreviousProcess: " + mPreviousProcess); 11267 if (mHeavyWeightProcess != null) { 11268 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11269 } 11270 11271 return true; 11272 } 11273 11274 /** 11275 * There are three ways to call this: 11276 * - no provider specified: dump all the providers 11277 * - a flattened component name that matched an existing provider was specified as the 11278 * first arg: dump that one provider 11279 * - the first arg isn't the flattened component name of an existing provider: 11280 * dump all providers whose component contains the first arg as a substring 11281 */ 11282 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11283 int opti, boolean dumpAll) { 11284 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11285 } 11286 11287 static class ItemMatcher { 11288 ArrayList<ComponentName> components; 11289 ArrayList<String> strings; 11290 ArrayList<Integer> objects; 11291 boolean all; 11292 11293 ItemMatcher() { 11294 all = true; 11295 } 11296 11297 void build(String name) { 11298 ComponentName componentName = ComponentName.unflattenFromString(name); 11299 if (componentName != null) { 11300 if (components == null) { 11301 components = new ArrayList<ComponentName>(); 11302 } 11303 components.add(componentName); 11304 all = false; 11305 } else { 11306 int objectId = 0; 11307 // Not a '/' separated full component name; maybe an object ID? 11308 try { 11309 objectId = Integer.parseInt(name, 16); 11310 if (objects == null) { 11311 objects = new ArrayList<Integer>(); 11312 } 11313 objects.add(objectId); 11314 all = false; 11315 } catch (RuntimeException e) { 11316 // Not an integer; just do string match. 11317 if (strings == null) { 11318 strings = new ArrayList<String>(); 11319 } 11320 strings.add(name); 11321 all = false; 11322 } 11323 } 11324 } 11325 11326 int build(String[] args, int opti) { 11327 for (; opti<args.length; opti++) { 11328 String name = args[opti]; 11329 if ("--".equals(name)) { 11330 return opti+1; 11331 } 11332 build(name); 11333 } 11334 return opti; 11335 } 11336 11337 boolean match(Object object, ComponentName comp) { 11338 if (all) { 11339 return true; 11340 } 11341 if (components != null) { 11342 for (int i=0; i<components.size(); i++) { 11343 if (components.get(i).equals(comp)) { 11344 return true; 11345 } 11346 } 11347 } 11348 if (objects != null) { 11349 for (int i=0; i<objects.size(); i++) { 11350 if (System.identityHashCode(object) == objects.get(i)) { 11351 return true; 11352 } 11353 } 11354 } 11355 if (strings != null) { 11356 String flat = comp.flattenToString(); 11357 for (int i=0; i<strings.size(); i++) { 11358 if (flat.contains(strings.get(i))) { 11359 return true; 11360 } 11361 } 11362 } 11363 return false; 11364 } 11365 } 11366 11367 /** 11368 * There are three things that cmd can be: 11369 * - a flattened component name that matches an existing activity 11370 * - the cmd arg isn't the flattened component name of an existing activity: 11371 * dump all activity whose component contains the cmd as a substring 11372 * - A hex number of the ActivityRecord object instance. 11373 */ 11374 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11375 int opti, boolean dumpAll) { 11376 ArrayList<ActivityRecord> activities; 11377 11378 synchronized (this) { 11379 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11380 } 11381 11382 if (activities.size() <= 0) { 11383 return false; 11384 } 11385 11386 String[] newArgs = new String[args.length - opti]; 11387 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11388 11389 TaskRecord lastTask = null; 11390 boolean needSep = false; 11391 for (int i=activities.size()-1; i>=0; i--) { 11392 ActivityRecord r = activities.get(i); 11393 if (needSep) { 11394 pw.println(); 11395 } 11396 needSep = true; 11397 synchronized (this) { 11398 if (lastTask != r.task) { 11399 lastTask = r.task; 11400 pw.print("TASK "); pw.print(lastTask.affinity); 11401 pw.print(" id="); pw.println(lastTask.taskId); 11402 if (dumpAll) { 11403 lastTask.dump(pw, " "); 11404 } 11405 } 11406 } 11407 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11408 } 11409 return true; 11410 } 11411 11412 /** 11413 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11414 * there is a thread associated with the activity. 11415 */ 11416 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11417 final ActivityRecord r, String[] args, boolean dumpAll) { 11418 String innerPrefix = prefix + " "; 11419 synchronized (this) { 11420 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11421 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11422 pw.print(" pid="); 11423 if (r.app != null) pw.println(r.app.pid); 11424 else pw.println("(not running)"); 11425 if (dumpAll) { 11426 r.dump(pw, innerPrefix); 11427 } 11428 } 11429 if (r.app != null && r.app.thread != null) { 11430 // flush anything that is already in the PrintWriter since the thread is going 11431 // to write to the file descriptor directly 11432 pw.flush(); 11433 try { 11434 TransferPipe tp = new TransferPipe(); 11435 try { 11436 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11437 r.appToken, innerPrefix, args); 11438 tp.go(fd); 11439 } finally { 11440 tp.kill(); 11441 } 11442 } catch (IOException e) { 11443 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11444 } catch (RemoteException e) { 11445 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11446 } 11447 } 11448 } 11449 11450 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11451 int opti, boolean dumpAll, String dumpPackage) { 11452 boolean needSep = false; 11453 boolean onlyHistory = false; 11454 boolean printedAnything = false; 11455 11456 if ("history".equals(dumpPackage)) { 11457 if (opti < args.length && "-s".equals(args[opti])) { 11458 dumpAll = false; 11459 } 11460 onlyHistory = true; 11461 dumpPackage = null; 11462 } 11463 11464 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11465 if (!onlyHistory && dumpAll) { 11466 if (mRegisteredReceivers.size() > 0) { 11467 boolean printed = false; 11468 Iterator it = mRegisteredReceivers.values().iterator(); 11469 while (it.hasNext()) { 11470 ReceiverList r = (ReceiverList)it.next(); 11471 if (dumpPackage != null && (r.app == null || 11472 !dumpPackage.equals(r.app.info.packageName))) { 11473 continue; 11474 } 11475 if (!printed) { 11476 pw.println(" Registered Receivers:"); 11477 needSep = true; 11478 printed = true; 11479 printedAnything = true; 11480 } 11481 pw.print(" * "); pw.println(r); 11482 r.dump(pw, " "); 11483 } 11484 } 11485 11486 if (mReceiverResolver.dump(pw, needSep ? 11487 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11488 " ", dumpPackage, false)) { 11489 needSep = true; 11490 printedAnything = true; 11491 } 11492 } 11493 11494 for (BroadcastQueue q : mBroadcastQueues) { 11495 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11496 printedAnything |= needSep; 11497 } 11498 11499 needSep = true; 11500 11501 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11502 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11503 if (needSep) { 11504 pw.println(); 11505 } 11506 needSep = true; 11507 printedAnything = true; 11508 pw.print(" Sticky broadcasts for user "); 11509 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11510 StringBuilder sb = new StringBuilder(128); 11511 for (Map.Entry<String, ArrayList<Intent>> ent 11512 : mStickyBroadcasts.valueAt(user).entrySet()) { 11513 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11514 if (dumpAll) { 11515 pw.println(":"); 11516 ArrayList<Intent> intents = ent.getValue(); 11517 final int N = intents.size(); 11518 for (int i=0; i<N; i++) { 11519 sb.setLength(0); 11520 sb.append(" Intent: "); 11521 intents.get(i).toShortString(sb, false, true, false, false); 11522 pw.println(sb.toString()); 11523 Bundle bundle = intents.get(i).getExtras(); 11524 if (bundle != null) { 11525 pw.print(" "); 11526 pw.println(bundle.toString()); 11527 } 11528 } 11529 } else { 11530 pw.println(""); 11531 } 11532 } 11533 } 11534 } 11535 11536 if (!onlyHistory && dumpAll) { 11537 pw.println(); 11538 for (BroadcastQueue queue : mBroadcastQueues) { 11539 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11540 + queue.mBroadcastsScheduled); 11541 } 11542 pw.println(" mHandler:"); 11543 mHandler.dump(new PrintWriterPrinter(pw), " "); 11544 needSep = true; 11545 printedAnything = true; 11546 } 11547 11548 if (!printedAnything) { 11549 pw.println(" (nothing)"); 11550 } 11551 } 11552 11553 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11554 int opti, boolean dumpAll, String dumpPackage) { 11555 boolean needSep; 11556 boolean printedAnything = false; 11557 11558 ItemMatcher matcher = new ItemMatcher(); 11559 matcher.build(args, opti); 11560 11561 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11562 11563 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11564 printedAnything |= needSep; 11565 11566 if (mLaunchingProviders.size() > 0) { 11567 boolean printed = false; 11568 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11569 ContentProviderRecord r = mLaunchingProviders.get(i); 11570 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11571 continue; 11572 } 11573 if (!printed) { 11574 if (needSep) pw.println(); 11575 needSep = true; 11576 pw.println(" Launching content providers:"); 11577 printed = true; 11578 printedAnything = true; 11579 } 11580 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11581 pw.println(r); 11582 } 11583 } 11584 11585 if (mGrantedUriPermissions.size() > 0) { 11586 boolean printed = false; 11587 int dumpUid = -2; 11588 if (dumpPackage != null) { 11589 try { 11590 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11591 } catch (NameNotFoundException e) { 11592 dumpUid = -1; 11593 } 11594 } 11595 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11596 int uid = mGrantedUriPermissions.keyAt(i); 11597 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11598 continue; 11599 } 11600 ArrayMap<Uri, UriPermission> perms 11601 = mGrantedUriPermissions.valueAt(i); 11602 if (!printed) { 11603 if (needSep) pw.println(); 11604 needSep = true; 11605 pw.println(" Granted Uri Permissions:"); 11606 printed = true; 11607 printedAnything = true; 11608 } 11609 pw.print(" * UID "); pw.print(uid); 11610 pw.println(" holds:"); 11611 for (UriPermission perm : perms.values()) { 11612 pw.print(" "); pw.println(perm); 11613 if (dumpAll) { 11614 perm.dump(pw, " "); 11615 } 11616 } 11617 } 11618 } 11619 11620 if (!printedAnything) { 11621 pw.println(" (nothing)"); 11622 } 11623 } 11624 11625 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11626 int opti, boolean dumpAll, String dumpPackage) { 11627 boolean printed = false; 11628 11629 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11630 11631 if (mIntentSenderRecords.size() > 0) { 11632 Iterator<WeakReference<PendingIntentRecord>> it 11633 = mIntentSenderRecords.values().iterator(); 11634 while (it.hasNext()) { 11635 WeakReference<PendingIntentRecord> ref = it.next(); 11636 PendingIntentRecord rec = ref != null ? ref.get(): null; 11637 if (dumpPackage != null && (rec == null 11638 || !dumpPackage.equals(rec.key.packageName))) { 11639 continue; 11640 } 11641 printed = true; 11642 if (rec != null) { 11643 pw.print(" * "); pw.println(rec); 11644 if (dumpAll) { 11645 rec.dump(pw, " "); 11646 } 11647 } else { 11648 pw.print(" * "); pw.println(ref); 11649 } 11650 } 11651 } 11652 11653 if (!printed) { 11654 pw.println(" (nothing)"); 11655 } 11656 } 11657 11658 private static final int dumpProcessList(PrintWriter pw, 11659 ActivityManagerService service, List list, 11660 String prefix, String normalLabel, String persistentLabel, 11661 String dumpPackage) { 11662 int numPers = 0; 11663 final int N = list.size()-1; 11664 for (int i=N; i>=0; i--) { 11665 ProcessRecord r = (ProcessRecord)list.get(i); 11666 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11667 continue; 11668 } 11669 pw.println(String.format("%s%s #%2d: %s", 11670 prefix, (r.persistent ? persistentLabel : normalLabel), 11671 i, r.toString())); 11672 if (r.persistent) { 11673 numPers++; 11674 } 11675 } 11676 return numPers; 11677 } 11678 11679 private static final boolean dumpProcessOomList(PrintWriter pw, 11680 ActivityManagerService service, List<ProcessRecord> origList, 11681 String prefix, String normalLabel, String persistentLabel, 11682 boolean inclDetails, String dumpPackage) { 11683 11684 ArrayList<Pair<ProcessRecord, Integer>> list 11685 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11686 for (int i=0; i<origList.size(); i++) { 11687 ProcessRecord r = origList.get(i); 11688 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11689 continue; 11690 } 11691 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11692 } 11693 11694 if (list.size() <= 0) { 11695 return false; 11696 } 11697 11698 Comparator<Pair<ProcessRecord, Integer>> comparator 11699 = new Comparator<Pair<ProcessRecord, Integer>>() { 11700 @Override 11701 public int compare(Pair<ProcessRecord, Integer> object1, 11702 Pair<ProcessRecord, Integer> object2) { 11703 if (object1.first.setAdj != object2.first.setAdj) { 11704 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11705 } 11706 if (object1.second.intValue() != object2.second.intValue()) { 11707 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11708 } 11709 return 0; 11710 } 11711 }; 11712 11713 Collections.sort(list, comparator); 11714 11715 final long curRealtime = SystemClock.elapsedRealtime(); 11716 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11717 final long curUptime = SystemClock.uptimeMillis(); 11718 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11719 11720 for (int i=list.size()-1; i>=0; i--) { 11721 ProcessRecord r = list.get(i).first; 11722 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11723 char schedGroup; 11724 switch (r.setSchedGroup) { 11725 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11726 schedGroup = 'B'; 11727 break; 11728 case Process.THREAD_GROUP_DEFAULT: 11729 schedGroup = 'F'; 11730 break; 11731 default: 11732 schedGroup = '?'; 11733 break; 11734 } 11735 char foreground; 11736 if (r.foregroundActivities) { 11737 foreground = 'A'; 11738 } else if (r.foregroundServices) { 11739 foreground = 'S'; 11740 } else { 11741 foreground = ' '; 11742 } 11743 String procState = ProcessList.makeProcStateString(r.curProcState); 11744 pw.print(prefix); 11745 pw.print(r.persistent ? persistentLabel : normalLabel); 11746 pw.print(" #"); 11747 int num = (origList.size()-1)-list.get(i).second; 11748 if (num < 10) pw.print(' '); 11749 pw.print(num); 11750 pw.print(": "); 11751 pw.print(oomAdj); 11752 pw.print(' '); 11753 pw.print(schedGroup); 11754 pw.print('/'); 11755 pw.print(foreground); 11756 pw.print('/'); 11757 pw.print(procState); 11758 pw.print(" trm:"); 11759 if (r.trimMemoryLevel < 10) pw.print(' '); 11760 pw.print(r.trimMemoryLevel); 11761 pw.print(' '); 11762 pw.print(r.toShortString()); 11763 pw.print(" ("); 11764 pw.print(r.adjType); 11765 pw.println(')'); 11766 if (r.adjSource != null || r.adjTarget != null) { 11767 pw.print(prefix); 11768 pw.print(" "); 11769 if (r.adjTarget instanceof ComponentName) { 11770 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11771 } else if (r.adjTarget != null) { 11772 pw.print(r.adjTarget.toString()); 11773 } else { 11774 pw.print("{null}"); 11775 } 11776 pw.print("<="); 11777 if (r.adjSource instanceof ProcessRecord) { 11778 pw.print("Proc{"); 11779 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11780 pw.println("}"); 11781 } else if (r.adjSource != null) { 11782 pw.println(r.adjSource.toString()); 11783 } else { 11784 pw.println("{null}"); 11785 } 11786 } 11787 if (inclDetails) { 11788 pw.print(prefix); 11789 pw.print(" "); 11790 pw.print("oom: max="); pw.print(r.maxAdj); 11791 pw.print(" curRaw="); pw.print(r.curRawAdj); 11792 pw.print(" setRaw="); pw.print(r.setRawAdj); 11793 pw.print(" cur="); pw.print(r.curAdj); 11794 pw.print(" set="); pw.println(r.setAdj); 11795 pw.print(prefix); 11796 pw.print(" "); 11797 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11798 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11799 pw.print(" lastPss="); pw.print(r.lastPss); 11800 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11801 pw.print(prefix); 11802 pw.print(" "); 11803 pw.print("keeping="); pw.print(r.keeping); 11804 pw.print(" cached="); pw.print(r.cached); 11805 pw.print(" empty="); pw.print(r.empty); 11806 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11807 11808 if (!r.keeping) { 11809 if (r.lastWakeTime != 0) { 11810 long wtime; 11811 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11812 synchronized (stats) { 11813 wtime = stats.getProcessWakeTime(r.info.uid, 11814 r.pid, curRealtime); 11815 } 11816 long timeUsed = wtime - r.lastWakeTime; 11817 pw.print(prefix); 11818 pw.print(" "); 11819 pw.print("keep awake over "); 11820 TimeUtils.formatDuration(realtimeSince, pw); 11821 pw.print(" used "); 11822 TimeUtils.formatDuration(timeUsed, pw); 11823 pw.print(" ("); 11824 pw.print((timeUsed*100)/realtimeSince); 11825 pw.println("%)"); 11826 } 11827 if (r.lastCpuTime != 0) { 11828 long timeUsed = r.curCpuTime - r.lastCpuTime; 11829 pw.print(prefix); 11830 pw.print(" "); 11831 pw.print("run cpu over "); 11832 TimeUtils.formatDuration(uptimeSince, pw); 11833 pw.print(" used "); 11834 TimeUtils.formatDuration(timeUsed, pw); 11835 pw.print(" ("); 11836 pw.print((timeUsed*100)/uptimeSince); 11837 pw.println("%)"); 11838 } 11839 } 11840 } 11841 } 11842 return true; 11843 } 11844 11845 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11846 ArrayList<ProcessRecord> procs; 11847 synchronized (this) { 11848 if (args != null && args.length > start 11849 && args[start].charAt(0) != '-') { 11850 procs = new ArrayList<ProcessRecord>(); 11851 int pid = -1; 11852 try { 11853 pid = Integer.parseInt(args[start]); 11854 } catch (NumberFormatException e) { 11855 } 11856 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11857 ProcessRecord proc = mLruProcesses.get(i); 11858 if (proc.pid == pid) { 11859 procs.add(proc); 11860 } else if (proc.processName.equals(args[start])) { 11861 procs.add(proc); 11862 } 11863 } 11864 if (procs.size() <= 0) { 11865 return null; 11866 } 11867 } else { 11868 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11869 } 11870 } 11871 return procs; 11872 } 11873 11874 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11875 PrintWriter pw, String[] args) { 11876 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11877 if (procs == null) { 11878 pw.println("No process found for: " + args[0]); 11879 return; 11880 } 11881 11882 long uptime = SystemClock.uptimeMillis(); 11883 long realtime = SystemClock.elapsedRealtime(); 11884 pw.println("Applications Graphics Acceleration Info:"); 11885 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11886 11887 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11888 ProcessRecord r = procs.get(i); 11889 if (r.thread != null) { 11890 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11891 pw.flush(); 11892 try { 11893 TransferPipe tp = new TransferPipe(); 11894 try { 11895 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11896 tp.go(fd); 11897 } finally { 11898 tp.kill(); 11899 } 11900 } catch (IOException e) { 11901 pw.println("Failure while dumping the app: " + r); 11902 pw.flush(); 11903 } catch (RemoteException e) { 11904 pw.println("Got a RemoteException while dumping the app " + r); 11905 pw.flush(); 11906 } 11907 } 11908 } 11909 } 11910 11911 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11912 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11913 if (procs == null) { 11914 pw.println("No process found for: " + args[0]); 11915 return; 11916 } 11917 11918 pw.println("Applications Database Info:"); 11919 11920 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11921 ProcessRecord r = procs.get(i); 11922 if (r.thread != null) { 11923 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11924 pw.flush(); 11925 try { 11926 TransferPipe tp = new TransferPipe(); 11927 try { 11928 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11929 tp.go(fd); 11930 } finally { 11931 tp.kill(); 11932 } 11933 } catch (IOException e) { 11934 pw.println("Failure while dumping the app: " + r); 11935 pw.flush(); 11936 } catch (RemoteException e) { 11937 pw.println("Got a RemoteException while dumping the app " + r); 11938 pw.flush(); 11939 } 11940 } 11941 } 11942 } 11943 11944 final static class MemItem { 11945 final boolean isProc; 11946 final String label; 11947 final String shortLabel; 11948 final long pss; 11949 final int id; 11950 final boolean hasActivities; 11951 ArrayList<MemItem> subitems; 11952 11953 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11954 boolean _hasActivities) { 11955 isProc = true; 11956 label = _label; 11957 shortLabel = _shortLabel; 11958 pss = _pss; 11959 id = _id; 11960 hasActivities = _hasActivities; 11961 } 11962 11963 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11964 isProc = false; 11965 label = _label; 11966 shortLabel = _shortLabel; 11967 pss = _pss; 11968 id = _id; 11969 hasActivities = false; 11970 } 11971 } 11972 11973 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11974 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11975 if (sort && !isCompact) { 11976 Collections.sort(items, new Comparator<MemItem>() { 11977 @Override 11978 public int compare(MemItem lhs, MemItem rhs) { 11979 if (lhs.pss < rhs.pss) { 11980 return 1; 11981 } else if (lhs.pss > rhs.pss) { 11982 return -1; 11983 } 11984 return 0; 11985 } 11986 }); 11987 } 11988 11989 for (int i=0; i<items.size(); i++) { 11990 MemItem mi = items.get(i); 11991 if (!isCompact) { 11992 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11993 } else if (mi.isProc) { 11994 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11995 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11996 pw.println(mi.hasActivities ? ",a" : ",e"); 11997 } else { 11998 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11999 pw.println(mi.pss); 12000 } 12001 if (mi.subitems != null) { 12002 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12003 true, isCompact); 12004 } 12005 } 12006 } 12007 12008 // These are in KB. 12009 static final long[] DUMP_MEM_BUCKETS = new long[] { 12010 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12011 120*1024, 160*1024, 200*1024, 12012 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12013 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12014 }; 12015 12016 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12017 boolean stackLike) { 12018 int start = label.lastIndexOf('.'); 12019 if (start >= 0) start++; 12020 else start = 0; 12021 int end = label.length(); 12022 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12023 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12024 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12025 out.append(bucket); 12026 out.append(stackLike ? "MB." : "MB "); 12027 out.append(label, start, end); 12028 return; 12029 } 12030 } 12031 out.append(memKB/1024); 12032 out.append(stackLike ? "MB." : "MB "); 12033 out.append(label, start, end); 12034 } 12035 12036 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12037 ProcessList.NATIVE_ADJ, 12038 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12039 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12040 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12041 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12042 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12043 }; 12044 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12045 "Native", 12046 "System", "Persistent", "Foreground", 12047 "Visible", "Perceptible", 12048 "Heavy Weight", "Backup", 12049 "A Services", "Home", 12050 "Previous", "B Services", "Cached" 12051 }; 12052 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12053 "native", 12054 "sys", "pers", "fore", 12055 "vis", "percept", 12056 "heavy", "backup", 12057 "servicea", "home", 12058 "prev", "serviceb", "cached" 12059 }; 12060 12061 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12062 long realtime, boolean isCheckinRequest, boolean isCompact) { 12063 if (isCheckinRequest || isCompact) { 12064 // short checkin version 12065 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12066 } else { 12067 pw.println("Applications Memory Usage (kB):"); 12068 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12069 } 12070 } 12071 12072 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12073 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12074 boolean dumpDetails = false; 12075 boolean dumpFullDetails = false; 12076 boolean dumpDalvik = false; 12077 boolean oomOnly = false; 12078 boolean isCompact = false; 12079 boolean localOnly = false; 12080 12081 int opti = 0; 12082 while (opti < args.length) { 12083 String opt = args[opti]; 12084 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12085 break; 12086 } 12087 opti++; 12088 if ("-a".equals(opt)) { 12089 dumpDetails = true; 12090 dumpFullDetails = true; 12091 dumpDalvik = true; 12092 } else if ("-d".equals(opt)) { 12093 dumpDalvik = true; 12094 } else if ("-c".equals(opt)) { 12095 isCompact = true; 12096 } else if ("--oom".equals(opt)) { 12097 oomOnly = true; 12098 } else if ("--local".equals(opt)) { 12099 localOnly = true; 12100 } else if ("-h".equals(opt)) { 12101 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12102 pw.println(" -a: include all available information for each process."); 12103 pw.println(" -d: include dalvik details when dumping process details."); 12104 pw.println(" -c: dump in a compact machine-parseable representation."); 12105 pw.println(" --oom: only show processes organized by oom adj."); 12106 pw.println(" --local: only collect details locally, don't call process."); 12107 pw.println("If [process] is specified it can be the name or "); 12108 pw.println("pid of a specific process to dump."); 12109 return; 12110 } else { 12111 pw.println("Unknown argument: " + opt + "; use -h for help"); 12112 } 12113 } 12114 12115 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12116 long uptime = SystemClock.uptimeMillis(); 12117 long realtime = SystemClock.elapsedRealtime(); 12118 final long[] tmpLong = new long[1]; 12119 12120 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12121 if (procs == null) { 12122 // No Java processes. Maybe they want to print a native process. 12123 if (args != null && args.length > opti 12124 && args[opti].charAt(0) != '-') { 12125 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12126 = new ArrayList<ProcessCpuTracker.Stats>(); 12127 updateCpuStatsNow(); 12128 int findPid = -1; 12129 try { 12130 findPid = Integer.parseInt(args[opti]); 12131 } catch (NumberFormatException e) { 12132 } 12133 synchronized (mProcessCpuThread) { 12134 final int N = mProcessCpuTracker.countStats(); 12135 for (int i=0; i<N; i++) { 12136 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12137 if (st.pid == findPid || (st.baseName != null 12138 && st.baseName.equals(args[opti]))) { 12139 nativeProcs.add(st); 12140 } 12141 } 12142 } 12143 if (nativeProcs.size() > 0) { 12144 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12145 isCompact); 12146 Debug.MemoryInfo mi = null; 12147 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12148 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12149 final int pid = r.pid; 12150 if (!isCheckinRequest && dumpDetails) { 12151 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12152 } 12153 if (mi == null) { 12154 mi = new Debug.MemoryInfo(); 12155 } 12156 if (dumpDetails || (!brief && !oomOnly)) { 12157 Debug.getMemoryInfo(pid, mi); 12158 } else { 12159 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12160 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12161 } 12162 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12163 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12164 if (isCheckinRequest) { 12165 pw.println(); 12166 } 12167 } 12168 return; 12169 } 12170 } 12171 pw.println("No process found for: " + args[opti]); 12172 return; 12173 } 12174 12175 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12176 dumpDetails = true; 12177 } 12178 12179 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12180 12181 String[] innerArgs = new String[args.length-opti]; 12182 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12183 12184 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12185 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12186 long nativePss=0, dalvikPss=0, otherPss=0; 12187 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12188 12189 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12190 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12191 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12192 12193 long totalPss = 0; 12194 long cachedPss = 0; 12195 12196 Debug.MemoryInfo mi = null; 12197 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12198 final ProcessRecord r = procs.get(i); 12199 final IApplicationThread thread; 12200 final int pid; 12201 final int oomAdj; 12202 final boolean hasActivities; 12203 synchronized (this) { 12204 thread = r.thread; 12205 pid = r.pid; 12206 oomAdj = r.getSetAdjWithServices(); 12207 hasActivities = r.activities.size() > 0; 12208 } 12209 if (thread != null) { 12210 if (!isCheckinRequest && dumpDetails) { 12211 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12212 } 12213 if (mi == null) { 12214 mi = new Debug.MemoryInfo(); 12215 } 12216 if (dumpDetails || (!brief && !oomOnly)) { 12217 Debug.getMemoryInfo(pid, mi); 12218 } else { 12219 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12220 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12221 } 12222 if (dumpDetails) { 12223 if (localOnly) { 12224 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12225 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12226 if (isCheckinRequest) { 12227 pw.println(); 12228 } 12229 } else { 12230 try { 12231 pw.flush(); 12232 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12233 dumpDalvik, innerArgs); 12234 } catch (RemoteException e) { 12235 if (!isCheckinRequest) { 12236 pw.println("Got RemoteException!"); 12237 pw.flush(); 12238 } 12239 } 12240 } 12241 } 12242 12243 final long myTotalPss = mi.getTotalPss(); 12244 final long myTotalUss = mi.getTotalUss(); 12245 12246 synchronized (this) { 12247 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12248 // Record this for posterity if the process has been stable. 12249 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12250 } 12251 } 12252 12253 if (!isCheckinRequest && mi != null) { 12254 totalPss += myTotalPss; 12255 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12256 (hasActivities ? " / activities)" : ")"), 12257 r.processName, myTotalPss, pid, hasActivities); 12258 procMems.add(pssItem); 12259 procMemsMap.put(pid, pssItem); 12260 12261 nativePss += mi.nativePss; 12262 dalvikPss += mi.dalvikPss; 12263 otherPss += mi.otherPss; 12264 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12265 long mem = mi.getOtherPss(j); 12266 miscPss[j] += mem; 12267 otherPss -= mem; 12268 } 12269 12270 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12271 cachedPss += myTotalPss; 12272 } 12273 12274 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12275 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12276 || oomIndex == (oomPss.length-1)) { 12277 oomPss[oomIndex] += myTotalPss; 12278 if (oomProcs[oomIndex] == null) { 12279 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12280 } 12281 oomProcs[oomIndex].add(pssItem); 12282 break; 12283 } 12284 } 12285 } 12286 } 12287 } 12288 12289 if (!isCheckinRequest && procs.size() > 1) { 12290 // If we are showing aggregations, also look for native processes to 12291 // include so that our aggregations are more accurate. 12292 updateCpuStatsNow(); 12293 synchronized (mProcessCpuThread) { 12294 final int N = mProcessCpuTracker.countStats(); 12295 for (int i=0; i<N; i++) { 12296 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12297 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12298 if (mi == null) { 12299 mi = new Debug.MemoryInfo(); 12300 } 12301 if (!brief && !oomOnly) { 12302 Debug.getMemoryInfo(st.pid, mi); 12303 } else { 12304 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12305 mi.nativePrivateDirty = (int)tmpLong[0]; 12306 } 12307 12308 final long myTotalPss = mi.getTotalPss(); 12309 totalPss += myTotalPss; 12310 12311 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12312 st.name, myTotalPss, st.pid, false); 12313 procMems.add(pssItem); 12314 12315 nativePss += mi.nativePss; 12316 dalvikPss += mi.dalvikPss; 12317 otherPss += mi.otherPss; 12318 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12319 long mem = mi.getOtherPss(j); 12320 miscPss[j] += mem; 12321 otherPss -= mem; 12322 } 12323 oomPss[0] += myTotalPss; 12324 if (oomProcs[0] == null) { 12325 oomProcs[0] = new ArrayList<MemItem>(); 12326 } 12327 oomProcs[0].add(pssItem); 12328 } 12329 } 12330 } 12331 12332 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12333 12334 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12335 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12336 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12337 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12338 String label = Debug.MemoryInfo.getOtherLabel(j); 12339 catMems.add(new MemItem(label, label, miscPss[j], j)); 12340 } 12341 12342 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12343 for (int j=0; j<oomPss.length; j++) { 12344 if (oomPss[j] != 0) { 12345 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12346 : DUMP_MEM_OOM_LABEL[j]; 12347 MemItem item = new MemItem(label, label, oomPss[j], 12348 DUMP_MEM_OOM_ADJ[j]); 12349 item.subitems = oomProcs[j]; 12350 oomMems.add(item); 12351 } 12352 } 12353 12354 if (!brief && !oomOnly && !isCompact) { 12355 pw.println(); 12356 pw.println("Total PSS by process:"); 12357 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12358 pw.println(); 12359 } 12360 if (!isCompact) { 12361 pw.println("Total PSS by OOM adjustment:"); 12362 } 12363 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12364 if (!brief && !oomOnly) { 12365 PrintWriter out = categoryPw != null ? categoryPw : pw; 12366 if (!isCompact) { 12367 out.println(); 12368 out.println("Total PSS by category:"); 12369 } 12370 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12371 } 12372 if (!isCompact) { 12373 pw.println(); 12374 } 12375 MemInfoReader memInfo = new MemInfoReader(); 12376 memInfo.readMemInfo(); 12377 if (!brief) { 12378 if (!isCompact) { 12379 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12380 pw.print(" kB (status "); 12381 switch (mLastMemoryLevel) { 12382 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12383 pw.println("normal)"); 12384 break; 12385 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12386 pw.println("moderate)"); 12387 break; 12388 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12389 pw.println("low)"); 12390 break; 12391 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12392 pw.println("critical)"); 12393 break; 12394 default: 12395 pw.print(mLastMemoryLevel); 12396 pw.println(")"); 12397 break; 12398 } 12399 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12400 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12401 pw.print(cachedPss); pw.print(" cached pss + "); 12402 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12403 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12404 } else { 12405 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12406 pw.print(cachedPss + memInfo.getCachedSizeKb() 12407 + memInfo.getFreeSizeKb()); pw.print(","); 12408 pw.println(totalPss - cachedPss); 12409 } 12410 } 12411 if (!isCompact) { 12412 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12413 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12414 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12415 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12416 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12417 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12418 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12419 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12420 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12421 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12422 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12423 } 12424 if (!brief) { 12425 if (memInfo.getZramTotalSizeKb() != 0) { 12426 if (!isCompact) { 12427 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12428 pw.print(" kB physical used for "); 12429 pw.print(memInfo.getSwapTotalSizeKb() 12430 - memInfo.getSwapFreeSizeKb()); 12431 pw.print(" kB in swap ("); 12432 pw.print(memInfo.getSwapTotalSizeKb()); 12433 pw.println(" kB total swap)"); 12434 } else { 12435 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12436 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12437 pw.println(memInfo.getSwapFreeSizeKb()); 12438 } 12439 } 12440 final int[] SINGLE_LONG_FORMAT = new int[] { 12441 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12442 }; 12443 long[] longOut = new long[1]; 12444 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12445 SINGLE_LONG_FORMAT, null, longOut, null); 12446 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12447 longOut[0] = 0; 12448 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12449 SINGLE_LONG_FORMAT, null, longOut, null); 12450 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12451 longOut[0] = 0; 12452 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12453 SINGLE_LONG_FORMAT, null, longOut, null); 12454 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12455 longOut[0] = 0; 12456 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12457 SINGLE_LONG_FORMAT, null, longOut, null); 12458 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12459 if (!isCompact) { 12460 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12461 pw.print(" KSM: "); pw.print(sharing); 12462 pw.print(" kB saved from shared "); 12463 pw.print(shared); pw.println(" kB"); 12464 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12465 pw.print(voltile); pw.println(" kB volatile"); 12466 } 12467 pw.print(" Tuning: "); 12468 pw.print(ActivityManager.staticGetMemoryClass()); 12469 pw.print(" (large "); 12470 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12471 pw.print("), oom "); 12472 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12473 pw.print(" kB"); 12474 pw.print(", restore limit "); 12475 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12476 pw.print(" kB"); 12477 if (ActivityManager.isLowRamDeviceStatic()) { 12478 pw.print(" (low-ram)"); 12479 } 12480 if (ActivityManager.isHighEndGfx()) { 12481 pw.print(" (high-end-gfx)"); 12482 } 12483 pw.println(); 12484 } else { 12485 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12486 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12487 pw.println(voltile); 12488 pw.print("tuning,"); 12489 pw.print(ActivityManager.staticGetMemoryClass()); 12490 pw.print(','); 12491 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12492 pw.print(','); 12493 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12494 if (ActivityManager.isLowRamDeviceStatic()) { 12495 pw.print(",low-ram"); 12496 } 12497 if (ActivityManager.isHighEndGfx()) { 12498 pw.print(",high-end-gfx"); 12499 } 12500 pw.println(); 12501 } 12502 } 12503 } 12504 } 12505 12506 /** 12507 * Searches array of arguments for the specified string 12508 * @param args array of argument strings 12509 * @param value value to search for 12510 * @return true if the value is contained in the array 12511 */ 12512 private static boolean scanArgs(String[] args, String value) { 12513 if (args != null) { 12514 for (String arg : args) { 12515 if (value.equals(arg)) { 12516 return true; 12517 } 12518 } 12519 } 12520 return false; 12521 } 12522 12523 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12524 ContentProviderRecord cpr, boolean always) { 12525 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12526 12527 if (!inLaunching || always) { 12528 synchronized (cpr) { 12529 cpr.launchingApp = null; 12530 cpr.notifyAll(); 12531 } 12532 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12533 String names[] = cpr.info.authority.split(";"); 12534 for (int j = 0; j < names.length; j++) { 12535 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12536 } 12537 } 12538 12539 for (int i=0; i<cpr.connections.size(); i++) { 12540 ContentProviderConnection conn = cpr.connections.get(i); 12541 if (conn.waiting) { 12542 // If this connection is waiting for the provider, then we don't 12543 // need to mess with its process unless we are always removing 12544 // or for some reason the provider is not currently launching. 12545 if (inLaunching && !always) { 12546 continue; 12547 } 12548 } 12549 ProcessRecord capp = conn.client; 12550 conn.dead = true; 12551 if (conn.stableCount > 0) { 12552 if (!capp.persistent && capp.thread != null 12553 && capp.pid != 0 12554 && capp.pid != MY_PID) { 12555 killUnneededProcessLocked(capp, "depends on provider " 12556 + cpr.name.flattenToShortString() 12557 + " in dying proc " + (proc != null ? proc.processName : "??")); 12558 } 12559 } else if (capp.thread != null && conn.provider.provider != null) { 12560 try { 12561 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12562 } catch (RemoteException e) { 12563 } 12564 // In the protocol here, we don't expect the client to correctly 12565 // clean up this connection, we'll just remove it. 12566 cpr.connections.remove(i); 12567 conn.client.conProviders.remove(conn); 12568 } 12569 } 12570 12571 if (inLaunching && always) { 12572 mLaunchingProviders.remove(cpr); 12573 } 12574 return inLaunching; 12575 } 12576 12577 /** 12578 * Main code for cleaning up a process when it has gone away. This is 12579 * called both as a result of the process dying, or directly when stopping 12580 * a process when running in single process mode. 12581 */ 12582 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12583 boolean restarting, boolean allowRestart, int index) { 12584 if (index >= 0) { 12585 removeLruProcessLocked(app); 12586 ProcessList.remove(app.pid); 12587 } 12588 12589 mProcessesToGc.remove(app); 12590 mPendingPssProcesses.remove(app); 12591 12592 // Dismiss any open dialogs. 12593 if (app.crashDialog != null && !app.forceCrashReport) { 12594 app.crashDialog.dismiss(); 12595 app.crashDialog = null; 12596 } 12597 if (app.anrDialog != null) { 12598 app.anrDialog.dismiss(); 12599 app.anrDialog = null; 12600 } 12601 if (app.waitDialog != null) { 12602 app.waitDialog.dismiss(); 12603 app.waitDialog = null; 12604 } 12605 12606 app.crashing = false; 12607 app.notResponding = false; 12608 12609 app.resetPackageList(mProcessStats); 12610 app.unlinkDeathRecipient(); 12611 app.makeInactive(mProcessStats); 12612 app.forcingToForeground = null; 12613 updateProcessForegroundLocked(app, false, false); 12614 app.foregroundActivities = false; 12615 app.hasShownUi = false; 12616 app.treatLikeActivity = false; 12617 app.hasAboveClient = false; 12618 app.hasClientActivities = false; 12619 12620 mServices.killServicesLocked(app, allowRestart); 12621 12622 boolean restart = false; 12623 12624 // Remove published content providers. 12625 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12626 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12627 final boolean always = app.bad || !allowRestart; 12628 if (removeDyingProviderLocked(app, cpr, always) || always) { 12629 // We left the provider in the launching list, need to 12630 // restart it. 12631 restart = true; 12632 } 12633 12634 cpr.provider = null; 12635 cpr.proc = null; 12636 } 12637 app.pubProviders.clear(); 12638 12639 // Take care of any launching providers waiting for this process. 12640 if (checkAppInLaunchingProvidersLocked(app, false)) { 12641 restart = true; 12642 } 12643 12644 // Unregister from connected content providers. 12645 if (!app.conProviders.isEmpty()) { 12646 for (int i=0; i<app.conProviders.size(); i++) { 12647 ContentProviderConnection conn = app.conProviders.get(i); 12648 conn.provider.connections.remove(conn); 12649 } 12650 app.conProviders.clear(); 12651 } 12652 12653 // At this point there may be remaining entries in mLaunchingProviders 12654 // where we were the only one waiting, so they are no longer of use. 12655 // Look for these and clean up if found. 12656 // XXX Commented out for now. Trying to figure out a way to reproduce 12657 // the actual situation to identify what is actually going on. 12658 if (false) { 12659 for (int i=0; i<mLaunchingProviders.size(); i++) { 12660 ContentProviderRecord cpr = (ContentProviderRecord) 12661 mLaunchingProviders.get(i); 12662 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12663 synchronized (cpr) { 12664 cpr.launchingApp = null; 12665 cpr.notifyAll(); 12666 } 12667 } 12668 } 12669 } 12670 12671 skipCurrentReceiverLocked(app); 12672 12673 // Unregister any receivers. 12674 for (int i=app.receivers.size()-1; i>=0; i--) { 12675 removeReceiverLocked(app.receivers.valueAt(i)); 12676 } 12677 app.receivers.clear(); 12678 12679 // If the app is undergoing backup, tell the backup manager about it 12680 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12681 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12682 + mBackupTarget.appInfo + " died during backup"); 12683 try { 12684 IBackupManager bm = IBackupManager.Stub.asInterface( 12685 ServiceManager.getService(Context.BACKUP_SERVICE)); 12686 bm.agentDisconnected(app.info.packageName); 12687 } catch (RemoteException e) { 12688 // can't happen; backup manager is local 12689 } 12690 } 12691 12692 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12693 ProcessChangeItem item = mPendingProcessChanges.get(i); 12694 if (item.pid == app.pid) { 12695 mPendingProcessChanges.remove(i); 12696 mAvailProcessChanges.add(item); 12697 } 12698 } 12699 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12700 12701 // If the caller is restarting this app, then leave it in its 12702 // current lists and let the caller take care of it. 12703 if (restarting) { 12704 return; 12705 } 12706 12707 if (!app.persistent || app.isolated) { 12708 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12709 "Removing non-persistent process during cleanup: " + app); 12710 mProcessNames.remove(app.processName, app.uid); 12711 mIsolatedProcesses.remove(app.uid); 12712 if (mHeavyWeightProcess == app) { 12713 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12714 mHeavyWeightProcess.userId, 0)); 12715 mHeavyWeightProcess = null; 12716 } 12717 } else if (!app.removed) { 12718 // This app is persistent, so we need to keep its record around. 12719 // If it is not already on the pending app list, add it there 12720 // and start a new process for it. 12721 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12722 mPersistentStartingProcesses.add(app); 12723 restart = true; 12724 } 12725 } 12726 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12727 "Clean-up removing on hold: " + app); 12728 mProcessesOnHold.remove(app); 12729 12730 if (app == mHomeProcess) { 12731 mHomeProcess = null; 12732 } 12733 if (app == mPreviousProcess) { 12734 mPreviousProcess = null; 12735 } 12736 12737 if (restart && !app.isolated) { 12738 // We have components that still need to be running in the 12739 // process, so re-launch it. 12740 mProcessNames.put(app.processName, app.uid, app); 12741 startProcessLocked(app, "restart", app.processName); 12742 } else if (app.pid > 0 && app.pid != MY_PID) { 12743 // Goodbye! 12744 boolean removed; 12745 synchronized (mPidsSelfLocked) { 12746 mPidsSelfLocked.remove(app.pid); 12747 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12748 } 12749 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12750 app.processName, app.info.uid); 12751 if (app.isolated) { 12752 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12753 } 12754 app.setPid(0); 12755 } 12756 } 12757 12758 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12759 // Look through the content providers we are waiting to have launched, 12760 // and if any run in this process then either schedule a restart of 12761 // the process or kill the client waiting for it if this process has 12762 // gone bad. 12763 int NL = mLaunchingProviders.size(); 12764 boolean restart = false; 12765 for (int i=0; i<NL; i++) { 12766 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12767 if (cpr.launchingApp == app) { 12768 if (!alwaysBad && !app.bad) { 12769 restart = true; 12770 } else { 12771 removeDyingProviderLocked(app, cpr, true); 12772 // cpr should have been removed from mLaunchingProviders 12773 NL = mLaunchingProviders.size(); 12774 i--; 12775 } 12776 } 12777 } 12778 return restart; 12779 } 12780 12781 // ========================================================= 12782 // SERVICES 12783 // ========================================================= 12784 12785 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12786 int flags) { 12787 enforceNotIsolatedCaller("getServices"); 12788 synchronized (this) { 12789 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12790 } 12791 } 12792 12793 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12794 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12795 synchronized (this) { 12796 return mServices.getRunningServiceControlPanelLocked(name); 12797 } 12798 } 12799 12800 public ComponentName startService(IApplicationThread caller, Intent service, 12801 String resolvedType, int userId) { 12802 enforceNotIsolatedCaller("startService"); 12803 // Refuse possible leaked file descriptors 12804 if (service != null && service.hasFileDescriptors() == true) { 12805 throw new IllegalArgumentException("File descriptors passed in Intent"); 12806 } 12807 12808 if (DEBUG_SERVICE) 12809 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12810 synchronized(this) { 12811 final int callingPid = Binder.getCallingPid(); 12812 final int callingUid = Binder.getCallingUid(); 12813 final long origId = Binder.clearCallingIdentity(); 12814 ComponentName res = mServices.startServiceLocked(caller, service, 12815 resolvedType, callingPid, callingUid, userId); 12816 Binder.restoreCallingIdentity(origId); 12817 return res; 12818 } 12819 } 12820 12821 ComponentName startServiceInPackage(int uid, 12822 Intent service, String resolvedType, int userId) { 12823 synchronized(this) { 12824 if (DEBUG_SERVICE) 12825 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12826 final long origId = Binder.clearCallingIdentity(); 12827 ComponentName res = mServices.startServiceLocked(null, service, 12828 resolvedType, -1, uid, userId); 12829 Binder.restoreCallingIdentity(origId); 12830 return res; 12831 } 12832 } 12833 12834 public int stopService(IApplicationThread caller, Intent service, 12835 String resolvedType, int userId) { 12836 enforceNotIsolatedCaller("stopService"); 12837 // Refuse possible leaked file descriptors 12838 if (service != null && service.hasFileDescriptors() == true) { 12839 throw new IllegalArgumentException("File descriptors passed in Intent"); 12840 } 12841 12842 synchronized(this) { 12843 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12844 } 12845 } 12846 12847 public IBinder peekService(Intent service, String resolvedType) { 12848 enforceNotIsolatedCaller("peekService"); 12849 // Refuse possible leaked file descriptors 12850 if (service != null && service.hasFileDescriptors() == true) { 12851 throw new IllegalArgumentException("File descriptors passed in Intent"); 12852 } 12853 synchronized(this) { 12854 return mServices.peekServiceLocked(service, resolvedType); 12855 } 12856 } 12857 12858 public boolean stopServiceToken(ComponentName className, IBinder token, 12859 int startId) { 12860 synchronized(this) { 12861 return mServices.stopServiceTokenLocked(className, token, startId); 12862 } 12863 } 12864 12865 public void setServiceForeground(ComponentName className, IBinder token, 12866 int id, Notification notification, boolean removeNotification) { 12867 synchronized(this) { 12868 mServices.setServiceForegroundLocked(className, token, id, notification, 12869 removeNotification); 12870 } 12871 } 12872 12873 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12874 boolean requireFull, String name, String callerPackage) { 12875 final int callingUserId = UserHandle.getUserId(callingUid); 12876 if (callingUserId != userId) { 12877 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12878 if ((requireFull || checkComponentPermission( 12879 android.Manifest.permission.INTERACT_ACROSS_USERS, 12880 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12881 && checkComponentPermission( 12882 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12883 callingPid, callingUid, -1, true) 12884 != PackageManager.PERMISSION_GRANTED) { 12885 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12886 // In this case, they would like to just execute as their 12887 // owner user instead of failing. 12888 userId = callingUserId; 12889 } else { 12890 StringBuilder builder = new StringBuilder(128); 12891 builder.append("Permission Denial: "); 12892 builder.append(name); 12893 if (callerPackage != null) { 12894 builder.append(" from "); 12895 builder.append(callerPackage); 12896 } 12897 builder.append(" asks to run as user "); 12898 builder.append(userId); 12899 builder.append(" but is calling from user "); 12900 builder.append(UserHandle.getUserId(callingUid)); 12901 builder.append("; this requires "); 12902 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12903 if (!requireFull) { 12904 builder.append(" or "); 12905 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12906 } 12907 String msg = builder.toString(); 12908 Slog.w(TAG, msg); 12909 throw new SecurityException(msg); 12910 } 12911 } 12912 } 12913 if (userId == UserHandle.USER_CURRENT 12914 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12915 // Note that we may be accessing this outside of a lock... 12916 // shouldn't be a big deal, if this is being called outside 12917 // of a locked context there is intrinsically a race with 12918 // the value the caller will receive and someone else changing it. 12919 userId = mCurrentUserId; 12920 } 12921 if (!allowAll && userId < 0) { 12922 throw new IllegalArgumentException( 12923 "Call does not support special user #" + userId); 12924 } 12925 } 12926 return userId; 12927 } 12928 12929 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12930 String className, int flags) { 12931 boolean result = false; 12932 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12933 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12934 if (ActivityManager.checkUidPermission( 12935 android.Manifest.permission.INTERACT_ACROSS_USERS, 12936 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12937 ComponentName comp = new ComponentName(aInfo.packageName, className); 12938 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12939 + " requests FLAG_SINGLE_USER, but app does not hold " 12940 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12941 Slog.w(TAG, msg); 12942 throw new SecurityException(msg); 12943 } 12944 result = true; 12945 } 12946 } else if (componentProcessName == aInfo.packageName) { 12947 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12948 } else if ("system".equals(componentProcessName)) { 12949 result = true; 12950 } 12951 if (DEBUG_MU) { 12952 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12953 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12954 } 12955 return result; 12956 } 12957 12958 public int bindService(IApplicationThread caller, IBinder token, 12959 Intent service, String resolvedType, 12960 IServiceConnection connection, int flags, int userId) { 12961 enforceNotIsolatedCaller("bindService"); 12962 // Refuse possible leaked file descriptors 12963 if (service != null && service.hasFileDescriptors() == true) { 12964 throw new IllegalArgumentException("File descriptors passed in Intent"); 12965 } 12966 12967 synchronized(this) { 12968 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12969 connection, flags, userId); 12970 } 12971 } 12972 12973 public boolean unbindService(IServiceConnection connection) { 12974 synchronized (this) { 12975 return mServices.unbindServiceLocked(connection); 12976 } 12977 } 12978 12979 public void publishService(IBinder token, Intent intent, IBinder service) { 12980 // Refuse possible leaked file descriptors 12981 if (intent != null && intent.hasFileDescriptors() == true) { 12982 throw new IllegalArgumentException("File descriptors passed in Intent"); 12983 } 12984 12985 synchronized(this) { 12986 if (!(token instanceof ServiceRecord)) { 12987 throw new IllegalArgumentException("Invalid service token"); 12988 } 12989 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12990 } 12991 } 12992 12993 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12994 // Refuse possible leaked file descriptors 12995 if (intent != null && intent.hasFileDescriptors() == true) { 12996 throw new IllegalArgumentException("File descriptors passed in Intent"); 12997 } 12998 12999 synchronized(this) { 13000 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13001 } 13002 } 13003 13004 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13005 synchronized(this) { 13006 if (!(token instanceof ServiceRecord)) { 13007 throw new IllegalArgumentException("Invalid service token"); 13008 } 13009 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13010 } 13011 } 13012 13013 // ========================================================= 13014 // BACKUP AND RESTORE 13015 // ========================================================= 13016 13017 // Cause the target app to be launched if necessary and its backup agent 13018 // instantiated. The backup agent will invoke backupAgentCreated() on the 13019 // activity manager to announce its creation. 13020 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13021 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13022 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13023 13024 synchronized(this) { 13025 // !!! TODO: currently no check here that we're already bound 13026 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13027 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13028 synchronized (stats) { 13029 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13030 } 13031 13032 // Backup agent is now in use, its package can't be stopped. 13033 try { 13034 AppGlobals.getPackageManager().setPackageStoppedState( 13035 app.packageName, false, UserHandle.getUserId(app.uid)); 13036 } catch (RemoteException e) { 13037 } catch (IllegalArgumentException e) { 13038 Slog.w(TAG, "Failed trying to unstop package " 13039 + app.packageName + ": " + e); 13040 } 13041 13042 BackupRecord r = new BackupRecord(ss, app, backupMode); 13043 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13044 ? new ComponentName(app.packageName, app.backupAgentName) 13045 : new ComponentName("android", "FullBackupAgent"); 13046 // startProcessLocked() returns existing proc's record if it's already running 13047 ProcessRecord proc = startProcessLocked(app.processName, app, 13048 false, 0, "backup", hostingName, false, false, false); 13049 if (proc == null) { 13050 Slog.e(TAG, "Unable to start backup agent process " + r); 13051 return false; 13052 } 13053 13054 r.app = proc; 13055 mBackupTarget = r; 13056 mBackupAppName = app.packageName; 13057 13058 // Try not to kill the process during backup 13059 updateOomAdjLocked(proc); 13060 13061 // If the process is already attached, schedule the creation of the backup agent now. 13062 // If it is not yet live, this will be done when it attaches to the framework. 13063 if (proc.thread != null) { 13064 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13065 try { 13066 proc.thread.scheduleCreateBackupAgent(app, 13067 compatibilityInfoForPackageLocked(app), backupMode); 13068 } catch (RemoteException e) { 13069 // Will time out on the backup manager side 13070 } 13071 } else { 13072 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13073 } 13074 // Invariants: at this point, the target app process exists and the application 13075 // is either already running or in the process of coming up. mBackupTarget and 13076 // mBackupAppName describe the app, so that when it binds back to the AM we 13077 // know that it's scheduled for a backup-agent operation. 13078 } 13079 13080 return true; 13081 } 13082 13083 @Override 13084 public void clearPendingBackup() { 13085 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13086 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13087 13088 synchronized (this) { 13089 mBackupTarget = null; 13090 mBackupAppName = null; 13091 } 13092 } 13093 13094 // A backup agent has just come up 13095 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13096 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13097 + " = " + agent); 13098 13099 synchronized(this) { 13100 if (!agentPackageName.equals(mBackupAppName)) { 13101 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13102 return; 13103 } 13104 } 13105 13106 long oldIdent = Binder.clearCallingIdentity(); 13107 try { 13108 IBackupManager bm = IBackupManager.Stub.asInterface( 13109 ServiceManager.getService(Context.BACKUP_SERVICE)); 13110 bm.agentConnected(agentPackageName, agent); 13111 } catch (RemoteException e) { 13112 // can't happen; the backup manager service is local 13113 } catch (Exception e) { 13114 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13115 e.printStackTrace(); 13116 } finally { 13117 Binder.restoreCallingIdentity(oldIdent); 13118 } 13119 } 13120 13121 // done with this agent 13122 public void unbindBackupAgent(ApplicationInfo appInfo) { 13123 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13124 if (appInfo == null) { 13125 Slog.w(TAG, "unbind backup agent for null app"); 13126 return; 13127 } 13128 13129 synchronized(this) { 13130 try { 13131 if (mBackupAppName == null) { 13132 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13133 return; 13134 } 13135 13136 if (!mBackupAppName.equals(appInfo.packageName)) { 13137 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13138 return; 13139 } 13140 13141 // Not backing this app up any more; reset its OOM adjustment 13142 final ProcessRecord proc = mBackupTarget.app; 13143 updateOomAdjLocked(proc); 13144 13145 // If the app crashed during backup, 'thread' will be null here 13146 if (proc.thread != null) { 13147 try { 13148 proc.thread.scheduleDestroyBackupAgent(appInfo, 13149 compatibilityInfoForPackageLocked(appInfo)); 13150 } catch (Exception e) { 13151 Slog.e(TAG, "Exception when unbinding backup agent:"); 13152 e.printStackTrace(); 13153 } 13154 } 13155 } finally { 13156 mBackupTarget = null; 13157 mBackupAppName = null; 13158 } 13159 } 13160 } 13161 // ========================================================= 13162 // BROADCASTS 13163 // ========================================================= 13164 13165 private final List getStickiesLocked(String action, IntentFilter filter, 13166 List cur, int userId) { 13167 final ContentResolver resolver = mContext.getContentResolver(); 13168 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13169 if (stickies == null) { 13170 return cur; 13171 } 13172 final ArrayList<Intent> list = stickies.get(action); 13173 if (list == null) { 13174 return cur; 13175 } 13176 int N = list.size(); 13177 for (int i=0; i<N; i++) { 13178 Intent intent = list.get(i); 13179 if (filter.match(resolver, intent, true, TAG) >= 0) { 13180 if (cur == null) { 13181 cur = new ArrayList<Intent>(); 13182 } 13183 cur.add(intent); 13184 } 13185 } 13186 return cur; 13187 } 13188 13189 boolean isPendingBroadcastProcessLocked(int pid) { 13190 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13191 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13192 } 13193 13194 void skipPendingBroadcastLocked(int pid) { 13195 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13196 for (BroadcastQueue queue : mBroadcastQueues) { 13197 queue.skipPendingBroadcastLocked(pid); 13198 } 13199 } 13200 13201 // The app just attached; send any pending broadcasts that it should receive 13202 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13203 boolean didSomething = false; 13204 for (BroadcastQueue queue : mBroadcastQueues) { 13205 didSomething |= queue.sendPendingBroadcastsLocked(app); 13206 } 13207 return didSomething; 13208 } 13209 13210 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13211 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13212 enforceNotIsolatedCaller("registerReceiver"); 13213 int callingUid; 13214 int callingPid; 13215 synchronized(this) { 13216 ProcessRecord callerApp = null; 13217 if (caller != null) { 13218 callerApp = getRecordForAppLocked(caller); 13219 if (callerApp == null) { 13220 throw new SecurityException( 13221 "Unable to find app for caller " + caller 13222 + " (pid=" + Binder.getCallingPid() 13223 + ") when registering receiver " + receiver); 13224 } 13225 if (callerApp.info.uid != Process.SYSTEM_UID && 13226 !callerApp.pkgList.containsKey(callerPackage) && 13227 !"android".equals(callerPackage)) { 13228 throw new SecurityException("Given caller package " + callerPackage 13229 + " is not running in process " + callerApp); 13230 } 13231 callingUid = callerApp.info.uid; 13232 callingPid = callerApp.pid; 13233 } else { 13234 callerPackage = null; 13235 callingUid = Binder.getCallingUid(); 13236 callingPid = Binder.getCallingPid(); 13237 } 13238 13239 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13240 true, true, "registerReceiver", callerPackage); 13241 13242 List allSticky = null; 13243 13244 // Look for any matching sticky broadcasts... 13245 Iterator actions = filter.actionsIterator(); 13246 if (actions != null) { 13247 while (actions.hasNext()) { 13248 String action = (String)actions.next(); 13249 allSticky = getStickiesLocked(action, filter, allSticky, 13250 UserHandle.USER_ALL); 13251 allSticky = getStickiesLocked(action, filter, allSticky, 13252 UserHandle.getUserId(callingUid)); 13253 } 13254 } else { 13255 allSticky = getStickiesLocked(null, filter, allSticky, 13256 UserHandle.USER_ALL); 13257 allSticky = getStickiesLocked(null, filter, allSticky, 13258 UserHandle.getUserId(callingUid)); 13259 } 13260 13261 // The first sticky in the list is returned directly back to 13262 // the client. 13263 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13264 13265 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13266 + ": " + sticky); 13267 13268 if (receiver == null) { 13269 return sticky; 13270 } 13271 13272 ReceiverList rl 13273 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13274 if (rl == null) { 13275 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13276 userId, receiver); 13277 if (rl.app != null) { 13278 rl.app.receivers.add(rl); 13279 } else { 13280 try { 13281 receiver.asBinder().linkToDeath(rl, 0); 13282 } catch (RemoteException e) { 13283 return sticky; 13284 } 13285 rl.linkedToDeath = true; 13286 } 13287 mRegisteredReceivers.put(receiver.asBinder(), rl); 13288 } else if (rl.uid != callingUid) { 13289 throw new IllegalArgumentException( 13290 "Receiver requested to register for uid " + callingUid 13291 + " was previously registered for uid " + rl.uid); 13292 } else if (rl.pid != callingPid) { 13293 throw new IllegalArgumentException( 13294 "Receiver requested to register for pid " + callingPid 13295 + " was previously registered for pid " + rl.pid); 13296 } else if (rl.userId != userId) { 13297 throw new IllegalArgumentException( 13298 "Receiver requested to register for user " + userId 13299 + " was previously registered for user " + rl.userId); 13300 } 13301 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13302 permission, callingUid, userId); 13303 rl.add(bf); 13304 if (!bf.debugCheck()) { 13305 Slog.w(TAG, "==> For Dynamic broadast"); 13306 } 13307 mReceiverResolver.addFilter(bf); 13308 13309 // Enqueue broadcasts for all existing stickies that match 13310 // this filter. 13311 if (allSticky != null) { 13312 ArrayList receivers = new ArrayList(); 13313 receivers.add(bf); 13314 13315 int N = allSticky.size(); 13316 for (int i=0; i<N; i++) { 13317 Intent intent = (Intent)allSticky.get(i); 13318 BroadcastQueue queue = broadcastQueueForIntent(intent); 13319 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13320 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13321 null, null, false, true, true, -1); 13322 queue.enqueueParallelBroadcastLocked(r); 13323 queue.scheduleBroadcastsLocked(); 13324 } 13325 } 13326 13327 return sticky; 13328 } 13329 } 13330 13331 public void unregisterReceiver(IIntentReceiver receiver) { 13332 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13333 13334 final long origId = Binder.clearCallingIdentity(); 13335 try { 13336 boolean doTrim = false; 13337 13338 synchronized(this) { 13339 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13340 if (rl != null) { 13341 if (rl.curBroadcast != null) { 13342 BroadcastRecord r = rl.curBroadcast; 13343 final boolean doNext = finishReceiverLocked( 13344 receiver.asBinder(), r.resultCode, r.resultData, 13345 r.resultExtras, r.resultAbort); 13346 if (doNext) { 13347 doTrim = true; 13348 r.queue.processNextBroadcast(false); 13349 } 13350 } 13351 13352 if (rl.app != null) { 13353 rl.app.receivers.remove(rl); 13354 } 13355 removeReceiverLocked(rl); 13356 if (rl.linkedToDeath) { 13357 rl.linkedToDeath = false; 13358 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13359 } 13360 } 13361 } 13362 13363 // If we actually concluded any broadcasts, we might now be able 13364 // to trim the recipients' apps from our working set 13365 if (doTrim) { 13366 trimApplications(); 13367 return; 13368 } 13369 13370 } finally { 13371 Binder.restoreCallingIdentity(origId); 13372 } 13373 } 13374 13375 void removeReceiverLocked(ReceiverList rl) { 13376 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13377 int N = rl.size(); 13378 for (int i=0; i<N; i++) { 13379 mReceiverResolver.removeFilter(rl.get(i)); 13380 } 13381 } 13382 13383 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13384 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13385 ProcessRecord r = mLruProcesses.get(i); 13386 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13387 try { 13388 r.thread.dispatchPackageBroadcast(cmd, packages); 13389 } catch (RemoteException ex) { 13390 } 13391 } 13392 } 13393 } 13394 13395 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13396 int[] users) { 13397 List<ResolveInfo> receivers = null; 13398 try { 13399 HashSet<ComponentName> singleUserReceivers = null; 13400 boolean scannedFirstReceivers = false; 13401 for (int user : users) { 13402 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13403 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13404 if (user != 0 && newReceivers != null) { 13405 // If this is not the primary user, we need to check for 13406 // any receivers that should be filtered out. 13407 for (int i=0; i<newReceivers.size(); i++) { 13408 ResolveInfo ri = newReceivers.get(i); 13409 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13410 newReceivers.remove(i); 13411 i--; 13412 } 13413 } 13414 } 13415 if (newReceivers != null && newReceivers.size() == 0) { 13416 newReceivers = null; 13417 } 13418 if (receivers == null) { 13419 receivers = newReceivers; 13420 } else if (newReceivers != null) { 13421 // We need to concatenate the additional receivers 13422 // found with what we have do far. This would be easy, 13423 // but we also need to de-dup any receivers that are 13424 // singleUser. 13425 if (!scannedFirstReceivers) { 13426 // Collect any single user receivers we had already retrieved. 13427 scannedFirstReceivers = true; 13428 for (int i=0; i<receivers.size(); i++) { 13429 ResolveInfo ri = receivers.get(i); 13430 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13431 ComponentName cn = new ComponentName( 13432 ri.activityInfo.packageName, ri.activityInfo.name); 13433 if (singleUserReceivers == null) { 13434 singleUserReceivers = new HashSet<ComponentName>(); 13435 } 13436 singleUserReceivers.add(cn); 13437 } 13438 } 13439 } 13440 // Add the new results to the existing results, tracking 13441 // and de-dupping single user receivers. 13442 for (int i=0; i<newReceivers.size(); i++) { 13443 ResolveInfo ri = newReceivers.get(i); 13444 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13445 ComponentName cn = new ComponentName( 13446 ri.activityInfo.packageName, ri.activityInfo.name); 13447 if (singleUserReceivers == null) { 13448 singleUserReceivers = new HashSet<ComponentName>(); 13449 } 13450 if (!singleUserReceivers.contains(cn)) { 13451 singleUserReceivers.add(cn); 13452 receivers.add(ri); 13453 } 13454 } else { 13455 receivers.add(ri); 13456 } 13457 } 13458 } 13459 } 13460 } catch (RemoteException ex) { 13461 // pm is in same process, this will never happen. 13462 } 13463 return receivers; 13464 } 13465 13466 private final int broadcastIntentLocked(ProcessRecord callerApp, 13467 String callerPackage, Intent intent, String resolvedType, 13468 IIntentReceiver resultTo, int resultCode, String resultData, 13469 Bundle map, String requiredPermission, int appOp, 13470 boolean ordered, boolean sticky, int callingPid, int callingUid, 13471 int userId) { 13472 intent = new Intent(intent); 13473 13474 // By default broadcasts do not go to stopped apps. 13475 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13476 13477 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13478 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13479 + " ordered=" + ordered + " userid=" + userId); 13480 if ((resultTo != null) && !ordered) { 13481 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13482 } 13483 13484 userId = handleIncomingUser(callingPid, callingUid, userId, 13485 true, false, "broadcast", callerPackage); 13486 13487 // Make sure that the user who is receiving this broadcast is started. 13488 // If not, we will just skip it. 13489 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13490 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13491 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13492 Slog.w(TAG, "Skipping broadcast of " + intent 13493 + ": user " + userId + " is stopped"); 13494 return ActivityManager.BROADCAST_SUCCESS; 13495 } 13496 } 13497 13498 /* 13499 * Prevent non-system code (defined here to be non-persistent 13500 * processes) from sending protected broadcasts. 13501 */ 13502 int callingAppId = UserHandle.getAppId(callingUid); 13503 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13504 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13505 callingUid == 0) { 13506 // Always okay. 13507 } else if (callerApp == null || !callerApp.persistent) { 13508 try { 13509 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13510 intent.getAction())) { 13511 String msg = "Permission Denial: not allowed to send broadcast " 13512 + intent.getAction() + " from pid=" 13513 + callingPid + ", uid=" + callingUid; 13514 Slog.w(TAG, msg); 13515 throw new SecurityException(msg); 13516 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13517 // Special case for compatibility: we don't want apps to send this, 13518 // but historically it has not been protected and apps may be using it 13519 // to poke their own app widget. So, instead of making it protected, 13520 // just limit it to the caller. 13521 if (callerApp == null) { 13522 String msg = "Permission Denial: not allowed to send broadcast " 13523 + intent.getAction() + " from unknown caller."; 13524 Slog.w(TAG, msg); 13525 throw new SecurityException(msg); 13526 } else if (intent.getComponent() != null) { 13527 // They are good enough to send to an explicit component... verify 13528 // it is being sent to the calling app. 13529 if (!intent.getComponent().getPackageName().equals( 13530 callerApp.info.packageName)) { 13531 String msg = "Permission Denial: not allowed to send broadcast " 13532 + intent.getAction() + " to " 13533 + intent.getComponent().getPackageName() + " from " 13534 + callerApp.info.packageName; 13535 Slog.w(TAG, msg); 13536 throw new SecurityException(msg); 13537 } 13538 } else { 13539 // Limit broadcast to their own package. 13540 intent.setPackage(callerApp.info.packageName); 13541 } 13542 } 13543 } catch (RemoteException e) { 13544 Slog.w(TAG, "Remote exception", e); 13545 return ActivityManager.BROADCAST_SUCCESS; 13546 } 13547 } 13548 13549 // Handle special intents: if this broadcast is from the package 13550 // manager about a package being removed, we need to remove all of 13551 // its activities from the history stack. 13552 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13553 intent.getAction()); 13554 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13555 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13556 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13557 || uidRemoved) { 13558 if (checkComponentPermission( 13559 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13560 callingPid, callingUid, -1, true) 13561 == PackageManager.PERMISSION_GRANTED) { 13562 if (uidRemoved) { 13563 final Bundle intentExtras = intent.getExtras(); 13564 final int uid = intentExtras != null 13565 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13566 if (uid >= 0) { 13567 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13568 synchronized (bs) { 13569 bs.removeUidStatsLocked(uid); 13570 } 13571 mAppOpsService.uidRemoved(uid); 13572 } 13573 } else { 13574 // If resources are unavailable just force stop all 13575 // those packages and flush the attribute cache as well. 13576 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13577 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13578 if (list != null && (list.length > 0)) { 13579 for (String pkg : list) { 13580 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13581 "storage unmount"); 13582 } 13583 sendPackageBroadcastLocked( 13584 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13585 } 13586 } else { 13587 Uri data = intent.getData(); 13588 String ssp; 13589 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13590 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13591 intent.getAction()); 13592 boolean fullUninstall = removed && 13593 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13594 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13595 forceStopPackageLocked(ssp, UserHandle.getAppId( 13596 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13597 false, fullUninstall, userId, 13598 removed ? "pkg removed" : "pkg changed"); 13599 } 13600 if (removed) { 13601 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13602 new String[] {ssp}, userId); 13603 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13604 mAppOpsService.packageRemoved( 13605 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13606 13607 // Remove all permissions granted from/to this package 13608 removeUriPermissionsForPackageLocked(ssp, userId, true); 13609 } 13610 } 13611 } 13612 } 13613 } 13614 } else { 13615 String msg = "Permission Denial: " + intent.getAction() 13616 + " broadcast from " + callerPackage + " (pid=" + callingPid 13617 + ", uid=" + callingUid + ")" 13618 + " requires " 13619 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13620 Slog.w(TAG, msg); 13621 throw new SecurityException(msg); 13622 } 13623 13624 // Special case for adding a package: by default turn on compatibility 13625 // mode. 13626 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13627 Uri data = intent.getData(); 13628 String ssp; 13629 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13630 mCompatModePackages.handlePackageAddedLocked(ssp, 13631 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13632 } 13633 } 13634 13635 /* 13636 * If this is the time zone changed action, queue up a message that will reset the timezone 13637 * of all currently running processes. This message will get queued up before the broadcast 13638 * happens. 13639 */ 13640 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13641 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13642 } 13643 13644 /* 13645 * If the user set the time, let all running processes know. 13646 */ 13647 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13648 final int is24Hour = intent.getBooleanExtra( 13649 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13650 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13651 } 13652 13653 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13654 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13655 } 13656 13657 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13658 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13659 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13660 } 13661 13662 // Add to the sticky list if requested. 13663 if (sticky) { 13664 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13665 callingPid, callingUid) 13666 != PackageManager.PERMISSION_GRANTED) { 13667 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13668 + callingPid + ", uid=" + callingUid 13669 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13670 Slog.w(TAG, msg); 13671 throw new SecurityException(msg); 13672 } 13673 if (requiredPermission != null) { 13674 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13675 + " and enforce permission " + requiredPermission); 13676 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13677 } 13678 if (intent.getComponent() != null) { 13679 throw new SecurityException( 13680 "Sticky broadcasts can't target a specific component"); 13681 } 13682 // We use userId directly here, since the "all" target is maintained 13683 // as a separate set of sticky broadcasts. 13684 if (userId != UserHandle.USER_ALL) { 13685 // But first, if this is not a broadcast to all users, then 13686 // make sure it doesn't conflict with an existing broadcast to 13687 // all users. 13688 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13689 UserHandle.USER_ALL); 13690 if (stickies != null) { 13691 ArrayList<Intent> list = stickies.get(intent.getAction()); 13692 if (list != null) { 13693 int N = list.size(); 13694 int i; 13695 for (i=0; i<N; i++) { 13696 if (intent.filterEquals(list.get(i))) { 13697 throw new IllegalArgumentException( 13698 "Sticky broadcast " + intent + " for user " 13699 + userId + " conflicts with existing global broadcast"); 13700 } 13701 } 13702 } 13703 } 13704 } 13705 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13706 if (stickies == null) { 13707 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13708 mStickyBroadcasts.put(userId, stickies); 13709 } 13710 ArrayList<Intent> list = stickies.get(intent.getAction()); 13711 if (list == null) { 13712 list = new ArrayList<Intent>(); 13713 stickies.put(intent.getAction(), list); 13714 } 13715 int N = list.size(); 13716 int i; 13717 for (i=0; i<N; i++) { 13718 if (intent.filterEquals(list.get(i))) { 13719 // This sticky already exists, replace it. 13720 list.set(i, new Intent(intent)); 13721 break; 13722 } 13723 } 13724 if (i >= N) { 13725 list.add(new Intent(intent)); 13726 } 13727 } 13728 13729 int[] users; 13730 if (userId == UserHandle.USER_ALL) { 13731 // Caller wants broadcast to go to all started users. 13732 users = mStartedUserArray; 13733 } else { 13734 // Caller wants broadcast to go to one specific user. 13735 users = new int[] {userId}; 13736 } 13737 13738 // Figure out who all will receive this broadcast. 13739 List receivers = null; 13740 List<BroadcastFilter> registeredReceivers = null; 13741 // Need to resolve the intent to interested receivers... 13742 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13743 == 0) { 13744 receivers = collectReceiverComponents(intent, resolvedType, users); 13745 } 13746 if (intent.getComponent() == null) { 13747 registeredReceivers = mReceiverResolver.queryIntent(intent, 13748 resolvedType, false, userId); 13749 } 13750 13751 final boolean replacePending = 13752 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13753 13754 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13755 + " replacePending=" + replacePending); 13756 13757 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13758 if (!ordered && NR > 0) { 13759 // If we are not serializing this broadcast, then send the 13760 // registered receivers separately so they don't wait for the 13761 // components to be launched. 13762 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13763 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13764 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13765 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13766 ordered, sticky, false, userId); 13767 if (DEBUG_BROADCAST) Slog.v( 13768 TAG, "Enqueueing parallel broadcast " + r); 13769 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13770 if (!replaced) { 13771 queue.enqueueParallelBroadcastLocked(r); 13772 queue.scheduleBroadcastsLocked(); 13773 } 13774 registeredReceivers = null; 13775 NR = 0; 13776 } 13777 13778 // Merge into one list. 13779 int ir = 0; 13780 if (receivers != null) { 13781 // A special case for PACKAGE_ADDED: do not allow the package 13782 // being added to see this broadcast. This prevents them from 13783 // using this as a back door to get run as soon as they are 13784 // installed. Maybe in the future we want to have a special install 13785 // broadcast or such for apps, but we'd like to deliberately make 13786 // this decision. 13787 String skipPackages[] = null; 13788 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13789 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13790 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13791 Uri data = intent.getData(); 13792 if (data != null) { 13793 String pkgName = data.getSchemeSpecificPart(); 13794 if (pkgName != null) { 13795 skipPackages = new String[] { pkgName }; 13796 } 13797 } 13798 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13799 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13800 } 13801 if (skipPackages != null && (skipPackages.length > 0)) { 13802 for (String skipPackage : skipPackages) { 13803 if (skipPackage != null) { 13804 int NT = receivers.size(); 13805 for (int it=0; it<NT; it++) { 13806 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13807 if (curt.activityInfo.packageName.equals(skipPackage)) { 13808 receivers.remove(it); 13809 it--; 13810 NT--; 13811 } 13812 } 13813 } 13814 } 13815 } 13816 13817 int NT = receivers != null ? receivers.size() : 0; 13818 int it = 0; 13819 ResolveInfo curt = null; 13820 BroadcastFilter curr = null; 13821 while (it < NT && ir < NR) { 13822 if (curt == null) { 13823 curt = (ResolveInfo)receivers.get(it); 13824 } 13825 if (curr == null) { 13826 curr = registeredReceivers.get(ir); 13827 } 13828 if (curr.getPriority() >= curt.priority) { 13829 // Insert this broadcast record into the final list. 13830 receivers.add(it, curr); 13831 ir++; 13832 curr = null; 13833 it++; 13834 NT++; 13835 } else { 13836 // Skip to the next ResolveInfo in the final list. 13837 it++; 13838 curt = null; 13839 } 13840 } 13841 } 13842 while (ir < NR) { 13843 if (receivers == null) { 13844 receivers = new ArrayList(); 13845 } 13846 receivers.add(registeredReceivers.get(ir)); 13847 ir++; 13848 } 13849 13850 if ((receivers != null && receivers.size() > 0) 13851 || resultTo != null) { 13852 BroadcastQueue queue = broadcastQueueForIntent(intent); 13853 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13854 callerPackage, callingPid, callingUid, resolvedType, 13855 requiredPermission, appOp, receivers, resultTo, resultCode, 13856 resultData, map, ordered, sticky, false, userId); 13857 if (DEBUG_BROADCAST) Slog.v( 13858 TAG, "Enqueueing ordered broadcast " + r 13859 + ": prev had " + queue.mOrderedBroadcasts.size()); 13860 if (DEBUG_BROADCAST) { 13861 int seq = r.intent.getIntExtra("seq", -1); 13862 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13863 } 13864 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13865 if (!replaced) { 13866 queue.enqueueOrderedBroadcastLocked(r); 13867 queue.scheduleBroadcastsLocked(); 13868 } 13869 } 13870 13871 return ActivityManager.BROADCAST_SUCCESS; 13872 } 13873 13874 final Intent verifyBroadcastLocked(Intent intent) { 13875 // Refuse possible leaked file descriptors 13876 if (intent != null && intent.hasFileDescriptors() == true) { 13877 throw new IllegalArgumentException("File descriptors passed in Intent"); 13878 } 13879 13880 int flags = intent.getFlags(); 13881 13882 if (!mProcessesReady) { 13883 // if the caller really truly claims to know what they're doing, go 13884 // ahead and allow the broadcast without launching any receivers 13885 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13886 intent = new Intent(intent); 13887 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13888 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13889 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13890 + " before boot completion"); 13891 throw new IllegalStateException("Cannot broadcast before boot completed"); 13892 } 13893 } 13894 13895 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13896 throw new IllegalArgumentException( 13897 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13898 } 13899 13900 return intent; 13901 } 13902 13903 public final int broadcastIntent(IApplicationThread caller, 13904 Intent intent, String resolvedType, IIntentReceiver resultTo, 13905 int resultCode, String resultData, Bundle map, 13906 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13907 enforceNotIsolatedCaller("broadcastIntent"); 13908 synchronized(this) { 13909 intent = verifyBroadcastLocked(intent); 13910 13911 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13912 final int callingPid = Binder.getCallingPid(); 13913 final int callingUid = Binder.getCallingUid(); 13914 final long origId = Binder.clearCallingIdentity(); 13915 int res = broadcastIntentLocked(callerApp, 13916 callerApp != null ? callerApp.info.packageName : null, 13917 intent, resolvedType, resultTo, 13918 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13919 callingPid, callingUid, userId); 13920 Binder.restoreCallingIdentity(origId); 13921 return res; 13922 } 13923 } 13924 13925 int broadcastIntentInPackage(String packageName, int uid, 13926 Intent intent, String resolvedType, IIntentReceiver resultTo, 13927 int resultCode, String resultData, Bundle map, 13928 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13929 synchronized(this) { 13930 intent = verifyBroadcastLocked(intent); 13931 13932 final long origId = Binder.clearCallingIdentity(); 13933 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13934 resultTo, resultCode, resultData, map, requiredPermission, 13935 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13936 Binder.restoreCallingIdentity(origId); 13937 return res; 13938 } 13939 } 13940 13941 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13942 // Refuse possible leaked file descriptors 13943 if (intent != null && intent.hasFileDescriptors() == true) { 13944 throw new IllegalArgumentException("File descriptors passed in Intent"); 13945 } 13946 13947 userId = handleIncomingUser(Binder.getCallingPid(), 13948 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13949 13950 synchronized(this) { 13951 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13952 != PackageManager.PERMISSION_GRANTED) { 13953 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13954 + Binder.getCallingPid() 13955 + ", uid=" + Binder.getCallingUid() 13956 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13957 Slog.w(TAG, msg); 13958 throw new SecurityException(msg); 13959 } 13960 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13961 if (stickies != null) { 13962 ArrayList<Intent> list = stickies.get(intent.getAction()); 13963 if (list != null) { 13964 int N = list.size(); 13965 int i; 13966 for (i=0; i<N; i++) { 13967 if (intent.filterEquals(list.get(i))) { 13968 list.remove(i); 13969 break; 13970 } 13971 } 13972 if (list.size() <= 0) { 13973 stickies.remove(intent.getAction()); 13974 } 13975 } 13976 if (stickies.size() <= 0) { 13977 mStickyBroadcasts.remove(userId); 13978 } 13979 } 13980 } 13981 } 13982 13983 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13984 String resultData, Bundle resultExtras, boolean resultAbort) { 13985 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13986 if (r == null) { 13987 Slog.w(TAG, "finishReceiver called but not found on queue"); 13988 return false; 13989 } 13990 13991 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13992 } 13993 13994 void backgroundServicesFinishedLocked(int userId) { 13995 for (BroadcastQueue queue : mBroadcastQueues) { 13996 queue.backgroundServicesFinishedLocked(userId); 13997 } 13998 } 13999 14000 public void finishReceiver(IBinder who, int resultCode, String resultData, 14001 Bundle resultExtras, boolean resultAbort) { 14002 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14003 14004 // Refuse possible leaked file descriptors 14005 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14006 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14007 } 14008 14009 final long origId = Binder.clearCallingIdentity(); 14010 try { 14011 boolean doNext = false; 14012 BroadcastRecord r; 14013 14014 synchronized(this) { 14015 r = broadcastRecordForReceiverLocked(who); 14016 if (r != null) { 14017 doNext = r.queue.finishReceiverLocked(r, resultCode, 14018 resultData, resultExtras, resultAbort, true); 14019 } 14020 } 14021 14022 if (doNext) { 14023 r.queue.processNextBroadcast(false); 14024 } 14025 trimApplications(); 14026 } finally { 14027 Binder.restoreCallingIdentity(origId); 14028 } 14029 } 14030 14031 // ========================================================= 14032 // INSTRUMENTATION 14033 // ========================================================= 14034 14035 public boolean startInstrumentation(ComponentName className, 14036 String profileFile, int flags, Bundle arguments, 14037 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14038 int userId) { 14039 enforceNotIsolatedCaller("startInstrumentation"); 14040 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14041 userId, false, true, "startInstrumentation", null); 14042 // Refuse possible leaked file descriptors 14043 if (arguments != null && arguments.hasFileDescriptors()) { 14044 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14045 } 14046 14047 synchronized(this) { 14048 InstrumentationInfo ii = null; 14049 ApplicationInfo ai = null; 14050 try { 14051 ii = mContext.getPackageManager().getInstrumentationInfo( 14052 className, STOCK_PM_FLAGS); 14053 ai = AppGlobals.getPackageManager().getApplicationInfo( 14054 ii.targetPackage, STOCK_PM_FLAGS, userId); 14055 } catch (PackageManager.NameNotFoundException e) { 14056 } catch (RemoteException e) { 14057 } 14058 if (ii == null) { 14059 reportStartInstrumentationFailure(watcher, className, 14060 "Unable to find instrumentation info for: " + className); 14061 return false; 14062 } 14063 if (ai == null) { 14064 reportStartInstrumentationFailure(watcher, className, 14065 "Unable to find instrumentation target package: " + ii.targetPackage); 14066 return false; 14067 } 14068 14069 int match = mContext.getPackageManager().checkSignatures( 14070 ii.targetPackage, ii.packageName); 14071 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14072 String msg = "Permission Denial: starting instrumentation " 14073 + className + " from pid=" 14074 + Binder.getCallingPid() 14075 + ", uid=" + Binder.getCallingPid() 14076 + " not allowed because package " + ii.packageName 14077 + " does not have a signature matching the target " 14078 + ii.targetPackage; 14079 reportStartInstrumentationFailure(watcher, className, msg); 14080 throw new SecurityException(msg); 14081 } 14082 14083 final long origId = Binder.clearCallingIdentity(); 14084 // Instrumentation can kill and relaunch even persistent processes 14085 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14086 "start instr"); 14087 ProcessRecord app = addAppLocked(ai, false); 14088 app.instrumentationClass = className; 14089 app.instrumentationInfo = ai; 14090 app.instrumentationProfileFile = profileFile; 14091 app.instrumentationArguments = arguments; 14092 app.instrumentationWatcher = watcher; 14093 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14094 app.instrumentationResultClass = className; 14095 Binder.restoreCallingIdentity(origId); 14096 } 14097 14098 return true; 14099 } 14100 14101 /** 14102 * Report errors that occur while attempting to start Instrumentation. Always writes the 14103 * error to the logs, but if somebody is watching, send the report there too. This enables 14104 * the "am" command to report errors with more information. 14105 * 14106 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14107 * @param cn The component name of the instrumentation. 14108 * @param report The error report. 14109 */ 14110 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14111 ComponentName cn, String report) { 14112 Slog.w(TAG, report); 14113 try { 14114 if (watcher != null) { 14115 Bundle results = new Bundle(); 14116 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14117 results.putString("Error", report); 14118 watcher.instrumentationStatus(cn, -1, results); 14119 } 14120 } catch (RemoteException e) { 14121 Slog.w(TAG, e); 14122 } 14123 } 14124 14125 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14126 if (app.instrumentationWatcher != null) { 14127 try { 14128 // NOTE: IInstrumentationWatcher *must* be oneway here 14129 app.instrumentationWatcher.instrumentationFinished( 14130 app.instrumentationClass, 14131 resultCode, 14132 results); 14133 } catch (RemoteException e) { 14134 } 14135 } 14136 if (app.instrumentationUiAutomationConnection != null) { 14137 try { 14138 app.instrumentationUiAutomationConnection.shutdown(); 14139 } catch (RemoteException re) { 14140 /* ignore */ 14141 } 14142 // Only a UiAutomation can set this flag and now that 14143 // it is finished we make sure it is reset to its default. 14144 mUserIsMonkey = false; 14145 } 14146 app.instrumentationWatcher = null; 14147 app.instrumentationUiAutomationConnection = null; 14148 app.instrumentationClass = null; 14149 app.instrumentationInfo = null; 14150 app.instrumentationProfileFile = null; 14151 app.instrumentationArguments = null; 14152 14153 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14154 "finished inst"); 14155 } 14156 14157 public void finishInstrumentation(IApplicationThread target, 14158 int resultCode, Bundle results) { 14159 int userId = UserHandle.getCallingUserId(); 14160 // Refuse possible leaked file descriptors 14161 if (results != null && results.hasFileDescriptors()) { 14162 throw new IllegalArgumentException("File descriptors passed in Intent"); 14163 } 14164 14165 synchronized(this) { 14166 ProcessRecord app = getRecordForAppLocked(target); 14167 if (app == null) { 14168 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14169 return; 14170 } 14171 final long origId = Binder.clearCallingIdentity(); 14172 finishInstrumentationLocked(app, resultCode, results); 14173 Binder.restoreCallingIdentity(origId); 14174 } 14175 } 14176 14177 // ========================================================= 14178 // CONFIGURATION 14179 // ========================================================= 14180 14181 public ConfigurationInfo getDeviceConfigurationInfo() { 14182 ConfigurationInfo config = new ConfigurationInfo(); 14183 synchronized (this) { 14184 config.reqTouchScreen = mConfiguration.touchscreen; 14185 config.reqKeyboardType = mConfiguration.keyboard; 14186 config.reqNavigation = mConfiguration.navigation; 14187 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14188 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14189 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14190 } 14191 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14192 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14193 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14194 } 14195 config.reqGlEsVersion = GL_ES_VERSION; 14196 } 14197 return config; 14198 } 14199 14200 ActivityStack getFocusedStack() { 14201 return mStackSupervisor.getFocusedStack(); 14202 } 14203 14204 public Configuration getConfiguration() { 14205 Configuration ci; 14206 synchronized(this) { 14207 ci = new Configuration(mConfiguration); 14208 } 14209 return ci; 14210 } 14211 14212 public void updatePersistentConfiguration(Configuration values) { 14213 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14214 "updateConfiguration()"); 14215 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14216 "updateConfiguration()"); 14217 if (values == null) { 14218 throw new NullPointerException("Configuration must not be null"); 14219 } 14220 14221 synchronized(this) { 14222 final long origId = Binder.clearCallingIdentity(); 14223 updateConfigurationLocked(values, null, true, false); 14224 Binder.restoreCallingIdentity(origId); 14225 } 14226 } 14227 14228 public void updateConfiguration(Configuration values) { 14229 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14230 "updateConfiguration()"); 14231 14232 synchronized(this) { 14233 if (values == null && mWindowManager != null) { 14234 // sentinel: fetch the current configuration from the window manager 14235 values = mWindowManager.computeNewConfiguration(); 14236 } 14237 14238 if (mWindowManager != null) { 14239 mProcessList.applyDisplaySize(mWindowManager); 14240 } 14241 14242 final long origId = Binder.clearCallingIdentity(); 14243 if (values != null) { 14244 Settings.System.clearConfiguration(values); 14245 } 14246 updateConfigurationLocked(values, null, false, false); 14247 Binder.restoreCallingIdentity(origId); 14248 } 14249 } 14250 14251 /** 14252 * Do either or both things: (1) change the current configuration, and (2) 14253 * make sure the given activity is running with the (now) current 14254 * configuration. Returns true if the activity has been left running, or 14255 * false if <var>starting</var> is being destroyed to match the new 14256 * configuration. 14257 * @param persistent TODO 14258 */ 14259 boolean updateConfigurationLocked(Configuration values, 14260 ActivityRecord starting, boolean persistent, boolean initLocale) { 14261 int changes = 0; 14262 14263 if (values != null) { 14264 Configuration newConfig = new Configuration(mConfiguration); 14265 changes = newConfig.updateFrom(values); 14266 if (changes != 0) { 14267 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14268 Slog.i(TAG, "Updating configuration to: " + values); 14269 } 14270 14271 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14272 14273 if (values.locale != null && !initLocale) { 14274 saveLocaleLocked(values.locale, 14275 !values.locale.equals(mConfiguration.locale), 14276 values.userSetLocale); 14277 } 14278 14279 mConfigurationSeq++; 14280 if (mConfigurationSeq <= 0) { 14281 mConfigurationSeq = 1; 14282 } 14283 newConfig.seq = mConfigurationSeq; 14284 mConfiguration = newConfig; 14285 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14286 14287 final Configuration configCopy = new Configuration(mConfiguration); 14288 14289 // TODO: If our config changes, should we auto dismiss any currently 14290 // showing dialogs? 14291 mShowDialogs = shouldShowDialogs(newConfig); 14292 14293 AttributeCache ac = AttributeCache.instance(); 14294 if (ac != null) { 14295 ac.updateConfiguration(configCopy); 14296 } 14297 14298 // Make sure all resources in our process are updated 14299 // right now, so that anyone who is going to retrieve 14300 // resource values after we return will be sure to get 14301 // the new ones. This is especially important during 14302 // boot, where the first config change needs to guarantee 14303 // all resources have that config before following boot 14304 // code is executed. 14305 mSystemThread.applyConfigurationToResources(configCopy); 14306 14307 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14308 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14309 msg.obj = new Configuration(configCopy); 14310 mHandler.sendMessage(msg); 14311 } 14312 14313 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14314 ProcessRecord app = mLruProcesses.get(i); 14315 try { 14316 if (app.thread != null) { 14317 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14318 + app.processName + " new config " + mConfiguration); 14319 app.thread.scheduleConfigurationChanged(configCopy); 14320 } 14321 } catch (Exception e) { 14322 } 14323 } 14324 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14325 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14326 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14327 | Intent.FLAG_RECEIVER_FOREGROUND); 14328 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14329 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14330 Process.SYSTEM_UID, UserHandle.USER_ALL); 14331 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14332 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14333 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14334 broadcastIntentLocked(null, null, intent, 14335 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14336 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14337 } 14338 } 14339 } 14340 14341 boolean kept = true; 14342 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14343 // mainStack is null during startup. 14344 if (mainStack != null) { 14345 if (changes != 0 && starting == null) { 14346 // If the configuration changed, and the caller is not already 14347 // in the process of starting an activity, then find the top 14348 // activity to check if its configuration needs to change. 14349 starting = mainStack.topRunningActivityLocked(null); 14350 } 14351 14352 if (starting != null) { 14353 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14354 // And we need to make sure at this point that all other activities 14355 // are made visible with the correct configuration. 14356 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14357 } 14358 } 14359 14360 if (values != null && mWindowManager != null) { 14361 mWindowManager.setNewConfiguration(mConfiguration); 14362 } 14363 14364 return kept; 14365 } 14366 14367 /** 14368 * Decide based on the configuration whether we should shouw the ANR, 14369 * crash, etc dialogs. The idea is that if there is no affordnace to 14370 * press the on-screen buttons, we shouldn't show the dialog. 14371 * 14372 * A thought: SystemUI might also want to get told about this, the Power 14373 * dialog / global actions also might want different behaviors. 14374 */ 14375 private static final boolean shouldShowDialogs(Configuration config) { 14376 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14377 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14378 } 14379 14380 /** 14381 * Save the locale. You must be inside a synchronized (this) block. 14382 */ 14383 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14384 if(isDiff) { 14385 SystemProperties.set("user.language", l.getLanguage()); 14386 SystemProperties.set("user.region", l.getCountry()); 14387 } 14388 14389 if(isPersist) { 14390 SystemProperties.set("persist.sys.language", l.getLanguage()); 14391 SystemProperties.set("persist.sys.country", l.getCountry()); 14392 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14393 } 14394 } 14395 14396 @Override 14397 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14398 ActivityRecord srec = ActivityRecord.forToken(token); 14399 return srec != null && srec.task.affinity != null && 14400 srec.task.affinity.equals(destAffinity); 14401 } 14402 14403 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14404 Intent resultData) { 14405 14406 synchronized (this) { 14407 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14408 if (stack != null) { 14409 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14410 } 14411 return false; 14412 } 14413 } 14414 14415 public int getLaunchedFromUid(IBinder activityToken) { 14416 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14417 if (srec == null) { 14418 return -1; 14419 } 14420 return srec.launchedFromUid; 14421 } 14422 14423 public String getLaunchedFromPackage(IBinder activityToken) { 14424 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14425 if (srec == null) { 14426 return null; 14427 } 14428 return srec.launchedFromPackage; 14429 } 14430 14431 // ========================================================= 14432 // LIFETIME MANAGEMENT 14433 // ========================================================= 14434 14435 // Returns which broadcast queue the app is the current [or imminent] receiver 14436 // on, or 'null' if the app is not an active broadcast recipient. 14437 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14438 BroadcastRecord r = app.curReceiver; 14439 if (r != null) { 14440 return r.queue; 14441 } 14442 14443 // It's not the current receiver, but it might be starting up to become one 14444 synchronized (this) { 14445 for (BroadcastQueue queue : mBroadcastQueues) { 14446 r = queue.mPendingBroadcast; 14447 if (r != null && r.curApp == app) { 14448 // found it; report which queue it's in 14449 return queue; 14450 } 14451 } 14452 } 14453 14454 return null; 14455 } 14456 14457 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14458 boolean doingAll, long now) { 14459 if (mAdjSeq == app.adjSeq) { 14460 // This adjustment has already been computed. 14461 return app.curRawAdj; 14462 } 14463 14464 if (app.thread == null) { 14465 app.adjSeq = mAdjSeq; 14466 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14467 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14468 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14469 } 14470 14471 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14472 app.adjSource = null; 14473 app.adjTarget = null; 14474 app.empty = false; 14475 app.cached = false; 14476 14477 final int activitiesSize = app.activities.size(); 14478 14479 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14480 // The max adjustment doesn't allow this app to be anything 14481 // below foreground, so it is not worth doing work for it. 14482 app.adjType = "fixed"; 14483 app.adjSeq = mAdjSeq; 14484 app.curRawAdj = app.maxAdj; 14485 app.foregroundActivities = false; 14486 app.keeping = true; 14487 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14488 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14489 // System process can do UI, and when they do we want to have 14490 // them trim their memory after the user leaves the UI. To 14491 // facilitate this, here we need to determine whether or not it 14492 // is currently showing UI. 14493 app.systemNoUi = true; 14494 if (app == TOP_APP) { 14495 app.systemNoUi = false; 14496 } else if (activitiesSize > 0) { 14497 for (int j = 0; j < activitiesSize; j++) { 14498 final ActivityRecord r = app.activities.get(j); 14499 if (r.visible) { 14500 app.systemNoUi = false; 14501 } 14502 } 14503 } 14504 if (!app.systemNoUi) { 14505 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14506 } 14507 return (app.curAdj=app.maxAdj); 14508 } 14509 14510 app.keeping = false; 14511 app.systemNoUi = false; 14512 14513 // Determine the importance of the process, starting with most 14514 // important to least, and assign an appropriate OOM adjustment. 14515 int adj; 14516 int schedGroup; 14517 int procState; 14518 boolean foregroundActivities = false; 14519 boolean interesting = false; 14520 BroadcastQueue queue; 14521 if (app == TOP_APP) { 14522 // The last app on the list is the foreground app. 14523 adj = ProcessList.FOREGROUND_APP_ADJ; 14524 schedGroup = Process.THREAD_GROUP_DEFAULT; 14525 app.adjType = "top-activity"; 14526 foregroundActivities = true; 14527 interesting = true; 14528 procState = ActivityManager.PROCESS_STATE_TOP; 14529 } else if (app.instrumentationClass != null) { 14530 // Don't want to kill running instrumentation. 14531 adj = ProcessList.FOREGROUND_APP_ADJ; 14532 schedGroup = Process.THREAD_GROUP_DEFAULT; 14533 app.adjType = "instrumentation"; 14534 interesting = true; 14535 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14536 } else if ((queue = isReceivingBroadcast(app)) != null) { 14537 // An app that is currently receiving a broadcast also 14538 // counts as being in the foreground for OOM killer purposes. 14539 // It's placed in a sched group based on the nature of the 14540 // broadcast as reflected by which queue it's active in. 14541 adj = ProcessList.FOREGROUND_APP_ADJ; 14542 schedGroup = (queue == mFgBroadcastQueue) 14543 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14544 app.adjType = "broadcast"; 14545 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14546 } else if (app.executingServices.size() > 0) { 14547 // An app that is currently executing a service callback also 14548 // counts as being in the foreground. 14549 adj = ProcessList.FOREGROUND_APP_ADJ; 14550 schedGroup = app.execServicesFg ? 14551 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14552 app.adjType = "exec-service"; 14553 procState = ActivityManager.PROCESS_STATE_SERVICE; 14554 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14555 } else { 14556 // As far as we know the process is empty. We may change our mind later. 14557 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14558 // At this point we don't actually know the adjustment. Use the cached adj 14559 // value that the caller wants us to. 14560 adj = cachedAdj; 14561 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14562 app.cached = true; 14563 app.empty = true; 14564 app.adjType = "cch-empty"; 14565 } 14566 14567 // Examine all activities if not already foreground. 14568 if (!foregroundActivities && activitiesSize > 0) { 14569 for (int j = 0; j < activitiesSize; j++) { 14570 final ActivityRecord r = app.activities.get(j); 14571 if (r.app != app) { 14572 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14573 + app + "?!?"); 14574 continue; 14575 } 14576 if (r.visible) { 14577 // App has a visible activity; only upgrade adjustment. 14578 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14579 adj = ProcessList.VISIBLE_APP_ADJ; 14580 app.adjType = "visible"; 14581 } 14582 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14583 procState = ActivityManager.PROCESS_STATE_TOP; 14584 } 14585 schedGroup = Process.THREAD_GROUP_DEFAULT; 14586 app.cached = false; 14587 app.empty = false; 14588 foregroundActivities = true; 14589 break; 14590 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14591 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14592 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14593 app.adjType = "pausing"; 14594 } 14595 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14596 procState = ActivityManager.PROCESS_STATE_TOP; 14597 } 14598 schedGroup = Process.THREAD_GROUP_DEFAULT; 14599 app.cached = false; 14600 app.empty = false; 14601 foregroundActivities = true; 14602 } else if (r.state == ActivityState.STOPPING) { 14603 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14604 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14605 app.adjType = "stopping"; 14606 } 14607 // For the process state, we will at this point consider the 14608 // process to be cached. It will be cached either as an activity 14609 // or empty depending on whether the activity is finishing. We do 14610 // this so that we can treat the process as cached for purposes of 14611 // memory trimming (determing current memory level, trim command to 14612 // send to process) since there can be an arbitrary number of stopping 14613 // processes and they should soon all go into the cached state. 14614 if (!r.finishing) { 14615 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14616 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14617 } 14618 } 14619 app.cached = false; 14620 app.empty = false; 14621 foregroundActivities = true; 14622 } else { 14623 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14624 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14625 app.adjType = "cch-act"; 14626 } 14627 } 14628 } 14629 } 14630 14631 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14632 if (app.foregroundServices) { 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 = "fg-service"; 14638 schedGroup = Process.THREAD_GROUP_DEFAULT; 14639 } else if (app.forcingToForeground != null) { 14640 // The user is aware of this app, so make it visible. 14641 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14642 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14643 app.cached = false; 14644 app.adjType = "force-fg"; 14645 app.adjSource = app.forcingToForeground; 14646 schedGroup = Process.THREAD_GROUP_DEFAULT; 14647 } 14648 } 14649 14650 if (app.foregroundServices) { 14651 interesting = true; 14652 } 14653 14654 if (app == mHeavyWeightProcess) { 14655 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14656 // We don't want to kill the current heavy-weight process. 14657 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14658 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14659 app.cached = false; 14660 app.adjType = "heavy"; 14661 } 14662 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14663 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14664 } 14665 } 14666 14667 if (app == mHomeProcess) { 14668 if (adj > ProcessList.HOME_APP_ADJ) { 14669 // This process is hosting what we currently consider to be the 14670 // home app, so we don't want to let it go into the background. 14671 adj = ProcessList.HOME_APP_ADJ; 14672 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14673 app.cached = false; 14674 app.adjType = "home"; 14675 } 14676 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14677 procState = ActivityManager.PROCESS_STATE_HOME; 14678 } 14679 } 14680 14681 if (app == mPreviousProcess && app.activities.size() > 0) { 14682 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14683 // This was the previous process that showed UI to the user. 14684 // We want to try to keep it around more aggressively, to give 14685 // a good experience around switching between two apps. 14686 adj = ProcessList.PREVIOUS_APP_ADJ; 14687 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14688 app.cached = false; 14689 app.adjType = "previous"; 14690 } 14691 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14692 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14693 } 14694 } 14695 14696 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14697 + " reason=" + app.adjType); 14698 14699 // By default, we use the computed adjustment. It may be changed if 14700 // there are applications dependent on our services or providers, but 14701 // this gives us a baseline and makes sure we don't get into an 14702 // infinite recursion. 14703 app.adjSeq = mAdjSeq; 14704 app.curRawAdj = adj; 14705 app.hasStartedServices = false; 14706 14707 if (mBackupTarget != null && app == mBackupTarget.app) { 14708 // If possible we want to avoid killing apps while they're being backed up 14709 if (adj > ProcessList.BACKUP_APP_ADJ) { 14710 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14711 adj = ProcessList.BACKUP_APP_ADJ; 14712 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14713 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14714 } 14715 app.adjType = "backup"; 14716 app.cached = false; 14717 } 14718 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14719 procState = ActivityManager.PROCESS_STATE_BACKUP; 14720 } 14721 } 14722 14723 boolean mayBeTop = false; 14724 14725 for (int is = app.services.size()-1; 14726 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14727 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14728 || procState > ActivityManager.PROCESS_STATE_TOP); 14729 is--) { 14730 ServiceRecord s = app.services.valueAt(is); 14731 if (s.startRequested) { 14732 app.hasStartedServices = true; 14733 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14734 procState = ActivityManager.PROCESS_STATE_SERVICE; 14735 } 14736 if (app.hasShownUi && app != mHomeProcess) { 14737 // If this process has shown some UI, let it immediately 14738 // go to the LRU list because it may be pretty heavy with 14739 // UI stuff. We'll tag it with a label just to help 14740 // debug and understand what is going on. 14741 if (adj > ProcessList.SERVICE_ADJ) { 14742 app.adjType = "cch-started-ui-services"; 14743 } 14744 } else { 14745 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14746 // This service has seen some activity within 14747 // recent memory, so we will keep its process ahead 14748 // of the background processes. 14749 if (adj > ProcessList.SERVICE_ADJ) { 14750 adj = ProcessList.SERVICE_ADJ; 14751 app.adjType = "started-services"; 14752 app.cached = false; 14753 } 14754 } 14755 // If we have let the service slide into the background 14756 // state, still have some text describing what it is doing 14757 // even though the service no longer has an impact. 14758 if (adj > ProcessList.SERVICE_ADJ) { 14759 app.adjType = "cch-started-services"; 14760 } 14761 } 14762 // Don't kill this process because it is doing work; it 14763 // has said it is doing work. 14764 app.keeping = true; 14765 } 14766 for (int conni = s.connections.size()-1; 14767 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14768 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14769 || procState > ActivityManager.PROCESS_STATE_TOP); 14770 conni--) { 14771 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14772 for (int i = 0; 14773 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14774 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14775 || procState > ActivityManager.PROCESS_STATE_TOP); 14776 i++) { 14777 // XXX should compute this based on the max of 14778 // all connected clients. 14779 ConnectionRecord cr = clist.get(i); 14780 if (cr.binding.client == app) { 14781 // Binding to ourself is not interesting. 14782 continue; 14783 } 14784 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14785 ProcessRecord client = cr.binding.client; 14786 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14787 TOP_APP, doingAll, now); 14788 int clientProcState = client.curProcState; 14789 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14790 // If the other app is cached for any reason, for purposes here 14791 // we are going to consider it empty. The specific cached state 14792 // doesn't propagate except under certain conditions. 14793 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14794 } 14795 String adjType = null; 14796 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14797 // Not doing bind OOM management, so treat 14798 // this guy more like a started service. 14799 if (app.hasShownUi && app != mHomeProcess) { 14800 // If this process has shown some UI, let it immediately 14801 // go to the LRU list because it may be pretty heavy with 14802 // UI stuff. We'll tag it with a label just to help 14803 // debug and understand what is going on. 14804 if (adj > clientAdj) { 14805 adjType = "cch-bound-ui-services"; 14806 } 14807 app.cached = false; 14808 clientAdj = adj; 14809 clientProcState = procState; 14810 } else { 14811 if (now >= (s.lastActivity 14812 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14813 // This service has not seen activity within 14814 // recent memory, so allow it to drop to the 14815 // LRU list if there is no other reason to keep 14816 // it around. We'll also tag it with a label just 14817 // to help debug and undertand what is going on. 14818 if (adj > clientAdj) { 14819 adjType = "cch-bound-services"; 14820 } 14821 clientAdj = adj; 14822 } 14823 } 14824 } 14825 if (adj > clientAdj) { 14826 // If this process has recently shown UI, and 14827 // the process that is binding to it is less 14828 // important than being visible, then we don't 14829 // care about the binding as much as we care 14830 // about letting this process get into the LRU 14831 // list to be killed and restarted if needed for 14832 // memory. 14833 if (app.hasShownUi && app != mHomeProcess 14834 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14835 adjType = "cch-bound-ui-services"; 14836 } else { 14837 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14838 |Context.BIND_IMPORTANT)) != 0) { 14839 adj = clientAdj; 14840 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14841 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14842 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14843 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14844 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14845 adj = clientAdj; 14846 } else { 14847 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14848 adj = ProcessList.VISIBLE_APP_ADJ; 14849 } 14850 } 14851 if (!client.cached) { 14852 app.cached = false; 14853 } 14854 if (client.keeping) { 14855 app.keeping = true; 14856 } 14857 adjType = "service"; 14858 } 14859 } 14860 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14861 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14862 schedGroup = Process.THREAD_GROUP_DEFAULT; 14863 } 14864 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14865 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14866 // Special handling of clients who are in the top state. 14867 // We *may* want to consider this process to be in the 14868 // top state as well, but only if there is not another 14869 // reason for it to be running. Being on the top is a 14870 // special state, meaning you are specifically running 14871 // for the current top app. If the process is already 14872 // running in the background for some other reason, it 14873 // is more important to continue considering it to be 14874 // in the background state. 14875 mayBeTop = true; 14876 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14877 } else { 14878 // Special handling for above-top states (persistent 14879 // processes). These should not bring the current process 14880 // into the top state, since they are not on top. Instead 14881 // give them the best state after that. 14882 clientProcState = 14883 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14884 } 14885 } 14886 } else { 14887 if (clientProcState < 14888 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14889 clientProcState = 14890 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14891 } 14892 } 14893 if (procState > clientProcState) { 14894 procState = clientProcState; 14895 } 14896 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14897 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14898 app.pendingUiClean = true; 14899 } 14900 if (adjType != null) { 14901 app.adjType = adjType; 14902 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14903 .REASON_SERVICE_IN_USE; 14904 app.adjSource = cr.binding.client; 14905 app.adjSourceOom = clientAdj; 14906 app.adjTarget = s.name; 14907 } 14908 } 14909 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 14910 app.treatLikeActivity = true; 14911 } 14912 final ActivityRecord a = cr.activity; 14913 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14914 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14915 (a.visible || a.state == ActivityState.RESUMED 14916 || a.state == ActivityState.PAUSING)) { 14917 adj = ProcessList.FOREGROUND_APP_ADJ; 14918 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14919 schedGroup = Process.THREAD_GROUP_DEFAULT; 14920 } 14921 app.cached = false; 14922 app.adjType = "service"; 14923 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14924 .REASON_SERVICE_IN_USE; 14925 app.adjSource = a; 14926 app.adjSourceOom = adj; 14927 app.adjTarget = s.name; 14928 } 14929 } 14930 } 14931 } 14932 } 14933 14934 for (int provi = app.pubProviders.size()-1; 14935 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14936 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14937 || procState > ActivityManager.PROCESS_STATE_TOP); 14938 provi--) { 14939 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14940 for (int i = cpr.connections.size()-1; 14941 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14942 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14943 || procState > ActivityManager.PROCESS_STATE_TOP); 14944 i--) { 14945 ContentProviderConnection conn = cpr.connections.get(i); 14946 ProcessRecord client = conn.client; 14947 if (client == app) { 14948 // Being our own client is not interesting. 14949 continue; 14950 } 14951 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14952 int clientProcState = client.curProcState; 14953 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14954 // If the other app is cached for any reason, for purposes here 14955 // we are going to consider it empty. 14956 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14957 } 14958 if (adj > clientAdj) { 14959 if (app.hasShownUi && app != mHomeProcess 14960 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14961 app.adjType = "cch-ui-provider"; 14962 } else { 14963 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14964 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14965 app.adjType = "provider"; 14966 } 14967 app.cached &= client.cached; 14968 app.keeping |= client.keeping; 14969 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14970 .REASON_PROVIDER_IN_USE; 14971 app.adjSource = client; 14972 app.adjSourceOom = clientAdj; 14973 app.adjTarget = cpr.name; 14974 } 14975 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14976 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14977 // Special handling of clients who are in the top state. 14978 // We *may* want to consider this process to be in the 14979 // top state as well, but only if there is not another 14980 // reason for it to be running. Being on the top is a 14981 // special state, meaning you are specifically running 14982 // for the current top app. If the process is already 14983 // running in the background for some other reason, it 14984 // is more important to continue considering it to be 14985 // in the background state. 14986 mayBeTop = true; 14987 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14988 } else { 14989 // Special handling for above-top states (persistent 14990 // processes). These should not bring the current process 14991 // into the top state, since they are not on top. Instead 14992 // give them the best state after that. 14993 clientProcState = 14994 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14995 } 14996 } 14997 if (procState > clientProcState) { 14998 procState = clientProcState; 14999 } 15000 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15001 schedGroup = Process.THREAD_GROUP_DEFAULT; 15002 } 15003 } 15004 // If the provider has external (non-framework) process 15005 // dependencies, ensure that its adjustment is at least 15006 // FOREGROUND_APP_ADJ. 15007 if (cpr.hasExternalProcessHandles()) { 15008 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15009 adj = ProcessList.FOREGROUND_APP_ADJ; 15010 schedGroup = Process.THREAD_GROUP_DEFAULT; 15011 app.cached = false; 15012 app.keeping = true; 15013 app.adjType = "provider"; 15014 app.adjTarget = cpr.name; 15015 } 15016 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15017 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15018 } 15019 } 15020 } 15021 15022 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15023 // A client of one of our services or providers is in the top state. We 15024 // *may* want to be in the top state, but not if we are already running in 15025 // the background for some other reason. For the decision here, we are going 15026 // to pick out a few specific states that we want to remain in when a client 15027 // is top (states that tend to be longer-term) and otherwise allow it to go 15028 // to the top state. 15029 switch (procState) { 15030 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15031 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15032 case ActivityManager.PROCESS_STATE_SERVICE: 15033 // These all are longer-term states, so pull them up to the top 15034 // of the background states, but not all the way to the top state. 15035 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15036 break; 15037 default: 15038 // Otherwise, top is a better choice, so take it. 15039 procState = ActivityManager.PROCESS_STATE_TOP; 15040 break; 15041 } 15042 } 15043 15044 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15045 if (app.hasClientActivities) { 15046 // This is a cached process, but with client activities. Mark it so. 15047 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15048 app.adjType = "cch-client-act"; 15049 } else if (app.treatLikeActivity) { 15050 // This is a cached process, but somebody wants us to treat it like it has 15051 // an activity, okay! 15052 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15053 app.adjType = "cch-as-act"; 15054 } 15055 } 15056 15057 if (adj == ProcessList.SERVICE_ADJ) { 15058 if (doingAll) { 15059 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15060 mNewNumServiceProcs++; 15061 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15062 if (!app.serviceb) { 15063 // This service isn't far enough down on the LRU list to 15064 // normally be a B service, but if we are low on RAM and it 15065 // is large we want to force it down since we would prefer to 15066 // keep launcher over it. 15067 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15068 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15069 app.serviceHighRam = true; 15070 app.serviceb = true; 15071 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15072 } else { 15073 mNewNumAServiceProcs++; 15074 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15075 } 15076 } else { 15077 app.serviceHighRam = false; 15078 } 15079 } 15080 if (app.serviceb) { 15081 adj = ProcessList.SERVICE_B_ADJ; 15082 } 15083 } 15084 15085 app.curRawAdj = adj; 15086 15087 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15088 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15089 if (adj > app.maxAdj) { 15090 adj = app.maxAdj; 15091 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15092 schedGroup = Process.THREAD_GROUP_DEFAULT; 15093 } 15094 } 15095 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15096 app.keeping = true; 15097 } 15098 15099 // Do final modification to adj. Everything we do between here and applying 15100 // the final setAdj must be done in this function, because we will also use 15101 // it when computing the final cached adj later. Note that we don't need to 15102 // worry about this for max adj above, since max adj will always be used to 15103 // keep it out of the cached vaues. 15104 adj = app.modifyRawOomAdj(adj); 15105 15106 app.curProcState = procState; 15107 15108 int importance = app.memImportance; 15109 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15110 app.curAdj = adj; 15111 app.curSchedGroup = schedGroup; 15112 if (!interesting) { 15113 // For this reporting, if there is not something explicitly 15114 // interesting in this process then we will push it to the 15115 // background importance. 15116 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15117 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15118 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15119 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15120 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15121 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15122 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15123 } else if (adj >= ProcessList.SERVICE_ADJ) { 15124 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15125 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15126 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15127 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15128 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15129 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15130 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15131 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15132 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15133 } else { 15134 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15135 } 15136 } 15137 15138 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15139 if (foregroundActivities != app.foregroundActivities) { 15140 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15141 } 15142 if (changes != 0) { 15143 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15144 app.memImportance = importance; 15145 app.foregroundActivities = foregroundActivities; 15146 int i = mPendingProcessChanges.size()-1; 15147 ProcessChangeItem item = null; 15148 while (i >= 0) { 15149 item = mPendingProcessChanges.get(i); 15150 if (item.pid == app.pid) { 15151 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15152 break; 15153 } 15154 i--; 15155 } 15156 if (i < 0) { 15157 // No existing item in pending changes; need a new one. 15158 final int NA = mAvailProcessChanges.size(); 15159 if (NA > 0) { 15160 item = mAvailProcessChanges.remove(NA-1); 15161 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15162 } else { 15163 item = new ProcessChangeItem(); 15164 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15165 } 15166 item.changes = 0; 15167 item.pid = app.pid; 15168 item.uid = app.info.uid; 15169 if (mPendingProcessChanges.size() == 0) { 15170 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15171 "*** Enqueueing dispatch processes changed!"); 15172 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15173 } 15174 mPendingProcessChanges.add(item); 15175 } 15176 item.changes |= changes; 15177 item.importance = importance; 15178 item.foregroundActivities = foregroundActivities; 15179 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15180 + Integer.toHexString(System.identityHashCode(item)) 15181 + " " + app.toShortString() + ": changes=" + item.changes 15182 + " importance=" + item.importance 15183 + " foreground=" + item.foregroundActivities 15184 + " type=" + app.adjType + " source=" + app.adjSource 15185 + " target=" + app.adjTarget); 15186 } 15187 15188 return app.curRawAdj; 15189 } 15190 15191 /** 15192 * Schedule PSS collection of a process. 15193 */ 15194 void requestPssLocked(ProcessRecord proc, int procState) { 15195 if (mPendingPssProcesses.contains(proc)) { 15196 return; 15197 } 15198 if (mPendingPssProcesses.size() == 0) { 15199 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15200 } 15201 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15202 proc.pssProcState = procState; 15203 mPendingPssProcesses.add(proc); 15204 } 15205 15206 /** 15207 * Schedule PSS collection of all processes. 15208 */ 15209 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15210 if (!always) { 15211 if (now < (mLastFullPssTime + 15212 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15213 return; 15214 } 15215 } 15216 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15217 mLastFullPssTime = now; 15218 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15219 mPendingPssProcesses.clear(); 15220 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15221 ProcessRecord app = mLruProcesses.get(i); 15222 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15223 app.pssProcState = app.setProcState; 15224 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15225 mSleeping, now); 15226 mPendingPssProcesses.add(app); 15227 } 15228 } 15229 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15230 } 15231 15232 /** 15233 * Ask a given process to GC right now. 15234 */ 15235 final void performAppGcLocked(ProcessRecord app) { 15236 try { 15237 app.lastRequestedGc = SystemClock.uptimeMillis(); 15238 if (app.thread != null) { 15239 if (app.reportLowMemory) { 15240 app.reportLowMemory = false; 15241 app.thread.scheduleLowMemory(); 15242 } else { 15243 app.thread.processInBackground(); 15244 } 15245 } 15246 } catch (Exception e) { 15247 // whatever. 15248 } 15249 } 15250 15251 /** 15252 * Returns true if things are idle enough to perform GCs. 15253 */ 15254 private final boolean canGcNowLocked() { 15255 boolean processingBroadcasts = false; 15256 for (BroadcastQueue q : mBroadcastQueues) { 15257 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15258 processingBroadcasts = true; 15259 } 15260 } 15261 return !processingBroadcasts 15262 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15263 } 15264 15265 /** 15266 * Perform GCs on all processes that are waiting for it, but only 15267 * if things are idle. 15268 */ 15269 final void performAppGcsLocked() { 15270 final int N = mProcessesToGc.size(); 15271 if (N <= 0) { 15272 return; 15273 } 15274 if (canGcNowLocked()) { 15275 while (mProcessesToGc.size() > 0) { 15276 ProcessRecord proc = mProcessesToGc.remove(0); 15277 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15278 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15279 <= SystemClock.uptimeMillis()) { 15280 // To avoid spamming the system, we will GC processes one 15281 // at a time, waiting a few seconds between each. 15282 performAppGcLocked(proc); 15283 scheduleAppGcsLocked(); 15284 return; 15285 } else { 15286 // It hasn't been long enough since we last GCed this 15287 // process... put it in the list to wait for its time. 15288 addProcessToGcListLocked(proc); 15289 break; 15290 } 15291 } 15292 } 15293 15294 scheduleAppGcsLocked(); 15295 } 15296 } 15297 15298 /** 15299 * If all looks good, perform GCs on all processes waiting for them. 15300 */ 15301 final void performAppGcsIfAppropriateLocked() { 15302 if (canGcNowLocked()) { 15303 performAppGcsLocked(); 15304 return; 15305 } 15306 // Still not idle, wait some more. 15307 scheduleAppGcsLocked(); 15308 } 15309 15310 /** 15311 * Schedule the execution of all pending app GCs. 15312 */ 15313 final void scheduleAppGcsLocked() { 15314 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15315 15316 if (mProcessesToGc.size() > 0) { 15317 // Schedule a GC for the time to the next process. 15318 ProcessRecord proc = mProcessesToGc.get(0); 15319 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15320 15321 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15322 long now = SystemClock.uptimeMillis(); 15323 if (when < (now+GC_TIMEOUT)) { 15324 when = now + GC_TIMEOUT; 15325 } 15326 mHandler.sendMessageAtTime(msg, when); 15327 } 15328 } 15329 15330 /** 15331 * Add a process to the array of processes waiting to be GCed. Keeps the 15332 * list in sorted order by the last GC time. The process can't already be 15333 * on the list. 15334 */ 15335 final void addProcessToGcListLocked(ProcessRecord proc) { 15336 boolean added = false; 15337 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15338 if (mProcessesToGc.get(i).lastRequestedGc < 15339 proc.lastRequestedGc) { 15340 added = true; 15341 mProcessesToGc.add(i+1, proc); 15342 break; 15343 } 15344 } 15345 if (!added) { 15346 mProcessesToGc.add(0, proc); 15347 } 15348 } 15349 15350 /** 15351 * Set up to ask a process to GC itself. This will either do it 15352 * immediately, or put it on the list of processes to gc the next 15353 * time things are idle. 15354 */ 15355 final void scheduleAppGcLocked(ProcessRecord app) { 15356 long now = SystemClock.uptimeMillis(); 15357 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15358 return; 15359 } 15360 if (!mProcessesToGc.contains(app)) { 15361 addProcessToGcListLocked(app); 15362 scheduleAppGcsLocked(); 15363 } 15364 } 15365 15366 final void checkExcessivePowerUsageLocked(boolean doKills) { 15367 updateCpuStatsNow(); 15368 15369 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15370 boolean doWakeKills = doKills; 15371 boolean doCpuKills = doKills; 15372 if (mLastPowerCheckRealtime == 0) { 15373 doWakeKills = false; 15374 } 15375 if (mLastPowerCheckUptime == 0) { 15376 doCpuKills = false; 15377 } 15378 if (stats.isScreenOn()) { 15379 doWakeKills = false; 15380 } 15381 final long curRealtime = SystemClock.elapsedRealtime(); 15382 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15383 final long curUptime = SystemClock.uptimeMillis(); 15384 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15385 mLastPowerCheckRealtime = curRealtime; 15386 mLastPowerCheckUptime = curUptime; 15387 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15388 doWakeKills = false; 15389 } 15390 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15391 doCpuKills = false; 15392 } 15393 int i = mLruProcesses.size(); 15394 while (i > 0) { 15395 i--; 15396 ProcessRecord app = mLruProcesses.get(i); 15397 if (!app.keeping) { 15398 long wtime; 15399 synchronized (stats) { 15400 wtime = stats.getProcessWakeTime(app.info.uid, 15401 app.pid, curRealtime); 15402 } 15403 long wtimeUsed = wtime - app.lastWakeTime; 15404 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15405 if (DEBUG_POWER) { 15406 StringBuilder sb = new StringBuilder(128); 15407 sb.append("Wake for "); 15408 app.toShortString(sb); 15409 sb.append(": over "); 15410 TimeUtils.formatDuration(realtimeSince, sb); 15411 sb.append(" used "); 15412 TimeUtils.formatDuration(wtimeUsed, sb); 15413 sb.append(" ("); 15414 sb.append((wtimeUsed*100)/realtimeSince); 15415 sb.append("%)"); 15416 Slog.i(TAG, sb.toString()); 15417 sb.setLength(0); 15418 sb.append("CPU for "); 15419 app.toShortString(sb); 15420 sb.append(": over "); 15421 TimeUtils.formatDuration(uptimeSince, sb); 15422 sb.append(" used "); 15423 TimeUtils.formatDuration(cputimeUsed, sb); 15424 sb.append(" ("); 15425 sb.append((cputimeUsed*100)/uptimeSince); 15426 sb.append("%)"); 15427 Slog.i(TAG, sb.toString()); 15428 } 15429 // If a process has held a wake lock for more 15430 // than 50% of the time during this period, 15431 // that sounds bad. Kill! 15432 if (doWakeKills && realtimeSince > 0 15433 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15434 synchronized (stats) { 15435 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15436 realtimeSince, wtimeUsed); 15437 } 15438 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15439 + " during " + realtimeSince); 15440 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15441 } else if (doCpuKills && uptimeSince > 0 15442 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15443 synchronized (stats) { 15444 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15445 uptimeSince, cputimeUsed); 15446 } 15447 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15448 + " during " + uptimeSince); 15449 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15450 } else { 15451 app.lastWakeTime = wtime; 15452 app.lastCpuTime = app.curCpuTime; 15453 } 15454 } 15455 } 15456 } 15457 15458 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15459 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15460 boolean success = true; 15461 15462 if (app.curRawAdj != app.setRawAdj) { 15463 if (wasKeeping && !app.keeping) { 15464 // This app is no longer something we want to keep. Note 15465 // its current wake lock time to later know to kill it if 15466 // it is not behaving well. 15467 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15468 synchronized (stats) { 15469 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15470 app.pid, SystemClock.elapsedRealtime()); 15471 } 15472 app.lastCpuTime = app.curCpuTime; 15473 } 15474 15475 app.setRawAdj = app.curRawAdj; 15476 } 15477 15478 if (app.curAdj != app.setAdj) { 15479 ProcessList.setOomAdj(app.pid, app.curAdj); 15480 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15481 TAG, "Set " + app.pid + " " + app.processName + 15482 " adj " + app.curAdj + ": " + app.adjType); 15483 app.setAdj = app.curAdj; 15484 } 15485 15486 if (app.setSchedGroup != app.curSchedGroup) { 15487 app.setSchedGroup = app.curSchedGroup; 15488 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15489 "Setting process group of " + app.processName 15490 + " to " + app.curSchedGroup); 15491 if (app.waitingToKill != null && 15492 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15493 killUnneededProcessLocked(app, app.waitingToKill); 15494 success = false; 15495 } else { 15496 if (true) { 15497 long oldId = Binder.clearCallingIdentity(); 15498 try { 15499 Process.setProcessGroup(app.pid, app.curSchedGroup); 15500 } catch (Exception e) { 15501 Slog.w(TAG, "Failed setting process group of " + app.pid 15502 + " to " + app.curSchedGroup); 15503 e.printStackTrace(); 15504 } finally { 15505 Binder.restoreCallingIdentity(oldId); 15506 } 15507 } else { 15508 if (app.thread != null) { 15509 try { 15510 app.thread.setSchedulingGroup(app.curSchedGroup); 15511 } catch (RemoteException e) { 15512 } 15513 } 15514 } 15515 Process.setSwappiness(app.pid, 15516 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15517 } 15518 } 15519 if (app.repProcState != app.curProcState) { 15520 app.repProcState = app.curProcState; 15521 if (!reportingProcessState && app.thread != null) { 15522 try { 15523 if (false) { 15524 //RuntimeException h = new RuntimeException("here"); 15525 Slog.i(TAG, "Sending new process state " + app.repProcState 15526 + " to " + app /*, h*/); 15527 } 15528 app.thread.setProcessState(app.repProcState); 15529 } catch (RemoteException e) { 15530 } 15531 } 15532 } 15533 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15534 app.setProcState)) { 15535 app.lastStateTime = now; 15536 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15537 mSleeping, now); 15538 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15539 + ProcessList.makeProcStateString(app.setProcState) + " to " 15540 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15541 + (app.nextPssTime-now) + ": " + app); 15542 } else { 15543 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15544 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15545 requestPssLocked(app, app.setProcState); 15546 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15547 mSleeping, now); 15548 } else if (false && DEBUG_PSS) { 15549 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15550 } 15551 } 15552 if (app.setProcState != app.curProcState) { 15553 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15554 "Proc state change of " + app.processName 15555 + " to " + app.curProcState); 15556 app.setProcState = app.curProcState; 15557 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15558 app.notCachedSinceIdle = false; 15559 } 15560 if (!doingAll) { 15561 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15562 } else { 15563 app.procStateChanged = true; 15564 } 15565 } 15566 return success; 15567 } 15568 15569 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15570 if (proc.thread != null && proc.baseProcessTracker != null) { 15571 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15572 } 15573 } 15574 15575 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15576 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15577 if (app.thread == null) { 15578 return false; 15579 } 15580 15581 final boolean wasKeeping = app.keeping; 15582 15583 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15584 15585 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15586 reportingProcessState, now); 15587 } 15588 15589 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15590 boolean oomAdj) { 15591 if (isForeground != proc.foregroundServices) { 15592 proc.foregroundServices = isForeground; 15593 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15594 proc.info.uid); 15595 if (isForeground) { 15596 if (curProcs == null) { 15597 curProcs = new ArrayList<ProcessRecord>(); 15598 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15599 } 15600 if (!curProcs.contains(proc)) { 15601 curProcs.add(proc); 15602 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15603 proc.info.packageName, proc.info.uid); 15604 } 15605 } else { 15606 if (curProcs != null) { 15607 if (curProcs.remove(proc)) { 15608 mBatteryStatsService.noteEvent( 15609 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15610 proc.info.packageName, proc.info.uid); 15611 if (curProcs.size() <= 0) { 15612 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15613 } 15614 } 15615 } 15616 } 15617 if (oomAdj) { 15618 updateOomAdjLocked(); 15619 } 15620 } 15621 } 15622 15623 private final ActivityRecord resumedAppLocked() { 15624 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15625 String pkg; 15626 int uid; 15627 if (act != null && !act.sleeping) { 15628 pkg = act.packageName; 15629 uid = act.info.applicationInfo.uid; 15630 } else { 15631 pkg = null; 15632 uid = -1; 15633 } 15634 // Has the UID or resumed package name changed? 15635 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15636 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15637 if (mCurResumedPackage != null) { 15638 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15639 mCurResumedPackage, mCurResumedUid); 15640 } 15641 mCurResumedPackage = pkg; 15642 mCurResumedUid = uid; 15643 if (mCurResumedPackage != null) { 15644 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15645 mCurResumedPackage, mCurResumedUid); 15646 } 15647 } 15648 return act; 15649 } 15650 15651 final boolean updateOomAdjLocked(ProcessRecord app) { 15652 return updateOomAdjLocked(app, false); 15653 } 15654 15655 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15656 final ActivityRecord TOP_ACT = resumedAppLocked(); 15657 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15658 final boolean wasCached = app.cached; 15659 15660 mAdjSeq++; 15661 15662 // This is the desired cached adjusment we want to tell it to use. 15663 // If our app is currently cached, we know it, and that is it. Otherwise, 15664 // we don't know it yet, and it needs to now be cached we will then 15665 // need to do a complete oom adj. 15666 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15667 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15668 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15669 SystemClock.uptimeMillis()); 15670 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15671 // Changed to/from cached state, so apps after it in the LRU 15672 // list may also be changed. 15673 updateOomAdjLocked(); 15674 } 15675 return success; 15676 } 15677 15678 final void updateOomAdjLocked() { 15679 final ActivityRecord TOP_ACT = resumedAppLocked(); 15680 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15681 final long now = SystemClock.uptimeMillis(); 15682 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15683 final int N = mLruProcesses.size(); 15684 15685 if (false) { 15686 RuntimeException e = new RuntimeException(); 15687 e.fillInStackTrace(); 15688 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15689 } 15690 15691 mAdjSeq++; 15692 mNewNumServiceProcs = 0; 15693 mNewNumAServiceProcs = 0; 15694 15695 final int emptyProcessLimit; 15696 final int cachedProcessLimit; 15697 if (mProcessLimit <= 0) { 15698 emptyProcessLimit = cachedProcessLimit = 0; 15699 } else if (mProcessLimit == 1) { 15700 emptyProcessLimit = 1; 15701 cachedProcessLimit = 0; 15702 } else { 15703 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15704 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15705 } 15706 15707 // Let's determine how many processes we have running vs. 15708 // how many slots we have for background processes; we may want 15709 // to put multiple processes in a slot of there are enough of 15710 // them. 15711 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15712 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15713 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15714 if (numEmptyProcs > cachedProcessLimit) { 15715 // If there are more empty processes than our limit on cached 15716 // processes, then use the cached process limit for the factor. 15717 // This ensures that the really old empty processes get pushed 15718 // down to the bottom, so if we are running low on memory we will 15719 // have a better chance at keeping around more cached processes 15720 // instead of a gazillion empty processes. 15721 numEmptyProcs = cachedProcessLimit; 15722 } 15723 int emptyFactor = numEmptyProcs/numSlots; 15724 if (emptyFactor < 1) emptyFactor = 1; 15725 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15726 if (cachedFactor < 1) cachedFactor = 1; 15727 int stepCached = 0; 15728 int stepEmpty = 0; 15729 int numCached = 0; 15730 int numEmpty = 0; 15731 int numTrimming = 0; 15732 15733 mNumNonCachedProcs = 0; 15734 mNumCachedHiddenProcs = 0; 15735 15736 // First update the OOM adjustment for each of the 15737 // application processes based on their current state. 15738 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15739 int nextCachedAdj = curCachedAdj+1; 15740 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15741 int nextEmptyAdj = curEmptyAdj+2; 15742 for (int i=N-1; i>=0; i--) { 15743 ProcessRecord app = mLruProcesses.get(i); 15744 if (!app.killedByAm && app.thread != null) { 15745 app.procStateChanged = false; 15746 final boolean wasKeeping = app.keeping; 15747 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15748 15749 // If we haven't yet assigned the final cached adj 15750 // to the process, do that now. 15751 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15752 switch (app.curProcState) { 15753 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15754 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15755 // This process is a cached process holding activities... 15756 // assign it the next cached value for that type, and then 15757 // step that cached level. 15758 app.curRawAdj = curCachedAdj; 15759 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15760 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15761 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15762 + ")"); 15763 if (curCachedAdj != nextCachedAdj) { 15764 stepCached++; 15765 if (stepCached >= cachedFactor) { 15766 stepCached = 0; 15767 curCachedAdj = nextCachedAdj; 15768 nextCachedAdj += 2; 15769 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15770 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15771 } 15772 } 15773 } 15774 break; 15775 default: 15776 // For everything else, assign next empty cached process 15777 // level and bump that up. Note that this means that 15778 // long-running services that have dropped down to the 15779 // cached level will be treated as empty (since their process 15780 // state is still as a service), which is what we want. 15781 app.curRawAdj = curEmptyAdj; 15782 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15783 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15784 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15785 + ")"); 15786 if (curEmptyAdj != nextEmptyAdj) { 15787 stepEmpty++; 15788 if (stepEmpty >= emptyFactor) { 15789 stepEmpty = 0; 15790 curEmptyAdj = nextEmptyAdj; 15791 nextEmptyAdj += 2; 15792 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15793 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15794 } 15795 } 15796 } 15797 break; 15798 } 15799 } 15800 15801 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15802 15803 // Count the number of process types. 15804 switch (app.curProcState) { 15805 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15806 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15807 mNumCachedHiddenProcs++; 15808 numCached++; 15809 if (numCached > cachedProcessLimit) { 15810 killUnneededProcessLocked(app, "cached #" + numCached); 15811 } 15812 break; 15813 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15814 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15815 && app.lastActivityTime < oldTime) { 15816 killUnneededProcessLocked(app, "empty for " 15817 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15818 / 1000) + "s"); 15819 } else { 15820 numEmpty++; 15821 if (numEmpty > emptyProcessLimit) { 15822 killUnneededProcessLocked(app, "empty #" + numEmpty); 15823 } 15824 } 15825 break; 15826 default: 15827 mNumNonCachedProcs++; 15828 break; 15829 } 15830 15831 if (app.isolated && app.services.size() <= 0) { 15832 // If this is an isolated process, and there are no 15833 // services running in it, then the process is no longer 15834 // needed. We agressively kill these because we can by 15835 // definition not re-use the same process again, and it is 15836 // good to avoid having whatever code was running in them 15837 // left sitting around after no longer needed. 15838 killUnneededProcessLocked(app, "isolated not needed"); 15839 } 15840 15841 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15842 && !app.killedByAm) { 15843 numTrimming++; 15844 } 15845 } 15846 } 15847 15848 mNumServiceProcs = mNewNumServiceProcs; 15849 15850 // Now determine the memory trimming level of background processes. 15851 // Unfortunately we need to start at the back of the list to do this 15852 // properly. We only do this if the number of background apps we 15853 // are managing to keep around is less than half the maximum we desire; 15854 // if we are keeping a good number around, we'll let them use whatever 15855 // memory they want. 15856 final int numCachedAndEmpty = numCached + numEmpty; 15857 int memFactor; 15858 if (numCached <= ProcessList.TRIM_CACHED_APPS 15859 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15860 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15861 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15862 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15863 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15864 } else { 15865 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15866 } 15867 } else { 15868 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15869 } 15870 // We always allow the memory level to go up (better). We only allow it to go 15871 // down if we are in a state where that is allowed, *and* the total number of processes 15872 // has gone down since last time. 15873 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15874 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15875 + " last=" + mLastNumProcesses); 15876 if (memFactor > mLastMemoryLevel) { 15877 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15878 memFactor = mLastMemoryLevel; 15879 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15880 } 15881 } 15882 mLastMemoryLevel = memFactor; 15883 mLastNumProcesses = mLruProcesses.size(); 15884 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15885 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15886 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15887 if (mLowRamStartTime == 0) { 15888 mLowRamStartTime = now; 15889 } 15890 int step = 0; 15891 int fgTrimLevel; 15892 switch (memFactor) { 15893 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15894 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15895 break; 15896 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15897 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15898 break; 15899 default: 15900 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15901 break; 15902 } 15903 int factor = numTrimming/3; 15904 int minFactor = 2; 15905 if (mHomeProcess != null) minFactor++; 15906 if (mPreviousProcess != null) minFactor++; 15907 if (factor < minFactor) factor = minFactor; 15908 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15909 for (int i=N-1; i>=0; i--) { 15910 ProcessRecord app = mLruProcesses.get(i); 15911 if (allChanged || app.procStateChanged) { 15912 setProcessTrackerState(app, trackerMemFactor, now); 15913 app.procStateChanged = false; 15914 } 15915 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15916 && !app.killedByAm) { 15917 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15918 try { 15919 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15920 "Trimming memory of " + app.processName 15921 + " to " + curLevel); 15922 app.thread.scheduleTrimMemory(curLevel); 15923 } catch (RemoteException e) { 15924 } 15925 if (false) { 15926 // For now we won't do this; our memory trimming seems 15927 // to be good enough at this point that destroying 15928 // activities causes more harm than good. 15929 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15930 && app != mHomeProcess && app != mPreviousProcess) { 15931 // Need to do this on its own message because the stack may not 15932 // be in a consistent state at this point. 15933 // For these apps we will also finish their activities 15934 // to help them free memory. 15935 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15936 } 15937 } 15938 } 15939 app.trimMemoryLevel = curLevel; 15940 step++; 15941 if (step >= factor) { 15942 step = 0; 15943 switch (curLevel) { 15944 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15945 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15946 break; 15947 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15948 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15949 break; 15950 } 15951 } 15952 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15953 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15954 && app.thread != null) { 15955 try { 15956 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15957 "Trimming memory of heavy-weight " + app.processName 15958 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15959 app.thread.scheduleTrimMemory( 15960 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15961 } catch (RemoteException e) { 15962 } 15963 } 15964 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15965 } else { 15966 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15967 || app.systemNoUi) && app.pendingUiClean) { 15968 // If this application is now in the background and it 15969 // had done UI, then give it the special trim level to 15970 // have it free UI resources. 15971 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15972 if (app.trimMemoryLevel < level && app.thread != null) { 15973 try { 15974 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15975 "Trimming memory of bg-ui " + app.processName 15976 + " to " + level); 15977 app.thread.scheduleTrimMemory(level); 15978 } catch (RemoteException e) { 15979 } 15980 } 15981 app.pendingUiClean = false; 15982 } 15983 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15984 try { 15985 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15986 "Trimming memory of fg " + app.processName 15987 + " to " + fgTrimLevel); 15988 app.thread.scheduleTrimMemory(fgTrimLevel); 15989 } catch (RemoteException e) { 15990 } 15991 } 15992 app.trimMemoryLevel = fgTrimLevel; 15993 } 15994 } 15995 } else { 15996 if (mLowRamStartTime != 0) { 15997 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15998 mLowRamStartTime = 0; 15999 } 16000 for (int i=N-1; i>=0; i--) { 16001 ProcessRecord app = mLruProcesses.get(i); 16002 if (allChanged || app.procStateChanged) { 16003 setProcessTrackerState(app, trackerMemFactor, now); 16004 app.procStateChanged = false; 16005 } 16006 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16007 || app.systemNoUi) && app.pendingUiClean) { 16008 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16009 && app.thread != null) { 16010 try { 16011 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16012 "Trimming memory of ui hidden " + app.processName 16013 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16014 app.thread.scheduleTrimMemory( 16015 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16016 } catch (RemoteException e) { 16017 } 16018 } 16019 app.pendingUiClean = false; 16020 } 16021 app.trimMemoryLevel = 0; 16022 } 16023 } 16024 16025 if (mAlwaysFinishActivities) { 16026 // Need to do this on its own message because the stack may not 16027 // be in a consistent state at this point. 16028 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16029 } 16030 16031 if (allChanged) { 16032 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16033 } 16034 16035 if (mProcessStats.shouldWriteNowLocked(now)) { 16036 mHandler.post(new Runnable() { 16037 @Override public void run() { 16038 synchronized (ActivityManagerService.this) { 16039 mProcessStats.writeStateAsyncLocked(); 16040 } 16041 } 16042 }); 16043 } 16044 16045 if (DEBUG_OOM_ADJ) { 16046 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16047 } 16048 } 16049 16050 final void trimApplications() { 16051 synchronized (this) { 16052 int i; 16053 16054 // First remove any unused application processes whose package 16055 // has been removed. 16056 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16057 final ProcessRecord app = mRemovedProcesses.get(i); 16058 if (app.activities.size() == 0 16059 && app.curReceiver == null && app.services.size() == 0) { 16060 Slog.i( 16061 TAG, "Exiting empty application process " 16062 + app.processName + " (" 16063 + (app.thread != null ? app.thread.asBinder() : null) 16064 + ")\n"); 16065 if (app.pid > 0 && app.pid != MY_PID) { 16066 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16067 app.processName, app.setAdj, "empty"); 16068 app.killedByAm = true; 16069 Process.killProcessQuiet(app.pid); 16070 } else { 16071 try { 16072 app.thread.scheduleExit(); 16073 } catch (Exception e) { 16074 // Ignore exceptions. 16075 } 16076 } 16077 cleanUpApplicationRecordLocked(app, false, true, -1); 16078 mRemovedProcesses.remove(i); 16079 16080 if (app.persistent) { 16081 if (app.persistent) { 16082 addAppLocked(app.info, false); 16083 } 16084 } 16085 } 16086 } 16087 16088 // Now update the oom adj for all processes. 16089 updateOomAdjLocked(); 16090 } 16091 } 16092 16093 /** This method sends the specified signal to each of the persistent apps */ 16094 public void signalPersistentProcesses(int sig) throws RemoteException { 16095 if (sig != Process.SIGNAL_USR1) { 16096 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16097 } 16098 16099 synchronized (this) { 16100 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16101 != PackageManager.PERMISSION_GRANTED) { 16102 throw new SecurityException("Requires permission " 16103 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16104 } 16105 16106 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16107 ProcessRecord r = mLruProcesses.get(i); 16108 if (r.thread != null && r.persistent) { 16109 Process.sendSignal(r.pid, sig); 16110 } 16111 } 16112 } 16113 } 16114 16115 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16116 if (proc == null || proc == mProfileProc) { 16117 proc = mProfileProc; 16118 path = mProfileFile; 16119 profileType = mProfileType; 16120 clearProfilerLocked(); 16121 } 16122 if (proc == null) { 16123 return; 16124 } 16125 try { 16126 proc.thread.profilerControl(false, path, null, profileType); 16127 } catch (RemoteException e) { 16128 throw new IllegalStateException("Process disappeared"); 16129 } 16130 } 16131 16132 private void clearProfilerLocked() { 16133 if (mProfileFd != null) { 16134 try { 16135 mProfileFd.close(); 16136 } catch (IOException e) { 16137 } 16138 } 16139 mProfileApp = null; 16140 mProfileProc = null; 16141 mProfileFile = null; 16142 mProfileType = 0; 16143 mAutoStopProfiler = false; 16144 } 16145 16146 public boolean profileControl(String process, int userId, boolean start, 16147 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16148 16149 try { 16150 synchronized (this) { 16151 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16152 // its own permission. 16153 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16154 != PackageManager.PERMISSION_GRANTED) { 16155 throw new SecurityException("Requires permission " 16156 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16157 } 16158 16159 if (start && fd == null) { 16160 throw new IllegalArgumentException("null fd"); 16161 } 16162 16163 ProcessRecord proc = null; 16164 if (process != null) { 16165 proc = findProcessLocked(process, userId, "profileControl"); 16166 } 16167 16168 if (start && (proc == null || proc.thread == null)) { 16169 throw new IllegalArgumentException("Unknown process: " + process); 16170 } 16171 16172 if (start) { 16173 stopProfilerLocked(null, null, 0); 16174 setProfileApp(proc.info, proc.processName, path, fd, false); 16175 mProfileProc = proc; 16176 mProfileType = profileType; 16177 try { 16178 fd = fd.dup(); 16179 } catch (IOException e) { 16180 fd = null; 16181 } 16182 proc.thread.profilerControl(start, path, fd, profileType); 16183 fd = null; 16184 mProfileFd = null; 16185 } else { 16186 stopProfilerLocked(proc, path, profileType); 16187 if (fd != null) { 16188 try { 16189 fd.close(); 16190 } catch (IOException e) { 16191 } 16192 } 16193 } 16194 16195 return true; 16196 } 16197 } catch (RemoteException e) { 16198 throw new IllegalStateException("Process disappeared"); 16199 } finally { 16200 if (fd != null) { 16201 try { 16202 fd.close(); 16203 } catch (IOException e) { 16204 } 16205 } 16206 } 16207 } 16208 16209 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16210 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16211 userId, true, true, callName, null); 16212 ProcessRecord proc = null; 16213 try { 16214 int pid = Integer.parseInt(process); 16215 synchronized (mPidsSelfLocked) { 16216 proc = mPidsSelfLocked.get(pid); 16217 } 16218 } catch (NumberFormatException e) { 16219 } 16220 16221 if (proc == null) { 16222 ArrayMap<String, SparseArray<ProcessRecord>> all 16223 = mProcessNames.getMap(); 16224 SparseArray<ProcessRecord> procs = all.get(process); 16225 if (procs != null && procs.size() > 0) { 16226 proc = procs.valueAt(0); 16227 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16228 for (int i=1; i<procs.size(); i++) { 16229 ProcessRecord thisProc = procs.valueAt(i); 16230 if (thisProc.userId == userId) { 16231 proc = thisProc; 16232 break; 16233 } 16234 } 16235 } 16236 } 16237 } 16238 16239 return proc; 16240 } 16241 16242 public boolean dumpHeap(String process, int userId, boolean managed, 16243 String path, ParcelFileDescriptor fd) throws RemoteException { 16244 16245 try { 16246 synchronized (this) { 16247 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16248 // its own permission (same as profileControl). 16249 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16250 != PackageManager.PERMISSION_GRANTED) { 16251 throw new SecurityException("Requires permission " 16252 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16253 } 16254 16255 if (fd == null) { 16256 throw new IllegalArgumentException("null fd"); 16257 } 16258 16259 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16260 if (proc == null || proc.thread == null) { 16261 throw new IllegalArgumentException("Unknown process: " + process); 16262 } 16263 16264 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16265 if (!isDebuggable) { 16266 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16267 throw new SecurityException("Process not debuggable: " + proc); 16268 } 16269 } 16270 16271 proc.thread.dumpHeap(managed, path, fd); 16272 fd = null; 16273 return true; 16274 } 16275 } catch (RemoteException e) { 16276 throw new IllegalStateException("Process disappeared"); 16277 } finally { 16278 if (fd != null) { 16279 try { 16280 fd.close(); 16281 } catch (IOException e) { 16282 } 16283 } 16284 } 16285 } 16286 16287 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16288 public void monitor() { 16289 synchronized (this) { } 16290 } 16291 16292 void onCoreSettingsChange(Bundle settings) { 16293 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16294 ProcessRecord processRecord = mLruProcesses.get(i); 16295 try { 16296 if (processRecord.thread != null) { 16297 processRecord.thread.setCoreSettings(settings); 16298 } 16299 } catch (RemoteException re) { 16300 /* ignore */ 16301 } 16302 } 16303 } 16304 16305 // Multi-user methods 16306 16307 /** 16308 * Start user, if its not already running, but don't bring it to foreground. 16309 */ 16310 @Override 16311 public boolean startUserInBackground(final int userId) { 16312 return startUser(userId, /* foreground */ false); 16313 } 16314 16315 /** 16316 * Refreshes the list of users related to the current user when either a 16317 * user switch happens or when a new related user is started in the 16318 * background. 16319 */ 16320 private void updateCurrentProfileIdsLocked() { 16321 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId); 16322 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16323 for (int i = 0; i < currentProfileIds.length; i++) { 16324 currentProfileIds[i] = profiles.get(i).id; 16325 } 16326 mCurrentProfileIds = currentProfileIds; 16327 } 16328 16329 private Set getProfileIdsLocked(int userId) { 16330 Set userIds = new HashSet<Integer>(); 16331 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(userId); 16332 for (UserInfo user : profiles) { 16333 userIds.add(Integer.valueOf(user.id)); 16334 } 16335 return userIds; 16336 } 16337 16338 @Override 16339 public boolean switchUser(final int userId) { 16340 return startUser(userId, /* foregound */ true); 16341 } 16342 16343 private boolean startUser(final int userId, boolean foreground) { 16344 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16345 != PackageManager.PERMISSION_GRANTED) { 16346 String msg = "Permission Denial: switchUser() from pid=" 16347 + Binder.getCallingPid() 16348 + ", uid=" + Binder.getCallingUid() 16349 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16350 Slog.w(TAG, msg); 16351 throw new SecurityException(msg); 16352 } 16353 16354 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16355 16356 final long ident = Binder.clearCallingIdentity(); 16357 try { 16358 synchronized (this) { 16359 final int oldUserId = mCurrentUserId; 16360 if (oldUserId == userId) { 16361 return true; 16362 } 16363 16364 mStackSupervisor.setLockTaskModeLocked(null); 16365 16366 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16367 if (userInfo == null) { 16368 Slog.w(TAG, "No user info for user #" + userId); 16369 return false; 16370 } 16371 16372 if (foreground) { 16373 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16374 R.anim.screen_user_enter); 16375 } 16376 16377 boolean needStart = false; 16378 16379 // If the user we are switching to is not currently started, then 16380 // we need to start it now. 16381 if (mStartedUsers.get(userId) == null) { 16382 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16383 updateStartedUserArrayLocked(); 16384 needStart = true; 16385 } 16386 16387 final Integer userIdInt = Integer.valueOf(userId); 16388 mUserLru.remove(userIdInt); 16389 mUserLru.add(userIdInt); 16390 16391 if (foreground) { 16392 mCurrentUserId = userId; 16393 updateCurrentProfileIdsLocked(); 16394 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16395 // Once the internal notion of the active user has switched, we lock the device 16396 // with the option to show the user switcher on the keyguard. 16397 mWindowManager.lockNow(null); 16398 } else { 16399 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16400 updateCurrentProfileIdsLocked(); 16401 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16402 mUserLru.remove(currentUserIdInt); 16403 mUserLru.add(currentUserIdInt); 16404 } 16405 16406 final UserStartedState uss = mStartedUsers.get(userId); 16407 16408 // Make sure user is in the started state. If it is currently 16409 // stopping, we need to knock that off. 16410 if (uss.mState == UserStartedState.STATE_STOPPING) { 16411 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16412 // so we can just fairly silently bring the user back from 16413 // the almost-dead. 16414 uss.mState = UserStartedState.STATE_RUNNING; 16415 updateStartedUserArrayLocked(); 16416 needStart = true; 16417 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16418 // This means ACTION_SHUTDOWN has been sent, so we will 16419 // need to treat this as a new boot of the user. 16420 uss.mState = UserStartedState.STATE_BOOTING; 16421 updateStartedUserArrayLocked(); 16422 needStart = true; 16423 } 16424 16425 if (foreground) { 16426 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16427 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16428 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16429 oldUserId, userId, uss)); 16430 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16431 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16432 } 16433 16434 if (needStart) { 16435 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16436 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16437 | Intent.FLAG_RECEIVER_FOREGROUND); 16438 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16439 broadcastIntentLocked(null, null, intent, 16440 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16441 false, false, MY_PID, Process.SYSTEM_UID, userId); 16442 } 16443 16444 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16445 if (userId != 0) { 16446 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16447 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16448 broadcastIntentLocked(null, null, intent, null, 16449 new IIntentReceiver.Stub() { 16450 public void performReceive(Intent intent, int resultCode, 16451 String data, Bundle extras, boolean ordered, 16452 boolean sticky, int sendingUser) { 16453 userInitialized(uss, userId); 16454 } 16455 }, 0, null, null, null, AppOpsManager.OP_NONE, 16456 true, false, MY_PID, Process.SYSTEM_UID, 16457 userId); 16458 uss.initializing = true; 16459 } else { 16460 getUserManagerLocked().makeInitialized(userInfo.id); 16461 } 16462 } 16463 16464 if (foreground) { 16465 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16466 if (homeInFront) { 16467 startHomeActivityLocked(userId); 16468 } else { 16469 mStackSupervisor.resumeTopActivitiesLocked(); 16470 } 16471 EventLogTags.writeAmSwitchUser(userId); 16472 getUserManagerLocked().userForeground(userId); 16473 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16474 } 16475 16476 if (needStart) { 16477 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16478 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16479 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16480 broadcastIntentLocked(null, null, intent, 16481 null, new IIntentReceiver.Stub() { 16482 @Override 16483 public void performReceive(Intent intent, int resultCode, String data, 16484 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16485 throws RemoteException { 16486 } 16487 }, 0, null, null, 16488 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16489 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16490 } 16491 } 16492 } finally { 16493 Binder.restoreCallingIdentity(ident); 16494 } 16495 16496 return true; 16497 } 16498 16499 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16500 long ident = Binder.clearCallingIdentity(); 16501 try { 16502 Intent intent; 16503 if (oldUserId >= 0) { 16504 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16505 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16506 | Intent.FLAG_RECEIVER_FOREGROUND); 16507 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16508 broadcastIntentLocked(null, null, intent, 16509 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16510 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16511 } 16512 if (newUserId >= 0) { 16513 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 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, null, AppOpsManager.OP_NONE, 16519 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16520 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16521 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16522 | Intent.FLAG_RECEIVER_FOREGROUND); 16523 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16524 broadcastIntentLocked(null, null, intent, 16525 null, null, 0, null, null, 16526 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16527 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16528 } 16529 } finally { 16530 Binder.restoreCallingIdentity(ident); 16531 } 16532 } 16533 16534 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16535 final int newUserId) { 16536 final int N = mUserSwitchObservers.beginBroadcast(); 16537 if (N > 0) { 16538 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16539 int mCount = 0; 16540 @Override 16541 public void sendResult(Bundle data) throws RemoteException { 16542 synchronized (ActivityManagerService.this) { 16543 if (mCurUserSwitchCallback == this) { 16544 mCount++; 16545 if (mCount == N) { 16546 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16547 } 16548 } 16549 } 16550 } 16551 }; 16552 synchronized (this) { 16553 uss.switching = true; 16554 mCurUserSwitchCallback = callback; 16555 } 16556 for (int i=0; i<N; i++) { 16557 try { 16558 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16559 newUserId, callback); 16560 } catch (RemoteException e) { 16561 } 16562 } 16563 } else { 16564 synchronized (this) { 16565 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16566 } 16567 } 16568 mUserSwitchObservers.finishBroadcast(); 16569 } 16570 16571 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16572 synchronized (this) { 16573 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16574 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16575 } 16576 } 16577 16578 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16579 mCurUserSwitchCallback = null; 16580 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16581 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16582 oldUserId, newUserId, uss)); 16583 } 16584 16585 void userInitialized(UserStartedState uss, int newUserId) { 16586 completeSwitchAndInitalize(uss, newUserId, true, false); 16587 } 16588 16589 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16590 completeSwitchAndInitalize(uss, newUserId, false, true); 16591 } 16592 16593 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16594 boolean clearInitializing, boolean clearSwitching) { 16595 boolean unfrozen = false; 16596 synchronized (this) { 16597 if (clearInitializing) { 16598 uss.initializing = false; 16599 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16600 } 16601 if (clearSwitching) { 16602 uss.switching = false; 16603 } 16604 if (!uss.switching && !uss.initializing) { 16605 mWindowManager.stopFreezingScreen(); 16606 unfrozen = true; 16607 } 16608 } 16609 if (unfrozen) { 16610 final int N = mUserSwitchObservers.beginBroadcast(); 16611 for (int i=0; i<N; i++) { 16612 try { 16613 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16614 } catch (RemoteException e) { 16615 } 16616 } 16617 mUserSwitchObservers.finishBroadcast(); 16618 } 16619 } 16620 16621 void scheduleStartProfilesLocked() { 16622 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16623 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16624 DateUtils.SECOND_IN_MILLIS); 16625 } 16626 } 16627 16628 void startProfilesLocked() { 16629 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16630 List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId); 16631 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16632 for (UserInfo user : profiles) { 16633 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16634 && user.id != mCurrentUserId) { 16635 toStart.add(user); 16636 } 16637 } 16638 final int n = toStart.size(); 16639 int i = 0; 16640 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16641 startUserInBackground(toStart.get(i).id); 16642 } 16643 if (i < n) { 16644 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16645 } 16646 } 16647 16648 void finishUserSwitch(UserStartedState uss) { 16649 synchronized (this) { 16650 if (uss.mState == UserStartedState.STATE_BOOTING 16651 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16652 uss.mState = UserStartedState.STATE_RUNNING; 16653 final int userId = uss.mHandle.getIdentifier(); 16654 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16655 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16656 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16657 broadcastIntentLocked(null, null, intent, 16658 null, null, 0, null, null, 16659 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16660 true, false, MY_PID, Process.SYSTEM_UID, userId); 16661 } 16662 16663 startProfilesLocked(); 16664 16665 int num = mUserLru.size(); 16666 int i = 0; 16667 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16668 Integer oldUserId = mUserLru.get(i); 16669 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16670 if (oldUss == null) { 16671 // Shouldn't happen, but be sane if it does. 16672 mUserLru.remove(i); 16673 num--; 16674 continue; 16675 } 16676 if (oldUss.mState == UserStartedState.STATE_STOPPING 16677 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16678 // This user is already stopping, doesn't count. 16679 num--; 16680 i++; 16681 continue; 16682 } 16683 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16684 // Owner and current can't be stopped, but count as running. 16685 i++; 16686 continue; 16687 } 16688 // This is a user to be stopped. 16689 stopUserLocked(oldUserId, null); 16690 num--; 16691 i++; 16692 } 16693 } 16694 } 16695 16696 @Override 16697 public int stopUser(final int userId, final IStopUserCallback callback) { 16698 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16699 != PackageManager.PERMISSION_GRANTED) { 16700 String msg = "Permission Denial: switchUser() from pid=" 16701 + Binder.getCallingPid() 16702 + ", uid=" + Binder.getCallingUid() 16703 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16704 Slog.w(TAG, msg); 16705 throw new SecurityException(msg); 16706 } 16707 if (userId <= 0) { 16708 throw new IllegalArgumentException("Can't stop primary user " + userId); 16709 } 16710 synchronized (this) { 16711 return stopUserLocked(userId, callback); 16712 } 16713 } 16714 16715 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16716 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16717 if (mCurrentUserId == userId) { 16718 return ActivityManager.USER_OP_IS_CURRENT; 16719 } 16720 16721 final UserStartedState uss = mStartedUsers.get(userId); 16722 if (uss == null) { 16723 // User is not started, nothing to do... but we do need to 16724 // callback if requested. 16725 if (callback != null) { 16726 mHandler.post(new Runnable() { 16727 @Override 16728 public void run() { 16729 try { 16730 callback.userStopped(userId); 16731 } catch (RemoteException e) { 16732 } 16733 } 16734 }); 16735 } 16736 return ActivityManager.USER_OP_SUCCESS; 16737 } 16738 16739 if (callback != null) { 16740 uss.mStopCallbacks.add(callback); 16741 } 16742 16743 if (uss.mState != UserStartedState.STATE_STOPPING 16744 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16745 uss.mState = UserStartedState.STATE_STOPPING; 16746 updateStartedUserArrayLocked(); 16747 16748 long ident = Binder.clearCallingIdentity(); 16749 try { 16750 // We are going to broadcast ACTION_USER_STOPPING and then 16751 // once that is done send a final ACTION_SHUTDOWN and then 16752 // stop the user. 16753 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16754 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16755 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16756 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16757 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16758 // This is the result receiver for the final shutdown broadcast. 16759 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16760 @Override 16761 public void performReceive(Intent intent, int resultCode, String data, 16762 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16763 finishUserStop(uss); 16764 } 16765 }; 16766 // This is the result receiver for the initial stopping broadcast. 16767 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16768 @Override 16769 public void performReceive(Intent intent, int resultCode, String data, 16770 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16771 // On to the next. 16772 synchronized (ActivityManagerService.this) { 16773 if (uss.mState != UserStartedState.STATE_STOPPING) { 16774 // Whoops, we are being started back up. Abort, abort! 16775 return; 16776 } 16777 uss.mState = UserStartedState.STATE_SHUTDOWN; 16778 } 16779 broadcastIntentLocked(null, null, shutdownIntent, 16780 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16781 true, false, MY_PID, Process.SYSTEM_UID, userId); 16782 } 16783 }; 16784 // Kick things off. 16785 broadcastIntentLocked(null, null, stoppingIntent, 16786 null, stoppingReceiver, 0, null, null, 16787 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16788 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16789 } finally { 16790 Binder.restoreCallingIdentity(ident); 16791 } 16792 } 16793 16794 return ActivityManager.USER_OP_SUCCESS; 16795 } 16796 16797 void finishUserStop(UserStartedState uss) { 16798 final int userId = uss.mHandle.getIdentifier(); 16799 boolean stopped; 16800 ArrayList<IStopUserCallback> callbacks; 16801 synchronized (this) { 16802 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16803 if (mStartedUsers.get(userId) != uss) { 16804 stopped = false; 16805 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16806 stopped = false; 16807 } else { 16808 stopped = true; 16809 // User can no longer run. 16810 mStartedUsers.remove(userId); 16811 mUserLru.remove(Integer.valueOf(userId)); 16812 updateStartedUserArrayLocked(); 16813 16814 // Clean up all state and processes associated with the user. 16815 // Kill all the processes for the user. 16816 forceStopUserLocked(userId, "finish user"); 16817 } 16818 } 16819 16820 for (int i=0; i<callbacks.size(); i++) { 16821 try { 16822 if (stopped) callbacks.get(i).userStopped(userId); 16823 else callbacks.get(i).userStopAborted(userId); 16824 } catch (RemoteException e) { 16825 } 16826 } 16827 16828 mStackSupervisor.removeUserLocked(userId); 16829 } 16830 16831 @Override 16832 public UserInfo getCurrentUser() { 16833 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16834 != PackageManager.PERMISSION_GRANTED) && ( 16835 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16836 != PackageManager.PERMISSION_GRANTED)) { 16837 String msg = "Permission Denial: getCurrentUser() from pid=" 16838 + Binder.getCallingPid() 16839 + ", uid=" + Binder.getCallingUid() 16840 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16841 Slog.w(TAG, msg); 16842 throw new SecurityException(msg); 16843 } 16844 synchronized (this) { 16845 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16846 } 16847 } 16848 16849 int getCurrentUserIdLocked() { 16850 return mCurrentUserId; 16851 } 16852 16853 @Override 16854 public boolean isUserRunning(int userId, boolean orStopped) { 16855 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16856 != PackageManager.PERMISSION_GRANTED) { 16857 String msg = "Permission Denial: isUserRunning() from pid=" 16858 + Binder.getCallingPid() 16859 + ", uid=" + Binder.getCallingUid() 16860 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16861 Slog.w(TAG, msg); 16862 throw new SecurityException(msg); 16863 } 16864 synchronized (this) { 16865 return isUserRunningLocked(userId, orStopped); 16866 } 16867 } 16868 16869 boolean isUserRunningLocked(int userId, boolean orStopped) { 16870 UserStartedState state = mStartedUsers.get(userId); 16871 if (state == null) { 16872 return false; 16873 } 16874 if (orStopped) { 16875 return true; 16876 } 16877 return state.mState != UserStartedState.STATE_STOPPING 16878 && state.mState != UserStartedState.STATE_SHUTDOWN; 16879 } 16880 16881 @Override 16882 public int[] getRunningUserIds() { 16883 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16884 != PackageManager.PERMISSION_GRANTED) { 16885 String msg = "Permission Denial: isUserRunning() from pid=" 16886 + Binder.getCallingPid() 16887 + ", uid=" + Binder.getCallingUid() 16888 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16889 Slog.w(TAG, msg); 16890 throw new SecurityException(msg); 16891 } 16892 synchronized (this) { 16893 return mStartedUserArray; 16894 } 16895 } 16896 16897 private void updateStartedUserArrayLocked() { 16898 int num = 0; 16899 for (int i=0; i<mStartedUsers.size(); i++) { 16900 UserStartedState uss = mStartedUsers.valueAt(i); 16901 // This list does not include stopping users. 16902 if (uss.mState != UserStartedState.STATE_STOPPING 16903 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16904 num++; 16905 } 16906 } 16907 mStartedUserArray = new int[num]; 16908 num = 0; 16909 for (int i=0; i<mStartedUsers.size(); i++) { 16910 UserStartedState uss = mStartedUsers.valueAt(i); 16911 if (uss.mState != UserStartedState.STATE_STOPPING 16912 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16913 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16914 num++; 16915 } 16916 } 16917 } 16918 16919 @Override 16920 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16921 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16922 != PackageManager.PERMISSION_GRANTED) { 16923 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16924 + Binder.getCallingPid() 16925 + ", uid=" + Binder.getCallingUid() 16926 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16927 Slog.w(TAG, msg); 16928 throw new SecurityException(msg); 16929 } 16930 16931 mUserSwitchObservers.register(observer); 16932 } 16933 16934 @Override 16935 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16936 mUserSwitchObservers.unregister(observer); 16937 } 16938 16939 private boolean userExists(int userId) { 16940 if (userId == 0) { 16941 return true; 16942 } 16943 UserManagerService ums = getUserManagerLocked(); 16944 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16945 } 16946 16947 int[] getUsersLocked() { 16948 UserManagerService ums = getUserManagerLocked(); 16949 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16950 } 16951 16952 UserManagerService getUserManagerLocked() { 16953 if (mUserManager == null) { 16954 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16955 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16956 } 16957 return mUserManager; 16958 } 16959 16960 private int applyUserId(int uid, int userId) { 16961 return UserHandle.getUid(userId, uid); 16962 } 16963 16964 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16965 if (info == null) return null; 16966 ApplicationInfo newInfo = new ApplicationInfo(info); 16967 newInfo.uid = applyUserId(info.uid, userId); 16968 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16969 + info.packageName; 16970 return newInfo; 16971 } 16972 16973 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16974 if (aInfo == null 16975 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16976 return aInfo; 16977 } 16978 16979 ActivityInfo info = new ActivityInfo(aInfo); 16980 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16981 return info; 16982 } 16983} 16984