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 17 package com.android.server.am; 18 19 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20 import static com.android.internal.util.XmlUtils.readIntAttribute; 21 import static com.android.internal.util.XmlUtils.readLongAttribute; 22 import static com.android.internal.util.XmlUtils.writeIntAttribute; 23 import static com.android.internal.util.XmlUtils.writeLongAttribute; 24 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26 import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30 import android.app.AppOpsManager; 31 import android.appwidget.AppWidgetManager; 32 import android.util.ArrayMap; 33 import com.android.internal.R; 34 import com.android.internal.annotations.GuardedBy; 35 import com.android.internal.app.IAppOpsService; 36 import com.android.internal.app.ProcessStats; 37 import com.android.internal.os.BackgroundThread; 38 import com.android.internal.os.BatteryStatsImpl; 39 import com.android.internal.os.ProcessCpuTracker; 40 import com.android.internal.os.TransferPipe; 41 import com.android.internal.util.FastPrintWriter; 42 import com.android.internal.util.FastXmlSerializer; 43 import com.android.internal.util.MemInfoReader; 44 import com.android.internal.util.Preconditions; 45 import com.android.server.AppOpsService; 46 import com.android.server.AttributeCache; 47 import com.android.server.IntentResolver; 48 import com.android.internal.app.ProcessMap; 49 import com.android.server.SystemServer; 50 import com.android.server.Watchdog; 51 import com.android.server.am.ActivityStack.ActivityState; 52 import com.android.server.firewall.IntentFirewall; 53 import com.android.server.pm.UserManagerService; 54 import com.android.server.wm.AppTransition; 55 import com.android.server.wm.StackBox; 56 import com.android.server.wm.WindowManagerService; 57 import com.google.android.collect.Lists; 58 import com.google.android.collect.Maps; 59 60 import dalvik.system.Zygote; 61 62 import libcore.io.IoUtils; 63 64 import org.xmlpull.v1.XmlPullParser; 65 import org.xmlpull.v1.XmlPullParserException; 66 import org.xmlpull.v1.XmlSerializer; 67 68 import android.app.Activity; 69 import android.app.ActivityManager; 70 import android.app.ActivityManager.RunningTaskInfo; 71 import android.app.ActivityManager.StackBoxInfo; 72 import android.app.ActivityManager.StackInfo; 73 import android.app.ActivityManagerNative; 74 import android.app.ActivityOptions; 75 import android.app.ActivityThread; 76 import android.app.AlertDialog; 77 import android.app.AppGlobals; 78 import android.app.ApplicationErrorReport; 79 import android.app.Dialog; 80 import android.app.IActivityController; 81 import android.app.IApplicationThread; 82 import android.app.IInstrumentationWatcher; 83 import android.app.INotificationManager; 84 import android.app.IProcessObserver; 85 import android.app.IServiceConnection; 86 import android.app.IStopUserCallback; 87 import android.app.IThumbnailReceiver; 88 import android.app.IUiAutomationConnection; 89 import android.app.IUserSwitchObserver; 90 import android.app.Instrumentation; 91 import android.app.Notification; 92 import android.app.NotificationManager; 93 import android.app.PendingIntent; 94 import android.app.backup.IBackupManager; 95 import android.content.ActivityNotFoundException; 96 import android.content.BroadcastReceiver; 97 import android.content.ClipData; 98 import android.content.ComponentCallbacks2; 99 import android.content.ComponentName; 100 import android.content.ContentProvider; 101 import android.content.ContentResolver; 102 import android.content.Context; 103 import android.content.DialogInterface; 104 import android.content.IContentProvider; 105 import android.content.IIntentReceiver; 106 import android.content.IIntentSender; 107 import android.content.Intent; 108 import android.content.IntentFilter; 109 import android.content.IntentSender; 110 import android.content.pm.ActivityInfo; 111 import android.content.pm.ApplicationInfo; 112 import android.content.pm.ConfigurationInfo; 113 import android.content.pm.IPackageDataObserver; 114 import android.content.pm.IPackageManager; 115 import android.content.pm.InstrumentationInfo; 116 import android.content.pm.PackageInfo; 117 import android.content.pm.PackageManager; 118 import android.content.pm.ParceledListSlice; 119 import android.content.pm.UserInfo; 120 import android.content.pm.PackageManager.NameNotFoundException; 121 import android.content.pm.PathPermission; 122 import android.content.pm.ProviderInfo; 123 import android.content.pm.ResolveInfo; 124 import android.content.pm.ServiceInfo; 125 import android.content.res.CompatibilityInfo; 126 import android.content.res.Configuration; 127 import android.graphics.Bitmap; 128 import android.net.Proxy; 129 import android.net.ProxyProperties; 130 import android.net.Uri; 131 import android.os.Binder; 132 import android.os.Build; 133 import android.os.Bundle; 134 import android.os.Debug; 135 import android.os.DropBoxManager; 136 import android.os.Environment; 137 import android.os.FileObserver; 138 import android.os.FileUtils; 139 import android.os.Handler; 140 import android.os.IBinder; 141 import android.os.IPermissionController; 142 import android.os.IRemoteCallback; 143 import android.os.IUserManager; 144 import android.os.Looper; 145 import android.os.Message; 146 import android.os.Parcel; 147 import android.os.ParcelFileDescriptor; 148 import android.os.Process; 149 import android.os.RemoteCallbackList; 150 import android.os.RemoteException; 151 import android.os.SELinux; 152 import android.os.ServiceManager; 153 import android.os.StrictMode; 154 import android.os.SystemClock; 155 import android.os.SystemProperties; 156 import android.os.UpdateLock; 157 import android.os.UserHandle; 158 import android.provider.Settings; 159 import android.text.format.DateUtils; 160 import android.text.format.Time; 161 import android.util.AtomicFile; 162 import android.util.EventLog; 163 import android.util.Log; 164 import android.util.Pair; 165 import android.util.PrintWriterPrinter; 166 import android.util.Slog; 167 import android.util.SparseArray; 168 import android.util.TimeUtils; 169 import android.util.Xml; 170 import android.view.Gravity; 171 import android.view.LayoutInflater; 172 import android.view.View; 173 import android.view.WindowManager; 174 175 import java.io.BufferedInputStream; 176 import java.io.BufferedOutputStream; 177 import java.io.DataInputStream; 178 import java.io.DataOutputStream; 179 import java.io.File; 180 import java.io.FileDescriptor; 181 import java.io.FileInputStream; 182 import java.io.FileNotFoundException; 183 import java.io.FileOutputStream; 184 import java.io.IOException; 185 import java.io.InputStreamReader; 186 import java.io.PrintWriter; 187 import java.io.StringWriter; 188 import java.lang.ref.WeakReference; 189 import java.util.ArrayList; 190 import java.util.Arrays; 191 import java.util.Collections; 192 import java.util.Comparator; 193 import java.util.HashMap; 194 import java.util.HashSet; 195 import java.util.Iterator; 196 import java.util.List; 197 import java.util.Locale; 198 import java.util.Map; 199 import java.util.Set; 200 import java.util.concurrent.atomic.AtomicBoolean; 201 import java.util.concurrent.atomic.AtomicLong; 202 203 public final class ActivityManagerService extends ActivityManagerNative 204 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 205 private static final String USER_DATA_DIR = "/data/user/"; 206 static final String TAG = "ActivityManager"; 207 static final String TAG_MU = "ActivityManagerServiceMU"; 208 static final boolean DEBUG = false; 209 static final boolean localLOGV = DEBUG; 210 static final boolean DEBUG_BACKUP = localLOGV || false; 211 static final boolean DEBUG_BROADCAST = localLOGV || false; 212 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 213 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 214 static final boolean DEBUG_CLEANUP = localLOGV || false; 215 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 216 static final boolean DEBUG_FOCUS = false; 217 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 218 static final boolean DEBUG_MU = localLOGV || false; 219 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 220 static final boolean DEBUG_LRU = localLOGV || false; 221 static final boolean DEBUG_PAUSE = localLOGV || false; 222 static final boolean DEBUG_POWER = localLOGV || false; 223 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 224 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 225 static final boolean DEBUG_PROCESSES = localLOGV || false; 226 static final boolean DEBUG_PROVIDER = localLOGV || false; 227 static final boolean DEBUG_RESULTS = localLOGV || false; 228 static final boolean DEBUG_SERVICE = localLOGV || false; 229 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 230 static final boolean DEBUG_STACK = localLOGV || false; 231 static final boolean DEBUG_SWITCH = localLOGV || false; 232 static final boolean DEBUG_TASKS = localLOGV || false; 233 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 234 static final boolean DEBUG_TRANSITION = localLOGV || false; 235 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 236 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 237 static final boolean DEBUG_VISBILITY = localLOGV || false; 238 static final boolean DEBUG_PSS = localLOGV || false; 239 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 240 static final boolean VALIDATE_TOKENS = false; 241 static final boolean SHOW_ACTIVITY_START_TIME = true; 242 243 // Control over CPU and battery monitoring. 244 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 245 static final boolean MONITOR_CPU_USAGE = true; 246 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 247 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 248 static final boolean MONITOR_THREAD_CPU_USAGE = false; 249 250 // The flags that are set for all calls we make to the package manager. 251 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 252 253 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 254 255 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 256 257 // Maximum number of recent tasks that we can remember. 258 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 259 260 // Amount of time after a call to stopAppSwitches() during which we will 261 // prevent further untrusted switches from happening. 262 static final long APP_SWITCH_DELAY_TIME = 5*1000; 263 264 // How long we wait for a launched process to attach to the activity manager 265 // before we decide it's never going to come up for real. 266 static final int PROC_START_TIMEOUT = 10*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real, when the process was 270 // started with a wrapper for instrumentation (such as Valgrind) because it 271 // could take much longer than usual. 272 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 273 274 // How long to wait after going idle before forcing apps to GC. 275 static final int GC_TIMEOUT = 5*1000; 276 277 // The minimum amount of time between successive GC requests for a process. 278 static final int GC_MIN_INTERVAL = 60*1000; 279 280 // The minimum amount of time between successive PSS requests for a process. 281 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 282 283 // The minimum amount of time between successive PSS requests for a process 284 // when the request is due to the memory state being lowered. 285 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 286 287 // The rate at which we check for apps using excessive power -- 15 mins. 288 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 289 290 // The minimum sample duration we will allow before deciding we have 291 // enough data on wake locks to start killing things. 292 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on CPU usage to start killing things. 296 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // How long we allow a receiver to run before giving up on it. 299 static final int BROADCAST_FG_TIMEOUT = 10*1000; 300 static final int BROADCAST_BG_TIMEOUT = 60*1000; 301 302 // How long we wait until we timeout on key dispatching. 303 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 304 305 // How long we wait until we timeout on key dispatching during instrumentation. 306 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 307 308 // Amount of time we wait for observers to handle a user switch before 309 // giving up on them and unfreezing the screen. 310 static final int USER_SWITCH_TIMEOUT = 2*1000; 311 312 // Maximum number of users we allow to be running at a time. 313 static final int MAX_RUNNING_USERS = 3; 314 315 // How long to wait in getAssistContextExtras for the activity and foreground services 316 // to respond with the result. 317 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 318 319 // Maximum number of persisted Uri grants a package is allowed 320 static final int MAX_PERSISTED_URI_GRANTS = 128; 321 322 static final int MY_PID = Process.myPid(); 323 324 static final String[] EMPTY_STRING_ARRAY = new String[0]; 325 326 // How many bytes to write into the dropbox log before truncating 327 static final int DROPBOX_MAX_SIZE = 256 * 1024; 328 329 /** Run all ActivityStacks through this */ 330 ActivityStackSupervisor mStackSupervisor; 331 332 public IntentFirewall mIntentFirewall; 333 334 private final boolean mHeadless; 335 336 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 337 // default actuion automatically. Important for devices without direct input 338 // devices. 339 private boolean mShowDialogs = true; 340 341 /** 342 * Description of a request to start a new activity, which has been held 343 * due to app switches being disabled. 344 */ 345 static class PendingActivityLaunch { 346 final ActivityRecord r; 347 final ActivityRecord sourceRecord; 348 final int startFlags; 349 final ActivityStack stack; 350 351 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 352 int _startFlags, ActivityStack _stack) { 353 r = _r; 354 sourceRecord = _sourceRecord; 355 startFlags = _startFlags; 356 stack = _stack; 357 } 358 } 359 360 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 361 = new ArrayList<PendingActivityLaunch>(); 362 363 BroadcastQueue mFgBroadcastQueue; 364 BroadcastQueue mBgBroadcastQueue; 365 // Convenient for easy iteration over the queues. Foreground is first 366 // so that dispatch of foreground broadcasts gets precedence. 367 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 368 369 BroadcastQueue broadcastQueueForIntent(Intent intent) { 370 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 371 if (DEBUG_BACKGROUND_BROADCAST) { 372 Slog.i(TAG, "Broadcast intent " + intent + " on " 373 + (isFg ? "foreground" : "background") 374 + " queue"); 375 } 376 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 377 } 378 379 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 380 for (BroadcastQueue queue : mBroadcastQueues) { 381 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 382 if (r != null) { 383 return r; 384 } 385 } 386 return null; 387 } 388 389 /** 390 * Activity we have told the window manager to have key focus. 391 */ 392 ActivityRecord mFocusedActivity = null; 393 394 /** 395 * List of intents that were used to start the most recent tasks. 396 */ 397 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 398 399 public class PendingAssistExtras extends Binder implements Runnable { 400 public final ActivityRecord activity; 401 public boolean haveResult = false; 402 public Bundle result = null; 403 public PendingAssistExtras(ActivityRecord _activity) { 404 activity = _activity; 405 } 406 @Override 407 public void run() { 408 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 409 synchronized (this) { 410 haveResult = true; 411 notifyAll(); 412 } 413 } 414 } 415 416 final ArrayList<PendingAssistExtras> mPendingAssistExtras 417 = new ArrayList<PendingAssistExtras>(); 418 419 /** 420 * Process management. 421 */ 422 final ProcessList mProcessList = new ProcessList(); 423 424 /** 425 * All of the applications we currently have running organized by name. 426 * The keys are strings of the application package name (as 427 * returned by the package manager), and the keys are ApplicationRecord 428 * objects. 429 */ 430 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 431 432 /** 433 * Tracking long-term execution of processes to look for abuse and other 434 * bad app behavior. 435 */ 436 final ProcessStatsService mProcessStats; 437 438 /** 439 * The currently running isolated processes. 440 */ 441 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 442 443 /** 444 * Counter for assigning isolated process uids, to avoid frequently reusing the 445 * same ones. 446 */ 447 int mNextIsolatedProcessUid = 0; 448 449 /** 450 * The currently running heavy-weight process, if any. 451 */ 452 ProcessRecord mHeavyWeightProcess = null; 453 454 /** 455 * The last time that various processes have crashed. 456 */ 457 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 458 459 /** 460 * Information about a process that is currently marked as bad. 461 */ 462 static final class BadProcessInfo { 463 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 464 this.time = time; 465 this.shortMsg = shortMsg; 466 this.longMsg = longMsg; 467 this.stack = stack; 468 } 469 470 final long time; 471 final String shortMsg; 472 final String longMsg; 473 final String stack; 474 } 475 476 /** 477 * Set of applications that we consider to be bad, and will reject 478 * incoming broadcasts from (which the user has no control over). 479 * Processes are added to this set when they have crashed twice within 480 * a minimum amount of time; they are removed from it when they are 481 * later restarted (hopefully due to some user action). The value is the 482 * time it was added to the list. 483 */ 484 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 485 486 /** 487 * All of the processes we currently have running organized by pid. 488 * The keys are the pid running the application. 489 * 490 * <p>NOTE: This object is protected by its own lock, NOT the global 491 * activity manager lock! 492 */ 493 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 494 495 /** 496 * All of the processes that have been forced to be foreground. The key 497 * is the pid of the caller who requested it (we hold a death 498 * link on it). 499 */ 500 abstract class ForegroundToken implements IBinder.DeathRecipient { 501 int pid; 502 IBinder token; 503 } 504 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 505 506 /** 507 * List of records for processes that someone had tried to start before the 508 * system was ready. We don't start them at that point, but ensure they 509 * are started by the time booting is complete. 510 */ 511 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 512 513 /** 514 * List of persistent applications that are in the process 515 * of being started. 516 */ 517 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 518 519 /** 520 * Processes that are being forcibly torn down. 521 */ 522 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 523 524 /** 525 * List of running applications, sorted by recent usage. 526 * The first entry in the list is the least recently used. 527 */ 528 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 529 530 /** 531 * Where in mLruProcesses that the processes hosting activities start. 532 */ 533 int mLruProcessActivityStart = 0; 534 535 /** 536 * Where in mLruProcesses that the processes hosting services start. 537 * This is after (lower index) than mLruProcessesActivityStart. 538 */ 539 int mLruProcessServiceStart = 0; 540 541 /** 542 * List of processes that should gc as soon as things are idle. 543 */ 544 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 545 546 /** 547 * Processes we want to collect PSS data from. 548 */ 549 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 550 551 /** 552 * Last time we requested PSS data of all processes. 553 */ 554 long mLastFullPssTime = SystemClock.uptimeMillis(); 555 556 /** 557 * This is the process holding what we currently consider to be 558 * the "home" activity. 559 */ 560 ProcessRecord mHomeProcess; 561 562 /** 563 * This is the process holding the activity the user last visited that 564 * is in a different process from the one they are currently in. 565 */ 566 ProcessRecord mPreviousProcess; 567 568 /** 569 * The time at which the previous process was last visible. 570 */ 571 long mPreviousProcessVisibleTime; 572 573 /** 574 * Which uses have been started, so are allowed to run code. 575 */ 576 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 577 578 /** 579 * LRU list of history of current users. Most recently current is at the end. 580 */ 581 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 582 583 /** 584 * Constant array of the users that are currently started. 585 */ 586 int[] mStartedUserArray = new int[] { 0 }; 587 588 /** 589 * Registered observers of the user switching mechanics. 590 */ 591 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 592 = new RemoteCallbackList<IUserSwitchObserver>(); 593 594 /** 595 * Currently active user switch. 596 */ 597 Object mCurUserSwitchCallback; 598 599 /** 600 * Packages that the user has asked to have run in screen size 601 * compatibility mode instead of filling the screen. 602 */ 603 final CompatModePackages mCompatModePackages; 604 605 /** 606 * Set of IntentSenderRecord objects that are currently active. 607 */ 608 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 609 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 610 611 /** 612 * Fingerprints (hashCode()) of stack traces that we've 613 * already logged DropBox entries for. Guarded by itself. If 614 * something (rogue user app) forces this over 615 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 616 */ 617 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 618 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 619 620 /** 621 * Strict Mode background batched logging state. 622 * 623 * The string buffer is guarded by itself, and its lock is also 624 * used to determine if another batched write is already 625 * in-flight. 626 */ 627 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 628 629 /** 630 * Keeps track of all IIntentReceivers that have been registered for 631 * broadcasts. Hash keys are the receiver IBinder, hash value is 632 * a ReceiverList. 633 */ 634 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 635 new HashMap<IBinder, ReceiverList>(); 636 637 /** 638 * Resolver for broadcast intents to registered receivers. 639 * Holds BroadcastFilter (subclass of IntentFilter). 640 */ 641 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 642 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 643 @Override 644 protected boolean allowFilterResult( 645 BroadcastFilter filter, List<BroadcastFilter> dest) { 646 IBinder target = filter.receiverList.receiver.asBinder(); 647 for (int i=dest.size()-1; i>=0; i--) { 648 if (dest.get(i).receiverList.receiver.asBinder() == target) { 649 return false; 650 } 651 } 652 return true; 653 } 654 655 @Override 656 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 657 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 658 || userId == filter.owningUserId) { 659 return super.newResult(filter, match, userId); 660 } 661 return null; 662 } 663 664 @Override 665 protected BroadcastFilter[] newArray(int size) { 666 return new BroadcastFilter[size]; 667 } 668 669 @Override 670 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 671 return packageName.equals(filter.packageName); 672 } 673 }; 674 675 /** 676 * State of all active sticky broadcasts per user. Keys are the action of the 677 * sticky Intent, values are an ArrayList of all broadcasted intents with 678 * that action (which should usually be one). The SparseArray is keyed 679 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 680 * for stickies that are sent to all users. 681 */ 682 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 683 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 684 685 final ActiveServices mServices; 686 687 /** 688 * Backup/restore process management 689 */ 690 String mBackupAppName = null; 691 BackupRecord mBackupTarget = null; 692 693 /** 694 * List of PendingThumbnailsRecord objects of clients who are still 695 * waiting to receive all of the thumbnails for a task. 696 */ 697 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 698 new ArrayList<PendingThumbnailsRecord>(); 699 700 final ProviderMap mProviderMap; 701 702 /** 703 * List of content providers who have clients waiting for them. The 704 * application is currently being launched and the provider will be 705 * removed from this list once it is published. 706 */ 707 final ArrayList<ContentProviderRecord> mLaunchingProviders 708 = new ArrayList<ContentProviderRecord>(); 709 710 /** 711 * File storing persisted {@link #mGrantedUriPermissions}. 712 */ 713 private final AtomicFile mGrantFile; 714 715 /** XML constants used in {@link #mGrantFile} */ 716 private static final String TAG_URI_GRANTS = "uri-grants"; 717 private static final String TAG_URI_GRANT = "uri-grant"; 718 private static final String ATTR_USER_HANDLE = "userHandle"; 719 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 720 private static final String ATTR_TARGET_PKG = "targetPkg"; 721 private static final String ATTR_URI = "uri"; 722 private static final String ATTR_MODE_FLAGS = "modeFlags"; 723 private static final String ATTR_CREATED_TIME = "createdTime"; 724 725 /** 726 * Global set of specific {@link Uri} permissions that have been granted. 727 * This optimized lookup structure maps from {@link UriPermission#targetUid} 728 * to {@link UriPermission#uri} to {@link UriPermission}. 729 */ 730 @GuardedBy("this") 731 private final SparseArray<ArrayMap<Uri, UriPermission>> 732 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 733 734 CoreSettingsObserver mCoreSettingsObserver; 735 736 /** 737 * Thread-local storage used to carry caller permissions over through 738 * indirect content-provider access. 739 */ 740 private class Identity { 741 public int pid; 742 public int uid; 743 744 Identity(int _pid, int _uid) { 745 pid = _pid; 746 uid = _uid; 747 } 748 } 749 750 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 751 752 /** 753 * All information we have collected about the runtime performance of 754 * any user id that can impact battery performance. 755 */ 756 final BatteryStatsService mBatteryStatsService; 757 758 /** 759 * Information about component usage 760 */ 761 final UsageStatsService mUsageStatsService; 762 763 /** 764 * Information about and control over application operations 765 */ 766 final AppOpsService mAppOpsService; 767 768 /** 769 * Current configuration information. HistoryRecord objects are given 770 * a reference to this object to indicate which configuration they are 771 * currently running in, so this object must be kept immutable. 772 */ 773 Configuration mConfiguration = new Configuration(); 774 775 /** 776 * Current sequencing integer of the configuration, for skipping old 777 * configurations. 778 */ 779 int mConfigurationSeq = 0; 780 781 /** 782 * Hardware-reported OpenGLES version. 783 */ 784 final int GL_ES_VERSION; 785 786 /** 787 * List of initialization arguments to pass to all processes when binding applications to them. 788 * For example, references to the commonly used services. 789 */ 790 HashMap<String, IBinder> mAppBindArgs; 791 792 /** 793 * Temporary to avoid allocations. Protected by main lock. 794 */ 795 final StringBuilder mStringBuilder = new StringBuilder(256); 796 797 /** 798 * Used to control how we initialize the service. 799 */ 800 boolean mStartRunning = false; 801 ComponentName mTopComponent; 802 String mTopAction; 803 String mTopData; 804 boolean mProcessesReady = false; 805 boolean mSystemReady = false; 806 boolean mBooting = false; 807 boolean mWaitingUpdate = false; 808 boolean mDidUpdate = false; 809 boolean mOnBattery = false; 810 boolean mLaunchWarningShown = false; 811 812 Context mContext; 813 814 int mFactoryTest; 815 816 boolean mCheckedForSetup; 817 818 /** 819 * The time at which we will allow normal application switches again, 820 * after a call to {@link #stopAppSwitches()}. 821 */ 822 long mAppSwitchesAllowedTime; 823 824 /** 825 * This is set to true after the first switch after mAppSwitchesAllowedTime 826 * is set; any switches after that will clear the time. 827 */ 828 boolean mDidAppSwitch; 829 830 /** 831 * Last time (in realtime) at which we checked for power usage. 832 */ 833 long mLastPowerCheckRealtime; 834 835 /** 836 * Last time (in uptime) at which we checked for power usage. 837 */ 838 long mLastPowerCheckUptime; 839 840 /** 841 * Set while we are wanting to sleep, to prevent any 842 * activities from being started/resumed. 843 */ 844 boolean mSleeping = false; 845 846 /** 847 * State of external calls telling us if the device is asleep. 848 */ 849 boolean mWentToSleep = false; 850 851 /** 852 * State of external call telling us if the lock screen is shown. 853 */ 854 boolean mLockScreenShown = false; 855 856 /** 857 * Set if we are shutting down the system, similar to sleeping. 858 */ 859 boolean mShuttingDown = false; 860 861 /** 862 * Current sequence id for oom_adj computation traversal. 863 */ 864 int mAdjSeq = 0; 865 866 /** 867 * Current sequence id for process LRU updating. 868 */ 869 int mLruSeq = 0; 870 871 /** 872 * Keep track of the non-cached/empty process we last found, to help 873 * determine how to distribute cached/empty processes next time. 874 */ 875 int mNumNonCachedProcs = 0; 876 877 /** 878 * Keep track of the number of cached hidden procs, to balance oom adj 879 * distribution between those and empty procs. 880 */ 881 int mNumCachedHiddenProcs = 0; 882 883 /** 884 * Keep track of the number of service processes we last found, to 885 * determine on the next iteration which should be B services. 886 */ 887 int mNumServiceProcs = 0; 888 int mNewNumAServiceProcs = 0; 889 int mNewNumServiceProcs = 0; 890 891 /** 892 * Allow the current computed overall memory level of the system to go down? 893 * This is set to false when we are killing processes for reasons other than 894 * memory management, so that the now smaller process list will not be taken as 895 * an indication that memory is tighter. 896 */ 897 boolean mAllowLowerMemLevel = false; 898 899 /** 900 * The last computed memory level, for holding when we are in a state that 901 * processes are going away for other reasons. 902 */ 903 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 904 905 /** 906 * The last total number of process we have, to determine if changes actually look 907 * like a shrinking number of process due to lower RAM. 908 */ 909 int mLastNumProcesses; 910 911 /** 912 * The uptime of the last time we performed idle maintenance. 913 */ 914 long mLastIdleTime = SystemClock.uptimeMillis(); 915 916 /** 917 * Total time spent with RAM that has been added in the past since the last idle time. 918 */ 919 long mLowRamTimeSinceLastIdle = 0; 920 921 /** 922 * If RAM is currently low, when that horrible situatin started. 923 */ 924 long mLowRamStartTime = 0; 925 926 /** 927 * This is set if we had to do a delayed dexopt of an app before launching 928 * it, to increasing the ANR timeouts in that case. 929 */ 930 boolean mDidDexOpt; 931 932 String mDebugApp = null; 933 boolean mWaitForDebugger = false; 934 boolean mDebugTransient = false; 935 String mOrigDebugApp = null; 936 boolean mOrigWaitForDebugger = false; 937 boolean mAlwaysFinishActivities = false; 938 IActivityController mController = null; 939 String mProfileApp = null; 940 ProcessRecord mProfileProc = null; 941 String mProfileFile; 942 ParcelFileDescriptor mProfileFd; 943 int mProfileType = 0; 944 boolean mAutoStopProfiler = false; 945 String mOpenGlTraceApp = null; 946 947 static class ProcessChangeItem { 948 static final int CHANGE_ACTIVITIES = 1<<0; 949 static final int CHANGE_IMPORTANCE= 1<<1; 950 int changes; 951 int uid; 952 int pid; 953 int importance; 954 boolean foregroundActivities; 955 } 956 957 final RemoteCallbackList<IProcessObserver> mProcessObservers 958 = new RemoteCallbackList<IProcessObserver>(); 959 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 960 961 final ArrayList<ProcessChangeItem> mPendingProcessChanges 962 = new ArrayList<ProcessChangeItem>(); 963 final ArrayList<ProcessChangeItem> mAvailProcessChanges 964 = new ArrayList<ProcessChangeItem>(); 965 966 /** 967 * Runtime CPU use collection thread. This object's lock is used to 968 * protect all related state. 969 */ 970 final Thread mProcessCpuThread; 971 972 /** 973 * Used to collect process stats when showing not responding dialog. 974 * Protected by mProcessCpuThread. 975 */ 976 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 977 MONITOR_THREAD_CPU_USAGE); 978 final AtomicLong mLastCpuTime = new AtomicLong(0); 979 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 980 981 long mLastWriteTime = 0; 982 983 /** 984 * Used to retain an update lock when the foreground activity is in 985 * immersive mode. 986 */ 987 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 988 989 /** 990 * Set to true after the system has finished booting. 991 */ 992 boolean mBooted = false; 993 994 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 995 int mProcessLimitOverride = -1; 996 997 WindowManagerService mWindowManager; 998 999 static ActivityManagerService mSelf; 1000 static ActivityThread mSystemThread; 1001 1002 int mCurrentUserId = 0; 1003 private UserManagerService mUserManager; 1004 1005 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1006 final ProcessRecord mApp; 1007 final int mPid; 1008 final IApplicationThread mAppThread; 1009 1010 AppDeathRecipient(ProcessRecord app, int pid, 1011 IApplicationThread thread) { 1012 if (localLOGV) Slog.v( 1013 TAG, "New death recipient " + this 1014 + " for thread " + thread.asBinder()); 1015 mApp = app; 1016 mPid = pid; 1017 mAppThread = thread; 1018 } 1019 1020 @Override 1021 public void binderDied() { 1022 if (localLOGV) Slog.v( 1023 TAG, "Death received in " + this 1024 + " for thread " + mAppThread.asBinder()); 1025 synchronized(ActivityManagerService.this) { 1026 appDiedLocked(mApp, mPid, mAppThread); 1027 } 1028 } 1029 } 1030 1031 static final int SHOW_ERROR_MSG = 1; 1032 static final int SHOW_NOT_RESPONDING_MSG = 2; 1033 static final int SHOW_FACTORY_ERROR_MSG = 3; 1034 static final int UPDATE_CONFIGURATION_MSG = 4; 1035 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1036 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1037 static final int SERVICE_TIMEOUT_MSG = 12; 1038 static final int UPDATE_TIME_ZONE = 13; 1039 static final int SHOW_UID_ERROR_MSG = 14; 1040 static final int IM_FEELING_LUCKY_MSG = 15; 1041 static final int PROC_START_TIMEOUT_MSG = 20; 1042 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1043 static final int KILL_APPLICATION_MSG = 22; 1044 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1045 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1046 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1047 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1048 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1049 static final int CLEAR_DNS_CACHE_MSG = 28; 1050 static final int UPDATE_HTTP_PROXY_MSG = 29; 1051 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1052 static final int DISPATCH_PROCESSES_CHANGED = 31; 1053 static final int DISPATCH_PROCESS_DIED = 32; 1054 static final int REPORT_MEM_USAGE_MSG = 33; 1055 static final int REPORT_USER_SWITCH_MSG = 34; 1056 static final int CONTINUE_USER_SWITCH_MSG = 35; 1057 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1058 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1059 static final int PERSIST_URI_GRANTS_MSG = 38; 1060 static final int REQUEST_ALL_PSS_MSG = 39; 1061 1062 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1063 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1064 static final int FIRST_COMPAT_MODE_MSG = 300; 1065 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1066 1067 AlertDialog mUidAlert; 1068 CompatModeDialog mCompatModeDialog; 1069 long mLastMemUsageReportTime = 0; 1070 1071 /** 1072 * Flag whether the current user is a "monkey", i.e. whether 1073 * the UI is driven by a UI automation tool. 1074 */ 1075 private boolean mUserIsMonkey; 1076 1077 final Handler mHandler = new Handler() { 1078 //public Handler() { 1079 // if (localLOGV) Slog.v(TAG, "Handler started!"); 1080 //} 1081 1082 @Override 1083 public void handleMessage(Message msg) { 1084 switch (msg.what) { 1085 case SHOW_ERROR_MSG: { 1086 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1087 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1088 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1089 synchronized (ActivityManagerService.this) { 1090 ProcessRecord proc = (ProcessRecord)data.get("app"); 1091 AppErrorResult res = (AppErrorResult) data.get("result"); 1092 if (proc != null && proc.crashDialog != null) { 1093 Slog.e(TAG, "App already has crash dialog: " + proc); 1094 if (res != null) { 1095 res.set(0); 1096 } 1097 return; 1098 } 1099 if (!showBackground && UserHandle.getAppId(proc.uid) 1100 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1101 && proc.pid != MY_PID) { 1102 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1103 if (res != null) { 1104 res.set(0); 1105 } 1106 return; 1107 } 1108 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1109 Dialog d = new AppErrorDialog(mContext, 1110 ActivityManagerService.this, res, proc); 1111 d.show(); 1112 proc.crashDialog = d; 1113 } else { 1114 // The device is asleep, so just pretend that the user 1115 // saw a crash dialog and hit "force quit". 1116 if (res != null) { 1117 res.set(0); 1118 } 1119 } 1120 } 1121 1122 ensureBootCompleted(); 1123 } break; 1124 case SHOW_NOT_RESPONDING_MSG: { 1125 synchronized (ActivityManagerService.this) { 1126 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1127 ProcessRecord proc = (ProcessRecord)data.get("app"); 1128 if (proc != null && proc.anrDialog != null) { 1129 Slog.e(TAG, "App already has anr dialog: " + proc); 1130 return; 1131 } 1132 1133 Intent intent = new Intent("android.intent.action.ANR"); 1134 if (!mProcessesReady) { 1135 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1136 | Intent.FLAG_RECEIVER_FOREGROUND); 1137 } 1138 broadcastIntentLocked(null, null, intent, 1139 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1140 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1141 1142 if (mShowDialogs) { 1143 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1144 mContext, proc, (ActivityRecord)data.get("activity"), 1145 msg.arg1 != 0); 1146 d.show(); 1147 proc.anrDialog = d; 1148 } else { 1149 // Just kill the app if there is no dialog to be shown. 1150 killAppAtUsersRequest(proc, null); 1151 } 1152 } 1153 1154 ensureBootCompleted(); 1155 } break; 1156 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1157 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1158 synchronized (ActivityManagerService.this) { 1159 ProcessRecord proc = (ProcessRecord) data.get("app"); 1160 if (proc == null) { 1161 Slog.e(TAG, "App not found when showing strict mode dialog."); 1162 break; 1163 } 1164 if (proc.crashDialog != null) { 1165 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1166 return; 1167 } 1168 AppErrorResult res = (AppErrorResult) data.get("result"); 1169 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1170 Dialog d = new StrictModeViolationDialog(mContext, 1171 ActivityManagerService.this, res, proc); 1172 d.show(); 1173 proc.crashDialog = d; 1174 } else { 1175 // The device is asleep, so just pretend that the user 1176 // saw a crash dialog and hit "force quit". 1177 res.set(0); 1178 } 1179 } 1180 ensureBootCompleted(); 1181 } break; 1182 case SHOW_FACTORY_ERROR_MSG: { 1183 Dialog d = new FactoryErrorDialog( 1184 mContext, msg.getData().getCharSequence("msg")); 1185 d.show(); 1186 ensureBootCompleted(); 1187 } break; 1188 case UPDATE_CONFIGURATION_MSG: { 1189 final ContentResolver resolver = mContext.getContentResolver(); 1190 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1191 } break; 1192 case GC_BACKGROUND_PROCESSES_MSG: { 1193 synchronized (ActivityManagerService.this) { 1194 performAppGcsIfAppropriateLocked(); 1195 } 1196 } break; 1197 case WAIT_FOR_DEBUGGER_MSG: { 1198 synchronized (ActivityManagerService.this) { 1199 ProcessRecord app = (ProcessRecord)msg.obj; 1200 if (msg.arg1 != 0) { 1201 if (!app.waitedForDebugger) { 1202 Dialog d = new AppWaitingForDebuggerDialog( 1203 ActivityManagerService.this, 1204 mContext, app); 1205 app.waitDialog = d; 1206 app.waitedForDebugger = true; 1207 d.show(); 1208 } 1209 } else { 1210 if (app.waitDialog != null) { 1211 app.waitDialog.dismiss(); 1212 app.waitDialog = null; 1213 } 1214 } 1215 } 1216 } break; 1217 case SERVICE_TIMEOUT_MSG: { 1218 if (mDidDexOpt) { 1219 mDidDexOpt = false; 1220 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1221 nmsg.obj = msg.obj; 1222 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1223 return; 1224 } 1225 mServices.serviceTimeout((ProcessRecord)msg.obj); 1226 } break; 1227 case UPDATE_TIME_ZONE: { 1228 synchronized (ActivityManagerService.this) { 1229 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1230 ProcessRecord r = mLruProcesses.get(i); 1231 if (r.thread != null) { 1232 try { 1233 r.thread.updateTimeZone(); 1234 } catch (RemoteException ex) { 1235 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1236 } 1237 } 1238 } 1239 } 1240 } break; 1241 case CLEAR_DNS_CACHE_MSG: { 1242 synchronized (ActivityManagerService.this) { 1243 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1244 ProcessRecord r = mLruProcesses.get(i); 1245 if (r.thread != null) { 1246 try { 1247 r.thread.clearDnsCache(); 1248 } catch (RemoteException ex) { 1249 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1250 } 1251 } 1252 } 1253 } 1254 } break; 1255 case UPDATE_HTTP_PROXY_MSG: { 1256 ProxyProperties proxy = (ProxyProperties)msg.obj; 1257 String host = ""; 1258 String port = ""; 1259 String exclList = ""; 1260 String pacFileUrl = null; 1261 if (proxy != null) { 1262 host = proxy.getHost(); 1263 port = Integer.toString(proxy.getPort()); 1264 exclList = proxy.getExclusionList(); 1265 pacFileUrl = proxy.getPacFileUrl(); 1266 } 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.setHttpProxy(host, port, exclList, pacFileUrl); 1273 } catch (RemoteException ex) { 1274 Slog.w(TAG, "Failed to update http proxy for: " + 1275 r.info.processName); 1276 } 1277 } 1278 } 1279 } 1280 } break; 1281 case SHOW_UID_ERROR_MSG: { 1282 String title = "System UIDs Inconsistent"; 1283 String text = "UIDs on the system are inconsistent, you need to wipe your" 1284 + " data partition or your device will be unstable."; 1285 Log.e(TAG, title + ": " + text); 1286 if (mShowDialogs) { 1287 // XXX This is a temporary dialog, no need to localize. 1288 AlertDialog d = new BaseErrorDialog(mContext); 1289 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1290 d.setCancelable(false); 1291 d.setTitle(title); 1292 d.setMessage(text); 1293 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1294 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1295 mUidAlert = d; 1296 d.show(); 1297 } 1298 } break; 1299 case IM_FEELING_LUCKY_MSG: { 1300 if (mUidAlert != null) { 1301 mUidAlert.dismiss(); 1302 mUidAlert = null; 1303 } 1304 } break; 1305 case PROC_START_TIMEOUT_MSG: { 1306 if (mDidDexOpt) { 1307 mDidDexOpt = false; 1308 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1309 nmsg.obj = msg.obj; 1310 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1311 return; 1312 } 1313 ProcessRecord app = (ProcessRecord)msg.obj; 1314 synchronized (ActivityManagerService.this) { 1315 processStartTimedOutLocked(app); 1316 } 1317 } break; 1318 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1319 synchronized (ActivityManagerService.this) { 1320 doPendingActivityLaunchesLocked(true); 1321 } 1322 } break; 1323 case KILL_APPLICATION_MSG: { 1324 synchronized (ActivityManagerService.this) { 1325 int appid = msg.arg1; 1326 boolean restart = (msg.arg2 == 1); 1327 Bundle bundle = (Bundle)msg.obj; 1328 String pkg = bundle.getString("pkg"); 1329 String reason = bundle.getString("reason"); 1330 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1331 UserHandle.USER_ALL, reason); 1332 } 1333 } break; 1334 case FINALIZE_PENDING_INTENT_MSG: { 1335 ((PendingIntentRecord)msg.obj).completeFinalize(); 1336 } break; 1337 case POST_HEAVY_NOTIFICATION_MSG: { 1338 INotificationManager inm = NotificationManager.getService(); 1339 if (inm == null) { 1340 return; 1341 } 1342 1343 ActivityRecord root = (ActivityRecord)msg.obj; 1344 ProcessRecord process = root.app; 1345 if (process == null) { 1346 return; 1347 } 1348 1349 try { 1350 Context context = mContext.createPackageContext(process.info.packageName, 0); 1351 String text = mContext.getString(R.string.heavy_weight_notification, 1352 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1353 Notification notification = new Notification(); 1354 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1355 notification.when = 0; 1356 notification.flags = Notification.FLAG_ONGOING_EVENT; 1357 notification.tickerText = text; 1358 notification.defaults = 0; // please be quiet 1359 notification.sound = null; 1360 notification.vibrate = null; 1361 notification.setLatestEventInfo(context, text, 1362 mContext.getText(R.string.heavy_weight_notification_detail), 1363 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1364 PendingIntent.FLAG_CANCEL_CURRENT, null, 1365 new UserHandle(root.userId))); 1366 1367 try { 1368 int[] outId = new int[1]; 1369 inm.enqueueNotificationWithTag("android", "android", null, 1370 R.string.heavy_weight_notification, 1371 notification, outId, root.userId); 1372 } catch (RuntimeException e) { 1373 Slog.w(ActivityManagerService.TAG, 1374 "Error showing notification for heavy-weight app", e); 1375 } catch (RemoteException e) { 1376 } 1377 } catch (NameNotFoundException e) { 1378 Slog.w(TAG, "Unable to create context for heavy notification", e); 1379 } 1380 } break; 1381 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1382 INotificationManager inm = NotificationManager.getService(); 1383 if (inm == null) { 1384 return; 1385 } 1386 try { 1387 inm.cancelNotificationWithTag("android", null, 1388 R.string.heavy_weight_notification, msg.arg1); 1389 } catch (RuntimeException e) { 1390 Slog.w(ActivityManagerService.TAG, 1391 "Error canceling notification for service", e); 1392 } catch (RemoteException e) { 1393 } 1394 } break; 1395 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1396 synchronized (ActivityManagerService.this) { 1397 checkExcessivePowerUsageLocked(true); 1398 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1399 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1400 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1401 } 1402 } break; 1403 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1404 synchronized (ActivityManagerService.this) { 1405 ActivityRecord ar = (ActivityRecord)msg.obj; 1406 if (mCompatModeDialog != null) { 1407 if (mCompatModeDialog.mAppInfo.packageName.equals( 1408 ar.info.applicationInfo.packageName)) { 1409 return; 1410 } 1411 mCompatModeDialog.dismiss(); 1412 mCompatModeDialog = null; 1413 } 1414 if (ar != null && false) { 1415 if (mCompatModePackages.getPackageAskCompatModeLocked( 1416 ar.packageName)) { 1417 int mode = mCompatModePackages.computeCompatModeLocked( 1418 ar.info.applicationInfo); 1419 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1420 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1421 mCompatModeDialog = new CompatModeDialog( 1422 ActivityManagerService.this, mContext, 1423 ar.info.applicationInfo); 1424 mCompatModeDialog.show(); 1425 } 1426 } 1427 } 1428 } 1429 break; 1430 } 1431 case DISPATCH_PROCESSES_CHANGED: { 1432 dispatchProcessesChanged(); 1433 break; 1434 } 1435 case DISPATCH_PROCESS_DIED: { 1436 final int pid = msg.arg1; 1437 final int uid = msg.arg2; 1438 dispatchProcessDied(pid, uid); 1439 break; 1440 } 1441 case REPORT_MEM_USAGE_MSG: { 1442 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1443 Thread thread = new Thread() { 1444 @Override public void run() { 1445 final SparseArray<ProcessMemInfo> infoMap 1446 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1447 for (int i=0, N=memInfos.size(); i<N; i++) { 1448 ProcessMemInfo mi = memInfos.get(i); 1449 infoMap.put(mi.pid, mi); 1450 } 1451 updateCpuStatsNow(); 1452 synchronized (mProcessCpuThread) { 1453 final int N = mProcessCpuTracker.countStats(); 1454 for (int i=0; i<N; i++) { 1455 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1456 if (st.vsize > 0) { 1457 long pss = Debug.getPss(st.pid, null); 1458 if (pss > 0) { 1459 if (infoMap.indexOfKey(st.pid) < 0) { 1460 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1461 ProcessList.NATIVE_ADJ, -1, "native", null); 1462 mi.pss = pss; 1463 memInfos.add(mi); 1464 } 1465 } 1466 } 1467 } 1468 } 1469 1470 long totalPss = 0; 1471 for (int i=0, N=memInfos.size(); i<N; i++) { 1472 ProcessMemInfo mi = memInfos.get(i); 1473 if (mi.pss == 0) { 1474 mi.pss = Debug.getPss(mi.pid, null); 1475 } 1476 totalPss += mi.pss; 1477 } 1478 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1479 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1480 if (lhs.oomAdj != rhs.oomAdj) { 1481 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1482 } 1483 if (lhs.pss != rhs.pss) { 1484 return lhs.pss < rhs.pss ? 1 : -1; 1485 } 1486 return 0; 1487 } 1488 }); 1489 1490 StringBuilder tag = new StringBuilder(128); 1491 StringBuilder stack = new StringBuilder(128); 1492 tag.append("Low on memory -- "); 1493 appendMemBucket(tag, totalPss, "total", false); 1494 appendMemBucket(stack, totalPss, "total", true); 1495 1496 StringBuilder logBuilder = new StringBuilder(1024); 1497 logBuilder.append("Low on memory:\n"); 1498 1499 boolean firstLine = true; 1500 int lastOomAdj = Integer.MIN_VALUE; 1501 for (int i=0, N=memInfos.size(); i<N; i++) { 1502 ProcessMemInfo mi = memInfos.get(i); 1503 1504 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1505 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1506 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1507 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1508 if (lastOomAdj != mi.oomAdj) { 1509 lastOomAdj = mi.oomAdj; 1510 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1511 tag.append(" / "); 1512 } 1513 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1514 if (firstLine) { 1515 stack.append(":"); 1516 firstLine = false; 1517 } 1518 stack.append("\n\t at "); 1519 } else { 1520 stack.append("$"); 1521 } 1522 } else { 1523 tag.append(" "); 1524 stack.append("$"); 1525 } 1526 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1527 appendMemBucket(tag, mi.pss, mi.name, false); 1528 } 1529 appendMemBucket(stack, mi.pss, mi.name, true); 1530 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1531 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1532 stack.append("("); 1533 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1534 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1535 stack.append(DUMP_MEM_OOM_LABEL[k]); 1536 stack.append(":"); 1537 stack.append(DUMP_MEM_OOM_ADJ[k]); 1538 } 1539 } 1540 stack.append(")"); 1541 } 1542 } 1543 1544 logBuilder.append(" "); 1545 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1546 logBuilder.append(' '); 1547 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1548 logBuilder.append(' '); 1549 ProcessList.appendRamKb(logBuilder, mi.pss); 1550 logBuilder.append(" kB: "); 1551 logBuilder.append(mi.name); 1552 logBuilder.append(" ("); 1553 logBuilder.append(mi.pid); 1554 logBuilder.append(") "); 1555 logBuilder.append(mi.adjType); 1556 logBuilder.append('\n'); 1557 if (mi.adjReason != null) { 1558 logBuilder.append(" "); 1559 logBuilder.append(mi.adjReason); 1560 logBuilder.append('\n'); 1561 } 1562 } 1563 1564 logBuilder.append(" "); 1565 ProcessList.appendRamKb(logBuilder, totalPss); 1566 logBuilder.append(" kB: TOTAL\n"); 1567 1568 long[] infos = new long[Debug.MEMINFO_COUNT]; 1569 Debug.getMemInfo(infos); 1570 logBuilder.append(" MemInfo: "); 1571 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1572 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1573 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1574 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1575 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1576 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1577 logBuilder.append(" ZRAM: "); 1578 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1579 logBuilder.append(" kB RAM, "); 1580 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1581 logBuilder.append(" kB swap total, "); 1582 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1583 logBuilder.append(" kB swap free\n"); 1584 } 1585 Slog.i(TAG, logBuilder.toString()); 1586 1587 StringBuilder dropBuilder = new StringBuilder(1024); 1588 /* 1589 StringWriter oomSw = new StringWriter(); 1590 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1591 StringWriter catSw = new StringWriter(); 1592 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1593 String[] emptyArgs = new String[] { }; 1594 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1595 oomPw.flush(); 1596 String oomString = oomSw.toString(); 1597 */ 1598 dropBuilder.append(stack); 1599 dropBuilder.append('\n'); 1600 dropBuilder.append('\n'); 1601 dropBuilder.append(logBuilder); 1602 dropBuilder.append('\n'); 1603 /* 1604 dropBuilder.append(oomString); 1605 dropBuilder.append('\n'); 1606 */ 1607 StringWriter catSw = new StringWriter(); 1608 synchronized (ActivityManagerService.this) { 1609 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1610 String[] emptyArgs = new String[] { }; 1611 catPw.println(); 1612 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1613 catPw.println(); 1614 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1615 false, false, null); 1616 catPw.println(); 1617 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1618 catPw.flush(); 1619 } 1620 dropBuilder.append(catSw.toString()); 1621 addErrorToDropBox("lowmem", null, "system_server", null, 1622 null, tag.toString(), dropBuilder.toString(), null, null); 1623 //Slog.i(TAG, "Sent to dropbox:"); 1624 //Slog.i(TAG, dropBuilder.toString()); 1625 synchronized (ActivityManagerService.this) { 1626 long now = SystemClock.uptimeMillis(); 1627 if (mLastMemUsageReportTime < now) { 1628 mLastMemUsageReportTime = now; 1629 } 1630 } 1631 } 1632 }; 1633 thread.start(); 1634 break; 1635 } 1636 case REPORT_USER_SWITCH_MSG: { 1637 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1638 break; 1639 } 1640 case CONTINUE_USER_SWITCH_MSG: { 1641 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1642 break; 1643 } 1644 case USER_SWITCH_TIMEOUT_MSG: { 1645 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1646 break; 1647 } 1648 case IMMERSIVE_MODE_LOCK_MSG: { 1649 final boolean nextState = (msg.arg1 != 0); 1650 if (mUpdateLock.isHeld() != nextState) { 1651 if (DEBUG_IMMERSIVE) { 1652 final ActivityRecord r = (ActivityRecord) msg.obj; 1653 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1654 } 1655 if (nextState) { 1656 mUpdateLock.acquire(); 1657 } else { 1658 mUpdateLock.release(); 1659 } 1660 } 1661 break; 1662 } 1663 case PERSIST_URI_GRANTS_MSG: { 1664 writeGrantedUriPermissions(); 1665 break; 1666 } 1667 case REQUEST_ALL_PSS_MSG: { 1668 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1669 break; 1670 } 1671 } 1672 } 1673 }; 1674 1675 static final int COLLECT_PSS_BG_MSG = 1; 1676 1677 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1678 @Override 1679 public void handleMessage(Message msg) { 1680 switch (msg.what) { 1681 case COLLECT_PSS_BG_MSG: { 1682 int i=0, num=0; 1683 long start = SystemClock.uptimeMillis(); 1684 long[] tmp = new long[1]; 1685 do { 1686 ProcessRecord proc; 1687 int procState; 1688 int pid; 1689 synchronized (ActivityManagerService.this) { 1690 if (i >= mPendingPssProcesses.size()) { 1691 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1692 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1693 mPendingPssProcesses.clear(); 1694 return; 1695 } 1696 proc = mPendingPssProcesses.get(i); 1697 procState = proc.pssProcState; 1698 if (proc.thread != null && procState == proc.setProcState) { 1699 pid = proc.pid; 1700 } else { 1701 proc = null; 1702 pid = 0; 1703 } 1704 i++; 1705 } 1706 if (proc != null) { 1707 long pss = Debug.getPss(pid, tmp); 1708 synchronized (ActivityManagerService.this) { 1709 if (proc.thread != null && proc.setProcState == procState 1710 && proc.pid == pid) { 1711 num++; 1712 proc.lastPssTime = SystemClock.uptimeMillis(); 1713 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1714 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1715 + ": " + pss + " lastPss=" + proc.lastPss 1716 + " state=" + ProcessList.makeProcStateString(procState)); 1717 if (proc.initialIdlePss == 0) { 1718 proc.initialIdlePss = pss; 1719 } 1720 proc.lastPss = pss; 1721 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1722 proc.lastCachedPss = pss; 1723 } 1724 } 1725 } 1726 } 1727 } while (true); 1728 } 1729 } 1730 } 1731 }; 1732 1733 public static void setSystemProcess() { 1734 try { 1735 ActivityManagerService m = mSelf; 1736 1737 ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true); 1738 ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats); 1739 ServiceManager.addService("meminfo", new MemBinder(m)); 1740 ServiceManager.addService("gfxinfo", new GraphicsBinder(m)); 1741 ServiceManager.addService("dbinfo", new DbBinder(m)); 1742 if (MONITOR_CPU_USAGE) { 1743 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1744 } 1745 ServiceManager.addService("permission", new PermissionController(m)); 1746 1747 ApplicationInfo info = 1748 mSelf.mContext.getPackageManager().getApplicationInfo( 1749 "android", STOCK_PM_FLAGS); 1750 mSystemThread.installSystemApplicationInfo(info); 1751 1752 synchronized (mSelf) { 1753 ProcessRecord app = mSelf.newProcessRecordLocked(info, 1754 info.processName, false); 1755 app.persistent = true; 1756 app.pid = MY_PID; 1757 app.maxAdj = ProcessList.SYSTEM_ADJ; 1758 app.makeActive(mSystemThread.getApplicationThread(), mSelf.mProcessStats); 1759 mSelf.mProcessNames.put(app.processName, app.uid, app); 1760 synchronized (mSelf.mPidsSelfLocked) { 1761 mSelf.mPidsSelfLocked.put(app.pid, app); 1762 } 1763 mSelf.updateLruProcessLocked(app, false, null); 1764 mSelf.updateOomAdjLocked(); 1765 } 1766 } catch (PackageManager.NameNotFoundException e) { 1767 throw new RuntimeException( 1768 "Unable to find android system package", e); 1769 } 1770 } 1771 1772 public void setWindowManager(WindowManagerService wm) { 1773 mWindowManager = wm; 1774 mStackSupervisor.setWindowManager(wm); 1775 wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f); 1776 } 1777 1778 public void startObservingNativeCrashes() { 1779 final NativeCrashListener ncl = new NativeCrashListener(); 1780 ncl.start(); 1781 } 1782 1783 public static final Context main(int factoryTest) { 1784 AThread thr = new AThread(); 1785 thr.start(); 1786 1787 synchronized (thr) { 1788 while (thr.mService == null) { 1789 try { 1790 thr.wait(); 1791 } catch (InterruptedException e) { 1792 } 1793 } 1794 } 1795 1796 ActivityManagerService m = thr.mService; 1797 mSelf = m; 1798 ActivityThread at = ActivityThread.systemMain(); 1799 mSystemThread = at; 1800 Context context = at.getSystemContext(); 1801 context.setTheme(android.R.style.Theme_Holo); 1802 m.mContext = context; 1803 m.mFactoryTest = factoryTest; 1804 m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface()); 1805 1806 m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper); 1807 1808 m.mBatteryStatsService.publish(context); 1809 m.mUsageStatsService.publish(context); 1810 m.mAppOpsService.publish(context); 1811 1812 synchronized (thr) { 1813 thr.mReady = true; 1814 thr.notifyAll(); 1815 } 1816 1817 m.startRunning(null, null, null, null); 1818 1819 return context; 1820 } 1821 1822 public static ActivityManagerService self() { 1823 return mSelf; 1824 } 1825 1826 public IAppOpsService getAppOpsService() { 1827 return mAppOpsService; 1828 } 1829 1830 static class AThread extends Thread { 1831 ActivityManagerService mService; 1832 Looper mLooper; 1833 boolean mReady = false; 1834 1835 public AThread() { 1836 super("ActivityManager"); 1837 } 1838 1839 @Override 1840 public void run() { 1841 Looper.prepare(); 1842 1843 android.os.Process.setThreadPriority( 1844 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1845 android.os.Process.setCanSelfBackground(false); 1846 1847 ActivityManagerService m = new ActivityManagerService(); 1848 1849 synchronized (this) { 1850 mService = m; 1851 mLooper = Looper.myLooper(); 1852 Watchdog.getInstance().addThread(new Handler(mLooper), getName()); 1853 notifyAll(); 1854 } 1855 1856 synchronized (this) { 1857 while (!mReady) { 1858 try { 1859 wait(); 1860 } catch (InterruptedException e) { 1861 } 1862 } 1863 } 1864 1865 // For debug builds, log event loop stalls to dropbox for analysis. 1866 if (StrictMode.conditionallyEnableDebugLogging()) { 1867 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper"); 1868 } 1869 1870 Looper.loop(); 1871 } 1872 } 1873 1874 static class MemBinder extends Binder { 1875 ActivityManagerService mActivityManagerService; 1876 MemBinder(ActivityManagerService activityManagerService) { 1877 mActivityManagerService = activityManagerService; 1878 } 1879 1880 @Override 1881 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1882 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1883 != PackageManager.PERMISSION_GRANTED) { 1884 pw.println("Permission Denial: can't dump meminfo from from pid=" 1885 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1886 + " without permission " + android.Manifest.permission.DUMP); 1887 return; 1888 } 1889 1890 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1891 } 1892 } 1893 1894 static class GraphicsBinder extends Binder { 1895 ActivityManagerService mActivityManagerService; 1896 GraphicsBinder(ActivityManagerService activityManagerService) { 1897 mActivityManagerService = activityManagerService; 1898 } 1899 1900 @Override 1901 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1902 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1903 != PackageManager.PERMISSION_GRANTED) { 1904 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1905 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1906 + " without permission " + android.Manifest.permission.DUMP); 1907 return; 1908 } 1909 1910 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1911 } 1912 } 1913 1914 static class DbBinder extends Binder { 1915 ActivityManagerService mActivityManagerService; 1916 DbBinder(ActivityManagerService activityManagerService) { 1917 mActivityManagerService = activityManagerService; 1918 } 1919 1920 @Override 1921 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1922 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1923 != PackageManager.PERMISSION_GRANTED) { 1924 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1925 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1926 + " without permission " + android.Manifest.permission.DUMP); 1927 return; 1928 } 1929 1930 mActivityManagerService.dumpDbInfo(fd, pw, args); 1931 } 1932 } 1933 1934 static class CpuBinder extends Binder { 1935 ActivityManagerService mActivityManagerService; 1936 CpuBinder(ActivityManagerService activityManagerService) { 1937 mActivityManagerService = activityManagerService; 1938 } 1939 1940 @Override 1941 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1942 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1943 != PackageManager.PERMISSION_GRANTED) { 1944 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1945 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1946 + " without permission " + android.Manifest.permission.DUMP); 1947 return; 1948 } 1949 1950 synchronized (mActivityManagerService.mProcessCpuThread) { 1951 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1952 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1953 SystemClock.uptimeMillis())); 1954 } 1955 } 1956 } 1957 1958 private ActivityManagerService() { 1959 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1960 1961 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT, false); 1962 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT, true); 1963 mBroadcastQueues[0] = mFgBroadcastQueue; 1964 mBroadcastQueues[1] = mBgBroadcastQueue; 1965 1966 mServices = new ActiveServices(this); 1967 mProviderMap = new ProviderMap(this); 1968 1969 File dataDir = Environment.getDataDirectory(); 1970 File systemDir = new File(dataDir, "system"); 1971 systemDir.mkdirs(); 1972 mBatteryStatsService = new BatteryStatsService(new File( 1973 systemDir, "batterystats.bin").toString()); 1974 mBatteryStatsService.getActiveStatistics().readLocked(); 1975 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1976 mOnBattery = DEBUG_POWER ? true 1977 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1978 mBatteryStatsService.getActiveStatistics().setCallback(this); 1979 1980 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1981 1982 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1983 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml")); 1984 1985 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1986 1987 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0")); 1988 1989 // User 0 is the first and only user that runs at boot. 1990 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1991 mUserLru.add(Integer.valueOf(0)); 1992 updateStartedUserArrayLocked(); 1993 1994 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1995 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1996 1997 mConfiguration.setToDefaults(); 1998 mConfiguration.setLocale(Locale.getDefault()); 1999 2000 mConfigurationSeq = mConfiguration.seq = 1; 2001 mProcessCpuTracker.init(); 2002 2003 mCompatModePackages = new CompatModePackages(this, systemDir); 2004 2005 // Add ourself to the Watchdog monitors. 2006 Watchdog.getInstance().addMonitor(this); 2007 2008 mProcessCpuThread = new Thread("CpuTracker") { 2009 @Override 2010 public void run() { 2011 while (true) { 2012 try { 2013 try { 2014 synchronized(this) { 2015 final long now = SystemClock.uptimeMillis(); 2016 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2017 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2018 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2019 // + ", write delay=" + nextWriteDelay); 2020 if (nextWriteDelay < nextCpuDelay) { 2021 nextCpuDelay = nextWriteDelay; 2022 } 2023 if (nextCpuDelay > 0) { 2024 mProcessCpuMutexFree.set(true); 2025 this.wait(nextCpuDelay); 2026 } 2027 } 2028 } catch (InterruptedException e) { 2029 } 2030 updateCpuStatsNow(); 2031 } catch (Exception e) { 2032 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2033 } 2034 } 2035 } 2036 }; 2037 mProcessCpuThread.start(); 2038 } 2039 2040 @Override 2041 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2042 throws RemoteException { 2043 if (code == SYSPROPS_TRANSACTION) { 2044 // We need to tell all apps about the system property change. 2045 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2046 synchronized(this) { 2047 final int NP = mProcessNames.getMap().size(); 2048 for (int ip=0; ip<NP; ip++) { 2049 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2050 final int NA = apps.size(); 2051 for (int ia=0; ia<NA; ia++) { 2052 ProcessRecord app = apps.valueAt(ia); 2053 if (app.thread != null) { 2054 procs.add(app.thread.asBinder()); 2055 } 2056 } 2057 } 2058 } 2059 2060 int N = procs.size(); 2061 for (int i=0; i<N; i++) { 2062 Parcel data2 = Parcel.obtain(); 2063 try { 2064 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2065 } catch (RemoteException e) { 2066 } 2067 data2.recycle(); 2068 } 2069 } 2070 try { 2071 return super.onTransact(code, data, reply, flags); 2072 } catch (RuntimeException e) { 2073 // The activity manager only throws security exceptions, so let's 2074 // log all others. 2075 if (!(e instanceof SecurityException)) { 2076 Slog.wtf(TAG, "Activity Manager Crash", e); 2077 } 2078 throw e; 2079 } 2080 } 2081 2082 void updateCpuStats() { 2083 final long now = SystemClock.uptimeMillis(); 2084 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2085 return; 2086 } 2087 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2088 synchronized (mProcessCpuThread) { 2089 mProcessCpuThread.notify(); 2090 } 2091 } 2092 } 2093 2094 void updateCpuStatsNow() { 2095 synchronized (mProcessCpuThread) { 2096 mProcessCpuMutexFree.set(false); 2097 final long now = SystemClock.uptimeMillis(); 2098 boolean haveNewCpuStats = false; 2099 2100 if (MONITOR_CPU_USAGE && 2101 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2102 mLastCpuTime.set(now); 2103 haveNewCpuStats = true; 2104 mProcessCpuTracker.update(); 2105 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2106 //Slog.i(TAG, "Total CPU usage: " 2107 // + mProcessCpu.getTotalCpuPercent() + "%"); 2108 2109 // Slog the cpu usage if the property is set. 2110 if ("true".equals(SystemProperties.get("events.cpu"))) { 2111 int user = mProcessCpuTracker.getLastUserTime(); 2112 int system = mProcessCpuTracker.getLastSystemTime(); 2113 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2114 int irq = mProcessCpuTracker.getLastIrqTime(); 2115 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2116 int idle = mProcessCpuTracker.getLastIdleTime(); 2117 2118 int total = user + system + iowait + irq + softIrq + idle; 2119 if (total == 0) total = 1; 2120 2121 EventLog.writeEvent(EventLogTags.CPU, 2122 ((user+system+iowait+irq+softIrq) * 100) / total, 2123 (user * 100) / total, 2124 (system * 100) / total, 2125 (iowait * 100) / total, 2126 (irq * 100) / total, 2127 (softIrq * 100) / total); 2128 } 2129 } 2130 2131 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2132 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2133 synchronized(bstats) { 2134 synchronized(mPidsSelfLocked) { 2135 if (haveNewCpuStats) { 2136 if (mOnBattery) { 2137 int perc = bstats.startAddingCpuLocked(); 2138 int totalUTime = 0; 2139 int totalSTime = 0; 2140 final int N = mProcessCpuTracker.countStats(); 2141 for (int i=0; i<N; i++) { 2142 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2143 if (!st.working) { 2144 continue; 2145 } 2146 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2147 int otherUTime = (st.rel_utime*perc)/100; 2148 int otherSTime = (st.rel_stime*perc)/100; 2149 totalUTime += otherUTime; 2150 totalSTime += otherSTime; 2151 if (pr != null) { 2152 BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked( 2153 st.name, st.pid); 2154 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2155 st.rel_stime-otherSTime); 2156 ps.addSpeedStepTimes(cpuSpeedTimes); 2157 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2158 } else if (st.uid >= Process.FIRST_APPLICATION_UID) { 2159 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2160 if (ps == null) { 2161 st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid, 2162 "(Unknown)"); 2163 } 2164 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2165 st.rel_stime-otherSTime); 2166 ps.addSpeedStepTimes(cpuSpeedTimes); 2167 } else { 2168 BatteryStatsImpl.Uid.Proc ps = 2169 bstats.getProcessStatsLocked(st.name, st.pid); 2170 if (ps != null) { 2171 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2172 st.rel_stime-otherSTime); 2173 ps.addSpeedStepTimes(cpuSpeedTimes); 2174 } 2175 } 2176 } 2177 bstats.finishAddingCpuLocked(perc, totalUTime, 2178 totalSTime, cpuSpeedTimes); 2179 } 2180 } 2181 } 2182 2183 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2184 mLastWriteTime = now; 2185 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2186 } 2187 } 2188 } 2189 } 2190 2191 @Override 2192 public void batteryNeedsCpuUpdate() { 2193 updateCpuStatsNow(); 2194 } 2195 2196 @Override 2197 public void batteryPowerChanged(boolean onBattery) { 2198 // When plugging in, update the CPU stats first before changing 2199 // the plug state. 2200 updateCpuStatsNow(); 2201 synchronized (this) { 2202 synchronized(mPidsSelfLocked) { 2203 mOnBattery = DEBUG_POWER ? true : onBattery; 2204 } 2205 } 2206 } 2207 2208 /** 2209 * Initialize the application bind args. These are passed to each 2210 * process when the bindApplication() IPC is sent to the process. They're 2211 * lazily setup to make sure the services are running when they're asked for. 2212 */ 2213 private HashMap<String, IBinder> getCommonServicesLocked() { 2214 if (mAppBindArgs == null) { 2215 mAppBindArgs = new HashMap<String, IBinder>(); 2216 2217 // Setup the application init args 2218 mAppBindArgs.put("package", ServiceManager.getService("package")); 2219 mAppBindArgs.put("window", ServiceManager.getService("window")); 2220 mAppBindArgs.put(Context.ALARM_SERVICE, 2221 ServiceManager.getService(Context.ALARM_SERVICE)); 2222 } 2223 return mAppBindArgs; 2224 } 2225 2226 final void setFocusedActivityLocked(ActivityRecord r) { 2227 if (mFocusedActivity != r) { 2228 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2229 mFocusedActivity = r; 2230 mStackSupervisor.setFocusedStack(r); 2231 if (r != null) { 2232 mWindowManager.setFocusedApp(r.appToken, true); 2233 } 2234 applyUpdateLockStateLocked(r); 2235 } 2236 } 2237 2238 @Override 2239 public void setFocusedStack(int stackId) { 2240 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2241 synchronized (ActivityManagerService.this) { 2242 ActivityStack stack = mStackSupervisor.getStack(stackId); 2243 if (stack != null) { 2244 ActivityRecord r = stack.topRunningActivityLocked(null); 2245 if (r != null) { 2246 setFocusedActivityLocked(r); 2247 } 2248 } 2249 } 2250 } 2251 2252 @Override 2253 public void notifyActivityDrawn(IBinder token) { 2254 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2255 synchronized (this) { 2256 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2257 if (r != null) { 2258 r.task.stack.notifyActivityDrawnLocked(r); 2259 } 2260 } 2261 } 2262 2263 final void applyUpdateLockStateLocked(ActivityRecord r) { 2264 // Modifications to the UpdateLock state are done on our handler, outside 2265 // the activity manager's locks. The new state is determined based on the 2266 // state *now* of the relevant activity record. The object is passed to 2267 // the handler solely for logging detail, not to be consulted/modified. 2268 final boolean nextState = r != null && r.immersive; 2269 mHandler.sendMessage( 2270 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2271 } 2272 2273 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2274 Message msg = Message.obtain(); 2275 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2276 msg.obj = r.task.askedCompatMode ? null : r; 2277 mHandler.sendMessage(msg); 2278 } 2279 2280 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2281 String what, Object obj, ProcessRecord srcApp) { 2282 app.lastActivityTime = now; 2283 2284 if (app.activities.size() > 0) { 2285 // Don't want to touch dependent processes that are hosting activities. 2286 return index; 2287 } 2288 2289 int lrui = mLruProcesses.lastIndexOf(app); 2290 if (lrui < 0) { 2291 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2292 + what + " " + obj + " from " + srcApp); 2293 return index; 2294 } 2295 2296 if (lrui >= index) { 2297 // Don't want to cause this to move dependent processes *back* in the 2298 // list as if they were less frequently used. 2299 return index; 2300 } 2301 2302 if (lrui >= mLruProcessActivityStart) { 2303 // Don't want to touch dependent processes that are hosting activities. 2304 return index; 2305 } 2306 2307 mLruProcesses.remove(lrui); 2308 if (index > 0) { 2309 index--; 2310 } 2311 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2312 + " in LRU list: " + app); 2313 mLruProcesses.add(index, app); 2314 return index; 2315 } 2316 2317 final void removeLruProcessLocked(ProcessRecord app) { 2318 int lrui = mLruProcesses.lastIndexOf(app); 2319 if (lrui >= 0) { 2320 if (lrui <= mLruProcessActivityStart) { 2321 mLruProcessActivityStart--; 2322 } 2323 if (lrui <= mLruProcessServiceStart) { 2324 mLruProcessServiceStart--; 2325 } 2326 mLruProcesses.remove(lrui); 2327 } 2328 } 2329 2330 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2331 ProcessRecord client) { 2332 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2333 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2334 if (!activityChange && hasActivity) { 2335 // The process has activties, so we are only going to allow activity-based 2336 // adjustments move it. It should be kept in the front of the list with other 2337 // processes that have activities, and we don't want those to change their 2338 // order except due to activity operations. 2339 return; 2340 } 2341 2342 mLruSeq++; 2343 final long now = SystemClock.uptimeMillis(); 2344 app.lastActivityTime = now; 2345 2346 // First a quick reject: if the app is already at the position we will 2347 // put it, then there is nothing to do. 2348 if (hasActivity) { 2349 final int N = mLruProcesses.size(); 2350 if (N > 0 && mLruProcesses.get(N-1) == app) { 2351 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2352 return; 2353 } 2354 } else { 2355 if (mLruProcessServiceStart > 0 2356 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2357 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2358 return; 2359 } 2360 } 2361 2362 int lrui = mLruProcesses.lastIndexOf(app); 2363 2364 if (app.persistent && lrui >= 0) { 2365 // We don't care about the position of persistent processes, as long as 2366 // they are in the list. 2367 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2368 return; 2369 } 2370 2371 /* In progress: compute new position first, so we can avoid doing work 2372 if the process is not actually going to move. Not yet working. 2373 int addIndex; 2374 int nextIndex; 2375 boolean inActivity = false, inService = false; 2376 if (hasActivity) { 2377 // Process has activities, put it at the very tipsy-top. 2378 addIndex = mLruProcesses.size(); 2379 nextIndex = mLruProcessServiceStart; 2380 inActivity = true; 2381 } else if (hasService) { 2382 // Process has services, put it at the top of the service list. 2383 addIndex = mLruProcessActivityStart; 2384 nextIndex = mLruProcessServiceStart; 2385 inActivity = true; 2386 inService = true; 2387 } else { 2388 // Process not otherwise of interest, it goes to the top of the non-service area. 2389 addIndex = mLruProcessServiceStart; 2390 if (client != null) { 2391 int clientIndex = mLruProcesses.lastIndexOf(client); 2392 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2393 + app); 2394 if (clientIndex >= 0 && addIndex > clientIndex) { 2395 addIndex = clientIndex; 2396 } 2397 } 2398 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2399 } 2400 2401 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2402 + mLruProcessActivityStart + "): " + app); 2403 */ 2404 2405 if (lrui >= 0) { 2406 if (lrui < mLruProcessActivityStart) { 2407 mLruProcessActivityStart--; 2408 } 2409 if (lrui < mLruProcessServiceStart) { 2410 mLruProcessServiceStart--; 2411 } 2412 /* 2413 if (addIndex > lrui) { 2414 addIndex--; 2415 } 2416 if (nextIndex > lrui) { 2417 nextIndex--; 2418 } 2419 */ 2420 mLruProcesses.remove(lrui); 2421 } 2422 2423 /* 2424 mLruProcesses.add(addIndex, app); 2425 if (inActivity) { 2426 mLruProcessActivityStart++; 2427 } 2428 if (inService) { 2429 mLruProcessActivityStart++; 2430 } 2431 */ 2432 2433 int nextIndex; 2434 if (hasActivity) { 2435 final int N = mLruProcesses.size(); 2436 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2437 // Process doesn't have activities, but has clients with 2438 // activities... move it up, but one below the top (the top 2439 // should always have a real activity). 2440 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2441 mLruProcesses.add(N-1, app); 2442 // To keep it from spamming the LRU list (by making a bunch of clients), 2443 // we will push down any other entries owned by the app. 2444 final int uid = app.info.uid; 2445 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2446 ProcessRecord subProc = mLruProcesses.get(i); 2447 if (subProc.info.uid == uid) { 2448 // We want to push this one down the list. If the process after 2449 // it is for the same uid, however, don't do so, because we don't 2450 // want them internally to be re-ordered. 2451 if (mLruProcesses.get(i-1).info.uid != uid) { 2452 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2453 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2454 ProcessRecord tmp = mLruProcesses.get(i); 2455 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2456 mLruProcesses.set(i-1, tmp); 2457 i--; 2458 } 2459 } else { 2460 // A gap, we can stop here. 2461 break; 2462 } 2463 } 2464 } else { 2465 // Process has activities, put it at the very tipsy-top. 2466 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2467 mLruProcesses.add(app); 2468 } 2469 nextIndex = mLruProcessServiceStart; 2470 } else if (hasService) { 2471 // Process has services, put it at the top of the service list. 2472 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2473 mLruProcesses.add(mLruProcessActivityStart, app); 2474 nextIndex = mLruProcessServiceStart; 2475 mLruProcessActivityStart++; 2476 } else { 2477 // Process not otherwise of interest, it goes to the top of the non-service area. 2478 int index = mLruProcessServiceStart; 2479 if (client != null) { 2480 // If there is a client, don't allow the process to be moved up higher 2481 // in the list than that client. 2482 int clientIndex = mLruProcesses.lastIndexOf(client); 2483 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2484 + " when updating " + app); 2485 if (clientIndex <= lrui) { 2486 // Don't allow the client index restriction to push it down farther in the 2487 // list than it already is. 2488 clientIndex = lrui; 2489 } 2490 if (clientIndex >= 0 && index > clientIndex) { 2491 index = clientIndex; 2492 } 2493 } 2494 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2495 mLruProcesses.add(index, app); 2496 nextIndex = index-1; 2497 mLruProcessActivityStart++; 2498 mLruProcessServiceStart++; 2499 } 2500 2501 // If the app is currently using a content provider or service, 2502 // bump those processes as well. 2503 for (int j=app.connections.size()-1; j>=0; j--) { 2504 ConnectionRecord cr = app.connections.valueAt(j); 2505 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2506 && cr.binding.service.app != null 2507 && cr.binding.service.app.lruSeq != mLruSeq 2508 && !cr.binding.service.app.persistent) { 2509 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2510 "service connection", cr, app); 2511 } 2512 } 2513 for (int j=app.conProviders.size()-1; j>=0; j--) { 2514 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2515 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2516 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2517 "provider reference", cpr, app); 2518 } 2519 } 2520 } 2521 2522 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2523 if (uid == Process.SYSTEM_UID) { 2524 // The system gets to run in any process. If there are multiple 2525 // processes with the same uid, just pick the first (this 2526 // should never happen). 2527 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2528 if (procs == null) return null; 2529 final int N = procs.size(); 2530 for (int i = 0; i < N; i++) { 2531 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2532 } 2533 } 2534 ProcessRecord proc = mProcessNames.get(processName, uid); 2535 if (false && proc != null && !keepIfLarge 2536 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2537 && proc.lastCachedPss >= 4000) { 2538 // Turn this condition on to cause killing to happen regularly, for testing. 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 } else if (proc != null && !keepIfLarge 2545 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2546 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2547 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2548 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2549 if (proc.baseProcessTracker != null) { 2550 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2551 } 2552 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2553 + "k from cached"); 2554 } 2555 } 2556 return proc; 2557 } 2558 2559 void ensurePackageDexOpt(String packageName) { 2560 IPackageManager pm = AppGlobals.getPackageManager(); 2561 try { 2562 if (pm.performDexOpt(packageName)) { 2563 mDidDexOpt = true; 2564 } 2565 } catch (RemoteException e) { 2566 } 2567 } 2568 2569 boolean isNextTransitionForward() { 2570 int transit = mWindowManager.getPendingAppTransition(); 2571 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2572 || transit == AppTransition.TRANSIT_TASK_OPEN 2573 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2574 } 2575 2576 final ProcessRecord startProcessLocked(String processName, 2577 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2578 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2579 boolean isolated, boolean keepIfLarge) { 2580 ProcessRecord app; 2581 if (!isolated) { 2582 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2583 } else { 2584 // If this is an isolated process, it can't re-use an existing process. 2585 app = null; 2586 } 2587 // We don't have to do anything more if: 2588 // (1) There is an existing application record; and 2589 // (2) The caller doesn't think it is dead, OR there is no thread 2590 // object attached to it so we know it couldn't have crashed; and 2591 // (3) There is a pid assigned to it, so it is either starting or 2592 // already running. 2593 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2594 + " app=" + app + " knownToBeDead=" + knownToBeDead 2595 + " thread=" + (app != null ? app.thread : null) 2596 + " pid=" + (app != null ? app.pid : -1)); 2597 if (app != null && app.pid > 0) { 2598 if (!knownToBeDead || app.thread == null) { 2599 // We already have the app running, or are waiting for it to 2600 // come up (we have a pid but not yet its thread), so keep it. 2601 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2602 // If this is a new package in the process, add the package to the list 2603 app.addPackage(info.packageName, mProcessStats); 2604 return app; 2605 } 2606 2607 // An application record is attached to a previous process, 2608 // clean it up now. 2609 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2610 handleAppDiedLocked(app, true, true); 2611 } 2612 2613 String hostingNameStr = hostingName != null 2614 ? hostingName.flattenToShortString() : null; 2615 2616 if (!isolated) { 2617 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2618 // If we are in the background, then check to see if this process 2619 // is bad. If so, we will just silently fail. 2620 if (mBadProcesses.get(info.processName, info.uid) != null) { 2621 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2622 + "/" + info.processName); 2623 return null; 2624 } 2625 } else { 2626 // When the user is explicitly starting a process, then clear its 2627 // crash count so that we won't make it bad until they see at 2628 // least one crash dialog again, and make the process good again 2629 // if it had been bad. 2630 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2631 + "/" + info.processName); 2632 mProcessCrashTimes.remove(info.processName, info.uid); 2633 if (mBadProcesses.get(info.processName, info.uid) != null) { 2634 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2635 UserHandle.getUserId(info.uid), info.uid, 2636 info.processName); 2637 mBadProcesses.remove(info.processName, info.uid); 2638 if (app != null) { 2639 app.bad = false; 2640 } 2641 } 2642 } 2643 } 2644 2645 if (app == null) { 2646 app = newProcessRecordLocked(info, processName, isolated); 2647 if (app == null) { 2648 Slog.w(TAG, "Failed making new process record for " 2649 + processName + "/" + info.uid + " isolated=" + isolated); 2650 return null; 2651 } 2652 mProcessNames.put(processName, app.uid, app); 2653 if (isolated) { 2654 mIsolatedProcesses.put(app.uid, app); 2655 } 2656 } else { 2657 // If this is a new package in the process, add the package to the list 2658 app.addPackage(info.packageName, mProcessStats); 2659 } 2660 2661 // If the system is not ready yet, then hold off on starting this 2662 // process until it is. 2663 if (!mProcessesReady 2664 && !isAllowedWhileBooting(info) 2665 && !allowWhileBooting) { 2666 if (!mProcessesOnHold.contains(app)) { 2667 mProcessesOnHold.add(app); 2668 } 2669 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2670 return app; 2671 } 2672 2673 startProcessLocked(app, hostingType, hostingNameStr); 2674 return (app.pid != 0) ? app : null; 2675 } 2676 2677 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2678 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2679 } 2680 2681 private final void startProcessLocked(ProcessRecord app, 2682 String hostingType, String hostingNameStr) { 2683 if (app.pid > 0 && app.pid != MY_PID) { 2684 synchronized (mPidsSelfLocked) { 2685 mPidsSelfLocked.remove(app.pid); 2686 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2687 } 2688 app.setPid(0); 2689 } 2690 2691 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2692 "startProcessLocked removing on hold: " + app); 2693 mProcessesOnHold.remove(app); 2694 2695 updateCpuStats(); 2696 2697 try { 2698 int uid = app.uid; 2699 2700 int[] gids = null; 2701 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2702 if (!app.isolated) { 2703 int[] permGids = null; 2704 try { 2705 final PackageManager pm = mContext.getPackageManager(); 2706 permGids = pm.getPackageGids(app.info.packageName); 2707 2708 if (Environment.isExternalStorageEmulated()) { 2709 if (pm.checkPermission( 2710 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2711 app.info.packageName) == PERMISSION_GRANTED) { 2712 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2713 } else { 2714 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2715 } 2716 } 2717 } catch (PackageManager.NameNotFoundException e) { 2718 Slog.w(TAG, "Unable to retrieve gids", e); 2719 } 2720 2721 /* 2722 * Add shared application GID so applications can share some 2723 * resources like shared libraries 2724 */ 2725 if (permGids == null) { 2726 gids = new int[1]; 2727 } else { 2728 gids = new int[permGids.length + 1]; 2729 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2730 } 2731 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2732 } 2733 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2734 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2735 && mTopComponent != null 2736 && app.processName.equals(mTopComponent.getPackageName())) { 2737 uid = 0; 2738 } 2739 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2740 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2741 uid = 0; 2742 } 2743 } 2744 int debugFlags = 0; 2745 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2746 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2747 // Also turn on CheckJNI for debuggable apps. It's quite 2748 // awkward to turn on otherwise. 2749 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2750 } 2751 // Run the app in safe mode if its manifest requests so or the 2752 // system is booted in safe mode. 2753 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2754 Zygote.systemInSafeMode == true) { 2755 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2756 } 2757 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2758 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2759 } 2760 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2761 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2762 } 2763 if ("1".equals(SystemProperties.get("debug.assert"))) { 2764 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2765 } 2766 2767 // Start the process. It will either succeed and return a result containing 2768 // the PID of the new process, or else throw a RuntimeException. 2769 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2770 app.processName, uid, uid, gids, debugFlags, mountExternal, 2771 app.info.targetSdkVersion, app.info.seinfo, null); 2772 2773 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2774 synchronized (bs) { 2775 if (bs.isOnBattery()) { 2776 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2777 } 2778 } 2779 2780 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2781 UserHandle.getUserId(uid), startResult.pid, uid, 2782 app.processName, hostingType, 2783 hostingNameStr != null ? hostingNameStr : ""); 2784 2785 if (app.persistent) { 2786 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2787 } 2788 2789 StringBuilder buf = mStringBuilder; 2790 buf.setLength(0); 2791 buf.append("Start proc "); 2792 buf.append(app.processName); 2793 buf.append(" for "); 2794 buf.append(hostingType); 2795 if (hostingNameStr != null) { 2796 buf.append(" "); 2797 buf.append(hostingNameStr); 2798 } 2799 buf.append(": pid="); 2800 buf.append(startResult.pid); 2801 buf.append(" uid="); 2802 buf.append(uid); 2803 buf.append(" gids={"); 2804 if (gids != null) { 2805 for (int gi=0; gi<gids.length; gi++) { 2806 if (gi != 0) buf.append(", "); 2807 buf.append(gids[gi]); 2808 2809 } 2810 } 2811 buf.append("}"); 2812 Slog.i(TAG, buf.toString()); 2813 app.setPid(startResult.pid); 2814 app.usingWrapper = startResult.usingWrapper; 2815 app.removed = false; 2816 synchronized (mPidsSelfLocked) { 2817 this.mPidsSelfLocked.put(startResult.pid, app); 2818 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2819 msg.obj = app; 2820 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2821 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2822 } 2823 } catch (RuntimeException e) { 2824 // XXX do better error recovery. 2825 app.setPid(0); 2826 Slog.e(TAG, "Failure starting process " + app.processName, e); 2827 } 2828 } 2829 2830 void updateUsageStats(ActivityRecord component, boolean resumed) { 2831 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2832 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2833 if (resumed) { 2834 mUsageStatsService.noteResumeComponent(component.realActivity); 2835 synchronized (stats) { 2836 stats.noteActivityResumedLocked(component.app.uid); 2837 } 2838 } else { 2839 mUsageStatsService.notePauseComponent(component.realActivity); 2840 synchronized (stats) { 2841 stats.noteActivityPausedLocked(component.app.uid); 2842 } 2843 } 2844 } 2845 2846 Intent getHomeIntent() { 2847 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2848 intent.setComponent(mTopComponent); 2849 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2850 intent.addCategory(Intent.CATEGORY_HOME); 2851 } 2852 return intent; 2853 } 2854 2855 boolean startHomeActivityLocked(int userId) { 2856 if (mHeadless) { 2857 // Added because none of the other calls to ensureBootCompleted seem to fire 2858 // when running headless. 2859 ensureBootCompleted(); 2860 return false; 2861 } 2862 2863 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2864 && mTopAction == null) { 2865 // We are running in factory test mode, but unable to find 2866 // the factory test app, so just sit around displaying the 2867 // error message and don't try to start anything. 2868 return false; 2869 } 2870 Intent intent = getHomeIntent(); 2871 ActivityInfo aInfo = 2872 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2873 if (aInfo != null) { 2874 intent.setComponent(new ComponentName( 2875 aInfo.applicationInfo.packageName, aInfo.name)); 2876 // Don't do this if the home app is currently being 2877 // instrumented. 2878 aInfo = new ActivityInfo(aInfo); 2879 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2880 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2881 aInfo.applicationInfo.uid, true); 2882 if (app == null || app.instrumentationClass == null) { 2883 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2884 mStackSupervisor.startHomeActivity(intent, aInfo); 2885 } 2886 } 2887 2888 return true; 2889 } 2890 2891 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2892 ActivityInfo ai = null; 2893 ComponentName comp = intent.getComponent(); 2894 try { 2895 if (comp != null) { 2896 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2897 } else { 2898 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2899 intent, 2900 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2901 flags, userId); 2902 2903 if (info != null) { 2904 ai = info.activityInfo; 2905 } 2906 } 2907 } catch (RemoteException e) { 2908 // ignore 2909 } 2910 2911 return ai; 2912 } 2913 2914 /** 2915 * Starts the "new version setup screen" if appropriate. 2916 */ 2917 void startSetupActivityLocked() { 2918 // Only do this once per boot. 2919 if (mCheckedForSetup) { 2920 return; 2921 } 2922 2923 // We will show this screen if the current one is a different 2924 // version than the last one shown, and we are not running in 2925 // low-level factory test mode. 2926 final ContentResolver resolver = mContext.getContentResolver(); 2927 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2928 Settings.Global.getInt(resolver, 2929 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2930 mCheckedForSetup = true; 2931 2932 // See if we should be showing the platform update setup UI. 2933 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2934 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2935 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2936 2937 // We don't allow third party apps to replace this. 2938 ResolveInfo ri = null; 2939 for (int i=0; ris != null && i<ris.size(); i++) { 2940 if ((ris.get(i).activityInfo.applicationInfo.flags 2941 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2942 ri = ris.get(i); 2943 break; 2944 } 2945 } 2946 2947 if (ri != null) { 2948 String vers = ri.activityInfo.metaData != null 2949 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2950 : null; 2951 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2952 vers = ri.activityInfo.applicationInfo.metaData.getString( 2953 Intent.METADATA_SETUP_VERSION); 2954 } 2955 String lastVers = Settings.Secure.getString( 2956 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2957 if (vers != null && !vers.equals(lastVers)) { 2958 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2959 intent.setComponent(new ComponentName( 2960 ri.activityInfo.packageName, ri.activityInfo.name)); 2961 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2962 null, null, 0, 0, 0, null, 0, null, false, null); 2963 } 2964 } 2965 } 2966 } 2967 2968 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2969 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2970 } 2971 2972 void enforceNotIsolatedCaller(String caller) { 2973 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2974 throw new SecurityException("Isolated process not allowed to call " + caller); 2975 } 2976 } 2977 2978 @Override 2979 public int getFrontActivityScreenCompatMode() { 2980 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2981 synchronized (this) { 2982 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2983 } 2984 } 2985 2986 @Override 2987 public void setFrontActivityScreenCompatMode(int mode) { 2988 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2989 "setFrontActivityScreenCompatMode"); 2990 synchronized (this) { 2991 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2992 } 2993 } 2994 2995 @Override 2996 public int getPackageScreenCompatMode(String packageName) { 2997 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2998 synchronized (this) { 2999 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3000 } 3001 } 3002 3003 @Override 3004 public void setPackageScreenCompatMode(String packageName, int mode) { 3005 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3006 "setPackageScreenCompatMode"); 3007 synchronized (this) { 3008 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3009 } 3010 } 3011 3012 @Override 3013 public boolean getPackageAskScreenCompat(String packageName) { 3014 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3015 synchronized (this) { 3016 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3017 } 3018 } 3019 3020 @Override 3021 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3022 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3023 "setPackageAskScreenCompat"); 3024 synchronized (this) { 3025 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3026 } 3027 } 3028 3029 private void dispatchProcessesChanged() { 3030 int N; 3031 synchronized (this) { 3032 N = mPendingProcessChanges.size(); 3033 if (mActiveProcessChanges.length < N) { 3034 mActiveProcessChanges = new ProcessChangeItem[N]; 3035 } 3036 mPendingProcessChanges.toArray(mActiveProcessChanges); 3037 mAvailProcessChanges.addAll(mPendingProcessChanges); 3038 mPendingProcessChanges.clear(); 3039 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3040 } 3041 3042 int i = mProcessObservers.beginBroadcast(); 3043 while (i > 0) { 3044 i--; 3045 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3046 if (observer != null) { 3047 try { 3048 for (int j=0; j<N; j++) { 3049 ProcessChangeItem item = mActiveProcessChanges[j]; 3050 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3051 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3052 + item.pid + " uid=" + item.uid + ": " 3053 + item.foregroundActivities); 3054 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3055 item.foregroundActivities); 3056 } 3057 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3058 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3059 + item.pid + " uid=" + item.uid + ": " + item.importance); 3060 observer.onImportanceChanged(item.pid, item.uid, 3061 item.importance); 3062 } 3063 } 3064 } catch (RemoteException e) { 3065 } 3066 } 3067 } 3068 mProcessObservers.finishBroadcast(); 3069 } 3070 3071 private void dispatchProcessDied(int pid, int uid) { 3072 int i = mProcessObservers.beginBroadcast(); 3073 while (i > 0) { 3074 i--; 3075 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3076 if (observer != null) { 3077 try { 3078 observer.onProcessDied(pid, uid); 3079 } catch (RemoteException e) { 3080 } 3081 } 3082 } 3083 mProcessObservers.finishBroadcast(); 3084 } 3085 3086 final void doPendingActivityLaunchesLocked(boolean doResume) { 3087 final int N = mPendingActivityLaunches.size(); 3088 if (N <= 0) { 3089 return; 3090 } 3091 for (int i=0; i<N; i++) { 3092 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3093 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3094 doResume && i == (N-1), null); 3095 } 3096 mPendingActivityLaunches.clear(); 3097 } 3098 3099 @Override 3100 public final int startActivity(IApplicationThread caller, String callingPackage, 3101 Intent intent, String resolvedType, IBinder resultTo, 3102 String resultWho, int requestCode, int startFlags, 3103 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3104 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3105 resultWho, requestCode, 3106 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3107 } 3108 3109 @Override 3110 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3111 Intent intent, String resolvedType, IBinder resultTo, 3112 String resultWho, int requestCode, int startFlags, 3113 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3114 enforceNotIsolatedCaller("startActivity"); 3115 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3116 false, true, "startActivity", null); 3117 // TODO: Switch to user app stacks here. 3118 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3119 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3120 null, null, options, userId); 3121 } 3122 3123 @Override 3124 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3125 Intent intent, String resolvedType, IBinder resultTo, 3126 String resultWho, int requestCode, int startFlags, String profileFile, 3127 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3128 enforceNotIsolatedCaller("startActivityAndWait"); 3129 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3130 false, true, "startActivityAndWait", null); 3131 WaitResult res = new WaitResult(); 3132 // TODO: Switch to user app stacks here. 3133 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3134 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3135 res, null, options, UserHandle.getCallingUserId()); 3136 return res; 3137 } 3138 3139 @Override 3140 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3141 Intent intent, String resolvedType, IBinder resultTo, 3142 String resultWho, int requestCode, int startFlags, Configuration config, 3143 Bundle options, int userId) { 3144 enforceNotIsolatedCaller("startActivityWithConfig"); 3145 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3146 false, true, "startActivityWithConfig", null); 3147 // TODO: Switch to user app stacks here. 3148 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3149 resolvedType, resultTo, resultWho, requestCode, startFlags, 3150 null, null, null, config, options, userId); 3151 return ret; 3152 } 3153 3154 @Override 3155 public int startActivityIntentSender(IApplicationThread caller, 3156 IntentSender intent, Intent fillInIntent, String resolvedType, 3157 IBinder resultTo, String resultWho, int requestCode, 3158 int flagsMask, int flagsValues, Bundle options) { 3159 enforceNotIsolatedCaller("startActivityIntentSender"); 3160 // Refuse possible leaked file descriptors 3161 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3162 throw new IllegalArgumentException("File descriptors passed in Intent"); 3163 } 3164 3165 IIntentSender sender = intent.getTarget(); 3166 if (!(sender instanceof PendingIntentRecord)) { 3167 throw new IllegalArgumentException("Bad PendingIntent object"); 3168 } 3169 3170 PendingIntentRecord pir = (PendingIntentRecord)sender; 3171 3172 synchronized (this) { 3173 // If this is coming from the currently resumed activity, it is 3174 // effectively saying that app switches are allowed at this point. 3175 final ActivityStack stack = getFocusedStack(); 3176 if (stack.mResumedActivity != null && 3177 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3178 mAppSwitchesAllowedTime = 0; 3179 } 3180 } 3181 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3182 resultTo, resultWho, requestCode, flagsMask, flagsValues, options); 3183 return ret; 3184 } 3185 3186 @Override 3187 public boolean startNextMatchingActivity(IBinder callingActivity, 3188 Intent intent, Bundle options) { 3189 // Refuse possible leaked file descriptors 3190 if (intent != null && intent.hasFileDescriptors() == true) { 3191 throw new IllegalArgumentException("File descriptors passed in Intent"); 3192 } 3193 3194 synchronized (this) { 3195 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3196 if (r == null) { 3197 ActivityOptions.abort(options); 3198 return false; 3199 } 3200 if (r.app == null || r.app.thread == null) { 3201 // The caller is not running... d'oh! 3202 ActivityOptions.abort(options); 3203 return false; 3204 } 3205 intent = new Intent(intent); 3206 // The caller is not allowed to change the data. 3207 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3208 // And we are resetting to find the next component... 3209 intent.setComponent(null); 3210 3211 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3212 3213 ActivityInfo aInfo = null; 3214 try { 3215 List<ResolveInfo> resolves = 3216 AppGlobals.getPackageManager().queryIntentActivities( 3217 intent, r.resolvedType, 3218 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3219 UserHandle.getCallingUserId()); 3220 3221 // Look for the original activity in the list... 3222 final int N = resolves != null ? resolves.size() : 0; 3223 for (int i=0; i<N; i++) { 3224 ResolveInfo rInfo = resolves.get(i); 3225 if (rInfo.activityInfo.packageName.equals(r.packageName) 3226 && rInfo.activityInfo.name.equals(r.info.name)) { 3227 // We found the current one... the next matching is 3228 // after it. 3229 i++; 3230 if (i<N) { 3231 aInfo = resolves.get(i).activityInfo; 3232 } 3233 if (debug) { 3234 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3235 + "/" + r.info.name); 3236 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3237 + "/" + aInfo.name); 3238 } 3239 break; 3240 } 3241 } 3242 } catch (RemoteException e) { 3243 } 3244 3245 if (aInfo == null) { 3246 // Nobody who is next! 3247 ActivityOptions.abort(options); 3248 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3249 return false; 3250 } 3251 3252 intent.setComponent(new ComponentName( 3253 aInfo.applicationInfo.packageName, aInfo.name)); 3254 intent.setFlags(intent.getFlags()&~( 3255 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3256 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3257 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3258 Intent.FLAG_ACTIVITY_NEW_TASK)); 3259 3260 // Okay now we need to start the new activity, replacing the 3261 // currently running activity. This is a little tricky because 3262 // we want to start the new one as if the current one is finished, 3263 // but not finish the current one first so that there is no flicker. 3264 // And thus... 3265 final boolean wasFinishing = r.finishing; 3266 r.finishing = true; 3267 3268 // Propagate reply information over to the new activity. 3269 final ActivityRecord resultTo = r.resultTo; 3270 final String resultWho = r.resultWho; 3271 final int requestCode = r.requestCode; 3272 r.resultTo = null; 3273 if (resultTo != null) { 3274 resultTo.removeResultsLocked(r, resultWho, requestCode); 3275 } 3276 3277 final long origId = Binder.clearCallingIdentity(); 3278 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3279 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3280 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3281 options, false, null); 3282 Binder.restoreCallingIdentity(origId); 3283 3284 r.finishing = wasFinishing; 3285 if (res != ActivityManager.START_SUCCESS) { 3286 return false; 3287 } 3288 return true; 3289 } 3290 } 3291 3292 final int startActivityInPackage(int uid, String callingPackage, 3293 Intent intent, String resolvedType, IBinder resultTo, 3294 String resultWho, int requestCode, int startFlags, Bundle options, int userId) { 3295 3296 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3297 false, true, "startActivityInPackage", null); 3298 3299 // TODO: Switch to user app stacks here. 3300 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3301 resultTo, resultWho, requestCode, startFlags, 3302 null, null, null, null, options, userId); 3303 return ret; 3304 } 3305 3306 @Override 3307 public final int startActivities(IApplicationThread caller, String callingPackage, 3308 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3309 int userId) { 3310 enforceNotIsolatedCaller("startActivities"); 3311 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3312 false, true, "startActivity", null); 3313 // TODO: Switch to user app stacks here. 3314 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3315 resolvedTypes, resultTo, options, userId); 3316 return ret; 3317 } 3318 3319 final int startActivitiesInPackage(int uid, String callingPackage, 3320 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3321 Bundle options, int userId) { 3322 3323 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3324 false, true, "startActivityInPackage", null); 3325 // TODO: Switch to user app stacks here. 3326 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3327 resultTo, options, userId); 3328 return ret; 3329 } 3330 3331 final void addRecentTaskLocked(TaskRecord task) { 3332 int N = mRecentTasks.size(); 3333 // Quick case: check if the top-most recent task is the same. 3334 if (N > 0 && mRecentTasks.get(0) == task) { 3335 return; 3336 } 3337 // Remove any existing entries that are the same kind of task. 3338 for (int i=0; i<N; i++) { 3339 TaskRecord tr = mRecentTasks.get(i); 3340 if (task.userId == tr.userId 3341 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3342 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3343 tr.disposeThumbnail(); 3344 mRecentTasks.remove(i); 3345 i--; 3346 N--; 3347 if (task.intent == null) { 3348 // If the new recent task we are adding is not fully 3349 // specified, then replace it with the existing recent task. 3350 task = tr; 3351 } 3352 } 3353 } 3354 if (N >= MAX_RECENT_TASKS) { 3355 mRecentTasks.remove(N-1).disposeThumbnail(); 3356 } 3357 mRecentTasks.add(0, task); 3358 } 3359 3360 @Override 3361 public void reportActivityFullyDrawn(IBinder token) { 3362 synchronized (this) { 3363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3364 if (r == null) { 3365 return; 3366 } 3367 r.reportFullyDrawnLocked(); 3368 } 3369 } 3370 3371 @Override 3372 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3373 synchronized (this) { 3374 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3375 if (r == null) { 3376 return; 3377 } 3378 final long origId = Binder.clearCallingIdentity(); 3379 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3380 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3381 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3382 if (config != null) { 3383 r.frozenBeforeDestroy = true; 3384 if (!updateConfigurationLocked(config, r, false, false)) { 3385 mStackSupervisor.resumeTopActivitiesLocked(); 3386 } 3387 } 3388 Binder.restoreCallingIdentity(origId); 3389 } 3390 } 3391 3392 @Override 3393 public int getRequestedOrientation(IBinder token) { 3394 synchronized (this) { 3395 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3396 if (r == null) { 3397 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3398 } 3399 return mWindowManager.getAppOrientation(r.appToken); 3400 } 3401 } 3402 3403 /** 3404 * This is the internal entry point for handling Activity.finish(). 3405 * 3406 * @param token The Binder token referencing the Activity we want to finish. 3407 * @param resultCode Result code, if any, from this Activity. 3408 * @param resultData Result data (Intent), if any, from this Activity. 3409 * 3410 * @return Returns true if the activity successfully finished, or false if it is still running. 3411 */ 3412 @Override 3413 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3414 // Refuse possible leaked file descriptors 3415 if (resultData != null && resultData.hasFileDescriptors() == true) { 3416 throw new IllegalArgumentException("File descriptors passed in Intent"); 3417 } 3418 3419 synchronized(this) { 3420 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3421 if (r == null) { 3422 return true; 3423 } 3424 if (mController != null) { 3425 // Find the first activity that is not finishing. 3426 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3427 if (next != null) { 3428 // ask watcher if this is allowed 3429 boolean resumeOK = true; 3430 try { 3431 resumeOK = mController.activityResuming(next.packageName); 3432 } catch (RemoteException e) { 3433 mController = null; 3434 Watchdog.getInstance().setActivityController(null); 3435 } 3436 3437 if (!resumeOK) { 3438 return false; 3439 } 3440 } 3441 } 3442 final long origId = Binder.clearCallingIdentity(); 3443 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3444 resultData, "app-request", true); 3445 Binder.restoreCallingIdentity(origId); 3446 return res; 3447 } 3448 } 3449 3450 @Override 3451 public final void finishHeavyWeightApp() { 3452 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3453 != PackageManager.PERMISSION_GRANTED) { 3454 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3455 + Binder.getCallingPid() 3456 + ", uid=" + Binder.getCallingUid() 3457 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3458 Slog.w(TAG, msg); 3459 throw new SecurityException(msg); 3460 } 3461 3462 synchronized(this) { 3463 if (mHeavyWeightProcess == null) { 3464 return; 3465 } 3466 3467 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3468 mHeavyWeightProcess.activities); 3469 for (int i=0; i<activities.size(); i++) { 3470 ActivityRecord r = activities.get(i); 3471 if (!r.finishing) { 3472 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3473 null, "finish-heavy", true); 3474 } 3475 } 3476 3477 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3478 mHeavyWeightProcess.userId, 0)); 3479 mHeavyWeightProcess = null; 3480 } 3481 } 3482 3483 @Override 3484 public void crashApplication(int uid, int initialPid, String packageName, 3485 String message) { 3486 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3487 != PackageManager.PERMISSION_GRANTED) { 3488 String msg = "Permission Denial: crashApplication() from pid=" 3489 + Binder.getCallingPid() 3490 + ", uid=" + Binder.getCallingUid() 3491 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3492 Slog.w(TAG, msg); 3493 throw new SecurityException(msg); 3494 } 3495 3496 synchronized(this) { 3497 ProcessRecord proc = null; 3498 3499 // Figure out which process to kill. We don't trust that initialPid 3500 // still has any relation to current pids, so must scan through the 3501 // list. 3502 synchronized (mPidsSelfLocked) { 3503 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3504 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3505 if (p.uid != uid) { 3506 continue; 3507 } 3508 if (p.pid == initialPid) { 3509 proc = p; 3510 break; 3511 } 3512 if (p.pkgList.containsKey(packageName)) { 3513 proc = p; 3514 } 3515 } 3516 } 3517 3518 if (proc == null) { 3519 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3520 + " initialPid=" + initialPid 3521 + " packageName=" + packageName); 3522 return; 3523 } 3524 3525 if (proc.thread != null) { 3526 if (proc.pid == Process.myPid()) { 3527 Log.w(TAG, "crashApplication: trying to crash self!"); 3528 return; 3529 } 3530 long ident = Binder.clearCallingIdentity(); 3531 try { 3532 proc.thread.scheduleCrash(message); 3533 } catch (RemoteException e) { 3534 } 3535 Binder.restoreCallingIdentity(ident); 3536 } 3537 } 3538 } 3539 3540 @Override 3541 public final void finishSubActivity(IBinder token, String resultWho, 3542 int requestCode) { 3543 synchronized(this) { 3544 final long origId = Binder.clearCallingIdentity(); 3545 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3546 if (r != null) { 3547 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3548 } 3549 Binder.restoreCallingIdentity(origId); 3550 } 3551 } 3552 3553 @Override 3554 public boolean finishActivityAffinity(IBinder token) { 3555 synchronized(this) { 3556 final long origId = Binder.clearCallingIdentity(); 3557 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3558 boolean res = false; 3559 if (r != null) { 3560 res = r.task.stack.finishActivityAffinityLocked(r); 3561 } 3562 Binder.restoreCallingIdentity(origId); 3563 return res; 3564 } 3565 } 3566 3567 @Override 3568 public boolean willActivityBeVisible(IBinder token) { 3569 synchronized(this) { 3570 ActivityStack stack = ActivityRecord.getStackLocked(token); 3571 if (stack != null) { 3572 return stack.willActivityBeVisibleLocked(token); 3573 } 3574 return false; 3575 } 3576 } 3577 3578 @Override 3579 public void overridePendingTransition(IBinder token, String packageName, 3580 int enterAnim, int exitAnim) { 3581 synchronized(this) { 3582 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3583 if (self == null) { 3584 return; 3585 } 3586 3587 final long origId = Binder.clearCallingIdentity(); 3588 3589 if (self.state == ActivityState.RESUMED 3590 || self.state == ActivityState.PAUSING) { 3591 mWindowManager.overridePendingAppTransition(packageName, 3592 enterAnim, exitAnim, null); 3593 } 3594 3595 Binder.restoreCallingIdentity(origId); 3596 } 3597 } 3598 3599 /** 3600 * Main function for removing an existing process from the activity manager 3601 * as a result of that process going away. Clears out all connections 3602 * to the process. 3603 */ 3604 private final void handleAppDiedLocked(ProcessRecord app, 3605 boolean restarting, boolean allowRestart) { 3606 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3607 if (!restarting) { 3608 removeLruProcessLocked(app); 3609 } 3610 3611 if (mProfileProc == app) { 3612 clearProfilerLocked(); 3613 } 3614 3615 // Remove this application's activities from active lists. 3616 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3617 3618 app.activities.clear(); 3619 3620 if (app.instrumentationClass != null) { 3621 Slog.w(TAG, "Crash of app " + app.processName 3622 + " running instrumentation " + app.instrumentationClass); 3623 Bundle info = new Bundle(); 3624 info.putString("shortMsg", "Process crashed."); 3625 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3626 } 3627 3628 if (!restarting) { 3629 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3630 // If there was nothing to resume, and we are not already 3631 // restarting this process, but there is a visible activity that 3632 // is hosted by the process... then make sure all visible 3633 // activities are running, taking care of restarting this 3634 // process. 3635 if (hasVisibleActivities) { 3636 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3637 } 3638 } 3639 } 3640 } 3641 3642 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3643 IBinder threadBinder = thread.asBinder(); 3644 // Find the application record. 3645 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3646 ProcessRecord rec = mLruProcesses.get(i); 3647 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3648 return i; 3649 } 3650 } 3651 return -1; 3652 } 3653 3654 final ProcessRecord getRecordForAppLocked( 3655 IApplicationThread thread) { 3656 if (thread == null) { 3657 return null; 3658 } 3659 3660 int appIndex = getLRURecordIndexForAppLocked(thread); 3661 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3662 } 3663 3664 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3665 // If there are no longer any background processes running, 3666 // and the app that died was not running instrumentation, 3667 // then tell everyone we are now low on memory. 3668 boolean haveBg = false; 3669 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3670 ProcessRecord rec = mLruProcesses.get(i); 3671 if (rec.thread != null 3672 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3673 haveBg = true; 3674 break; 3675 } 3676 } 3677 3678 if (!haveBg) { 3679 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3680 if (doReport) { 3681 long now = SystemClock.uptimeMillis(); 3682 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3683 doReport = false; 3684 } else { 3685 mLastMemUsageReportTime = now; 3686 } 3687 } 3688 final ArrayList<ProcessMemInfo> memInfos 3689 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3690 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3691 long now = SystemClock.uptimeMillis(); 3692 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3693 ProcessRecord rec = mLruProcesses.get(i); 3694 if (rec == dyingProc || rec.thread == null) { 3695 continue; 3696 } 3697 if (doReport) { 3698 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3699 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3700 } 3701 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3702 // The low memory report is overriding any current 3703 // state for a GC request. Make sure to do 3704 // heavy/important/visible/foreground processes first. 3705 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3706 rec.lastRequestedGc = 0; 3707 } else { 3708 rec.lastRequestedGc = rec.lastLowMemory; 3709 } 3710 rec.reportLowMemory = true; 3711 rec.lastLowMemory = now; 3712 mProcessesToGc.remove(rec); 3713 addProcessToGcListLocked(rec); 3714 } 3715 } 3716 if (doReport) { 3717 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3718 mHandler.sendMessage(msg); 3719 } 3720 scheduleAppGcsLocked(); 3721 } 3722 } 3723 3724 final void appDiedLocked(ProcessRecord app, int pid, 3725 IApplicationThread thread) { 3726 3727 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3728 synchronized (stats) { 3729 stats.noteProcessDiedLocked(app.info.uid, pid); 3730 } 3731 3732 // Clean up already done if the process has been re-started. 3733 if (app.pid == pid && app.thread != null && 3734 app.thread.asBinder() == thread.asBinder()) { 3735 boolean doLowMem = app.instrumentationClass == null; 3736 boolean doOomAdj = doLowMem; 3737 if (!app.killedByAm) { 3738 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3739 + ") has died."); 3740 mAllowLowerMemLevel = true; 3741 } else { 3742 // Note that we always want to do oom adj to update our state with the 3743 // new number of procs. 3744 mAllowLowerMemLevel = false; 3745 doLowMem = false; 3746 } 3747 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3748 if (DEBUG_CLEANUP) Slog.v( 3749 TAG, "Dying app: " + app + ", pid: " + pid 3750 + ", thread: " + thread.asBinder()); 3751 handleAppDiedLocked(app, false, true); 3752 3753 if (doOomAdj) { 3754 updateOomAdjLocked(); 3755 } 3756 if (doLowMem) { 3757 doLowMemReportIfNeededLocked(app); 3758 } 3759 } else if (app.pid != pid) { 3760 // A new process has already been started. 3761 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3762 + ") has died and restarted (pid " + app.pid + ")."); 3763 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3764 } else if (DEBUG_PROCESSES) { 3765 Slog.d(TAG, "Received spurious death notification for thread " 3766 + thread.asBinder()); 3767 } 3768 } 3769 3770 /** 3771 * If a stack trace dump file is configured, dump process stack traces. 3772 * @param clearTraces causes the dump file to be erased prior to the new 3773 * traces being written, if true; when false, the new traces will be 3774 * appended to any existing file content. 3775 * @param firstPids of dalvik VM processes to dump stack traces for first 3776 * @param lastPids of dalvik VM processes to dump stack traces for last 3777 * @param nativeProcs optional list of native process names to dump stack crawls 3778 * @return file containing stack traces, or null if no dump file is configured 3779 */ 3780 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3781 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3782 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3783 if (tracesPath == null || tracesPath.length() == 0) { 3784 return null; 3785 } 3786 3787 File tracesFile = new File(tracesPath); 3788 try { 3789 File tracesDir = tracesFile.getParentFile(); 3790 if (!tracesDir.exists()) { 3791 tracesFile.mkdirs(); 3792 if (!SELinux.restorecon(tracesDir)) { 3793 return null; 3794 } 3795 } 3796 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3797 3798 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3799 tracesFile.createNewFile(); 3800 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3801 } catch (IOException e) { 3802 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3803 return null; 3804 } 3805 3806 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3807 return tracesFile; 3808 } 3809 3810 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3811 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3812 // Use a FileObserver to detect when traces finish writing. 3813 // The order of traces is considered important to maintain for legibility. 3814 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3815 @Override 3816 public synchronized void onEvent(int event, String path) { notify(); } 3817 }; 3818 3819 try { 3820 observer.startWatching(); 3821 3822 // First collect all of the stacks of the most important pids. 3823 if (firstPids != null) { 3824 try { 3825 int num = firstPids.size(); 3826 for (int i = 0; i < num; i++) { 3827 synchronized (observer) { 3828 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3829 observer.wait(200); // Wait for write-close, give up after 200msec 3830 } 3831 } 3832 } catch (InterruptedException e) { 3833 Log.wtf(TAG, e); 3834 } 3835 } 3836 3837 // Next collect the stacks of the native pids 3838 if (nativeProcs != null) { 3839 int[] pids = Process.getPidsForCommands(nativeProcs); 3840 if (pids != null) { 3841 for (int pid : pids) { 3842 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3843 } 3844 } 3845 } 3846 3847 // Lastly, measure CPU usage. 3848 if (processCpuTracker != null) { 3849 processCpuTracker.init(); 3850 System.gc(); 3851 processCpuTracker.update(); 3852 try { 3853 synchronized (processCpuTracker) { 3854 processCpuTracker.wait(500); // measure over 1/2 second. 3855 } 3856 } catch (InterruptedException e) { 3857 } 3858 processCpuTracker.update(); 3859 3860 // We'll take the stack crawls of just the top apps using CPU. 3861 final int N = processCpuTracker.countWorkingStats(); 3862 int numProcs = 0; 3863 for (int i=0; i<N && numProcs<5; i++) { 3864 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3865 if (lastPids.indexOfKey(stats.pid) >= 0) { 3866 numProcs++; 3867 try { 3868 synchronized (observer) { 3869 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3870 observer.wait(200); // Wait for write-close, give up after 200msec 3871 } 3872 } catch (InterruptedException e) { 3873 Log.wtf(TAG, e); 3874 } 3875 3876 } 3877 } 3878 } 3879 } finally { 3880 observer.stopWatching(); 3881 } 3882 } 3883 3884 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3885 if (true || IS_USER_BUILD) { 3886 return; 3887 } 3888 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3889 if (tracesPath == null || tracesPath.length() == 0) { 3890 return; 3891 } 3892 3893 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3894 StrictMode.allowThreadDiskWrites(); 3895 try { 3896 final File tracesFile = new File(tracesPath); 3897 final File tracesDir = tracesFile.getParentFile(); 3898 final File tracesTmp = new File(tracesDir, "__tmp__"); 3899 try { 3900 if (!tracesDir.exists()) { 3901 tracesFile.mkdirs(); 3902 if (!SELinux.restorecon(tracesDir.getPath())) { 3903 return; 3904 } 3905 } 3906 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3907 3908 if (tracesFile.exists()) { 3909 tracesTmp.delete(); 3910 tracesFile.renameTo(tracesTmp); 3911 } 3912 StringBuilder sb = new StringBuilder(); 3913 Time tobj = new Time(); 3914 tobj.set(System.currentTimeMillis()); 3915 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3916 sb.append(": "); 3917 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3918 sb.append(" since "); 3919 sb.append(msg); 3920 FileOutputStream fos = new FileOutputStream(tracesFile); 3921 fos.write(sb.toString().getBytes()); 3922 if (app == null) { 3923 fos.write("\n*** No application process!".getBytes()); 3924 } 3925 fos.close(); 3926 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3927 } catch (IOException e) { 3928 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3929 return; 3930 } 3931 3932 if (app != null) { 3933 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3934 firstPids.add(app.pid); 3935 dumpStackTraces(tracesPath, firstPids, null, null, null); 3936 } 3937 3938 File lastTracesFile = null; 3939 File curTracesFile = null; 3940 for (int i=9; i>=0; i--) { 3941 String name = String.format(Locale.US, "slow%02d.txt", i); 3942 curTracesFile = new File(tracesDir, name); 3943 if (curTracesFile.exists()) { 3944 if (lastTracesFile != null) { 3945 curTracesFile.renameTo(lastTracesFile); 3946 } else { 3947 curTracesFile.delete(); 3948 } 3949 } 3950 lastTracesFile = curTracesFile; 3951 } 3952 tracesFile.renameTo(curTracesFile); 3953 if (tracesTmp.exists()) { 3954 tracesTmp.renameTo(tracesFile); 3955 } 3956 } finally { 3957 StrictMode.setThreadPolicy(oldPolicy); 3958 } 3959 } 3960 3961 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3962 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3963 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3964 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3965 3966 if (mController != null) { 3967 try { 3968 // 0 == continue, -1 = kill process immediately 3969 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3970 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3971 } catch (RemoteException e) { 3972 mController = null; 3973 Watchdog.getInstance().setActivityController(null); 3974 } 3975 } 3976 3977 long anrTime = SystemClock.uptimeMillis(); 3978 if (MONITOR_CPU_USAGE) { 3979 updateCpuStatsNow(); 3980 } 3981 3982 synchronized (this) { 3983 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3984 if (mShuttingDown) { 3985 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3986 return; 3987 } else if (app.notResponding) { 3988 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3989 return; 3990 } else if (app.crashing) { 3991 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3992 return; 3993 } 3994 3995 // In case we come through here for the same app before completing 3996 // this one, mark as anring now so we will bail out. 3997 app.notResponding = true; 3998 3999 // Log the ANR to the event log. 4000 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4001 app.processName, app.info.flags, annotation); 4002 4003 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4004 firstPids.add(app.pid); 4005 4006 int parentPid = app.pid; 4007 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4008 if (parentPid != app.pid) firstPids.add(parentPid); 4009 4010 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4011 4012 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4013 ProcessRecord r = mLruProcesses.get(i); 4014 if (r != null && r.thread != null) { 4015 int pid = r.pid; 4016 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4017 if (r.persistent) { 4018 firstPids.add(pid); 4019 } else { 4020 lastPids.put(pid, Boolean.TRUE); 4021 } 4022 } 4023 } 4024 } 4025 } 4026 4027 // Log the ANR to the main log. 4028 StringBuilder info = new StringBuilder(); 4029 info.setLength(0); 4030 info.append("ANR in ").append(app.processName); 4031 if (activity != null && activity.shortComponentName != null) { 4032 info.append(" (").append(activity.shortComponentName).append(")"); 4033 } 4034 info.append("\n"); 4035 info.append("PID: ").append(app.pid).append("\n"); 4036 if (annotation != null) { 4037 info.append("Reason: ").append(annotation).append("\n"); 4038 } 4039 if (parent != null && parent != activity) { 4040 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4041 } 4042 4043 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4044 4045 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4046 NATIVE_STACKS_OF_INTEREST); 4047 4048 String cpuInfo = null; 4049 if (MONITOR_CPU_USAGE) { 4050 updateCpuStatsNow(); 4051 synchronized (mProcessCpuThread) { 4052 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4053 } 4054 info.append(processCpuTracker.printCurrentLoad()); 4055 info.append(cpuInfo); 4056 } 4057 4058 info.append(processCpuTracker.printCurrentState(anrTime)); 4059 4060 Slog.e(TAG, info.toString()); 4061 if (tracesFile == null) { 4062 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4063 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4064 } 4065 4066 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4067 cpuInfo, tracesFile, null); 4068 4069 if (mController != null) { 4070 try { 4071 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4072 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4073 if (res != 0) { 4074 if (res < 0 && app.pid != MY_PID) { 4075 Process.killProcess(app.pid); 4076 } else { 4077 synchronized (this) { 4078 mServices.scheduleServiceTimeoutLocked(app); 4079 } 4080 } 4081 return; 4082 } 4083 } catch (RemoteException e) { 4084 mController = null; 4085 Watchdog.getInstance().setActivityController(null); 4086 } 4087 } 4088 4089 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4090 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4091 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4092 4093 synchronized (this) { 4094 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4095 killUnneededProcessLocked(app, "background ANR"); 4096 return; 4097 } 4098 4099 // Set the app's notResponding state, and look up the errorReportReceiver 4100 makeAppNotRespondingLocked(app, 4101 activity != null ? activity.shortComponentName : null, 4102 annotation != null ? "ANR " + annotation : "ANR", 4103 info.toString()); 4104 4105 // Bring up the infamous App Not Responding dialog 4106 Message msg = Message.obtain(); 4107 HashMap<String, Object> map = new HashMap<String, Object>(); 4108 msg.what = SHOW_NOT_RESPONDING_MSG; 4109 msg.obj = map; 4110 msg.arg1 = aboveSystem ? 1 : 0; 4111 map.put("app", app); 4112 if (activity != null) { 4113 map.put("activity", activity); 4114 } 4115 4116 mHandler.sendMessage(msg); 4117 } 4118 } 4119 4120 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4121 if (!mLaunchWarningShown) { 4122 mLaunchWarningShown = true; 4123 mHandler.post(new Runnable() { 4124 @Override 4125 public void run() { 4126 synchronized (ActivityManagerService.this) { 4127 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4128 d.show(); 4129 mHandler.postDelayed(new Runnable() { 4130 @Override 4131 public void run() { 4132 synchronized (ActivityManagerService.this) { 4133 d.dismiss(); 4134 mLaunchWarningShown = false; 4135 } 4136 } 4137 }, 4000); 4138 } 4139 } 4140 }); 4141 } 4142 } 4143 4144 @Override 4145 public boolean clearApplicationUserData(final String packageName, 4146 final IPackageDataObserver observer, int userId) { 4147 enforceNotIsolatedCaller("clearApplicationUserData"); 4148 int uid = Binder.getCallingUid(); 4149 int pid = Binder.getCallingPid(); 4150 userId = handleIncomingUser(pid, uid, 4151 userId, false, true, "clearApplicationUserData", null); 4152 long callingId = Binder.clearCallingIdentity(); 4153 try { 4154 IPackageManager pm = AppGlobals.getPackageManager(); 4155 int pkgUid = -1; 4156 synchronized(this) { 4157 try { 4158 pkgUid = pm.getPackageUid(packageName, userId); 4159 } catch (RemoteException e) { 4160 } 4161 if (pkgUid == -1) { 4162 Slog.w(TAG, "Invalid packageName: " + packageName); 4163 if (observer != null) { 4164 try { 4165 observer.onRemoveCompleted(packageName, false); 4166 } catch (RemoteException e) { 4167 Slog.i(TAG, "Observer no longer exists."); 4168 } 4169 } 4170 return false; 4171 } 4172 if (uid == pkgUid || checkComponentPermission( 4173 android.Manifest.permission.CLEAR_APP_USER_DATA, 4174 pid, uid, -1, true) 4175 == PackageManager.PERMISSION_GRANTED) { 4176 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4177 } else { 4178 throw new SecurityException(pid+" does not have permission:"+ 4179 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 4180 "for process:"+packageName); 4181 } 4182 } 4183 4184 try { 4185 // Clear application user data 4186 pm.clearApplicationUserData(packageName, observer, userId); 4187 4188 // Remove all permissions granted from/to this package 4189 removeUriPermissionsForPackageLocked(packageName, userId, true); 4190 4191 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4192 Uri.fromParts("package", packageName, null)); 4193 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4194 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4195 null, null, 0, null, null, null, false, false, userId); 4196 } catch (RemoteException e) { 4197 } 4198 } finally { 4199 Binder.restoreCallingIdentity(callingId); 4200 } 4201 return true; 4202 } 4203 4204 @Override 4205 public void killBackgroundProcesses(final String packageName, int userId) { 4206 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4207 != PackageManager.PERMISSION_GRANTED && 4208 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4209 != PackageManager.PERMISSION_GRANTED) { 4210 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4211 + Binder.getCallingPid() 4212 + ", uid=" + Binder.getCallingUid() 4213 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4214 Slog.w(TAG, msg); 4215 throw new SecurityException(msg); 4216 } 4217 4218 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4219 userId, true, true, "killBackgroundProcesses", null); 4220 long callingId = Binder.clearCallingIdentity(); 4221 try { 4222 IPackageManager pm = AppGlobals.getPackageManager(); 4223 synchronized(this) { 4224 int appId = -1; 4225 try { 4226 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4227 } catch (RemoteException e) { 4228 } 4229 if (appId == -1) { 4230 Slog.w(TAG, "Invalid packageName: " + packageName); 4231 return; 4232 } 4233 killPackageProcessesLocked(packageName, appId, userId, 4234 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4235 } 4236 } finally { 4237 Binder.restoreCallingIdentity(callingId); 4238 } 4239 } 4240 4241 @Override 4242 public void killAllBackgroundProcesses() { 4243 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4244 != PackageManager.PERMISSION_GRANTED) { 4245 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4246 + Binder.getCallingPid() 4247 + ", uid=" + Binder.getCallingUid() 4248 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4249 Slog.w(TAG, msg); 4250 throw new SecurityException(msg); 4251 } 4252 4253 long callingId = Binder.clearCallingIdentity(); 4254 try { 4255 synchronized(this) { 4256 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4257 final int NP = mProcessNames.getMap().size(); 4258 for (int ip=0; ip<NP; ip++) { 4259 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4260 final int NA = apps.size(); 4261 for (int ia=0; ia<NA; ia++) { 4262 ProcessRecord app = apps.valueAt(ia); 4263 if (app.persistent) { 4264 // we don't kill persistent processes 4265 continue; 4266 } 4267 if (app.removed) { 4268 procs.add(app); 4269 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4270 app.removed = true; 4271 procs.add(app); 4272 } 4273 } 4274 } 4275 4276 int N = procs.size(); 4277 for (int i=0; i<N; i++) { 4278 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4279 } 4280 mAllowLowerMemLevel = true; 4281 updateOomAdjLocked(); 4282 doLowMemReportIfNeededLocked(null); 4283 } 4284 } finally { 4285 Binder.restoreCallingIdentity(callingId); 4286 } 4287 } 4288 4289 @Override 4290 public void forceStopPackage(final String packageName, int userId) { 4291 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4292 != PackageManager.PERMISSION_GRANTED) { 4293 String msg = "Permission Denial: forceStopPackage() from pid=" 4294 + Binder.getCallingPid() 4295 + ", uid=" + Binder.getCallingUid() 4296 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4297 Slog.w(TAG, msg); 4298 throw new SecurityException(msg); 4299 } 4300 final int callingPid = Binder.getCallingPid(); 4301 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4302 userId, true, true, "forceStopPackage", null); 4303 long callingId = Binder.clearCallingIdentity(); 4304 try { 4305 IPackageManager pm = AppGlobals.getPackageManager(); 4306 synchronized(this) { 4307 int[] users = userId == UserHandle.USER_ALL 4308 ? getUsersLocked() : new int[] { userId }; 4309 for (int user : users) { 4310 int pkgUid = -1; 4311 try { 4312 pkgUid = pm.getPackageUid(packageName, user); 4313 } catch (RemoteException e) { 4314 } 4315 if (pkgUid == -1) { 4316 Slog.w(TAG, "Invalid packageName: " + packageName); 4317 continue; 4318 } 4319 try { 4320 pm.setPackageStoppedState(packageName, true, user); 4321 } catch (RemoteException e) { 4322 } catch (IllegalArgumentException e) { 4323 Slog.w(TAG, "Failed trying to unstop package " 4324 + packageName + ": " + e); 4325 } 4326 if (isUserRunningLocked(user, false)) { 4327 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4328 } 4329 } 4330 } 4331 } finally { 4332 Binder.restoreCallingIdentity(callingId); 4333 } 4334 } 4335 4336 /* 4337 * The pkg name and app id have to be specified. 4338 */ 4339 @Override 4340 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4341 if (pkg == null) { 4342 return; 4343 } 4344 // Make sure the uid is valid. 4345 if (appid < 0) { 4346 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4347 return; 4348 } 4349 int callerUid = Binder.getCallingUid(); 4350 // Only the system server can kill an application 4351 if (callerUid == Process.SYSTEM_UID) { 4352 // Post an aysnc message to kill the application 4353 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4354 msg.arg1 = appid; 4355 msg.arg2 = 0; 4356 Bundle bundle = new Bundle(); 4357 bundle.putString("pkg", pkg); 4358 bundle.putString("reason", reason); 4359 msg.obj = bundle; 4360 mHandler.sendMessage(msg); 4361 } else { 4362 throw new SecurityException(callerUid + " cannot kill pkg: " + 4363 pkg); 4364 } 4365 } 4366 4367 @Override 4368 public void closeSystemDialogs(String reason) { 4369 enforceNotIsolatedCaller("closeSystemDialogs"); 4370 4371 final int pid = Binder.getCallingPid(); 4372 final int uid = Binder.getCallingUid(); 4373 final long origId = Binder.clearCallingIdentity(); 4374 try { 4375 synchronized (this) { 4376 // Only allow this from foreground processes, so that background 4377 // applications can't abuse it to prevent system UI from being shown. 4378 if (uid >= Process.FIRST_APPLICATION_UID) { 4379 ProcessRecord proc; 4380 synchronized (mPidsSelfLocked) { 4381 proc = mPidsSelfLocked.get(pid); 4382 } 4383 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4384 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4385 + " from background process " + proc); 4386 return; 4387 } 4388 } 4389 closeSystemDialogsLocked(reason); 4390 } 4391 } finally { 4392 Binder.restoreCallingIdentity(origId); 4393 } 4394 } 4395 4396 void closeSystemDialogsLocked(String reason) { 4397 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4398 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4399 | Intent.FLAG_RECEIVER_FOREGROUND); 4400 if (reason != null) { 4401 intent.putExtra("reason", reason); 4402 } 4403 mWindowManager.closeSystemDialogs(reason); 4404 4405 mStackSupervisor.closeSystemDialogsLocked(); 4406 4407 broadcastIntentLocked(null, null, intent, null, 4408 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4409 Process.SYSTEM_UID, UserHandle.USER_ALL); 4410 } 4411 4412 @Override 4413 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4414 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4415 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4416 for (int i=pids.length-1; i>=0; i--) { 4417 ProcessRecord proc; 4418 int oomAdj; 4419 synchronized (this) { 4420 synchronized (mPidsSelfLocked) { 4421 proc = mPidsSelfLocked.get(pids[i]); 4422 oomAdj = proc != null ? proc.setAdj : 0; 4423 } 4424 } 4425 infos[i] = new Debug.MemoryInfo(); 4426 Debug.getMemoryInfo(pids[i], infos[i]); 4427 if (proc != null) { 4428 synchronized (this) { 4429 if (proc.thread != null && proc.setAdj == oomAdj) { 4430 // Record this for posterity if the process has been stable. 4431 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4432 infos[i].getTotalUss(), false, proc.pkgList); 4433 } 4434 } 4435 } 4436 } 4437 return infos; 4438 } 4439 4440 @Override 4441 public long[] getProcessPss(int[] pids) { 4442 enforceNotIsolatedCaller("getProcessPss"); 4443 long[] pss = new long[pids.length]; 4444 for (int i=pids.length-1; i>=0; i--) { 4445 ProcessRecord proc; 4446 int oomAdj; 4447 synchronized (this) { 4448 synchronized (mPidsSelfLocked) { 4449 proc = mPidsSelfLocked.get(pids[i]); 4450 oomAdj = proc != null ? proc.setAdj : 0; 4451 } 4452 } 4453 long[] tmpUss = new long[1]; 4454 pss[i] = Debug.getPss(pids[i], tmpUss); 4455 if (proc != null) { 4456 synchronized (this) { 4457 if (proc.thread != null && proc.setAdj == oomAdj) { 4458 // Record this for posterity if the process has been stable. 4459 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4460 } 4461 } 4462 } 4463 } 4464 return pss; 4465 } 4466 4467 @Override 4468 public void killApplicationProcess(String processName, int uid) { 4469 if (processName == null) { 4470 return; 4471 } 4472 4473 int callerUid = Binder.getCallingUid(); 4474 // Only the system server can kill an application 4475 if (callerUid == Process.SYSTEM_UID) { 4476 synchronized (this) { 4477 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4478 if (app != null && app.thread != null) { 4479 try { 4480 app.thread.scheduleSuicide(); 4481 } catch (RemoteException e) { 4482 // If the other end already died, then our work here is done. 4483 } 4484 } else { 4485 Slog.w(TAG, "Process/uid not found attempting kill of " 4486 + processName + " / " + uid); 4487 } 4488 } 4489 } else { 4490 throw new SecurityException(callerUid + " cannot kill app process: " + 4491 processName); 4492 } 4493 } 4494 4495 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4496 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4497 false, true, false, UserHandle.getUserId(uid), reason); 4498 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4499 Uri.fromParts("package", packageName, null)); 4500 if (!mProcessesReady) { 4501 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4502 | Intent.FLAG_RECEIVER_FOREGROUND); 4503 } 4504 intent.putExtra(Intent.EXTRA_UID, uid); 4505 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4506 broadcastIntentLocked(null, null, intent, 4507 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4508 false, false, 4509 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4510 } 4511 4512 private void forceStopUserLocked(int userId, String reason) { 4513 forceStopPackageLocked(null, -1, false, false, true, false, userId, reason); 4514 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4515 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4516 | Intent.FLAG_RECEIVER_FOREGROUND); 4517 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4518 broadcastIntentLocked(null, null, intent, 4519 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4520 false, false, 4521 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4522 } 4523 4524 private final boolean killPackageProcessesLocked(String packageName, int appId, 4525 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4526 boolean doit, boolean evenPersistent, String reason) { 4527 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4528 4529 // Remove all processes this package may have touched: all with the 4530 // same UID (except for the system or root user), and all whose name 4531 // matches the package name. 4532 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4533 final int NP = mProcessNames.getMap().size(); 4534 for (int ip=0; ip<NP; ip++) { 4535 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4536 final int NA = apps.size(); 4537 for (int ia=0; ia<NA; ia++) { 4538 ProcessRecord app = apps.valueAt(ia); 4539 if (app.persistent && !evenPersistent) { 4540 // we don't kill persistent processes 4541 continue; 4542 } 4543 if (app.removed) { 4544 if (doit) { 4545 procs.add(app); 4546 } 4547 continue; 4548 } 4549 4550 // Skip process if it doesn't meet our oom adj requirement. 4551 if (app.setAdj < minOomAdj) { 4552 continue; 4553 } 4554 4555 // If no package is specified, we call all processes under the 4556 // give user id. 4557 if (packageName == null) { 4558 if (app.userId != userId) { 4559 continue; 4560 } 4561 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4562 continue; 4563 } 4564 // Package has been specified, we want to hit all processes 4565 // that match it. We need to qualify this by the processes 4566 // that are running under the specified app and user ID. 4567 } else { 4568 if (UserHandle.getAppId(app.uid) != appId) { 4569 continue; 4570 } 4571 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4572 continue; 4573 } 4574 if (!app.pkgList.containsKey(packageName)) { 4575 continue; 4576 } 4577 } 4578 4579 // Process has passed all conditions, kill it! 4580 if (!doit) { 4581 return true; 4582 } 4583 app.removed = true; 4584 procs.add(app); 4585 } 4586 } 4587 4588 int N = procs.size(); 4589 for (int i=0; i<N; i++) { 4590 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4591 } 4592 updateOomAdjLocked(); 4593 return N > 0; 4594 } 4595 4596 private final boolean forceStopPackageLocked(String name, int appId, 4597 boolean callerWillRestart, boolean purgeCache, boolean doit, 4598 boolean evenPersistent, int userId, String reason) { 4599 int i; 4600 int N; 4601 4602 if (userId == UserHandle.USER_ALL && name == null) { 4603 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4604 } 4605 4606 if (appId < 0 && name != null) { 4607 try { 4608 appId = UserHandle.getAppId( 4609 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4610 } catch (RemoteException e) { 4611 } 4612 } 4613 4614 if (doit) { 4615 if (name != null) { 4616 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4617 + " user=" + userId + ": " + reason); 4618 } else { 4619 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4620 } 4621 4622 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4623 for (int ip=pmap.size()-1; ip>=0; ip--) { 4624 SparseArray<Long> ba = pmap.valueAt(ip); 4625 for (i=ba.size()-1; i>=0; i--) { 4626 boolean remove = false; 4627 final int entUid = ba.keyAt(i); 4628 if (name != null) { 4629 if (userId == UserHandle.USER_ALL) { 4630 if (UserHandle.getAppId(entUid) == appId) { 4631 remove = true; 4632 } 4633 } else { 4634 if (entUid == UserHandle.getUid(userId, appId)) { 4635 remove = true; 4636 } 4637 } 4638 } else if (UserHandle.getUserId(entUid) == userId) { 4639 remove = true; 4640 } 4641 if (remove) { 4642 ba.removeAt(i); 4643 } 4644 } 4645 if (ba.size() == 0) { 4646 pmap.removeAt(ip); 4647 } 4648 } 4649 } 4650 4651 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4652 -100, callerWillRestart, true, doit, evenPersistent, 4653 name == null ? ("stop user " + userId) : ("stop " + name)); 4654 4655 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4656 if (!doit) { 4657 return true; 4658 } 4659 didSomething = true; 4660 } 4661 4662 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4663 if (!doit) { 4664 return true; 4665 } 4666 didSomething = true; 4667 } 4668 4669 if (name == null) { 4670 // Remove all sticky broadcasts from this user. 4671 mStickyBroadcasts.remove(userId); 4672 } 4673 4674 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4675 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4676 userId, providers)) { 4677 if (!doit) { 4678 return true; 4679 } 4680 didSomething = true; 4681 } 4682 N = providers.size(); 4683 for (i=0; i<N; i++) { 4684 removeDyingProviderLocked(null, providers.get(i), true); 4685 } 4686 4687 // Remove transient permissions granted from/to this package/user 4688 removeUriPermissionsForPackageLocked(name, userId, false); 4689 4690 if (name == null) { 4691 // Remove pending intents. For now we only do this when force 4692 // stopping users, because we have some problems when doing this 4693 // for packages -- app widgets are not currently cleaned up for 4694 // such packages, so they can be left with bad pending intents. 4695 if (mIntentSenderRecords.size() > 0) { 4696 Iterator<WeakReference<PendingIntentRecord>> it 4697 = mIntentSenderRecords.values().iterator(); 4698 while (it.hasNext()) { 4699 WeakReference<PendingIntentRecord> wpir = it.next(); 4700 if (wpir == null) { 4701 it.remove(); 4702 continue; 4703 } 4704 PendingIntentRecord pir = wpir.get(); 4705 if (pir == null) { 4706 it.remove(); 4707 continue; 4708 } 4709 if (name == null) { 4710 // Stopping user, remove all objects for the user. 4711 if (pir.key.userId != userId) { 4712 // Not the same user, skip it. 4713 continue; 4714 } 4715 } else { 4716 if (UserHandle.getAppId(pir.uid) != appId) { 4717 // Different app id, skip it. 4718 continue; 4719 } 4720 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4721 // Different user, skip it. 4722 continue; 4723 } 4724 if (!pir.key.packageName.equals(name)) { 4725 // Different package, skip it. 4726 continue; 4727 } 4728 } 4729 if (!doit) { 4730 return true; 4731 } 4732 didSomething = true; 4733 it.remove(); 4734 pir.canceled = true; 4735 if (pir.key.activity != null) { 4736 pir.key.activity.pendingResults.remove(pir.ref); 4737 } 4738 } 4739 } 4740 } 4741 4742 if (doit) { 4743 if (purgeCache && name != null) { 4744 AttributeCache ac = AttributeCache.instance(); 4745 if (ac != null) { 4746 ac.removePackage(name); 4747 } 4748 } 4749 if (mBooted) { 4750 mStackSupervisor.resumeTopActivitiesLocked(); 4751 mStackSupervisor.scheduleIdleLocked(); 4752 } 4753 } 4754 4755 return didSomething; 4756 } 4757 4758 private final boolean removeProcessLocked(ProcessRecord app, 4759 boolean callerWillRestart, boolean allowRestart, String reason) { 4760 final String name = app.processName; 4761 final int uid = app.uid; 4762 if (DEBUG_PROCESSES) Slog.d( 4763 TAG, "Force removing proc " + app.toShortString() + " (" + name 4764 + "/" + uid + ")"); 4765 4766 mProcessNames.remove(name, uid); 4767 mIsolatedProcesses.remove(app.uid); 4768 if (mHeavyWeightProcess == app) { 4769 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4770 mHeavyWeightProcess.userId, 0)); 4771 mHeavyWeightProcess = null; 4772 } 4773 boolean needRestart = false; 4774 if (app.pid > 0 && app.pid != MY_PID) { 4775 int pid = app.pid; 4776 synchronized (mPidsSelfLocked) { 4777 mPidsSelfLocked.remove(pid); 4778 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4779 } 4780 killUnneededProcessLocked(app, reason); 4781 handleAppDiedLocked(app, true, allowRestart); 4782 removeLruProcessLocked(app); 4783 4784 if (app.persistent && !app.isolated) { 4785 if (!callerWillRestart) { 4786 addAppLocked(app.info, false); 4787 } else { 4788 needRestart = true; 4789 } 4790 } 4791 } else { 4792 mRemovedProcesses.add(app); 4793 } 4794 4795 return needRestart; 4796 } 4797 4798 private final void processStartTimedOutLocked(ProcessRecord app) { 4799 final int pid = app.pid; 4800 boolean gone = false; 4801 synchronized (mPidsSelfLocked) { 4802 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4803 if (knownApp != null && knownApp.thread == null) { 4804 mPidsSelfLocked.remove(pid); 4805 gone = true; 4806 } 4807 } 4808 4809 if (gone) { 4810 Slog.w(TAG, "Process " + app + " failed to attach"); 4811 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4812 pid, app.uid, app.processName); 4813 mProcessNames.remove(app.processName, app.uid); 4814 mIsolatedProcesses.remove(app.uid); 4815 if (mHeavyWeightProcess == app) { 4816 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4817 mHeavyWeightProcess.userId, 0)); 4818 mHeavyWeightProcess = null; 4819 } 4820 // Take care of any launching providers waiting for this process. 4821 checkAppInLaunchingProvidersLocked(app, true); 4822 // Take care of any services that are waiting for the process. 4823 mServices.processStartTimedOutLocked(app); 4824 killUnneededProcessLocked(app, "start timeout"); 4825 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4826 Slog.w(TAG, "Unattached app died before backup, skipping"); 4827 try { 4828 IBackupManager bm = IBackupManager.Stub.asInterface( 4829 ServiceManager.getService(Context.BACKUP_SERVICE)); 4830 bm.agentDisconnected(app.info.packageName); 4831 } catch (RemoteException e) { 4832 // Can't happen; the backup manager is local 4833 } 4834 } 4835 if (isPendingBroadcastProcessLocked(pid)) { 4836 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4837 skipPendingBroadcastLocked(pid); 4838 } 4839 } else { 4840 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4841 } 4842 } 4843 4844 private final boolean attachApplicationLocked(IApplicationThread thread, 4845 int pid) { 4846 4847 // Find the application record that is being attached... either via 4848 // the pid if we are running in multiple processes, or just pull the 4849 // next app record if we are emulating process with anonymous threads. 4850 ProcessRecord app; 4851 if (pid != MY_PID && pid >= 0) { 4852 synchronized (mPidsSelfLocked) { 4853 app = mPidsSelfLocked.get(pid); 4854 } 4855 } else { 4856 app = null; 4857 } 4858 4859 if (app == null) { 4860 Slog.w(TAG, "No pending application record for pid " + pid 4861 + " (IApplicationThread " + thread + "); dropping process"); 4862 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4863 if (pid > 0 && pid != MY_PID) { 4864 Process.killProcessQuiet(pid); 4865 } else { 4866 try { 4867 thread.scheduleExit(); 4868 } catch (Exception e) { 4869 // Ignore exceptions. 4870 } 4871 } 4872 return false; 4873 } 4874 4875 // If this application record is still attached to a previous 4876 // process, clean it up now. 4877 if (app.thread != null) { 4878 handleAppDiedLocked(app, true, true); 4879 } 4880 4881 // Tell the process all about itself. 4882 4883 if (localLOGV) Slog.v( 4884 TAG, "Binding process pid " + pid + " to record " + app); 4885 4886 final String processName = app.processName; 4887 try { 4888 AppDeathRecipient adr = new AppDeathRecipient( 4889 app, pid, thread); 4890 thread.asBinder().linkToDeath(adr, 0); 4891 app.deathRecipient = adr; 4892 } catch (RemoteException e) { 4893 app.resetPackageList(mProcessStats); 4894 startProcessLocked(app, "link fail", processName); 4895 return false; 4896 } 4897 4898 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4899 4900 app.makeActive(thread, mProcessStats); 4901 app.curAdj = app.setAdj = -100; 4902 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4903 app.forcingToForeground = null; 4904 app.foregroundServices = false; 4905 app.hasShownUi = false; 4906 app.debugging = false; 4907 app.cached = false; 4908 4909 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4910 4911 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4912 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4913 4914 if (!normalMode) { 4915 Slog.i(TAG, "Launching preboot mode app: " + app); 4916 } 4917 4918 if (localLOGV) Slog.v( 4919 TAG, "New app record " + app 4920 + " thread=" + thread.asBinder() + " pid=" + pid); 4921 try { 4922 int testMode = IApplicationThread.DEBUG_OFF; 4923 if (mDebugApp != null && mDebugApp.equals(processName)) { 4924 testMode = mWaitForDebugger 4925 ? IApplicationThread.DEBUG_WAIT 4926 : IApplicationThread.DEBUG_ON; 4927 app.debugging = true; 4928 if (mDebugTransient) { 4929 mDebugApp = mOrigDebugApp; 4930 mWaitForDebugger = mOrigWaitForDebugger; 4931 } 4932 } 4933 String profileFile = app.instrumentationProfileFile; 4934 ParcelFileDescriptor profileFd = null; 4935 boolean profileAutoStop = false; 4936 if (mProfileApp != null && mProfileApp.equals(processName)) { 4937 mProfileProc = app; 4938 profileFile = mProfileFile; 4939 profileFd = mProfileFd; 4940 profileAutoStop = mAutoStopProfiler; 4941 } 4942 boolean enableOpenGlTrace = false; 4943 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4944 enableOpenGlTrace = true; 4945 mOpenGlTraceApp = null; 4946 } 4947 4948 // If the app is being launched for restore or full backup, set it up specially 4949 boolean isRestrictedBackupMode = false; 4950 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4951 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4952 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4953 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4954 } 4955 4956 ensurePackageDexOpt(app.instrumentationInfo != null 4957 ? app.instrumentationInfo.packageName 4958 : app.info.packageName); 4959 if (app.instrumentationClass != null) { 4960 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4961 } 4962 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4963 + processName + " with config " + mConfiguration); 4964 ApplicationInfo appInfo = app.instrumentationInfo != null 4965 ? app.instrumentationInfo : app.info; 4966 app.compat = compatibilityInfoForPackageLocked(appInfo); 4967 if (profileFd != null) { 4968 profileFd = profileFd.dup(); 4969 } 4970 thread.bindApplication(processName, appInfo, providers, 4971 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4972 app.instrumentationArguments, app.instrumentationWatcher, 4973 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4974 isRestrictedBackupMode || !normalMode, app.persistent, 4975 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4976 mCoreSettingsObserver.getCoreSettingsLocked()); 4977 updateLruProcessLocked(app, false, null); 4978 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4979 } catch (Exception e) { 4980 // todo: Yikes! What should we do? For now we will try to 4981 // start another process, but that could easily get us in 4982 // an infinite loop of restarting processes... 4983 Slog.w(TAG, "Exception thrown during bind!", e); 4984 4985 app.resetPackageList(mProcessStats); 4986 app.unlinkDeathRecipient(); 4987 startProcessLocked(app, "bind fail", processName); 4988 return false; 4989 } 4990 4991 // Remove this record from the list of starting applications. 4992 mPersistentStartingProcesses.remove(app); 4993 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4994 "Attach application locked removing on hold: " + app); 4995 mProcessesOnHold.remove(app); 4996 4997 boolean badApp = false; 4998 boolean didSomething = false; 4999 5000 // See if the top visible activity is waiting to run in this process... 5001 if (normalMode) { 5002 try { 5003 if (mStackSupervisor.attachApplicationLocked(app, mHeadless)) { 5004 didSomething = true; 5005 } 5006 } catch (Exception e) { 5007 badApp = true; 5008 } 5009 } 5010 5011 // Find any services that should be running in this process... 5012 if (!badApp) { 5013 try { 5014 didSomething |= mServices.attachApplicationLocked(app, processName); 5015 } catch (Exception e) { 5016 badApp = true; 5017 } 5018 } 5019 5020 // Check if a next-broadcast receiver is in this process... 5021 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5022 try { 5023 didSomething |= sendPendingBroadcastsLocked(app); 5024 } catch (Exception e) { 5025 // If the app died trying to launch the receiver we declare it 'bad' 5026 badApp = true; 5027 } 5028 } 5029 5030 // Check whether the next backup agent is in this process... 5031 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5032 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5033 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5034 try { 5035 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5036 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5037 mBackupTarget.backupMode); 5038 } catch (Exception e) { 5039 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5040 e.printStackTrace(); 5041 } 5042 } 5043 5044 if (badApp) { 5045 // todo: Also need to kill application to deal with all 5046 // kinds of exceptions. 5047 handleAppDiedLocked(app, false, true); 5048 return false; 5049 } 5050 5051 if (!didSomething) { 5052 updateOomAdjLocked(); 5053 } 5054 5055 return true; 5056 } 5057 5058 @Override 5059 public final void attachApplication(IApplicationThread thread) { 5060 synchronized (this) { 5061 int callingPid = Binder.getCallingPid(); 5062 final long origId = Binder.clearCallingIdentity(); 5063 attachApplicationLocked(thread, callingPid); 5064 Binder.restoreCallingIdentity(origId); 5065 } 5066 } 5067 5068 @Override 5069 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5070 final long origId = Binder.clearCallingIdentity(); 5071 synchronized (this) { 5072 ActivityStack stack = ActivityRecord.getStackLocked(token); 5073 if (stack != null) { 5074 ActivityRecord r = 5075 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5076 if (stopProfiling) { 5077 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5078 try { 5079 mProfileFd.close(); 5080 } catch (IOException e) { 5081 } 5082 clearProfilerLocked(); 5083 } 5084 } 5085 } 5086 } 5087 Binder.restoreCallingIdentity(origId); 5088 } 5089 5090 void enableScreenAfterBoot() { 5091 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5092 SystemClock.uptimeMillis()); 5093 mWindowManager.enableScreenAfterBoot(); 5094 5095 synchronized (this) { 5096 updateEventDispatchingLocked(); 5097 } 5098 } 5099 5100 @Override 5101 public void showBootMessage(final CharSequence msg, final boolean always) { 5102 enforceNotIsolatedCaller("showBootMessage"); 5103 mWindowManager.showBootMessage(msg, always); 5104 } 5105 5106 @Override 5107 public void dismissKeyguardOnNextActivity() { 5108 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5109 final long token = Binder.clearCallingIdentity(); 5110 try { 5111 synchronized (this) { 5112 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5113 if (mLockScreenShown) { 5114 mLockScreenShown = false; 5115 comeOutOfSleepIfNeededLocked(); 5116 } 5117 mStackSupervisor.setDismissKeyguard(true); 5118 } 5119 } finally { 5120 Binder.restoreCallingIdentity(token); 5121 } 5122 } 5123 5124 final void finishBooting() { 5125 IntentFilter pkgFilter = new IntentFilter(); 5126 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5127 pkgFilter.addDataScheme("package"); 5128 mContext.registerReceiver(new BroadcastReceiver() { 5129 @Override 5130 public void onReceive(Context context, Intent intent) { 5131 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5132 if (pkgs != null) { 5133 for (String pkg : pkgs) { 5134 synchronized (ActivityManagerService.this) { 5135 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0, 5136 "finished booting")) { 5137 setResultCode(Activity.RESULT_OK); 5138 return; 5139 } 5140 } 5141 } 5142 } 5143 } 5144 }, pkgFilter); 5145 5146 synchronized (this) { 5147 // Ensure that any processes we had put on hold are now started 5148 // up. 5149 final int NP = mProcessesOnHold.size(); 5150 if (NP > 0) { 5151 ArrayList<ProcessRecord> procs = 5152 new ArrayList<ProcessRecord>(mProcessesOnHold); 5153 for (int ip=0; ip<NP; ip++) { 5154 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5155 + procs.get(ip)); 5156 startProcessLocked(procs.get(ip), "on-hold", null); 5157 } 5158 } 5159 5160 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 5161 // Start looking for apps that are abusing wake locks. 5162 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5163 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5164 // Tell anyone interested that we are done booting! 5165 SystemProperties.set("sys.boot_completed", "1"); 5166 SystemProperties.set("dev.bootcomplete", "1"); 5167 for (int i=0; i<mStartedUsers.size(); i++) { 5168 UserStartedState uss = mStartedUsers.valueAt(i); 5169 if (uss.mState == UserStartedState.STATE_BOOTING) { 5170 uss.mState = UserStartedState.STATE_RUNNING; 5171 final int userId = mStartedUsers.keyAt(i); 5172 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5173 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5174 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5175 broadcastIntentLocked(null, null, intent, null, 5176 new IIntentReceiver.Stub() { 5177 @Override 5178 public void performReceive(Intent intent, int resultCode, 5179 String data, Bundle extras, boolean ordered, 5180 boolean sticky, int sendingUser) { 5181 synchronized (ActivityManagerService.this) { 5182 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5183 true, false); 5184 } 5185 } 5186 }, 5187 0, null, null, 5188 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5189 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5190 userId); 5191 } 5192 } 5193 } 5194 } 5195 } 5196 5197 final void ensureBootCompleted() { 5198 boolean booting; 5199 boolean enableScreen; 5200 synchronized (this) { 5201 booting = mBooting; 5202 mBooting = false; 5203 enableScreen = !mBooted; 5204 mBooted = true; 5205 } 5206 5207 if (booting) { 5208 finishBooting(); 5209 } 5210 5211 if (enableScreen) { 5212 enableScreenAfterBoot(); 5213 } 5214 } 5215 5216 @Override 5217 public final void activityResumed(IBinder token) { 5218 final long origId = Binder.clearCallingIdentity(); 5219 synchronized(this) { 5220 ActivityStack stack = ActivityRecord.getStackLocked(token); 5221 if (stack != null) { 5222 ActivityRecord.activityResumedLocked(token); 5223 } 5224 } 5225 Binder.restoreCallingIdentity(origId); 5226 } 5227 5228 @Override 5229 public final void activityPaused(IBinder token) { 5230 final long origId = Binder.clearCallingIdentity(); 5231 synchronized(this) { 5232 ActivityStack stack = ActivityRecord.getStackLocked(token); 5233 if (stack != null) { 5234 stack.activityPausedLocked(token, false); 5235 } 5236 } 5237 Binder.restoreCallingIdentity(origId); 5238 } 5239 5240 @Override 5241 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5242 CharSequence description) { 5243 if (localLOGV) Slog.v( 5244 TAG, "Activity stopped: token=" + token); 5245 5246 // Refuse possible leaked file descriptors 5247 if (icicle != null && icicle.hasFileDescriptors()) { 5248 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5249 } 5250 5251 ActivityRecord r = null; 5252 5253 final long origId = Binder.clearCallingIdentity(); 5254 5255 synchronized (this) { 5256 r = ActivityRecord.isInStackLocked(token); 5257 if (r != null) { 5258 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5259 } 5260 } 5261 5262 if (r != null) { 5263 sendPendingThumbnail(r, null, null, null, false); 5264 } 5265 5266 trimApplications(); 5267 5268 Binder.restoreCallingIdentity(origId); 5269 } 5270 5271 @Override 5272 public final void activityDestroyed(IBinder token) { 5273 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5274 synchronized (this) { 5275 ActivityStack stack = ActivityRecord.getStackLocked(token); 5276 if (stack != null) { 5277 stack.activityDestroyedLocked(token); 5278 } 5279 } 5280 } 5281 5282 @Override 5283 public String getCallingPackage(IBinder token) { 5284 synchronized (this) { 5285 ActivityRecord r = getCallingRecordLocked(token); 5286 return r != null ? r.info.packageName : null; 5287 } 5288 } 5289 5290 @Override 5291 public ComponentName getCallingActivity(IBinder token) { 5292 synchronized (this) { 5293 ActivityRecord r = getCallingRecordLocked(token); 5294 return r != null ? r.intent.getComponent() : null; 5295 } 5296 } 5297 5298 private ActivityRecord getCallingRecordLocked(IBinder token) { 5299 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5300 if (r == null) { 5301 return null; 5302 } 5303 return r.resultTo; 5304 } 5305 5306 @Override 5307 public ComponentName getActivityClassForToken(IBinder token) { 5308 synchronized(this) { 5309 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5310 if (r == null) { 5311 return null; 5312 } 5313 return r.intent.getComponent(); 5314 } 5315 } 5316 5317 @Override 5318 public String getPackageForToken(IBinder token) { 5319 synchronized(this) { 5320 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5321 if (r == null) { 5322 return null; 5323 } 5324 return r.packageName; 5325 } 5326 } 5327 5328 @Override 5329 public IIntentSender getIntentSender(int type, 5330 String packageName, IBinder token, String resultWho, 5331 int requestCode, Intent[] intents, String[] resolvedTypes, 5332 int flags, Bundle options, int userId) { 5333 enforceNotIsolatedCaller("getIntentSender"); 5334 // Refuse possible leaked file descriptors 5335 if (intents != null) { 5336 if (intents.length < 1) { 5337 throw new IllegalArgumentException("Intents array length must be >= 1"); 5338 } 5339 for (int i=0; i<intents.length; i++) { 5340 Intent intent = intents[i]; 5341 if (intent != null) { 5342 if (intent.hasFileDescriptors()) { 5343 throw new IllegalArgumentException("File descriptors passed in Intent"); 5344 } 5345 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5346 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5347 throw new IllegalArgumentException( 5348 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5349 } 5350 intents[i] = new Intent(intent); 5351 } 5352 } 5353 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5354 throw new IllegalArgumentException( 5355 "Intent array length does not match resolvedTypes length"); 5356 } 5357 } 5358 if (options != null) { 5359 if (options.hasFileDescriptors()) { 5360 throw new IllegalArgumentException("File descriptors passed in options"); 5361 } 5362 } 5363 5364 synchronized(this) { 5365 int callingUid = Binder.getCallingUid(); 5366 int origUserId = userId; 5367 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5368 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5369 "getIntentSender", null); 5370 if (origUserId == UserHandle.USER_CURRENT) { 5371 // We don't want to evaluate this until the pending intent is 5372 // actually executed. However, we do want to always do the 5373 // security checking for it above. 5374 userId = UserHandle.USER_CURRENT; 5375 } 5376 try { 5377 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5378 int uid = AppGlobals.getPackageManager() 5379 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5380 if (!UserHandle.isSameApp(callingUid, uid)) { 5381 String msg = "Permission Denial: getIntentSender() from pid=" 5382 + Binder.getCallingPid() 5383 + ", uid=" + Binder.getCallingUid() 5384 + ", (need uid=" + uid + ")" 5385 + " is not allowed to send as package " + packageName; 5386 Slog.w(TAG, msg); 5387 throw new SecurityException(msg); 5388 } 5389 } 5390 5391 return getIntentSenderLocked(type, packageName, callingUid, userId, 5392 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5393 5394 } catch (RemoteException e) { 5395 throw new SecurityException(e); 5396 } 5397 } 5398 } 5399 5400 IIntentSender getIntentSenderLocked(int type, String packageName, 5401 int callingUid, int userId, IBinder token, String resultWho, 5402 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5403 Bundle options) { 5404 if (DEBUG_MU) 5405 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5406 ActivityRecord activity = null; 5407 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5408 activity = ActivityRecord.isInStackLocked(token); 5409 if (activity == null) { 5410 return null; 5411 } 5412 if (activity.finishing) { 5413 return null; 5414 } 5415 } 5416 5417 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5418 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5419 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5420 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5421 |PendingIntent.FLAG_UPDATE_CURRENT); 5422 5423 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5424 type, packageName, activity, resultWho, 5425 requestCode, intents, resolvedTypes, flags, options, userId); 5426 WeakReference<PendingIntentRecord> ref; 5427 ref = mIntentSenderRecords.get(key); 5428 PendingIntentRecord rec = ref != null ? ref.get() : null; 5429 if (rec != null) { 5430 if (!cancelCurrent) { 5431 if (updateCurrent) { 5432 if (rec.key.requestIntent != null) { 5433 rec.key.requestIntent.replaceExtras(intents != null ? 5434 intents[intents.length - 1] : null); 5435 } 5436 if (intents != null) { 5437 intents[intents.length-1] = rec.key.requestIntent; 5438 rec.key.allIntents = intents; 5439 rec.key.allResolvedTypes = resolvedTypes; 5440 } else { 5441 rec.key.allIntents = null; 5442 rec.key.allResolvedTypes = null; 5443 } 5444 } 5445 return rec; 5446 } 5447 rec.canceled = true; 5448 mIntentSenderRecords.remove(key); 5449 } 5450 if (noCreate) { 5451 return rec; 5452 } 5453 rec = new PendingIntentRecord(this, key, callingUid); 5454 mIntentSenderRecords.put(key, rec.ref); 5455 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5456 if (activity.pendingResults == null) { 5457 activity.pendingResults 5458 = new HashSet<WeakReference<PendingIntentRecord>>(); 5459 } 5460 activity.pendingResults.add(rec.ref); 5461 } 5462 return rec; 5463 } 5464 5465 @Override 5466 public void cancelIntentSender(IIntentSender sender) { 5467 if (!(sender instanceof PendingIntentRecord)) { 5468 return; 5469 } 5470 synchronized(this) { 5471 PendingIntentRecord rec = (PendingIntentRecord)sender; 5472 try { 5473 int uid = AppGlobals.getPackageManager() 5474 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5475 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5476 String msg = "Permission Denial: cancelIntentSender() from pid=" 5477 + Binder.getCallingPid() 5478 + ", uid=" + Binder.getCallingUid() 5479 + " is not allowed to cancel packges " 5480 + rec.key.packageName; 5481 Slog.w(TAG, msg); 5482 throw new SecurityException(msg); 5483 } 5484 } catch (RemoteException e) { 5485 throw new SecurityException(e); 5486 } 5487 cancelIntentSenderLocked(rec, true); 5488 } 5489 } 5490 5491 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5492 rec.canceled = true; 5493 mIntentSenderRecords.remove(rec.key); 5494 if (cleanActivity && rec.key.activity != null) { 5495 rec.key.activity.pendingResults.remove(rec.ref); 5496 } 5497 } 5498 5499 @Override 5500 public String getPackageForIntentSender(IIntentSender pendingResult) { 5501 if (!(pendingResult instanceof PendingIntentRecord)) { 5502 return null; 5503 } 5504 try { 5505 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5506 return res.key.packageName; 5507 } catch (ClassCastException e) { 5508 } 5509 return null; 5510 } 5511 5512 @Override 5513 public int getUidForIntentSender(IIntentSender sender) { 5514 if (sender instanceof PendingIntentRecord) { 5515 try { 5516 PendingIntentRecord res = (PendingIntentRecord)sender; 5517 return res.uid; 5518 } catch (ClassCastException e) { 5519 } 5520 } 5521 return -1; 5522 } 5523 5524 @Override 5525 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5526 if (!(pendingResult instanceof PendingIntentRecord)) { 5527 return false; 5528 } 5529 try { 5530 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5531 if (res.key.allIntents == null) { 5532 return false; 5533 } 5534 for (int i=0; i<res.key.allIntents.length; i++) { 5535 Intent intent = res.key.allIntents[i]; 5536 if (intent.getPackage() != null && intent.getComponent() != null) { 5537 return false; 5538 } 5539 } 5540 return true; 5541 } catch (ClassCastException e) { 5542 } 5543 return false; 5544 } 5545 5546 @Override 5547 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5548 if (!(pendingResult instanceof PendingIntentRecord)) { 5549 return false; 5550 } 5551 try { 5552 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5553 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5554 return true; 5555 } 5556 return false; 5557 } catch (ClassCastException e) { 5558 } 5559 return false; 5560 } 5561 5562 @Override 5563 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5564 if (!(pendingResult instanceof PendingIntentRecord)) { 5565 return null; 5566 } 5567 try { 5568 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5569 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5570 } catch (ClassCastException e) { 5571 } 5572 return null; 5573 } 5574 5575 @Override 5576 public void setProcessLimit(int max) { 5577 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5578 "setProcessLimit()"); 5579 synchronized (this) { 5580 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5581 mProcessLimitOverride = max; 5582 } 5583 trimApplications(); 5584 } 5585 5586 @Override 5587 public int getProcessLimit() { 5588 synchronized (this) { 5589 return mProcessLimitOverride; 5590 } 5591 } 5592 5593 void foregroundTokenDied(ForegroundToken token) { 5594 synchronized (ActivityManagerService.this) { 5595 synchronized (mPidsSelfLocked) { 5596 ForegroundToken cur 5597 = mForegroundProcesses.get(token.pid); 5598 if (cur != token) { 5599 return; 5600 } 5601 mForegroundProcesses.remove(token.pid); 5602 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5603 if (pr == null) { 5604 return; 5605 } 5606 pr.forcingToForeground = null; 5607 pr.foregroundServices = false; 5608 } 5609 updateOomAdjLocked(); 5610 } 5611 } 5612 5613 @Override 5614 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5615 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5616 "setProcessForeground()"); 5617 synchronized(this) { 5618 boolean changed = false; 5619 5620 synchronized (mPidsSelfLocked) { 5621 ProcessRecord pr = mPidsSelfLocked.get(pid); 5622 if (pr == null && isForeground) { 5623 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5624 return; 5625 } 5626 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5627 if (oldToken != null) { 5628 oldToken.token.unlinkToDeath(oldToken, 0); 5629 mForegroundProcesses.remove(pid); 5630 if (pr != null) { 5631 pr.forcingToForeground = null; 5632 } 5633 changed = true; 5634 } 5635 if (isForeground && token != null) { 5636 ForegroundToken newToken = new ForegroundToken() { 5637 @Override 5638 public void binderDied() { 5639 foregroundTokenDied(this); 5640 } 5641 }; 5642 newToken.pid = pid; 5643 newToken.token = token; 5644 try { 5645 token.linkToDeath(newToken, 0); 5646 mForegroundProcesses.put(pid, newToken); 5647 pr.forcingToForeground = token; 5648 changed = true; 5649 } catch (RemoteException e) { 5650 // If the process died while doing this, we will later 5651 // do the cleanup with the process death link. 5652 } 5653 } 5654 } 5655 5656 if (changed) { 5657 updateOomAdjLocked(); 5658 } 5659 } 5660 } 5661 5662 // ========================================================= 5663 // PERMISSIONS 5664 // ========================================================= 5665 5666 static class PermissionController extends IPermissionController.Stub { 5667 ActivityManagerService mActivityManagerService; 5668 PermissionController(ActivityManagerService activityManagerService) { 5669 mActivityManagerService = activityManagerService; 5670 } 5671 5672 @Override 5673 public boolean checkPermission(String permission, int pid, int uid) { 5674 return mActivityManagerService.checkPermission(permission, pid, 5675 uid) == PackageManager.PERMISSION_GRANTED; 5676 } 5677 } 5678 5679 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5680 @Override 5681 public int checkComponentPermission(String permission, int pid, int uid, 5682 int owningUid, boolean exported) { 5683 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5684 owningUid, exported); 5685 } 5686 5687 @Override 5688 public Object getAMSLock() { 5689 return ActivityManagerService.this; 5690 } 5691 } 5692 5693 /** 5694 * This can be called with or without the global lock held. 5695 */ 5696 int checkComponentPermission(String permission, int pid, int uid, 5697 int owningUid, boolean exported) { 5698 // We might be performing an operation on behalf of an indirect binder 5699 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5700 // client identity accordingly before proceeding. 5701 Identity tlsIdentity = sCallerIdentity.get(); 5702 if (tlsIdentity != null) { 5703 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5704 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5705 uid = tlsIdentity.uid; 5706 pid = tlsIdentity.pid; 5707 } 5708 5709 if (pid == MY_PID) { 5710 return PackageManager.PERMISSION_GRANTED; 5711 } 5712 5713 return ActivityManager.checkComponentPermission(permission, uid, 5714 owningUid, exported); 5715 } 5716 5717 /** 5718 * As the only public entry point for permissions checking, this method 5719 * can enforce the semantic that requesting a check on a null global 5720 * permission is automatically denied. (Internally a null permission 5721 * string is used when calling {@link #checkComponentPermission} in cases 5722 * when only uid-based security is needed.) 5723 * 5724 * This can be called with or without the global lock held. 5725 */ 5726 @Override 5727 public int checkPermission(String permission, int pid, int uid) { 5728 if (permission == null) { 5729 return PackageManager.PERMISSION_DENIED; 5730 } 5731 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5732 } 5733 5734 /** 5735 * Binder IPC calls go through the public entry point. 5736 * This can be called with or without the global lock held. 5737 */ 5738 int checkCallingPermission(String permission) { 5739 return checkPermission(permission, 5740 Binder.getCallingPid(), 5741 UserHandle.getAppId(Binder.getCallingUid())); 5742 } 5743 5744 /** 5745 * This can be called with or without the global lock held. 5746 */ 5747 void enforceCallingPermission(String permission, String func) { 5748 if (checkCallingPermission(permission) 5749 == PackageManager.PERMISSION_GRANTED) { 5750 return; 5751 } 5752 5753 String msg = "Permission Denial: " + func + " from pid=" 5754 + Binder.getCallingPid() 5755 + ", uid=" + Binder.getCallingUid() 5756 + " requires " + permission; 5757 Slog.w(TAG, msg); 5758 throw new SecurityException(msg); 5759 } 5760 5761 /** 5762 * Determine if UID is holding permissions required to access {@link Uri} in 5763 * the given {@link ProviderInfo}. Final permission checking is always done 5764 * in {@link ContentProvider}. 5765 */ 5766 private final boolean checkHoldingPermissionsLocked( 5767 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5768 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5769 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5770 5771 if (pi.applicationInfo.uid == uid) { 5772 return true; 5773 } else if (!pi.exported) { 5774 return false; 5775 } 5776 5777 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5778 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5779 try { 5780 // check if target holds top-level <provider> permissions 5781 if (!readMet && pi.readPermission != null 5782 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5783 readMet = true; 5784 } 5785 if (!writeMet && pi.writePermission != null 5786 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5787 writeMet = true; 5788 } 5789 5790 // track if unprotected read/write is allowed; any denied 5791 // <path-permission> below removes this ability 5792 boolean allowDefaultRead = pi.readPermission == null; 5793 boolean allowDefaultWrite = pi.writePermission == null; 5794 5795 // check if target holds any <path-permission> that match uri 5796 final PathPermission[] pps = pi.pathPermissions; 5797 if (pps != null) { 5798 final String path = uri.getPath(); 5799 int i = pps.length; 5800 while (i > 0 && (!readMet || !writeMet)) { 5801 i--; 5802 PathPermission pp = pps[i]; 5803 if (pp.match(path)) { 5804 if (!readMet) { 5805 final String pprperm = pp.getReadPermission(); 5806 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5807 + pprperm + " for " + pp.getPath() 5808 + ": match=" + pp.match(path) 5809 + " check=" + pm.checkUidPermission(pprperm, uid)); 5810 if (pprperm != null) { 5811 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5812 readMet = true; 5813 } else { 5814 allowDefaultRead = false; 5815 } 5816 } 5817 } 5818 if (!writeMet) { 5819 final String ppwperm = pp.getWritePermission(); 5820 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5821 + ppwperm + " for " + pp.getPath() 5822 + ": match=" + pp.match(path) 5823 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5824 if (ppwperm != null) { 5825 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5826 writeMet = true; 5827 } else { 5828 allowDefaultWrite = false; 5829 } 5830 } 5831 } 5832 } 5833 } 5834 } 5835 5836 // grant unprotected <provider> read/write, if not blocked by 5837 // <path-permission> above 5838 if (allowDefaultRead) readMet = true; 5839 if (allowDefaultWrite) writeMet = true; 5840 5841 } catch (RemoteException e) { 5842 return false; 5843 } 5844 5845 return readMet && writeMet; 5846 } 5847 5848 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5849 ProviderInfo pi = null; 5850 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5851 if (cpr != null) { 5852 pi = cpr.info; 5853 } else { 5854 try { 5855 pi = AppGlobals.getPackageManager().resolveContentProvider( 5856 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5857 } catch (RemoteException ex) { 5858 } 5859 } 5860 return pi; 5861 } 5862 5863 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5864 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5865 if (targetUris != null) { 5866 return targetUris.get(uri); 5867 } else { 5868 return null; 5869 } 5870 } 5871 5872 private UriPermission findOrCreateUriPermissionLocked( 5873 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5874 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5875 if (targetUris == null) { 5876 targetUris = Maps.newArrayMap(); 5877 mGrantedUriPermissions.put(targetUid, targetUris); 5878 } 5879 5880 UriPermission perm = targetUris.get(uri); 5881 if (perm == null) { 5882 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5883 targetUris.put(uri, perm); 5884 } 5885 5886 return perm; 5887 } 5888 5889 private final boolean checkUriPermissionLocked( 5890 Uri uri, int uid, int modeFlags, int minStrength) { 5891 // Root gets to do everything. 5892 if (uid == 0) { 5893 return true; 5894 } 5895 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5896 if (perms == null) return false; 5897 UriPermission perm = perms.get(uri); 5898 if (perm == null) return false; 5899 return perm.getStrength(modeFlags) >= minStrength; 5900 } 5901 5902 @Override 5903 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5904 enforceNotIsolatedCaller("checkUriPermission"); 5905 5906 // Another redirected-binder-call permissions check as in 5907 // {@link checkComponentPermission}. 5908 Identity tlsIdentity = sCallerIdentity.get(); 5909 if (tlsIdentity != null) { 5910 uid = tlsIdentity.uid; 5911 pid = tlsIdentity.pid; 5912 } 5913 5914 // Our own process gets to do everything. 5915 if (pid == MY_PID) { 5916 return PackageManager.PERMISSION_GRANTED; 5917 } 5918 synchronized(this) { 5919 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5920 ? PackageManager.PERMISSION_GRANTED 5921 : PackageManager.PERMISSION_DENIED; 5922 } 5923 } 5924 5925 /** 5926 * Check if the targetPkg can be granted permission to access uri by 5927 * the callingUid using the given modeFlags. Throws a security exception 5928 * if callingUid is not allowed to do this. Returns the uid of the target 5929 * if the URI permission grant should be performed; returns -1 if it is not 5930 * needed (for example targetPkg already has permission to access the URI). 5931 * If you already know the uid of the target, you can supply it in 5932 * lastTargetUid else set that to -1. 5933 */ 5934 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5935 Uri uri, int modeFlags, int lastTargetUid) { 5936 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5937 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5938 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5939 if (modeFlags == 0) { 5940 return -1; 5941 } 5942 5943 if (targetPkg != null) { 5944 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5945 "Checking grant " + targetPkg + " permission to " + uri); 5946 } 5947 5948 final IPackageManager pm = AppGlobals.getPackageManager(); 5949 5950 // If this is not a content: uri, we can't do anything with it. 5951 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5952 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5953 "Can't grant URI permission for non-content URI: " + uri); 5954 return -1; 5955 } 5956 5957 final String authority = uri.getAuthority(); 5958 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5959 if (pi == null) { 5960 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5961 return -1; 5962 } 5963 5964 int targetUid = lastTargetUid; 5965 if (targetUid < 0 && targetPkg != null) { 5966 try { 5967 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5968 if (targetUid < 0) { 5969 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5970 "Can't grant URI permission no uid for: " + targetPkg); 5971 return -1; 5972 } 5973 } catch (RemoteException ex) { 5974 return -1; 5975 } 5976 } 5977 5978 if (targetUid >= 0) { 5979 // First... does the target actually need this permission? 5980 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 5981 // No need to grant the target this permission. 5982 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5983 "Target " + targetPkg + " already has full permission to " + uri); 5984 return -1; 5985 } 5986 } else { 5987 // First... there is no target package, so can anyone access it? 5988 boolean allowed = pi.exported; 5989 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5990 if (pi.readPermission != null) { 5991 allowed = false; 5992 } 5993 } 5994 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5995 if (pi.writePermission != null) { 5996 allowed = false; 5997 } 5998 } 5999 if (allowed) { 6000 return -1; 6001 } 6002 } 6003 6004 // Second... is the provider allowing granting of URI permissions? 6005 if (!pi.grantUriPermissions) { 6006 throw new SecurityException("Provider " + pi.packageName 6007 + "/" + pi.name 6008 + " does not allow granting of Uri permissions (uri " 6009 + uri + ")"); 6010 } 6011 if (pi.uriPermissionPatterns != null) { 6012 final int N = pi.uriPermissionPatterns.length; 6013 boolean allowed = false; 6014 for (int i=0; i<N; i++) { 6015 if (pi.uriPermissionPatterns[i] != null 6016 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6017 allowed = true; 6018 break; 6019 } 6020 } 6021 if (!allowed) { 6022 throw new SecurityException("Provider " + pi.packageName 6023 + "/" + pi.name 6024 + " does not allow granting of permission to path of Uri " 6025 + uri); 6026 } 6027 } 6028 6029 // Third... does the caller itself have permission to access 6030 // this uri? 6031 if (callingUid != Process.myUid()) { 6032 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6033 // Require they hold a strong enough Uri permission 6034 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6035 : UriPermission.STRENGTH_OWNED; 6036 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6037 throw new SecurityException("Uid " + callingUid 6038 + " does not have permission to uri " + uri); 6039 } 6040 } 6041 } 6042 6043 return targetUid; 6044 } 6045 6046 @Override 6047 public int checkGrantUriPermission(int callingUid, String targetPkg, 6048 Uri uri, int modeFlags) { 6049 enforceNotIsolatedCaller("checkGrantUriPermission"); 6050 synchronized(this) { 6051 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6052 } 6053 } 6054 6055 void grantUriPermissionUncheckedLocked( 6056 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6057 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6058 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6059 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6060 if (modeFlags == 0) { 6061 return; 6062 } 6063 6064 // So here we are: the caller has the assumed permission 6065 // to the uri, and the target doesn't. Let's now give this to 6066 // the target. 6067 6068 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6069 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6070 6071 final String authority = uri.getAuthority(); 6072 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6073 if (pi == null) { 6074 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6075 return; 6076 } 6077 6078 final UriPermission perm = findOrCreateUriPermissionLocked( 6079 pi.packageName, targetPkg, targetUid, uri); 6080 perm.grantModes(modeFlags, persistable, owner); 6081 } 6082 6083 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6084 int modeFlags, UriPermissionOwner owner) { 6085 if (targetPkg == null) { 6086 throw new NullPointerException("targetPkg"); 6087 } 6088 6089 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6090 if (targetUid < 0) { 6091 return; 6092 } 6093 6094 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6095 } 6096 6097 static class NeededUriGrants extends ArrayList<Uri> { 6098 final String targetPkg; 6099 final int targetUid; 6100 final int flags; 6101 6102 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6103 this.targetPkg = targetPkg; 6104 this.targetUid = targetUid; 6105 this.flags = flags; 6106 } 6107 } 6108 6109 /** 6110 * Like checkGrantUriPermissionLocked, but takes an Intent. 6111 */ 6112 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6113 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6114 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6115 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6116 + " clip=" + (intent != null ? intent.getClipData() : null) 6117 + " from " + intent + "; flags=0x" 6118 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6119 6120 if (targetPkg == null) { 6121 throw new NullPointerException("targetPkg"); 6122 } 6123 6124 if (intent == null) { 6125 return null; 6126 } 6127 Uri data = intent.getData(); 6128 ClipData clip = intent.getClipData(); 6129 if (data == null && clip == null) { 6130 return null; 6131 } 6132 6133 if (data != null) { 6134 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6135 mode, needed != null ? needed.targetUid : -1); 6136 if (targetUid > 0) { 6137 if (needed == null) { 6138 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6139 } 6140 needed.add(data); 6141 } 6142 } 6143 if (clip != null) { 6144 for (int i=0; i<clip.getItemCount(); i++) { 6145 Uri uri = clip.getItemAt(i).getUri(); 6146 if (uri != null) { 6147 int targetUid = -1; 6148 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6149 mode, needed != null ? needed.targetUid : -1); 6150 if (targetUid > 0) { 6151 if (needed == null) { 6152 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6153 } 6154 needed.add(uri); 6155 } 6156 } else { 6157 Intent clipIntent = clip.getItemAt(i).getIntent(); 6158 if (clipIntent != null) { 6159 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6160 callingUid, targetPkg, clipIntent, mode, needed); 6161 if (newNeeded != null) { 6162 needed = newNeeded; 6163 } 6164 } 6165 } 6166 } 6167 } 6168 6169 return needed; 6170 } 6171 6172 /** 6173 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6174 */ 6175 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6176 UriPermissionOwner owner) { 6177 if (needed != null) { 6178 for (int i=0; i<needed.size(); i++) { 6179 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6180 needed.get(i), needed.flags, owner); 6181 } 6182 } 6183 } 6184 6185 void grantUriPermissionFromIntentLocked(int callingUid, 6186 String targetPkg, Intent intent, UriPermissionOwner owner) { 6187 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6188 intent, intent != null ? intent.getFlags() : 0, null); 6189 if (needed == null) { 6190 return; 6191 } 6192 6193 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6194 } 6195 6196 @Override 6197 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6198 Uri uri, int modeFlags) { 6199 enforceNotIsolatedCaller("grantUriPermission"); 6200 synchronized(this) { 6201 final ProcessRecord r = getRecordForAppLocked(caller); 6202 if (r == null) { 6203 throw new SecurityException("Unable to find app for caller " 6204 + caller 6205 + " when granting permission to uri " + uri); 6206 } 6207 if (targetPkg == null) { 6208 throw new IllegalArgumentException("null target"); 6209 } 6210 if (uri == null) { 6211 throw new IllegalArgumentException("null uri"); 6212 } 6213 6214 // Persistable only supported through Intents 6215 Preconditions.checkFlagsArgument(modeFlags, 6216 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6217 6218 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6219 null); 6220 } 6221 } 6222 6223 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6224 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6225 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6226 ArrayMap<Uri, UriPermission> perms 6227 = mGrantedUriPermissions.get(perm.targetUid); 6228 if (perms != null) { 6229 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6230 "Removing " + perm.targetUid + " permission to " + perm.uri); 6231 perms.remove(perm.uri); 6232 if (perms.size() == 0) { 6233 mGrantedUriPermissions.remove(perm.targetUid); 6234 } 6235 } 6236 } 6237 } 6238 6239 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6240 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6241 6242 final IPackageManager pm = AppGlobals.getPackageManager(); 6243 final String authority = uri.getAuthority(); 6244 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6245 if (pi == null) { 6246 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6247 return; 6248 } 6249 6250 // Does the caller have this permission on the URI? 6251 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6252 // Right now, if you are not the original owner of the permission, 6253 // you are not allowed to revoke it. 6254 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6255 throw new SecurityException("Uid " + callingUid 6256 + " does not have permission to uri " + uri); 6257 //} 6258 } 6259 6260 boolean persistChanged = false; 6261 6262 // Go through all of the permissions and remove any that match. 6263 final List<String> SEGMENTS = uri.getPathSegments(); 6264 if (SEGMENTS != null) { 6265 final int NS = SEGMENTS.size(); 6266 int N = mGrantedUriPermissions.size(); 6267 for (int i=0; i<N; i++) { 6268 ArrayMap<Uri, UriPermission> perms 6269 = mGrantedUriPermissions.valueAt(i); 6270 Iterator<UriPermission> it = perms.values().iterator(); 6271 toploop: 6272 while (it.hasNext()) { 6273 UriPermission perm = it.next(); 6274 Uri targetUri = perm.uri; 6275 if (!authority.equals(targetUri.getAuthority())) { 6276 continue; 6277 } 6278 List<String> targetSegments = targetUri.getPathSegments(); 6279 if (targetSegments == null) { 6280 continue; 6281 } 6282 if (targetSegments.size() < NS) { 6283 continue; 6284 } 6285 for (int j=0; j<NS; j++) { 6286 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6287 continue toploop; 6288 } 6289 } 6290 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6291 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6292 persistChanged |= perm.clearModes(modeFlags, true); 6293 if (perm.modeFlags == 0) { 6294 it.remove(); 6295 } 6296 } 6297 if (perms.size() == 0) { 6298 mGrantedUriPermissions.remove( 6299 mGrantedUriPermissions.keyAt(i)); 6300 N--; 6301 i--; 6302 } 6303 } 6304 } 6305 6306 if (persistChanged) { 6307 schedulePersistUriGrants(); 6308 } 6309 } 6310 6311 @Override 6312 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6313 int modeFlags) { 6314 enforceNotIsolatedCaller("revokeUriPermission"); 6315 synchronized(this) { 6316 final ProcessRecord r = getRecordForAppLocked(caller); 6317 if (r == null) { 6318 throw new SecurityException("Unable to find app for caller " 6319 + caller 6320 + " when revoking permission to uri " + uri); 6321 } 6322 if (uri == null) { 6323 Slog.w(TAG, "revokeUriPermission: null uri"); 6324 return; 6325 } 6326 6327 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6328 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6329 if (modeFlags == 0) { 6330 return; 6331 } 6332 6333 final IPackageManager pm = AppGlobals.getPackageManager(); 6334 final String authority = uri.getAuthority(); 6335 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6336 if (pi == null) { 6337 Slog.w(TAG, "No content provider found for permission revoke: " 6338 + uri.toSafeString()); 6339 return; 6340 } 6341 6342 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6343 } 6344 } 6345 6346 /** 6347 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6348 * given package. 6349 * 6350 * @param packageName Package name to match, or {@code null} to apply to all 6351 * packages. 6352 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6353 * to all users. 6354 * @param persistable If persistable grants should be removed. 6355 */ 6356 private void removeUriPermissionsForPackageLocked( 6357 String packageName, int userHandle, boolean persistable) { 6358 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6359 throw new IllegalArgumentException("Must narrow by either package or user"); 6360 } 6361 6362 boolean persistChanged = false; 6363 6364 final int size = mGrantedUriPermissions.size(); 6365 for (int i = 0; i < size; i++) { 6366 // Only inspect grants matching user 6367 if (userHandle == UserHandle.USER_ALL 6368 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6369 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6370 .values().iterator(); 6371 while (it.hasNext()) { 6372 final UriPermission perm = it.next(); 6373 6374 // Only inspect grants matching package 6375 if (packageName == null || perm.sourcePkg.equals(packageName) 6376 || perm.targetPkg.equals(packageName)) { 6377 persistChanged |= perm.clearModes(~0, persistable); 6378 6379 // Only remove when no modes remain; any persisted grants 6380 // will keep this alive. 6381 if (perm.modeFlags == 0) { 6382 it.remove(); 6383 } 6384 } 6385 } 6386 } 6387 } 6388 6389 if (persistChanged) { 6390 schedulePersistUriGrants(); 6391 } 6392 } 6393 6394 @Override 6395 public IBinder newUriPermissionOwner(String name) { 6396 enforceNotIsolatedCaller("newUriPermissionOwner"); 6397 synchronized(this) { 6398 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6399 return owner.getExternalTokenLocked(); 6400 } 6401 } 6402 6403 @Override 6404 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6405 Uri uri, int modeFlags) { 6406 synchronized(this) { 6407 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6408 if (owner == null) { 6409 throw new IllegalArgumentException("Unknown owner: " + token); 6410 } 6411 if (fromUid != Binder.getCallingUid()) { 6412 if (Binder.getCallingUid() != Process.myUid()) { 6413 // Only system code can grant URI permissions on behalf 6414 // of other users. 6415 throw new SecurityException("nice try"); 6416 } 6417 } 6418 if (targetPkg == null) { 6419 throw new IllegalArgumentException("null target"); 6420 } 6421 if (uri == null) { 6422 throw new IllegalArgumentException("null uri"); 6423 } 6424 6425 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6426 } 6427 } 6428 6429 @Override 6430 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6431 synchronized(this) { 6432 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6433 if (owner == null) { 6434 throw new IllegalArgumentException("Unknown owner: " + token); 6435 } 6436 6437 if (uri == null) { 6438 owner.removeUriPermissionsLocked(mode); 6439 } else { 6440 owner.removeUriPermissionLocked(uri, mode); 6441 } 6442 } 6443 } 6444 6445 private void schedulePersistUriGrants() { 6446 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6447 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6448 10 * DateUtils.SECOND_IN_MILLIS); 6449 } 6450 } 6451 6452 private void writeGrantedUriPermissions() { 6453 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6454 6455 // Snapshot permissions so we can persist without lock 6456 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6457 synchronized (this) { 6458 final int size = mGrantedUriPermissions.size(); 6459 for (int i = 0 ; i < size; i++) { 6460 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6461 if (perm.persistedModeFlags != 0) { 6462 persist.add(perm.snapshot()); 6463 } 6464 } 6465 } 6466 } 6467 6468 FileOutputStream fos = null; 6469 try { 6470 fos = mGrantFile.startWrite(); 6471 6472 XmlSerializer out = new FastXmlSerializer(); 6473 out.setOutput(fos, "utf-8"); 6474 out.startDocument(null, true); 6475 out.startTag(null, TAG_URI_GRANTS); 6476 for (UriPermission.Snapshot perm : persist) { 6477 out.startTag(null, TAG_URI_GRANT); 6478 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6479 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6480 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6481 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6482 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6483 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6484 out.endTag(null, TAG_URI_GRANT); 6485 } 6486 out.endTag(null, TAG_URI_GRANTS); 6487 out.endDocument(); 6488 6489 mGrantFile.finishWrite(fos); 6490 } catch (IOException e) { 6491 if (fos != null) { 6492 mGrantFile.failWrite(fos); 6493 } 6494 } 6495 } 6496 6497 private void readGrantedUriPermissionsLocked() { 6498 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6499 6500 final long now = System.currentTimeMillis(); 6501 6502 FileInputStream fis = null; 6503 try { 6504 fis = mGrantFile.openRead(); 6505 final XmlPullParser in = Xml.newPullParser(); 6506 in.setInput(fis, null); 6507 6508 int type; 6509 while ((type = in.next()) != END_DOCUMENT) { 6510 final String tag = in.getName(); 6511 if (type == START_TAG) { 6512 if (TAG_URI_GRANT.equals(tag)) { 6513 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6514 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6515 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6516 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6517 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6518 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6519 6520 // Sanity check that provider still belongs to source package 6521 final ProviderInfo pi = getProviderInfoLocked( 6522 uri.getAuthority(), userHandle); 6523 if (pi != null && sourcePkg.equals(pi.packageName)) { 6524 int targetUid = -1; 6525 try { 6526 targetUid = AppGlobals.getPackageManager() 6527 .getPackageUid(targetPkg, userHandle); 6528 } catch (RemoteException e) { 6529 } 6530 if (targetUid != -1) { 6531 final UriPermission perm = findOrCreateUriPermissionLocked( 6532 sourcePkg, targetPkg, targetUid, uri); 6533 perm.initPersistedModes(modeFlags, createdTime); 6534 } 6535 } else { 6536 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6537 + " but instead found " + pi); 6538 } 6539 } 6540 } 6541 } 6542 } catch (FileNotFoundException e) { 6543 // Missing grants is okay 6544 } catch (IOException e) { 6545 Log.wtf(TAG, "Failed reading Uri grants", e); 6546 } catch (XmlPullParserException e) { 6547 Log.wtf(TAG, "Failed reading Uri grants", e); 6548 } finally { 6549 IoUtils.closeQuietly(fis); 6550 } 6551 } 6552 6553 @Override 6554 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6555 enforceNotIsolatedCaller("takePersistableUriPermission"); 6556 6557 Preconditions.checkFlagsArgument(modeFlags, 6558 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6559 6560 synchronized (this) { 6561 final int callingUid = Binder.getCallingUid(); 6562 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6563 if (perm == null) { 6564 throw new SecurityException("No permission grant found for UID " + callingUid 6565 + " and Uri " + uri.toSafeString()); 6566 } 6567 6568 boolean persistChanged = perm.takePersistableModes(modeFlags); 6569 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6570 6571 if (persistChanged) { 6572 schedulePersistUriGrants(); 6573 } 6574 } 6575 } 6576 6577 @Override 6578 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6579 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6580 6581 Preconditions.checkFlagsArgument(modeFlags, 6582 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6583 6584 synchronized (this) { 6585 final int callingUid = Binder.getCallingUid(); 6586 6587 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6588 if (perm == null) { 6589 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6590 + uri.toSafeString()); 6591 return; 6592 } 6593 6594 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6595 removeUriPermissionIfNeededLocked(perm); 6596 if (persistChanged) { 6597 schedulePersistUriGrants(); 6598 } 6599 } 6600 } 6601 6602 /** 6603 * Prune any older {@link UriPermission} for the given UID until outstanding 6604 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6605 * 6606 * @return if any mutations occured that require persisting. 6607 */ 6608 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6609 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6610 if (perms == null) return false; 6611 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6612 6613 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6614 for (UriPermission perm : perms.values()) { 6615 if (perm.persistedModeFlags != 0) { 6616 persisted.add(perm); 6617 } 6618 } 6619 6620 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6621 if (trimCount <= 0) return false; 6622 6623 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6624 for (int i = 0; i < trimCount; i++) { 6625 final UriPermission perm = persisted.get(i); 6626 6627 if (DEBUG_URI_PERMISSION) { 6628 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6629 } 6630 6631 perm.releasePersistableModes(~0); 6632 removeUriPermissionIfNeededLocked(perm); 6633 } 6634 6635 return true; 6636 } 6637 6638 @Override 6639 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6640 String packageName, boolean incoming) { 6641 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6642 Preconditions.checkNotNull(packageName, "packageName"); 6643 6644 final int callingUid = Binder.getCallingUid(); 6645 final IPackageManager pm = AppGlobals.getPackageManager(); 6646 try { 6647 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6648 if (packageUid != callingUid) { 6649 throw new SecurityException( 6650 "Package " + packageName + " does not belong to calling UID " + callingUid); 6651 } 6652 } catch (RemoteException e) { 6653 throw new SecurityException("Failed to verify package name ownership"); 6654 } 6655 6656 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6657 synchronized (this) { 6658 if (incoming) { 6659 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6660 if (perms == null) { 6661 Slog.w(TAG, "No permission grants found for " + packageName); 6662 } else { 6663 final int size = perms.size(); 6664 for (int i = 0; i < size; i++) { 6665 final UriPermission perm = perms.valueAt(i); 6666 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6667 result.add(perm.buildPersistedPublicApiObject()); 6668 } 6669 } 6670 } 6671 } else { 6672 final int size = mGrantedUriPermissions.size(); 6673 for (int i = 0; i < size; i++) { 6674 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6675 final int permsSize = perms.size(); 6676 for (int j = 0; j < permsSize; j++) { 6677 final UriPermission perm = perms.valueAt(j); 6678 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6679 result.add(perm.buildPersistedPublicApiObject()); 6680 } 6681 } 6682 } 6683 } 6684 } 6685 return new ParceledListSlice<android.content.UriPermission>(result); 6686 } 6687 6688 @Override 6689 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6690 synchronized (this) { 6691 ProcessRecord app = 6692 who != null ? getRecordForAppLocked(who) : null; 6693 if (app == null) return; 6694 6695 Message msg = Message.obtain(); 6696 msg.what = WAIT_FOR_DEBUGGER_MSG; 6697 msg.obj = app; 6698 msg.arg1 = waiting ? 1 : 0; 6699 mHandler.sendMessage(msg); 6700 } 6701 } 6702 6703 @Override 6704 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6705 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6706 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6707 outInfo.availMem = Process.getFreeMemory(); 6708 outInfo.totalMem = Process.getTotalMemory(); 6709 outInfo.threshold = homeAppMem; 6710 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6711 outInfo.hiddenAppThreshold = cachedAppMem; 6712 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6713 ProcessList.SERVICE_ADJ); 6714 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6715 ProcessList.VISIBLE_APP_ADJ); 6716 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6717 ProcessList.FOREGROUND_APP_ADJ); 6718 } 6719 6720 // ========================================================= 6721 // TASK MANAGEMENT 6722 // ========================================================= 6723 6724 @Override 6725 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6726 IThumbnailReceiver receiver) { 6727 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6728 6729 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6730 ActivityRecord topRecord = null; 6731 6732 synchronized(this) { 6733 if (localLOGV) Slog.v( 6734 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6735 + ", receiver=" + receiver); 6736 6737 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6738 != PackageManager.PERMISSION_GRANTED) { 6739 if (receiver != null) { 6740 // If the caller wants to wait for pending thumbnails, 6741 // it ain't gonna get them. 6742 try { 6743 receiver.finished(); 6744 } catch (RemoteException ex) { 6745 } 6746 } 6747 String msg = "Permission Denial: getTasks() from pid=" 6748 + Binder.getCallingPid() 6749 + ", uid=" + Binder.getCallingUid() 6750 + " requires " + android.Manifest.permission.GET_TASKS; 6751 Slog.w(TAG, msg); 6752 throw new SecurityException(msg); 6753 } 6754 6755 // TODO: Improve with MRU list from all ActivityStacks. 6756 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6757 6758 if (!pending.pendingRecords.isEmpty()) { 6759 mPendingThumbnails.add(pending); 6760 } 6761 } 6762 6763 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6764 6765 if (topRecord != null) { 6766 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6767 try { 6768 IApplicationThread topThumbnail = topRecord.app.thread; 6769 topThumbnail.requestThumbnail(topRecord.appToken); 6770 } catch (Exception e) { 6771 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6772 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6773 } 6774 } 6775 6776 if (pending == null && receiver != null) { 6777 // In this case all thumbnails were available and the client 6778 // is being asked to be told when the remaining ones come in... 6779 // which is unusually, since the top-most currently running 6780 // activity should never have a canned thumbnail! Oh well. 6781 try { 6782 receiver.finished(); 6783 } catch (RemoteException ex) { 6784 } 6785 } 6786 6787 return list; 6788 } 6789 6790 TaskRecord getMostRecentTask() { 6791 return mRecentTasks.get(0); 6792 } 6793 6794 @Override 6795 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6796 int flags, int userId) { 6797 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6798 false, true, "getRecentTasks", null); 6799 6800 synchronized (this) { 6801 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6802 "getRecentTasks()"); 6803 final boolean detailed = checkCallingPermission( 6804 android.Manifest.permission.GET_DETAILED_TASKS) 6805 == PackageManager.PERMISSION_GRANTED; 6806 6807 IPackageManager pm = AppGlobals.getPackageManager(); 6808 6809 final int N = mRecentTasks.size(); 6810 ArrayList<ActivityManager.RecentTaskInfo> res 6811 = new ArrayList<ActivityManager.RecentTaskInfo>( 6812 maxNum < N ? maxNum : N); 6813 for (int i=0; i<N && maxNum > 0; i++) { 6814 TaskRecord tr = mRecentTasks.get(i); 6815 // Only add calling user's recent tasks 6816 if (tr.userId != userId) continue; 6817 // Return the entry if desired by the caller. We always return 6818 // the first entry, because callers always expect this to be the 6819 // foreground app. We may filter others if the caller has 6820 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6821 // we should exclude the entry. 6822 6823 if (i == 0 6824 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6825 || (tr.intent == null) 6826 || ((tr.intent.getFlags() 6827 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6828 ActivityManager.RecentTaskInfo rti 6829 = new ActivityManager.RecentTaskInfo(); 6830 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6831 rti.persistentId = tr.taskId; 6832 rti.baseIntent = new Intent( 6833 tr.intent != null ? tr.intent : tr.affinityIntent); 6834 if (!detailed) { 6835 rti.baseIntent.replaceExtras((Bundle)null); 6836 } 6837 rti.origActivity = tr.origActivity; 6838 rti.description = tr.lastDescription; 6839 rti.stackId = tr.stack.mStackId; 6840 6841 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6842 // Check whether this activity is currently available. 6843 try { 6844 if (rti.origActivity != null) { 6845 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6846 == null) { 6847 continue; 6848 } 6849 } else if (rti.baseIntent != null) { 6850 if (pm.queryIntentActivities(rti.baseIntent, 6851 null, 0, userId) == null) { 6852 continue; 6853 } 6854 } 6855 } catch (RemoteException e) { 6856 // Will never happen. 6857 } 6858 } 6859 6860 res.add(rti); 6861 maxNum--; 6862 } 6863 } 6864 return res; 6865 } 6866 } 6867 6868 private TaskRecord recentTaskForIdLocked(int id) { 6869 final int N = mRecentTasks.size(); 6870 for (int i=0; i<N; i++) { 6871 TaskRecord tr = mRecentTasks.get(i); 6872 if (tr.taskId == id) { 6873 return tr; 6874 } 6875 } 6876 return null; 6877 } 6878 6879 @Override 6880 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6881 synchronized (this) { 6882 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6883 "getTaskThumbnails()"); 6884 TaskRecord tr = recentTaskForIdLocked(id); 6885 if (tr != null) { 6886 return tr.getTaskThumbnailsLocked(); 6887 } 6888 } 6889 return null; 6890 } 6891 6892 @Override 6893 public Bitmap getTaskTopThumbnail(int id) { 6894 synchronized (this) { 6895 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6896 "getTaskTopThumbnail()"); 6897 TaskRecord tr = recentTaskForIdLocked(id); 6898 if (tr != null) { 6899 return tr.getTaskTopThumbnailLocked(); 6900 } 6901 } 6902 return null; 6903 } 6904 6905 @Override 6906 public boolean removeSubTask(int taskId, int subTaskIndex) { 6907 synchronized (this) { 6908 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6909 "removeSubTask()"); 6910 long ident = Binder.clearCallingIdentity(); 6911 try { 6912 TaskRecord tr = recentTaskForIdLocked(taskId); 6913 if (tr != null) { 6914 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6915 } 6916 return false; 6917 } finally { 6918 Binder.restoreCallingIdentity(ident); 6919 } 6920 } 6921 } 6922 6923 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6924 if (!pr.killedByAm) { 6925 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6926 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6927 pr.processName, pr.setAdj, reason); 6928 pr.killedByAm = true; 6929 Process.killProcessQuiet(pr.pid); 6930 } 6931 } 6932 6933 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6934 tr.disposeThumbnail(); 6935 mRecentTasks.remove(tr); 6936 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6937 Intent baseIntent = new Intent( 6938 tr.intent != null ? tr.intent : tr.affinityIntent); 6939 ComponentName component = baseIntent.getComponent(); 6940 if (component == null) { 6941 Slog.w(TAG, "Now component for base intent of task: " + tr); 6942 return; 6943 } 6944 6945 // Find any running services associated with this app. 6946 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6947 6948 if (killProcesses) { 6949 // Find any running processes associated with this app. 6950 final String pkg = component.getPackageName(); 6951 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6952 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6953 for (int i=0; i<pmap.size(); i++) { 6954 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6955 for (int j=0; j<uids.size(); j++) { 6956 ProcessRecord proc = uids.valueAt(j); 6957 if (proc.userId != tr.userId) { 6958 continue; 6959 } 6960 if (!proc.pkgList.containsKey(pkg)) { 6961 continue; 6962 } 6963 procs.add(proc); 6964 } 6965 } 6966 6967 // Kill the running processes. 6968 for (int i=0; i<procs.size(); i++) { 6969 ProcessRecord pr = procs.get(i); 6970 if (pr == mHomeProcess) { 6971 // Don't kill the home process along with tasks from the same package. 6972 continue; 6973 } 6974 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 6975 killUnneededProcessLocked(pr, "remove task"); 6976 } else { 6977 pr.waitingToKill = "remove task"; 6978 } 6979 } 6980 } 6981 } 6982 6983 @Override 6984 public boolean removeTask(int taskId, int flags) { 6985 synchronized (this) { 6986 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6987 "removeTask()"); 6988 long ident = Binder.clearCallingIdentity(); 6989 try { 6990 TaskRecord tr = recentTaskForIdLocked(taskId); 6991 if (tr != null) { 6992 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 6993 if (r != null) { 6994 cleanUpRemovedTaskLocked(tr, flags); 6995 return true; 6996 } 6997 if (tr.mActivities.size() == 0) { 6998 // Caller is just removing a recent task that is 6999 // not actively running. That is easy! 7000 cleanUpRemovedTaskLocked(tr, flags); 7001 return true; 7002 } 7003 Slog.w(TAG, "removeTask: task " + taskId 7004 + " does not have activities to remove, " 7005 + " but numActivities=" + tr.numActivities 7006 + ": " + tr); 7007 } 7008 } finally { 7009 Binder.restoreCallingIdentity(ident); 7010 } 7011 } 7012 return false; 7013 } 7014 7015 /** 7016 * TODO: Add mController hook 7017 */ 7018 @Override 7019 public void moveTaskToFront(int task, int flags, Bundle options) { 7020 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7021 "moveTaskToFront()"); 7022 7023 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task); 7024 synchronized(this) { 7025 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7026 Binder.getCallingUid(), "Task to front")) { 7027 ActivityOptions.abort(options); 7028 return; 7029 } 7030 final long origId = Binder.clearCallingIdentity(); 7031 try { 7032 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7033 } finally { 7034 Binder.restoreCallingIdentity(origId); 7035 } 7036 ActivityOptions.abort(options); 7037 } 7038 } 7039 7040 @Override 7041 public void moveTaskToBack(int taskId) { 7042 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7043 "moveTaskToBack()"); 7044 7045 synchronized(this) { 7046 TaskRecord tr = recentTaskForIdLocked(taskId); 7047 if (tr != null) { 7048 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7049 ActivityStack stack = tr.stack; 7050 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7051 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7052 Binder.getCallingUid(), "Task to back")) { 7053 return; 7054 } 7055 } 7056 final long origId = Binder.clearCallingIdentity(); 7057 try { 7058 stack.moveTaskToBackLocked(taskId, null); 7059 } finally { 7060 Binder.restoreCallingIdentity(origId); 7061 } 7062 } 7063 } 7064 } 7065 7066 /** 7067 * Moves an activity, and all of the other activities within the same task, to the bottom 7068 * of the history stack. The activity's order within the task is unchanged. 7069 * 7070 * @param token A reference to the activity we wish to move 7071 * @param nonRoot If false then this only works if the activity is the root 7072 * of a task; if true it will work for any activity in a task. 7073 * @return Returns true if the move completed, false if not. 7074 */ 7075 @Override 7076 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7077 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7078 synchronized(this) { 7079 final long origId = Binder.clearCallingIdentity(); 7080 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7081 if (taskId >= 0) { 7082 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7083 } 7084 Binder.restoreCallingIdentity(origId); 7085 } 7086 return false; 7087 } 7088 7089 @Override 7090 public void moveTaskBackwards(int task) { 7091 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7092 "moveTaskBackwards()"); 7093 7094 synchronized(this) { 7095 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7096 Binder.getCallingUid(), "Task backwards")) { 7097 return; 7098 } 7099 final long origId = Binder.clearCallingIdentity(); 7100 moveTaskBackwardsLocked(task); 7101 Binder.restoreCallingIdentity(origId); 7102 } 7103 } 7104 7105 private final void moveTaskBackwardsLocked(int task) { 7106 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7107 } 7108 7109 @Override 7110 public int createStack(int taskId, int relativeStackBoxId, int position, float weight) { 7111 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7112 "createStack()"); 7113 if (DEBUG_STACK) Slog.d(TAG, "createStack: taskId=" + taskId + " relStackBoxId=" + 7114 relativeStackBoxId + " position=" + position + " weight=" + weight); 7115 synchronized (this) { 7116 long ident = Binder.clearCallingIdentity(); 7117 try { 7118 int stackId = mStackSupervisor.createStack(); 7119 mWindowManager.createStack(stackId, relativeStackBoxId, position, weight); 7120 if (taskId > 0) { 7121 moveTaskToStack(taskId, stackId, true); 7122 } 7123 return stackId; 7124 } finally { 7125 Binder.restoreCallingIdentity(ident); 7126 } 7127 } 7128 } 7129 7130 @Override 7131 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7132 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7133 "moveTaskToStack()"); 7134 if (stackId == HOME_STACK_ID) { 7135 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7136 new RuntimeException("here").fillInStackTrace()); 7137 } 7138 synchronized (this) { 7139 long ident = Binder.clearCallingIdentity(); 7140 try { 7141 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7142 + stackId + " toTop=" + toTop); 7143 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7144 } finally { 7145 Binder.restoreCallingIdentity(ident); 7146 } 7147 } 7148 } 7149 7150 @Override 7151 public void resizeStackBox(int stackBoxId, float weight) { 7152 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7153 "resizeStackBox()"); 7154 long ident = Binder.clearCallingIdentity(); 7155 try { 7156 mWindowManager.resizeStackBox(stackBoxId, weight); 7157 } finally { 7158 Binder.restoreCallingIdentity(ident); 7159 } 7160 } 7161 7162 private ArrayList<StackInfo> getStacks() { 7163 synchronized (this) { 7164 ArrayList<ActivityManager.StackInfo> list = new ArrayList<ActivityManager.StackInfo>(); 7165 ArrayList<ActivityStack> stacks = mStackSupervisor.getStacks(); 7166 for (ActivityStack stack : stacks) { 7167 ActivityManager.StackInfo stackInfo = new ActivityManager.StackInfo(); 7168 int stackId = stack.mStackId; 7169 stackInfo.stackId = stackId; 7170 stackInfo.bounds = mWindowManager.getStackBounds(stackId); 7171 ArrayList<TaskRecord> tasks = stack.getAllTasks(); 7172 final int numTasks = tasks.size(); 7173 int[] taskIds = new int[numTasks]; 7174 String[] taskNames = new String[numTasks]; 7175 for (int i = 0; i < numTasks; ++i) { 7176 final TaskRecord task = tasks.get(i); 7177 taskIds[i] = task.taskId; 7178 taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString() 7179 : task.realActivity != null ? task.realActivity.flattenToString() 7180 : task.getTopActivity() != null ? task.getTopActivity().packageName 7181 : "unknown"; 7182 } 7183 stackInfo.taskIds = taskIds; 7184 stackInfo.taskNames = taskNames; 7185 list.add(stackInfo); 7186 } 7187 return list; 7188 } 7189 } 7190 7191 private void addStackInfoToStackBoxInfo(StackBoxInfo stackBoxInfo, List<StackInfo> stackInfos) { 7192 final int stackId = stackBoxInfo.stackId; 7193 if (stackId >= 0) { 7194 for (StackInfo stackInfo : stackInfos) { 7195 if (stackId == stackInfo.stackId) { 7196 stackBoxInfo.stack = stackInfo; 7197 stackInfos.remove(stackInfo); 7198 return; 7199 } 7200 } 7201 } else { 7202 addStackInfoToStackBoxInfo(stackBoxInfo.children[0], stackInfos); 7203 addStackInfoToStackBoxInfo(stackBoxInfo.children[1], stackInfos); 7204 } 7205 } 7206 7207 @Override 7208 public List<StackBoxInfo> getStackBoxes() { 7209 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7210 "getStackBoxes()"); 7211 long ident = Binder.clearCallingIdentity(); 7212 try { 7213 List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos(); 7214 synchronized (this) { 7215 List<StackInfo> stackInfos = getStacks(); 7216 for (StackBoxInfo stackBoxInfo : stackBoxInfos) { 7217 addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos); 7218 } 7219 } 7220 return stackBoxInfos; 7221 } finally { 7222 Binder.restoreCallingIdentity(ident); 7223 } 7224 } 7225 7226 @Override 7227 public StackBoxInfo getStackBoxInfo(int stackBoxId) { 7228 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7229 "getStackBoxInfo()"); 7230 long ident = Binder.clearCallingIdentity(); 7231 try { 7232 List<StackBoxInfo> stackBoxInfos = mWindowManager.getStackBoxInfos(); 7233 StackBoxInfo info = null; 7234 synchronized (this) { 7235 List<StackInfo> stackInfos = getStacks(); 7236 for (StackBoxInfo stackBoxInfo : stackBoxInfos) { 7237 addStackInfoToStackBoxInfo(stackBoxInfo, stackInfos); 7238 if (stackBoxInfo.stackBoxId == stackBoxId) { 7239 info = stackBoxInfo; 7240 } 7241 } 7242 } 7243 return info; 7244 } finally { 7245 Binder.restoreCallingIdentity(ident); 7246 } 7247 } 7248 7249 @Override 7250 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7251 synchronized(this) { 7252 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7253 } 7254 } 7255 7256 // ========================================================= 7257 // THUMBNAILS 7258 // ========================================================= 7259 7260 public void reportThumbnail(IBinder token, 7261 Bitmap thumbnail, CharSequence description) { 7262 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7263 final long origId = Binder.clearCallingIdentity(); 7264 sendPendingThumbnail(null, token, thumbnail, description, true); 7265 Binder.restoreCallingIdentity(origId); 7266 } 7267 7268 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7269 Bitmap thumbnail, CharSequence description, boolean always) { 7270 TaskRecord task; 7271 ArrayList<PendingThumbnailsRecord> receivers = null; 7272 7273 //System.out.println("Send pending thumbnail: " + r); 7274 7275 synchronized(this) { 7276 if (r == null) { 7277 r = ActivityRecord.isInStackLocked(token); 7278 if (r == null) { 7279 return; 7280 } 7281 } 7282 if (thumbnail == null && r.thumbHolder != null) { 7283 thumbnail = r.thumbHolder.lastThumbnail; 7284 description = r.thumbHolder.lastDescription; 7285 } 7286 if (thumbnail == null && !always) { 7287 // If there is no thumbnail, and this entry is not actually 7288 // going away, then abort for now and pick up the next 7289 // thumbnail we get. 7290 return; 7291 } 7292 task = r.task; 7293 7294 int N = mPendingThumbnails.size(); 7295 int i=0; 7296 while (i<N) { 7297 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7298 //System.out.println("Looking in " + pr.pendingRecords); 7299 if (pr.pendingRecords.remove(r)) { 7300 if (receivers == null) { 7301 receivers = new ArrayList<PendingThumbnailsRecord>(); 7302 } 7303 receivers.add(pr); 7304 if (pr.pendingRecords.size() == 0) { 7305 pr.finished = true; 7306 mPendingThumbnails.remove(i); 7307 N--; 7308 continue; 7309 } 7310 } 7311 i++; 7312 } 7313 } 7314 7315 if (receivers != null) { 7316 final int N = receivers.size(); 7317 for (int i=0; i<N; i++) { 7318 try { 7319 PendingThumbnailsRecord pr = receivers.get(i); 7320 pr.receiver.newThumbnail( 7321 task != null ? task.taskId : -1, thumbnail, description); 7322 if (pr.finished) { 7323 pr.receiver.finished(); 7324 } 7325 } catch (Exception e) { 7326 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7327 } 7328 } 7329 } 7330 } 7331 7332 // ========================================================= 7333 // CONTENT PROVIDERS 7334 // ========================================================= 7335 7336 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7337 List<ProviderInfo> providers = null; 7338 try { 7339 providers = AppGlobals.getPackageManager(). 7340 queryContentProviders(app.processName, app.uid, 7341 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7342 } catch (RemoteException ex) { 7343 } 7344 if (DEBUG_MU) 7345 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7346 int userId = app.userId; 7347 if (providers != null) { 7348 int N = providers.size(); 7349 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7350 for (int i=0; i<N; i++) { 7351 ProviderInfo cpi = 7352 (ProviderInfo)providers.get(i); 7353 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7354 cpi.name, cpi.flags); 7355 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7356 // This is a singleton provider, but a user besides the 7357 // default user is asking to initialize a process it runs 7358 // in... well, no, it doesn't actually run in this process, 7359 // it runs in the process of the default user. Get rid of it. 7360 providers.remove(i); 7361 N--; 7362 i--; 7363 continue; 7364 } 7365 7366 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7367 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7368 if (cpr == null) { 7369 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7370 mProviderMap.putProviderByClass(comp, cpr); 7371 } 7372 if (DEBUG_MU) 7373 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7374 app.pubProviders.put(cpi.name, cpr); 7375 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7376 // Don't add this if it is a platform component that is marked 7377 // to run in multiple processes, because this is actually 7378 // part of the framework so doesn't make sense to track as a 7379 // separate apk in the process. 7380 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7381 } 7382 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7383 } 7384 } 7385 return providers; 7386 } 7387 7388 /** 7389 * Check if {@link ProcessRecord} has a possible chance at accessing the 7390 * given {@link ProviderInfo}. Final permission checking is always done 7391 * in {@link ContentProvider}. 7392 */ 7393 private final String checkContentProviderPermissionLocked( 7394 ProviderInfo cpi, ProcessRecord r) { 7395 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7396 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7397 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7398 cpi.applicationInfo.uid, cpi.exported) 7399 == PackageManager.PERMISSION_GRANTED) { 7400 return null; 7401 } 7402 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7403 cpi.applicationInfo.uid, cpi.exported) 7404 == PackageManager.PERMISSION_GRANTED) { 7405 return null; 7406 } 7407 7408 PathPermission[] pps = cpi.pathPermissions; 7409 if (pps != null) { 7410 int i = pps.length; 7411 while (i > 0) { 7412 i--; 7413 PathPermission pp = pps[i]; 7414 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7415 cpi.applicationInfo.uid, cpi.exported) 7416 == PackageManager.PERMISSION_GRANTED) { 7417 return null; 7418 } 7419 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7420 cpi.applicationInfo.uid, cpi.exported) 7421 == PackageManager.PERMISSION_GRANTED) { 7422 return null; 7423 } 7424 } 7425 } 7426 7427 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7428 if (perms != null) { 7429 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7430 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7431 return null; 7432 } 7433 } 7434 } 7435 7436 String msg; 7437 if (!cpi.exported) { 7438 msg = "Permission Denial: opening provider " + cpi.name 7439 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7440 + ", uid=" + callingUid + ") that is not exported from uid " 7441 + cpi.applicationInfo.uid; 7442 } else { 7443 msg = "Permission Denial: opening provider " + cpi.name 7444 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7445 + ", uid=" + callingUid + ") requires " 7446 + cpi.readPermission + " or " + cpi.writePermission; 7447 } 7448 Slog.w(TAG, msg); 7449 return msg; 7450 } 7451 7452 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7453 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7454 if (r != null) { 7455 for (int i=0; i<r.conProviders.size(); i++) { 7456 ContentProviderConnection conn = r.conProviders.get(i); 7457 if (conn.provider == cpr) { 7458 if (DEBUG_PROVIDER) Slog.v(TAG, 7459 "Adding provider requested by " 7460 + r.processName + " from process " 7461 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7462 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7463 if (stable) { 7464 conn.stableCount++; 7465 conn.numStableIncs++; 7466 } else { 7467 conn.unstableCount++; 7468 conn.numUnstableIncs++; 7469 } 7470 return conn; 7471 } 7472 } 7473 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7474 if (stable) { 7475 conn.stableCount = 1; 7476 conn.numStableIncs = 1; 7477 } else { 7478 conn.unstableCount = 1; 7479 conn.numUnstableIncs = 1; 7480 } 7481 cpr.connections.add(conn); 7482 r.conProviders.add(conn); 7483 return conn; 7484 } 7485 cpr.addExternalProcessHandleLocked(externalProcessToken); 7486 return null; 7487 } 7488 7489 boolean decProviderCountLocked(ContentProviderConnection conn, 7490 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7491 if (conn != null) { 7492 cpr = conn.provider; 7493 if (DEBUG_PROVIDER) Slog.v(TAG, 7494 "Removing provider requested by " 7495 + conn.client.processName + " from process " 7496 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7497 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7498 if (stable) { 7499 conn.stableCount--; 7500 } else { 7501 conn.unstableCount--; 7502 } 7503 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7504 cpr.connections.remove(conn); 7505 conn.client.conProviders.remove(conn); 7506 return true; 7507 } 7508 return false; 7509 } 7510 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7511 return false; 7512 } 7513 7514 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7515 String name, IBinder token, boolean stable, int userId) { 7516 ContentProviderRecord cpr; 7517 ContentProviderConnection conn = null; 7518 ProviderInfo cpi = null; 7519 7520 synchronized(this) { 7521 ProcessRecord r = null; 7522 if (caller != null) { 7523 r = getRecordForAppLocked(caller); 7524 if (r == null) { 7525 throw new SecurityException( 7526 "Unable to find app for caller " + caller 7527 + " (pid=" + Binder.getCallingPid() 7528 + ") when getting content provider " + name); 7529 } 7530 } 7531 7532 // First check if this content provider has been published... 7533 cpr = mProviderMap.getProviderByName(name, userId); 7534 boolean providerRunning = cpr != null; 7535 if (providerRunning) { 7536 cpi = cpr.info; 7537 String msg; 7538 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7539 throw new SecurityException(msg); 7540 } 7541 7542 if (r != null && cpr.canRunHere(r)) { 7543 // This provider has been published or is in the process 7544 // of being published... but it is also allowed to run 7545 // in the caller's process, so don't make a connection 7546 // and just let the caller instantiate its own instance. 7547 ContentProviderHolder holder = cpr.newHolder(null); 7548 // don't give caller the provider object, it needs 7549 // to make its own. 7550 holder.provider = null; 7551 return holder; 7552 } 7553 7554 final long origId = Binder.clearCallingIdentity(); 7555 7556 // In this case the provider instance already exists, so we can 7557 // return it right away. 7558 conn = incProviderCountLocked(r, cpr, token, stable); 7559 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7560 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7561 // If this is a perceptible app accessing the provider, 7562 // make sure to count it as being accessed and thus 7563 // back up on the LRU list. This is good because 7564 // content providers are often expensive to start. 7565 updateLruProcessLocked(cpr.proc, false, null); 7566 } 7567 } 7568 7569 if (cpr.proc != null) { 7570 if (false) { 7571 if (cpr.name.flattenToShortString().equals( 7572 "com.android.providers.calendar/.CalendarProvider2")) { 7573 Slog.v(TAG, "****************** KILLING " 7574 + cpr.name.flattenToShortString()); 7575 Process.killProcess(cpr.proc.pid); 7576 } 7577 } 7578 boolean success = updateOomAdjLocked(cpr.proc); 7579 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7580 // NOTE: there is still a race here where a signal could be 7581 // pending on the process even though we managed to update its 7582 // adj level. Not sure what to do about this, but at least 7583 // the race is now smaller. 7584 if (!success) { 7585 // Uh oh... it looks like the provider's process 7586 // has been killed on us. We need to wait for a new 7587 // process to be started, and make sure its death 7588 // doesn't kill our process. 7589 Slog.i(TAG, 7590 "Existing provider " + cpr.name.flattenToShortString() 7591 + " is crashing; detaching " + r); 7592 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7593 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7594 if (!lastRef) { 7595 // This wasn't the last ref our process had on 7596 // the provider... we have now been killed, bail. 7597 return null; 7598 } 7599 providerRunning = false; 7600 conn = null; 7601 } 7602 } 7603 7604 Binder.restoreCallingIdentity(origId); 7605 } 7606 7607 boolean singleton; 7608 if (!providerRunning) { 7609 try { 7610 cpi = AppGlobals.getPackageManager(). 7611 resolveContentProvider(name, 7612 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7613 } catch (RemoteException ex) { 7614 } 7615 if (cpi == null) { 7616 return null; 7617 } 7618 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7619 cpi.name, cpi.flags); 7620 if (singleton) { 7621 userId = 0; 7622 } 7623 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7624 7625 String msg; 7626 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7627 throw new SecurityException(msg); 7628 } 7629 7630 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7631 && !cpi.processName.equals("system")) { 7632 // If this content provider does not run in the system 7633 // process, and the system is not yet ready to run other 7634 // processes, then fail fast instead of hanging. 7635 throw new IllegalArgumentException( 7636 "Attempt to launch content provider before system ready"); 7637 } 7638 7639 // Make sure that the user who owns this provider is started. If not, 7640 // we don't want to allow it to run. 7641 if (mStartedUsers.get(userId) == null) { 7642 Slog.w(TAG, "Unable to launch app " 7643 + cpi.applicationInfo.packageName + "/" 7644 + cpi.applicationInfo.uid + " for provider " 7645 + name + ": user " + userId + " is stopped"); 7646 return null; 7647 } 7648 7649 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7650 cpr = mProviderMap.getProviderByClass(comp, userId); 7651 final boolean firstClass = cpr == null; 7652 if (firstClass) { 7653 try { 7654 ApplicationInfo ai = 7655 AppGlobals.getPackageManager(). 7656 getApplicationInfo( 7657 cpi.applicationInfo.packageName, 7658 STOCK_PM_FLAGS, userId); 7659 if (ai == null) { 7660 Slog.w(TAG, "No package info for content provider " 7661 + cpi.name); 7662 return null; 7663 } 7664 ai = getAppInfoForUser(ai, userId); 7665 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7666 } catch (RemoteException ex) { 7667 // pm is in same process, this will never happen. 7668 } 7669 } 7670 7671 if (r != null && cpr.canRunHere(r)) { 7672 // If this is a multiprocess provider, then just return its 7673 // info and allow the caller to instantiate it. Only do 7674 // this if the provider is the same user as the caller's 7675 // process, or can run as root (so can be in any process). 7676 return cpr.newHolder(null); 7677 } 7678 7679 if (DEBUG_PROVIDER) { 7680 RuntimeException e = new RuntimeException("here"); 7681 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7682 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7683 } 7684 7685 // This is single process, and our app is now connecting to it. 7686 // See if we are already in the process of launching this 7687 // provider. 7688 final int N = mLaunchingProviders.size(); 7689 int i; 7690 for (i=0; i<N; i++) { 7691 if (mLaunchingProviders.get(i) == cpr) { 7692 break; 7693 } 7694 } 7695 7696 // If the provider is not already being launched, then get it 7697 // started. 7698 if (i >= N) { 7699 final long origId = Binder.clearCallingIdentity(); 7700 7701 try { 7702 // Content provider is now in use, its package can't be stopped. 7703 try { 7704 AppGlobals.getPackageManager().setPackageStoppedState( 7705 cpr.appInfo.packageName, false, userId); 7706 } catch (RemoteException e) { 7707 } catch (IllegalArgumentException e) { 7708 Slog.w(TAG, "Failed trying to unstop package " 7709 + cpr.appInfo.packageName + ": " + e); 7710 } 7711 7712 // Use existing process if already started 7713 ProcessRecord proc = getProcessRecordLocked( 7714 cpi.processName, cpr.appInfo.uid, false); 7715 if (proc != null && proc.thread != null) { 7716 if (DEBUG_PROVIDER) { 7717 Slog.d(TAG, "Installing in existing process " + proc); 7718 } 7719 proc.pubProviders.put(cpi.name, cpr); 7720 try { 7721 proc.thread.scheduleInstallProvider(cpi); 7722 } catch (RemoteException e) { 7723 } 7724 } else { 7725 proc = startProcessLocked(cpi.processName, 7726 cpr.appInfo, false, 0, "content provider", 7727 new ComponentName(cpi.applicationInfo.packageName, 7728 cpi.name), false, false, false); 7729 if (proc == null) { 7730 Slog.w(TAG, "Unable to launch app " 7731 + cpi.applicationInfo.packageName + "/" 7732 + cpi.applicationInfo.uid + " for provider " 7733 + name + ": process is bad"); 7734 return null; 7735 } 7736 } 7737 cpr.launchingApp = proc; 7738 mLaunchingProviders.add(cpr); 7739 } finally { 7740 Binder.restoreCallingIdentity(origId); 7741 } 7742 } 7743 7744 // Make sure the provider is published (the same provider class 7745 // may be published under multiple names). 7746 if (firstClass) { 7747 mProviderMap.putProviderByClass(comp, cpr); 7748 } 7749 7750 mProviderMap.putProviderByName(name, cpr); 7751 conn = incProviderCountLocked(r, cpr, token, stable); 7752 if (conn != null) { 7753 conn.waiting = true; 7754 } 7755 } 7756 } 7757 7758 // Wait for the provider to be published... 7759 synchronized (cpr) { 7760 while (cpr.provider == null) { 7761 if (cpr.launchingApp == null) { 7762 Slog.w(TAG, "Unable to launch app " 7763 + cpi.applicationInfo.packageName + "/" 7764 + cpi.applicationInfo.uid + " for provider " 7765 + name + ": launching app became null"); 7766 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7767 UserHandle.getUserId(cpi.applicationInfo.uid), 7768 cpi.applicationInfo.packageName, 7769 cpi.applicationInfo.uid, name); 7770 return null; 7771 } 7772 try { 7773 if (DEBUG_MU) { 7774 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7775 + cpr.launchingApp); 7776 } 7777 if (conn != null) { 7778 conn.waiting = true; 7779 } 7780 cpr.wait(); 7781 } catch (InterruptedException ex) { 7782 } finally { 7783 if (conn != null) { 7784 conn.waiting = false; 7785 } 7786 } 7787 } 7788 } 7789 return cpr != null ? cpr.newHolder(conn) : null; 7790 } 7791 7792 public final ContentProviderHolder getContentProvider( 7793 IApplicationThread caller, String name, int userId, boolean stable) { 7794 enforceNotIsolatedCaller("getContentProvider"); 7795 if (caller == null) { 7796 String msg = "null IApplicationThread when getting content provider " 7797 + name; 7798 Slog.w(TAG, msg); 7799 throw new SecurityException(msg); 7800 } 7801 7802 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7803 false, true, "getContentProvider", null); 7804 return getContentProviderImpl(caller, name, null, stable, userId); 7805 } 7806 7807 public ContentProviderHolder getContentProviderExternal( 7808 String name, int userId, IBinder token) { 7809 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7810 "Do not have permission in call getContentProviderExternal()"); 7811 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7812 false, true, "getContentProvider", null); 7813 return getContentProviderExternalUnchecked(name, token, userId); 7814 } 7815 7816 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7817 IBinder token, int userId) { 7818 return getContentProviderImpl(null, name, token, true, userId); 7819 } 7820 7821 /** 7822 * Drop a content provider from a ProcessRecord's bookkeeping 7823 */ 7824 public void removeContentProvider(IBinder connection, boolean stable) { 7825 enforceNotIsolatedCaller("removeContentProvider"); 7826 synchronized (this) { 7827 ContentProviderConnection conn; 7828 try { 7829 conn = (ContentProviderConnection)connection; 7830 } catch (ClassCastException e) { 7831 String msg ="removeContentProvider: " + connection 7832 + " not a ContentProviderConnection"; 7833 Slog.w(TAG, msg); 7834 throw new IllegalArgumentException(msg); 7835 } 7836 if (conn == null) { 7837 throw new NullPointerException("connection is null"); 7838 } 7839 if (decProviderCountLocked(conn, null, null, stable)) { 7840 updateOomAdjLocked(); 7841 } 7842 } 7843 } 7844 7845 public void removeContentProviderExternal(String name, IBinder token) { 7846 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7847 "Do not have permission in call removeContentProviderExternal()"); 7848 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7849 } 7850 7851 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7852 synchronized (this) { 7853 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7854 if(cpr == null) { 7855 //remove from mProvidersByClass 7856 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7857 return; 7858 } 7859 7860 //update content provider record entry info 7861 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7862 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7863 if (localCpr.hasExternalProcessHandles()) { 7864 if (localCpr.removeExternalProcessHandleLocked(token)) { 7865 updateOomAdjLocked(); 7866 } else { 7867 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7868 + " with no external reference for token: " 7869 + token + "."); 7870 } 7871 } else { 7872 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7873 + " with no external references."); 7874 } 7875 } 7876 } 7877 7878 public final void publishContentProviders(IApplicationThread caller, 7879 List<ContentProviderHolder> providers) { 7880 if (providers == null) { 7881 return; 7882 } 7883 7884 enforceNotIsolatedCaller("publishContentProviders"); 7885 synchronized (this) { 7886 final ProcessRecord r = getRecordForAppLocked(caller); 7887 if (DEBUG_MU) 7888 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7889 if (r == null) { 7890 throw new SecurityException( 7891 "Unable to find app for caller " + caller 7892 + " (pid=" + Binder.getCallingPid() 7893 + ") when publishing content providers"); 7894 } 7895 7896 final long origId = Binder.clearCallingIdentity(); 7897 7898 final int N = providers.size(); 7899 for (int i=0; i<N; i++) { 7900 ContentProviderHolder src = providers.get(i); 7901 if (src == null || src.info == null || src.provider == null) { 7902 continue; 7903 } 7904 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 7905 if (DEBUG_MU) 7906 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 7907 if (dst != null) { 7908 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 7909 mProviderMap.putProviderByClass(comp, dst); 7910 String names[] = dst.info.authority.split(";"); 7911 for (int j = 0; j < names.length; j++) { 7912 mProviderMap.putProviderByName(names[j], dst); 7913 } 7914 7915 int NL = mLaunchingProviders.size(); 7916 int j; 7917 for (j=0; j<NL; j++) { 7918 if (mLaunchingProviders.get(j) == dst) { 7919 mLaunchingProviders.remove(j); 7920 j--; 7921 NL--; 7922 } 7923 } 7924 synchronized (dst) { 7925 dst.provider = src.provider; 7926 dst.proc = r; 7927 dst.notifyAll(); 7928 } 7929 updateOomAdjLocked(r); 7930 } 7931 } 7932 7933 Binder.restoreCallingIdentity(origId); 7934 } 7935 } 7936 7937 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 7938 ContentProviderConnection conn; 7939 try { 7940 conn = (ContentProviderConnection)connection; 7941 } catch (ClassCastException e) { 7942 String msg ="refContentProvider: " + connection 7943 + " not a ContentProviderConnection"; 7944 Slog.w(TAG, msg); 7945 throw new IllegalArgumentException(msg); 7946 } 7947 if (conn == null) { 7948 throw new NullPointerException("connection is null"); 7949 } 7950 7951 synchronized (this) { 7952 if (stable > 0) { 7953 conn.numStableIncs += stable; 7954 } 7955 stable = conn.stableCount + stable; 7956 if (stable < 0) { 7957 throw new IllegalStateException("stableCount < 0: " + stable); 7958 } 7959 7960 if (unstable > 0) { 7961 conn.numUnstableIncs += unstable; 7962 } 7963 unstable = conn.unstableCount + unstable; 7964 if (unstable < 0) { 7965 throw new IllegalStateException("unstableCount < 0: " + unstable); 7966 } 7967 7968 if ((stable+unstable) <= 0) { 7969 throw new IllegalStateException("ref counts can't go to zero here: stable=" 7970 + stable + " unstable=" + unstable); 7971 } 7972 conn.stableCount = stable; 7973 conn.unstableCount = unstable; 7974 return !conn.dead; 7975 } 7976 } 7977 7978 public void unstableProviderDied(IBinder connection) { 7979 ContentProviderConnection conn; 7980 try { 7981 conn = (ContentProviderConnection)connection; 7982 } catch (ClassCastException e) { 7983 String msg ="refContentProvider: " + connection 7984 + " not a ContentProviderConnection"; 7985 Slog.w(TAG, msg); 7986 throw new IllegalArgumentException(msg); 7987 } 7988 if (conn == null) { 7989 throw new NullPointerException("connection is null"); 7990 } 7991 7992 // Safely retrieve the content provider associated with the connection. 7993 IContentProvider provider; 7994 synchronized (this) { 7995 provider = conn.provider.provider; 7996 } 7997 7998 if (provider == null) { 7999 // Um, yeah, we're way ahead of you. 8000 return; 8001 } 8002 8003 // Make sure the caller is being honest with us. 8004 if (provider.asBinder().pingBinder()) { 8005 // Er, no, still looks good to us. 8006 synchronized (this) { 8007 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8008 + " says " + conn + " died, but we don't agree"); 8009 return; 8010 } 8011 } 8012 8013 // Well look at that! It's dead! 8014 synchronized (this) { 8015 if (conn.provider.provider != provider) { 8016 // But something changed... good enough. 8017 return; 8018 } 8019 8020 ProcessRecord proc = conn.provider.proc; 8021 if (proc == null || proc.thread == null) { 8022 // Seems like the process is already cleaned up. 8023 return; 8024 } 8025 8026 // As far as we're concerned, this is just like receiving a 8027 // death notification... just a bit prematurely. 8028 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8029 + ") early provider death"); 8030 final long ident = Binder.clearCallingIdentity(); 8031 try { 8032 appDiedLocked(proc, proc.pid, proc.thread); 8033 } finally { 8034 Binder.restoreCallingIdentity(ident); 8035 } 8036 } 8037 } 8038 8039 @Override 8040 public void appNotRespondingViaProvider(IBinder connection) { 8041 enforceCallingPermission( 8042 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8043 8044 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8045 if (conn == null) { 8046 Slog.w(TAG, "ContentProviderConnection is null"); 8047 return; 8048 } 8049 8050 final ProcessRecord host = conn.provider.proc; 8051 if (host == null) { 8052 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8053 return; 8054 } 8055 8056 final long token = Binder.clearCallingIdentity(); 8057 try { 8058 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8059 } finally { 8060 Binder.restoreCallingIdentity(token); 8061 } 8062 } 8063 8064 public static final void installSystemProviders() { 8065 List<ProviderInfo> providers; 8066 synchronized (mSelf) { 8067 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 8068 providers = mSelf.generateApplicationProvidersLocked(app); 8069 if (providers != null) { 8070 for (int i=providers.size()-1; i>=0; i--) { 8071 ProviderInfo pi = (ProviderInfo)providers.get(i); 8072 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8073 Slog.w(TAG, "Not installing system proc provider " + pi.name 8074 + ": not system .apk"); 8075 providers.remove(i); 8076 } 8077 } 8078 } 8079 } 8080 if (providers != null) { 8081 mSystemThread.installSystemProviders(providers); 8082 } 8083 8084 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf); 8085 8086 mSelf.mUsageStatsService.monitorPackages(); 8087 } 8088 8089 /** 8090 * Allows app to retrieve the MIME type of a URI without having permission 8091 * to access its content provider. 8092 * 8093 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8094 * 8095 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8096 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8097 */ 8098 public String getProviderMimeType(Uri uri, int userId) { 8099 enforceNotIsolatedCaller("getProviderMimeType"); 8100 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8101 userId, false, true, "getProviderMimeType", null); 8102 final String name = uri.getAuthority(); 8103 final long ident = Binder.clearCallingIdentity(); 8104 ContentProviderHolder holder = null; 8105 8106 try { 8107 holder = getContentProviderExternalUnchecked(name, null, userId); 8108 if (holder != null) { 8109 return holder.provider.getType(uri); 8110 } 8111 } catch (RemoteException e) { 8112 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8113 return null; 8114 } finally { 8115 if (holder != null) { 8116 removeContentProviderExternalUnchecked(name, null, userId); 8117 } 8118 Binder.restoreCallingIdentity(ident); 8119 } 8120 8121 return null; 8122 } 8123 8124 // ========================================================= 8125 // GLOBAL MANAGEMENT 8126 // ========================================================= 8127 8128 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8129 boolean isolated) { 8130 String proc = customProcess != null ? customProcess : info.processName; 8131 BatteryStatsImpl.Uid.Proc ps = null; 8132 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8133 int uid = info.uid; 8134 if (isolated) { 8135 int userId = UserHandle.getUserId(uid); 8136 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8137 while (true) { 8138 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8139 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8140 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8141 } 8142 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8143 mNextIsolatedProcessUid++; 8144 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8145 // No process for this uid, use it. 8146 break; 8147 } 8148 stepsLeft--; 8149 if (stepsLeft <= 0) { 8150 return null; 8151 } 8152 } 8153 } 8154 return new ProcessRecord(stats, info, proc, uid); 8155 } 8156 8157 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8158 ProcessRecord app; 8159 if (!isolated) { 8160 app = getProcessRecordLocked(info.processName, info.uid, true); 8161 } else { 8162 app = null; 8163 } 8164 8165 if (app == null) { 8166 app = newProcessRecordLocked(info, null, isolated); 8167 mProcessNames.put(info.processName, app.uid, app); 8168 if (isolated) { 8169 mIsolatedProcesses.put(app.uid, app); 8170 } 8171 updateLruProcessLocked(app, false, null); 8172 updateOomAdjLocked(); 8173 } 8174 8175 // This package really, really can not be stopped. 8176 try { 8177 AppGlobals.getPackageManager().setPackageStoppedState( 8178 info.packageName, false, UserHandle.getUserId(app.uid)); 8179 } catch (RemoteException e) { 8180 } catch (IllegalArgumentException e) { 8181 Slog.w(TAG, "Failed trying to unstop package " 8182 + info.packageName + ": " + e); 8183 } 8184 8185 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8186 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8187 app.persistent = true; 8188 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8189 } 8190 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8191 mPersistentStartingProcesses.add(app); 8192 startProcessLocked(app, "added application", app.processName); 8193 } 8194 8195 return app; 8196 } 8197 8198 public void unhandledBack() { 8199 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8200 "unhandledBack()"); 8201 8202 synchronized(this) { 8203 final long origId = Binder.clearCallingIdentity(); 8204 try { 8205 getFocusedStack().unhandledBackLocked(); 8206 } finally { 8207 Binder.restoreCallingIdentity(origId); 8208 } 8209 } 8210 } 8211 8212 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8213 enforceNotIsolatedCaller("openContentUri"); 8214 final int userId = UserHandle.getCallingUserId(); 8215 String name = uri.getAuthority(); 8216 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8217 ParcelFileDescriptor pfd = null; 8218 if (cph != null) { 8219 // We record the binder invoker's uid in thread-local storage before 8220 // going to the content provider to open the file. Later, in the code 8221 // that handles all permissions checks, we look for this uid and use 8222 // that rather than the Activity Manager's own uid. The effect is that 8223 // we do the check against the caller's permissions even though it looks 8224 // to the content provider like the Activity Manager itself is making 8225 // the request. 8226 sCallerIdentity.set(new Identity( 8227 Binder.getCallingPid(), Binder.getCallingUid())); 8228 try { 8229 pfd = cph.provider.openFile(null, uri, "r", null); 8230 } catch (FileNotFoundException e) { 8231 // do nothing; pfd will be returned null 8232 } finally { 8233 // Ensure that whatever happens, we clean up the identity state 8234 sCallerIdentity.remove(); 8235 } 8236 8237 // We've got the fd now, so we're done with the provider. 8238 removeContentProviderExternalUnchecked(name, null, userId); 8239 } else { 8240 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8241 } 8242 return pfd; 8243 } 8244 8245 // Actually is sleeping or shutting down or whatever else in the future 8246 // is an inactive state. 8247 public boolean isSleepingOrShuttingDown() { 8248 return mSleeping || mShuttingDown; 8249 } 8250 8251 public void goingToSleep() { 8252 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8253 != PackageManager.PERMISSION_GRANTED) { 8254 throw new SecurityException("Requires permission " 8255 + android.Manifest.permission.DEVICE_POWER); 8256 } 8257 8258 synchronized(this) { 8259 mWentToSleep = true; 8260 updateEventDispatchingLocked(); 8261 8262 if (!mSleeping) { 8263 mSleeping = true; 8264 mStackSupervisor.goingToSleepLocked(); 8265 8266 // Initialize the wake times of all processes. 8267 checkExcessivePowerUsageLocked(false); 8268 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8269 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8270 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8271 } 8272 } 8273 } 8274 8275 @Override 8276 public boolean shutdown(int timeout) { 8277 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8278 != PackageManager.PERMISSION_GRANTED) { 8279 throw new SecurityException("Requires permission " 8280 + android.Manifest.permission.SHUTDOWN); 8281 } 8282 8283 boolean timedout = false; 8284 8285 synchronized(this) { 8286 mShuttingDown = true; 8287 updateEventDispatchingLocked(); 8288 timedout = mStackSupervisor.shutdownLocked(timeout); 8289 } 8290 8291 mAppOpsService.shutdown(); 8292 mUsageStatsService.shutdown(); 8293 mBatteryStatsService.shutdown(); 8294 synchronized (this) { 8295 mProcessStats.shutdownLocked(); 8296 } 8297 8298 return timedout; 8299 } 8300 8301 public final void activitySlept(IBinder token) { 8302 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8303 8304 final long origId = Binder.clearCallingIdentity(); 8305 8306 synchronized (this) { 8307 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8308 if (r != null) { 8309 mStackSupervisor.activitySleptLocked(r); 8310 } 8311 } 8312 8313 Binder.restoreCallingIdentity(origId); 8314 } 8315 8316 void logLockScreen(String msg) { 8317 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8318 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8319 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8320 mStackSupervisor.mDismissKeyguardOnNextActivity); 8321 } 8322 8323 private void comeOutOfSleepIfNeededLocked() { 8324 if (!mWentToSleep && !mLockScreenShown) { 8325 if (mSleeping) { 8326 mSleeping = false; 8327 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8328 } 8329 } 8330 } 8331 8332 public void wakingUp() { 8333 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8334 != PackageManager.PERMISSION_GRANTED) { 8335 throw new SecurityException("Requires permission " 8336 + android.Manifest.permission.DEVICE_POWER); 8337 } 8338 8339 synchronized(this) { 8340 mWentToSleep = false; 8341 updateEventDispatchingLocked(); 8342 comeOutOfSleepIfNeededLocked(); 8343 } 8344 } 8345 8346 private void updateEventDispatchingLocked() { 8347 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8348 } 8349 8350 public void setLockScreenShown(boolean shown) { 8351 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8352 != PackageManager.PERMISSION_GRANTED) { 8353 throw new SecurityException("Requires permission " 8354 + android.Manifest.permission.DEVICE_POWER); 8355 } 8356 8357 synchronized(this) { 8358 long ident = Binder.clearCallingIdentity(); 8359 try { 8360 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8361 mLockScreenShown = shown; 8362 comeOutOfSleepIfNeededLocked(); 8363 } finally { 8364 Binder.restoreCallingIdentity(ident); 8365 } 8366 } 8367 } 8368 8369 public void stopAppSwitches() { 8370 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8371 != PackageManager.PERMISSION_GRANTED) { 8372 throw new SecurityException("Requires permission " 8373 + android.Manifest.permission.STOP_APP_SWITCHES); 8374 } 8375 8376 synchronized(this) { 8377 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8378 + APP_SWITCH_DELAY_TIME; 8379 mDidAppSwitch = false; 8380 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8381 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8382 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8383 } 8384 } 8385 8386 public void resumeAppSwitches() { 8387 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8388 != PackageManager.PERMISSION_GRANTED) { 8389 throw new SecurityException("Requires permission " 8390 + android.Manifest.permission.STOP_APP_SWITCHES); 8391 } 8392 8393 synchronized(this) { 8394 // Note that we don't execute any pending app switches... we will 8395 // let those wait until either the timeout, or the next start 8396 // activity request. 8397 mAppSwitchesAllowedTime = 0; 8398 } 8399 } 8400 8401 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8402 String name) { 8403 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8404 return true; 8405 } 8406 8407 final int perm = checkComponentPermission( 8408 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8409 callingUid, -1, true); 8410 if (perm == PackageManager.PERMISSION_GRANTED) { 8411 return true; 8412 } 8413 8414 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8415 return false; 8416 } 8417 8418 public void setDebugApp(String packageName, boolean waitForDebugger, 8419 boolean persistent) { 8420 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8421 "setDebugApp()"); 8422 8423 long ident = Binder.clearCallingIdentity(); 8424 try { 8425 // Note that this is not really thread safe if there are multiple 8426 // callers into it at the same time, but that's not a situation we 8427 // care about. 8428 if (persistent) { 8429 final ContentResolver resolver = mContext.getContentResolver(); 8430 Settings.Global.putString( 8431 resolver, Settings.Global.DEBUG_APP, 8432 packageName); 8433 Settings.Global.putInt( 8434 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8435 waitForDebugger ? 1 : 0); 8436 } 8437 8438 synchronized (this) { 8439 if (!persistent) { 8440 mOrigDebugApp = mDebugApp; 8441 mOrigWaitForDebugger = mWaitForDebugger; 8442 } 8443 mDebugApp = packageName; 8444 mWaitForDebugger = waitForDebugger; 8445 mDebugTransient = !persistent; 8446 if (packageName != null) { 8447 forceStopPackageLocked(packageName, -1, false, false, true, true, 8448 UserHandle.USER_ALL, "set debug app"); 8449 } 8450 } 8451 } finally { 8452 Binder.restoreCallingIdentity(ident); 8453 } 8454 } 8455 8456 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8457 synchronized (this) { 8458 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8459 if (!isDebuggable) { 8460 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8461 throw new SecurityException("Process not debuggable: " + app.packageName); 8462 } 8463 } 8464 8465 mOpenGlTraceApp = processName; 8466 } 8467 } 8468 8469 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8470 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8471 synchronized (this) { 8472 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8473 if (!isDebuggable) { 8474 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8475 throw new SecurityException("Process not debuggable: " + app.packageName); 8476 } 8477 } 8478 mProfileApp = processName; 8479 mProfileFile = profileFile; 8480 if (mProfileFd != null) { 8481 try { 8482 mProfileFd.close(); 8483 } catch (IOException e) { 8484 } 8485 mProfileFd = null; 8486 } 8487 mProfileFd = profileFd; 8488 mProfileType = 0; 8489 mAutoStopProfiler = autoStopProfiler; 8490 } 8491 } 8492 8493 @Override 8494 public void setAlwaysFinish(boolean enabled) { 8495 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8496 "setAlwaysFinish()"); 8497 8498 Settings.Global.putInt( 8499 mContext.getContentResolver(), 8500 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8501 8502 synchronized (this) { 8503 mAlwaysFinishActivities = enabled; 8504 } 8505 } 8506 8507 @Override 8508 public void setActivityController(IActivityController controller) { 8509 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8510 "setActivityController()"); 8511 synchronized (this) { 8512 mController = controller; 8513 Watchdog.getInstance().setActivityController(controller); 8514 } 8515 } 8516 8517 @Override 8518 public void setUserIsMonkey(boolean userIsMonkey) { 8519 synchronized (this) { 8520 synchronized (mPidsSelfLocked) { 8521 final int callingPid = Binder.getCallingPid(); 8522 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8523 if (precessRecord == null) { 8524 throw new SecurityException("Unknown process: " + callingPid); 8525 } 8526 if (precessRecord.instrumentationUiAutomationConnection == null) { 8527 throw new SecurityException("Only an instrumentation process " 8528 + "with a UiAutomation can call setUserIsMonkey"); 8529 } 8530 } 8531 mUserIsMonkey = userIsMonkey; 8532 } 8533 } 8534 8535 @Override 8536 public boolean isUserAMonkey() { 8537 synchronized (this) { 8538 // If there is a controller also implies the user is a monkey. 8539 return (mUserIsMonkey || mController != null); 8540 } 8541 } 8542 8543 public void requestBugReport() { 8544 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8545 SystemProperties.set("ctl.start", "bugreport"); 8546 } 8547 8548 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8549 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8550 } 8551 8552 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8553 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8554 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8555 } 8556 return KEY_DISPATCHING_TIMEOUT; 8557 } 8558 8559 @Override 8560 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8561 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8562 != PackageManager.PERMISSION_GRANTED) { 8563 throw new SecurityException("Requires permission " 8564 + android.Manifest.permission.FILTER_EVENTS); 8565 } 8566 ProcessRecord proc; 8567 long timeout; 8568 synchronized (this) { 8569 synchronized (mPidsSelfLocked) { 8570 proc = mPidsSelfLocked.get(pid); 8571 } 8572 timeout = getInputDispatchingTimeoutLocked(proc); 8573 } 8574 8575 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8576 return -1; 8577 } 8578 8579 return timeout; 8580 } 8581 8582 /** 8583 * Handle input dispatching timeouts. 8584 * Returns whether input dispatching should be aborted or not. 8585 */ 8586 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8587 final ActivityRecord activity, final ActivityRecord parent, 8588 final boolean aboveSystem, String reason) { 8589 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8590 != PackageManager.PERMISSION_GRANTED) { 8591 throw new SecurityException("Requires permission " 8592 + android.Manifest.permission.FILTER_EVENTS); 8593 } 8594 8595 final String annotation; 8596 if (reason == null) { 8597 annotation = "Input dispatching timed out"; 8598 } else { 8599 annotation = "Input dispatching timed out (" + reason + ")"; 8600 } 8601 8602 if (proc != null) { 8603 synchronized (this) { 8604 if (proc.debugging) { 8605 return false; 8606 } 8607 8608 if (mDidDexOpt) { 8609 // Give more time since we were dexopting. 8610 mDidDexOpt = false; 8611 return false; 8612 } 8613 8614 if (proc.instrumentationClass != null) { 8615 Bundle info = new Bundle(); 8616 info.putString("shortMsg", "keyDispatchingTimedOut"); 8617 info.putString("longMsg", annotation); 8618 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8619 return true; 8620 } 8621 } 8622 mHandler.post(new Runnable() { 8623 @Override 8624 public void run() { 8625 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8626 } 8627 }); 8628 } 8629 8630 return true; 8631 } 8632 8633 public Bundle getAssistContextExtras(int requestType) { 8634 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8635 "getAssistContextExtras()"); 8636 PendingAssistExtras pae; 8637 Bundle extras = new Bundle(); 8638 synchronized (this) { 8639 ActivityRecord activity = getFocusedStack().mResumedActivity; 8640 if (activity == null) { 8641 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8642 return null; 8643 } 8644 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8645 if (activity.app == null || activity.app.thread == null) { 8646 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8647 return extras; 8648 } 8649 if (activity.app.pid == Binder.getCallingPid()) { 8650 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8651 return extras; 8652 } 8653 pae = new PendingAssistExtras(activity); 8654 try { 8655 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8656 requestType); 8657 mPendingAssistExtras.add(pae); 8658 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8659 } catch (RemoteException e) { 8660 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8661 return extras; 8662 } 8663 } 8664 synchronized (pae) { 8665 while (!pae.haveResult) { 8666 try { 8667 pae.wait(); 8668 } catch (InterruptedException e) { 8669 } 8670 } 8671 if (pae.result != null) { 8672 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8673 } 8674 } 8675 synchronized (this) { 8676 mPendingAssistExtras.remove(pae); 8677 mHandler.removeCallbacks(pae); 8678 } 8679 return extras; 8680 } 8681 8682 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8683 PendingAssistExtras pae = (PendingAssistExtras)token; 8684 synchronized (pae) { 8685 pae.result = extras; 8686 pae.haveResult = true; 8687 pae.notifyAll(); 8688 } 8689 } 8690 8691 public void registerProcessObserver(IProcessObserver observer) { 8692 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8693 "registerProcessObserver()"); 8694 synchronized (this) { 8695 mProcessObservers.register(observer); 8696 } 8697 } 8698 8699 @Override 8700 public void unregisterProcessObserver(IProcessObserver observer) { 8701 synchronized (this) { 8702 mProcessObservers.unregister(observer); 8703 } 8704 } 8705 8706 @Override 8707 public boolean convertFromTranslucent(IBinder token) { 8708 final long origId = Binder.clearCallingIdentity(); 8709 try { 8710 synchronized (this) { 8711 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8712 if (r == null) { 8713 return false; 8714 } 8715 if (r.changeWindowTranslucency(true)) { 8716 mWindowManager.setAppFullscreen(token, true); 8717 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8718 return true; 8719 } 8720 return false; 8721 } 8722 } finally { 8723 Binder.restoreCallingIdentity(origId); 8724 } 8725 } 8726 8727 @Override 8728 public boolean convertToTranslucent(IBinder token) { 8729 final long origId = Binder.clearCallingIdentity(); 8730 try { 8731 synchronized (this) { 8732 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8733 if (r == null) { 8734 return false; 8735 } 8736 if (r.changeWindowTranslucency(false)) { 8737 r.task.stack.convertToTranslucent(r); 8738 mWindowManager.setAppFullscreen(token, false); 8739 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8740 return true; 8741 } 8742 return false; 8743 } 8744 } finally { 8745 Binder.restoreCallingIdentity(origId); 8746 } 8747 } 8748 8749 @Override 8750 public void setImmersive(IBinder token, boolean immersive) { 8751 synchronized(this) { 8752 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8753 if (r == null) { 8754 throw new IllegalArgumentException(); 8755 } 8756 r.immersive = immersive; 8757 8758 // update associated state if we're frontmost 8759 if (r == mFocusedActivity) { 8760 if (DEBUG_IMMERSIVE) { 8761 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8762 } 8763 applyUpdateLockStateLocked(r); 8764 } 8765 } 8766 } 8767 8768 @Override 8769 public boolean isImmersive(IBinder token) { 8770 synchronized (this) { 8771 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8772 if (r == null) { 8773 throw new IllegalArgumentException(); 8774 } 8775 return r.immersive; 8776 } 8777 } 8778 8779 public boolean isTopActivityImmersive() { 8780 enforceNotIsolatedCaller("startActivity"); 8781 synchronized (this) { 8782 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8783 return (r != null) ? r.immersive : false; 8784 } 8785 } 8786 8787 public final void enterSafeMode() { 8788 synchronized(this) { 8789 // It only makes sense to do this before the system is ready 8790 // and started launching other packages. 8791 if (!mSystemReady) { 8792 try { 8793 AppGlobals.getPackageManager().enterSafeMode(); 8794 } catch (RemoteException e) { 8795 } 8796 } 8797 } 8798 } 8799 8800 public final void showSafeModeOverlay() { 8801 View v = LayoutInflater.from(mContext).inflate( 8802 com.android.internal.R.layout.safe_mode, null); 8803 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8804 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8805 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8806 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8807 lp.gravity = Gravity.BOTTOM | Gravity.START; 8808 lp.format = v.getBackground().getOpacity(); 8809 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8810 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8811 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8812 ((WindowManager)mContext.getSystemService( 8813 Context.WINDOW_SERVICE)).addView(v, lp); 8814 } 8815 8816 public void noteWakeupAlarm(IIntentSender sender) { 8817 if (!(sender instanceof PendingIntentRecord)) { 8818 return; 8819 } 8820 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8821 synchronized (stats) { 8822 if (mBatteryStatsService.isOnBattery()) { 8823 mBatteryStatsService.enforceCallingPermission(); 8824 PendingIntentRecord rec = (PendingIntentRecord)sender; 8825 int MY_UID = Binder.getCallingUid(); 8826 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8827 BatteryStatsImpl.Uid.Pkg pkg = 8828 stats.getPackageStatsLocked(uid, rec.key.packageName); 8829 pkg.incWakeupsLocked(); 8830 } 8831 } 8832 } 8833 8834 public boolean killPids(int[] pids, String pReason, boolean secure) { 8835 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8836 throw new SecurityException("killPids only available to the system"); 8837 } 8838 String reason = (pReason == null) ? "Unknown" : pReason; 8839 // XXX Note: don't acquire main activity lock here, because the window 8840 // manager calls in with its locks held. 8841 8842 boolean killed = false; 8843 synchronized (mPidsSelfLocked) { 8844 int[] types = new int[pids.length]; 8845 int worstType = 0; 8846 for (int i=0; i<pids.length; i++) { 8847 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8848 if (proc != null) { 8849 int type = proc.setAdj; 8850 types[i] = type; 8851 if (type > worstType) { 8852 worstType = type; 8853 } 8854 } 8855 } 8856 8857 // If the worst oom_adj is somewhere in the cached proc LRU range, 8858 // then constrain it so we will kill all cached procs. 8859 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8860 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8861 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8862 } 8863 8864 // If this is not a secure call, don't let it kill processes that 8865 // are important. 8866 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8867 worstType = ProcessList.SERVICE_ADJ; 8868 } 8869 8870 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8871 for (int i=0; i<pids.length; i++) { 8872 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8873 if (proc == null) { 8874 continue; 8875 } 8876 int adj = proc.setAdj; 8877 if (adj >= worstType && !proc.killedByAm) { 8878 killUnneededProcessLocked(proc, reason); 8879 killed = true; 8880 } 8881 } 8882 } 8883 return killed; 8884 } 8885 8886 @Override 8887 public void killUid(int uid, String reason) { 8888 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8889 throw new SecurityException("killUid only available to the system"); 8890 } 8891 synchronized (this) { 8892 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 8893 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 8894 reason != null ? reason : "kill uid"); 8895 } 8896 } 8897 8898 @Override 8899 public boolean killProcessesBelowForeground(String reason) { 8900 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8901 throw new SecurityException("killProcessesBelowForeground() only available to system"); 8902 } 8903 8904 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 8905 } 8906 8907 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 8908 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8909 throw new SecurityException("killProcessesBelowAdj() only available to system"); 8910 } 8911 8912 boolean killed = false; 8913 synchronized (mPidsSelfLocked) { 8914 final int size = mPidsSelfLocked.size(); 8915 for (int i = 0; i < size; i++) { 8916 final int pid = mPidsSelfLocked.keyAt(i); 8917 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8918 if (proc == null) continue; 8919 8920 final int adj = proc.setAdj; 8921 if (adj > belowAdj && !proc.killedByAm) { 8922 killUnneededProcessLocked(proc, reason); 8923 killed = true; 8924 } 8925 } 8926 } 8927 return killed; 8928 } 8929 8930 @Override 8931 public void hang(final IBinder who, boolean allowRestart) { 8932 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8933 != PackageManager.PERMISSION_GRANTED) { 8934 throw new SecurityException("Requires permission " 8935 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8936 } 8937 8938 final IBinder.DeathRecipient death = new DeathRecipient() { 8939 @Override 8940 public void binderDied() { 8941 synchronized (this) { 8942 notifyAll(); 8943 } 8944 } 8945 }; 8946 8947 try { 8948 who.linkToDeath(death, 0); 8949 } catch (RemoteException e) { 8950 Slog.w(TAG, "hang: given caller IBinder is already dead."); 8951 return; 8952 } 8953 8954 synchronized (this) { 8955 Watchdog.getInstance().setAllowRestart(allowRestart); 8956 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 8957 synchronized (death) { 8958 while (who.isBinderAlive()) { 8959 try { 8960 death.wait(); 8961 } catch (InterruptedException e) { 8962 } 8963 } 8964 } 8965 Watchdog.getInstance().setAllowRestart(true); 8966 } 8967 } 8968 8969 @Override 8970 public void restart() { 8971 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 8972 != PackageManager.PERMISSION_GRANTED) { 8973 throw new SecurityException("Requires permission " 8974 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 8975 } 8976 8977 Log.i(TAG, "Sending shutdown broadcast..."); 8978 8979 BroadcastReceiver br = new BroadcastReceiver() { 8980 @Override public void onReceive(Context context, Intent intent) { 8981 // Now the broadcast is done, finish up the low-level shutdown. 8982 Log.i(TAG, "Shutting down activity manager..."); 8983 shutdown(10000); 8984 Log.i(TAG, "Shutdown complete, restarting!"); 8985 Process.killProcess(Process.myPid()); 8986 System.exit(10); 8987 } 8988 }; 8989 8990 // First send the high-level shut down broadcast. 8991 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 8992 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 8993 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 8994 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 8995 mContext.sendOrderedBroadcastAsUser(intent, 8996 UserHandle.ALL, null, br, mHandler, 0, null, null); 8997 */ 8998 br.onReceive(mContext, intent); 8999 } 9000 9001 private long getLowRamTimeSinceIdle(long now) { 9002 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9003 } 9004 9005 @Override 9006 public void performIdleMaintenance() { 9007 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9008 != PackageManager.PERMISSION_GRANTED) { 9009 throw new SecurityException("Requires permission " 9010 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9011 } 9012 9013 synchronized (this) { 9014 final long now = SystemClock.uptimeMillis(); 9015 final long timeSinceLastIdle = now - mLastIdleTime; 9016 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9017 mLastIdleTime = now; 9018 mLowRamTimeSinceLastIdle = 0; 9019 if (mLowRamStartTime != 0) { 9020 mLowRamStartTime = now; 9021 } 9022 9023 StringBuilder sb = new StringBuilder(128); 9024 sb.append("Idle maintenance over "); 9025 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9026 sb.append(" low RAM for "); 9027 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9028 Slog.i(TAG, sb.toString()); 9029 9030 // If at least 1/3 of our time since the last idle period has been spent 9031 // with RAM low, then we want to kill processes. 9032 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9033 9034 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9035 ProcessRecord proc = mLruProcesses.get(i); 9036 if (proc.notCachedSinceIdle) { 9037 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9038 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9039 if (doKilling && proc.initialIdlePss != 0 9040 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9041 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9042 + " from " + proc.initialIdlePss + ")"); 9043 } 9044 } 9045 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9046 proc.notCachedSinceIdle = true; 9047 proc.initialIdlePss = 0; 9048 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9049 mSleeping, now); 9050 } 9051 } 9052 9053 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9054 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9055 } 9056 } 9057 9058 public final void startRunning(String pkg, String cls, String action, 9059 String data) { 9060 synchronized(this) { 9061 if (mStartRunning) { 9062 return; 9063 } 9064 mStartRunning = true; 9065 mTopComponent = pkg != null && cls != null 9066 ? new ComponentName(pkg, cls) : null; 9067 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9068 mTopData = data; 9069 if (!mSystemReady) { 9070 return; 9071 } 9072 } 9073 9074 systemReady(null); 9075 } 9076 9077 private void retrieveSettings() { 9078 final ContentResolver resolver = mContext.getContentResolver(); 9079 String debugApp = Settings.Global.getString( 9080 resolver, Settings.Global.DEBUG_APP); 9081 boolean waitForDebugger = Settings.Global.getInt( 9082 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9083 boolean alwaysFinishActivities = Settings.Global.getInt( 9084 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9085 boolean forceRtl = Settings.Global.getInt( 9086 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9087 // Transfer any global setting for forcing RTL layout, into a System Property 9088 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9089 9090 Configuration configuration = new Configuration(); 9091 Settings.System.getConfiguration(resolver, configuration); 9092 if (forceRtl) { 9093 // This will take care of setting the correct layout direction flags 9094 configuration.setLayoutDirection(configuration.locale); 9095 } 9096 9097 synchronized (this) { 9098 mDebugApp = mOrigDebugApp = debugApp; 9099 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9100 mAlwaysFinishActivities = alwaysFinishActivities; 9101 // This happens before any activities are started, so we can 9102 // change mConfiguration in-place. 9103 updateConfigurationLocked(configuration, null, false, true); 9104 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9105 } 9106 } 9107 9108 public boolean testIsSystemReady() { 9109 // no need to synchronize(this) just to read & return the value 9110 return mSystemReady; 9111 } 9112 9113 private static File getCalledPreBootReceiversFile() { 9114 File dataDir = Environment.getDataDirectory(); 9115 File systemDir = new File(dataDir, "system"); 9116 File fname = new File(systemDir, "called_pre_boots.dat"); 9117 return fname; 9118 } 9119 9120 static final int LAST_DONE_VERSION = 10000; 9121 9122 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9123 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9124 File file = getCalledPreBootReceiversFile(); 9125 FileInputStream fis = null; 9126 try { 9127 fis = new FileInputStream(file); 9128 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9129 int fvers = dis.readInt(); 9130 if (fvers == LAST_DONE_VERSION) { 9131 String vers = dis.readUTF(); 9132 String codename = dis.readUTF(); 9133 String build = dis.readUTF(); 9134 if (android.os.Build.VERSION.RELEASE.equals(vers) 9135 && android.os.Build.VERSION.CODENAME.equals(codename) 9136 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9137 int num = dis.readInt(); 9138 while (num > 0) { 9139 num--; 9140 String pkg = dis.readUTF(); 9141 String cls = dis.readUTF(); 9142 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9143 } 9144 } 9145 } 9146 } catch (FileNotFoundException e) { 9147 } catch (IOException e) { 9148 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9149 } finally { 9150 if (fis != null) { 9151 try { 9152 fis.close(); 9153 } catch (IOException e) { 9154 } 9155 } 9156 } 9157 return lastDoneReceivers; 9158 } 9159 9160 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9161 File file = getCalledPreBootReceiversFile(); 9162 FileOutputStream fos = null; 9163 DataOutputStream dos = null; 9164 try { 9165 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9166 fos = new FileOutputStream(file); 9167 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9168 dos.writeInt(LAST_DONE_VERSION); 9169 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9170 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9171 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9172 dos.writeInt(list.size()); 9173 for (int i=0; i<list.size(); i++) { 9174 dos.writeUTF(list.get(i).getPackageName()); 9175 dos.writeUTF(list.get(i).getClassName()); 9176 } 9177 } catch (IOException e) { 9178 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9179 file.delete(); 9180 } finally { 9181 FileUtils.sync(fos); 9182 if (dos != null) { 9183 try { 9184 dos.close(); 9185 } catch (IOException e) { 9186 // TODO Auto-generated catch block 9187 e.printStackTrace(); 9188 } 9189 } 9190 } 9191 } 9192 9193 public void systemReady(final Runnable goingCallback) { 9194 synchronized(this) { 9195 if (mSystemReady) { 9196 if (goingCallback != null) goingCallback.run(); 9197 return; 9198 } 9199 9200 // Check to see if there are any update receivers to run. 9201 if (!mDidUpdate) { 9202 if (mWaitingUpdate) { 9203 return; 9204 } 9205 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9206 List<ResolveInfo> ris = null; 9207 try { 9208 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9209 intent, null, 0, 0); 9210 } catch (RemoteException e) { 9211 } 9212 if (ris != null) { 9213 for (int i=ris.size()-1; i>=0; i--) { 9214 if ((ris.get(i).activityInfo.applicationInfo.flags 9215 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9216 ris.remove(i); 9217 } 9218 } 9219 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9220 9221 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9222 9223 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9224 for (int i=0; i<ris.size(); i++) { 9225 ActivityInfo ai = ris.get(i).activityInfo; 9226 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9227 if (lastDoneReceivers.contains(comp)) { 9228 ris.remove(i); 9229 i--; 9230 } 9231 } 9232 9233 final int[] users = getUsersLocked(); 9234 for (int i=0; i<ris.size(); i++) { 9235 ActivityInfo ai = ris.get(i).activityInfo; 9236 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9237 doneReceivers.add(comp); 9238 intent.setComponent(comp); 9239 for (int j=0; j<users.length; j++) { 9240 IIntentReceiver finisher = null; 9241 if (i == ris.size()-1 && j == users.length-1) { 9242 finisher = new IIntentReceiver.Stub() { 9243 public void performReceive(Intent intent, int resultCode, 9244 String data, Bundle extras, boolean ordered, 9245 boolean sticky, int sendingUser) { 9246 // The raw IIntentReceiver interface is called 9247 // with the AM lock held, so redispatch to 9248 // execute our code without the lock. 9249 mHandler.post(new Runnable() { 9250 public void run() { 9251 synchronized (ActivityManagerService.this) { 9252 mDidUpdate = true; 9253 } 9254 writeLastDonePreBootReceivers(doneReceivers); 9255 showBootMessage(mContext.getText( 9256 R.string.android_upgrading_complete), 9257 false); 9258 systemReady(goingCallback); 9259 } 9260 }); 9261 } 9262 }; 9263 } 9264 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9265 + " for user " + users[j]); 9266 broadcastIntentLocked(null, null, intent, null, finisher, 9267 0, null, null, null, AppOpsManager.OP_NONE, 9268 true, false, MY_PID, Process.SYSTEM_UID, 9269 users[j]); 9270 if (finisher != null) { 9271 mWaitingUpdate = true; 9272 } 9273 } 9274 } 9275 } 9276 if (mWaitingUpdate) { 9277 return; 9278 } 9279 mDidUpdate = true; 9280 } 9281 9282 mAppOpsService.systemReady(); 9283 mSystemReady = true; 9284 if (!mStartRunning) { 9285 return; 9286 } 9287 } 9288 9289 ArrayList<ProcessRecord> procsToKill = null; 9290 synchronized(mPidsSelfLocked) { 9291 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9292 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9293 if (!isAllowedWhileBooting(proc.info)){ 9294 if (procsToKill == null) { 9295 procsToKill = new ArrayList<ProcessRecord>(); 9296 } 9297 procsToKill.add(proc); 9298 } 9299 } 9300 } 9301 9302 synchronized(this) { 9303 if (procsToKill != null) { 9304 for (int i=procsToKill.size()-1; i>=0; i--) { 9305 ProcessRecord proc = procsToKill.get(i); 9306 Slog.i(TAG, "Removing system update proc: " + proc); 9307 removeProcessLocked(proc, true, false, "system update done"); 9308 } 9309 } 9310 9311 // Now that we have cleaned up any update processes, we 9312 // are ready to start launching real processes and know that 9313 // we won't trample on them any more. 9314 mProcessesReady = true; 9315 } 9316 9317 Slog.i(TAG, "System now ready"); 9318 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9319 SystemClock.uptimeMillis()); 9320 9321 synchronized(this) { 9322 // Make sure we have no pre-ready processes sitting around. 9323 9324 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 9325 ResolveInfo ri = mContext.getPackageManager() 9326 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9327 STOCK_PM_FLAGS); 9328 CharSequence errorMsg = null; 9329 if (ri != null) { 9330 ActivityInfo ai = ri.activityInfo; 9331 ApplicationInfo app = ai.applicationInfo; 9332 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9333 mTopAction = Intent.ACTION_FACTORY_TEST; 9334 mTopData = null; 9335 mTopComponent = new ComponentName(app.packageName, 9336 ai.name); 9337 } else { 9338 errorMsg = mContext.getResources().getText( 9339 com.android.internal.R.string.factorytest_not_system); 9340 } 9341 } else { 9342 errorMsg = mContext.getResources().getText( 9343 com.android.internal.R.string.factorytest_no_action); 9344 } 9345 if (errorMsg != null) { 9346 mTopAction = null; 9347 mTopData = null; 9348 mTopComponent = null; 9349 Message msg = Message.obtain(); 9350 msg.what = SHOW_FACTORY_ERROR_MSG; 9351 msg.getData().putCharSequence("msg", errorMsg); 9352 mHandler.sendMessage(msg); 9353 } 9354 } 9355 } 9356 9357 retrieveSettings(); 9358 9359 synchronized (this) { 9360 readGrantedUriPermissionsLocked(); 9361 } 9362 9363 if (goingCallback != null) goingCallback.run(); 9364 9365 synchronized (this) { 9366 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 9367 try { 9368 List apps = AppGlobals.getPackageManager(). 9369 getPersistentApplications(STOCK_PM_FLAGS); 9370 if (apps != null) { 9371 int N = apps.size(); 9372 int i; 9373 for (i=0; i<N; i++) { 9374 ApplicationInfo info 9375 = (ApplicationInfo)apps.get(i); 9376 if (info != null && 9377 !info.packageName.equals("android")) { 9378 addAppLocked(info, false); 9379 } 9380 } 9381 } 9382 } catch (RemoteException ex) { 9383 // pm is in same process, this will never happen. 9384 } 9385 } 9386 9387 // Start up initial activity. 9388 mBooting = true; 9389 9390 try { 9391 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9392 Message msg = Message.obtain(); 9393 msg.what = SHOW_UID_ERROR_MSG; 9394 mHandler.sendMessage(msg); 9395 } 9396 } catch (RemoteException e) { 9397 } 9398 9399 long ident = Binder.clearCallingIdentity(); 9400 try { 9401 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9402 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9403 | Intent.FLAG_RECEIVER_FOREGROUND); 9404 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9405 broadcastIntentLocked(null, null, intent, 9406 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9407 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9408 intent = new Intent(Intent.ACTION_USER_STARTING); 9409 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9410 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9411 broadcastIntentLocked(null, null, intent, 9412 null, new IIntentReceiver.Stub() { 9413 @Override 9414 public void performReceive(Intent intent, int resultCode, String data, 9415 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9416 throws RemoteException { 9417 } 9418 }, 0, null, null, 9419 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9420 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9421 } finally { 9422 Binder.restoreCallingIdentity(ident); 9423 } 9424 mStackSupervisor.resumeTopActivitiesLocked(); 9425 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9426 } 9427 } 9428 9429 private boolean makeAppCrashingLocked(ProcessRecord app, 9430 String shortMsg, String longMsg, String stackTrace) { 9431 app.crashing = true; 9432 app.crashingReport = generateProcessError(app, 9433 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9434 startAppProblemLocked(app); 9435 app.stopFreezingAllLocked(); 9436 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9437 } 9438 9439 private void makeAppNotRespondingLocked(ProcessRecord app, 9440 String activity, String shortMsg, String longMsg) { 9441 app.notResponding = true; 9442 app.notRespondingReport = generateProcessError(app, 9443 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9444 activity, shortMsg, longMsg, null); 9445 startAppProblemLocked(app); 9446 app.stopFreezingAllLocked(); 9447 } 9448 9449 /** 9450 * Generate a process error record, suitable for attachment to a ProcessRecord. 9451 * 9452 * @param app The ProcessRecord in which the error occurred. 9453 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9454 * ActivityManager.AppErrorStateInfo 9455 * @param activity The activity associated with the crash, if known. 9456 * @param shortMsg Short message describing the crash. 9457 * @param longMsg Long message describing the crash. 9458 * @param stackTrace Full crash stack trace, may be null. 9459 * 9460 * @return Returns a fully-formed AppErrorStateInfo record. 9461 */ 9462 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9463 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9464 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9465 9466 report.condition = condition; 9467 report.processName = app.processName; 9468 report.pid = app.pid; 9469 report.uid = app.info.uid; 9470 report.tag = activity; 9471 report.shortMsg = shortMsg; 9472 report.longMsg = longMsg; 9473 report.stackTrace = stackTrace; 9474 9475 return report; 9476 } 9477 9478 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9479 synchronized (this) { 9480 app.crashing = false; 9481 app.crashingReport = null; 9482 app.notResponding = false; 9483 app.notRespondingReport = null; 9484 if (app.anrDialog == fromDialog) { 9485 app.anrDialog = null; 9486 } 9487 if (app.waitDialog == fromDialog) { 9488 app.waitDialog = null; 9489 } 9490 if (app.pid > 0 && app.pid != MY_PID) { 9491 handleAppCrashLocked(app, null, null, null); 9492 killUnneededProcessLocked(app, "user request after error"); 9493 } 9494 } 9495 } 9496 9497 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9498 String stackTrace) { 9499 if (mHeadless) { 9500 Log.e(TAG, "handleAppCrashLocked: " + app.processName); 9501 return false; 9502 } 9503 long now = SystemClock.uptimeMillis(); 9504 9505 Long crashTime; 9506 if (!app.isolated) { 9507 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9508 } else { 9509 crashTime = null; 9510 } 9511 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9512 // This process loses! 9513 Slog.w(TAG, "Process " + app.info.processName 9514 + " has crashed too many times: killing!"); 9515 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9516 app.userId, app.info.processName, app.uid); 9517 mStackSupervisor.handleAppCrashLocked(app); 9518 if (!app.persistent) { 9519 // We don't want to start this process again until the user 9520 // explicitly does so... but for persistent process, we really 9521 // need to keep it running. If a persistent process is actually 9522 // repeatedly crashing, then badness for everyone. 9523 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9524 app.info.processName); 9525 if (!app.isolated) { 9526 // XXX We don't have a way to mark isolated processes 9527 // as bad, since they don't have a peristent identity. 9528 mBadProcesses.put(app.info.processName, app.uid, 9529 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9530 mProcessCrashTimes.remove(app.info.processName, app.uid); 9531 } 9532 app.bad = true; 9533 app.removed = true; 9534 // Don't let services in this process be restarted and potentially 9535 // annoy the user repeatedly. Unless it is persistent, since those 9536 // processes run critical code. 9537 removeProcessLocked(app, false, false, "crash"); 9538 mStackSupervisor.resumeTopActivitiesLocked(); 9539 return false; 9540 } 9541 mStackSupervisor.resumeTopActivitiesLocked(); 9542 } else { 9543 mStackSupervisor.finishTopRunningActivityLocked(app); 9544 } 9545 9546 // Bump up the crash count of any services currently running in the proc. 9547 for (int i=app.services.size()-1; i>=0; i--) { 9548 // Any services running in the application need to be placed 9549 // back in the pending list. 9550 ServiceRecord sr = app.services.valueAt(i); 9551 sr.crashCount++; 9552 } 9553 9554 // If the crashing process is what we consider to be the "home process" and it has been 9555 // replaced by a third-party app, clear the package preferred activities from packages 9556 // with a home activity running in the process to prevent a repeatedly crashing app 9557 // from blocking the user to manually clear the list. 9558 final ArrayList<ActivityRecord> activities = app.activities; 9559 if (app == mHomeProcess && activities.size() > 0 9560 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9561 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9562 final ActivityRecord r = activities.get(activityNdx); 9563 if (r.isHomeActivity()) { 9564 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9565 try { 9566 ActivityThread.getPackageManager() 9567 .clearPackagePreferredActivities(r.packageName); 9568 } catch (RemoteException c) { 9569 // pm is in same process, this will never happen. 9570 } 9571 } 9572 } 9573 } 9574 9575 if (!app.isolated) { 9576 // XXX Can't keep track of crash times for isolated processes, 9577 // because they don't have a perisistent identity. 9578 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9579 } 9580 9581 return true; 9582 } 9583 9584 void startAppProblemLocked(ProcessRecord app) { 9585 if (app.userId == mCurrentUserId) { 9586 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9587 mContext, app.info.packageName, app.info.flags); 9588 } else { 9589 // If this app is not running under the current user, then we 9590 // can't give it a report button because that would require 9591 // launching the report UI under a different user. 9592 app.errorReportReceiver = null; 9593 } 9594 skipCurrentReceiverLocked(app); 9595 } 9596 9597 void skipCurrentReceiverLocked(ProcessRecord app) { 9598 for (BroadcastQueue queue : mBroadcastQueues) { 9599 queue.skipCurrentReceiverLocked(app); 9600 } 9601 } 9602 9603 /** 9604 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9605 * The application process will exit immediately after this call returns. 9606 * @param app object of the crashing app, null for the system server 9607 * @param crashInfo describing the exception 9608 */ 9609 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9610 ProcessRecord r = findAppProcess(app, "Crash"); 9611 final String processName = app == null ? "system_server" 9612 : (r == null ? "unknown" : r.processName); 9613 9614 handleApplicationCrashInner("crash", r, processName, crashInfo); 9615 } 9616 9617 /* Native crash reporting uses this inner version because it needs to be somewhat 9618 * decoupled from the AM-managed cleanup lifecycle 9619 */ 9620 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9621 ApplicationErrorReport.CrashInfo crashInfo) { 9622 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9623 UserHandle.getUserId(Binder.getCallingUid()), processName, 9624 r == null ? -1 : r.info.flags, 9625 crashInfo.exceptionClassName, 9626 crashInfo.exceptionMessage, 9627 crashInfo.throwFileName, 9628 crashInfo.throwLineNumber); 9629 9630 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9631 9632 crashApplication(r, crashInfo); 9633 } 9634 9635 public void handleApplicationStrictModeViolation( 9636 IBinder app, 9637 int violationMask, 9638 StrictMode.ViolationInfo info) { 9639 ProcessRecord r = findAppProcess(app, "StrictMode"); 9640 if (r == null) { 9641 return; 9642 } 9643 9644 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9645 Integer stackFingerprint = info.hashCode(); 9646 boolean logIt = true; 9647 synchronized (mAlreadyLoggedViolatedStacks) { 9648 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9649 logIt = false; 9650 // TODO: sub-sample into EventLog for these, with 9651 // the info.durationMillis? Then we'd get 9652 // the relative pain numbers, without logging all 9653 // the stack traces repeatedly. We'd want to do 9654 // likewise in the client code, which also does 9655 // dup suppression, before the Binder call. 9656 } else { 9657 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9658 mAlreadyLoggedViolatedStacks.clear(); 9659 } 9660 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9661 } 9662 } 9663 if (logIt) { 9664 logStrictModeViolationToDropBox(r, info); 9665 } 9666 } 9667 9668 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9669 AppErrorResult result = new AppErrorResult(); 9670 synchronized (this) { 9671 final long origId = Binder.clearCallingIdentity(); 9672 9673 Message msg = Message.obtain(); 9674 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9675 HashMap<String, Object> data = new HashMap<String, Object>(); 9676 data.put("result", result); 9677 data.put("app", r); 9678 data.put("violationMask", violationMask); 9679 data.put("info", info); 9680 msg.obj = data; 9681 mHandler.sendMessage(msg); 9682 9683 Binder.restoreCallingIdentity(origId); 9684 } 9685 int res = result.get(); 9686 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9687 } 9688 } 9689 9690 // Depending on the policy in effect, there could be a bunch of 9691 // these in quick succession so we try to batch these together to 9692 // minimize disk writes, number of dropbox entries, and maximize 9693 // compression, by having more fewer, larger records. 9694 private void logStrictModeViolationToDropBox( 9695 ProcessRecord process, 9696 StrictMode.ViolationInfo info) { 9697 if (info == null) { 9698 return; 9699 } 9700 final boolean isSystemApp = process == null || 9701 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9702 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9703 final String processName = process == null ? "unknown" : process.processName; 9704 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9705 final DropBoxManager dbox = (DropBoxManager) 9706 mContext.getSystemService(Context.DROPBOX_SERVICE); 9707 9708 // Exit early if the dropbox isn't configured to accept this report type. 9709 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9710 9711 boolean bufferWasEmpty; 9712 boolean needsFlush; 9713 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9714 synchronized (sb) { 9715 bufferWasEmpty = sb.length() == 0; 9716 appendDropBoxProcessHeaders(process, processName, sb); 9717 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9718 sb.append("System-App: ").append(isSystemApp).append("\n"); 9719 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9720 if (info.violationNumThisLoop != 0) { 9721 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9722 } 9723 if (info.numAnimationsRunning != 0) { 9724 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9725 } 9726 if (info.broadcastIntentAction != null) { 9727 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9728 } 9729 if (info.durationMillis != -1) { 9730 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9731 } 9732 if (info.numInstances != -1) { 9733 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9734 } 9735 if (info.tags != null) { 9736 for (String tag : info.tags) { 9737 sb.append("Span-Tag: ").append(tag).append("\n"); 9738 } 9739 } 9740 sb.append("\n"); 9741 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9742 sb.append(info.crashInfo.stackTrace); 9743 } 9744 sb.append("\n"); 9745 9746 // Only buffer up to ~64k. Various logging bits truncate 9747 // things at 128k. 9748 needsFlush = (sb.length() > 64 * 1024); 9749 } 9750 9751 // Flush immediately if the buffer's grown too large, or this 9752 // is a non-system app. Non-system apps are isolated with a 9753 // different tag & policy and not batched. 9754 // 9755 // Batching is useful during internal testing with 9756 // StrictMode settings turned up high. Without batching, 9757 // thousands of separate files could be created on boot. 9758 if (!isSystemApp || needsFlush) { 9759 new Thread("Error dump: " + dropboxTag) { 9760 @Override 9761 public void run() { 9762 String report; 9763 synchronized (sb) { 9764 report = sb.toString(); 9765 sb.delete(0, sb.length()); 9766 sb.trimToSize(); 9767 } 9768 if (report.length() != 0) { 9769 dbox.addText(dropboxTag, report); 9770 } 9771 } 9772 }.start(); 9773 return; 9774 } 9775 9776 // System app batching: 9777 if (!bufferWasEmpty) { 9778 // An existing dropbox-writing thread is outstanding, so 9779 // we don't need to start it up. The existing thread will 9780 // catch the buffer appends we just did. 9781 return; 9782 } 9783 9784 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9785 // (After this point, we shouldn't access AMS internal data structures.) 9786 new Thread("Error dump: " + dropboxTag) { 9787 @Override 9788 public void run() { 9789 // 5 second sleep to let stacks arrive and be batched together 9790 try { 9791 Thread.sleep(5000); // 5 seconds 9792 } catch (InterruptedException e) {} 9793 9794 String errorReport; 9795 synchronized (mStrictModeBuffer) { 9796 errorReport = mStrictModeBuffer.toString(); 9797 if (errorReport.length() == 0) { 9798 return; 9799 } 9800 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9801 mStrictModeBuffer.trimToSize(); 9802 } 9803 dbox.addText(dropboxTag, errorReport); 9804 } 9805 }.start(); 9806 } 9807 9808 /** 9809 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9810 * @param app object of the crashing app, null for the system server 9811 * @param tag reported by the caller 9812 * @param crashInfo describing the context of the error 9813 * @return true if the process should exit immediately (WTF is fatal) 9814 */ 9815 public boolean handleApplicationWtf(IBinder app, String tag, 9816 ApplicationErrorReport.CrashInfo crashInfo) { 9817 ProcessRecord r = findAppProcess(app, "WTF"); 9818 final String processName = app == null ? "system_server" 9819 : (r == null ? "unknown" : r.processName); 9820 9821 EventLog.writeEvent(EventLogTags.AM_WTF, 9822 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9823 processName, 9824 r == null ? -1 : r.info.flags, 9825 tag, crashInfo.exceptionMessage); 9826 9827 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9828 9829 if (r != null && r.pid != Process.myPid() && 9830 Settings.Global.getInt(mContext.getContentResolver(), 9831 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9832 crashApplication(r, crashInfo); 9833 return true; 9834 } else { 9835 return false; 9836 } 9837 } 9838 9839 /** 9840 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9841 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9842 */ 9843 private ProcessRecord findAppProcess(IBinder app, String reason) { 9844 if (app == null) { 9845 return null; 9846 } 9847 9848 synchronized (this) { 9849 final int NP = mProcessNames.getMap().size(); 9850 for (int ip=0; ip<NP; ip++) { 9851 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9852 final int NA = apps.size(); 9853 for (int ia=0; ia<NA; ia++) { 9854 ProcessRecord p = apps.valueAt(ia); 9855 if (p.thread != null && p.thread.asBinder() == app) { 9856 return p; 9857 } 9858 } 9859 } 9860 9861 Slog.w(TAG, "Can't find mystery application for " + reason 9862 + " from pid=" + Binder.getCallingPid() 9863 + " uid=" + Binder.getCallingUid() + ": " + app); 9864 return null; 9865 } 9866 } 9867 9868 /** 9869 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9870 * to append various headers to the dropbox log text. 9871 */ 9872 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9873 StringBuilder sb) { 9874 // Watchdog thread ends up invoking this function (with 9875 // a null ProcessRecord) to add the stack file to dropbox. 9876 // Do not acquire a lock on this (am) in such cases, as it 9877 // could cause a potential deadlock, if and when watchdog 9878 // is invoked due to unavailability of lock on am and it 9879 // would prevent watchdog from killing system_server. 9880 if (process == null) { 9881 sb.append("Process: ").append(processName).append("\n"); 9882 return; 9883 } 9884 // Note: ProcessRecord 'process' is guarded by the service 9885 // instance. (notably process.pkgList, which could otherwise change 9886 // concurrently during execution of this method) 9887 synchronized (this) { 9888 sb.append("Process: ").append(processName).append("\n"); 9889 int flags = process.info.flags; 9890 IPackageManager pm = AppGlobals.getPackageManager(); 9891 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9892 for (int ip=0; ip<process.pkgList.size(); ip++) { 9893 String pkg = process.pkgList.keyAt(ip); 9894 sb.append("Package: ").append(pkg); 9895 try { 9896 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 9897 if (pi != null) { 9898 sb.append(" v").append(pi.versionCode); 9899 if (pi.versionName != null) { 9900 sb.append(" (").append(pi.versionName).append(")"); 9901 } 9902 } 9903 } catch (RemoteException e) { 9904 Slog.e(TAG, "Error getting package info: " + pkg, e); 9905 } 9906 sb.append("\n"); 9907 } 9908 } 9909 } 9910 9911 private static String processClass(ProcessRecord process) { 9912 if (process == null || process.pid == MY_PID) { 9913 return "system_server"; 9914 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9915 return "system_app"; 9916 } else { 9917 return "data_app"; 9918 } 9919 } 9920 9921 /** 9922 * Write a description of an error (crash, WTF, ANR) to the drop box. 9923 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9924 * @param process which caused the error, null means the system server 9925 * @param activity which triggered the error, null if unknown 9926 * @param parent activity related to the error, null if unknown 9927 * @param subject line related to the error, null if absent 9928 * @param report in long form describing the error, null if absent 9929 * @param logFile to include in the report, null if none 9930 * @param crashInfo giving an application stack trace, null if absent 9931 */ 9932 public void addErrorToDropBox(String eventType, 9933 ProcessRecord process, String processName, ActivityRecord activity, 9934 ActivityRecord parent, String subject, 9935 final String report, final File logFile, 9936 final ApplicationErrorReport.CrashInfo crashInfo) { 9937 // NOTE -- this must never acquire the ActivityManagerService lock, 9938 // otherwise the watchdog may be prevented from resetting the system. 9939 9940 final String dropboxTag = processClass(process) + "_" + eventType; 9941 final DropBoxManager dbox = (DropBoxManager) 9942 mContext.getSystemService(Context.DROPBOX_SERVICE); 9943 9944 // Exit early if the dropbox isn't configured to accept this report type. 9945 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9946 9947 final StringBuilder sb = new StringBuilder(1024); 9948 appendDropBoxProcessHeaders(process, processName, sb); 9949 if (activity != null) { 9950 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9951 } 9952 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9953 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9954 } 9955 if (parent != null && parent != activity) { 9956 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9957 } 9958 if (subject != null) { 9959 sb.append("Subject: ").append(subject).append("\n"); 9960 } 9961 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9962 if (Debug.isDebuggerConnected()) { 9963 sb.append("Debugger: Connected\n"); 9964 } 9965 sb.append("\n"); 9966 9967 // Do the rest in a worker thread to avoid blocking the caller on I/O 9968 // (After this point, we shouldn't access AMS internal data structures.) 9969 Thread worker = new Thread("Error dump: " + dropboxTag) { 9970 @Override 9971 public void run() { 9972 if (report != null) { 9973 sb.append(report); 9974 } 9975 if (logFile != null) { 9976 try { 9977 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 9978 "\n\n[[TRUNCATED]]")); 9979 } catch (IOException e) { 9980 Slog.e(TAG, "Error reading " + logFile, e); 9981 } 9982 } 9983 if (crashInfo != null && crashInfo.stackTrace != null) { 9984 sb.append(crashInfo.stackTrace); 9985 } 9986 9987 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 9988 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 9989 if (lines > 0) { 9990 sb.append("\n"); 9991 9992 // Merge several logcat streams, and take the last N lines 9993 InputStreamReader input = null; 9994 try { 9995 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9996 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9997 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9998 9999 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10000 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10001 input = new InputStreamReader(logcat.getInputStream()); 10002 10003 int num; 10004 char[] buf = new char[8192]; 10005 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10006 } catch (IOException e) { 10007 Slog.e(TAG, "Error running logcat", e); 10008 } finally { 10009 if (input != null) try { input.close(); } catch (IOException e) {} 10010 } 10011 } 10012 10013 dbox.addText(dropboxTag, sb.toString()); 10014 } 10015 }; 10016 10017 if (process == null) { 10018 // If process is null, we are being called from some internal code 10019 // and may be about to die -- run this synchronously. 10020 worker.run(); 10021 } else { 10022 worker.start(); 10023 } 10024 } 10025 10026 /** 10027 * Bring up the "unexpected error" dialog box for a crashing app. 10028 * Deal with edge cases (intercepts from instrumented applications, 10029 * ActivityController, error intent receivers, that sort of thing). 10030 * @param r the application crashing 10031 * @param crashInfo describing the failure 10032 */ 10033 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10034 long timeMillis = System.currentTimeMillis(); 10035 String shortMsg = crashInfo.exceptionClassName; 10036 String longMsg = crashInfo.exceptionMessage; 10037 String stackTrace = crashInfo.stackTrace; 10038 if (shortMsg != null && longMsg != null) { 10039 longMsg = shortMsg + ": " + longMsg; 10040 } else if (shortMsg != null) { 10041 longMsg = shortMsg; 10042 } 10043 10044 AppErrorResult result = new AppErrorResult(); 10045 synchronized (this) { 10046 if (mController != null) { 10047 try { 10048 String name = r != null ? r.processName : null; 10049 int pid = r != null ? r.pid : Binder.getCallingPid(); 10050 if (!mController.appCrashed(name, pid, 10051 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10052 Slog.w(TAG, "Force-killing crashed app " + name 10053 + " at watcher's request"); 10054 Process.killProcess(pid); 10055 return; 10056 } 10057 } catch (RemoteException e) { 10058 mController = null; 10059 Watchdog.getInstance().setActivityController(null); 10060 } 10061 } 10062 10063 final long origId = Binder.clearCallingIdentity(); 10064 10065 // If this process is running instrumentation, finish it. 10066 if (r != null && r.instrumentationClass != null) { 10067 Slog.w(TAG, "Error in app " + r.processName 10068 + " running instrumentation " + r.instrumentationClass + ":"); 10069 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10070 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10071 Bundle info = new Bundle(); 10072 info.putString("shortMsg", shortMsg); 10073 info.putString("longMsg", longMsg); 10074 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10075 Binder.restoreCallingIdentity(origId); 10076 return; 10077 } 10078 10079 // If we can't identify the process or it's already exceeded its crash quota, 10080 // quit right away without showing a crash dialog. 10081 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10082 Binder.restoreCallingIdentity(origId); 10083 return; 10084 } 10085 10086 Message msg = Message.obtain(); 10087 msg.what = SHOW_ERROR_MSG; 10088 HashMap data = new HashMap(); 10089 data.put("result", result); 10090 data.put("app", r); 10091 msg.obj = data; 10092 mHandler.sendMessage(msg); 10093 10094 Binder.restoreCallingIdentity(origId); 10095 } 10096 10097 int res = result.get(); 10098 10099 Intent appErrorIntent = null; 10100 synchronized (this) { 10101 if (r != null && !r.isolated) { 10102 // XXX Can't keep track of crash time for isolated processes, 10103 // since they don't have a persistent identity. 10104 mProcessCrashTimes.put(r.info.processName, r.uid, 10105 SystemClock.uptimeMillis()); 10106 } 10107 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10108 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10109 } 10110 } 10111 10112 if (appErrorIntent != null) { 10113 try { 10114 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10115 } catch (ActivityNotFoundException e) { 10116 Slog.w(TAG, "bug report receiver dissappeared", e); 10117 } 10118 } 10119 } 10120 10121 Intent createAppErrorIntentLocked(ProcessRecord r, 10122 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10123 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10124 if (report == null) { 10125 return null; 10126 } 10127 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10128 result.setComponent(r.errorReportReceiver); 10129 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10130 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10131 return result; 10132 } 10133 10134 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10135 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10136 if (r.errorReportReceiver == null) { 10137 return null; 10138 } 10139 10140 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10141 return null; 10142 } 10143 10144 ApplicationErrorReport report = new ApplicationErrorReport(); 10145 report.packageName = r.info.packageName; 10146 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10147 report.processName = r.processName; 10148 report.time = timeMillis; 10149 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10150 10151 if (r.crashing || r.forceCrashReport) { 10152 report.type = ApplicationErrorReport.TYPE_CRASH; 10153 report.crashInfo = crashInfo; 10154 } else if (r.notResponding) { 10155 report.type = ApplicationErrorReport.TYPE_ANR; 10156 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10157 10158 report.anrInfo.activity = r.notRespondingReport.tag; 10159 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10160 report.anrInfo.info = r.notRespondingReport.longMsg; 10161 } 10162 10163 return report; 10164 } 10165 10166 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10167 enforceNotIsolatedCaller("getProcessesInErrorState"); 10168 // assume our apps are happy - lazy create the list 10169 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10170 10171 final boolean allUsers = ActivityManager.checkUidPermission( 10172 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10173 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10174 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10175 10176 synchronized (this) { 10177 10178 // iterate across all processes 10179 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10180 ProcessRecord app = mLruProcesses.get(i); 10181 if (!allUsers && app.userId != userId) { 10182 continue; 10183 } 10184 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10185 // This one's in trouble, so we'll generate a report for it 10186 // crashes are higher priority (in case there's a crash *and* an anr) 10187 ActivityManager.ProcessErrorStateInfo report = null; 10188 if (app.crashing) { 10189 report = app.crashingReport; 10190 } else if (app.notResponding) { 10191 report = app.notRespondingReport; 10192 } 10193 10194 if (report != null) { 10195 if (errList == null) { 10196 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10197 } 10198 errList.add(report); 10199 } else { 10200 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10201 " crashing = " + app.crashing + 10202 " notResponding = " + app.notResponding); 10203 } 10204 } 10205 } 10206 } 10207 10208 return errList; 10209 } 10210 10211 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10212 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10213 if (currApp != null) { 10214 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10215 } 10216 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10217 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10218 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10219 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10220 if (currApp != null) { 10221 currApp.lru = 0; 10222 } 10223 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10224 } else if (adj >= ProcessList.SERVICE_ADJ) { 10225 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10226 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10227 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10228 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10229 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10230 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10231 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10232 } else { 10233 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10234 } 10235 } 10236 10237 private void fillInProcMemInfo(ProcessRecord app, 10238 ActivityManager.RunningAppProcessInfo outInfo) { 10239 outInfo.pid = app.pid; 10240 outInfo.uid = app.info.uid; 10241 if (mHeavyWeightProcess == app) { 10242 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10243 } 10244 if (app.persistent) { 10245 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10246 } 10247 if (app.activities.size() > 0) { 10248 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10249 } 10250 outInfo.lastTrimLevel = app.trimMemoryLevel; 10251 int adj = app.curAdj; 10252 outInfo.importance = oomAdjToImportance(adj, outInfo); 10253 outInfo.importanceReasonCode = app.adjTypeCode; 10254 } 10255 10256 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10257 enforceNotIsolatedCaller("getRunningAppProcesses"); 10258 // Lazy instantiation of list 10259 List<ActivityManager.RunningAppProcessInfo> runList = null; 10260 final boolean allUsers = ActivityManager.checkUidPermission( 10261 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10262 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10263 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10264 synchronized (this) { 10265 // Iterate across all processes 10266 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10267 ProcessRecord app = mLruProcesses.get(i); 10268 if (!allUsers && app.userId != userId) { 10269 continue; 10270 } 10271 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10272 // Generate process state info for running application 10273 ActivityManager.RunningAppProcessInfo currApp = 10274 new ActivityManager.RunningAppProcessInfo(app.processName, 10275 app.pid, app.getPackageList()); 10276 fillInProcMemInfo(app, currApp); 10277 if (app.adjSource instanceof ProcessRecord) { 10278 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10279 currApp.importanceReasonImportance = oomAdjToImportance( 10280 app.adjSourceOom, null); 10281 } else if (app.adjSource instanceof ActivityRecord) { 10282 ActivityRecord r = (ActivityRecord)app.adjSource; 10283 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10284 } 10285 if (app.adjTarget instanceof ComponentName) { 10286 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10287 } 10288 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10289 // + " lru=" + currApp.lru); 10290 if (runList == null) { 10291 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10292 } 10293 runList.add(currApp); 10294 } 10295 } 10296 } 10297 return runList; 10298 } 10299 10300 public List<ApplicationInfo> getRunningExternalApplications() { 10301 enforceNotIsolatedCaller("getRunningExternalApplications"); 10302 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10303 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10304 if (runningApps != null && runningApps.size() > 0) { 10305 Set<String> extList = new HashSet<String>(); 10306 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10307 if (app.pkgList != null) { 10308 for (String pkg : app.pkgList) { 10309 extList.add(pkg); 10310 } 10311 } 10312 } 10313 IPackageManager pm = AppGlobals.getPackageManager(); 10314 for (String pkg : extList) { 10315 try { 10316 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10317 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10318 retList.add(info); 10319 } 10320 } catch (RemoteException e) { 10321 } 10322 } 10323 } 10324 return retList; 10325 } 10326 10327 @Override 10328 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10329 enforceNotIsolatedCaller("getMyMemoryState"); 10330 synchronized (this) { 10331 ProcessRecord proc; 10332 synchronized (mPidsSelfLocked) { 10333 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10334 } 10335 fillInProcMemInfo(proc, outInfo); 10336 } 10337 } 10338 10339 @Override 10340 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10341 if (checkCallingPermission(android.Manifest.permission.DUMP) 10342 != PackageManager.PERMISSION_GRANTED) { 10343 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10344 + Binder.getCallingPid() 10345 + ", uid=" + Binder.getCallingUid() 10346 + " without permission " 10347 + android.Manifest.permission.DUMP); 10348 return; 10349 } 10350 10351 boolean dumpAll = false; 10352 boolean dumpClient = false; 10353 String dumpPackage = null; 10354 10355 int opti = 0; 10356 while (opti < args.length) { 10357 String opt = args[opti]; 10358 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10359 break; 10360 } 10361 opti++; 10362 if ("-a".equals(opt)) { 10363 dumpAll = true; 10364 } else if ("-c".equals(opt)) { 10365 dumpClient = true; 10366 } else if ("-h".equals(opt)) { 10367 pw.println("Activity manager dump options:"); 10368 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10369 pw.println(" cmd may be one of:"); 10370 pw.println(" a[ctivities]: activity stack state"); 10371 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10372 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10373 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10374 pw.println(" o[om]: out of memory management"); 10375 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10376 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10377 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10378 pw.println(" service [COMP_SPEC]: service client-side state"); 10379 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10380 pw.println(" all: dump all activities"); 10381 pw.println(" top: dump the top activity"); 10382 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10383 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10384 pw.println(" a partial substring in a component name, a"); 10385 pw.println(" hex object identifier."); 10386 pw.println(" -a: include all available server state."); 10387 pw.println(" -c: include client state."); 10388 return; 10389 } else { 10390 pw.println("Unknown argument: " + opt + "; use -h for help"); 10391 } 10392 } 10393 10394 long origId = Binder.clearCallingIdentity(); 10395 boolean more = false; 10396 // Is the caller requesting to dump a particular piece of data? 10397 if (opti < args.length) { 10398 String cmd = args[opti]; 10399 opti++; 10400 if ("activities".equals(cmd) || "a".equals(cmd)) { 10401 synchronized (this) { 10402 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10403 } 10404 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10405 String[] newArgs; 10406 String name; 10407 if (opti >= args.length) { 10408 name = null; 10409 newArgs = EMPTY_STRING_ARRAY; 10410 } else { 10411 name = args[opti]; 10412 opti++; 10413 newArgs = new String[args.length - opti]; 10414 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10415 args.length - opti); 10416 } 10417 synchronized (this) { 10418 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10419 } 10420 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10421 String[] newArgs; 10422 String name; 10423 if (opti >= args.length) { 10424 name = null; 10425 newArgs = EMPTY_STRING_ARRAY; 10426 } else { 10427 name = args[opti]; 10428 opti++; 10429 newArgs = new String[args.length - opti]; 10430 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10431 args.length - opti); 10432 } 10433 synchronized (this) { 10434 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10435 } 10436 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10437 String[] newArgs; 10438 String name; 10439 if (opti >= args.length) { 10440 name = null; 10441 newArgs = EMPTY_STRING_ARRAY; 10442 } else { 10443 name = args[opti]; 10444 opti++; 10445 newArgs = new String[args.length - opti]; 10446 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10447 args.length - opti); 10448 } 10449 synchronized (this) { 10450 dumpProcessesLocked(fd, pw, args, opti, true, name); 10451 } 10452 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10453 synchronized (this) { 10454 dumpOomLocked(fd, pw, args, opti, true); 10455 } 10456 } else if ("provider".equals(cmd)) { 10457 String[] newArgs; 10458 String name; 10459 if (opti >= args.length) { 10460 name = null; 10461 newArgs = EMPTY_STRING_ARRAY; 10462 } else { 10463 name = args[opti]; 10464 opti++; 10465 newArgs = new String[args.length - opti]; 10466 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10467 } 10468 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10469 pw.println("No providers match: " + name); 10470 pw.println("Use -h for help."); 10471 } 10472 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10473 synchronized (this) { 10474 dumpProvidersLocked(fd, pw, args, opti, true, null); 10475 } 10476 } else if ("service".equals(cmd)) { 10477 String[] newArgs; 10478 String name; 10479 if (opti >= args.length) { 10480 name = null; 10481 newArgs = EMPTY_STRING_ARRAY; 10482 } else { 10483 name = args[opti]; 10484 opti++; 10485 newArgs = new String[args.length - opti]; 10486 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10487 args.length - opti); 10488 } 10489 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10490 pw.println("No services match: " + name); 10491 pw.println("Use -h for help."); 10492 } 10493 } else if ("package".equals(cmd)) { 10494 String[] newArgs; 10495 if (opti >= args.length) { 10496 pw.println("package: no package name specified"); 10497 pw.println("Use -h for help."); 10498 } else { 10499 dumpPackage = args[opti]; 10500 opti++; 10501 newArgs = new String[args.length - opti]; 10502 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10503 args.length - opti); 10504 args = newArgs; 10505 opti = 0; 10506 more = true; 10507 } 10508 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10509 synchronized (this) { 10510 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10511 } 10512 } else { 10513 // Dumping a single activity? 10514 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10515 pw.println("Bad activity command, or no activities match: " + cmd); 10516 pw.println("Use -h for help."); 10517 } 10518 } 10519 if (!more) { 10520 Binder.restoreCallingIdentity(origId); 10521 return; 10522 } 10523 } 10524 10525 // No piece of data specified, dump everything. 10526 synchronized (this) { 10527 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10528 pw.println(); 10529 if (dumpAll) { 10530 pw.println("-------------------------------------------------------------------------------"); 10531 } 10532 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10533 pw.println(); 10534 if (dumpAll) { 10535 pw.println("-------------------------------------------------------------------------------"); 10536 } 10537 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10538 pw.println(); 10539 if (dumpAll) { 10540 pw.println("-------------------------------------------------------------------------------"); 10541 } 10542 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10543 pw.println(); 10544 if (dumpAll) { 10545 pw.println("-------------------------------------------------------------------------------"); 10546 } 10547 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10548 pw.println(); 10549 if (dumpAll) { 10550 pw.println("-------------------------------------------------------------------------------"); 10551 } 10552 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10553 } 10554 Binder.restoreCallingIdentity(origId); 10555 } 10556 10557 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10558 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10559 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10560 10561 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10562 dumpPackage); 10563 boolean needSep = printedAnything; 10564 10565 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10566 dumpPackage, needSep, " mFocusedActivity: "); 10567 if (printed) { 10568 printedAnything = true; 10569 needSep = false; 10570 } 10571 10572 if (dumpPackage == null) { 10573 if (needSep) { 10574 pw.println(); 10575 } 10576 needSep = true; 10577 printedAnything = true; 10578 mStackSupervisor.dump(pw, " "); 10579 } 10580 10581 if (mRecentTasks.size() > 0) { 10582 boolean printedHeader = false; 10583 10584 final int N = mRecentTasks.size(); 10585 for (int i=0; i<N; i++) { 10586 TaskRecord tr = mRecentTasks.get(i); 10587 if (dumpPackage != null) { 10588 if (tr.realActivity == null || 10589 !dumpPackage.equals(tr.realActivity)) { 10590 continue; 10591 } 10592 } 10593 if (!printedHeader) { 10594 if (needSep) { 10595 pw.println(); 10596 } 10597 pw.println(" Recent tasks:"); 10598 printedHeader = true; 10599 printedAnything = true; 10600 } 10601 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10602 pw.println(tr); 10603 if (dumpAll) { 10604 mRecentTasks.get(i).dump(pw, " "); 10605 } 10606 } 10607 } 10608 10609 if (!printedAnything) { 10610 pw.println(" (nothing)"); 10611 } 10612 } 10613 10614 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10615 int opti, boolean dumpAll, String dumpPackage) { 10616 boolean needSep = false; 10617 boolean printedAnything = false; 10618 int numPers = 0; 10619 10620 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10621 10622 if (dumpAll) { 10623 final int NP = mProcessNames.getMap().size(); 10624 for (int ip=0; ip<NP; ip++) { 10625 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10626 final int NA = procs.size(); 10627 for (int ia=0; ia<NA; ia++) { 10628 ProcessRecord r = procs.valueAt(ia); 10629 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10630 continue; 10631 } 10632 if (!needSep) { 10633 pw.println(" All known processes:"); 10634 needSep = true; 10635 printedAnything = true; 10636 } 10637 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10638 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10639 pw.print(" "); pw.println(r); 10640 r.dump(pw, " "); 10641 if (r.persistent) { 10642 numPers++; 10643 } 10644 } 10645 } 10646 } 10647 10648 if (mIsolatedProcesses.size() > 0) { 10649 boolean printed = false; 10650 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10651 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10652 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10653 continue; 10654 } 10655 if (!printed) { 10656 if (needSep) { 10657 pw.println(); 10658 } 10659 pw.println(" Isolated process list (sorted by uid):"); 10660 printedAnything = true; 10661 printed = true; 10662 needSep = true; 10663 } 10664 pw.println(String.format("%sIsolated #%2d: %s", 10665 " ", i, r.toString())); 10666 } 10667 } 10668 10669 if (mLruProcesses.size() > 0) { 10670 if (needSep) { 10671 pw.println(); 10672 } 10673 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10674 pw.print(" total, non-act at "); 10675 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10676 pw.print(", non-svc at "); 10677 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10678 pw.println("):"); 10679 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10680 needSep = true; 10681 printedAnything = true; 10682 } 10683 10684 if (dumpAll || dumpPackage != null) { 10685 synchronized (mPidsSelfLocked) { 10686 boolean printed = false; 10687 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10688 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10689 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10690 continue; 10691 } 10692 if (!printed) { 10693 if (needSep) pw.println(); 10694 needSep = true; 10695 pw.println(" PID mappings:"); 10696 printed = true; 10697 printedAnything = true; 10698 } 10699 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10700 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10701 } 10702 } 10703 } 10704 10705 if (mForegroundProcesses.size() > 0) { 10706 synchronized (mPidsSelfLocked) { 10707 boolean printed = false; 10708 for (int i=0; i<mForegroundProcesses.size(); i++) { 10709 ProcessRecord r = mPidsSelfLocked.get( 10710 mForegroundProcesses.valueAt(i).pid); 10711 if (dumpPackage != null && (r == null 10712 || !r.pkgList.containsKey(dumpPackage))) { 10713 continue; 10714 } 10715 if (!printed) { 10716 if (needSep) pw.println(); 10717 needSep = true; 10718 pw.println(" Foreground Processes:"); 10719 printed = true; 10720 printedAnything = true; 10721 } 10722 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10723 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10724 } 10725 } 10726 } 10727 10728 if (mPersistentStartingProcesses.size() > 0) { 10729 if (needSep) pw.println(); 10730 needSep = true; 10731 printedAnything = true; 10732 pw.println(" Persisent processes that are starting:"); 10733 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10734 "Starting Norm", "Restarting PERS", dumpPackage); 10735 } 10736 10737 if (mRemovedProcesses.size() > 0) { 10738 if (needSep) pw.println(); 10739 needSep = true; 10740 printedAnything = true; 10741 pw.println(" Processes that are being removed:"); 10742 dumpProcessList(pw, this, mRemovedProcesses, " ", 10743 "Removed Norm", "Removed PERS", dumpPackage); 10744 } 10745 10746 if (mProcessesOnHold.size() > 0) { 10747 if (needSep) pw.println(); 10748 needSep = true; 10749 printedAnything = true; 10750 pw.println(" Processes that are on old until the system is ready:"); 10751 dumpProcessList(pw, this, mProcessesOnHold, " ", 10752 "OnHold Norm", "OnHold PERS", dumpPackage); 10753 } 10754 10755 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10756 10757 if (mProcessCrashTimes.getMap().size() > 0) { 10758 boolean printed = false; 10759 long now = SystemClock.uptimeMillis(); 10760 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10761 final int NP = pmap.size(); 10762 for (int ip=0; ip<NP; ip++) { 10763 String pname = pmap.keyAt(ip); 10764 SparseArray<Long> uids = pmap.valueAt(ip); 10765 final int N = uids.size(); 10766 for (int i=0; i<N; i++) { 10767 int puid = uids.keyAt(i); 10768 ProcessRecord r = mProcessNames.get(pname, puid); 10769 if (dumpPackage != null && (r == null 10770 || !r.pkgList.containsKey(dumpPackage))) { 10771 continue; 10772 } 10773 if (!printed) { 10774 if (needSep) pw.println(); 10775 needSep = true; 10776 pw.println(" Time since processes crashed:"); 10777 printed = true; 10778 printedAnything = true; 10779 } 10780 pw.print(" Process "); pw.print(pname); 10781 pw.print(" uid "); pw.print(puid); 10782 pw.print(": last crashed "); 10783 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10784 pw.println(" ago"); 10785 } 10786 } 10787 } 10788 10789 if (mBadProcesses.getMap().size() > 0) { 10790 boolean printed = false; 10791 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10792 final int NP = pmap.size(); 10793 for (int ip=0; ip<NP; ip++) { 10794 String pname = pmap.keyAt(ip); 10795 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10796 final int N = uids.size(); 10797 for (int i=0; i<N; i++) { 10798 int puid = uids.keyAt(i); 10799 ProcessRecord r = mProcessNames.get(pname, puid); 10800 if (dumpPackage != null && (r == null 10801 || !r.pkgList.containsKey(dumpPackage))) { 10802 continue; 10803 } 10804 if (!printed) { 10805 if (needSep) pw.println(); 10806 needSep = true; 10807 pw.println(" Bad processes:"); 10808 printedAnything = true; 10809 } 10810 BadProcessInfo info = uids.valueAt(i); 10811 pw.print(" Bad process "); pw.print(pname); 10812 pw.print(" uid "); pw.print(puid); 10813 pw.print(": crashed at time "); pw.println(info.time); 10814 if (info.shortMsg != null) { 10815 pw.print(" Short msg: "); pw.println(info.shortMsg); 10816 } 10817 if (info.longMsg != null) { 10818 pw.print(" Long msg: "); pw.println(info.longMsg); 10819 } 10820 if (info.stack != null) { 10821 pw.println(" Stack:"); 10822 int lastPos = 0; 10823 for (int pos=0; pos<info.stack.length(); pos++) { 10824 if (info.stack.charAt(pos) == '\n') { 10825 pw.print(" "); 10826 pw.write(info.stack, lastPos, pos-lastPos); 10827 pw.println(); 10828 lastPos = pos+1; 10829 } 10830 } 10831 if (lastPos < info.stack.length()) { 10832 pw.print(" "); 10833 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10834 pw.println(); 10835 } 10836 } 10837 } 10838 } 10839 } 10840 10841 if (dumpPackage == null) { 10842 pw.println(); 10843 needSep = false; 10844 pw.println(" mStartedUsers:"); 10845 for (int i=0; i<mStartedUsers.size(); i++) { 10846 UserStartedState uss = mStartedUsers.valueAt(i); 10847 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10848 pw.print(": "); uss.dump("", pw); 10849 } 10850 pw.print(" mStartedUserArray: ["); 10851 for (int i=0; i<mStartedUserArray.length; i++) { 10852 if (i > 0) pw.print(", "); 10853 pw.print(mStartedUserArray[i]); 10854 } 10855 pw.println("]"); 10856 pw.print(" mUserLru: ["); 10857 for (int i=0; i<mUserLru.size(); i++) { 10858 if (i > 0) pw.print(", "); 10859 pw.print(mUserLru.get(i)); 10860 } 10861 pw.println("]"); 10862 if (dumpAll) { 10863 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10864 } 10865 } 10866 if (mHomeProcess != null && (dumpPackage == null 10867 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10868 if (needSep) { 10869 pw.println(); 10870 needSep = false; 10871 } 10872 pw.println(" mHomeProcess: " + mHomeProcess); 10873 } 10874 if (mPreviousProcess != null && (dumpPackage == null 10875 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10876 if (needSep) { 10877 pw.println(); 10878 needSep = false; 10879 } 10880 pw.println(" mPreviousProcess: " + mPreviousProcess); 10881 } 10882 if (dumpAll) { 10883 StringBuilder sb = new StringBuilder(128); 10884 sb.append(" mPreviousProcessVisibleTime: "); 10885 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10886 pw.println(sb); 10887 } 10888 if (mHeavyWeightProcess != null && (dumpPackage == null 10889 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 10890 if (needSep) { 10891 pw.println(); 10892 needSep = false; 10893 } 10894 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 10895 } 10896 if (dumpPackage == null) { 10897 pw.println(" mConfiguration: " + mConfiguration); 10898 } 10899 if (dumpAll) { 10900 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 10901 if (mCompatModePackages.getPackages().size() > 0) { 10902 boolean printed = false; 10903 for (Map.Entry<String, Integer> entry 10904 : mCompatModePackages.getPackages().entrySet()) { 10905 String pkg = entry.getKey(); 10906 int mode = entry.getValue(); 10907 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 10908 continue; 10909 } 10910 if (!printed) { 10911 pw.println(" mScreenCompatPackages:"); 10912 printed = true; 10913 } 10914 pw.print(" "); pw.print(pkg); pw.print(": "); 10915 pw.print(mode); pw.println(); 10916 } 10917 } 10918 } 10919 if (dumpPackage == null) { 10920 if (mSleeping || mWentToSleep || mLockScreenShown) { 10921 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 10922 + " mLockScreenShown " + mLockScreenShown); 10923 } 10924 if (mShuttingDown) { 10925 pw.println(" mShuttingDown=" + mShuttingDown); 10926 } 10927 } 10928 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 10929 || mOrigWaitForDebugger) { 10930 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 10931 || dumpPackage.equals(mOrigDebugApp)) { 10932 if (needSep) { 10933 pw.println(); 10934 needSep = false; 10935 } 10936 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 10937 + " mDebugTransient=" + mDebugTransient 10938 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 10939 } 10940 } 10941 if (mOpenGlTraceApp != null) { 10942 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 10943 if (needSep) { 10944 pw.println(); 10945 needSep = false; 10946 } 10947 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 10948 } 10949 } 10950 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 10951 || mProfileFd != null) { 10952 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 10953 if (needSep) { 10954 pw.println(); 10955 needSep = false; 10956 } 10957 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 10958 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 10959 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 10960 + mAutoStopProfiler); 10961 } 10962 } 10963 if (dumpPackage == null) { 10964 if (mAlwaysFinishActivities || mController != null) { 10965 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 10966 + " mController=" + mController); 10967 } 10968 if (dumpAll) { 10969 pw.println(" Total persistent processes: " + numPers); 10970 pw.println(" mStartRunning=" + mStartRunning 10971 + " mProcessesReady=" + mProcessesReady 10972 + " mSystemReady=" + mSystemReady); 10973 pw.println(" mBooting=" + mBooting 10974 + " mBooted=" + mBooted 10975 + " mFactoryTest=" + mFactoryTest); 10976 pw.print(" mLastPowerCheckRealtime="); 10977 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 10978 pw.println(""); 10979 pw.print(" mLastPowerCheckUptime="); 10980 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 10981 pw.println(""); 10982 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 10983 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 10984 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 10985 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 10986 + " (" + mLruProcesses.size() + " total)" 10987 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 10988 + " mNumServiceProcs=" + mNumServiceProcs 10989 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 10990 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 10991 + " mLastMemoryLevel" + mLastMemoryLevel 10992 + " mLastNumProcesses" + mLastNumProcesses); 10993 long now = SystemClock.uptimeMillis(); 10994 pw.print(" mLastIdleTime="); 10995 TimeUtils.formatDuration(now, mLastIdleTime, pw); 10996 pw.print(" mLowRamSinceLastIdle="); 10997 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 10998 pw.println(); 10999 } 11000 } 11001 11002 if (!printedAnything) { 11003 pw.println(" (nothing)"); 11004 } 11005 } 11006 11007 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11008 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11009 if (mProcessesToGc.size() > 0) { 11010 boolean printed = false; 11011 long now = SystemClock.uptimeMillis(); 11012 for (int i=0; i<mProcessesToGc.size(); i++) { 11013 ProcessRecord proc = mProcessesToGc.get(i); 11014 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11015 continue; 11016 } 11017 if (!printed) { 11018 if (needSep) pw.println(); 11019 needSep = true; 11020 pw.println(" Processes that are waiting to GC:"); 11021 printed = true; 11022 } 11023 pw.print(" Process "); pw.println(proc); 11024 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11025 pw.print(", last gced="); 11026 pw.print(now-proc.lastRequestedGc); 11027 pw.print(" ms ago, last lowMem="); 11028 pw.print(now-proc.lastLowMemory); 11029 pw.println(" ms ago"); 11030 11031 } 11032 } 11033 return needSep; 11034 } 11035 11036 void printOomLevel(PrintWriter pw, String name, int adj) { 11037 pw.print(" "); 11038 if (adj >= 0) { 11039 pw.print(' '); 11040 if (adj < 10) pw.print(' '); 11041 } else { 11042 if (adj > -10) pw.print(' '); 11043 } 11044 pw.print(adj); 11045 pw.print(": "); 11046 pw.print(name); 11047 pw.print(" ("); 11048 pw.print(mProcessList.getMemLevel(adj)/1024); 11049 pw.println(" kB)"); 11050 } 11051 11052 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11053 int opti, boolean dumpAll) { 11054 boolean needSep = false; 11055 11056 if (mLruProcesses.size() > 0) { 11057 if (needSep) pw.println(); 11058 needSep = true; 11059 pw.println(" OOM levels:"); 11060 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11061 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11062 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11063 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11064 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11065 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11066 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11067 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11068 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11069 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11070 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11071 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11072 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11073 11074 if (needSep) pw.println(); 11075 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11076 pw.print(" total, non-act at "); 11077 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11078 pw.print(", non-svc at "); 11079 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11080 pw.println("):"); 11081 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11082 needSep = true; 11083 } 11084 11085 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11086 11087 pw.println(); 11088 pw.println(" mHomeProcess: " + mHomeProcess); 11089 pw.println(" mPreviousProcess: " + mPreviousProcess); 11090 if (mHeavyWeightProcess != null) { 11091 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11092 } 11093 11094 return true; 11095 } 11096 11097 /** 11098 * There are three ways to call this: 11099 * - no provider specified: dump all the providers 11100 * - a flattened component name that matched an existing provider was specified as the 11101 * first arg: dump that one provider 11102 * - the first arg isn't the flattened component name of an existing provider: 11103 * dump all providers whose component contains the first arg as a substring 11104 */ 11105 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11106 int opti, boolean dumpAll) { 11107 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11108 } 11109 11110 static class ItemMatcher { 11111 ArrayList<ComponentName> components; 11112 ArrayList<String> strings; 11113 ArrayList<Integer> objects; 11114 boolean all; 11115 11116 ItemMatcher() { 11117 all = true; 11118 } 11119 11120 void build(String name) { 11121 ComponentName componentName = ComponentName.unflattenFromString(name); 11122 if (componentName != null) { 11123 if (components == null) { 11124 components = new ArrayList<ComponentName>(); 11125 } 11126 components.add(componentName); 11127 all = false; 11128 } else { 11129 int objectId = 0; 11130 // Not a '/' separated full component name; maybe an object ID? 11131 try { 11132 objectId = Integer.parseInt(name, 16); 11133 if (objects == null) { 11134 objects = new ArrayList<Integer>(); 11135 } 11136 objects.add(objectId); 11137 all = false; 11138 } catch (RuntimeException e) { 11139 // Not an integer; just do string match. 11140 if (strings == null) { 11141 strings = new ArrayList<String>(); 11142 } 11143 strings.add(name); 11144 all = false; 11145 } 11146 } 11147 } 11148 11149 int build(String[] args, int opti) { 11150 for (; opti<args.length; opti++) { 11151 String name = args[opti]; 11152 if ("--".equals(name)) { 11153 return opti+1; 11154 } 11155 build(name); 11156 } 11157 return opti; 11158 } 11159 11160 boolean match(Object object, ComponentName comp) { 11161 if (all) { 11162 return true; 11163 } 11164 if (components != null) { 11165 for (int i=0; i<components.size(); i++) { 11166 if (components.get(i).equals(comp)) { 11167 return true; 11168 } 11169 } 11170 } 11171 if (objects != null) { 11172 for (int i=0; i<objects.size(); i++) { 11173 if (System.identityHashCode(object) == objects.get(i)) { 11174 return true; 11175 } 11176 } 11177 } 11178 if (strings != null) { 11179 String flat = comp.flattenToString(); 11180 for (int i=0; i<strings.size(); i++) { 11181 if (flat.contains(strings.get(i))) { 11182 return true; 11183 } 11184 } 11185 } 11186 return false; 11187 } 11188 } 11189 11190 /** 11191 * There are three things that cmd can be: 11192 * - a flattened component name that matches an existing activity 11193 * - the cmd arg isn't the flattened component name of an existing activity: 11194 * dump all activity whose component contains the cmd as a substring 11195 * - A hex number of the ActivityRecord object instance. 11196 */ 11197 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11198 int opti, boolean dumpAll) { 11199 ArrayList<ActivityRecord> activities; 11200 11201 synchronized (this) { 11202 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11203 } 11204 11205 if (activities.size() <= 0) { 11206 return false; 11207 } 11208 11209 String[] newArgs = new String[args.length - opti]; 11210 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11211 11212 TaskRecord lastTask = null; 11213 boolean needSep = false; 11214 for (int i=activities.size()-1; i>=0; i--) { 11215 ActivityRecord r = activities.get(i); 11216 if (needSep) { 11217 pw.println(); 11218 } 11219 needSep = true; 11220 synchronized (this) { 11221 if (lastTask != r.task) { 11222 lastTask = r.task; 11223 pw.print("TASK "); pw.print(lastTask.affinity); 11224 pw.print(" id="); pw.println(lastTask.taskId); 11225 if (dumpAll) { 11226 lastTask.dump(pw, " "); 11227 } 11228 } 11229 } 11230 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11231 } 11232 return true; 11233 } 11234 11235 /** 11236 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11237 * there is a thread associated with the activity. 11238 */ 11239 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11240 final ActivityRecord r, String[] args, boolean dumpAll) { 11241 String innerPrefix = prefix + " "; 11242 synchronized (this) { 11243 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11244 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11245 pw.print(" pid="); 11246 if (r.app != null) pw.println(r.app.pid); 11247 else pw.println("(not running)"); 11248 if (dumpAll) { 11249 r.dump(pw, innerPrefix); 11250 } 11251 } 11252 if (r.app != null && r.app.thread != null) { 11253 // flush anything that is already in the PrintWriter since the thread is going 11254 // to write to the file descriptor directly 11255 pw.flush(); 11256 try { 11257 TransferPipe tp = new TransferPipe(); 11258 try { 11259 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11260 r.appToken, innerPrefix, args); 11261 tp.go(fd); 11262 } finally { 11263 tp.kill(); 11264 } 11265 } catch (IOException e) { 11266 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11267 } catch (RemoteException e) { 11268 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11269 } 11270 } 11271 } 11272 11273 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11274 int opti, boolean dumpAll, String dumpPackage) { 11275 boolean needSep = false; 11276 boolean onlyHistory = false; 11277 boolean printedAnything = false; 11278 11279 if ("history".equals(dumpPackage)) { 11280 if (opti < args.length && "-s".equals(args[opti])) { 11281 dumpAll = false; 11282 } 11283 onlyHistory = true; 11284 dumpPackage = null; 11285 } 11286 11287 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11288 if (!onlyHistory && dumpAll) { 11289 if (mRegisteredReceivers.size() > 0) { 11290 boolean printed = false; 11291 Iterator it = mRegisteredReceivers.values().iterator(); 11292 while (it.hasNext()) { 11293 ReceiverList r = (ReceiverList)it.next(); 11294 if (dumpPackage != null && (r.app == null || 11295 !dumpPackage.equals(r.app.info.packageName))) { 11296 continue; 11297 } 11298 if (!printed) { 11299 pw.println(" Registered Receivers:"); 11300 needSep = true; 11301 printed = true; 11302 printedAnything = true; 11303 } 11304 pw.print(" * "); pw.println(r); 11305 r.dump(pw, " "); 11306 } 11307 } 11308 11309 if (mReceiverResolver.dump(pw, needSep ? 11310 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11311 " ", dumpPackage, false)) { 11312 needSep = true; 11313 printedAnything = true; 11314 } 11315 } 11316 11317 for (BroadcastQueue q : mBroadcastQueues) { 11318 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11319 printedAnything |= needSep; 11320 } 11321 11322 needSep = true; 11323 11324 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11325 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11326 if (needSep) { 11327 pw.println(); 11328 } 11329 needSep = true; 11330 printedAnything = true; 11331 pw.print(" Sticky broadcasts for user "); 11332 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11333 StringBuilder sb = new StringBuilder(128); 11334 for (Map.Entry<String, ArrayList<Intent>> ent 11335 : mStickyBroadcasts.valueAt(user).entrySet()) { 11336 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11337 if (dumpAll) { 11338 pw.println(":"); 11339 ArrayList<Intent> intents = ent.getValue(); 11340 final int N = intents.size(); 11341 for (int i=0; i<N; i++) { 11342 sb.setLength(0); 11343 sb.append(" Intent: "); 11344 intents.get(i).toShortString(sb, false, true, false, false); 11345 pw.println(sb.toString()); 11346 Bundle bundle = intents.get(i).getExtras(); 11347 if (bundle != null) { 11348 pw.print(" "); 11349 pw.println(bundle.toString()); 11350 } 11351 } 11352 } else { 11353 pw.println(""); 11354 } 11355 } 11356 } 11357 } 11358 11359 if (!onlyHistory && dumpAll) { 11360 pw.println(); 11361 for (BroadcastQueue queue : mBroadcastQueues) { 11362 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11363 + queue.mBroadcastsScheduled); 11364 } 11365 pw.println(" mHandler:"); 11366 mHandler.dump(new PrintWriterPrinter(pw), " "); 11367 needSep = true; 11368 printedAnything = true; 11369 } 11370 11371 if (!printedAnything) { 11372 pw.println(" (nothing)"); 11373 } 11374 } 11375 11376 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11377 int opti, boolean dumpAll, String dumpPackage) { 11378 boolean needSep; 11379 boolean printedAnything = false; 11380 11381 ItemMatcher matcher = new ItemMatcher(); 11382 matcher.build(args, opti); 11383 11384 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11385 11386 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11387 printedAnything |= needSep; 11388 11389 if (mLaunchingProviders.size() > 0) { 11390 boolean printed = false; 11391 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11392 ContentProviderRecord r = mLaunchingProviders.get(i); 11393 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11394 continue; 11395 } 11396 if (!printed) { 11397 if (needSep) pw.println(); 11398 needSep = true; 11399 pw.println(" Launching content providers:"); 11400 printed = true; 11401 printedAnything = true; 11402 } 11403 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11404 pw.println(r); 11405 } 11406 } 11407 11408 if (mGrantedUriPermissions.size() > 0) { 11409 boolean printed = false; 11410 int dumpUid = -2; 11411 if (dumpPackage != null) { 11412 try { 11413 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11414 } catch (NameNotFoundException e) { 11415 dumpUid = -1; 11416 } 11417 } 11418 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11419 int uid = mGrantedUriPermissions.keyAt(i); 11420 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11421 continue; 11422 } 11423 ArrayMap<Uri, UriPermission> perms 11424 = mGrantedUriPermissions.valueAt(i); 11425 if (!printed) { 11426 if (needSep) pw.println(); 11427 needSep = true; 11428 pw.println(" Granted Uri Permissions:"); 11429 printed = true; 11430 printedAnything = true; 11431 } 11432 pw.print(" * UID "); pw.print(uid); 11433 pw.println(" holds:"); 11434 for (UriPermission perm : perms.values()) { 11435 pw.print(" "); pw.println(perm); 11436 if (dumpAll) { 11437 perm.dump(pw, " "); 11438 } 11439 } 11440 } 11441 } 11442 11443 if (!printedAnything) { 11444 pw.println(" (nothing)"); 11445 } 11446 } 11447 11448 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11449 int opti, boolean dumpAll, String dumpPackage) { 11450 boolean printed = false; 11451 11452 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11453 11454 if (mIntentSenderRecords.size() > 0) { 11455 Iterator<WeakReference<PendingIntentRecord>> it 11456 = mIntentSenderRecords.values().iterator(); 11457 while (it.hasNext()) { 11458 WeakReference<PendingIntentRecord> ref = it.next(); 11459 PendingIntentRecord rec = ref != null ? ref.get(): null; 11460 if (dumpPackage != null && (rec == null 11461 || !dumpPackage.equals(rec.key.packageName))) { 11462 continue; 11463 } 11464 printed = true; 11465 if (rec != null) { 11466 pw.print(" * "); pw.println(rec); 11467 if (dumpAll) { 11468 rec.dump(pw, " "); 11469 } 11470 } else { 11471 pw.print(" * "); pw.println(ref); 11472 } 11473 } 11474 } 11475 11476 if (!printed) { 11477 pw.println(" (nothing)"); 11478 } 11479 } 11480 11481 private static final int dumpProcessList(PrintWriter pw, 11482 ActivityManagerService service, List list, 11483 String prefix, String normalLabel, String persistentLabel, 11484 String dumpPackage) { 11485 int numPers = 0; 11486 final int N = list.size()-1; 11487 for (int i=N; i>=0; i--) { 11488 ProcessRecord r = (ProcessRecord)list.get(i); 11489 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11490 continue; 11491 } 11492 pw.println(String.format("%s%s #%2d: %s", 11493 prefix, (r.persistent ? persistentLabel : normalLabel), 11494 i, r.toString())); 11495 if (r.persistent) { 11496 numPers++; 11497 } 11498 } 11499 return numPers; 11500 } 11501 11502 private static final boolean dumpProcessOomList(PrintWriter pw, 11503 ActivityManagerService service, List<ProcessRecord> origList, 11504 String prefix, String normalLabel, String persistentLabel, 11505 boolean inclDetails, String dumpPackage) { 11506 11507 ArrayList<Pair<ProcessRecord, Integer>> list 11508 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11509 for (int i=0; i<origList.size(); i++) { 11510 ProcessRecord r = origList.get(i); 11511 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11512 continue; 11513 } 11514 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11515 } 11516 11517 if (list.size() <= 0) { 11518 return false; 11519 } 11520 11521 Comparator<Pair<ProcessRecord, Integer>> comparator 11522 = new Comparator<Pair<ProcessRecord, Integer>>() { 11523 @Override 11524 public int compare(Pair<ProcessRecord, Integer> object1, 11525 Pair<ProcessRecord, Integer> object2) { 11526 if (object1.first.setAdj != object2.first.setAdj) { 11527 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11528 } 11529 if (object1.second.intValue() != object2.second.intValue()) { 11530 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11531 } 11532 return 0; 11533 } 11534 }; 11535 11536 Collections.sort(list, comparator); 11537 11538 final long curRealtime = SystemClock.elapsedRealtime(); 11539 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11540 final long curUptime = SystemClock.uptimeMillis(); 11541 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11542 11543 for (int i=list.size()-1; i>=0; i--) { 11544 ProcessRecord r = list.get(i).first; 11545 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11546 char schedGroup; 11547 switch (r.setSchedGroup) { 11548 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11549 schedGroup = 'B'; 11550 break; 11551 case Process.THREAD_GROUP_DEFAULT: 11552 schedGroup = 'F'; 11553 break; 11554 default: 11555 schedGroup = '?'; 11556 break; 11557 } 11558 char foreground; 11559 if (r.foregroundActivities) { 11560 foreground = 'A'; 11561 } else if (r.foregroundServices) { 11562 foreground = 'S'; 11563 } else { 11564 foreground = ' '; 11565 } 11566 String procState = ProcessList.makeProcStateString(r.curProcState); 11567 pw.print(prefix); 11568 pw.print(r.persistent ? persistentLabel : normalLabel); 11569 pw.print(" #"); 11570 int num = (origList.size()-1)-list.get(i).second; 11571 if (num < 10) pw.print(' '); 11572 pw.print(num); 11573 pw.print(": "); 11574 pw.print(oomAdj); 11575 pw.print(' '); 11576 pw.print(schedGroup); 11577 pw.print('/'); 11578 pw.print(foreground); 11579 pw.print('/'); 11580 pw.print(procState); 11581 pw.print(" trm:"); 11582 if (r.trimMemoryLevel < 10) pw.print(' '); 11583 pw.print(r.trimMemoryLevel); 11584 pw.print(' '); 11585 pw.print(r.toShortString()); 11586 pw.print(" ("); 11587 pw.print(r.adjType); 11588 pw.println(')'); 11589 if (r.adjSource != null || r.adjTarget != null) { 11590 pw.print(prefix); 11591 pw.print(" "); 11592 if (r.adjTarget instanceof ComponentName) { 11593 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11594 } else if (r.adjTarget != null) { 11595 pw.print(r.adjTarget.toString()); 11596 } else { 11597 pw.print("{null}"); 11598 } 11599 pw.print("<="); 11600 if (r.adjSource instanceof ProcessRecord) { 11601 pw.print("Proc{"); 11602 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11603 pw.println("}"); 11604 } else if (r.adjSource != null) { 11605 pw.println(r.adjSource.toString()); 11606 } else { 11607 pw.println("{null}"); 11608 } 11609 } 11610 if (inclDetails) { 11611 pw.print(prefix); 11612 pw.print(" "); 11613 pw.print("oom: max="); pw.print(r.maxAdj); 11614 pw.print(" curRaw="); pw.print(r.curRawAdj); 11615 pw.print(" setRaw="); pw.print(r.setRawAdj); 11616 pw.print(" cur="); pw.print(r.curAdj); 11617 pw.print(" set="); pw.println(r.setAdj); 11618 pw.print(prefix); 11619 pw.print(" "); 11620 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11621 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11622 pw.print(" lastPss="); pw.print(r.lastPss); 11623 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11624 pw.print(prefix); 11625 pw.print(" "); 11626 pw.print("keeping="); pw.print(r.keeping); 11627 pw.print(" cached="); pw.print(r.cached); 11628 pw.print(" empty="); pw.print(r.empty); 11629 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11630 11631 if (!r.keeping) { 11632 if (r.lastWakeTime != 0) { 11633 long wtime; 11634 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11635 synchronized (stats) { 11636 wtime = stats.getProcessWakeTime(r.info.uid, 11637 r.pid, curRealtime); 11638 } 11639 long timeUsed = wtime - r.lastWakeTime; 11640 pw.print(prefix); 11641 pw.print(" "); 11642 pw.print("keep awake over "); 11643 TimeUtils.formatDuration(realtimeSince, pw); 11644 pw.print(" used "); 11645 TimeUtils.formatDuration(timeUsed, pw); 11646 pw.print(" ("); 11647 pw.print((timeUsed*100)/realtimeSince); 11648 pw.println("%)"); 11649 } 11650 if (r.lastCpuTime != 0) { 11651 long timeUsed = r.curCpuTime - r.lastCpuTime; 11652 pw.print(prefix); 11653 pw.print(" "); 11654 pw.print("run cpu over "); 11655 TimeUtils.formatDuration(uptimeSince, pw); 11656 pw.print(" used "); 11657 TimeUtils.formatDuration(timeUsed, pw); 11658 pw.print(" ("); 11659 pw.print((timeUsed*100)/uptimeSince); 11660 pw.println("%)"); 11661 } 11662 } 11663 } 11664 } 11665 return true; 11666 } 11667 11668 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11669 ArrayList<ProcessRecord> procs; 11670 synchronized (this) { 11671 if (args != null && args.length > start 11672 && args[start].charAt(0) != '-') { 11673 procs = new ArrayList<ProcessRecord>(); 11674 int pid = -1; 11675 try { 11676 pid = Integer.parseInt(args[start]); 11677 } catch (NumberFormatException e) { 11678 } 11679 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11680 ProcessRecord proc = mLruProcesses.get(i); 11681 if (proc.pid == pid) { 11682 procs.add(proc); 11683 } else if (proc.processName.equals(args[start])) { 11684 procs.add(proc); 11685 } 11686 } 11687 if (procs.size() <= 0) { 11688 return null; 11689 } 11690 } else { 11691 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11692 } 11693 } 11694 return procs; 11695 } 11696 11697 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11698 PrintWriter pw, String[] args) { 11699 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11700 if (procs == null) { 11701 pw.println("No process found for: " + args[0]); 11702 return; 11703 } 11704 11705 long uptime = SystemClock.uptimeMillis(); 11706 long realtime = SystemClock.elapsedRealtime(); 11707 pw.println("Applications Graphics Acceleration Info:"); 11708 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11709 11710 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11711 ProcessRecord r = procs.get(i); 11712 if (r.thread != null) { 11713 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11714 pw.flush(); 11715 try { 11716 TransferPipe tp = new TransferPipe(); 11717 try { 11718 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11719 tp.go(fd); 11720 } finally { 11721 tp.kill(); 11722 } 11723 } catch (IOException e) { 11724 pw.println("Failure while dumping the app: " + r); 11725 pw.flush(); 11726 } catch (RemoteException e) { 11727 pw.println("Got a RemoteException while dumping the app " + r); 11728 pw.flush(); 11729 } 11730 } 11731 } 11732 } 11733 11734 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11735 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11736 if (procs == null) { 11737 pw.println("No process found for: " + args[0]); 11738 return; 11739 } 11740 11741 pw.println("Applications Database Info:"); 11742 11743 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11744 ProcessRecord r = procs.get(i); 11745 if (r.thread != null) { 11746 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11747 pw.flush(); 11748 try { 11749 TransferPipe tp = new TransferPipe(); 11750 try { 11751 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11752 tp.go(fd); 11753 } finally { 11754 tp.kill(); 11755 } 11756 } catch (IOException e) { 11757 pw.println("Failure while dumping the app: " + r); 11758 pw.flush(); 11759 } catch (RemoteException e) { 11760 pw.println("Got a RemoteException while dumping the app " + r); 11761 pw.flush(); 11762 } 11763 } 11764 } 11765 } 11766 11767 final static class MemItem { 11768 final boolean isProc; 11769 final String label; 11770 final String shortLabel; 11771 final long pss; 11772 final int id; 11773 final boolean hasActivities; 11774 ArrayList<MemItem> subitems; 11775 11776 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11777 boolean _hasActivities) { 11778 isProc = true; 11779 label = _label; 11780 shortLabel = _shortLabel; 11781 pss = _pss; 11782 id = _id; 11783 hasActivities = _hasActivities; 11784 } 11785 11786 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11787 isProc = false; 11788 label = _label; 11789 shortLabel = _shortLabel; 11790 pss = _pss; 11791 id = _id; 11792 hasActivities = false; 11793 } 11794 } 11795 11796 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11797 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11798 if (sort && !isCompact) { 11799 Collections.sort(items, new Comparator<MemItem>() { 11800 @Override 11801 public int compare(MemItem lhs, MemItem rhs) { 11802 if (lhs.pss < rhs.pss) { 11803 return 1; 11804 } else if (lhs.pss > rhs.pss) { 11805 return -1; 11806 } 11807 return 0; 11808 } 11809 }); 11810 } 11811 11812 for (int i=0; i<items.size(); i++) { 11813 MemItem mi = items.get(i); 11814 if (!isCompact) { 11815 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11816 } else if (mi.isProc) { 11817 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11818 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11819 pw.println(mi.hasActivities ? ",a" : ",e"); 11820 } else { 11821 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11822 pw.println(mi.pss); 11823 } 11824 if (mi.subitems != null) { 11825 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11826 true, isCompact); 11827 } 11828 } 11829 } 11830 11831 // These are in KB. 11832 static final long[] DUMP_MEM_BUCKETS = new long[] { 11833 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11834 120*1024, 160*1024, 200*1024, 11835 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11836 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11837 }; 11838 11839 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11840 boolean stackLike) { 11841 int start = label.lastIndexOf('.'); 11842 if (start >= 0) start++; 11843 else start = 0; 11844 int end = label.length(); 11845 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11846 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11847 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11848 out.append(bucket); 11849 out.append(stackLike ? "MB." : "MB "); 11850 out.append(label, start, end); 11851 return; 11852 } 11853 } 11854 out.append(memKB/1024); 11855 out.append(stackLike ? "MB." : "MB "); 11856 out.append(label, start, end); 11857 } 11858 11859 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11860 ProcessList.NATIVE_ADJ, 11861 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11862 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11863 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11864 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11865 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11866 }; 11867 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11868 "Native", 11869 "System", "Persistent", "Foreground", 11870 "Visible", "Perceptible", 11871 "Heavy Weight", "Backup", 11872 "A Services", "Home", 11873 "Previous", "B Services", "Cached" 11874 }; 11875 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11876 "native", 11877 "sys", "pers", "fore", 11878 "vis", "percept", 11879 "heavy", "backup", 11880 "servicea", "home", 11881 "prev", "serviceb", "cached" 11882 }; 11883 11884 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11885 long realtime, boolean isCheckinRequest, boolean isCompact) { 11886 if (isCheckinRequest || isCompact) { 11887 // short checkin version 11888 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11889 } else { 11890 pw.println("Applications Memory Usage (kB):"); 11891 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11892 } 11893 } 11894 11895 final void dumpApplicationMemoryUsage(FileDescriptor fd, 11896 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 11897 boolean dumpDetails = false; 11898 boolean dumpFullDetails = false; 11899 boolean dumpDalvik = false; 11900 boolean oomOnly = false; 11901 boolean isCompact = false; 11902 boolean localOnly = false; 11903 11904 int opti = 0; 11905 while (opti < args.length) { 11906 String opt = args[opti]; 11907 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11908 break; 11909 } 11910 opti++; 11911 if ("-a".equals(opt)) { 11912 dumpDetails = true; 11913 dumpFullDetails = true; 11914 dumpDalvik = true; 11915 } else if ("-d".equals(opt)) { 11916 dumpDalvik = true; 11917 } else if ("-c".equals(opt)) { 11918 isCompact = true; 11919 } else if ("--oom".equals(opt)) { 11920 oomOnly = true; 11921 } else if ("--local".equals(opt)) { 11922 localOnly = true; 11923 } else if ("-h".equals(opt)) { 11924 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 11925 pw.println(" -a: include all available information for each process."); 11926 pw.println(" -d: include dalvik details when dumping process details."); 11927 pw.println(" -c: dump in a compact machine-parseable representation."); 11928 pw.println(" --oom: only show processes organized by oom adj."); 11929 pw.println(" --local: only collect details locally, don't call process."); 11930 pw.println("If [process] is specified it can be the name or "); 11931 pw.println("pid of a specific process to dump."); 11932 return; 11933 } else { 11934 pw.println("Unknown argument: " + opt + "; use -h for help"); 11935 } 11936 } 11937 11938 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 11939 long uptime = SystemClock.uptimeMillis(); 11940 long realtime = SystemClock.elapsedRealtime(); 11941 final long[] tmpLong = new long[1]; 11942 11943 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 11944 if (procs == null) { 11945 // No Java processes. Maybe they want to print a native process. 11946 if (args != null && args.length > opti 11947 && args[opti].charAt(0) != '-') { 11948 ArrayList<ProcessCpuTracker.Stats> nativeProcs 11949 = new ArrayList<ProcessCpuTracker.Stats>(); 11950 updateCpuStatsNow(); 11951 int findPid = -1; 11952 try { 11953 findPid = Integer.parseInt(args[opti]); 11954 } catch (NumberFormatException e) { 11955 } 11956 synchronized (mProcessCpuThread) { 11957 final int N = mProcessCpuTracker.countStats(); 11958 for (int i=0; i<N; i++) { 11959 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 11960 if (st.pid == findPid || (st.baseName != null 11961 && st.baseName.equals(args[opti]))) { 11962 nativeProcs.add(st); 11963 } 11964 } 11965 } 11966 if (nativeProcs.size() > 0) { 11967 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 11968 isCompact); 11969 Debug.MemoryInfo mi = null; 11970 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 11971 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 11972 final int pid = r.pid; 11973 if (!isCheckinRequest && dumpDetails) { 11974 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 11975 } 11976 if (mi == null) { 11977 mi = new Debug.MemoryInfo(); 11978 } 11979 if (dumpDetails || (!brief && !oomOnly)) { 11980 Debug.getMemoryInfo(pid, mi); 11981 } else { 11982 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 11983 mi.dalvikPrivateDirty = (int)tmpLong[0]; 11984 } 11985 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 11986 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 11987 if (isCheckinRequest) { 11988 pw.println(); 11989 } 11990 } 11991 return; 11992 } 11993 } 11994 pw.println("No process found for: " + args[opti]); 11995 return; 11996 } 11997 11998 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 11999 dumpDetails = true; 12000 } 12001 12002 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12003 12004 String[] innerArgs = new String[args.length-opti]; 12005 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12006 12007 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12008 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12009 long nativePss=0, dalvikPss=0, otherPss=0; 12010 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12011 12012 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12013 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12014 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12015 12016 long totalPss = 0; 12017 long cachedPss = 0; 12018 12019 Debug.MemoryInfo mi = null; 12020 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12021 final ProcessRecord r = procs.get(i); 12022 final IApplicationThread thread; 12023 final int pid; 12024 final int oomAdj; 12025 final boolean hasActivities; 12026 synchronized (this) { 12027 thread = r.thread; 12028 pid = r.pid; 12029 oomAdj = r.getSetAdjWithServices(); 12030 hasActivities = r.activities.size() > 0; 12031 } 12032 if (thread != null) { 12033 if (!isCheckinRequest && dumpDetails) { 12034 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12035 } 12036 if (mi == null) { 12037 mi = new Debug.MemoryInfo(); 12038 } 12039 if (dumpDetails || (!brief && !oomOnly)) { 12040 Debug.getMemoryInfo(pid, mi); 12041 } else { 12042 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12043 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12044 } 12045 if (dumpDetails) { 12046 if (localOnly) { 12047 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12048 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12049 if (isCheckinRequest) { 12050 pw.println(); 12051 } 12052 } else { 12053 try { 12054 pw.flush(); 12055 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12056 dumpDalvik, innerArgs); 12057 } catch (RemoteException e) { 12058 if (!isCheckinRequest) { 12059 pw.println("Got RemoteException!"); 12060 pw.flush(); 12061 } 12062 } 12063 } 12064 } 12065 12066 final long myTotalPss = mi.getTotalPss(); 12067 final long myTotalUss = mi.getTotalUss(); 12068 12069 synchronized (this) { 12070 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12071 // Record this for posterity if the process has been stable. 12072 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12073 } 12074 } 12075 12076 if (!isCheckinRequest && mi != null) { 12077 totalPss += myTotalPss; 12078 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12079 (hasActivities ? " / activities)" : ")"), 12080 r.processName, myTotalPss, pid, hasActivities); 12081 procMems.add(pssItem); 12082 procMemsMap.put(pid, pssItem); 12083 12084 nativePss += mi.nativePss; 12085 dalvikPss += mi.dalvikPss; 12086 otherPss += mi.otherPss; 12087 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12088 long mem = mi.getOtherPss(j); 12089 miscPss[j] += mem; 12090 otherPss -= mem; 12091 } 12092 12093 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12094 cachedPss += myTotalPss; 12095 } 12096 12097 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12098 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12099 || oomIndex == (oomPss.length-1)) { 12100 oomPss[oomIndex] += myTotalPss; 12101 if (oomProcs[oomIndex] == null) { 12102 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12103 } 12104 oomProcs[oomIndex].add(pssItem); 12105 break; 12106 } 12107 } 12108 } 12109 } 12110 } 12111 12112 if (!isCheckinRequest && procs.size() > 1) { 12113 // If we are showing aggregations, also look for native processes to 12114 // include so that our aggregations are more accurate. 12115 updateCpuStatsNow(); 12116 synchronized (mProcessCpuThread) { 12117 final int N = mProcessCpuTracker.countStats(); 12118 for (int i=0; i<N; i++) { 12119 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12120 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12121 if (mi == null) { 12122 mi = new Debug.MemoryInfo(); 12123 } 12124 if (!brief && !oomOnly) { 12125 Debug.getMemoryInfo(st.pid, mi); 12126 } else { 12127 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12128 mi.nativePrivateDirty = (int)tmpLong[0]; 12129 } 12130 12131 final long myTotalPss = mi.getTotalPss(); 12132 totalPss += myTotalPss; 12133 12134 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12135 st.name, myTotalPss, st.pid, false); 12136 procMems.add(pssItem); 12137 12138 nativePss += mi.nativePss; 12139 dalvikPss += mi.dalvikPss; 12140 otherPss += mi.otherPss; 12141 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12142 long mem = mi.getOtherPss(j); 12143 miscPss[j] += mem; 12144 otherPss -= mem; 12145 } 12146 oomPss[0] += myTotalPss; 12147 if (oomProcs[0] == null) { 12148 oomProcs[0] = new ArrayList<MemItem>(); 12149 } 12150 oomProcs[0].add(pssItem); 12151 } 12152 } 12153 } 12154 12155 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12156 12157 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12158 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12159 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12160 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12161 String label = Debug.MemoryInfo.getOtherLabel(j); 12162 catMems.add(new MemItem(label, label, miscPss[j], j)); 12163 } 12164 12165 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12166 for (int j=0; j<oomPss.length; j++) { 12167 if (oomPss[j] != 0) { 12168 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12169 : DUMP_MEM_OOM_LABEL[j]; 12170 MemItem item = new MemItem(label, label, oomPss[j], 12171 DUMP_MEM_OOM_ADJ[j]); 12172 item.subitems = oomProcs[j]; 12173 oomMems.add(item); 12174 } 12175 } 12176 12177 if (!brief && !oomOnly && !isCompact) { 12178 pw.println(); 12179 pw.println("Total PSS by process:"); 12180 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12181 pw.println(); 12182 } 12183 if (!isCompact) { 12184 pw.println("Total PSS by OOM adjustment:"); 12185 } 12186 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12187 if (!brief && !oomOnly) { 12188 PrintWriter out = categoryPw != null ? categoryPw : pw; 12189 if (!isCompact) { 12190 out.println(); 12191 out.println("Total PSS by category:"); 12192 } 12193 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12194 } 12195 if (!isCompact) { 12196 pw.println(); 12197 } 12198 MemInfoReader memInfo = new MemInfoReader(); 12199 memInfo.readMemInfo(); 12200 if (!brief) { 12201 if (!isCompact) { 12202 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12203 pw.println(" kB"); 12204 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12205 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12206 pw.print(cachedPss); pw.print(" cached pss + "); 12207 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12208 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12209 } else { 12210 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12211 pw.print(cachedPss + memInfo.getCachedSizeKb() 12212 + memInfo.getFreeSizeKb()); pw.print(","); 12213 pw.println(totalPss - cachedPss); 12214 } 12215 } 12216 if (!isCompact) { 12217 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12218 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12219 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12220 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12221 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12222 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12223 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12224 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12225 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12226 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12227 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12228 } 12229 if (!brief) { 12230 if (memInfo.getZramTotalSizeKb() != 0) { 12231 if (!isCompact) { 12232 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12233 pw.print(" kB physical used for "); 12234 pw.print(memInfo.getSwapTotalSizeKb() 12235 - memInfo.getSwapFreeSizeKb()); 12236 pw.print(" kB in swap ("); 12237 pw.print(memInfo.getSwapTotalSizeKb()); 12238 pw.println(" kB total swap)"); 12239 } else { 12240 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12241 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12242 pw.println(memInfo.getSwapFreeSizeKb()); 12243 } 12244 } 12245 final int[] SINGLE_LONG_FORMAT = new int[] { 12246 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12247 }; 12248 long[] longOut = new long[1]; 12249 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12250 SINGLE_LONG_FORMAT, null, longOut, null); 12251 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12252 longOut[0] = 0; 12253 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12254 SINGLE_LONG_FORMAT, null, longOut, null); 12255 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12256 longOut[0] = 0; 12257 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12258 SINGLE_LONG_FORMAT, null, longOut, null); 12259 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12260 longOut[0] = 0; 12261 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12262 SINGLE_LONG_FORMAT, null, longOut, null); 12263 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12264 if (!isCompact) { 12265 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12266 pw.print(" KSM: "); pw.print(sharing); 12267 pw.print(" kB saved from shared "); 12268 pw.print(shared); pw.println(" kB"); 12269 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12270 pw.print(voltile); pw.println(" kB volatile"); 12271 } 12272 pw.print(" Tuning: "); 12273 pw.print(ActivityManager.staticGetMemoryClass()); 12274 pw.print(" (large "); 12275 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12276 pw.print("), oom "); 12277 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12278 pw.print(" kB"); 12279 pw.print(", restore limit "); 12280 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12281 pw.print(" kB"); 12282 if (ActivityManager.isLowRamDeviceStatic()) { 12283 pw.print(" (low-ram)"); 12284 } 12285 if (ActivityManager.isHighEndGfx()) { 12286 pw.print(" (high-end-gfx)"); 12287 } 12288 pw.println(); 12289 } else { 12290 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12291 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12292 pw.println(voltile); 12293 pw.print("tuning,"); 12294 pw.print(ActivityManager.staticGetMemoryClass()); 12295 pw.print(','); 12296 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12297 pw.print(','); 12298 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12299 if (ActivityManager.isLowRamDeviceStatic()) { 12300 pw.print(",low-ram"); 12301 } 12302 if (ActivityManager.isHighEndGfx()) { 12303 pw.print(",high-end-gfx"); 12304 } 12305 pw.println(); 12306 } 12307 } 12308 } 12309 } 12310 12311 /** 12312 * Searches array of arguments for the specified string 12313 * @param args array of argument strings 12314 * @param value value to search for 12315 * @return true if the value is contained in the array 12316 */ 12317 private static boolean scanArgs(String[] args, String value) { 12318 if (args != null) { 12319 for (String arg : args) { 12320 if (value.equals(arg)) { 12321 return true; 12322 } 12323 } 12324 } 12325 return false; 12326 } 12327 12328 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12329 ContentProviderRecord cpr, boolean always) { 12330 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12331 12332 if (!inLaunching || always) { 12333 synchronized (cpr) { 12334 cpr.launchingApp = null; 12335 cpr.notifyAll(); 12336 } 12337 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12338 String names[] = cpr.info.authority.split(";"); 12339 for (int j = 0; j < names.length; j++) { 12340 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12341 } 12342 } 12343 12344 for (int i=0; i<cpr.connections.size(); i++) { 12345 ContentProviderConnection conn = cpr.connections.get(i); 12346 if (conn.waiting) { 12347 // If this connection is waiting for the provider, then we don't 12348 // need to mess with its process unless we are always removing 12349 // or for some reason the provider is not currently launching. 12350 if (inLaunching && !always) { 12351 continue; 12352 } 12353 } 12354 ProcessRecord capp = conn.client; 12355 conn.dead = true; 12356 if (conn.stableCount > 0) { 12357 if (!capp.persistent && capp.thread != null 12358 && capp.pid != 0 12359 && capp.pid != MY_PID) { 12360 killUnneededProcessLocked(capp, "depends on provider " 12361 + cpr.name.flattenToShortString() 12362 + " in dying proc " + (proc != null ? proc.processName : "??")); 12363 } 12364 } else if (capp.thread != null && conn.provider.provider != null) { 12365 try { 12366 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12367 } catch (RemoteException e) { 12368 } 12369 // In the protocol here, we don't expect the client to correctly 12370 // clean up this connection, we'll just remove it. 12371 cpr.connections.remove(i); 12372 conn.client.conProviders.remove(conn); 12373 } 12374 } 12375 12376 if (inLaunching && always) { 12377 mLaunchingProviders.remove(cpr); 12378 } 12379 return inLaunching; 12380 } 12381 12382 /** 12383 * Main code for cleaning up a process when it has gone away. This is 12384 * called both as a result of the process dying, or directly when stopping 12385 * a process when running in single process mode. 12386 */ 12387 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12388 boolean restarting, boolean allowRestart, int index) { 12389 if (index >= 0) { 12390 removeLruProcessLocked(app); 12391 } 12392 12393 mProcessesToGc.remove(app); 12394 mPendingPssProcesses.remove(app); 12395 12396 // Dismiss any open dialogs. 12397 if (app.crashDialog != null && !app.forceCrashReport) { 12398 app.crashDialog.dismiss(); 12399 app.crashDialog = null; 12400 } 12401 if (app.anrDialog != null) { 12402 app.anrDialog.dismiss(); 12403 app.anrDialog = null; 12404 } 12405 if (app.waitDialog != null) { 12406 app.waitDialog.dismiss(); 12407 app.waitDialog = null; 12408 } 12409 12410 app.crashing = false; 12411 app.notResponding = false; 12412 12413 app.resetPackageList(mProcessStats); 12414 app.unlinkDeathRecipient(); 12415 app.makeInactive(mProcessStats); 12416 app.forcingToForeground = null; 12417 app.foregroundServices = false; 12418 app.foregroundActivities = false; 12419 app.hasShownUi = false; 12420 app.hasAboveClient = false; 12421 12422 mServices.killServicesLocked(app, allowRestart); 12423 12424 boolean restart = false; 12425 12426 // Remove published content providers. 12427 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12428 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12429 final boolean always = app.bad || !allowRestart; 12430 if (removeDyingProviderLocked(app, cpr, always) || always) { 12431 // We left the provider in the launching list, need to 12432 // restart it. 12433 restart = true; 12434 } 12435 12436 cpr.provider = null; 12437 cpr.proc = null; 12438 } 12439 app.pubProviders.clear(); 12440 12441 // Take care of any launching providers waiting for this process. 12442 if (checkAppInLaunchingProvidersLocked(app, false)) { 12443 restart = true; 12444 } 12445 12446 // Unregister from connected content providers. 12447 if (!app.conProviders.isEmpty()) { 12448 for (int i=0; i<app.conProviders.size(); i++) { 12449 ContentProviderConnection conn = app.conProviders.get(i); 12450 conn.provider.connections.remove(conn); 12451 } 12452 app.conProviders.clear(); 12453 } 12454 12455 // At this point there may be remaining entries in mLaunchingProviders 12456 // where we were the only one waiting, so they are no longer of use. 12457 // Look for these and clean up if found. 12458 // XXX Commented out for now. Trying to figure out a way to reproduce 12459 // the actual situation to identify what is actually going on. 12460 if (false) { 12461 for (int i=0; i<mLaunchingProviders.size(); i++) { 12462 ContentProviderRecord cpr = (ContentProviderRecord) 12463 mLaunchingProviders.get(i); 12464 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12465 synchronized (cpr) { 12466 cpr.launchingApp = null; 12467 cpr.notifyAll(); 12468 } 12469 } 12470 } 12471 } 12472 12473 skipCurrentReceiverLocked(app); 12474 12475 // Unregister any receivers. 12476 for (int i=app.receivers.size()-1; i>=0; i--) { 12477 removeReceiverLocked(app.receivers.valueAt(i)); 12478 } 12479 app.receivers.clear(); 12480 12481 // If the app is undergoing backup, tell the backup manager about it 12482 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12483 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12484 + mBackupTarget.appInfo + " died during backup"); 12485 try { 12486 IBackupManager bm = IBackupManager.Stub.asInterface( 12487 ServiceManager.getService(Context.BACKUP_SERVICE)); 12488 bm.agentDisconnected(app.info.packageName); 12489 } catch (RemoteException e) { 12490 // can't happen; backup manager is local 12491 } 12492 } 12493 12494 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12495 ProcessChangeItem item = mPendingProcessChanges.get(i); 12496 if (item.pid == app.pid) { 12497 mPendingProcessChanges.remove(i); 12498 mAvailProcessChanges.add(item); 12499 } 12500 } 12501 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12502 12503 // If the caller is restarting this app, then leave it in its 12504 // current lists and let the caller take care of it. 12505 if (restarting) { 12506 return; 12507 } 12508 12509 if (!app.persistent || app.isolated) { 12510 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12511 "Removing non-persistent process during cleanup: " + app); 12512 mProcessNames.remove(app.processName, app.uid); 12513 mIsolatedProcesses.remove(app.uid); 12514 if (mHeavyWeightProcess == app) { 12515 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12516 mHeavyWeightProcess.userId, 0)); 12517 mHeavyWeightProcess = null; 12518 } 12519 } else if (!app.removed) { 12520 // This app is persistent, so we need to keep its record around. 12521 // If it is not already on the pending app list, add it there 12522 // and start a new process for it. 12523 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12524 mPersistentStartingProcesses.add(app); 12525 restart = true; 12526 } 12527 } 12528 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12529 "Clean-up removing on hold: " + app); 12530 mProcessesOnHold.remove(app); 12531 12532 if (app == mHomeProcess) { 12533 mHomeProcess = null; 12534 } 12535 if (app == mPreviousProcess) { 12536 mPreviousProcess = null; 12537 } 12538 12539 if (restart && !app.isolated) { 12540 // We have components that still need to be running in the 12541 // process, so re-launch it. 12542 mProcessNames.put(app.processName, app.uid, app); 12543 startProcessLocked(app, "restart", app.processName); 12544 } else if (app.pid > 0 && app.pid != MY_PID) { 12545 // Goodbye! 12546 synchronized (mPidsSelfLocked) { 12547 mPidsSelfLocked.remove(app.pid); 12548 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12549 } 12550 app.setPid(0); 12551 } 12552 } 12553 12554 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12555 // Look through the content providers we are waiting to have launched, 12556 // and if any run in this process then either schedule a restart of 12557 // the process or kill the client waiting for it if this process has 12558 // gone bad. 12559 int NL = mLaunchingProviders.size(); 12560 boolean restart = false; 12561 for (int i=0; i<NL; i++) { 12562 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12563 if (cpr.launchingApp == app) { 12564 if (!alwaysBad && !app.bad) { 12565 restart = true; 12566 } else { 12567 removeDyingProviderLocked(app, cpr, true); 12568 // cpr should have been removed from mLaunchingProviders 12569 NL = mLaunchingProviders.size(); 12570 i--; 12571 } 12572 } 12573 } 12574 return restart; 12575 } 12576 12577 // ========================================================= 12578 // SERVICES 12579 // ========================================================= 12580 12581 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12582 int flags) { 12583 enforceNotIsolatedCaller("getServices"); 12584 synchronized (this) { 12585 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12586 } 12587 } 12588 12589 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12590 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12591 synchronized (this) { 12592 return mServices.getRunningServiceControlPanelLocked(name); 12593 } 12594 } 12595 12596 public ComponentName startService(IApplicationThread caller, Intent service, 12597 String resolvedType, int userId) { 12598 enforceNotIsolatedCaller("startService"); 12599 // Refuse possible leaked file descriptors 12600 if (service != null && service.hasFileDescriptors() == true) { 12601 throw new IllegalArgumentException("File descriptors passed in Intent"); 12602 } 12603 12604 if (DEBUG_SERVICE) 12605 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12606 synchronized(this) { 12607 final int callingPid = Binder.getCallingPid(); 12608 final int callingUid = Binder.getCallingUid(); 12609 final long origId = Binder.clearCallingIdentity(); 12610 ComponentName res = mServices.startServiceLocked(caller, service, 12611 resolvedType, callingPid, callingUid, userId); 12612 Binder.restoreCallingIdentity(origId); 12613 return res; 12614 } 12615 } 12616 12617 ComponentName startServiceInPackage(int uid, 12618 Intent service, String resolvedType, int userId) { 12619 synchronized(this) { 12620 if (DEBUG_SERVICE) 12621 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12622 final long origId = Binder.clearCallingIdentity(); 12623 ComponentName res = mServices.startServiceLocked(null, service, 12624 resolvedType, -1, uid, userId); 12625 Binder.restoreCallingIdentity(origId); 12626 return res; 12627 } 12628 } 12629 12630 public int stopService(IApplicationThread caller, Intent service, 12631 String resolvedType, int userId) { 12632 enforceNotIsolatedCaller("stopService"); 12633 // Refuse possible leaked file descriptors 12634 if (service != null && service.hasFileDescriptors() == true) { 12635 throw new IllegalArgumentException("File descriptors passed in Intent"); 12636 } 12637 12638 synchronized(this) { 12639 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12640 } 12641 } 12642 12643 public IBinder peekService(Intent service, String resolvedType) { 12644 enforceNotIsolatedCaller("peekService"); 12645 // Refuse possible leaked file descriptors 12646 if (service != null && service.hasFileDescriptors() == true) { 12647 throw new IllegalArgumentException("File descriptors passed in Intent"); 12648 } 12649 synchronized(this) { 12650 return mServices.peekServiceLocked(service, resolvedType); 12651 } 12652 } 12653 12654 public boolean stopServiceToken(ComponentName className, IBinder token, 12655 int startId) { 12656 synchronized(this) { 12657 return mServices.stopServiceTokenLocked(className, token, startId); 12658 } 12659 } 12660 12661 public void setServiceForeground(ComponentName className, IBinder token, 12662 int id, Notification notification, boolean removeNotification) { 12663 synchronized(this) { 12664 mServices.setServiceForegroundLocked(className, token, id, notification, 12665 removeNotification); 12666 } 12667 } 12668 12669 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12670 boolean requireFull, String name, String callerPackage) { 12671 final int callingUserId = UserHandle.getUserId(callingUid); 12672 if (callingUserId != userId) { 12673 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12674 if ((requireFull || checkComponentPermission( 12675 android.Manifest.permission.INTERACT_ACROSS_USERS, 12676 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12677 && checkComponentPermission( 12678 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12679 callingPid, callingUid, -1, true) 12680 != PackageManager.PERMISSION_GRANTED) { 12681 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12682 // In this case, they would like to just execute as their 12683 // owner user instead of failing. 12684 userId = callingUserId; 12685 } else { 12686 StringBuilder builder = new StringBuilder(128); 12687 builder.append("Permission Denial: "); 12688 builder.append(name); 12689 if (callerPackage != null) { 12690 builder.append(" from "); 12691 builder.append(callerPackage); 12692 } 12693 builder.append(" asks to run as user "); 12694 builder.append(userId); 12695 builder.append(" but is calling from user "); 12696 builder.append(UserHandle.getUserId(callingUid)); 12697 builder.append("; this requires "); 12698 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12699 if (!requireFull) { 12700 builder.append(" or "); 12701 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12702 } 12703 String msg = builder.toString(); 12704 Slog.w(TAG, msg); 12705 throw new SecurityException(msg); 12706 } 12707 } 12708 } 12709 if (userId == UserHandle.USER_CURRENT 12710 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12711 // Note that we may be accessing this outside of a lock... 12712 // shouldn't be a big deal, if this is being called outside 12713 // of a locked context there is intrinsically a race with 12714 // the value the caller will receive and someone else changing it. 12715 userId = mCurrentUserId; 12716 } 12717 if (!allowAll && userId < 0) { 12718 throw new IllegalArgumentException( 12719 "Call does not support special user #" + userId); 12720 } 12721 } 12722 return userId; 12723 } 12724 12725 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12726 String className, int flags) { 12727 boolean result = false; 12728 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12729 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12730 if (ActivityManager.checkUidPermission( 12731 android.Manifest.permission.INTERACT_ACROSS_USERS, 12732 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12733 ComponentName comp = new ComponentName(aInfo.packageName, className); 12734 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12735 + " requests FLAG_SINGLE_USER, but app does not hold " 12736 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12737 Slog.w(TAG, msg); 12738 throw new SecurityException(msg); 12739 } 12740 result = true; 12741 } 12742 } else if (componentProcessName == aInfo.packageName) { 12743 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12744 } else if ("system".equals(componentProcessName)) { 12745 result = true; 12746 } 12747 if (DEBUG_MU) { 12748 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12749 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12750 } 12751 return result; 12752 } 12753 12754 public int bindService(IApplicationThread caller, IBinder token, 12755 Intent service, String resolvedType, 12756 IServiceConnection connection, int flags, int userId) { 12757 enforceNotIsolatedCaller("bindService"); 12758 // Refuse possible leaked file descriptors 12759 if (service != null && service.hasFileDescriptors() == true) { 12760 throw new IllegalArgumentException("File descriptors passed in Intent"); 12761 } 12762 12763 synchronized(this) { 12764 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12765 connection, flags, userId); 12766 } 12767 } 12768 12769 public boolean unbindService(IServiceConnection connection) { 12770 synchronized (this) { 12771 return mServices.unbindServiceLocked(connection); 12772 } 12773 } 12774 12775 public void publishService(IBinder token, Intent intent, IBinder service) { 12776 // Refuse possible leaked file descriptors 12777 if (intent != null && intent.hasFileDescriptors() == true) { 12778 throw new IllegalArgumentException("File descriptors passed in Intent"); 12779 } 12780 12781 synchronized(this) { 12782 if (!(token instanceof ServiceRecord)) { 12783 throw new IllegalArgumentException("Invalid service token"); 12784 } 12785 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12786 } 12787 } 12788 12789 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12790 // Refuse possible leaked file descriptors 12791 if (intent != null && intent.hasFileDescriptors() == true) { 12792 throw new IllegalArgumentException("File descriptors passed in Intent"); 12793 } 12794 12795 synchronized(this) { 12796 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12797 } 12798 } 12799 12800 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12801 synchronized(this) { 12802 if (!(token instanceof ServiceRecord)) { 12803 throw new IllegalArgumentException("Invalid service token"); 12804 } 12805 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12806 } 12807 } 12808 12809 // ========================================================= 12810 // BACKUP AND RESTORE 12811 // ========================================================= 12812 12813 // Cause the target app to be launched if necessary and its backup agent 12814 // instantiated. The backup agent will invoke backupAgentCreated() on the 12815 // activity manager to announce its creation. 12816 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12817 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12818 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12819 12820 synchronized(this) { 12821 // !!! TODO: currently no check here that we're already bound 12822 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12823 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12824 synchronized (stats) { 12825 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12826 } 12827 12828 // Backup agent is now in use, its package can't be stopped. 12829 try { 12830 AppGlobals.getPackageManager().setPackageStoppedState( 12831 app.packageName, false, UserHandle.getUserId(app.uid)); 12832 } catch (RemoteException e) { 12833 } catch (IllegalArgumentException e) { 12834 Slog.w(TAG, "Failed trying to unstop package " 12835 + app.packageName + ": " + e); 12836 } 12837 12838 BackupRecord r = new BackupRecord(ss, app, backupMode); 12839 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12840 ? new ComponentName(app.packageName, app.backupAgentName) 12841 : new ComponentName("android", "FullBackupAgent"); 12842 // startProcessLocked() returns existing proc's record if it's already running 12843 ProcessRecord proc = startProcessLocked(app.processName, app, 12844 false, 0, "backup", hostingName, false, false, false); 12845 if (proc == null) { 12846 Slog.e(TAG, "Unable to start backup agent process " + r); 12847 return false; 12848 } 12849 12850 r.app = proc; 12851 mBackupTarget = r; 12852 mBackupAppName = app.packageName; 12853 12854 // Try not to kill the process during backup 12855 updateOomAdjLocked(proc); 12856 12857 // If the process is already attached, schedule the creation of the backup agent now. 12858 // If it is not yet live, this will be done when it attaches to the framework. 12859 if (proc.thread != null) { 12860 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12861 try { 12862 proc.thread.scheduleCreateBackupAgent(app, 12863 compatibilityInfoForPackageLocked(app), backupMode); 12864 } catch (RemoteException e) { 12865 // Will time out on the backup manager side 12866 } 12867 } else { 12868 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12869 } 12870 // Invariants: at this point, the target app process exists and the application 12871 // is either already running or in the process of coming up. mBackupTarget and 12872 // mBackupAppName describe the app, so that when it binds back to the AM we 12873 // know that it's scheduled for a backup-agent operation. 12874 } 12875 12876 return true; 12877 } 12878 12879 @Override 12880 public void clearPendingBackup() { 12881 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 12882 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 12883 12884 synchronized (this) { 12885 mBackupTarget = null; 12886 mBackupAppName = null; 12887 } 12888 } 12889 12890 // A backup agent has just come up 12891 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12892 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12893 + " = " + agent); 12894 12895 synchronized(this) { 12896 if (!agentPackageName.equals(mBackupAppName)) { 12897 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12898 return; 12899 } 12900 } 12901 12902 long oldIdent = Binder.clearCallingIdentity(); 12903 try { 12904 IBackupManager bm = IBackupManager.Stub.asInterface( 12905 ServiceManager.getService(Context.BACKUP_SERVICE)); 12906 bm.agentConnected(agentPackageName, agent); 12907 } catch (RemoteException e) { 12908 // can't happen; the backup manager service is local 12909 } catch (Exception e) { 12910 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12911 e.printStackTrace(); 12912 } finally { 12913 Binder.restoreCallingIdentity(oldIdent); 12914 } 12915 } 12916 12917 // done with this agent 12918 public void unbindBackupAgent(ApplicationInfo appInfo) { 12919 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12920 if (appInfo == null) { 12921 Slog.w(TAG, "unbind backup agent for null app"); 12922 return; 12923 } 12924 12925 synchronized(this) { 12926 try { 12927 if (mBackupAppName == null) { 12928 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12929 return; 12930 } 12931 12932 if (!mBackupAppName.equals(appInfo.packageName)) { 12933 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12934 return; 12935 } 12936 12937 // Not backing this app up any more; reset its OOM adjustment 12938 final ProcessRecord proc = mBackupTarget.app; 12939 updateOomAdjLocked(proc); 12940 12941 // If the app crashed during backup, 'thread' will be null here 12942 if (proc.thread != null) { 12943 try { 12944 proc.thread.scheduleDestroyBackupAgent(appInfo, 12945 compatibilityInfoForPackageLocked(appInfo)); 12946 } catch (Exception e) { 12947 Slog.e(TAG, "Exception when unbinding backup agent:"); 12948 e.printStackTrace(); 12949 } 12950 } 12951 } finally { 12952 mBackupTarget = null; 12953 mBackupAppName = null; 12954 } 12955 } 12956 } 12957 // ========================================================= 12958 // BROADCASTS 12959 // ========================================================= 12960 12961 private final List getStickiesLocked(String action, IntentFilter filter, 12962 List cur, int userId) { 12963 final ContentResolver resolver = mContext.getContentResolver(); 12964 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 12965 if (stickies == null) { 12966 return cur; 12967 } 12968 final ArrayList<Intent> list = stickies.get(action); 12969 if (list == null) { 12970 return cur; 12971 } 12972 int N = list.size(); 12973 for (int i=0; i<N; i++) { 12974 Intent intent = list.get(i); 12975 if (filter.match(resolver, intent, true, TAG) >= 0) { 12976 if (cur == null) { 12977 cur = new ArrayList<Intent>(); 12978 } 12979 cur.add(intent); 12980 } 12981 } 12982 return cur; 12983 } 12984 12985 boolean isPendingBroadcastProcessLocked(int pid) { 12986 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 12987 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 12988 } 12989 12990 void skipPendingBroadcastLocked(int pid) { 12991 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 12992 for (BroadcastQueue queue : mBroadcastQueues) { 12993 queue.skipPendingBroadcastLocked(pid); 12994 } 12995 } 12996 12997 // The app just attached; send any pending broadcasts that it should receive 12998 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 12999 boolean didSomething = false; 13000 for (BroadcastQueue queue : mBroadcastQueues) { 13001 didSomething |= queue.sendPendingBroadcastsLocked(app); 13002 } 13003 return didSomething; 13004 } 13005 13006 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13007 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13008 enforceNotIsolatedCaller("registerReceiver"); 13009 int callingUid; 13010 int callingPid; 13011 synchronized(this) { 13012 ProcessRecord callerApp = null; 13013 if (caller != null) { 13014 callerApp = getRecordForAppLocked(caller); 13015 if (callerApp == null) { 13016 throw new SecurityException( 13017 "Unable to find app for caller " + caller 13018 + " (pid=" + Binder.getCallingPid() 13019 + ") when registering receiver " + receiver); 13020 } 13021 if (callerApp.info.uid != Process.SYSTEM_UID && 13022 !callerApp.pkgList.containsKey(callerPackage) && 13023 !"android".equals(callerPackage)) { 13024 throw new SecurityException("Given caller package " + callerPackage 13025 + " is not running in process " + callerApp); 13026 } 13027 callingUid = callerApp.info.uid; 13028 callingPid = callerApp.pid; 13029 } else { 13030 callerPackage = null; 13031 callingUid = Binder.getCallingUid(); 13032 callingPid = Binder.getCallingPid(); 13033 } 13034 13035 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13036 true, true, "registerReceiver", callerPackage); 13037 13038 List allSticky = null; 13039 13040 // Look for any matching sticky broadcasts... 13041 Iterator actions = filter.actionsIterator(); 13042 if (actions != null) { 13043 while (actions.hasNext()) { 13044 String action = (String)actions.next(); 13045 allSticky = getStickiesLocked(action, filter, allSticky, 13046 UserHandle.USER_ALL); 13047 allSticky = getStickiesLocked(action, filter, allSticky, 13048 UserHandle.getUserId(callingUid)); 13049 } 13050 } else { 13051 allSticky = getStickiesLocked(null, filter, allSticky, 13052 UserHandle.USER_ALL); 13053 allSticky = getStickiesLocked(null, filter, allSticky, 13054 UserHandle.getUserId(callingUid)); 13055 } 13056 13057 // The first sticky in the list is returned directly back to 13058 // the client. 13059 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13060 13061 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13062 + ": " + sticky); 13063 13064 if (receiver == null) { 13065 return sticky; 13066 } 13067 13068 ReceiverList rl 13069 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13070 if (rl == null) { 13071 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13072 userId, receiver); 13073 if (rl.app != null) { 13074 rl.app.receivers.add(rl); 13075 } else { 13076 try { 13077 receiver.asBinder().linkToDeath(rl, 0); 13078 } catch (RemoteException e) { 13079 return sticky; 13080 } 13081 rl.linkedToDeath = true; 13082 } 13083 mRegisteredReceivers.put(receiver.asBinder(), rl); 13084 } else if (rl.uid != callingUid) { 13085 throw new IllegalArgumentException( 13086 "Receiver requested to register for uid " + callingUid 13087 + " was previously registered for uid " + rl.uid); 13088 } else if (rl.pid != callingPid) { 13089 throw new IllegalArgumentException( 13090 "Receiver requested to register for pid " + callingPid 13091 + " was previously registered for pid " + rl.pid); 13092 } else if (rl.userId != userId) { 13093 throw new IllegalArgumentException( 13094 "Receiver requested to register for user " + userId 13095 + " was previously registered for user " + rl.userId); 13096 } 13097 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13098 permission, callingUid, userId); 13099 rl.add(bf); 13100 if (!bf.debugCheck()) { 13101 Slog.w(TAG, "==> For Dynamic broadast"); 13102 } 13103 mReceiverResolver.addFilter(bf); 13104 13105 // Enqueue broadcasts for all existing stickies that match 13106 // this filter. 13107 if (allSticky != null) { 13108 ArrayList receivers = new ArrayList(); 13109 receivers.add(bf); 13110 13111 int N = allSticky.size(); 13112 for (int i=0; i<N; i++) { 13113 Intent intent = (Intent)allSticky.get(i); 13114 BroadcastQueue queue = broadcastQueueForIntent(intent); 13115 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13116 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13117 null, null, false, true, true, -1); 13118 queue.enqueueParallelBroadcastLocked(r); 13119 queue.scheduleBroadcastsLocked(); 13120 } 13121 } 13122 13123 return sticky; 13124 } 13125 } 13126 13127 public void unregisterReceiver(IIntentReceiver receiver) { 13128 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13129 13130 final long origId = Binder.clearCallingIdentity(); 13131 try { 13132 boolean doTrim = false; 13133 13134 synchronized(this) { 13135 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13136 if (rl != null) { 13137 if (rl.curBroadcast != null) { 13138 BroadcastRecord r = rl.curBroadcast; 13139 final boolean doNext = finishReceiverLocked( 13140 receiver.asBinder(), r.resultCode, r.resultData, 13141 r.resultExtras, r.resultAbort); 13142 if (doNext) { 13143 doTrim = true; 13144 r.queue.processNextBroadcast(false); 13145 } 13146 } 13147 13148 if (rl.app != null) { 13149 rl.app.receivers.remove(rl); 13150 } 13151 removeReceiverLocked(rl); 13152 if (rl.linkedToDeath) { 13153 rl.linkedToDeath = false; 13154 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13155 } 13156 } 13157 } 13158 13159 // If we actually concluded any broadcasts, we might now be able 13160 // to trim the recipients' apps from our working set 13161 if (doTrim) { 13162 trimApplications(); 13163 return; 13164 } 13165 13166 } finally { 13167 Binder.restoreCallingIdentity(origId); 13168 } 13169 } 13170 13171 void removeReceiverLocked(ReceiverList rl) { 13172 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13173 int N = rl.size(); 13174 for (int i=0; i<N; i++) { 13175 mReceiverResolver.removeFilter(rl.get(i)); 13176 } 13177 } 13178 13179 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13180 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13181 ProcessRecord r = mLruProcesses.get(i); 13182 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13183 try { 13184 r.thread.dispatchPackageBroadcast(cmd, packages); 13185 } catch (RemoteException ex) { 13186 } 13187 } 13188 } 13189 } 13190 13191 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13192 int[] users) { 13193 List<ResolveInfo> receivers = null; 13194 try { 13195 HashSet<ComponentName> singleUserReceivers = null; 13196 boolean scannedFirstReceivers = false; 13197 for (int user : users) { 13198 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13199 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13200 if (user != 0 && newReceivers != null) { 13201 // If this is not the primary user, we need to check for 13202 // any receivers that should be filtered out. 13203 for (int i=0; i<newReceivers.size(); i++) { 13204 ResolveInfo ri = newReceivers.get(i); 13205 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13206 newReceivers.remove(i); 13207 i--; 13208 } 13209 } 13210 } 13211 if (newReceivers != null && newReceivers.size() == 0) { 13212 newReceivers = null; 13213 } 13214 if (receivers == null) { 13215 receivers = newReceivers; 13216 } else if (newReceivers != null) { 13217 // We need to concatenate the additional receivers 13218 // found with what we have do far. This would be easy, 13219 // but we also need to de-dup any receivers that are 13220 // singleUser. 13221 if (!scannedFirstReceivers) { 13222 // Collect any single user receivers we had already retrieved. 13223 scannedFirstReceivers = true; 13224 for (int i=0; i<receivers.size(); i++) { 13225 ResolveInfo ri = receivers.get(i); 13226 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13227 ComponentName cn = new ComponentName( 13228 ri.activityInfo.packageName, ri.activityInfo.name); 13229 if (singleUserReceivers == null) { 13230 singleUserReceivers = new HashSet<ComponentName>(); 13231 } 13232 singleUserReceivers.add(cn); 13233 } 13234 } 13235 } 13236 // Add the new results to the existing results, tracking 13237 // and de-dupping single user receivers. 13238 for (int i=0; i<newReceivers.size(); i++) { 13239 ResolveInfo ri = newReceivers.get(i); 13240 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13241 ComponentName cn = new ComponentName( 13242 ri.activityInfo.packageName, ri.activityInfo.name); 13243 if (singleUserReceivers == null) { 13244 singleUserReceivers = new HashSet<ComponentName>(); 13245 } 13246 if (!singleUserReceivers.contains(cn)) { 13247 singleUserReceivers.add(cn); 13248 receivers.add(ri); 13249 } 13250 } else { 13251 receivers.add(ri); 13252 } 13253 } 13254 } 13255 } 13256 } catch (RemoteException ex) { 13257 // pm is in same process, this will never happen. 13258 } 13259 return receivers; 13260 } 13261 13262 private final int broadcastIntentLocked(ProcessRecord callerApp, 13263 String callerPackage, Intent intent, String resolvedType, 13264 IIntentReceiver resultTo, int resultCode, String resultData, 13265 Bundle map, String requiredPermission, int appOp, 13266 boolean ordered, boolean sticky, int callingPid, int callingUid, 13267 int userId) { 13268 intent = new Intent(intent); 13269 13270 // By default broadcasts do not go to stopped apps. 13271 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13272 13273 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13274 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13275 + " ordered=" + ordered + " userid=" + userId); 13276 if ((resultTo != null) && !ordered) { 13277 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13278 } 13279 13280 userId = handleIncomingUser(callingPid, callingUid, userId, 13281 true, false, "broadcast", callerPackage); 13282 13283 // Make sure that the user who is receiving this broadcast is started. 13284 // If not, we will just skip it. 13285 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13286 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13287 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13288 Slog.w(TAG, "Skipping broadcast of " + intent 13289 + ": user " + userId + " is stopped"); 13290 return ActivityManager.BROADCAST_SUCCESS; 13291 } 13292 } 13293 13294 /* 13295 * Prevent non-system code (defined here to be non-persistent 13296 * processes) from sending protected broadcasts. 13297 */ 13298 int callingAppId = UserHandle.getAppId(callingUid); 13299 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13300 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13301 callingUid == 0) { 13302 // Always okay. 13303 } else if (callerApp == null || !callerApp.persistent) { 13304 try { 13305 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13306 intent.getAction())) { 13307 String msg = "Permission Denial: not allowed to send broadcast " 13308 + intent.getAction() + " from pid=" 13309 + callingPid + ", uid=" + callingUid; 13310 Slog.w(TAG, msg); 13311 throw new SecurityException(msg); 13312 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13313 // Special case for compatibility: we don't want apps to send this, 13314 // but historically it has not been protected and apps may be using it 13315 // to poke their own app widget. So, instead of making it protected, 13316 // just limit it to the caller. 13317 if (callerApp == null) { 13318 String msg = "Permission Denial: not allowed to send broadcast " 13319 + intent.getAction() + " from unknown caller."; 13320 Slog.w(TAG, msg); 13321 throw new SecurityException(msg); 13322 } else if (intent.getComponent() != null) { 13323 // They are good enough to send to an explicit component... verify 13324 // it is being sent to the calling app. 13325 if (!intent.getComponent().getPackageName().equals( 13326 callerApp.info.packageName)) { 13327 String msg = "Permission Denial: not allowed to send broadcast " 13328 + intent.getAction() + " to " 13329 + intent.getComponent().getPackageName() + " from " 13330 + callerApp.info.packageName; 13331 Slog.w(TAG, msg); 13332 throw new SecurityException(msg); 13333 } 13334 } else { 13335 // Limit broadcast to their own package. 13336 intent.setPackage(callerApp.info.packageName); 13337 } 13338 } 13339 } catch (RemoteException e) { 13340 Slog.w(TAG, "Remote exception", e); 13341 return ActivityManager.BROADCAST_SUCCESS; 13342 } 13343 } 13344 13345 // Handle special intents: if this broadcast is from the package 13346 // manager about a package being removed, we need to remove all of 13347 // its activities from the history stack. 13348 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13349 intent.getAction()); 13350 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13351 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13352 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13353 || uidRemoved) { 13354 if (checkComponentPermission( 13355 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13356 callingPid, callingUid, -1, true) 13357 == PackageManager.PERMISSION_GRANTED) { 13358 if (uidRemoved) { 13359 final Bundle intentExtras = intent.getExtras(); 13360 final int uid = intentExtras != null 13361 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13362 if (uid >= 0) { 13363 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13364 synchronized (bs) { 13365 bs.removeUidStatsLocked(uid); 13366 } 13367 mAppOpsService.uidRemoved(uid); 13368 } 13369 } else { 13370 // If resources are unavailable just force stop all 13371 // those packages and flush the attribute cache as well. 13372 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13373 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13374 if (list != null && (list.length > 0)) { 13375 for (String pkg : list) { 13376 forceStopPackageLocked(pkg, -1, false, true, true, false, userId, 13377 "storage unmount"); 13378 } 13379 sendPackageBroadcastLocked( 13380 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13381 } 13382 } else { 13383 Uri data = intent.getData(); 13384 String ssp; 13385 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13386 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13387 intent.getAction()); 13388 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13389 forceStopPackageLocked(ssp, UserHandle.getAppId( 13390 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13391 false, userId, removed ? "pkg removed" : "pkg changed"); 13392 } 13393 if (removed) { 13394 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13395 new String[] {ssp}, userId); 13396 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13397 mAppOpsService.packageRemoved( 13398 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13399 13400 // Remove all permissions granted from/to this package 13401 removeUriPermissionsForPackageLocked(ssp, userId, true); 13402 } 13403 } 13404 } 13405 } 13406 } 13407 } else { 13408 String msg = "Permission Denial: " + intent.getAction() 13409 + " broadcast from " + callerPackage + " (pid=" + callingPid 13410 + ", uid=" + callingUid + ")" 13411 + " requires " 13412 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13413 Slog.w(TAG, msg); 13414 throw new SecurityException(msg); 13415 } 13416 13417 // Special case for adding a package: by default turn on compatibility 13418 // mode. 13419 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13420 Uri data = intent.getData(); 13421 String ssp; 13422 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13423 mCompatModePackages.handlePackageAddedLocked(ssp, 13424 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13425 } 13426 } 13427 13428 /* 13429 * If this is the time zone changed action, queue up a message that will reset the timezone 13430 * of all currently running processes. This message will get queued up before the broadcast 13431 * happens. 13432 */ 13433 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13434 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13435 } 13436 13437 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13438 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13439 } 13440 13441 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13442 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13443 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13444 } 13445 13446 // Add to the sticky list if requested. 13447 if (sticky) { 13448 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13449 callingPid, callingUid) 13450 != PackageManager.PERMISSION_GRANTED) { 13451 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13452 + callingPid + ", uid=" + callingUid 13453 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13454 Slog.w(TAG, msg); 13455 throw new SecurityException(msg); 13456 } 13457 if (requiredPermission != null) { 13458 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13459 + " and enforce permission " + requiredPermission); 13460 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13461 } 13462 if (intent.getComponent() != null) { 13463 throw new SecurityException( 13464 "Sticky broadcasts can't target a specific component"); 13465 } 13466 // We use userId directly here, since the "all" target is maintained 13467 // as a separate set of sticky broadcasts. 13468 if (userId != UserHandle.USER_ALL) { 13469 // But first, if this is not a broadcast to all users, then 13470 // make sure it doesn't conflict with an existing broadcast to 13471 // all users. 13472 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13473 UserHandle.USER_ALL); 13474 if (stickies != null) { 13475 ArrayList<Intent> list = stickies.get(intent.getAction()); 13476 if (list != null) { 13477 int N = list.size(); 13478 int i; 13479 for (i=0; i<N; i++) { 13480 if (intent.filterEquals(list.get(i))) { 13481 throw new IllegalArgumentException( 13482 "Sticky broadcast " + intent + " for user " 13483 + userId + " conflicts with existing global broadcast"); 13484 } 13485 } 13486 } 13487 } 13488 } 13489 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13490 if (stickies == null) { 13491 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13492 mStickyBroadcasts.put(userId, stickies); 13493 } 13494 ArrayList<Intent> list = stickies.get(intent.getAction()); 13495 if (list == null) { 13496 list = new ArrayList<Intent>(); 13497 stickies.put(intent.getAction(), list); 13498 } 13499 int N = list.size(); 13500 int i; 13501 for (i=0; i<N; i++) { 13502 if (intent.filterEquals(list.get(i))) { 13503 // This sticky already exists, replace it. 13504 list.set(i, new Intent(intent)); 13505 break; 13506 } 13507 } 13508 if (i >= N) { 13509 list.add(new Intent(intent)); 13510 } 13511 } 13512 13513 int[] users; 13514 if (userId == UserHandle.USER_ALL) { 13515 // Caller wants broadcast to go to all started users. 13516 users = mStartedUserArray; 13517 } else { 13518 // Caller wants broadcast to go to one specific user. 13519 users = new int[] {userId}; 13520 } 13521 13522 // Figure out who all will receive this broadcast. 13523 List receivers = null; 13524 List<BroadcastFilter> registeredReceivers = null; 13525 // Need to resolve the intent to interested receivers... 13526 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13527 == 0) { 13528 receivers = collectReceiverComponents(intent, resolvedType, users); 13529 } 13530 if (intent.getComponent() == null) { 13531 registeredReceivers = mReceiverResolver.queryIntent(intent, 13532 resolvedType, false, userId); 13533 } 13534 13535 final boolean replacePending = 13536 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13537 13538 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13539 + " replacePending=" + replacePending); 13540 13541 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13542 if (!ordered && NR > 0) { 13543 // If we are not serializing this broadcast, then send the 13544 // registered receivers separately so they don't wait for the 13545 // components to be launched. 13546 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13547 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13548 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13549 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13550 ordered, sticky, false, userId); 13551 if (DEBUG_BROADCAST) Slog.v( 13552 TAG, "Enqueueing parallel broadcast " + r); 13553 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13554 if (!replaced) { 13555 queue.enqueueParallelBroadcastLocked(r); 13556 queue.scheduleBroadcastsLocked(); 13557 } 13558 registeredReceivers = null; 13559 NR = 0; 13560 } 13561 13562 // Merge into one list. 13563 int ir = 0; 13564 if (receivers != null) { 13565 // A special case for PACKAGE_ADDED: do not allow the package 13566 // being added to see this broadcast. This prevents them from 13567 // using this as a back door to get run as soon as they are 13568 // installed. Maybe in the future we want to have a special install 13569 // broadcast or such for apps, but we'd like to deliberately make 13570 // this decision. 13571 String skipPackages[] = null; 13572 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13573 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13574 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13575 Uri data = intent.getData(); 13576 if (data != null) { 13577 String pkgName = data.getSchemeSpecificPart(); 13578 if (pkgName != null) { 13579 skipPackages = new String[] { pkgName }; 13580 } 13581 } 13582 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13583 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13584 } 13585 if (skipPackages != null && (skipPackages.length > 0)) { 13586 for (String skipPackage : skipPackages) { 13587 if (skipPackage != null) { 13588 int NT = receivers.size(); 13589 for (int it=0; it<NT; it++) { 13590 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13591 if (curt.activityInfo.packageName.equals(skipPackage)) { 13592 receivers.remove(it); 13593 it--; 13594 NT--; 13595 } 13596 } 13597 } 13598 } 13599 } 13600 13601 int NT = receivers != null ? receivers.size() : 0; 13602 int it = 0; 13603 ResolveInfo curt = null; 13604 BroadcastFilter curr = null; 13605 while (it < NT && ir < NR) { 13606 if (curt == null) { 13607 curt = (ResolveInfo)receivers.get(it); 13608 } 13609 if (curr == null) { 13610 curr = registeredReceivers.get(ir); 13611 } 13612 if (curr.getPriority() >= curt.priority) { 13613 // Insert this broadcast record into the final list. 13614 receivers.add(it, curr); 13615 ir++; 13616 curr = null; 13617 it++; 13618 NT++; 13619 } else { 13620 // Skip to the next ResolveInfo in the final list. 13621 it++; 13622 curt = null; 13623 } 13624 } 13625 } 13626 while (ir < NR) { 13627 if (receivers == null) { 13628 receivers = new ArrayList(); 13629 } 13630 receivers.add(registeredReceivers.get(ir)); 13631 ir++; 13632 } 13633 13634 if ((receivers != null && receivers.size() > 0) 13635 || resultTo != null) { 13636 BroadcastQueue queue = broadcastQueueForIntent(intent); 13637 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13638 callerPackage, callingPid, callingUid, resolvedType, 13639 requiredPermission, appOp, receivers, resultTo, resultCode, 13640 resultData, map, ordered, sticky, false, userId); 13641 if (DEBUG_BROADCAST) Slog.v( 13642 TAG, "Enqueueing ordered broadcast " + r 13643 + ": prev had " + queue.mOrderedBroadcasts.size()); 13644 if (DEBUG_BROADCAST) { 13645 int seq = r.intent.getIntExtra("seq", -1); 13646 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13647 } 13648 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13649 if (!replaced) { 13650 queue.enqueueOrderedBroadcastLocked(r); 13651 queue.scheduleBroadcastsLocked(); 13652 } 13653 } 13654 13655 return ActivityManager.BROADCAST_SUCCESS; 13656 } 13657 13658 final Intent verifyBroadcastLocked(Intent intent) { 13659 // Refuse possible leaked file descriptors 13660 if (intent != null && intent.hasFileDescriptors() == true) { 13661 throw new IllegalArgumentException("File descriptors passed in Intent"); 13662 } 13663 13664 int flags = intent.getFlags(); 13665 13666 if (!mProcessesReady) { 13667 // if the caller really truly claims to know what they're doing, go 13668 // ahead and allow the broadcast without launching any receivers 13669 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13670 intent = new Intent(intent); 13671 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13672 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13673 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13674 + " before boot completion"); 13675 throw new IllegalStateException("Cannot broadcast before boot completed"); 13676 } 13677 } 13678 13679 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13680 throw new IllegalArgumentException( 13681 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13682 } 13683 13684 return intent; 13685 } 13686 13687 public final int broadcastIntent(IApplicationThread caller, 13688 Intent intent, String resolvedType, IIntentReceiver resultTo, 13689 int resultCode, String resultData, Bundle map, 13690 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13691 enforceNotIsolatedCaller("broadcastIntent"); 13692 synchronized(this) { 13693 intent = verifyBroadcastLocked(intent); 13694 13695 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13696 final int callingPid = Binder.getCallingPid(); 13697 final int callingUid = Binder.getCallingUid(); 13698 final long origId = Binder.clearCallingIdentity(); 13699 int res = broadcastIntentLocked(callerApp, 13700 callerApp != null ? callerApp.info.packageName : null, 13701 intent, resolvedType, resultTo, 13702 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13703 callingPid, callingUid, userId); 13704 Binder.restoreCallingIdentity(origId); 13705 return res; 13706 } 13707 } 13708 13709 int broadcastIntentInPackage(String packageName, int uid, 13710 Intent intent, String resolvedType, IIntentReceiver resultTo, 13711 int resultCode, String resultData, Bundle map, 13712 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13713 synchronized(this) { 13714 intent = verifyBroadcastLocked(intent); 13715 13716 final long origId = Binder.clearCallingIdentity(); 13717 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13718 resultTo, resultCode, resultData, map, requiredPermission, 13719 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13720 Binder.restoreCallingIdentity(origId); 13721 return res; 13722 } 13723 } 13724 13725 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13726 // Refuse possible leaked file descriptors 13727 if (intent != null && intent.hasFileDescriptors() == true) { 13728 throw new IllegalArgumentException("File descriptors passed in Intent"); 13729 } 13730 13731 userId = handleIncomingUser(Binder.getCallingPid(), 13732 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13733 13734 synchronized(this) { 13735 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13736 != PackageManager.PERMISSION_GRANTED) { 13737 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13738 + Binder.getCallingPid() 13739 + ", uid=" + Binder.getCallingUid() 13740 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13741 Slog.w(TAG, msg); 13742 throw new SecurityException(msg); 13743 } 13744 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13745 if (stickies != null) { 13746 ArrayList<Intent> list = stickies.get(intent.getAction()); 13747 if (list != null) { 13748 int N = list.size(); 13749 int i; 13750 for (i=0; i<N; i++) { 13751 if (intent.filterEquals(list.get(i))) { 13752 list.remove(i); 13753 break; 13754 } 13755 } 13756 if (list.size() <= 0) { 13757 stickies.remove(intent.getAction()); 13758 } 13759 } 13760 if (stickies.size() <= 0) { 13761 mStickyBroadcasts.remove(userId); 13762 } 13763 } 13764 } 13765 } 13766 13767 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13768 String resultData, Bundle resultExtras, boolean resultAbort) { 13769 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13770 if (r == null) { 13771 Slog.w(TAG, "finishReceiver called but not found on queue"); 13772 return false; 13773 } 13774 13775 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13776 } 13777 13778 void backgroundServicesFinishedLocked(int userId) { 13779 for (BroadcastQueue queue : mBroadcastQueues) { 13780 queue.backgroundServicesFinishedLocked(userId); 13781 } 13782 } 13783 13784 public void finishReceiver(IBinder who, int resultCode, String resultData, 13785 Bundle resultExtras, boolean resultAbort) { 13786 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13787 13788 // Refuse possible leaked file descriptors 13789 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13790 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13791 } 13792 13793 final long origId = Binder.clearCallingIdentity(); 13794 try { 13795 boolean doNext = false; 13796 BroadcastRecord r; 13797 13798 synchronized(this) { 13799 r = broadcastRecordForReceiverLocked(who); 13800 if (r != null) { 13801 doNext = r.queue.finishReceiverLocked(r, resultCode, 13802 resultData, resultExtras, resultAbort, true); 13803 } 13804 } 13805 13806 if (doNext) { 13807 r.queue.processNextBroadcast(false); 13808 } 13809 trimApplications(); 13810 } finally { 13811 Binder.restoreCallingIdentity(origId); 13812 } 13813 } 13814 13815 // ========================================================= 13816 // INSTRUMENTATION 13817 // ========================================================= 13818 13819 public boolean startInstrumentation(ComponentName className, 13820 String profileFile, int flags, Bundle arguments, 13821 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13822 int userId) { 13823 enforceNotIsolatedCaller("startInstrumentation"); 13824 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13825 userId, false, true, "startInstrumentation", null); 13826 // Refuse possible leaked file descriptors 13827 if (arguments != null && arguments.hasFileDescriptors()) { 13828 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13829 } 13830 13831 synchronized(this) { 13832 InstrumentationInfo ii = null; 13833 ApplicationInfo ai = null; 13834 try { 13835 ii = mContext.getPackageManager().getInstrumentationInfo( 13836 className, STOCK_PM_FLAGS); 13837 ai = AppGlobals.getPackageManager().getApplicationInfo( 13838 ii.targetPackage, STOCK_PM_FLAGS, userId); 13839 } catch (PackageManager.NameNotFoundException e) { 13840 } catch (RemoteException e) { 13841 } 13842 if (ii == null) { 13843 reportStartInstrumentationFailure(watcher, className, 13844 "Unable to find instrumentation info for: " + className); 13845 return false; 13846 } 13847 if (ai == null) { 13848 reportStartInstrumentationFailure(watcher, className, 13849 "Unable to find instrumentation target package: " + ii.targetPackage); 13850 return false; 13851 } 13852 13853 int match = mContext.getPackageManager().checkSignatures( 13854 ii.targetPackage, ii.packageName); 13855 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13856 String msg = "Permission Denial: starting instrumentation " 13857 + className + " from pid=" 13858 + Binder.getCallingPid() 13859 + ", uid=" + Binder.getCallingPid() 13860 + " not allowed because package " + ii.packageName 13861 + " does not have a signature matching the target " 13862 + ii.targetPackage; 13863 reportStartInstrumentationFailure(watcher, className, msg); 13864 throw new SecurityException(msg); 13865 } 13866 13867 final long origId = Binder.clearCallingIdentity(); 13868 // Instrumentation can kill and relaunch even persistent processes 13869 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId, 13870 "start instr"); 13871 ProcessRecord app = addAppLocked(ai, false); 13872 app.instrumentationClass = className; 13873 app.instrumentationInfo = ai; 13874 app.instrumentationProfileFile = profileFile; 13875 app.instrumentationArguments = arguments; 13876 app.instrumentationWatcher = watcher; 13877 app.instrumentationUiAutomationConnection = uiAutomationConnection; 13878 app.instrumentationResultClass = className; 13879 Binder.restoreCallingIdentity(origId); 13880 } 13881 13882 return true; 13883 } 13884 13885 /** 13886 * Report errors that occur while attempting to start Instrumentation. Always writes the 13887 * error to the logs, but if somebody is watching, send the report there too. This enables 13888 * the "am" command to report errors with more information. 13889 * 13890 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13891 * @param cn The component name of the instrumentation. 13892 * @param report The error report. 13893 */ 13894 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13895 ComponentName cn, String report) { 13896 Slog.w(TAG, report); 13897 try { 13898 if (watcher != null) { 13899 Bundle results = new Bundle(); 13900 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13901 results.putString("Error", report); 13902 watcher.instrumentationStatus(cn, -1, results); 13903 } 13904 } catch (RemoteException e) { 13905 Slog.w(TAG, e); 13906 } 13907 } 13908 13909 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13910 if (app.instrumentationWatcher != null) { 13911 try { 13912 // NOTE: IInstrumentationWatcher *must* be oneway here 13913 app.instrumentationWatcher.instrumentationFinished( 13914 app.instrumentationClass, 13915 resultCode, 13916 results); 13917 } catch (RemoteException e) { 13918 } 13919 } 13920 if (app.instrumentationUiAutomationConnection != null) { 13921 try { 13922 app.instrumentationUiAutomationConnection.shutdown(); 13923 } catch (RemoteException re) { 13924 /* ignore */ 13925 } 13926 // Only a UiAutomation can set this flag and now that 13927 // it is finished we make sure it is reset to its default. 13928 mUserIsMonkey = false; 13929 } 13930 app.instrumentationWatcher = null; 13931 app.instrumentationUiAutomationConnection = null; 13932 app.instrumentationClass = null; 13933 app.instrumentationInfo = null; 13934 app.instrumentationProfileFile = null; 13935 app.instrumentationArguments = null; 13936 13937 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId, 13938 "finished inst"); 13939 } 13940 13941 public void finishInstrumentation(IApplicationThread target, 13942 int resultCode, Bundle results) { 13943 int userId = UserHandle.getCallingUserId(); 13944 // Refuse possible leaked file descriptors 13945 if (results != null && results.hasFileDescriptors()) { 13946 throw new IllegalArgumentException("File descriptors passed in Intent"); 13947 } 13948 13949 synchronized(this) { 13950 ProcessRecord app = getRecordForAppLocked(target); 13951 if (app == null) { 13952 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13953 return; 13954 } 13955 final long origId = Binder.clearCallingIdentity(); 13956 finishInstrumentationLocked(app, resultCode, results); 13957 Binder.restoreCallingIdentity(origId); 13958 } 13959 } 13960 13961 // ========================================================= 13962 // CONFIGURATION 13963 // ========================================================= 13964 13965 public ConfigurationInfo getDeviceConfigurationInfo() { 13966 ConfigurationInfo config = new ConfigurationInfo(); 13967 synchronized (this) { 13968 config.reqTouchScreen = mConfiguration.touchscreen; 13969 config.reqKeyboardType = mConfiguration.keyboard; 13970 config.reqNavigation = mConfiguration.navigation; 13971 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13972 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13973 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13974 } 13975 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13976 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13977 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13978 } 13979 config.reqGlEsVersion = GL_ES_VERSION; 13980 } 13981 return config; 13982 } 13983 13984 ActivityStack getFocusedStack() { 13985 return mStackSupervisor.getFocusedStack(); 13986 } 13987 13988 public Configuration getConfiguration() { 13989 Configuration ci; 13990 synchronized(this) { 13991 ci = new Configuration(mConfiguration); 13992 } 13993 return ci; 13994 } 13995 13996 public void updatePersistentConfiguration(Configuration values) { 13997 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13998 "updateConfiguration()"); 13999 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14000 "updateConfiguration()"); 14001 if (values == null) { 14002 throw new NullPointerException("Configuration must not be null"); 14003 } 14004 14005 synchronized(this) { 14006 final long origId = Binder.clearCallingIdentity(); 14007 updateConfigurationLocked(values, null, true, false); 14008 Binder.restoreCallingIdentity(origId); 14009 } 14010 } 14011 14012 public void updateConfiguration(Configuration values) { 14013 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14014 "updateConfiguration()"); 14015 14016 synchronized(this) { 14017 if (values == null && mWindowManager != null) { 14018 // sentinel: fetch the current configuration from the window manager 14019 values = mWindowManager.computeNewConfiguration(); 14020 } 14021 14022 if (mWindowManager != null) { 14023 mProcessList.applyDisplaySize(mWindowManager); 14024 } 14025 14026 final long origId = Binder.clearCallingIdentity(); 14027 if (values != null) { 14028 Settings.System.clearConfiguration(values); 14029 } 14030 updateConfigurationLocked(values, null, false, false); 14031 Binder.restoreCallingIdentity(origId); 14032 } 14033 } 14034 14035 /** 14036 * Do either or both things: (1) change the current configuration, and (2) 14037 * make sure the given activity is running with the (now) current 14038 * configuration. Returns true if the activity has been left running, or 14039 * false if <var>starting</var> is being destroyed to match the new 14040 * configuration. 14041 * @param persistent TODO 14042 */ 14043 boolean updateConfigurationLocked(Configuration values, 14044 ActivityRecord starting, boolean persistent, boolean initLocale) { 14045 // do nothing if we are headless 14046 if (mHeadless) return true; 14047 14048 int changes = 0; 14049 14050 if (values != null) { 14051 Configuration newConfig = new Configuration(mConfiguration); 14052 changes = newConfig.updateFrom(values); 14053 if (changes != 0) { 14054 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14055 Slog.i(TAG, "Updating configuration to: " + values); 14056 } 14057 14058 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14059 14060 if (values.locale != null && !initLocale) { 14061 saveLocaleLocked(values.locale, 14062 !values.locale.equals(mConfiguration.locale), 14063 values.userSetLocale); 14064 } 14065 14066 mConfigurationSeq++; 14067 if (mConfigurationSeq <= 0) { 14068 mConfigurationSeq = 1; 14069 } 14070 newConfig.seq = mConfigurationSeq; 14071 mConfiguration = newConfig; 14072 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14073 14074 final Configuration configCopy = new Configuration(mConfiguration); 14075 14076 // TODO: If our config changes, should we auto dismiss any currently 14077 // showing dialogs? 14078 mShowDialogs = shouldShowDialogs(newConfig); 14079 14080 AttributeCache ac = AttributeCache.instance(); 14081 if (ac != null) { 14082 ac.updateConfiguration(configCopy); 14083 } 14084 14085 // Make sure all resources in our process are updated 14086 // right now, so that anyone who is going to retrieve 14087 // resource values after we return will be sure to get 14088 // the new ones. This is especially important during 14089 // boot, where the first config change needs to guarantee 14090 // all resources have that config before following boot 14091 // code is executed. 14092 mSystemThread.applyConfigurationToResources(configCopy); 14093 14094 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14095 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14096 msg.obj = new Configuration(configCopy); 14097 mHandler.sendMessage(msg); 14098 } 14099 14100 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14101 ProcessRecord app = mLruProcesses.get(i); 14102 try { 14103 if (app.thread != null) { 14104 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14105 + app.processName + " new config " + mConfiguration); 14106 app.thread.scheduleConfigurationChanged(configCopy); 14107 } 14108 } catch (Exception e) { 14109 } 14110 } 14111 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14112 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14113 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14114 | Intent.FLAG_RECEIVER_FOREGROUND); 14115 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14116 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14117 Process.SYSTEM_UID, UserHandle.USER_ALL); 14118 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14119 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14120 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14121 broadcastIntentLocked(null, null, intent, 14122 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14123 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14124 } 14125 } 14126 } 14127 14128 boolean kept = true; 14129 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14130 if (changes != 0 && starting == null) { 14131 // If the configuration changed, and the caller is not already 14132 // in the process of starting an activity, then find the top 14133 // activity to check if its configuration needs to change. 14134 starting = mainStack.topRunningActivityLocked(null); 14135 } 14136 14137 if (starting != null) { 14138 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14139 // And we need to make sure at this point that all other activities 14140 // are made visible with the correct configuration. 14141 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14142 } 14143 14144 if (values != null && mWindowManager != null) { 14145 mWindowManager.setNewConfiguration(mConfiguration); 14146 } 14147 14148 return kept; 14149 } 14150 14151 /** 14152 * Decide based on the configuration whether we should shouw the ANR, 14153 * crash, etc dialogs. The idea is that if there is no affordnace to 14154 * press the on-screen buttons, we shouldn't show the dialog. 14155 * 14156 * A thought: SystemUI might also want to get told about this, the Power 14157 * dialog / global actions also might want different behaviors. 14158 */ 14159 private static final boolean shouldShowDialogs(Configuration config) { 14160 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14161 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14162 } 14163 14164 /** 14165 * Save the locale. You must be inside a synchronized (this) block. 14166 */ 14167 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14168 if(isDiff) { 14169 SystemProperties.set("user.language", l.getLanguage()); 14170 SystemProperties.set("user.region", l.getCountry()); 14171 } 14172 14173 if(isPersist) { 14174 SystemProperties.set("persist.sys.language", l.getLanguage()); 14175 SystemProperties.set("persist.sys.country", l.getCountry()); 14176 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14177 } 14178 } 14179 14180 @Override 14181 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14182 ActivityRecord srec = ActivityRecord.forToken(token); 14183 return srec != null && srec.task.affinity != null && 14184 srec.task.affinity.equals(destAffinity); 14185 } 14186 14187 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14188 Intent resultData) { 14189 14190 synchronized (this) { 14191 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14192 if (stack != null) { 14193 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14194 } 14195 return false; 14196 } 14197 } 14198 14199 public int getLaunchedFromUid(IBinder activityToken) { 14200 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14201 if (srec == null) { 14202 return -1; 14203 } 14204 return srec.launchedFromUid; 14205 } 14206 14207 public String getLaunchedFromPackage(IBinder activityToken) { 14208 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14209 if (srec == null) { 14210 return null; 14211 } 14212 return srec.launchedFromPackage; 14213 } 14214 14215 // ========================================================= 14216 // LIFETIME MANAGEMENT 14217 // ========================================================= 14218 14219 // Returns which broadcast queue the app is the current [or imminent] receiver 14220 // on, or 'null' if the app is not an active broadcast recipient. 14221 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14222 BroadcastRecord r = app.curReceiver; 14223 if (r != null) { 14224 return r.queue; 14225 } 14226 14227 // It's not the current receiver, but it might be starting up to become one 14228 synchronized (this) { 14229 for (BroadcastQueue queue : mBroadcastQueues) { 14230 r = queue.mPendingBroadcast; 14231 if (r != null && r.curApp == app) { 14232 // found it; report which queue it's in 14233 return queue; 14234 } 14235 } 14236 } 14237 14238 return null; 14239 } 14240 14241 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14242 boolean doingAll, long now) { 14243 if (mAdjSeq == app.adjSeq) { 14244 // This adjustment has already been computed. 14245 return app.curRawAdj; 14246 } 14247 14248 if (app.thread == null) { 14249 app.adjSeq = mAdjSeq; 14250 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14251 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14252 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14253 } 14254 14255 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14256 app.adjSource = null; 14257 app.adjTarget = null; 14258 app.empty = false; 14259 app.cached = false; 14260 14261 final int activitiesSize = app.activities.size(); 14262 14263 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14264 // The max adjustment doesn't allow this app to be anything 14265 // below foreground, so it is not worth doing work for it. 14266 app.adjType = "fixed"; 14267 app.adjSeq = mAdjSeq; 14268 app.curRawAdj = app.maxAdj; 14269 app.foregroundActivities = false; 14270 app.keeping = true; 14271 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14272 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14273 // System process can do UI, and when they do we want to have 14274 // them trim their memory after the user leaves the UI. To 14275 // facilitate this, here we need to determine whether or not it 14276 // is currently showing UI. 14277 app.systemNoUi = true; 14278 if (app == TOP_APP) { 14279 app.systemNoUi = false; 14280 } else if (activitiesSize > 0) { 14281 for (int j = 0; j < activitiesSize; j++) { 14282 final ActivityRecord r = app.activities.get(j); 14283 if (r.visible) { 14284 app.systemNoUi = false; 14285 } 14286 } 14287 } 14288 if (!app.systemNoUi) { 14289 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14290 } 14291 return (app.curAdj=app.maxAdj); 14292 } 14293 14294 app.keeping = false; 14295 app.systemNoUi = false; 14296 14297 // Determine the importance of the process, starting with most 14298 // important to least, and assign an appropriate OOM adjustment. 14299 int adj; 14300 int schedGroup; 14301 int procState; 14302 boolean foregroundActivities = false; 14303 boolean interesting = false; 14304 BroadcastQueue queue; 14305 if (app == TOP_APP) { 14306 // The last app on the list is the foreground app. 14307 adj = ProcessList.FOREGROUND_APP_ADJ; 14308 schedGroup = Process.THREAD_GROUP_DEFAULT; 14309 app.adjType = "top-activity"; 14310 foregroundActivities = true; 14311 interesting = true; 14312 procState = ActivityManager.PROCESS_STATE_TOP; 14313 } else if (app.instrumentationClass != null) { 14314 // Don't want to kill running instrumentation. 14315 adj = ProcessList.FOREGROUND_APP_ADJ; 14316 schedGroup = Process.THREAD_GROUP_DEFAULT; 14317 app.adjType = "instrumentation"; 14318 interesting = true; 14319 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14320 } else if ((queue = isReceivingBroadcast(app)) != null) { 14321 // An app that is currently receiving a broadcast also 14322 // counts as being in the foreground for OOM killer purposes. 14323 // It's placed in a sched group based on the nature of the 14324 // broadcast as reflected by which queue it's active in. 14325 adj = ProcessList.FOREGROUND_APP_ADJ; 14326 schedGroup = (queue == mFgBroadcastQueue) 14327 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14328 app.adjType = "broadcast"; 14329 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14330 } else if (app.executingServices.size() > 0) { 14331 // An app that is currently executing a service callback also 14332 // counts as being in the foreground. 14333 adj = ProcessList.FOREGROUND_APP_ADJ; 14334 schedGroup = app.execServicesFg ? 14335 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14336 app.adjType = "exec-service"; 14337 procState = ActivityManager.PROCESS_STATE_SERVICE; 14338 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14339 } else { 14340 // As far as we know the process is empty. We may change our mind later. 14341 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14342 // At this point we don't actually know the adjustment. Use the cached adj 14343 // value that the caller wants us to. 14344 adj = cachedAdj; 14345 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14346 app.cached = true; 14347 app.empty = true; 14348 app.adjType = "cch-empty"; 14349 } 14350 14351 // Examine all activities if not already foreground. 14352 if (!foregroundActivities && activitiesSize > 0) { 14353 for (int j = 0; j < activitiesSize; j++) { 14354 final ActivityRecord r = app.activities.get(j); 14355 if (r.app != app) { 14356 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14357 + app + "?!?"); 14358 continue; 14359 } 14360 if (r.visible) { 14361 // App has a visible activity; only upgrade adjustment. 14362 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14363 adj = ProcessList.VISIBLE_APP_ADJ; 14364 app.adjType = "visible"; 14365 } 14366 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14367 procState = ActivityManager.PROCESS_STATE_TOP; 14368 } 14369 schedGroup = Process.THREAD_GROUP_DEFAULT; 14370 app.cached = false; 14371 app.empty = false; 14372 foregroundActivities = true; 14373 break; 14374 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14375 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14376 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14377 app.adjType = "pausing"; 14378 } 14379 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14380 procState = ActivityManager.PROCESS_STATE_TOP; 14381 } 14382 schedGroup = Process.THREAD_GROUP_DEFAULT; 14383 app.cached = false; 14384 app.empty = false; 14385 foregroundActivities = true; 14386 } else if (r.state == ActivityState.STOPPING) { 14387 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14388 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14389 app.adjType = "stopping"; 14390 } 14391 // For the process state, we will at this point consider the 14392 // process to be cached. It will be cached either as an activity 14393 // or empty depending on whether the activity is finishing. We do 14394 // this so that we can treat the process as cached for purposes of 14395 // memory trimming (determing current memory level, trim command to 14396 // send to process) since there can be an arbitrary number of stopping 14397 // processes and they should soon all go into the cached state. 14398 if (!r.finishing) { 14399 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14400 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14401 } 14402 } 14403 app.cached = false; 14404 app.empty = false; 14405 foregroundActivities = true; 14406 } else { 14407 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14408 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14409 app.adjType = "cch-act"; 14410 } 14411 } 14412 } 14413 } 14414 14415 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14416 if (app.foregroundServices) { 14417 // The user is aware of this app, so make it visible. 14418 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14419 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14420 app.cached = false; 14421 app.adjType = "fg-service"; 14422 schedGroup = Process.THREAD_GROUP_DEFAULT; 14423 } else if (app.forcingToForeground != null) { 14424 // The user is aware of this app, so make it visible. 14425 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14426 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14427 app.cached = false; 14428 app.adjType = "force-fg"; 14429 app.adjSource = app.forcingToForeground; 14430 schedGroup = Process.THREAD_GROUP_DEFAULT; 14431 } 14432 } 14433 14434 if (app.foregroundServices) { 14435 interesting = true; 14436 } 14437 14438 if (app == mHeavyWeightProcess) { 14439 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14440 // We don't want to kill the current heavy-weight process. 14441 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14442 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14443 app.cached = false; 14444 app.adjType = "heavy"; 14445 } 14446 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14447 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14448 } 14449 } 14450 14451 if (app == mHomeProcess) { 14452 if (adj > ProcessList.HOME_APP_ADJ) { 14453 // This process is hosting what we currently consider to be the 14454 // home app, so we don't want to let it go into the background. 14455 adj = ProcessList.HOME_APP_ADJ; 14456 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14457 app.cached = false; 14458 app.adjType = "home"; 14459 } 14460 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14461 procState = ActivityManager.PROCESS_STATE_HOME; 14462 } 14463 } 14464 14465 if (app == mPreviousProcess && app.activities.size() > 0) { 14466 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14467 // This was the previous process that showed UI to the user. 14468 // We want to try to keep it around more aggressively, to give 14469 // a good experience around switching between two apps. 14470 adj = ProcessList.PREVIOUS_APP_ADJ; 14471 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14472 app.cached = false; 14473 app.adjType = "previous"; 14474 } 14475 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14476 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14477 } 14478 } 14479 14480 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14481 + " reason=" + app.adjType); 14482 14483 // By default, we use the computed adjustment. It may be changed if 14484 // there are applications dependent on our services or providers, but 14485 // this gives us a baseline and makes sure we don't get into an 14486 // infinite recursion. 14487 app.adjSeq = mAdjSeq; 14488 app.curRawAdj = adj; 14489 app.hasStartedServices = false; 14490 14491 if (mBackupTarget != null && app == mBackupTarget.app) { 14492 // If possible we want to avoid killing apps while they're being backed up 14493 if (adj > ProcessList.BACKUP_APP_ADJ) { 14494 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14495 adj = ProcessList.BACKUP_APP_ADJ; 14496 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14497 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14498 } 14499 app.adjType = "backup"; 14500 app.cached = false; 14501 } 14502 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14503 procState = ActivityManager.PROCESS_STATE_BACKUP; 14504 } 14505 } 14506 14507 boolean mayBeTop = false; 14508 14509 for (int is = app.services.size()-1; 14510 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14511 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14512 || procState > ActivityManager.PROCESS_STATE_TOP); 14513 is--) { 14514 ServiceRecord s = app.services.valueAt(is); 14515 if (s.startRequested) { 14516 app.hasStartedServices = true; 14517 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14518 procState = ActivityManager.PROCESS_STATE_SERVICE; 14519 } 14520 if (app.hasShownUi && app != mHomeProcess) { 14521 // If this process has shown some UI, let it immediately 14522 // go to the LRU list because it may be pretty heavy with 14523 // UI stuff. We'll tag it with a label just to help 14524 // debug and understand what is going on. 14525 if (adj > ProcessList.SERVICE_ADJ) { 14526 app.adjType = "cch-started-ui-services"; 14527 } 14528 } else { 14529 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14530 // This service has seen some activity within 14531 // recent memory, so we will keep its process ahead 14532 // of the background processes. 14533 if (adj > ProcessList.SERVICE_ADJ) { 14534 adj = ProcessList.SERVICE_ADJ; 14535 app.adjType = "started-services"; 14536 app.cached = false; 14537 } 14538 } 14539 // If we have let the service slide into the background 14540 // state, still have some text describing what it is doing 14541 // even though the service no longer has an impact. 14542 if (adj > ProcessList.SERVICE_ADJ) { 14543 app.adjType = "cch-started-services"; 14544 } 14545 } 14546 // Don't kill this process because it is doing work; it 14547 // has said it is doing work. 14548 app.keeping = true; 14549 } 14550 for (int conni = s.connections.size()-1; 14551 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14552 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14553 || procState > ActivityManager.PROCESS_STATE_TOP); 14554 conni--) { 14555 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14556 for (int i = 0; 14557 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14558 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14559 || procState > ActivityManager.PROCESS_STATE_TOP); 14560 i++) { 14561 // XXX should compute this based on the max of 14562 // all connected clients. 14563 ConnectionRecord cr = clist.get(i); 14564 if (cr.binding.client == app) { 14565 // Binding to ourself is not interesting. 14566 continue; 14567 } 14568 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14569 ProcessRecord client = cr.binding.client; 14570 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14571 TOP_APP, doingAll, now); 14572 int clientProcState = client.curProcState; 14573 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14574 // If the other app is cached for any reason, for purposes here 14575 // we are going to consider it empty. The specific cached state 14576 // doesn't propagate except under certain conditions. 14577 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14578 } 14579 String adjType = null; 14580 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14581 // Not doing bind OOM management, so treat 14582 // this guy more like a started service. 14583 if (app.hasShownUi && app != mHomeProcess) { 14584 // If this process has shown some UI, let it immediately 14585 // go to the LRU list because it may be pretty heavy with 14586 // UI stuff. We'll tag it with a label just to help 14587 // debug and understand what is going on. 14588 if (adj > clientAdj) { 14589 adjType = "cch-bound-ui-services"; 14590 } 14591 app.cached = false; 14592 clientAdj = adj; 14593 clientProcState = procState; 14594 } else { 14595 if (now >= (s.lastActivity 14596 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14597 // This service has not seen activity within 14598 // recent memory, so allow it to drop to the 14599 // LRU list if there is no other reason to keep 14600 // it around. We'll also tag it with a label just 14601 // to help debug and undertand what is going on. 14602 if (adj > clientAdj) { 14603 adjType = "cch-bound-services"; 14604 } 14605 clientAdj = adj; 14606 } 14607 } 14608 } 14609 if (adj > clientAdj) { 14610 // If this process has recently shown UI, and 14611 // the process that is binding to it is less 14612 // important than being visible, then we don't 14613 // care about the binding as much as we care 14614 // about letting this process get into the LRU 14615 // list to be killed and restarted if needed for 14616 // memory. 14617 if (app.hasShownUi && app != mHomeProcess 14618 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14619 adjType = "cch-bound-ui-services"; 14620 } else { 14621 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14622 |Context.BIND_IMPORTANT)) != 0) { 14623 adj = clientAdj; 14624 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14625 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14626 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14627 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14628 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14629 adj = clientAdj; 14630 } else { 14631 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14632 adj = ProcessList.VISIBLE_APP_ADJ; 14633 } 14634 } 14635 if (!client.cached) { 14636 app.cached = false; 14637 } 14638 if (client.keeping) { 14639 app.keeping = true; 14640 } 14641 adjType = "service"; 14642 } 14643 } 14644 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14645 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14646 schedGroup = Process.THREAD_GROUP_DEFAULT; 14647 } 14648 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14649 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14650 // Special handling of clients who are in the top state. 14651 // We *may* want to consider this process to be in the 14652 // top state as well, but only if there is not another 14653 // reason for it to be running. Being on the top is a 14654 // special state, meaning you are specifically running 14655 // for the current top app. If the process is already 14656 // running in the background for some other reason, it 14657 // is more important to continue considering it to be 14658 // in the background state. 14659 mayBeTop = true; 14660 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14661 } else { 14662 // Special handling for above-top states (persistent 14663 // processes). These should not bring the current process 14664 // into the top state, since they are not on top. Instead 14665 // give them the best state after that. 14666 clientProcState = 14667 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14668 } 14669 } 14670 } else { 14671 if (clientProcState < 14672 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14673 clientProcState = 14674 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14675 } 14676 } 14677 if (procState > clientProcState) { 14678 procState = clientProcState; 14679 } 14680 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14681 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14682 app.pendingUiClean = true; 14683 } 14684 if (adjType != null) { 14685 app.adjType = adjType; 14686 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14687 .REASON_SERVICE_IN_USE; 14688 app.adjSource = cr.binding.client; 14689 app.adjSourceOom = clientAdj; 14690 app.adjTarget = s.name; 14691 } 14692 } 14693 final ActivityRecord a = cr.activity; 14694 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14695 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14696 (a.visible || a.state == ActivityState.RESUMED 14697 || a.state == ActivityState.PAUSING)) { 14698 adj = ProcessList.FOREGROUND_APP_ADJ; 14699 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14700 schedGroup = Process.THREAD_GROUP_DEFAULT; 14701 } 14702 app.cached = false; 14703 app.adjType = "service"; 14704 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14705 .REASON_SERVICE_IN_USE; 14706 app.adjSource = a; 14707 app.adjSourceOom = adj; 14708 app.adjTarget = s.name; 14709 } 14710 } 14711 } 14712 } 14713 } 14714 14715 for (int provi = app.pubProviders.size()-1; 14716 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14717 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14718 || procState > ActivityManager.PROCESS_STATE_TOP); 14719 provi--) { 14720 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14721 for (int i = cpr.connections.size()-1; 14722 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14723 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14724 || procState > ActivityManager.PROCESS_STATE_TOP); 14725 i--) { 14726 ContentProviderConnection conn = cpr.connections.get(i); 14727 ProcessRecord client = conn.client; 14728 if (client == app) { 14729 // Being our own client is not interesting. 14730 continue; 14731 } 14732 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14733 int clientProcState = client.curProcState; 14734 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14735 // If the other app is cached for any reason, for purposes here 14736 // we are going to consider it empty. 14737 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14738 } 14739 if (adj > clientAdj) { 14740 if (app.hasShownUi && app != mHomeProcess 14741 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14742 app.adjType = "cch-ui-provider"; 14743 } else { 14744 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14745 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14746 app.adjType = "provider"; 14747 } 14748 app.cached &= client.cached; 14749 app.keeping |= client.keeping; 14750 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14751 .REASON_PROVIDER_IN_USE; 14752 app.adjSource = client; 14753 app.adjSourceOom = clientAdj; 14754 app.adjTarget = cpr.name; 14755 } 14756 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14757 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14758 // Special handling of clients who are in the top state. 14759 // We *may* want to consider this process to be in the 14760 // top state as well, but only if there is not another 14761 // reason for it to be running. Being on the top is a 14762 // special state, meaning you are specifically running 14763 // for the current top app. If the process is already 14764 // running in the background for some other reason, it 14765 // is more important to continue considering it to be 14766 // in the background state. 14767 mayBeTop = true; 14768 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14769 } else { 14770 // Special handling for above-top states (persistent 14771 // processes). These should not bring the current process 14772 // into the top state, since they are not on top. Instead 14773 // give them the best state after that. 14774 clientProcState = 14775 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14776 } 14777 } 14778 if (procState > clientProcState) { 14779 procState = clientProcState; 14780 } 14781 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14782 schedGroup = Process.THREAD_GROUP_DEFAULT; 14783 } 14784 } 14785 // If the provider has external (non-framework) process 14786 // dependencies, ensure that its adjustment is at least 14787 // FOREGROUND_APP_ADJ. 14788 if (cpr.hasExternalProcessHandles()) { 14789 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14790 adj = ProcessList.FOREGROUND_APP_ADJ; 14791 schedGroup = Process.THREAD_GROUP_DEFAULT; 14792 app.cached = false; 14793 app.keeping = true; 14794 app.adjType = "provider"; 14795 app.adjTarget = cpr.name; 14796 } 14797 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14798 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14799 } 14800 } 14801 } 14802 14803 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14804 // A client of one of our services or providers is in the top state. We 14805 // *may* want to be in the top state, but not if we are already running in 14806 // the background for some other reason. For the decision here, we are going 14807 // to pick out a few specific states that we want to remain in when a client 14808 // is top (states that tend to be longer-term) and otherwise allow it to go 14809 // to the top state. 14810 switch (procState) { 14811 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14812 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14813 case ActivityManager.PROCESS_STATE_SERVICE: 14814 // These all are longer-term states, so pull them up to the top 14815 // of the background states, but not all the way to the top state. 14816 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14817 break; 14818 default: 14819 // Otherwise, top is a better choice, so take it. 14820 procState = ActivityManager.PROCESS_STATE_TOP; 14821 break; 14822 } 14823 } 14824 14825 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14826 // This is a cached process, but with client activities. Mark it so. 14827 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14828 app.adjType = "cch-client-act"; 14829 } 14830 14831 if (adj == ProcessList.SERVICE_ADJ) { 14832 if (doingAll) { 14833 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14834 mNewNumServiceProcs++; 14835 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14836 if (!app.serviceb) { 14837 // This service isn't far enough down on the LRU list to 14838 // normally be a B service, but if we are low on RAM and it 14839 // is large we want to force it down since we would prefer to 14840 // keep launcher over it. 14841 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14842 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14843 app.serviceHighRam = true; 14844 app.serviceb = true; 14845 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14846 } else { 14847 mNewNumAServiceProcs++; 14848 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14849 } 14850 } else { 14851 app.serviceHighRam = false; 14852 } 14853 } 14854 if (app.serviceb) { 14855 adj = ProcessList.SERVICE_B_ADJ; 14856 } 14857 } 14858 14859 app.curRawAdj = adj; 14860 14861 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14862 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14863 if (adj > app.maxAdj) { 14864 adj = app.maxAdj; 14865 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 14866 schedGroup = Process.THREAD_GROUP_DEFAULT; 14867 } 14868 } 14869 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 14870 app.keeping = true; 14871 } 14872 14873 // Do final modification to adj. Everything we do between here and applying 14874 // the final setAdj must be done in this function, because we will also use 14875 // it when computing the final cached adj later. Note that we don't need to 14876 // worry about this for max adj above, since max adj will always be used to 14877 // keep it out of the cached vaues. 14878 adj = app.modifyRawOomAdj(adj); 14879 14880 app.curProcState = procState; 14881 14882 int importance = app.memImportance; 14883 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 14884 app.curAdj = adj; 14885 app.curSchedGroup = schedGroup; 14886 if (!interesting) { 14887 // For this reporting, if there is not something explicitly 14888 // interesting in this process then we will push it to the 14889 // background importance. 14890 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14891 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 14892 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14893 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 14894 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14895 } else if (adj >= ProcessList.HOME_APP_ADJ) { 14896 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 14897 } else if (adj >= ProcessList.SERVICE_ADJ) { 14898 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 14899 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14900 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 14901 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 14902 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 14903 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 14904 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 14905 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 14906 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 14907 } else { 14908 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 14909 } 14910 } 14911 14912 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 14913 if (foregroundActivities != app.foregroundActivities) { 14914 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 14915 } 14916 if (changes != 0) { 14917 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 14918 app.memImportance = importance; 14919 app.foregroundActivities = foregroundActivities; 14920 int i = mPendingProcessChanges.size()-1; 14921 ProcessChangeItem item = null; 14922 while (i >= 0) { 14923 item = mPendingProcessChanges.get(i); 14924 if (item.pid == app.pid) { 14925 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 14926 break; 14927 } 14928 i--; 14929 } 14930 if (i < 0) { 14931 // No existing item in pending changes; need a new one. 14932 final int NA = mAvailProcessChanges.size(); 14933 if (NA > 0) { 14934 item = mAvailProcessChanges.remove(NA-1); 14935 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 14936 } else { 14937 item = new ProcessChangeItem(); 14938 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 14939 } 14940 item.changes = 0; 14941 item.pid = app.pid; 14942 item.uid = app.info.uid; 14943 if (mPendingProcessChanges.size() == 0) { 14944 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 14945 "*** Enqueueing dispatch processes changed!"); 14946 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 14947 } 14948 mPendingProcessChanges.add(item); 14949 } 14950 item.changes |= changes; 14951 item.importance = importance; 14952 item.foregroundActivities = foregroundActivities; 14953 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 14954 + Integer.toHexString(System.identityHashCode(item)) 14955 + " " + app.toShortString() + ": changes=" + item.changes 14956 + " importance=" + item.importance 14957 + " foreground=" + item.foregroundActivities 14958 + " type=" + app.adjType + " source=" + app.adjSource 14959 + " target=" + app.adjTarget); 14960 } 14961 14962 return app.curRawAdj; 14963 } 14964 14965 /** 14966 * Schedule PSS collection of a process. 14967 */ 14968 void requestPssLocked(ProcessRecord proc, int procState) { 14969 if (mPendingPssProcesses.contains(proc)) { 14970 return; 14971 } 14972 if (mPendingPssProcesses.size() == 0) { 14973 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 14974 } 14975 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 14976 proc.pssProcState = procState; 14977 mPendingPssProcesses.add(proc); 14978 } 14979 14980 /** 14981 * Schedule PSS collection of all processes. 14982 */ 14983 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 14984 if (!always) { 14985 if (now < (mLastFullPssTime + 14986 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 14987 return; 14988 } 14989 } 14990 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 14991 mLastFullPssTime = now; 14992 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 14993 mPendingPssProcesses.clear(); 14994 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14995 ProcessRecord app = mLruProcesses.get(i); 14996 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 14997 app.pssProcState = app.setProcState; 14998 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 14999 mSleeping, now); 15000 mPendingPssProcesses.add(app); 15001 } 15002 } 15003 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15004 } 15005 15006 /** 15007 * Ask a given process to GC right now. 15008 */ 15009 final void performAppGcLocked(ProcessRecord app) { 15010 try { 15011 app.lastRequestedGc = SystemClock.uptimeMillis(); 15012 if (app.thread != null) { 15013 if (app.reportLowMemory) { 15014 app.reportLowMemory = false; 15015 app.thread.scheduleLowMemory(); 15016 } else { 15017 app.thread.processInBackground(); 15018 } 15019 } 15020 } catch (Exception e) { 15021 // whatever. 15022 } 15023 } 15024 15025 /** 15026 * Returns true if things are idle enough to perform GCs. 15027 */ 15028 private final boolean canGcNowLocked() { 15029 boolean processingBroadcasts = false; 15030 for (BroadcastQueue q : mBroadcastQueues) { 15031 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15032 processingBroadcasts = true; 15033 } 15034 } 15035 return !processingBroadcasts 15036 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15037 } 15038 15039 /** 15040 * Perform GCs on all processes that are waiting for it, but only 15041 * if things are idle. 15042 */ 15043 final void performAppGcsLocked() { 15044 final int N = mProcessesToGc.size(); 15045 if (N <= 0) { 15046 return; 15047 } 15048 if (canGcNowLocked()) { 15049 while (mProcessesToGc.size() > 0) { 15050 ProcessRecord proc = mProcessesToGc.remove(0); 15051 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15052 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15053 <= SystemClock.uptimeMillis()) { 15054 // To avoid spamming the system, we will GC processes one 15055 // at a time, waiting a few seconds between each. 15056 performAppGcLocked(proc); 15057 scheduleAppGcsLocked(); 15058 return; 15059 } else { 15060 // It hasn't been long enough since we last GCed this 15061 // process... put it in the list to wait for its time. 15062 addProcessToGcListLocked(proc); 15063 break; 15064 } 15065 } 15066 } 15067 15068 scheduleAppGcsLocked(); 15069 } 15070 } 15071 15072 /** 15073 * If all looks good, perform GCs on all processes waiting for them. 15074 */ 15075 final void performAppGcsIfAppropriateLocked() { 15076 if (canGcNowLocked()) { 15077 performAppGcsLocked(); 15078 return; 15079 } 15080 // Still not idle, wait some more. 15081 scheduleAppGcsLocked(); 15082 } 15083 15084 /** 15085 * Schedule the execution of all pending app GCs. 15086 */ 15087 final void scheduleAppGcsLocked() { 15088 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15089 15090 if (mProcessesToGc.size() > 0) { 15091 // Schedule a GC for the time to the next process. 15092 ProcessRecord proc = mProcessesToGc.get(0); 15093 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15094 15095 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15096 long now = SystemClock.uptimeMillis(); 15097 if (when < (now+GC_TIMEOUT)) { 15098 when = now + GC_TIMEOUT; 15099 } 15100 mHandler.sendMessageAtTime(msg, when); 15101 } 15102 } 15103 15104 /** 15105 * Add a process to the array of processes waiting to be GCed. Keeps the 15106 * list in sorted order by the last GC time. The process can't already be 15107 * on the list. 15108 */ 15109 final void addProcessToGcListLocked(ProcessRecord proc) { 15110 boolean added = false; 15111 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15112 if (mProcessesToGc.get(i).lastRequestedGc < 15113 proc.lastRequestedGc) { 15114 added = true; 15115 mProcessesToGc.add(i+1, proc); 15116 break; 15117 } 15118 } 15119 if (!added) { 15120 mProcessesToGc.add(0, proc); 15121 } 15122 } 15123 15124 /** 15125 * Set up to ask a process to GC itself. This will either do it 15126 * immediately, or put it on the list of processes to gc the next 15127 * time things are idle. 15128 */ 15129 final void scheduleAppGcLocked(ProcessRecord app) { 15130 long now = SystemClock.uptimeMillis(); 15131 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15132 return; 15133 } 15134 if (!mProcessesToGc.contains(app)) { 15135 addProcessToGcListLocked(app); 15136 scheduleAppGcsLocked(); 15137 } 15138 } 15139 15140 final void checkExcessivePowerUsageLocked(boolean doKills) { 15141 updateCpuStatsNow(); 15142 15143 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15144 boolean doWakeKills = doKills; 15145 boolean doCpuKills = doKills; 15146 if (mLastPowerCheckRealtime == 0) { 15147 doWakeKills = false; 15148 } 15149 if (mLastPowerCheckUptime == 0) { 15150 doCpuKills = false; 15151 } 15152 if (stats.isScreenOn()) { 15153 doWakeKills = false; 15154 } 15155 final long curRealtime = SystemClock.elapsedRealtime(); 15156 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15157 final long curUptime = SystemClock.uptimeMillis(); 15158 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15159 mLastPowerCheckRealtime = curRealtime; 15160 mLastPowerCheckUptime = curUptime; 15161 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15162 doWakeKills = false; 15163 } 15164 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15165 doCpuKills = false; 15166 } 15167 int i = mLruProcesses.size(); 15168 while (i > 0) { 15169 i--; 15170 ProcessRecord app = mLruProcesses.get(i); 15171 if (!app.keeping) { 15172 long wtime; 15173 synchronized (stats) { 15174 wtime = stats.getProcessWakeTime(app.info.uid, 15175 app.pid, curRealtime); 15176 } 15177 long wtimeUsed = wtime - app.lastWakeTime; 15178 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15179 if (DEBUG_POWER) { 15180 StringBuilder sb = new StringBuilder(128); 15181 sb.append("Wake for "); 15182 app.toShortString(sb); 15183 sb.append(": over "); 15184 TimeUtils.formatDuration(realtimeSince, sb); 15185 sb.append(" used "); 15186 TimeUtils.formatDuration(wtimeUsed, sb); 15187 sb.append(" ("); 15188 sb.append((wtimeUsed*100)/realtimeSince); 15189 sb.append("%)"); 15190 Slog.i(TAG, sb.toString()); 15191 sb.setLength(0); 15192 sb.append("CPU for "); 15193 app.toShortString(sb); 15194 sb.append(": over "); 15195 TimeUtils.formatDuration(uptimeSince, sb); 15196 sb.append(" used "); 15197 TimeUtils.formatDuration(cputimeUsed, sb); 15198 sb.append(" ("); 15199 sb.append((cputimeUsed*100)/uptimeSince); 15200 sb.append("%)"); 15201 Slog.i(TAG, sb.toString()); 15202 } 15203 // If a process has held a wake lock for more 15204 // than 50% of the time during this period, 15205 // that sounds bad. Kill! 15206 if (doWakeKills && realtimeSince > 0 15207 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15208 synchronized (stats) { 15209 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15210 realtimeSince, wtimeUsed); 15211 } 15212 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15213 + " during " + realtimeSince); 15214 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15215 } else if (doCpuKills && uptimeSince > 0 15216 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15217 synchronized (stats) { 15218 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15219 uptimeSince, cputimeUsed); 15220 } 15221 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15222 + " during " + uptimeSince); 15223 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15224 } else { 15225 app.lastWakeTime = wtime; 15226 app.lastCpuTime = app.curCpuTime; 15227 } 15228 } 15229 } 15230 } 15231 15232 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15233 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15234 boolean success = true; 15235 15236 if (app.curRawAdj != app.setRawAdj) { 15237 if (wasKeeping && !app.keeping) { 15238 // This app is no longer something we want to keep. Note 15239 // its current wake lock time to later know to kill it if 15240 // it is not behaving well. 15241 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15242 synchronized (stats) { 15243 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15244 app.pid, SystemClock.elapsedRealtime()); 15245 } 15246 app.lastCpuTime = app.curCpuTime; 15247 } 15248 15249 app.setRawAdj = app.curRawAdj; 15250 } 15251 15252 if (app.curAdj != app.setAdj) { 15253 if (Process.setOomAdj(app.pid, app.curAdj)) { 15254 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15255 TAG, "Set " + app.pid + " " + app.processName + 15256 " adj " + app.curAdj + ": " + app.adjType); 15257 app.setAdj = app.curAdj; 15258 } else { 15259 success = false; 15260 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj); 15261 } 15262 } 15263 if (app.setSchedGroup != app.curSchedGroup) { 15264 app.setSchedGroup = app.curSchedGroup; 15265 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15266 "Setting process group of " + app.processName 15267 + " to " + app.curSchedGroup); 15268 if (app.waitingToKill != null && 15269 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15270 killUnneededProcessLocked(app, app.waitingToKill); 15271 success = false; 15272 } else { 15273 if (true) { 15274 long oldId = Binder.clearCallingIdentity(); 15275 try { 15276 Process.setProcessGroup(app.pid, app.curSchedGroup); 15277 } catch (Exception e) { 15278 Slog.w(TAG, "Failed setting process group of " + app.pid 15279 + " to " + app.curSchedGroup); 15280 e.printStackTrace(); 15281 } finally { 15282 Binder.restoreCallingIdentity(oldId); 15283 } 15284 } else { 15285 if (app.thread != null) { 15286 try { 15287 app.thread.setSchedulingGroup(app.curSchedGroup); 15288 } catch (RemoteException e) { 15289 } 15290 } 15291 } 15292 Process.setSwappiness(app.pid, 15293 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15294 } 15295 } 15296 if (app.repProcState != app.curProcState) { 15297 app.repProcState = app.curProcState; 15298 if (!reportingProcessState && app.thread != null) { 15299 try { 15300 if (false) { 15301 //RuntimeException h = new RuntimeException("here"); 15302 Slog.i(TAG, "Sending new process state " + app.repProcState 15303 + " to " + app /*, h*/); 15304 } 15305 app.thread.setProcessState(app.repProcState); 15306 } catch (RemoteException e) { 15307 } 15308 } 15309 } 15310 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15311 app.setProcState)) { 15312 app.lastStateTime = now; 15313 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15314 mSleeping, now); 15315 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15316 + ProcessList.makeProcStateString(app.setProcState) + " to " 15317 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15318 + (app.nextPssTime-now) + ": " + app); 15319 } else { 15320 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15321 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15322 requestPssLocked(app, app.setProcState); 15323 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15324 mSleeping, now); 15325 } else if (false && DEBUG_PSS) { 15326 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15327 } 15328 } 15329 if (app.setProcState != app.curProcState) { 15330 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15331 "Proc state change of " + app.processName 15332 + " to " + app.curProcState); 15333 app.setProcState = app.curProcState; 15334 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15335 app.notCachedSinceIdle = false; 15336 } 15337 if (!doingAll) { 15338 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15339 } else { 15340 app.procStateChanged = true; 15341 } 15342 } 15343 return success; 15344 } 15345 15346 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15347 if (proc.thread != null && proc.baseProcessTracker != null) { 15348 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15349 } 15350 } 15351 15352 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15353 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15354 if (app.thread == null) { 15355 return false; 15356 } 15357 15358 final boolean wasKeeping = app.keeping; 15359 15360 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15361 15362 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15363 reportingProcessState, now); 15364 } 15365 15366 private final ActivityRecord resumedAppLocked() { 15367 return mStackSupervisor.resumedAppLocked(); 15368 } 15369 15370 final boolean updateOomAdjLocked(ProcessRecord app) { 15371 return updateOomAdjLocked(app, false); 15372 } 15373 15374 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15375 final ActivityRecord TOP_ACT = resumedAppLocked(); 15376 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15377 final boolean wasCached = app.cached; 15378 15379 mAdjSeq++; 15380 15381 // This is the desired cached adjusment we want to tell it to use. 15382 // If our app is currently cached, we know it, and that is it. Otherwise, 15383 // we don't know it yet, and it needs to now be cached we will then 15384 // need to do a complete oom adj. 15385 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15386 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15387 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15388 SystemClock.uptimeMillis()); 15389 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15390 // Changed to/from cached state, so apps after it in the LRU 15391 // list may also be changed. 15392 updateOomAdjLocked(); 15393 } 15394 return success; 15395 } 15396 15397 final void updateOomAdjLocked() { 15398 final ActivityRecord TOP_ACT = resumedAppLocked(); 15399 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15400 final long now = SystemClock.uptimeMillis(); 15401 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15402 final int N = mLruProcesses.size(); 15403 15404 if (false) { 15405 RuntimeException e = new RuntimeException(); 15406 e.fillInStackTrace(); 15407 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15408 } 15409 15410 mAdjSeq++; 15411 mNewNumServiceProcs = 0; 15412 mNewNumAServiceProcs = 0; 15413 15414 final int emptyProcessLimit; 15415 final int cachedProcessLimit; 15416 if (mProcessLimit <= 0) { 15417 emptyProcessLimit = cachedProcessLimit = 0; 15418 } else if (mProcessLimit == 1) { 15419 emptyProcessLimit = 1; 15420 cachedProcessLimit = 0; 15421 } else { 15422 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15423 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15424 } 15425 15426 // Let's determine how many processes we have running vs. 15427 // how many slots we have for background processes; we may want 15428 // to put multiple processes in a slot of there are enough of 15429 // them. 15430 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15431 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15432 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15433 if (numEmptyProcs > cachedProcessLimit) { 15434 // If there are more empty processes than our limit on cached 15435 // processes, then use the cached process limit for the factor. 15436 // This ensures that the really old empty processes get pushed 15437 // down to the bottom, so if we are running low on memory we will 15438 // have a better chance at keeping around more cached processes 15439 // instead of a gazillion empty processes. 15440 numEmptyProcs = cachedProcessLimit; 15441 } 15442 int emptyFactor = numEmptyProcs/numSlots; 15443 if (emptyFactor < 1) emptyFactor = 1; 15444 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15445 if (cachedFactor < 1) cachedFactor = 1; 15446 int stepCached = 0; 15447 int stepEmpty = 0; 15448 int numCached = 0; 15449 int numEmpty = 0; 15450 int numTrimming = 0; 15451 15452 mNumNonCachedProcs = 0; 15453 mNumCachedHiddenProcs = 0; 15454 15455 // First update the OOM adjustment for each of the 15456 // application processes based on their current state. 15457 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15458 int nextCachedAdj = curCachedAdj+1; 15459 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15460 int nextEmptyAdj = curEmptyAdj+2; 15461 for (int i=N-1; i>=0; i--) { 15462 ProcessRecord app = mLruProcesses.get(i); 15463 if (!app.killedByAm && app.thread != null) { 15464 app.procStateChanged = false; 15465 final boolean wasKeeping = app.keeping; 15466 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15467 15468 // If we haven't yet assigned the final cached adj 15469 // to the process, do that now. 15470 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15471 switch (app.curProcState) { 15472 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15473 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15474 // This process is a cached process holding activities... 15475 // assign it the next cached value for that type, and then 15476 // step that cached level. 15477 app.curRawAdj = curCachedAdj; 15478 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15479 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15480 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15481 + ")"); 15482 if (curCachedAdj != nextCachedAdj) { 15483 stepCached++; 15484 if (stepCached >= cachedFactor) { 15485 stepCached = 0; 15486 curCachedAdj = nextCachedAdj; 15487 nextCachedAdj += 2; 15488 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15489 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15490 } 15491 } 15492 } 15493 break; 15494 default: 15495 // For everything else, assign next empty cached process 15496 // level and bump that up. Note that this means that 15497 // long-running services that have dropped down to the 15498 // cached level will be treated as empty (since their process 15499 // state is still as a service), which is what we want. 15500 app.curRawAdj = curEmptyAdj; 15501 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15502 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15503 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15504 + ")"); 15505 if (curEmptyAdj != nextEmptyAdj) { 15506 stepEmpty++; 15507 if (stepEmpty >= emptyFactor) { 15508 stepEmpty = 0; 15509 curEmptyAdj = nextEmptyAdj; 15510 nextEmptyAdj += 2; 15511 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15512 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15513 } 15514 } 15515 } 15516 break; 15517 } 15518 } 15519 15520 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15521 15522 // Count the number of process types. 15523 switch (app.curProcState) { 15524 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15525 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15526 mNumCachedHiddenProcs++; 15527 numCached++; 15528 if (numCached > cachedProcessLimit) { 15529 killUnneededProcessLocked(app, "cached #" + numCached); 15530 } 15531 break; 15532 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15533 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15534 && app.lastActivityTime < oldTime) { 15535 killUnneededProcessLocked(app, "empty for " 15536 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15537 / 1000) + "s"); 15538 } else { 15539 numEmpty++; 15540 if (numEmpty > emptyProcessLimit) { 15541 killUnneededProcessLocked(app, "empty #" + numEmpty); 15542 } 15543 } 15544 break; 15545 default: 15546 mNumNonCachedProcs++; 15547 break; 15548 } 15549 15550 if (app.isolated && app.services.size() <= 0) { 15551 // If this is an isolated process, and there are no 15552 // services running in it, then the process is no longer 15553 // needed. We agressively kill these because we can by 15554 // definition not re-use the same process again, and it is 15555 // good to avoid having whatever code was running in them 15556 // left sitting around after no longer needed. 15557 killUnneededProcessLocked(app, "isolated not needed"); 15558 } 15559 15560 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15561 && !app.killedByAm) { 15562 numTrimming++; 15563 } 15564 } 15565 } 15566 15567 mNumServiceProcs = mNewNumServiceProcs; 15568 15569 // Now determine the memory trimming level of background processes. 15570 // Unfortunately we need to start at the back of the list to do this 15571 // properly. We only do this if the number of background apps we 15572 // are managing to keep around is less than half the maximum we desire; 15573 // if we are keeping a good number around, we'll let them use whatever 15574 // memory they want. 15575 final int numCachedAndEmpty = numCached + numEmpty; 15576 int memFactor; 15577 if (numCached <= ProcessList.TRIM_CACHED_APPS 15578 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15579 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15580 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15581 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15582 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15583 } else { 15584 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15585 } 15586 } else { 15587 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15588 } 15589 // We always allow the memory level to go up (better). We only allow it to go 15590 // down if we are in a state where that is allowed, *and* the total number of processes 15591 // has gone down since last time. 15592 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15593 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15594 + " last=" + mLastNumProcesses); 15595 if (memFactor > mLastMemoryLevel) { 15596 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15597 memFactor = mLastMemoryLevel; 15598 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15599 } 15600 } 15601 mLastMemoryLevel = memFactor; 15602 mLastNumProcesses = mLruProcesses.size(); 15603 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15604 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15605 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15606 if (mLowRamStartTime == 0) { 15607 mLowRamStartTime = now; 15608 } 15609 int step = 0; 15610 int fgTrimLevel; 15611 switch (memFactor) { 15612 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15613 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15614 break; 15615 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15616 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15617 break; 15618 default: 15619 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15620 break; 15621 } 15622 int factor = numTrimming/3; 15623 int minFactor = 2; 15624 if (mHomeProcess != null) minFactor++; 15625 if (mPreviousProcess != null) minFactor++; 15626 if (factor < minFactor) factor = minFactor; 15627 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15628 for (int i=N-1; i>=0; i--) { 15629 ProcessRecord app = mLruProcesses.get(i); 15630 if (allChanged || app.procStateChanged) { 15631 setProcessTrackerState(app, trackerMemFactor, now); 15632 app.procStateChanged = false; 15633 } 15634 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15635 && !app.killedByAm) { 15636 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15637 try { 15638 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15639 "Trimming memory of " + app.processName 15640 + " to " + curLevel); 15641 app.thread.scheduleTrimMemory(curLevel); 15642 } catch (RemoteException e) { 15643 } 15644 if (false) { 15645 // For now we won't do this; our memory trimming seems 15646 // to be good enough at this point that destroying 15647 // activities causes more harm than good. 15648 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15649 && app != mHomeProcess && app != mPreviousProcess) { 15650 // Need to do this on its own message because the stack may not 15651 // be in a consistent state at this point. 15652 // For these apps we will also finish their activities 15653 // to help them free memory. 15654 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15655 } 15656 } 15657 } 15658 app.trimMemoryLevel = curLevel; 15659 step++; 15660 if (step >= factor) { 15661 step = 0; 15662 switch (curLevel) { 15663 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15664 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15665 break; 15666 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15667 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15668 break; 15669 } 15670 } 15671 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15672 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15673 && app.thread != null) { 15674 try { 15675 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15676 "Trimming memory of heavy-weight " + app.processName 15677 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15678 app.thread.scheduleTrimMemory( 15679 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15680 } catch (RemoteException e) { 15681 } 15682 } 15683 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15684 } else { 15685 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15686 || app.systemNoUi) && app.pendingUiClean) { 15687 // If this application is now in the background and it 15688 // had done UI, then give it the special trim level to 15689 // have it free UI resources. 15690 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15691 if (app.trimMemoryLevel < level && app.thread != null) { 15692 try { 15693 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15694 "Trimming memory of bg-ui " + app.processName 15695 + " to " + level); 15696 app.thread.scheduleTrimMemory(level); 15697 } catch (RemoteException e) { 15698 } 15699 } 15700 app.pendingUiClean = false; 15701 } 15702 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15703 try { 15704 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15705 "Trimming memory of fg " + app.processName 15706 + " to " + fgTrimLevel); 15707 app.thread.scheduleTrimMemory(fgTrimLevel); 15708 } catch (RemoteException e) { 15709 } 15710 } 15711 app.trimMemoryLevel = fgTrimLevel; 15712 } 15713 } 15714 } else { 15715 if (mLowRamStartTime != 0) { 15716 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15717 mLowRamStartTime = 0; 15718 } 15719 for (int i=N-1; i>=0; i--) { 15720 ProcessRecord app = mLruProcesses.get(i); 15721 if (allChanged || app.procStateChanged) { 15722 setProcessTrackerState(app, trackerMemFactor, now); 15723 app.procStateChanged = false; 15724 } 15725 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15726 || app.systemNoUi) && app.pendingUiClean) { 15727 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15728 && app.thread != null) { 15729 try { 15730 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15731 "Trimming memory of ui hidden " + app.processName 15732 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15733 app.thread.scheduleTrimMemory( 15734 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15735 } catch (RemoteException e) { 15736 } 15737 } 15738 app.pendingUiClean = false; 15739 } 15740 app.trimMemoryLevel = 0; 15741 } 15742 } 15743 15744 if (mAlwaysFinishActivities) { 15745 // Need to do this on its own message because the stack may not 15746 // be in a consistent state at this point. 15747 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15748 } 15749 15750 if (allChanged) { 15751 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15752 } 15753 15754 if (mProcessStats.shouldWriteNowLocked(now)) { 15755 mHandler.post(new Runnable() { 15756 @Override public void run() { 15757 synchronized (ActivityManagerService.this) { 15758 mProcessStats.writeStateAsyncLocked(); 15759 } 15760 } 15761 }); 15762 } 15763 15764 if (DEBUG_OOM_ADJ) { 15765 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15766 } 15767 } 15768 15769 final void trimApplications() { 15770 synchronized (this) { 15771 int i; 15772 15773 // First remove any unused application processes whose package 15774 // has been removed. 15775 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15776 final ProcessRecord app = mRemovedProcesses.get(i); 15777 if (app.activities.size() == 0 15778 && app.curReceiver == null && app.services.size() == 0) { 15779 Slog.i( 15780 TAG, "Exiting empty application process " 15781 + app.processName + " (" 15782 + (app.thread != null ? app.thread.asBinder() : null) 15783 + ")\n"); 15784 if (app.pid > 0 && app.pid != MY_PID) { 15785 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15786 app.processName, app.setAdj, "empty"); 15787 app.killedByAm = true; 15788 Process.killProcessQuiet(app.pid); 15789 } else { 15790 try { 15791 app.thread.scheduleExit(); 15792 } catch (Exception e) { 15793 // Ignore exceptions. 15794 } 15795 } 15796 cleanUpApplicationRecordLocked(app, false, true, -1); 15797 mRemovedProcesses.remove(i); 15798 15799 if (app.persistent) { 15800 if (app.persistent) { 15801 addAppLocked(app.info, false); 15802 } 15803 } 15804 } 15805 } 15806 15807 // Now update the oom adj for all processes. 15808 updateOomAdjLocked(); 15809 } 15810 } 15811 15812 /** This method sends the specified signal to each of the persistent apps */ 15813 public void signalPersistentProcesses(int sig) throws RemoteException { 15814 if (sig != Process.SIGNAL_USR1) { 15815 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 15816 } 15817 15818 synchronized (this) { 15819 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 15820 != PackageManager.PERMISSION_GRANTED) { 15821 throw new SecurityException("Requires permission " 15822 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 15823 } 15824 15825 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15826 ProcessRecord r = mLruProcesses.get(i); 15827 if (r.thread != null && r.persistent) { 15828 Process.sendSignal(r.pid, sig); 15829 } 15830 } 15831 } 15832 } 15833 15834 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 15835 if (proc == null || proc == mProfileProc) { 15836 proc = mProfileProc; 15837 path = mProfileFile; 15838 profileType = mProfileType; 15839 clearProfilerLocked(); 15840 } 15841 if (proc == null) { 15842 return; 15843 } 15844 try { 15845 proc.thread.profilerControl(false, path, null, profileType); 15846 } catch (RemoteException e) { 15847 throw new IllegalStateException("Process disappeared"); 15848 } 15849 } 15850 15851 private void clearProfilerLocked() { 15852 if (mProfileFd != null) { 15853 try { 15854 mProfileFd.close(); 15855 } catch (IOException e) { 15856 } 15857 } 15858 mProfileApp = null; 15859 mProfileProc = null; 15860 mProfileFile = null; 15861 mProfileType = 0; 15862 mAutoStopProfiler = false; 15863 } 15864 15865 public boolean profileControl(String process, int userId, boolean start, 15866 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 15867 15868 try { 15869 synchronized (this) { 15870 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15871 // its own permission. 15872 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15873 != PackageManager.PERMISSION_GRANTED) { 15874 throw new SecurityException("Requires permission " 15875 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15876 } 15877 15878 if (start && fd == null) { 15879 throw new IllegalArgumentException("null fd"); 15880 } 15881 15882 ProcessRecord proc = null; 15883 if (process != null) { 15884 proc = findProcessLocked(process, userId, "profileControl"); 15885 } 15886 15887 if (start && (proc == null || proc.thread == null)) { 15888 throw new IllegalArgumentException("Unknown process: " + process); 15889 } 15890 15891 if (start) { 15892 stopProfilerLocked(null, null, 0); 15893 setProfileApp(proc.info, proc.processName, path, fd, false); 15894 mProfileProc = proc; 15895 mProfileType = profileType; 15896 try { 15897 fd = fd.dup(); 15898 } catch (IOException e) { 15899 fd = null; 15900 } 15901 proc.thread.profilerControl(start, path, fd, profileType); 15902 fd = null; 15903 mProfileFd = null; 15904 } else { 15905 stopProfilerLocked(proc, path, profileType); 15906 if (fd != null) { 15907 try { 15908 fd.close(); 15909 } catch (IOException e) { 15910 } 15911 } 15912 } 15913 15914 return true; 15915 } 15916 } catch (RemoteException e) { 15917 throw new IllegalStateException("Process disappeared"); 15918 } finally { 15919 if (fd != null) { 15920 try { 15921 fd.close(); 15922 } catch (IOException e) { 15923 } 15924 } 15925 } 15926 } 15927 15928 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 15929 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15930 userId, true, true, callName, null); 15931 ProcessRecord proc = null; 15932 try { 15933 int pid = Integer.parseInt(process); 15934 synchronized (mPidsSelfLocked) { 15935 proc = mPidsSelfLocked.get(pid); 15936 } 15937 } catch (NumberFormatException e) { 15938 } 15939 15940 if (proc == null) { 15941 ArrayMap<String, SparseArray<ProcessRecord>> all 15942 = mProcessNames.getMap(); 15943 SparseArray<ProcessRecord> procs = all.get(process); 15944 if (procs != null && procs.size() > 0) { 15945 proc = procs.valueAt(0); 15946 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 15947 for (int i=1; i<procs.size(); i++) { 15948 ProcessRecord thisProc = procs.valueAt(i); 15949 if (thisProc.userId == userId) { 15950 proc = thisProc; 15951 break; 15952 } 15953 } 15954 } 15955 } 15956 } 15957 15958 return proc; 15959 } 15960 15961 public boolean dumpHeap(String process, int userId, boolean managed, 15962 String path, ParcelFileDescriptor fd) throws RemoteException { 15963 15964 try { 15965 synchronized (this) { 15966 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 15967 // its own permission (same as profileControl). 15968 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 15969 != PackageManager.PERMISSION_GRANTED) { 15970 throw new SecurityException("Requires permission " 15971 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 15972 } 15973 15974 if (fd == null) { 15975 throw new IllegalArgumentException("null fd"); 15976 } 15977 15978 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 15979 if (proc == null || proc.thread == null) { 15980 throw new IllegalArgumentException("Unknown process: " + process); 15981 } 15982 15983 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 15984 if (!isDebuggable) { 15985 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15986 throw new SecurityException("Process not debuggable: " + proc); 15987 } 15988 } 15989 15990 proc.thread.dumpHeap(managed, path, fd); 15991 fd = null; 15992 return true; 15993 } 15994 } catch (RemoteException e) { 15995 throw new IllegalStateException("Process disappeared"); 15996 } finally { 15997 if (fd != null) { 15998 try { 15999 fd.close(); 16000 } catch (IOException e) { 16001 } 16002 } 16003 } 16004 } 16005 16006 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16007 public void monitor() { 16008 synchronized (this) { } 16009 } 16010 16011 void onCoreSettingsChange(Bundle settings) { 16012 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16013 ProcessRecord processRecord = mLruProcesses.get(i); 16014 try { 16015 if (processRecord.thread != null) { 16016 processRecord.thread.setCoreSettings(settings); 16017 } 16018 } catch (RemoteException re) { 16019 /* ignore */ 16020 } 16021 } 16022 } 16023 16024 // Multi-user methods 16025 16026 @Override 16027 public boolean switchUser(final int userId) { 16028 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16029 != PackageManager.PERMISSION_GRANTED) { 16030 String msg = "Permission Denial: switchUser() from pid=" 16031 + Binder.getCallingPid() 16032 + ", uid=" + Binder.getCallingUid() 16033 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16034 Slog.w(TAG, msg); 16035 throw new SecurityException(msg); 16036 } 16037 16038 final long ident = Binder.clearCallingIdentity(); 16039 try { 16040 synchronized (this) { 16041 final int oldUserId = mCurrentUserId; 16042 if (oldUserId == userId) { 16043 return true; 16044 } 16045 16046 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16047 if (userInfo == null) { 16048 Slog.w(TAG, "No user info for user #" + userId); 16049 return false; 16050 } 16051 16052 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16053 R.anim.screen_user_enter); 16054 16055 boolean needStart = false; 16056 16057 // If the user we are switching to is not currently started, then 16058 // we need to start it now. 16059 if (mStartedUsers.get(userId) == null) { 16060 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16061 updateStartedUserArrayLocked(); 16062 needStart = true; 16063 } 16064 16065 mCurrentUserId = userId; 16066 final Integer userIdInt = Integer.valueOf(userId); 16067 mUserLru.remove(userIdInt); 16068 mUserLru.add(userIdInt); 16069 16070 mWindowManager.setCurrentUser(userId); 16071 16072 // Once the internal notion of the active user has switched, we lock the device 16073 // with the option to show the user switcher on the keyguard. 16074 mWindowManager.lockNow(null); 16075 16076 final UserStartedState uss = mStartedUsers.get(userId); 16077 16078 // Make sure user is in the started state. If it is currently 16079 // stopping, we need to knock that off. 16080 if (uss.mState == UserStartedState.STATE_STOPPING) { 16081 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16082 // so we can just fairly silently bring the user back from 16083 // the almost-dead. 16084 uss.mState = UserStartedState.STATE_RUNNING; 16085 updateStartedUserArrayLocked(); 16086 needStart = true; 16087 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16088 // This means ACTION_SHUTDOWN has been sent, so we will 16089 // need to treat this as a new boot of the user. 16090 uss.mState = UserStartedState.STATE_BOOTING; 16091 updateStartedUserArrayLocked(); 16092 needStart = true; 16093 } 16094 16095 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16096 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16097 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16098 oldUserId, userId, uss)); 16099 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16100 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16101 if (needStart) { 16102 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16103 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16104 | Intent.FLAG_RECEIVER_FOREGROUND); 16105 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16106 broadcastIntentLocked(null, null, intent, 16107 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16108 false, false, MY_PID, Process.SYSTEM_UID, userId); 16109 } 16110 16111 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16112 if (userId != 0) { 16113 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16114 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16115 broadcastIntentLocked(null, null, intent, null, 16116 new IIntentReceiver.Stub() { 16117 public void performReceive(Intent intent, int resultCode, 16118 String data, Bundle extras, boolean ordered, 16119 boolean sticky, int sendingUser) { 16120 userInitialized(uss, userId); 16121 } 16122 }, 0, null, null, null, AppOpsManager.OP_NONE, 16123 true, false, MY_PID, Process.SYSTEM_UID, 16124 userId); 16125 uss.initializing = true; 16126 } else { 16127 getUserManagerLocked().makeInitialized(userInfo.id); 16128 } 16129 } 16130 16131 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16132 if (homeInFront) { 16133 startHomeActivityLocked(userId); 16134 } else { 16135 mStackSupervisor.resumeTopActivitiesLocked(); 16136 } 16137 16138 EventLogTags.writeAmSwitchUser(userId); 16139 getUserManagerLocked().userForeground(userId); 16140 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16141 if (needStart) { 16142 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16143 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16144 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16145 broadcastIntentLocked(null, null, intent, 16146 null, new IIntentReceiver.Stub() { 16147 @Override 16148 public void performReceive(Intent intent, int resultCode, String data, 16149 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16150 throws RemoteException { 16151 } 16152 }, 0, null, null, 16153 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16154 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16155 } 16156 } 16157 } finally { 16158 Binder.restoreCallingIdentity(ident); 16159 } 16160 16161 return true; 16162 } 16163 16164 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16165 long ident = Binder.clearCallingIdentity(); 16166 try { 16167 Intent intent; 16168 if (oldUserId >= 0) { 16169 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16170 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16171 | Intent.FLAG_RECEIVER_FOREGROUND); 16172 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16173 broadcastIntentLocked(null, null, intent, 16174 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16175 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16176 } 16177 if (newUserId >= 0) { 16178 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16179 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16180 | Intent.FLAG_RECEIVER_FOREGROUND); 16181 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16182 broadcastIntentLocked(null, null, intent, 16183 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16184 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16185 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16186 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16187 | Intent.FLAG_RECEIVER_FOREGROUND); 16188 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16189 broadcastIntentLocked(null, null, intent, 16190 null, null, 0, null, null, 16191 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16192 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16193 } 16194 } finally { 16195 Binder.restoreCallingIdentity(ident); 16196 } 16197 } 16198 16199 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16200 final int newUserId) { 16201 final int N = mUserSwitchObservers.beginBroadcast(); 16202 if (N > 0) { 16203 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16204 int mCount = 0; 16205 @Override 16206 public void sendResult(Bundle data) throws RemoteException { 16207 synchronized (ActivityManagerService.this) { 16208 if (mCurUserSwitchCallback == this) { 16209 mCount++; 16210 if (mCount == N) { 16211 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16212 } 16213 } 16214 } 16215 } 16216 }; 16217 synchronized (this) { 16218 uss.switching = true; 16219 mCurUserSwitchCallback = callback; 16220 } 16221 for (int i=0; i<N; i++) { 16222 try { 16223 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16224 newUserId, callback); 16225 } catch (RemoteException e) { 16226 } 16227 } 16228 } else { 16229 synchronized (this) { 16230 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16231 } 16232 } 16233 mUserSwitchObservers.finishBroadcast(); 16234 } 16235 16236 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16237 synchronized (this) { 16238 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16239 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16240 } 16241 } 16242 16243 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16244 mCurUserSwitchCallback = null; 16245 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16246 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16247 oldUserId, newUserId, uss)); 16248 } 16249 16250 void userInitialized(UserStartedState uss, int newUserId) { 16251 completeSwitchAndInitalize(uss, newUserId, true, false); 16252 } 16253 16254 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16255 completeSwitchAndInitalize(uss, newUserId, false, true); 16256 } 16257 16258 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16259 boolean clearInitializing, boolean clearSwitching) { 16260 boolean unfrozen = false; 16261 synchronized (this) { 16262 if (clearInitializing) { 16263 uss.initializing = false; 16264 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16265 } 16266 if (clearSwitching) { 16267 uss.switching = false; 16268 } 16269 if (!uss.switching && !uss.initializing) { 16270 mWindowManager.stopFreezingScreen(); 16271 unfrozen = true; 16272 } 16273 } 16274 if (unfrozen) { 16275 final int N = mUserSwitchObservers.beginBroadcast(); 16276 for (int i=0; i<N; i++) { 16277 try { 16278 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16279 } catch (RemoteException e) { 16280 } 16281 } 16282 mUserSwitchObservers.finishBroadcast(); 16283 } 16284 } 16285 16286 void finishUserSwitch(UserStartedState uss) { 16287 synchronized (this) { 16288 if (uss.mState == UserStartedState.STATE_BOOTING 16289 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16290 uss.mState = UserStartedState.STATE_RUNNING; 16291 final int userId = uss.mHandle.getIdentifier(); 16292 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16293 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16294 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16295 broadcastIntentLocked(null, null, intent, 16296 null, null, 0, null, null, 16297 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16298 true, false, MY_PID, Process.SYSTEM_UID, userId); 16299 } 16300 int num = mUserLru.size(); 16301 int i = 0; 16302 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16303 Integer oldUserId = mUserLru.get(i); 16304 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16305 if (oldUss == null) { 16306 // Shouldn't happen, but be sane if it does. 16307 mUserLru.remove(i); 16308 num--; 16309 continue; 16310 } 16311 if (oldUss.mState == UserStartedState.STATE_STOPPING 16312 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16313 // This user is already stopping, doesn't count. 16314 num--; 16315 i++; 16316 continue; 16317 } 16318 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16319 // Owner and current can't be stopped, but count as running. 16320 i++; 16321 continue; 16322 } 16323 // This is a user to be stopped. 16324 stopUserLocked(oldUserId, null); 16325 num--; 16326 i++; 16327 } 16328 } 16329 } 16330 16331 @Override 16332 public int stopUser(final int userId, final IStopUserCallback callback) { 16333 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16334 != PackageManager.PERMISSION_GRANTED) { 16335 String msg = "Permission Denial: switchUser() from pid=" 16336 + Binder.getCallingPid() 16337 + ", uid=" + Binder.getCallingUid() 16338 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16339 Slog.w(TAG, msg); 16340 throw new SecurityException(msg); 16341 } 16342 if (userId <= 0) { 16343 throw new IllegalArgumentException("Can't stop primary user " + userId); 16344 } 16345 synchronized (this) { 16346 return stopUserLocked(userId, callback); 16347 } 16348 } 16349 16350 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16351 if (mCurrentUserId == userId) { 16352 return ActivityManager.USER_OP_IS_CURRENT; 16353 } 16354 16355 final UserStartedState uss = mStartedUsers.get(userId); 16356 if (uss == null) { 16357 // User is not started, nothing to do... but we do need to 16358 // callback if requested. 16359 if (callback != null) { 16360 mHandler.post(new Runnable() { 16361 @Override 16362 public void run() { 16363 try { 16364 callback.userStopped(userId); 16365 } catch (RemoteException e) { 16366 } 16367 } 16368 }); 16369 } 16370 return ActivityManager.USER_OP_SUCCESS; 16371 } 16372 16373 if (callback != null) { 16374 uss.mStopCallbacks.add(callback); 16375 } 16376 16377 if (uss.mState != UserStartedState.STATE_STOPPING 16378 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16379 uss.mState = UserStartedState.STATE_STOPPING; 16380 updateStartedUserArrayLocked(); 16381 16382 long ident = Binder.clearCallingIdentity(); 16383 try { 16384 // We are going to broadcast ACTION_USER_STOPPING and then 16385 // once that is done send a final ACTION_SHUTDOWN and then 16386 // stop the user. 16387 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16388 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16389 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16390 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16391 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16392 // This is the result receiver for the final shutdown broadcast. 16393 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16394 @Override 16395 public void performReceive(Intent intent, int resultCode, String data, 16396 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16397 finishUserStop(uss); 16398 } 16399 }; 16400 // This is the result receiver for the initial stopping broadcast. 16401 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16402 @Override 16403 public void performReceive(Intent intent, int resultCode, String data, 16404 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16405 // On to the next. 16406 synchronized (ActivityManagerService.this) { 16407 if (uss.mState != UserStartedState.STATE_STOPPING) { 16408 // Whoops, we are being started back up. Abort, abort! 16409 return; 16410 } 16411 uss.mState = UserStartedState.STATE_SHUTDOWN; 16412 } 16413 broadcastIntentLocked(null, null, shutdownIntent, 16414 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16415 true, false, MY_PID, Process.SYSTEM_UID, userId); 16416 } 16417 }; 16418 // Kick things off. 16419 broadcastIntentLocked(null, null, stoppingIntent, 16420 null, stoppingReceiver, 0, null, null, 16421 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16422 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16423 } finally { 16424 Binder.restoreCallingIdentity(ident); 16425 } 16426 } 16427 16428 return ActivityManager.USER_OP_SUCCESS; 16429 } 16430 16431 void finishUserStop(UserStartedState uss) { 16432 final int userId = uss.mHandle.getIdentifier(); 16433 boolean stopped; 16434 ArrayList<IStopUserCallback> callbacks; 16435 synchronized (this) { 16436 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16437 if (mStartedUsers.get(userId) != uss) { 16438 stopped = false; 16439 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16440 stopped = false; 16441 } else { 16442 stopped = true; 16443 // User can no longer run. 16444 mStartedUsers.remove(userId); 16445 mUserLru.remove(Integer.valueOf(userId)); 16446 updateStartedUserArrayLocked(); 16447 16448 // Clean up all state and processes associated with the user. 16449 // Kill all the processes for the user. 16450 forceStopUserLocked(userId, "finish user"); 16451 } 16452 } 16453 16454 for (int i=0; i<callbacks.size(); i++) { 16455 try { 16456 if (stopped) callbacks.get(i).userStopped(userId); 16457 else callbacks.get(i).userStopAborted(userId); 16458 } catch (RemoteException e) { 16459 } 16460 } 16461 16462 mStackSupervisor.removeUserLocked(userId); 16463 } 16464 16465 @Override 16466 public UserInfo getCurrentUser() { 16467 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16468 != PackageManager.PERMISSION_GRANTED) && ( 16469 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16470 != PackageManager.PERMISSION_GRANTED)) { 16471 String msg = "Permission Denial: getCurrentUser() from pid=" 16472 + Binder.getCallingPid() 16473 + ", uid=" + Binder.getCallingUid() 16474 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16475 Slog.w(TAG, msg); 16476 throw new SecurityException(msg); 16477 } 16478 synchronized (this) { 16479 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16480 } 16481 } 16482 16483 int getCurrentUserIdLocked() { 16484 return mCurrentUserId; 16485 } 16486 16487 @Override 16488 public boolean isUserRunning(int userId, boolean orStopped) { 16489 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16490 != PackageManager.PERMISSION_GRANTED) { 16491 String msg = "Permission Denial: isUserRunning() from pid=" 16492 + Binder.getCallingPid() 16493 + ", uid=" + Binder.getCallingUid() 16494 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16495 Slog.w(TAG, msg); 16496 throw new SecurityException(msg); 16497 } 16498 synchronized (this) { 16499 return isUserRunningLocked(userId, orStopped); 16500 } 16501 } 16502 16503 boolean isUserRunningLocked(int userId, boolean orStopped) { 16504 UserStartedState state = mStartedUsers.get(userId); 16505 if (state == null) { 16506 return false; 16507 } 16508 if (orStopped) { 16509 return true; 16510 } 16511 return state.mState != UserStartedState.STATE_STOPPING 16512 && state.mState != UserStartedState.STATE_SHUTDOWN; 16513 } 16514 16515 @Override 16516 public int[] getRunningUserIds() { 16517 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16518 != PackageManager.PERMISSION_GRANTED) { 16519 String msg = "Permission Denial: isUserRunning() from pid=" 16520 + Binder.getCallingPid() 16521 + ", uid=" + Binder.getCallingUid() 16522 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16523 Slog.w(TAG, msg); 16524 throw new SecurityException(msg); 16525 } 16526 synchronized (this) { 16527 return mStartedUserArray; 16528 } 16529 } 16530 16531 private void updateStartedUserArrayLocked() { 16532 int num = 0; 16533 for (int i=0; i<mStartedUsers.size(); i++) { 16534 UserStartedState uss = mStartedUsers.valueAt(i); 16535 // This list does not include stopping users. 16536 if (uss.mState != UserStartedState.STATE_STOPPING 16537 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16538 num++; 16539 } 16540 } 16541 mStartedUserArray = new int[num]; 16542 num = 0; 16543 for (int i=0; i<mStartedUsers.size(); i++) { 16544 UserStartedState uss = mStartedUsers.valueAt(i); 16545 if (uss.mState != UserStartedState.STATE_STOPPING 16546 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16547 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16548 num++; 16549 } 16550 } 16551 } 16552 16553 @Override 16554 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16555 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16556 != PackageManager.PERMISSION_GRANTED) { 16557 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16558 + Binder.getCallingPid() 16559 + ", uid=" + Binder.getCallingUid() 16560 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16561 Slog.w(TAG, msg); 16562 throw new SecurityException(msg); 16563 } 16564 16565 mUserSwitchObservers.register(observer); 16566 } 16567 16568 @Override 16569 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16570 mUserSwitchObservers.unregister(observer); 16571 } 16572 16573 private boolean userExists(int userId) { 16574 if (userId == 0) { 16575 return true; 16576 } 16577 UserManagerService ums = getUserManagerLocked(); 16578 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16579 } 16580 16581 int[] getUsersLocked() { 16582 UserManagerService ums = getUserManagerLocked(); 16583 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16584 } 16585 16586 UserManagerService getUserManagerLocked() { 16587 if (mUserManager == null) { 16588 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16589 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16590 } 16591 return mUserManager; 16592 } 16593 16594 private int applyUserId(int uid, int userId) { 16595 return UserHandle.getUid(userId, uid); 16596 } 16597 16598 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16599 if (info == null) return null; 16600 ApplicationInfo newInfo = new ApplicationInfo(info); 16601 newInfo.uid = applyUserId(info.uid, userId); 16602 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16603 + info.packageName; 16604 return newInfo; 16605 } 16606 16607 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16608 if (aInfo == null 16609 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16610 return aInfo; 16611 } 16612 16613 ActivityInfo info = new ActivityInfo(aInfo); 16614 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16615 return info; 16616 } 16617 } 16618