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.Manifest.permission.CHANGE_CONFIGURATION; 20 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST; 21 import static android.Manifest.permission.INTERACT_ACROSS_USERS; 22 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 23 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 24 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; 25 import static android.Manifest.permission.READ_FRAME_BUFFER; 26 import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 27 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; 28 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW; 29 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; 30 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; 31 import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID; 32 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; 33 import static android.app.ActivityManager.StackId.INVALID_STACK_ID; 34 import static android.app.ActivityManager.StackId.PINNED_STACK_ID; 35 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS; 36 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; 37 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY; 38 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; 39 import static android.content.pm.PackageManager.GET_PROVIDERS; 40 import static android.content.pm.PackageManager.MATCH_ANY_USER; 41 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 42 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 43 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 44 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 45 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 46 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 47 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION; 48 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode; 49 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground; 50 import static android.os.Build.VERSION_CODES.N; 51 import static android.os.Process.BLUETOOTH_UID; 52 import static android.os.Process.FIRST_APPLICATION_UID; 53 import static android.os.Process.FIRST_ISOLATED_UID; 54 import static android.os.Process.LAST_ISOLATED_UID; 55 import static android.os.Process.NFC_UID; 56 import static android.os.Process.PHONE_UID; 57 import static android.os.Process.PROC_CHAR; 58 import static android.os.Process.PROC_OUT_LONG; 59 import static android.os.Process.PROC_PARENS; 60 import static android.os.Process.PROC_SPACE_TERM; 61 import static android.os.Process.ProcessStartResult; 62 import static android.os.Process.ROOT_UID; 63 import static android.os.Process.SCHED_FIFO; 64 import static android.os.Process.SCHED_OTHER; 65 import static android.os.Process.SCHED_RESET_ON_FORK; 66 import static android.os.Process.SHELL_UID; 67 import static android.os.Process.SIGNAL_QUIT; 68 import static android.os.Process.SIGNAL_USR1; 69 import static android.os.Process.SYSTEM_UID; 70 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE; 71 import static android.os.Process.THREAD_GROUP_DEFAULT; 72 import static android.os.Process.THREAD_GROUP_TOP_APP; 73 import static android.os.Process.THREAD_PRIORITY_BACKGROUND; 74 import static android.os.Process.THREAD_PRIORITY_FOREGROUND; 75 import static android.os.Process.getFreeMemory; 76 import static android.os.Process.getTotalMemory; 77 import static android.os.Process.isThreadInProcess; 78 import static android.os.Process.killProcess; 79 import static android.os.Process.killProcessQuiet; 80 import static android.os.Process.myPid; 81 import static android.os.Process.myUid; 82 import static android.os.Process.readProcFile; 83 import static android.os.Process.removeAllProcessGroups; 84 import static android.os.Process.sendSignal; 85 import static android.os.Process.setProcessGroup; 86 import static android.os.Process.setThreadPriority; 87 import static android.os.Process.setThreadScheduler; 88 import static android.os.Process.startWebView; 89 import static android.os.Process.zygoteProcess; 90 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES; 91 import static android.provider.Settings.Global.DEBUG_APP; 92 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT; 93 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES; 94 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL; 95 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS; 96 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER; 97 import static android.provider.Settings.System.FONT_SCALE; 98 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION; 99 import static android.text.format.DateUtils.DAY_IN_MILLIS; 100 import static android.view.Display.DEFAULT_DISPLAY; 101 import static android.view.Display.INVALID_DISPLAY; 102 import static com.android.internal.util.XmlUtils.readBooleanAttribute; 103 import static com.android.internal.util.XmlUtils.readIntAttribute; 104 import static com.android.internal.util.XmlUtils.readLongAttribute; 105 import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 106 import static com.android.internal.util.XmlUtils.writeIntAttribute; 107 import static com.android.internal.util.XmlUtils.writeLongAttribute; 108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; 109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR; 110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK; 111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP; 112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST; 113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND; 114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT; 115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP; 116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION; 117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS; 118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE; 119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; 120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU; 121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU; 122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK; 123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ; 124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON; 125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; 126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER; 127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES; 128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS; 129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER; 130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS; 131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS; 132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE; 133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; 134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH; 135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; 136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS; 137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION; 138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS; 139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY; 140 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS; 141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP; 142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST; 143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP; 144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION; 145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS; 146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE; 147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN; 148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK; 149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU; 150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU; 151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK; 152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ; 153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER; 154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES; 155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS; 156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER; 157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS; 158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS; 159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE; 160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; 161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH; 162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS; 163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION; 164 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY; 165 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND; 166 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 167 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 168 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED; 169 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME; 170 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY; 171 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS; 172 import static com.android.server.am.ActivityStackSupervisor.ON_TOP; 173 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; 174 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS; 175 import static com.android.server.am.TaskRecord.INVALID_TASK_ID; 176 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; 177 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; 178 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; 179 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT; 180 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE; 181 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN; 182 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH; 183 import static com.android.server.wm.AppTransition.TRANSIT_NONE; 184 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE; 185 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN; 186 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT; 187 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 188 import static org.xmlpull.v1.XmlPullParser.START_TAG; 189 190 import android.Manifest; 191 import android.Manifest.permission; 192 import android.annotation.NonNull; 193 import android.annotation.Nullable; 194 import android.annotation.UserIdInt; 195 import android.app.Activity; 196 import android.app.ActivityManager; 197 import android.app.ActivityManager.RunningTaskInfo; 198 import android.app.ActivityManager.StackId; 199 import android.app.ActivityManager.StackInfo; 200 import android.app.ActivityManager.TaskSnapshot; 201 import android.app.ActivityManager.TaskThumbnailInfo; 202 import android.app.ActivityManagerInternal; 203 import android.app.ActivityManagerInternal.SleepToken; 204 import android.app.ActivityOptions; 205 import android.app.ActivityThread; 206 import android.app.AlertDialog; 207 import android.app.AppGlobals; 208 import android.app.AppOpsManager; 209 import android.app.ApplicationErrorReport; 210 import android.app.ApplicationThreadConstants; 211 import android.app.BroadcastOptions; 212 import android.app.ContentProviderHolder; 213 import android.app.Dialog; 214 import android.app.IActivityController; 215 import android.app.IActivityManager; 216 import android.app.IAppTask; 217 import android.app.IApplicationThread; 218 import android.app.IInstrumentationWatcher; 219 import android.app.INotificationManager; 220 import android.app.IProcessObserver; 221 import android.app.IServiceConnection; 222 import android.app.IStopUserCallback; 223 import android.app.ITaskStackListener; 224 import android.app.IUiAutomationConnection; 225 import android.app.IUidObserver; 226 import android.app.IUserSwitchObserver; 227 import android.app.Instrumentation; 228 import android.app.Notification; 229 import android.app.NotificationManager; 230 import android.app.PendingIntent; 231 import android.app.PictureInPictureParams; 232 import android.app.ProfilerInfo; 233 import android.app.RemoteAction; 234 import android.app.WaitResult; 235 import android.app.admin.DevicePolicyManager; 236 import android.app.assist.AssistContent; 237 import android.app.assist.AssistStructure; 238 import android.app.backup.IBackupManager; 239 import android.app.usage.UsageEvents; 240 import android.app.usage.UsageStatsManagerInternal; 241 import android.appwidget.AppWidgetManager; 242 import android.content.ActivityNotFoundException; 243 import android.content.BroadcastReceiver; 244 import android.content.ClipData; 245 import android.content.ComponentCallbacks2; 246 import android.content.ComponentName; 247 import android.content.ContentProvider; 248 import android.content.ContentResolver; 249 import android.content.Context; 250 import android.content.DialogInterface; 251 import android.content.IContentProvider; 252 import android.content.IIntentReceiver; 253 import android.content.IIntentSender; 254 import android.content.Intent; 255 import android.content.IntentFilter; 256 import android.content.pm.ActivityInfo; 257 import android.content.pm.ApplicationInfo; 258 import android.content.pm.ConfigurationInfo; 259 import android.content.pm.IPackageDataObserver; 260 import android.content.pm.IPackageManager; 261 import android.content.pm.InstrumentationInfo; 262 import android.content.pm.PackageInfo; 263 import android.content.pm.PackageManager; 264 import android.content.pm.PackageManager.NameNotFoundException; 265 import android.content.pm.PackageManagerInternal; 266 import android.content.pm.ParceledListSlice; 267 import android.content.pm.PathPermission; 268 import android.content.pm.PermissionInfo; 269 import android.content.pm.ProviderInfo; 270 import android.content.pm.ResolveInfo; 271 import android.content.pm.SELinuxUtil; 272 import android.content.pm.ServiceInfo; 273 import android.content.pm.UserInfo; 274 import android.content.res.CompatibilityInfo; 275 import android.content.res.Configuration; 276 import android.content.res.Resources; 277 import android.database.ContentObserver; 278 import android.graphics.Bitmap; 279 import android.graphics.Point; 280 import android.graphics.Rect; 281 import android.location.LocationManager; 282 import android.media.audiofx.AudioEffect; 283 import android.metrics.LogMaker; 284 import android.net.Proxy; 285 import android.net.ProxyInfo; 286 import android.net.Uri; 287 import android.os.BatteryStats; 288 import android.os.Binder; 289 import android.os.Build; 290 import android.os.Bundle; 291 import android.os.Debug; 292 import android.os.DropBoxManager; 293 import android.os.Environment; 294 import android.os.FactoryTest; 295 import android.os.FileObserver; 296 import android.os.FileUtils; 297 import android.os.Handler; 298 import android.os.IBinder; 299 import android.os.IDeviceIdentifiersPolicyService; 300 import android.os.IPermissionController; 301 import android.os.IProcessInfoService; 302 import android.os.IProgressListener; 303 import android.os.LocaleList; 304 import android.os.Looper; 305 import android.os.Message; 306 import android.os.Parcel; 307 import android.os.ParcelFileDescriptor; 308 import android.os.PersistableBundle; 309 import android.os.PowerManager; 310 import android.os.PowerManagerInternal; 311 import android.os.Process; 312 import android.os.RemoteCallbackList; 313 import android.os.RemoteException; 314 import android.os.ResultReceiver; 315 import android.os.ServiceManager; 316 import android.os.ShellCallback; 317 import android.os.StrictMode; 318 import android.os.SystemClock; 319 import android.os.SystemProperties; 320 import android.os.Trace; 321 import android.os.TransactionTooLargeException; 322 import android.os.UpdateLock; 323 import android.os.UserHandle; 324 import android.os.UserManager; 325 import android.os.WorkSource; 326 import android.os.storage.IStorageManager; 327 import android.os.storage.StorageManager; 328 import android.os.storage.StorageManagerInternal; 329 import android.provider.Downloads; 330 import android.provider.Settings; 331 import android.service.voice.IVoiceInteractionSession; 332 import android.service.voice.VoiceInteractionManagerInternal; 333 import android.service.voice.VoiceInteractionSession; 334 import android.telecom.TelecomManager; 335 import android.text.TextUtils; 336 import android.text.format.DateUtils; 337 import android.text.format.Time; 338 import android.text.style.SuggestionSpan; 339 import android.util.ArrayMap; 340 import android.util.ArraySet; 341 import android.util.AtomicFile; 342 import android.util.TimingsTraceLog; 343 import android.util.DebugUtils; 344 import android.util.DisplayMetrics; 345 import android.util.EventLog; 346 import android.util.Log; 347 import android.util.Pair; 348 import android.util.PrintWriterPrinter; 349 import android.util.Slog; 350 import android.util.SparseArray; 351 import android.util.SparseIntArray; 352 import android.util.TimeUtils; 353 import android.util.Xml; 354 import android.view.Gravity; 355 import android.view.LayoutInflater; 356 import android.view.View; 357 import android.view.WindowManager; 358 359 import com.android.server.job.JobSchedulerInternal; 360 import com.google.android.collect.Lists; 361 import com.google.android.collect.Maps; 362 363 import com.android.internal.R; 364 import com.android.internal.annotations.GuardedBy; 365 import com.android.internal.annotations.VisibleForTesting; 366 import com.android.internal.app.AssistUtils; 367 import com.android.internal.app.DumpHeapActivity; 368 import com.android.internal.app.IAppOpsCallback; 369 import com.android.internal.app.IAppOpsService; 370 import com.android.internal.app.IVoiceInteractor; 371 import com.android.internal.app.ProcessMap; 372 import com.android.internal.app.SystemUserHomeActivity; 373 import com.android.internal.app.procstats.ProcessStats; 374 import com.android.internal.logging.MetricsLogger; 375 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 376 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; 377 import com.android.internal.notification.SystemNotificationChannels; 378 import com.android.internal.os.BackgroundThread; 379 import com.android.internal.os.BatteryStatsImpl; 380 import com.android.internal.os.IResultReceiver; 381 import com.android.internal.os.ProcessCpuTracker; 382 import com.android.internal.os.TransferPipe; 383 import com.android.internal.os.Zygote; 384 import com.android.internal.policy.IKeyguardDismissCallback; 385 import com.android.internal.telephony.TelephonyIntents; 386 import com.android.internal.util.ArrayUtils; 387 import com.android.internal.util.DumpUtils; 388 import com.android.internal.util.FastPrintWriter; 389 import com.android.internal.util.FastXmlSerializer; 390 import com.android.internal.util.MemInfoReader; 391 import com.android.internal.util.Preconditions; 392 import com.android.server.AppOpsService; 393 import com.android.server.AttributeCache; 394 import com.android.server.DeviceIdleController; 395 import com.android.server.IntentResolver; 396 import com.android.server.LocalServices; 397 import com.android.server.LockGuard; 398 import com.android.server.NetworkManagementInternal; 399 import com.android.server.RescueParty; 400 import com.android.server.ServiceThread; 401 import com.android.server.SystemConfig; 402 import com.android.server.SystemService; 403 import com.android.server.SystemServiceManager; 404 import com.android.server.ThreadPriorityBooster; 405 import com.android.server.Watchdog; 406 import com.android.server.am.ActivityStack.ActivityState; 407 import com.android.server.firewall.IntentFirewall; 408 import com.android.server.pm.Installer; 409 import com.android.server.pm.Installer.InstallerException; 410 import com.android.server.statusbar.StatusBarManagerInternal; 411 import com.android.server.vr.VrManagerInternal; 412 import com.android.server.wm.PinnedStackWindowController; 413 import com.android.server.wm.WindowManagerService; 414 415 import java.text.SimpleDateFormat; 416 import org.xmlpull.v1.XmlPullParser; 417 import org.xmlpull.v1.XmlPullParserException; 418 import org.xmlpull.v1.XmlSerializer; 419 420 import java.io.File; 421 import java.io.FileDescriptor; 422 import java.io.FileInputStream; 423 import java.io.FileNotFoundException; 424 import java.io.FileOutputStream; 425 import java.io.IOException; 426 import java.io.InputStreamReader; 427 import java.io.PrintWriter; 428 import java.io.StringWriter; 429 import java.io.UnsupportedEncodingException; 430 import java.lang.ref.WeakReference; 431 import java.nio.charset.StandardCharsets; 432 import java.text.DateFormat; 433 import java.util.ArrayList; 434 import java.util.Arrays; 435 import java.util.Collections; 436 import java.util.Comparator; 437 import java.util.Date; 438 import java.util.HashMap; 439 import java.util.HashSet; 440 import java.util.Iterator; 441 import java.util.List; 442 import java.util.Locale; 443 import java.util.Map; 444 import java.util.Objects; 445 import java.util.Set; 446 import java.util.concurrent.CountDownLatch; 447 import java.util.concurrent.atomic.AtomicBoolean; 448 import java.util.concurrent.atomic.AtomicLong; 449 450 import dalvik.system.VMRuntime; 451 import libcore.io.IoUtils; 452 import libcore.util.EmptyArray; 453 454 public class ActivityManagerService extends IActivityManager.Stub 455 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 456 457 /** 458 * Priority we boost main thread and RT of top app to. 459 */ 460 public static final int TOP_APP_PRIORITY_BOOST = -10; 461 462 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM; 463 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP; 464 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST; 465 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP; 466 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; 467 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; 468 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE; 469 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; 470 private static final String TAG_LRU = TAG + POSTFIX_LRU; 471 private static final String TAG_MU = TAG + POSTFIX_MU; 472 private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK; 473 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ; 474 private static final String TAG_POWER = TAG + POSTFIX_POWER; 475 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS; 476 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES; 477 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER; 478 private static final String TAG_PSS = TAG + POSTFIX_PSS; 479 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; 480 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE; 481 private static final String TAG_STACK = TAG + POSTFIX_STACK; 482 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; 483 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS; 484 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION; 485 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY; 486 487 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared 488 // here so that while the job scheduler can depend on AMS, the other way around 489 // need not be the case. 490 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE"; 491 492 /** Control over CPU and battery monitoring */ 493 // write battery stats every 30 minutes. 494 static final long BATTERY_STATS_TIME = 30 * 60 * 1000; 495 static final boolean MONITOR_CPU_USAGE = true; 496 // don't sample cpu less than every 5 seconds. 497 static final long MONITOR_CPU_MIN_TIME = 5 * 1000; 498 // wait possibly forever for next cpu sample. 499 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; 500 static final boolean MONITOR_THREAD_CPU_USAGE = false; 501 502 // The flags that are set for all calls we make to the package manager. 503 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 504 505 static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 506 507 // Amount of time after a call to stopAppSwitches() during which we will 508 // prevent further untrusted switches from happening. 509 static final long APP_SWITCH_DELAY_TIME = 5*1000; 510 511 // How long we wait for a launched process to attach to the activity manager 512 // before we decide it's never going to come up for real. 513 static final int PROC_START_TIMEOUT = 10*1000; 514 // How long we wait for an attached process to publish its content providers 515 // before we decide it must be hung. 516 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000; 517 518 // How long we wait for a launched process to attach to the activity manager 519 // before we decide it's never going to come up for real, when the process was 520 // started with a wrapper for instrumentation (such as Valgrind) because it 521 // could take much longer than usual. 522 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 523 524 // How long we allow a receiver to run before giving up on it. 525 static final int BROADCAST_FG_TIMEOUT = 10*1000; 526 static final int BROADCAST_BG_TIMEOUT = 60*1000; 527 528 // How long we wait until we timeout on key dispatching. 529 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 530 531 // How long we wait until we timeout on key dispatching during instrumentation. 532 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 533 534 // How long to wait in getAssistContextExtras for the activity and foreground services 535 // to respond with the result. 536 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 537 538 // How long top wait when going through the modern assist (which doesn't need to block 539 // on getting this result before starting to launch its UI). 540 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000; 541 542 // How long to wait in getAutofillAssistStructure() for the activity to respond with the result. 543 static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000; 544 545 // Maximum number of persisted Uri grants a package is allowed 546 static final int MAX_PERSISTED_URI_GRANTS = 128; 547 548 static final int MY_PID = myPid(); 549 550 static final String[] EMPTY_STRING_ARRAY = new String[0]; 551 552 // How many bytes to write into the dropbox log before truncating 553 static final int DROPBOX_MAX_SIZE = 192 * 1024; 554 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count 555 // as one line, but close enough for now. 556 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100; 557 558 // Access modes for handleIncomingUser. 559 static final int ALLOW_NON_FULL = 0; 560 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 561 static final int ALLOW_FULL_ONLY = 2; 562 563 // Necessary ApplicationInfo flags to mark an app as persistent 564 private static final int PERSISTENT_MASK = 565 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT; 566 567 // Intent sent when remote bugreport collection has been completed 568 private static final String INTENT_REMOTE_BUGREPORT_FINISHED = 569 "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED"; 570 571 // Used to indicate that an app transition should be animated. 572 static final boolean ANIMATE = true; 573 574 // Determines whether to take full screen screenshots 575 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true; 576 577 /** 578 * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}. 579 */ 580 private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec 581 582 /** 583 * State indicating that there is no need for any blocking for network. 584 */ 585 @VisibleForTesting 586 static final int NETWORK_STATE_NO_CHANGE = 0; 587 588 /** 589 * State indicating that the main thread needs to be informed about the network wait. 590 */ 591 @VisibleForTesting 592 static final int NETWORK_STATE_BLOCK = 1; 593 594 /** 595 * State indicating that any threads waiting for network state to get updated can be unblocked. 596 */ 597 @VisibleForTesting 598 static final int NETWORK_STATE_UNBLOCK = 2; 599 600 // Max character limit for a notification title. If the notification title is larger than this 601 // the notification will not be legible to the user. 602 private static final int MAX_BUGREPORT_TITLE_SIZE = 50; 603 604 private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds; 605 606 /** All system services */ 607 SystemServiceManager mSystemServiceManager; 608 AssistUtils mAssistUtils; 609 610 private Installer mInstaller; 611 612 /** Run all ActivityStacks through this */ 613 final ActivityStackSupervisor mStackSupervisor; 614 private final KeyguardController mKeyguardController; 615 616 final ActivityStarter mActivityStarter; 617 618 final TaskChangeNotificationController mTaskChangeNotificationController; 619 620 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter(); 621 622 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>(); 623 624 public final IntentFirewall mIntentFirewall; 625 626 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 627 // default action automatically. Important for devices without direct input 628 // devices. 629 private boolean mShowDialogs = true; 630 631 private final VrController mVrController; 632 633 // VR Vr2d Display Id. 634 int mVr2dDisplayId = INVALID_DISPLAY; 635 636 // Whether we should use SCHED_FIFO for UI and RenderThreads. 637 private boolean mUseFifoUiScheduling = false; 638 639 BroadcastQueue mFgBroadcastQueue; 640 BroadcastQueue mBgBroadcastQueue; 641 // Convenient for easy iteration over the queues. Foreground is first 642 // so that dispatch of foreground broadcasts gets precedence. 643 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 644 645 BroadcastStats mLastBroadcastStats; 646 BroadcastStats mCurBroadcastStats; 647 648 BroadcastQueue broadcastQueueForIntent(Intent intent) { 649 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 650 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST, 651 "Broadcast intent " + intent + " on " 652 + (isFg ? "foreground" : "background") + " queue"); 653 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 654 } 655 656 /** 657 * The last resumed activity. This is identical to the current resumed activity most 658 * of the time but could be different when we're pausing one activity before we resume 659 * another activity. 660 */ 661 private ActivityRecord mLastResumedActivity; 662 663 /** 664 * If non-null, we are tracking the time the user spends in the currently focused app. 665 */ 666 private AppTimeTracker mCurAppTimeTracker; 667 668 /** 669 * List of intents that were used to start the most recent tasks. 670 */ 671 final RecentTasks mRecentTasks; 672 673 /** 674 * For addAppTask: cached of the last activity component that was added. 675 */ 676 ComponentName mLastAddedTaskComponent; 677 678 /** 679 * For addAppTask: cached of the last activity uid that was added. 680 */ 681 int mLastAddedTaskUid; 682 683 /** 684 * For addAppTask: cached of the last ActivityInfo that was added. 685 */ 686 ActivityInfo mLastAddedTaskActivity; 687 688 /** 689 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId. 690 */ 691 SparseArray<String[]> mLockTaskPackages = new SparseArray<>(); 692 693 /** 694 * The package name of the DeviceOwner. This package is not permitted to have its data cleared. 695 */ 696 String mDeviceOwnerName; 697 698 final UserController mUserController; 699 700 final AppErrors mAppErrors; 701 702 /** 703 * Dump of the activity state at the time of the last ANR. Cleared after 704 * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS} 705 */ 706 String mLastANRState; 707 708 /** 709 * Indicates the maximum time spent waiting for the network rules to get updated. 710 */ 711 @VisibleForTesting 712 long mWaitForNetworkTimeoutMs; 713 714 public boolean canShowErrorDialogs() { 715 return mShowDialogs && !mSleeping && !mShuttingDown 716 && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY) 717 && !(UserManager.isDeviceInDemoMode(mContext) 718 && mUserController.getCurrentUser().isDemo()); 719 } 720 721 private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster( 722 THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY); 723 724 static void boostPriorityForLockedSection() { 725 sThreadPriorityBooster.boost(); 726 } 727 728 static void resetPriorityAfterLockedSection() { 729 sThreadPriorityBooster.reset(); 730 } 731 732 public class PendingAssistExtras extends Binder implements Runnable { 733 public final ActivityRecord activity; 734 public boolean isHome; 735 public final Bundle extras; 736 public final Intent intent; 737 public final String hint; 738 public final IResultReceiver receiver; 739 public final int userHandle; 740 public boolean haveResult = false; 741 public Bundle result = null; 742 public AssistStructure structure = null; 743 public AssistContent content = null; 744 public Bundle receiverExtras; 745 746 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 747 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) { 748 activity = _activity; 749 extras = _extras; 750 intent = _intent; 751 hint = _hint; 752 receiver = _receiver; 753 receiverExtras = _receiverExtras; 754 userHandle = _userHandle; 755 } 756 757 @Override 758 public void run() { 759 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 760 synchronized (this) { 761 haveResult = true; 762 notifyAll(); 763 } 764 pendingAssistExtrasTimedOut(this); 765 } 766 } 767 768 final ArrayList<PendingAssistExtras> mPendingAssistExtras 769 = new ArrayList<PendingAssistExtras>(); 770 771 /** 772 * Process management. 773 */ 774 final ProcessList mProcessList = new ProcessList(); 775 776 /** 777 * All of the applications we currently have running organized by name. 778 * The keys are strings of the application package name (as 779 * returned by the package manager), and the keys are ApplicationRecord 780 * objects. 781 */ 782 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 783 784 /** 785 * Tracking long-term execution of processes to look for abuse and other 786 * bad app behavior. 787 */ 788 final ProcessStatsService mProcessStats; 789 790 /** 791 * The currently running isolated processes. 792 */ 793 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 794 795 /** 796 * Counter for assigning isolated process uids, to avoid frequently reusing the 797 * same ones. 798 */ 799 int mNextIsolatedProcessUid = 0; 800 801 /** 802 * The currently running heavy-weight process, if any. 803 */ 804 ProcessRecord mHeavyWeightProcess = null; 805 806 /** 807 * Non-persistent appId whitelist for background restrictions 808 */ 809 int[] mBackgroundAppIdWhitelist = new int[] { 810 BLUETOOTH_UID 811 }; 812 813 /** 814 * Broadcast actions that will always be deliverable to unlaunched/background apps 815 */ 816 ArraySet<String> mBackgroundLaunchBroadcasts; 817 818 /** 819 * All of the processes we currently have running organized by pid. 820 * The keys are the pid running the application. 821 * 822 * <p>NOTE: This object is protected by its own lock, NOT the global 823 * activity manager lock! 824 */ 825 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 826 827 /** 828 * All of the processes that have been forced to be important. The key 829 * is the pid of the caller who requested it (we hold a death 830 * link on it). 831 */ 832 abstract class ImportanceToken implements IBinder.DeathRecipient { 833 final int pid; 834 final IBinder token; 835 final String reason; 836 837 ImportanceToken(int _pid, IBinder _token, String _reason) { 838 pid = _pid; 839 token = _token; 840 reason = _reason; 841 } 842 843 @Override 844 public String toString() { 845 return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this)) 846 + " " + reason + " " + pid + " " + token + " }"; 847 } 848 } 849 final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>(); 850 851 /** 852 * List of records for processes that someone had tried to start before the 853 * system was ready. We don't start them at that point, but ensure they 854 * are started by the time booting is complete. 855 */ 856 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 857 858 /** 859 * List of persistent applications that are in the process 860 * of being started. 861 */ 862 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 863 864 /** 865 * Processes that are being forcibly torn down. 866 */ 867 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 868 869 /** 870 * List of running applications, sorted by recent usage. 871 * The first entry in the list is the least recently used. 872 */ 873 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 874 875 /** 876 * Where in mLruProcesses that the processes hosting activities start. 877 */ 878 int mLruProcessActivityStart = 0; 879 880 /** 881 * Where in mLruProcesses that the processes hosting services start. 882 * This is after (lower index) than mLruProcessesActivityStart. 883 */ 884 int mLruProcessServiceStart = 0; 885 886 /** 887 * List of processes that should gc as soon as things are idle. 888 */ 889 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 890 891 /** 892 * Processes we want to collect PSS data from. 893 */ 894 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 895 896 private boolean mBinderTransactionTrackingEnabled = false; 897 898 /** 899 * Last time we requested PSS data of all processes. 900 */ 901 long mLastFullPssTime = SystemClock.uptimeMillis(); 902 903 /** 904 * If set, the next time we collect PSS data we should do a full collection 905 * with data from native processes and the kernel. 906 */ 907 boolean mFullPssPending = false; 908 909 /** 910 * This is the process holding what we currently consider to be 911 * the "home" activity. 912 */ 913 ProcessRecord mHomeProcess; 914 915 /** 916 * This is the process holding the activity the user last visited that 917 * is in a different process from the one they are currently in. 918 */ 919 ProcessRecord mPreviousProcess; 920 921 /** 922 * The time at which the previous process was last visible. 923 */ 924 long mPreviousProcessVisibleTime; 925 926 /** 927 * Track all uids that have actively running processes. 928 */ 929 final SparseArray<UidRecord> mActiveUids = new SparseArray<>(); 930 931 /** 932 * This is for verifying the UID report flow. 933 */ 934 static final boolean VALIDATE_UID_STATES = true; 935 final SparseArray<UidRecord> mValidateUids = new SparseArray<>(); 936 937 /** 938 * Packages that the user has asked to have run in screen size 939 * compatibility mode instead of filling the screen. 940 */ 941 final CompatModePackages mCompatModePackages; 942 943 /** 944 * Set of IntentSenderRecord objects that are currently active. 945 */ 946 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 947 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 948 949 /** 950 * Fingerprints (hashCode()) of stack traces that we've 951 * already logged DropBox entries for. Guarded by itself. If 952 * something (rogue user app) forces this over 953 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 954 */ 955 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 956 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 957 958 /** 959 * Strict Mode background batched logging state. 960 * 961 * The string buffer is guarded by itself, and its lock is also 962 * used to determine if another batched write is already 963 * in-flight. 964 */ 965 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 966 967 /** 968 * Keeps track of all IIntentReceivers that have been registered for broadcasts. 969 * Hash keys are the receiver IBinder, hash value is a ReceiverList. 970 */ 971 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>(); 972 973 /** 974 * Resolver for broadcast intents to registered receivers. 975 * Holds BroadcastFilter (subclass of IntentFilter). 976 */ 977 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 978 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 979 @Override 980 protected boolean allowFilterResult( 981 BroadcastFilter filter, List<BroadcastFilter> dest) { 982 IBinder target = filter.receiverList.receiver.asBinder(); 983 for (int i = dest.size() - 1; i >= 0; i--) { 984 if (dest.get(i).receiverList.receiver.asBinder() == target) { 985 return false; 986 } 987 } 988 return true; 989 } 990 991 @Override 992 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 993 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 994 || userId == filter.owningUserId) { 995 return super.newResult(filter, match, userId); 996 } 997 return null; 998 } 999 1000 @Override 1001 protected BroadcastFilter[] newArray(int size) { 1002 return new BroadcastFilter[size]; 1003 } 1004 1005 @Override 1006 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 1007 return packageName.equals(filter.packageName); 1008 } 1009 }; 1010 1011 /** 1012 * State of all active sticky broadcasts per user. Keys are the action of the 1013 * sticky Intent, values are an ArrayList of all broadcasted intents with 1014 * that action (which should usually be one). The SparseArray is keyed 1015 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 1016 * for stickies that are sent to all users. 1017 */ 1018 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 1019 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 1020 1021 final ActiveServices mServices; 1022 1023 final static class Association { 1024 final int mSourceUid; 1025 final String mSourceProcess; 1026 final int mTargetUid; 1027 final ComponentName mTargetComponent; 1028 final String mTargetProcess; 1029 1030 int mCount; 1031 long mTime; 1032 1033 int mNesting; 1034 long mStartTime; 1035 1036 // states of the source process when the bind occurred. 1037 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1; 1038 long mLastStateUptime; 1039 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE 1040 - ActivityManager.MIN_PROCESS_STATE+1]; 1041 1042 Association(int sourceUid, String sourceProcess, int targetUid, 1043 ComponentName targetComponent, String targetProcess) { 1044 mSourceUid = sourceUid; 1045 mSourceProcess = sourceProcess; 1046 mTargetUid = targetUid; 1047 mTargetComponent = targetComponent; 1048 mTargetProcess = targetProcess; 1049 } 1050 } 1051 1052 /** 1053 * When service association tracking is enabled, this is all of the associations we 1054 * have seen. Mapping is target uid -> target component -> source uid -> source process name 1055 * -> association data. 1056 */ 1057 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>> 1058 mAssociations = new SparseArray<>(); 1059 boolean mTrackingAssociations; 1060 1061 /** 1062 * Backup/restore process management 1063 */ 1064 String mBackupAppName = null; 1065 BackupRecord mBackupTarget = null; 1066 1067 final ProviderMap mProviderMap; 1068 1069 /** 1070 * List of content providers who have clients waiting for them. The 1071 * application is currently being launched and the provider will be 1072 * removed from this list once it is published. 1073 */ 1074 final ArrayList<ContentProviderRecord> mLaunchingProviders 1075 = new ArrayList<ContentProviderRecord>(); 1076 1077 /** 1078 * File storing persisted {@link #mGrantedUriPermissions}. 1079 */ 1080 private final AtomicFile mGrantFile; 1081 1082 /** XML constants used in {@link #mGrantFile} */ 1083 private static final String TAG_URI_GRANTS = "uri-grants"; 1084 private static final String TAG_URI_GRANT = "uri-grant"; 1085 private static final String ATTR_USER_HANDLE = "userHandle"; 1086 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 1087 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 1088 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 1089 private static final String ATTR_TARGET_PKG = "targetPkg"; 1090 private static final String ATTR_URI = "uri"; 1091 private static final String ATTR_MODE_FLAGS = "modeFlags"; 1092 private static final String ATTR_CREATED_TIME = "createdTime"; 1093 private static final String ATTR_PREFIX = "prefix"; 1094 1095 /** 1096 * Global set of specific {@link Uri} permissions that have been granted. 1097 * This optimized lookup structure maps from {@link UriPermission#targetUid} 1098 * to {@link UriPermission#uri} to {@link UriPermission}. 1099 */ 1100 @GuardedBy("this") 1101 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 1102 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 1103 1104 public static class GrantUri { 1105 public final int sourceUserId; 1106 public final Uri uri; 1107 public boolean prefix; 1108 1109 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 1110 this.sourceUserId = sourceUserId; 1111 this.uri = uri; 1112 this.prefix = prefix; 1113 } 1114 1115 @Override 1116 public int hashCode() { 1117 int hashCode = 1; 1118 hashCode = 31 * hashCode + sourceUserId; 1119 hashCode = 31 * hashCode + uri.hashCode(); 1120 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 1121 return hashCode; 1122 } 1123 1124 @Override 1125 public boolean equals(Object o) { 1126 if (o instanceof GrantUri) { 1127 GrantUri other = (GrantUri) o; 1128 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 1129 && prefix == other.prefix; 1130 } 1131 return false; 1132 } 1133 1134 @Override 1135 public String toString() { 1136 String result = uri.toString() + " [user " + sourceUserId + "]"; 1137 if (prefix) result += " [prefix]"; 1138 return result; 1139 } 1140 1141 public String toSafeString() { 1142 String result = uri.toSafeString() + " [user " + sourceUserId + "]"; 1143 if (prefix) result += " [prefix]"; 1144 return result; 1145 } 1146 1147 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 1148 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 1149 ContentProvider.getUriWithoutUserId(uri), false); 1150 } 1151 } 1152 1153 CoreSettingsObserver mCoreSettingsObserver; 1154 1155 FontScaleSettingObserver mFontScaleSettingObserver; 1156 1157 private final class FontScaleSettingObserver extends ContentObserver { 1158 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE); 1159 1160 public FontScaleSettingObserver() { 1161 super(mHandler); 1162 ContentResolver resolver = mContext.getContentResolver(); 1163 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL); 1164 } 1165 1166 @Override 1167 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) { 1168 if (mFontScaleUri.equals(uri)) { 1169 updateFontScaleIfNeeded(userId); 1170 } 1171 } 1172 } 1173 1174 /** 1175 * Thread-local storage used to carry caller permissions over through 1176 * indirect content-provider access. 1177 */ 1178 private class Identity { 1179 public final IBinder token; 1180 public final int pid; 1181 public final int uid; 1182 1183 Identity(IBinder _token, int _pid, int _uid) { 1184 token = _token; 1185 pid = _pid; 1186 uid = _uid; 1187 } 1188 } 1189 1190 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 1191 1192 /** 1193 * All information we have collected about the runtime performance of 1194 * any user id that can impact battery performance. 1195 */ 1196 final BatteryStatsService mBatteryStatsService; 1197 1198 /** 1199 * Information about component usage 1200 */ 1201 UsageStatsManagerInternal mUsageStatsService; 1202 1203 /** 1204 * Access to DeviceIdleController service. 1205 */ 1206 DeviceIdleController.LocalService mLocalDeviceIdleController; 1207 1208 /** 1209 * Set of app ids that are whitelisted for device idle and thus background check. 1210 */ 1211 int[] mDeviceIdleWhitelist = new int[0]; 1212 1213 /** 1214 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message 1215 */ 1216 int[] mDeviceIdleTempWhitelist = new int[0]; 1217 1218 static final class PendingTempWhitelist { 1219 final int targetUid; 1220 final long duration; 1221 final String tag; 1222 1223 PendingTempWhitelist(int _targetUid, long _duration, String _tag) { 1224 targetUid = _targetUid; 1225 duration = _duration; 1226 tag = _tag; 1227 } 1228 } 1229 1230 final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>(); 1231 1232 /** 1233 * Information about and control over application operations 1234 */ 1235 final AppOpsService mAppOpsService; 1236 1237 /** Current sequencing integer of the configuration, for skipping old configurations. */ 1238 private int mConfigurationSeq; 1239 1240 /** 1241 * Temp object used when global and/or display override configuration is updated. It is also 1242 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust 1243 * anyone... 1244 */ 1245 private Configuration mTempConfig = new Configuration(); 1246 1247 private final UpdateConfigurationResult mTmpUpdateConfigurationResult = 1248 new UpdateConfigurationResult(); 1249 private static final class UpdateConfigurationResult { 1250 // Configuration changes that were updated. 1251 int changes; 1252 // If the activity was relaunched to match the new configuration. 1253 boolean activityRelaunched; 1254 1255 void reset() { 1256 changes = 0; 1257 activityRelaunched = false; 1258 } 1259 } 1260 1261 boolean mSuppressResizeConfigChanges; 1262 1263 /** 1264 * Hardware-reported OpenGLES version. 1265 */ 1266 final int GL_ES_VERSION; 1267 1268 /** 1269 * List of initialization arguments to pass to all processes when binding applications to them. 1270 * For example, references to the commonly used services. 1271 */ 1272 HashMap<String, IBinder> mAppBindArgs; 1273 HashMap<String, IBinder> mIsolatedAppBindArgs; 1274 1275 /** 1276 * Temporary to avoid allocations. Protected by main lock. 1277 */ 1278 final StringBuilder mStringBuilder = new StringBuilder(256); 1279 1280 /** 1281 * Used to control how we initialize the service. 1282 */ 1283 ComponentName mTopComponent; 1284 String mTopAction = Intent.ACTION_MAIN; 1285 String mTopData; 1286 1287 volatile boolean mProcessesReady = false; 1288 volatile boolean mSystemReady = false; 1289 volatile boolean mOnBattery = false; 1290 volatile int mFactoryTest; 1291 1292 @GuardedBy("this") boolean mBooting = false; 1293 @GuardedBy("this") boolean mCallFinishBooting = false; 1294 @GuardedBy("this") boolean mBootAnimationComplete = false; 1295 @GuardedBy("this") boolean mLaunchWarningShown = false; 1296 @GuardedBy("this") boolean mCheckedForSetup = false; 1297 1298 final Context mContext; 1299 1300 /** 1301 * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can 1302 * change at runtime. Use mContext for non-UI purposes. 1303 */ 1304 final Context mUiContext; 1305 1306 /** 1307 * The time at which we will allow normal application switches again, 1308 * after a call to {@link #stopAppSwitches()}. 1309 */ 1310 long mAppSwitchesAllowedTime; 1311 1312 /** 1313 * This is set to true after the first switch after mAppSwitchesAllowedTime 1314 * is set; any switches after that will clear the time. 1315 */ 1316 boolean mDidAppSwitch; 1317 1318 /** 1319 * Last time (in uptime) at which we checked for power usage. 1320 */ 1321 long mLastPowerCheckUptime; 1322 1323 /** 1324 * Set while we are wanting to sleep, to prevent any 1325 * activities from being started/resumed. 1326 * 1327 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping. 1328 * 1329 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true 1330 * while in the sleep state until there is a pending transition out of sleep, in which case 1331 * mSleeping is set to false, and remains false while awake. 1332 * 1333 * Whether mSleeping can quickly toggled between true/false without the device actually 1334 * display changing states is undefined. 1335 */ 1336 private boolean mSleeping = false; 1337 1338 /** 1339 * The process state used for processes that are running the top activities. 1340 * This changes between TOP and TOP_SLEEPING to following mSleeping. 1341 */ 1342 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP; 1343 1344 /** 1345 * Set while we are running a voice interaction. This overrides 1346 * sleeping while it is active. 1347 */ 1348 IVoiceInteractionSession mRunningVoice; 1349 1350 /** 1351 * For some direct access we need to power manager. 1352 */ 1353 PowerManagerInternal mLocalPowerManager; 1354 1355 /** 1356 * We want to hold a wake lock while running a voice interaction session, since 1357 * this may happen with the screen off and we need to keep the CPU running to 1358 * be able to continue to interact with the user. 1359 */ 1360 PowerManager.WakeLock mVoiceWakeLock; 1361 1362 /** 1363 * State of external calls telling us if the device is awake or asleep. 1364 */ 1365 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 1366 1367 /** 1368 * Set if we are shutting down the system, similar to sleeping. 1369 */ 1370 boolean mShuttingDown = false; 1371 1372 /** 1373 * Current sequence id for oom_adj computation traversal. 1374 */ 1375 int mAdjSeq = 0; 1376 1377 /** 1378 * Current sequence id for process LRU updating. 1379 */ 1380 int mLruSeq = 0; 1381 1382 /** 1383 * Keep track of the non-cached/empty process we last found, to help 1384 * determine how to distribute cached/empty processes next time. 1385 */ 1386 int mNumNonCachedProcs = 0; 1387 1388 /** 1389 * Keep track of the number of cached hidden procs, to balance oom adj 1390 * distribution between those and empty procs. 1391 */ 1392 int mNumCachedHiddenProcs = 0; 1393 1394 /** 1395 * Keep track of the number of service processes we last found, to 1396 * determine on the next iteration which should be B services. 1397 */ 1398 int mNumServiceProcs = 0; 1399 int mNewNumAServiceProcs = 0; 1400 int mNewNumServiceProcs = 0; 1401 1402 /** 1403 * Allow the current computed overall memory level of the system to go down? 1404 * This is set to false when we are killing processes for reasons other than 1405 * memory management, so that the now smaller process list will not be taken as 1406 * an indication that memory is tighter. 1407 */ 1408 boolean mAllowLowerMemLevel = false; 1409 1410 /** 1411 * The last computed memory level, for holding when we are in a state that 1412 * processes are going away for other reasons. 1413 */ 1414 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1415 1416 /** 1417 * The last total number of process we have, to determine if changes actually look 1418 * like a shrinking number of process due to lower RAM. 1419 */ 1420 int mLastNumProcesses; 1421 1422 /** 1423 * The uptime of the last time we performed idle maintenance. 1424 */ 1425 long mLastIdleTime = SystemClock.uptimeMillis(); 1426 1427 /** 1428 * Total time spent with RAM that has been added in the past since the last idle time. 1429 */ 1430 long mLowRamTimeSinceLastIdle = 0; 1431 1432 /** 1433 * If RAM is currently low, when that horrible situation started. 1434 */ 1435 long mLowRamStartTime = 0; 1436 1437 /** 1438 * For reporting to battery stats the current top application. 1439 */ 1440 private String mCurResumedPackage = null; 1441 private int mCurResumedUid = -1; 1442 1443 /** 1444 * For reporting to battery stats the apps currently running foreground 1445 * service. The ProcessMap is package/uid tuples; each of these contain 1446 * an array of the currently foreground processes. 1447 */ 1448 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1449 = new ProcessMap<ArrayList<ProcessRecord>>(); 1450 1451 /** 1452 * Set if the systemServer made a call to enterSafeMode. 1453 */ 1454 boolean mSafeMode; 1455 1456 /** 1457 * If true, we are running under a test environment so will sample PSS from processes 1458 * much more rapidly to try to collect better data when the tests are rapidly 1459 * running through apps. 1460 */ 1461 boolean mTestPssMode = false; 1462 1463 String mDebugApp = null; 1464 boolean mWaitForDebugger = false; 1465 boolean mDebugTransient = false; 1466 String mOrigDebugApp = null; 1467 boolean mOrigWaitForDebugger = false; 1468 boolean mAlwaysFinishActivities = false; 1469 boolean mForceResizableActivities; 1470 /** 1471 * Flag that indicates if multi-window is enabled. 1472 * 1473 * For any particular form of multi-window to be enabled, generic multi-window must be enabled 1474 * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or 1475 * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set. 1476 * At least one of the forms of multi-window must be enabled in order for this flag to be 1477 * initialized to 'true'. 1478 * 1479 * @see #mSupportsSplitScreenMultiWindow 1480 * @see #mSupportsFreeformWindowManagement 1481 * @see #mSupportsPictureInPicture 1482 * @see #mSupportsMultiDisplay 1483 */ 1484 boolean mSupportsMultiWindow; 1485 boolean mSupportsSplitScreenMultiWindow; 1486 boolean mSupportsFreeformWindowManagement; 1487 boolean mSupportsPictureInPicture; 1488 boolean mSupportsMultiDisplay; 1489 boolean mSupportsLeanbackOnly; 1490 IActivityController mController = null; 1491 boolean mControllerIsAMonkey = false; 1492 String mProfileApp = null; 1493 ProcessRecord mProfileProc = null; 1494 ProfilerInfo mProfilerInfo = null; 1495 int mProfileType = 0; 1496 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>(); 1497 String mMemWatchDumpProcName; 1498 String mMemWatchDumpFile; 1499 int mMemWatchDumpPid; 1500 int mMemWatchDumpUid; 1501 String mTrackAllocationApp = null; 1502 String mNativeDebuggingApp = null; 1503 1504 final long[] mTmpLong = new long[2]; 1505 1506 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet(); 1507 1508 /** 1509 * A global counter for generating sequence numbers. 1510 * This value will be used when incrementing sequence numbers in individual uidRecords. 1511 * 1512 * Having a global counter ensures that seq numbers are monotonically increasing for a 1513 * particular uid even when the uidRecord is re-created. 1514 */ 1515 @GuardedBy("this") 1516 @VisibleForTesting 1517 long mProcStateSeqCounter = 0; 1518 1519 private final Injector mInjector; 1520 1521 static final class ProcessChangeItem { 1522 static final int CHANGE_ACTIVITIES = 1<<0; 1523 int changes; 1524 int uid; 1525 int pid; 1526 int processState; 1527 boolean foregroundActivities; 1528 } 1529 1530 static final class UidObserverRegistration { 1531 final int uid; 1532 final String pkg; 1533 final int which; 1534 final int cutpoint; 1535 1536 final SparseIntArray lastProcStates; 1537 1538 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) { 1539 uid = _uid; 1540 pkg = _pkg; 1541 which = _which; 1542 cutpoint = _cutpoint; 1543 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) { 1544 lastProcStates = new SparseIntArray(); 1545 } else { 1546 lastProcStates = null; 1547 } 1548 } 1549 } 1550 1551 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>(); 1552 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1553 1554 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>(); 1555 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>(); 1556 1557 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>(); 1558 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5]; 1559 1560 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>(); 1561 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>(); 1562 1563 OomAdjObserver mCurOomAdjObserver; 1564 int mCurOomAdjUid; 1565 1566 interface OomAdjObserver { 1567 void onOomAdjMessage(String msg); 1568 } 1569 1570 /** 1571 * Runtime CPU use collection thread. This object's lock is used to 1572 * perform synchronization with the thread (notifying it to run). 1573 */ 1574 final Thread mProcessCpuThread; 1575 1576 /** 1577 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1578 * Must acquire this object's lock when accessing it. 1579 * NOTE: this lock will be held while doing long operations (trawling 1580 * through all processes in /proc), so it should never be acquired by 1581 * any critical paths such as when holding the main activity manager lock. 1582 */ 1583 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1584 MONITOR_THREAD_CPU_USAGE); 1585 final AtomicLong mLastCpuTime = new AtomicLong(0); 1586 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1587 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1); 1588 1589 long mLastWriteTime = 0; 1590 1591 /** 1592 * Used to retain an update lock when the foreground activity is in 1593 * immersive mode. 1594 */ 1595 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1596 1597 /** 1598 * Set to true after the system has finished booting. 1599 */ 1600 boolean mBooted = false; 1601 1602 WindowManagerService mWindowManager; 1603 final ActivityThread mSystemThread; 1604 1605 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1606 final ProcessRecord mApp; 1607 final int mPid; 1608 final IApplicationThread mAppThread; 1609 1610 AppDeathRecipient(ProcessRecord app, int pid, 1611 IApplicationThread thread) { 1612 if (DEBUG_ALL) Slog.v( 1613 TAG, "New death recipient " + this 1614 + " for thread " + thread.asBinder()); 1615 mApp = app; 1616 mPid = pid; 1617 mAppThread = thread; 1618 } 1619 1620 @Override 1621 public void binderDied() { 1622 if (DEBUG_ALL) Slog.v( 1623 TAG, "Death received in " + this 1624 + " for thread " + mAppThread.asBinder()); 1625 synchronized(ActivityManagerService.this) { 1626 appDiedLocked(mApp, mPid, mAppThread, true); 1627 } 1628 } 1629 } 1630 1631 static final int SHOW_ERROR_UI_MSG = 1; 1632 static final int SHOW_NOT_RESPONDING_UI_MSG = 2; 1633 static final int SHOW_FACTORY_ERROR_UI_MSG = 3; 1634 static final int UPDATE_CONFIGURATION_MSG = 4; 1635 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1636 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6; 1637 static final int SERVICE_TIMEOUT_MSG = 12; 1638 static final int UPDATE_TIME_ZONE = 13; 1639 static final int SHOW_UID_ERROR_UI_MSG = 14; 1640 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15; 1641 static final int PROC_START_TIMEOUT_MSG = 20; 1642 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1643 static final int KILL_APPLICATION_MSG = 22; 1644 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1645 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1646 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1647 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26; 1648 static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27; 1649 static final int CLEAR_DNS_CACHE_MSG = 28; 1650 static final int UPDATE_HTTP_PROXY_MSG = 29; 1651 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30; 1652 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31; 1653 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32; 1654 static final int REPORT_MEM_USAGE_MSG = 33; 1655 static final int REPORT_USER_SWITCH_MSG = 34; 1656 static final int CONTINUE_USER_SWITCH_MSG = 35; 1657 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1658 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1659 static final int PERSIST_URI_GRANTS_MSG = 38; 1660 static final int REQUEST_ALL_PSS_MSG = 39; 1661 static final int START_PROFILES_MSG = 40; 1662 static final int UPDATE_TIME_PREFERENCE_MSG = 41; 1663 static final int SYSTEM_USER_START_MSG = 42; 1664 static final int SYSTEM_USER_CURRENT_MSG = 43; 1665 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1666 static final int FINISH_BOOTING_MSG = 45; 1667 static final int START_USER_SWITCH_UI_MSG = 46; 1668 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1669 static final int DISMISS_DIALOG_UI_MSG = 48; 1670 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49; 1671 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50; 1672 static final int DELETE_DUMPHEAP_MSG = 51; 1673 static final int FOREGROUND_PROFILE_CHANGED_MSG = 52; 1674 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53; 1675 static final int REPORT_TIME_TRACKER_MSG = 54; 1676 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55; 1677 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56; 1678 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57; 1679 static final int IDLE_UIDS_MSG = 58; 1680 static final int SYSTEM_USER_UNLOCK_MSG = 59; 1681 static final int LOG_STACK_STATE = 60; 1682 static final int VR_MODE_CHANGE_MSG = 61; 1683 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62; 1684 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63; 1685 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64; 1686 static final int NOTIFY_VR_SLEEPING_MSG = 65; 1687 static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66; 1688 static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67; 1689 static final int PUSH_TEMP_WHITELIST_UI_MSG = 68; 1690 static final int SERVICE_FOREGROUND_CRASH_MSG = 69; 1691 static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70; 1692 static final int START_USER_SWITCH_FG_MSG = 712; 1693 static final int NOTIFY_VR_KEYGUARD_MSG = 74; 1694 1695 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1696 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1697 static final int FIRST_COMPAT_MODE_MSG = 300; 1698 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1699 1700 static ServiceThread sKillThread = null; 1701 static KillHandler sKillHandler = null; 1702 1703 CompatModeDialog mCompatModeDialog; 1704 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog; 1705 long mLastMemUsageReportTime = 0; 1706 1707 /** 1708 * Flag whether the current user is a "monkey", i.e. whether 1709 * the UI is driven by a UI automation tool. 1710 */ 1711 private boolean mUserIsMonkey; 1712 1713 /** Flag whether the device has a Recents UI */ 1714 boolean mHasRecents; 1715 1716 /** The dimensions of the thumbnails in the Recents UI. */ 1717 int mThumbnailWidth; 1718 int mThumbnailHeight; 1719 float mFullscreenThumbnailScale; 1720 1721 final ServiceThread mHandlerThread; 1722 final MainHandler mHandler; 1723 final Handler mUiHandler; 1724 1725 final ActivityManagerConstants mConstants; 1726 1727 PackageManagerInternal mPackageManagerInt; 1728 1729 // VoiceInteraction session ID that changes for each new request except when 1730 // being called for multiwindow assist in a single session. 1731 private int mViSessionId = 1000; 1732 1733 final boolean mPermissionReviewRequired; 1734 1735 private static String sTheRealBuildSerial = Build.UNKNOWN; 1736 1737 /** 1738 * Current global configuration information. Contains general settings for the entire system, 1739 * also corresponds to the merged configuration of the default display. 1740 */ 1741 Configuration getGlobalConfiguration() { 1742 return mStackSupervisor.getConfiguration(); 1743 } 1744 1745 final class KillHandler extends Handler { 1746 static final int KILL_PROCESS_GROUP_MSG = 4000; 1747 1748 public KillHandler(Looper looper) { 1749 super(looper, null, true); 1750 } 1751 1752 @Override 1753 public void handleMessage(Message msg) { 1754 switch (msg.what) { 1755 case KILL_PROCESS_GROUP_MSG: 1756 { 1757 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup"); 1758 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */); 1759 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1760 } 1761 break; 1762 1763 default: 1764 super.handleMessage(msg); 1765 } 1766 } 1767 } 1768 1769 final class UiHandler extends Handler { 1770 public UiHandler() { 1771 super(com.android.server.UiThread.get().getLooper(), null, true); 1772 } 1773 1774 @Override 1775 public void handleMessage(Message msg) { 1776 switch (msg.what) { 1777 case SHOW_ERROR_UI_MSG: { 1778 mAppErrors.handleShowAppErrorUi(msg); 1779 ensureBootCompleted(); 1780 } break; 1781 case SHOW_NOT_RESPONDING_UI_MSG: { 1782 mAppErrors.handleShowAnrUi(msg); 1783 ensureBootCompleted(); 1784 } break; 1785 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: { 1786 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1787 synchronized (ActivityManagerService.this) { 1788 ProcessRecord proc = (ProcessRecord) data.get("app"); 1789 if (proc == null) { 1790 Slog.e(TAG, "App not found when showing strict mode dialog."); 1791 break; 1792 } 1793 if (proc.crashDialog != null) { 1794 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1795 return; 1796 } 1797 AppErrorResult res = (AppErrorResult) data.get("result"); 1798 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1799 Dialog d = new StrictModeViolationDialog(mUiContext, 1800 ActivityManagerService.this, res, proc); 1801 d.show(); 1802 proc.crashDialog = d; 1803 } else { 1804 // The device is asleep, so just pretend that the user 1805 // saw a crash dialog and hit "force quit". 1806 res.set(0); 1807 } 1808 } 1809 ensureBootCompleted(); 1810 } break; 1811 case SHOW_FACTORY_ERROR_UI_MSG: { 1812 Dialog d = new FactoryErrorDialog( 1813 mUiContext, msg.getData().getCharSequence("msg")); 1814 d.show(); 1815 ensureBootCompleted(); 1816 } break; 1817 case WAIT_FOR_DEBUGGER_UI_MSG: { 1818 synchronized (ActivityManagerService.this) { 1819 ProcessRecord app = (ProcessRecord)msg.obj; 1820 if (msg.arg1 != 0) { 1821 if (!app.waitedForDebugger) { 1822 Dialog d = new AppWaitingForDebuggerDialog( 1823 ActivityManagerService.this, 1824 mUiContext, app); 1825 app.waitDialog = d; 1826 app.waitedForDebugger = true; 1827 d.show(); 1828 } 1829 } else { 1830 if (app.waitDialog != null) { 1831 app.waitDialog.dismiss(); 1832 app.waitDialog = null; 1833 } 1834 } 1835 } 1836 } break; 1837 case SHOW_UID_ERROR_UI_MSG: { 1838 if (mShowDialogs) { 1839 AlertDialog d = new BaseErrorDialog(mUiContext); 1840 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1841 d.setCancelable(false); 1842 d.setTitle(mUiContext.getText(R.string.android_system_label)); 1843 d.setMessage(mUiContext.getText(R.string.system_error_wipe_data)); 1844 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok), 1845 obtainMessage(DISMISS_DIALOG_UI_MSG, d)); 1846 d.show(); 1847 } 1848 } break; 1849 case SHOW_FINGERPRINT_ERROR_UI_MSG: { 1850 if (mShowDialogs) { 1851 AlertDialog d = new BaseErrorDialog(mUiContext); 1852 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1853 d.setCancelable(false); 1854 d.setTitle(mUiContext.getText(R.string.android_system_label)); 1855 d.setMessage(mUiContext.getText(R.string.system_error_manufacturer)); 1856 d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok), 1857 obtainMessage(DISMISS_DIALOG_UI_MSG, d)); 1858 d.show(); 1859 } 1860 } break; 1861 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: { 1862 synchronized (ActivityManagerService.this) { 1863 ActivityRecord ar = (ActivityRecord) msg.obj; 1864 if (mCompatModeDialog != null) { 1865 if (mCompatModeDialog.mAppInfo.packageName.equals( 1866 ar.info.applicationInfo.packageName)) { 1867 return; 1868 } 1869 mCompatModeDialog.dismiss(); 1870 mCompatModeDialog = null; 1871 } 1872 if (ar != null && false) { 1873 if (mCompatModePackages.getPackageAskCompatModeLocked( 1874 ar.packageName)) { 1875 int mode = mCompatModePackages.computeCompatModeLocked( 1876 ar.info.applicationInfo); 1877 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1878 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1879 mCompatModeDialog = new CompatModeDialog( 1880 ActivityManagerService.this, mUiContext, 1881 ar.info.applicationInfo); 1882 mCompatModeDialog.show(); 1883 } 1884 } 1885 } 1886 } 1887 break; 1888 } 1889 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: { 1890 synchronized (ActivityManagerService.this) { 1891 final ActivityRecord ar = (ActivityRecord) msg.obj; 1892 if (mUnsupportedDisplaySizeDialog != null) { 1893 mUnsupportedDisplaySizeDialog.dismiss(); 1894 mUnsupportedDisplaySizeDialog = null; 1895 } 1896 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked( 1897 ar.packageName)) { 1898 // TODO(multi-display): Show dialog on appropriate display. 1899 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog( 1900 ActivityManagerService.this, mUiContext, ar.info.applicationInfo); 1901 mUnsupportedDisplaySizeDialog.show(); 1902 } 1903 } 1904 break; 1905 } 1906 case START_USER_SWITCH_UI_MSG: { 1907 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj); 1908 break; 1909 } 1910 case DISMISS_DIALOG_UI_MSG: { 1911 final Dialog d = (Dialog) msg.obj; 1912 d.dismiss(); 1913 break; 1914 } 1915 case DISPATCH_PROCESSES_CHANGED_UI_MSG: { 1916 dispatchProcessesChanged(); 1917 break; 1918 } 1919 case DISPATCH_PROCESS_DIED_UI_MSG: { 1920 final int pid = msg.arg1; 1921 final int uid = msg.arg2; 1922 dispatchProcessDied(pid, uid); 1923 break; 1924 } 1925 case DISPATCH_UIDS_CHANGED_UI_MSG: { 1926 dispatchUidsChanged(); 1927 } break; 1928 case DISPATCH_OOM_ADJ_OBSERVER_MSG: { 1929 dispatchOomAdjObserver((String)msg.obj); 1930 } break; 1931 case PUSH_TEMP_WHITELIST_UI_MSG: { 1932 pushTempWhitelist(); 1933 } break; 1934 } 1935 } 1936 } 1937 1938 final class MainHandler extends Handler { 1939 public MainHandler(Looper looper) { 1940 super(looper, null, true); 1941 } 1942 1943 @Override 1944 public void handleMessage(Message msg) { 1945 switch (msg.what) { 1946 case UPDATE_CONFIGURATION_MSG: { 1947 final ContentResolver resolver = mContext.getContentResolver(); 1948 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj, 1949 msg.arg1); 1950 } break; 1951 case GC_BACKGROUND_PROCESSES_MSG: { 1952 synchronized (ActivityManagerService.this) { 1953 performAppGcsIfAppropriateLocked(); 1954 } 1955 } break; 1956 case SERVICE_TIMEOUT_MSG: { 1957 mServices.serviceTimeout((ProcessRecord)msg.obj); 1958 } break; 1959 case SERVICE_FOREGROUND_TIMEOUT_MSG: { 1960 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj); 1961 } break; 1962 case SERVICE_FOREGROUND_CRASH_MSG: { 1963 mServices.serviceForegroundCrash((ProcessRecord)msg.obj); 1964 } break; 1965 case DISPATCH_PENDING_INTENT_CANCEL_MSG: { 1966 RemoteCallbackList<IResultReceiver> callbacks 1967 = (RemoteCallbackList<IResultReceiver>)msg.obj; 1968 int N = callbacks.beginBroadcast(); 1969 for (int i = 0; i < N; i++) { 1970 try { 1971 callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null); 1972 } catch (RemoteException e) { 1973 } 1974 } 1975 callbacks.finishBroadcast(); 1976 } break; 1977 case UPDATE_TIME_ZONE: { 1978 synchronized (ActivityManagerService.this) { 1979 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1980 ProcessRecord r = mLruProcesses.get(i); 1981 if (r.thread != null) { 1982 try { 1983 r.thread.updateTimeZone(); 1984 } catch (RemoteException ex) { 1985 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1986 } 1987 } 1988 } 1989 } 1990 } break; 1991 case CLEAR_DNS_CACHE_MSG: { 1992 synchronized (ActivityManagerService.this) { 1993 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1994 ProcessRecord r = mLruProcesses.get(i); 1995 if (r.thread != null) { 1996 try { 1997 r.thread.clearDnsCache(); 1998 } catch (RemoteException ex) { 1999 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 2000 } 2001 } 2002 } 2003 } 2004 } break; 2005 case UPDATE_HTTP_PROXY_MSG: { 2006 ProxyInfo proxy = (ProxyInfo)msg.obj; 2007 String host = ""; 2008 String port = ""; 2009 String exclList = ""; 2010 Uri pacFileUrl = Uri.EMPTY; 2011 if (proxy != null) { 2012 host = proxy.getHost(); 2013 port = Integer.toString(proxy.getPort()); 2014 exclList = proxy.getExclusionListAsString(); 2015 pacFileUrl = proxy.getPacFileUrl(); 2016 } 2017 synchronized (ActivityManagerService.this) { 2018 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 2019 ProcessRecord r = mLruProcesses.get(i); 2020 if (r.thread != null) { 2021 try { 2022 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 2023 } catch (RemoteException ex) { 2024 Slog.w(TAG, "Failed to update http proxy for: " + 2025 r.info.processName); 2026 } 2027 } 2028 } 2029 } 2030 } break; 2031 case PROC_START_TIMEOUT_MSG: { 2032 ProcessRecord app = (ProcessRecord)msg.obj; 2033 synchronized (ActivityManagerService.this) { 2034 processStartTimedOutLocked(app); 2035 } 2036 } break; 2037 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: { 2038 ProcessRecord app = (ProcessRecord)msg.obj; 2039 synchronized (ActivityManagerService.this) { 2040 processContentProviderPublishTimedOutLocked(app); 2041 } 2042 } break; 2043 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 2044 synchronized (ActivityManagerService.this) { 2045 mActivityStarter.doPendingActivityLaunchesLocked(true); 2046 } 2047 } break; 2048 case KILL_APPLICATION_MSG: { 2049 synchronized (ActivityManagerService.this) { 2050 final int appId = msg.arg1; 2051 final int userId = msg.arg2; 2052 Bundle bundle = (Bundle)msg.obj; 2053 String pkg = bundle.getString("pkg"); 2054 String reason = bundle.getString("reason"); 2055 forceStopPackageLocked(pkg, appId, false, false, true, false, 2056 false, userId, reason); 2057 } 2058 } break; 2059 case FINALIZE_PENDING_INTENT_MSG: { 2060 ((PendingIntentRecord)msg.obj).completeFinalize(); 2061 } break; 2062 case POST_HEAVY_NOTIFICATION_MSG: { 2063 INotificationManager inm = NotificationManager.getService(); 2064 if (inm == null) { 2065 return; 2066 } 2067 2068 ActivityRecord root = (ActivityRecord)msg.obj; 2069 ProcessRecord process = root.app; 2070 if (process == null) { 2071 return; 2072 } 2073 2074 try { 2075 Context context = mContext.createPackageContext(process.info.packageName, 0); 2076 String text = mContext.getString(R.string.heavy_weight_notification, 2077 context.getApplicationInfo().loadLabel(context.getPackageManager())); 2078 Notification notification = 2079 new Notification.Builder(context, SystemNotificationChannels.DEVELOPER) 2080 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) 2081 .setWhen(0) 2082 .setOngoing(true) 2083 .setTicker(text) 2084 .setColor(mContext.getColor( 2085 com.android.internal.R.color.system_notification_accent_color)) 2086 .setContentTitle(text) 2087 .setContentText( 2088 mContext.getText(R.string.heavy_weight_notification_detail)) 2089 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0, 2090 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null, 2091 new UserHandle(root.userId))) 2092 .build(); 2093 try { 2094 inm.enqueueNotificationWithTag("android", "android", null, 2095 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, 2096 notification, root.userId); 2097 } catch (RuntimeException e) { 2098 Slog.w(ActivityManagerService.TAG, 2099 "Error showing notification for heavy-weight app", e); 2100 } catch (RemoteException e) { 2101 } 2102 } catch (NameNotFoundException e) { 2103 Slog.w(TAG, "Unable to create context for heavy notification", e); 2104 } 2105 } break; 2106 case CANCEL_HEAVY_NOTIFICATION_MSG: { 2107 INotificationManager inm = NotificationManager.getService(); 2108 if (inm == null) { 2109 return; 2110 } 2111 try { 2112 inm.cancelNotificationWithTag("android", null, 2113 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, msg.arg1); 2114 } catch (RuntimeException e) { 2115 Slog.w(ActivityManagerService.TAG, 2116 "Error canceling notification for service", e); 2117 } catch (RemoteException e) { 2118 } 2119 } break; 2120 case CHECK_EXCESSIVE_POWER_USE_MSG: { 2121 synchronized (ActivityManagerService.this) { 2122 checkExcessivePowerUsageLocked(); 2123 removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG); 2124 Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG); 2125 sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL); 2126 } 2127 } break; 2128 case REPORT_MEM_USAGE_MSG: { 2129 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 2130 Thread thread = new Thread() { 2131 @Override public void run() { 2132 reportMemUsage(memInfos); 2133 } 2134 }; 2135 thread.start(); 2136 break; 2137 } 2138 case START_USER_SWITCH_FG_MSG: { 2139 mUserController.startUserInForeground(msg.arg1); 2140 break; 2141 } 2142 case REPORT_USER_SWITCH_MSG: { 2143 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2); 2144 break; 2145 } 2146 case CONTINUE_USER_SWITCH_MSG: { 2147 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2); 2148 break; 2149 } 2150 case USER_SWITCH_TIMEOUT_MSG: { 2151 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2); 2152 break; 2153 } 2154 case IMMERSIVE_MODE_LOCK_MSG: { 2155 final boolean nextState = (msg.arg1 != 0); 2156 if (mUpdateLock.isHeld() != nextState) { 2157 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, 2158 "Applying new update lock state '" + nextState 2159 + "' for " + (ActivityRecord)msg.obj); 2160 if (nextState) { 2161 mUpdateLock.acquire(); 2162 } else { 2163 mUpdateLock.release(); 2164 } 2165 } 2166 break; 2167 } 2168 case PERSIST_URI_GRANTS_MSG: { 2169 writeGrantedUriPermissions(); 2170 break; 2171 } 2172 case REQUEST_ALL_PSS_MSG: { 2173 synchronized (ActivityManagerService.this) { 2174 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 2175 } 2176 break; 2177 } 2178 case START_PROFILES_MSG: { 2179 synchronized (ActivityManagerService.this) { 2180 mUserController.startProfilesLocked(); 2181 } 2182 break; 2183 } 2184 case UPDATE_TIME_PREFERENCE_MSG: { 2185 // The user's time format preference might have changed. 2186 // For convenience we re-use the Intent extra values. 2187 synchronized (ActivityManagerService.this) { 2188 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 2189 ProcessRecord r = mLruProcesses.get(i); 2190 if (r.thread != null) { 2191 try { 2192 r.thread.updateTimePrefs(msg.arg1); 2193 } catch (RemoteException ex) { 2194 Slog.w(TAG, "Failed to update preferences for: " 2195 + r.info.processName); 2196 } 2197 } 2198 } 2199 } 2200 break; 2201 } 2202 case SYSTEM_USER_START_MSG: { 2203 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 2204 Integer.toString(msg.arg1), msg.arg1); 2205 mSystemServiceManager.startUser(msg.arg1); 2206 break; 2207 } 2208 case SYSTEM_USER_UNLOCK_MSG: { 2209 final int userId = msg.arg1; 2210 mSystemServiceManager.unlockUser(userId); 2211 synchronized (ActivityManagerService.this) { 2212 mRecentTasks.loadUserRecentsLocked(userId); 2213 } 2214 if (userId == UserHandle.USER_SYSTEM) { 2215 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE); 2216 } 2217 installEncryptionUnawareProviders(userId); 2218 mUserController.finishUserUnlocked((UserState) msg.obj); 2219 break; 2220 } 2221 case SYSTEM_USER_CURRENT_MSG: { 2222 mBatteryStatsService.noteEvent( 2223 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 2224 Integer.toString(msg.arg2), msg.arg2); 2225 mBatteryStatsService.noteEvent( 2226 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 2227 Integer.toString(msg.arg1), msg.arg1); 2228 mSystemServiceManager.switchUser(msg.arg1); 2229 break; 2230 } 2231 case ENTER_ANIMATION_COMPLETE_MSG: { 2232 synchronized (ActivityManagerService.this) { 2233 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj); 2234 if (r != null && r.app != null && r.app.thread != null) { 2235 try { 2236 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 2237 } catch (RemoteException e) { 2238 } 2239 } 2240 } 2241 break; 2242 } 2243 case FINISH_BOOTING_MSG: { 2244 if (msg.arg1 != 0) { 2245 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting"); 2246 finishBooting(); 2247 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 2248 } 2249 if (msg.arg2 != 0) { 2250 enableScreenAfterBoot(); 2251 } 2252 break; 2253 } 2254 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 2255 try { 2256 Locale l = (Locale) msg.obj; 2257 IBinder service = ServiceManager.getService("mount"); 2258 IStorageManager storageManager = IStorageManager.Stub.asInterface(service); 2259 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 2260 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 2261 } catch (RemoteException e) { 2262 Log.e(TAG, "Error storing locale for decryption UI", e); 2263 } 2264 break; 2265 } 2266 case NOTIFY_CLEARTEXT_NETWORK_MSG: { 2267 final int uid = msg.arg1; 2268 final byte[] firstPacket = (byte[]) msg.obj; 2269 2270 synchronized (mPidsSelfLocked) { 2271 for (int i = 0; i < mPidsSelfLocked.size(); i++) { 2272 final ProcessRecord p = mPidsSelfLocked.valueAt(i); 2273 if (p.uid == uid) { 2274 try { 2275 p.thread.notifyCleartextNetwork(firstPacket); 2276 } catch (RemoteException ignored) { 2277 } 2278 } 2279 } 2280 } 2281 break; 2282 } 2283 case POST_DUMP_HEAP_NOTIFICATION_MSG: { 2284 final String procName; 2285 final int uid; 2286 final long memLimit; 2287 final String reportPackage; 2288 synchronized (ActivityManagerService.this) { 2289 procName = mMemWatchDumpProcName; 2290 uid = mMemWatchDumpUid; 2291 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid); 2292 if (val == null) { 2293 val = mMemWatchProcesses.get(procName, 0); 2294 } 2295 if (val != null) { 2296 memLimit = val.first; 2297 reportPackage = val.second; 2298 } else { 2299 memLimit = 0; 2300 reportPackage = null; 2301 } 2302 } 2303 if (procName == null) { 2304 return; 2305 } 2306 2307 if (DEBUG_PSS) Slog.d(TAG_PSS, 2308 "Showing dump heap notification from " + procName + "/" + uid); 2309 2310 INotificationManager inm = NotificationManager.getService(); 2311 if (inm == null) { 2312 return; 2313 } 2314 2315 String text = mContext.getString(R.string.dump_heap_notification, procName); 2316 2317 2318 Intent deleteIntent = new Intent(); 2319 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP); 2320 Intent intent = new Intent(); 2321 intent.setClassName("android", DumpHeapActivity.class.getName()); 2322 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName); 2323 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit); 2324 if (reportPackage != null) { 2325 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage); 2326 } 2327 int userId = UserHandle.getUserId(uid); 2328 Notification notification = 2329 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER) 2330 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) 2331 .setWhen(0) 2332 .setOngoing(true) 2333 .setAutoCancel(true) 2334 .setTicker(text) 2335 .setColor(mContext.getColor( 2336 com.android.internal.R.color.system_notification_accent_color)) 2337 .setContentTitle(text) 2338 .setContentText( 2339 mContext.getText(R.string.dump_heap_notification_detail)) 2340 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0, 2341 intent, PendingIntent.FLAG_CANCEL_CURRENT, null, 2342 new UserHandle(userId))) 2343 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0, 2344 deleteIntent, 0, UserHandle.SYSTEM)) 2345 .build(); 2346 2347 try { 2348 inm.enqueueNotificationWithTag("android", "android", null, 2349 SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION, 2350 notification, userId); 2351 } catch (RuntimeException e) { 2352 Slog.w(ActivityManagerService.TAG, 2353 "Error showing notification for dump heap", e); 2354 } catch (RemoteException e) { 2355 } 2356 } break; 2357 case DELETE_DUMPHEAP_MSG: { 2358 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(), 2359 null, DumpHeapActivity.JAVA_URI, 2360 Intent.FLAG_GRANT_READ_URI_PERMISSION 2361 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 2362 UserHandle.myUserId()); 2363 synchronized (ActivityManagerService.this) { 2364 mMemWatchDumpFile = null; 2365 mMemWatchDumpProcName = null; 2366 mMemWatchDumpPid = -1; 2367 mMemWatchDumpUid = -1; 2368 } 2369 } break; 2370 case FOREGROUND_PROFILE_CHANGED_MSG: { 2371 mUserController.dispatchForegroundProfileChanged(msg.arg1); 2372 } break; 2373 case REPORT_TIME_TRACKER_MSG: { 2374 AppTimeTracker tracker = (AppTimeTracker)msg.obj; 2375 tracker.deliverResult(mContext); 2376 } break; 2377 case REPORT_USER_SWITCH_COMPLETE_MSG: { 2378 mUserController.dispatchUserSwitchComplete(msg.arg1); 2379 } break; 2380 case REPORT_LOCKED_BOOT_COMPLETE_MSG: { 2381 mUserController.dispatchLockedBootComplete(msg.arg1); 2382 } break; 2383 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: { 2384 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj; 2385 try { 2386 connection.shutdown(); 2387 } catch (RemoteException e) { 2388 Slog.w(TAG, "Error shutting down UiAutomationConnection"); 2389 } 2390 // Only a UiAutomation can set this flag and now that 2391 // it is finished we make sure it is reset to its default. 2392 mUserIsMonkey = false; 2393 } break; 2394 case IDLE_UIDS_MSG: { 2395 idleUids(); 2396 } break; 2397 case VR_MODE_CHANGE_MSG: { 2398 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) { 2399 return; 2400 } 2401 synchronized (ActivityManagerService.this) { 2402 final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked(); 2403 mWindowManager.disableNonVrUi(disableNonVrUi); 2404 if (disableNonVrUi) { 2405 // If we are in a VR mode where Picture-in-Picture mode is unsupported, 2406 // then remove the pinned stack. 2407 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack( 2408 PINNED_STACK_ID); 2409 if (pinnedStack != null) { 2410 mStackSupervisor.removeStackLocked(PINNED_STACK_ID); 2411 } 2412 } 2413 } 2414 } break; 2415 case NOTIFY_VR_SLEEPING_MSG: { 2416 notifyVrManagerOfSleepState(msg.arg1 != 0); 2417 } break; 2418 case NOTIFY_VR_KEYGUARD_MSG: { 2419 notifyVrManagerOfKeyguardState(msg.arg1 != 0); 2420 } break; 2421 case HANDLE_TRUST_STORAGE_UPDATE_MSG: { 2422 synchronized (ActivityManagerService.this) { 2423 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 2424 ProcessRecord r = mLruProcesses.get(i); 2425 if (r.thread != null) { 2426 try { 2427 r.thread.handleTrustStorageUpdate(); 2428 } catch (RemoteException ex) { 2429 Slog.w(TAG, "Failed to handle trust storage update for: " + 2430 r.info.processName); 2431 } 2432 } 2433 } 2434 } 2435 } break; 2436 } 2437 } 2438 }; 2439 2440 static final int COLLECT_PSS_BG_MSG = 1; 2441 2442 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 2443 @Override 2444 public void handleMessage(Message msg) { 2445 switch (msg.what) { 2446 case COLLECT_PSS_BG_MSG: { 2447 long start = SystemClock.uptimeMillis(); 2448 MemInfoReader memInfo = null; 2449 synchronized (ActivityManagerService.this) { 2450 if (mFullPssPending) { 2451 mFullPssPending = false; 2452 memInfo = new MemInfoReader(); 2453 } 2454 } 2455 if (memInfo != null) { 2456 updateCpuStatsNow(); 2457 long nativeTotalPss = 0; 2458 final List<ProcessCpuTracker.Stats> stats; 2459 synchronized (mProcessCpuTracker) { 2460 stats = mProcessCpuTracker.getStats( (st)-> { 2461 return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID; 2462 }); 2463 } 2464 final int N = stats.size(); 2465 for (int j = 0; j < N; j++) { 2466 synchronized (mPidsSelfLocked) { 2467 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) { 2468 // This is one of our own processes; skip it. 2469 continue; 2470 } 2471 } 2472 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null); 2473 } 2474 memInfo.readMemInfo(); 2475 synchronized (ActivityManagerService.this) { 2476 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in " 2477 + (SystemClock.uptimeMillis()-start) + "ms"); 2478 final long cachedKb = memInfo.getCachedSizeKb(); 2479 final long freeKb = memInfo.getFreeSizeKb(); 2480 final long zramKb = memInfo.getZramTotalSizeKb(); 2481 final long kernelKb = memInfo.getKernelUsedSizeKb(); 2482 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024, 2483 kernelKb*1024, nativeTotalPss*1024); 2484 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb, 2485 nativeTotalPss); 2486 } 2487 } 2488 2489 int num = 0; 2490 long[] tmp = new long[2]; 2491 do { 2492 ProcessRecord proc; 2493 int procState; 2494 int pid; 2495 long lastPssTime; 2496 synchronized (ActivityManagerService.this) { 2497 if (mPendingPssProcesses.size() <= 0) { 2498 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS, 2499 "Collected PSS of " + num + " processes in " 2500 + (SystemClock.uptimeMillis() - start) + "ms"); 2501 mPendingPssProcesses.clear(); 2502 return; 2503 } 2504 proc = mPendingPssProcesses.remove(0); 2505 procState = proc.pssProcState; 2506 lastPssTime = proc.lastPssTime; 2507 if (proc.thread != null && procState == proc.setProcState 2508 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 2509 < SystemClock.uptimeMillis()) { 2510 pid = proc.pid; 2511 } else { 2512 proc = null; 2513 pid = 0; 2514 } 2515 } 2516 if (proc != null) { 2517 long pss = Debug.getPss(pid, tmp, null); 2518 synchronized (ActivityManagerService.this) { 2519 if (pss != 0 && proc.thread != null && proc.setProcState == procState 2520 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 2521 num++; 2522 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], 2523 SystemClock.uptimeMillis()); 2524 } 2525 } 2526 } 2527 } while (true); 2528 } 2529 } 2530 } 2531 }; 2532 2533 public void setSystemProcess() { 2534 try { 2535 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2536 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2537 ServiceManager.addService("meminfo", new MemBinder(this)); 2538 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2539 ServiceManager.addService("dbinfo", new DbBinder(this)); 2540 if (MONITOR_CPU_USAGE) { 2541 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2542 } 2543 ServiceManager.addService("permission", new PermissionController(this)); 2544 ServiceManager.addService("processinfo", new ProcessInfoService(this)); 2545 2546 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2547 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY); 2548 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2549 2550 synchronized (this) { 2551 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2552 app.persistent = true; 2553 app.pid = MY_PID; 2554 app.maxAdj = ProcessList.SYSTEM_ADJ; 2555 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2556 synchronized (mPidsSelfLocked) { 2557 mPidsSelfLocked.put(app.pid, app); 2558 } 2559 updateLruProcessLocked(app, false, null); 2560 updateOomAdjLocked(); 2561 } 2562 } catch (PackageManager.NameNotFoundException e) { 2563 throw new RuntimeException( 2564 "Unable to find android system package", e); 2565 } 2566 } 2567 2568 public void setWindowManager(WindowManagerService wm) { 2569 mWindowManager = wm; 2570 mStackSupervisor.setWindowManager(wm); 2571 mActivityStarter.setWindowManager(wm); 2572 } 2573 2574 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2575 mUsageStatsService = usageStatsManager; 2576 } 2577 2578 public void startObservingNativeCrashes() { 2579 final NativeCrashListener ncl = new NativeCrashListener(this); 2580 ncl.start(); 2581 } 2582 2583 public IAppOpsService getAppOpsService() { 2584 return mAppOpsService; 2585 } 2586 2587 static class MemBinder extends Binder { 2588 ActivityManagerService mActivityManagerService; 2589 MemBinder(ActivityManagerService activityManagerService) { 2590 mActivityManagerService = activityManagerService; 2591 } 2592 2593 @Override 2594 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2595 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, 2596 "meminfo", pw)) return; 2597 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2598 } 2599 } 2600 2601 static class GraphicsBinder extends Binder { 2602 ActivityManagerService mActivityManagerService; 2603 GraphicsBinder(ActivityManagerService activityManagerService) { 2604 mActivityManagerService = activityManagerService; 2605 } 2606 2607 @Override 2608 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2609 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, 2610 "gfxinfo", pw)) return; 2611 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2612 } 2613 } 2614 2615 static class DbBinder extends Binder { 2616 ActivityManagerService mActivityManagerService; 2617 DbBinder(ActivityManagerService activityManagerService) { 2618 mActivityManagerService = activityManagerService; 2619 } 2620 2621 @Override 2622 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2623 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, 2624 "dbinfo", pw)) return; 2625 mActivityManagerService.dumpDbInfo(fd, pw, args); 2626 } 2627 } 2628 2629 static class CpuBinder extends Binder { 2630 ActivityManagerService mActivityManagerService; 2631 CpuBinder(ActivityManagerService activityManagerService) { 2632 mActivityManagerService = activityManagerService; 2633 } 2634 2635 @Override 2636 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2637 if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext, 2638 "cpuinfo", pw)) return; 2639 synchronized (mActivityManagerService.mProcessCpuTracker) { 2640 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2641 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2642 SystemClock.uptimeMillis())); 2643 } 2644 } 2645 } 2646 2647 public static final class Lifecycle extends SystemService { 2648 private final ActivityManagerService mService; 2649 2650 public Lifecycle(Context context) { 2651 super(context); 2652 mService = new ActivityManagerService(context); 2653 } 2654 2655 @Override 2656 public void onStart() { 2657 mService.start(); 2658 } 2659 2660 @Override 2661 public void onCleanupUser(int userId) { 2662 mService.mBatteryStatsService.onCleanupUser(userId); 2663 } 2664 2665 public ActivityManagerService getService() { 2666 return mService; 2667 } 2668 } 2669 2670 @VisibleForTesting 2671 public ActivityManagerService(Injector injector) { 2672 mInjector = injector; 2673 mContext = mInjector.getContext(); 2674 mUiContext = null; 2675 GL_ES_VERSION = 0; 2676 mActivityStarter = null; 2677 mAppErrors = null; 2678 mAppOpsService = mInjector.getAppOpsService(null, null); 2679 mBatteryStatsService = null; 2680 mCompatModePackages = null; 2681 mConstants = null; 2682 mGrantFile = null; 2683 mHandler = null; 2684 mHandlerThread = null; 2685 mIntentFirewall = null; 2686 mKeyguardController = null; 2687 mPermissionReviewRequired = false; 2688 mProcessCpuThread = null; 2689 mProcessStats = null; 2690 mProviderMap = null; 2691 mRecentTasks = null; 2692 mServices = null; 2693 mStackSupervisor = null; 2694 mSystemThread = null; 2695 mTaskChangeNotificationController = null; 2696 mUiHandler = injector.getUiHandler(null); 2697 mUserController = null; 2698 mVrController = null; 2699 } 2700 2701 // Note: This method is invoked on the main thread but may need to attach various 2702 // handlers to other threads. So take care to be explicit about the looper. 2703 public ActivityManagerService(Context systemContext) { 2704 LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY); 2705 mInjector = new Injector(); 2706 mContext = systemContext; 2707 2708 mFactoryTest = FactoryTest.getMode(); 2709 mSystemThread = ActivityThread.currentActivityThread(); 2710 mUiContext = mSystemThread.getSystemUiContext(); 2711 2712 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2713 2714 mPermissionReviewRequired = mContext.getResources().getBoolean( 2715 com.android.internal.R.bool.config_permissionReviewRequired); 2716 2717 mHandlerThread = new ServiceThread(TAG, 2718 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2719 mHandlerThread.start(); 2720 mHandler = new MainHandler(mHandlerThread.getLooper()); 2721 mUiHandler = mInjector.getUiHandler(this); 2722 2723 mConstants = new ActivityManagerConstants(this, mHandler); 2724 2725 /* static; one-time init here */ 2726 if (sKillHandler == null) { 2727 sKillThread = new ServiceThread(TAG + ":kill", 2728 THREAD_PRIORITY_BACKGROUND, true /* allowIo */); 2729 sKillThread.start(); 2730 sKillHandler = new KillHandler(sKillThread.getLooper()); 2731 } 2732 2733 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2734 "foreground", BROADCAST_FG_TIMEOUT, false); 2735 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2736 "background", BROADCAST_BG_TIMEOUT, true); 2737 mBroadcastQueues[0] = mFgBroadcastQueue; 2738 mBroadcastQueues[1] = mBgBroadcastQueue; 2739 2740 mServices = new ActiveServices(this); 2741 mProviderMap = new ProviderMap(this); 2742 mAppErrors = new AppErrors(mUiContext, this); 2743 2744 // TODO: Move creation of battery stats service outside of activity manager service. 2745 File dataDir = Environment.getDataDirectory(); 2746 File systemDir = new File(dataDir, "system"); 2747 systemDir.mkdirs(); 2748 mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler); 2749 mBatteryStatsService.getActiveStatistics().readLocked(); 2750 mBatteryStatsService.scheduleWriteToDisk(); 2751 mOnBattery = DEBUG_POWER ? true 2752 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2753 mBatteryStatsService.getActiveStatistics().setCallback(this); 2754 2755 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2756 2757 mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler); 2758 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null, 2759 new IAppOpsCallback.Stub() { 2760 @Override public void opChanged(int op, int uid, String packageName) { 2761 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) { 2762 if (mAppOpsService.checkOperation(op, uid, packageName) 2763 != AppOpsManager.MODE_ALLOWED) { 2764 runInBackgroundDisabled(uid); 2765 } 2766 } 2767 } 2768 }); 2769 2770 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2771 2772 mUserController = new UserController(this); 2773 2774 mVrController = new VrController(this); 2775 2776 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2777 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2778 2779 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) { 2780 mUseFifoUiScheduling = true; 2781 } 2782 2783 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations")); 2784 mTempConfig.setToDefaults(); 2785 mTempConfig.setLocales(LocaleList.getDefault()); 2786 mConfigurationSeq = mTempConfig.seq = 1; 2787 mStackSupervisor = createStackSupervisor(); 2788 mStackSupervisor.onConfigurationChanged(mTempConfig); 2789 mKeyguardController = mStackSupervisor.mKeyguardController; 2790 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2791 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2792 mTaskChangeNotificationController = 2793 new TaskChangeNotificationController(this, mStackSupervisor, mHandler); 2794 mActivityStarter = new ActivityStarter(this, mStackSupervisor); 2795 mRecentTasks = new RecentTasks(this, mStackSupervisor); 2796 2797 mProcessCpuThread = new Thread("CpuTracker") { 2798 @Override 2799 public void run() { 2800 synchronized (mProcessCpuTracker) { 2801 mProcessCpuInitLatch.countDown(); 2802 mProcessCpuTracker.init(); 2803 } 2804 while (true) { 2805 try { 2806 try { 2807 synchronized(this) { 2808 final long now = SystemClock.uptimeMillis(); 2809 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2810 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2811 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2812 // + ", write delay=" + nextWriteDelay); 2813 if (nextWriteDelay < nextCpuDelay) { 2814 nextCpuDelay = nextWriteDelay; 2815 } 2816 if (nextCpuDelay > 0) { 2817 mProcessCpuMutexFree.set(true); 2818 this.wait(nextCpuDelay); 2819 } 2820 } 2821 } catch (InterruptedException e) { 2822 } 2823 updateCpuStatsNow(); 2824 } catch (Exception e) { 2825 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2826 } 2827 } 2828 } 2829 }; 2830 2831 Watchdog.getInstance().addMonitor(this); 2832 Watchdog.getInstance().addThread(mHandler); 2833 } 2834 2835 protected ActivityStackSupervisor createStackSupervisor() { 2836 return new ActivityStackSupervisor(this, mHandler.getLooper()); 2837 } 2838 2839 public void setSystemServiceManager(SystemServiceManager mgr) { 2840 mSystemServiceManager = mgr; 2841 } 2842 2843 public void setInstaller(Installer installer) { 2844 mInstaller = installer; 2845 } 2846 2847 private void start() { 2848 removeAllProcessGroups(); 2849 mProcessCpuThread.start(); 2850 2851 mBatteryStatsService.publish(); 2852 mAppOpsService.publish(mContext); 2853 Slog.d("AppOps", "AppOpsService published"); 2854 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2855 // Wait for the synchronized block started in mProcessCpuThread, 2856 // so that any other acccess to mProcessCpuTracker from main thread 2857 // will be blocked during mProcessCpuTracker initialization. 2858 try { 2859 mProcessCpuInitLatch.await(); 2860 } catch (InterruptedException e) { 2861 Slog.wtf(TAG, "Interrupted wait during start", e); 2862 Thread.currentThread().interrupt(); 2863 throw new IllegalStateException("Interrupted wait during start"); 2864 } 2865 } 2866 2867 void onUserStoppedLocked(int userId) { 2868 mRecentTasks.unloadUserDataFromMemoryLocked(userId); 2869 } 2870 2871 public void initPowerManagement() { 2872 mStackSupervisor.initPowerManagement(); 2873 mBatteryStatsService.initPowerManagement(); 2874 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class); 2875 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); 2876 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*"); 2877 mVoiceWakeLock.setReferenceCounted(false); 2878 } 2879 2880 private ArraySet<String> getBackgroundLaunchBroadcasts() { 2881 if (mBackgroundLaunchBroadcasts == null) { 2882 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts(); 2883 } 2884 return mBackgroundLaunchBroadcasts; 2885 } 2886 2887 @Override 2888 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2889 throws RemoteException { 2890 if (code == SYSPROPS_TRANSACTION) { 2891 // We need to tell all apps about the system property change. 2892 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2893 synchronized(this) { 2894 final int NP = mProcessNames.getMap().size(); 2895 for (int ip=0; ip<NP; ip++) { 2896 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2897 final int NA = apps.size(); 2898 for (int ia=0; ia<NA; ia++) { 2899 ProcessRecord app = apps.valueAt(ia); 2900 if (app.thread != null) { 2901 procs.add(app.thread.asBinder()); 2902 } 2903 } 2904 } 2905 } 2906 2907 int N = procs.size(); 2908 for (int i=0; i<N; i++) { 2909 Parcel data2 = Parcel.obtain(); 2910 try { 2911 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 2912 Binder.FLAG_ONEWAY); 2913 } catch (RemoteException e) { 2914 } 2915 data2.recycle(); 2916 } 2917 } 2918 try { 2919 return super.onTransact(code, data, reply, flags); 2920 } catch (RuntimeException e) { 2921 // The activity manager only throws security exceptions, so let's 2922 // log all others. 2923 if (!(e instanceof SecurityException)) { 2924 Slog.wtf(TAG, "Activity Manager Crash." 2925 + " UID:" + Binder.getCallingUid() 2926 + " PID:" + Binder.getCallingPid() 2927 + " TRANS:" + code, e); 2928 } 2929 throw e; 2930 } 2931 } 2932 2933 void updateCpuStats() { 2934 final long now = SystemClock.uptimeMillis(); 2935 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2936 return; 2937 } 2938 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2939 synchronized (mProcessCpuThread) { 2940 mProcessCpuThread.notify(); 2941 } 2942 } 2943 } 2944 2945 void updateCpuStatsNow() { 2946 synchronized (mProcessCpuTracker) { 2947 mProcessCpuMutexFree.set(false); 2948 final long now = SystemClock.uptimeMillis(); 2949 boolean haveNewCpuStats = false; 2950 2951 if (MONITOR_CPU_USAGE && 2952 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2953 mLastCpuTime.set(now); 2954 mProcessCpuTracker.update(); 2955 if (mProcessCpuTracker.hasGoodLastStats()) { 2956 haveNewCpuStats = true; 2957 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2958 //Slog.i(TAG, "Total CPU usage: " 2959 // + mProcessCpu.getTotalCpuPercent() + "%"); 2960 2961 // Slog the cpu usage if the property is set. 2962 if ("true".equals(SystemProperties.get("events.cpu"))) { 2963 int user = mProcessCpuTracker.getLastUserTime(); 2964 int system = mProcessCpuTracker.getLastSystemTime(); 2965 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2966 int irq = mProcessCpuTracker.getLastIrqTime(); 2967 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2968 int idle = mProcessCpuTracker.getLastIdleTime(); 2969 2970 int total = user + system + iowait + irq + softIrq + idle; 2971 if (total == 0) total = 1; 2972 2973 EventLog.writeEvent(EventLogTags.CPU, 2974 ((user+system+iowait+irq+softIrq) * 100) / total, 2975 (user * 100) / total, 2976 (system * 100) / total, 2977 (iowait * 100) / total, 2978 (irq * 100) / total, 2979 (softIrq * 100) / total); 2980 } 2981 } 2982 } 2983 2984 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2985 synchronized(bstats) { 2986 synchronized(mPidsSelfLocked) { 2987 if (haveNewCpuStats) { 2988 if (bstats.startAddingCpuLocked()) { 2989 int totalUTime = 0; 2990 int totalSTime = 0; 2991 final int N = mProcessCpuTracker.countStats(); 2992 for (int i=0; i<N; i++) { 2993 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2994 if (!st.working) { 2995 continue; 2996 } 2997 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2998 totalUTime += st.rel_utime; 2999 totalSTime += st.rel_stime; 3000 if (pr != null) { 3001 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 3002 if (ps == null || !ps.isActive()) { 3003 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 3004 pr.info.uid, pr.processName); 3005 } 3006 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 3007 pr.curCpuTime += st.rel_utime + st.rel_stime; 3008 if (pr.lastCpuTime == 0) { 3009 pr.lastCpuTime = pr.curCpuTime; 3010 } 3011 } else { 3012 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 3013 if (ps == null || !ps.isActive()) { 3014 st.batteryStats = ps = bstats.getProcessStatsLocked( 3015 bstats.mapUid(st.uid), st.name); 3016 } 3017 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 3018 } 3019 } 3020 final int userTime = mProcessCpuTracker.getLastUserTime(); 3021 final int systemTime = mProcessCpuTracker.getLastSystemTime(); 3022 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime(); 3023 final int irqTime = mProcessCpuTracker.getLastIrqTime(); 3024 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime(); 3025 final int idleTime = mProcessCpuTracker.getLastIdleTime(); 3026 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime, 3027 systemTime, iowaitTime, irqTime, softIrqTime, idleTime); 3028 } 3029 } 3030 } 3031 3032 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 3033 mLastWriteTime = now; 3034 mBatteryStatsService.scheduleWriteToDisk(); 3035 } 3036 } 3037 } 3038 } 3039 3040 @Override 3041 public void batteryNeedsCpuUpdate() { 3042 updateCpuStatsNow(); 3043 } 3044 3045 @Override 3046 public void batteryPowerChanged(boolean onBattery) { 3047 // When plugging in, update the CPU stats first before changing 3048 // the plug state. 3049 updateCpuStatsNow(); 3050 synchronized (this) { 3051 synchronized(mPidsSelfLocked) { 3052 mOnBattery = DEBUG_POWER ? true : onBattery; 3053 } 3054 } 3055 } 3056 3057 @Override 3058 public void batterySendBroadcast(Intent intent) { 3059 synchronized (this) { 3060 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 3061 AppOpsManager.OP_NONE, null, false, false, 3062 -1, SYSTEM_UID, UserHandle.USER_ALL); 3063 } 3064 } 3065 3066 /** 3067 * Initialize the application bind args. These are passed to each 3068 * process when the bindApplication() IPC is sent to the process. They're 3069 * lazily setup to make sure the services are running when they're asked for. 3070 */ 3071 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 3072 // Isolated processes won't get this optimization, so that we don't 3073 // violate the rules about which services they have access to. 3074 if (isolated) { 3075 if (mIsolatedAppBindArgs == null) { 3076 mIsolatedAppBindArgs = new HashMap<>(); 3077 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package")); 3078 } 3079 return mIsolatedAppBindArgs; 3080 } 3081 3082 if (mAppBindArgs == null) { 3083 mAppBindArgs = new HashMap<>(); 3084 3085 // Setup the application init args 3086 mAppBindArgs.put("package", ServiceManager.getService("package")); 3087 mAppBindArgs.put("window", ServiceManager.getService("window")); 3088 mAppBindArgs.put(Context.ALARM_SERVICE, 3089 ServiceManager.getService(Context.ALARM_SERVICE)); 3090 } 3091 return mAppBindArgs; 3092 } 3093 3094 /** 3095 * Update AMS states when an activity is resumed. This should only be called by 3096 * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed. 3097 */ 3098 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) { 3099 final TaskRecord task = r.getTask(); 3100 if (task.isApplicationTask()) { 3101 if (mCurAppTimeTracker != r.appTimeTracker) { 3102 // We are switching app tracking. Complete the current one. 3103 if (mCurAppTimeTracker != null) { 3104 mCurAppTimeTracker.stop(); 3105 mHandler.obtainMessage( 3106 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget(); 3107 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker); 3108 mCurAppTimeTracker = null; 3109 } 3110 if (r.appTimeTracker != null) { 3111 mCurAppTimeTracker = r.appTimeTracker; 3112 startTimeTrackingFocusedActivityLocked(); 3113 } 3114 } else { 3115 startTimeTrackingFocusedActivityLocked(); 3116 } 3117 } else { 3118 r.appTimeTracker = null; 3119 } 3120 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null 3121 // TODO: Probably not, because we don't want to resume voice on switching 3122 // back to this activity 3123 if (task.voiceInteractor != null) { 3124 startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid); 3125 } else { 3126 finishRunningVoiceLocked(); 3127 3128 if (mLastResumedActivity != null) { 3129 final IVoiceInteractionSession session; 3130 3131 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask(); 3132 if (lastResumedActivityTask != null 3133 && lastResumedActivityTask.voiceSession != null) { 3134 session = lastResumedActivityTask.voiceSession; 3135 } else { 3136 session = mLastResumedActivity.voiceSession; 3137 } 3138 3139 if (session != null) { 3140 // We had been in a voice interaction session, but now focused has 3141 // move to something different. Just finish the session, we can't 3142 // return to it and retain the proper state and synchronization with 3143 // the voice interaction service. 3144 finishVoiceTask(session); 3145 } 3146 } 3147 } 3148 3149 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) { 3150 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG); 3151 mHandler.obtainMessage( 3152 FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget(); 3153 } 3154 mLastResumedActivity = r; 3155 3156 mWindowManager.setFocusedApp(r.appToken, true); 3157 3158 applyUpdateLockStateLocked(r); 3159 applyUpdateVrModeLocked(r); 3160 3161 EventLogTags.writeAmSetResumedActivity( 3162 r == null ? -1 : r.userId, 3163 r == null ? "NULL" : r.shortComponentName, 3164 reason); 3165 } 3166 3167 @Override 3168 public void setFocusedStack(int stackId) { 3169 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()"); 3170 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId); 3171 final long callingId = Binder.clearCallingIdentity(); 3172 try { 3173 synchronized (this) { 3174 final ActivityStack stack = mStackSupervisor.getStack(stackId); 3175 if (stack == null) { 3176 return; 3177 } 3178 final ActivityRecord r = stack.topRunningActivityLocked(); 3179 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) { 3180 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 3181 } 3182 } 3183 } finally { 3184 Binder.restoreCallingIdentity(callingId); 3185 } 3186 } 3187 3188 @Override 3189 public void setFocusedTask(int taskId) { 3190 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()"); 3191 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId); 3192 final long callingId = Binder.clearCallingIdentity(); 3193 try { 3194 synchronized (this) { 3195 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 3196 if (task == null) { 3197 return; 3198 } 3199 final ActivityRecord r = task.topRunningActivityLocked(); 3200 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) { 3201 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 3202 } 3203 } 3204 } finally { 3205 Binder.restoreCallingIdentity(callingId); 3206 } 3207 } 3208 3209 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 3210 @Override 3211 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 3212 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()"); 3213 mTaskChangeNotificationController.registerTaskStackListener(listener); 3214 } 3215 3216 /** 3217 * Unregister a task stack listener so that it stops receiving callbacks. 3218 */ 3219 @Override 3220 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException { 3221 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()"); 3222 mTaskChangeNotificationController.unregisterTaskStackListener(listener); 3223 } 3224 3225 @Override 3226 public void notifyActivityDrawn(IBinder token) { 3227 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token); 3228 synchronized (this) { 3229 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token); 3230 if (r != null) { 3231 r.getStack().notifyActivityDrawnLocked(r); 3232 } 3233 } 3234 } 3235 3236 final void applyUpdateLockStateLocked(ActivityRecord r) { 3237 // Modifications to the UpdateLock state are done on our handler, outside 3238 // the activity manager's locks. The new state is determined based on the 3239 // state *now* of the relevant activity record. The object is passed to 3240 // the handler solely for logging detail, not to be consulted/modified. 3241 final boolean nextState = r != null && r.immersive; 3242 mHandler.sendMessage( 3243 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 3244 } 3245 3246 final void applyUpdateVrModeLocked(ActivityRecord r) { 3247 // VR apps are expected to run in a main display. If an app is turning on VR for 3248 // itself, but lives in a dynamic stack, then make sure that it is moved to the main 3249 // fullscreen stack before enabling VR Mode. 3250 // TODO: The goal of this code is to keep the VR app on the main display. When the 3251 // stack implementation changes in the future, keep in mind that the use of the fullscreen 3252 // stack is a means to move the activity to the main display and a moveActivityToDisplay() 3253 // option would be a better choice here. 3254 if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) { 3255 Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId() 3256 + " to main stack for VR"); 3257 moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */); 3258 } 3259 mHandler.sendMessage( 3260 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r)); 3261 } 3262 3263 private void sendNotifyVrManagerOfSleepState(boolean isSleeping) { 3264 mHandler.sendMessage( 3265 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0)); 3266 } 3267 3268 private void notifyVrManagerOfSleepState(boolean isSleeping) { 3269 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); 3270 if (vrService == null) { 3271 return; 3272 } 3273 vrService.onSleepStateChanged(isSleeping); 3274 } 3275 3276 private void sendNotifyVrManagerOfKeyguardState(boolean isShowing) { 3277 mHandler.sendMessage( 3278 mHandler.obtainMessage(NOTIFY_VR_KEYGUARD_MSG, isShowing ? 1 : 0, 0)); 3279 } 3280 3281 private void notifyVrManagerOfKeyguardState(boolean isShowing) { 3282 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); 3283 if (vrService == null) { 3284 return; 3285 } 3286 vrService.onKeyguardStateChanged(isShowing); 3287 } 3288 3289 final void showAskCompatModeDialogLocked(ActivityRecord r) { 3290 Message msg = Message.obtain(); 3291 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG; 3292 msg.obj = r.getTask().askedCompatMode ? null : r; 3293 mUiHandler.sendMessage(msg); 3294 } 3295 3296 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) { 3297 final Configuration globalConfig = getGlobalConfiguration(); 3298 if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE 3299 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) { 3300 final Message msg = Message.obtain(); 3301 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG; 3302 msg.obj = r; 3303 mUiHandler.sendMessage(msg); 3304 } 3305 } 3306 3307 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 3308 String what, Object obj, ProcessRecord srcApp) { 3309 app.lastActivityTime = now; 3310 3311 if (app.activities.size() > 0) { 3312 // Don't want to touch dependent processes that are hosting activities. 3313 return index; 3314 } 3315 3316 int lrui = mLruProcesses.lastIndexOf(app); 3317 if (lrui < 0) { 3318 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 3319 + what + " " + obj + " from " + srcApp); 3320 return index; 3321 } 3322 3323 if (lrui >= index) { 3324 // Don't want to cause this to move dependent processes *back* in the 3325 // list as if they were less frequently used. 3326 return index; 3327 } 3328 3329 if (lrui >= mLruProcessActivityStart) { 3330 // Don't want to touch dependent processes that are hosting activities. 3331 return index; 3332 } 3333 3334 mLruProcesses.remove(lrui); 3335 if (index > 0) { 3336 index--; 3337 } 3338 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index 3339 + " in LRU list: " + app); 3340 mLruProcesses.add(index, app); 3341 return index; 3342 } 3343 3344 static void killProcessGroup(int uid, int pid) { 3345 if (sKillHandler != null) { 3346 sKillHandler.sendMessage( 3347 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid)); 3348 } else { 3349 Slog.w(TAG, "Asked to kill process group before system bringup!"); 3350 Process.killProcessGroup(uid, pid); 3351 } 3352 } 3353 3354 final void removeLruProcessLocked(ProcessRecord app) { 3355 int lrui = mLruProcesses.lastIndexOf(app); 3356 if (lrui >= 0) { 3357 if (!app.killed) { 3358 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 3359 killProcessQuiet(app.pid); 3360 killProcessGroup(app.uid, app.pid); 3361 } 3362 if (lrui <= mLruProcessActivityStart) { 3363 mLruProcessActivityStart--; 3364 } 3365 if (lrui <= mLruProcessServiceStart) { 3366 mLruProcessServiceStart--; 3367 } 3368 mLruProcesses.remove(lrui); 3369 } 3370 } 3371 3372 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 3373 ProcessRecord client) { 3374 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 3375 || app.treatLikeActivity; 3376 final boolean hasService = false; // not impl yet. app.services.size() > 0; 3377 if (!activityChange && hasActivity) { 3378 // The process has activities, so we are only allowing activity-based adjustments 3379 // to move it. It should be kept in the front of the list with other 3380 // processes that have activities, and we don't want those to change their 3381 // order except due to activity operations. 3382 return; 3383 } 3384 3385 mLruSeq++; 3386 final long now = SystemClock.uptimeMillis(); 3387 app.lastActivityTime = now; 3388 3389 // First a quick reject: if the app is already at the position we will 3390 // put it, then there is nothing to do. 3391 if (hasActivity) { 3392 final int N = mLruProcesses.size(); 3393 if (N > 0 && mLruProcesses.get(N-1) == app) { 3394 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app); 3395 return; 3396 } 3397 } else { 3398 if (mLruProcessServiceStart > 0 3399 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 3400 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app); 3401 return; 3402 } 3403 } 3404 3405 int lrui = mLruProcesses.lastIndexOf(app); 3406 3407 if (app.persistent && lrui >= 0) { 3408 // We don't care about the position of persistent processes, as long as 3409 // they are in the list. 3410 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app); 3411 return; 3412 } 3413 3414 /* In progress: compute new position first, so we can avoid doing work 3415 if the process is not actually going to move. Not yet working. 3416 int addIndex; 3417 int nextIndex; 3418 boolean inActivity = false, inService = false; 3419 if (hasActivity) { 3420 // Process has activities, put it at the very tipsy-top. 3421 addIndex = mLruProcesses.size(); 3422 nextIndex = mLruProcessServiceStart; 3423 inActivity = true; 3424 } else if (hasService) { 3425 // Process has services, put it at the top of the service list. 3426 addIndex = mLruProcessActivityStart; 3427 nextIndex = mLruProcessServiceStart; 3428 inActivity = true; 3429 inService = true; 3430 } else { 3431 // Process not otherwise of interest, it goes to the top of the non-service area. 3432 addIndex = mLruProcessServiceStart; 3433 if (client != null) { 3434 int clientIndex = mLruProcesses.lastIndexOf(client); 3435 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 3436 + app); 3437 if (clientIndex >= 0 && addIndex > clientIndex) { 3438 addIndex = clientIndex; 3439 } 3440 } 3441 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 3442 } 3443 3444 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 3445 + mLruProcessActivityStart + "): " + app); 3446 */ 3447 3448 if (lrui >= 0) { 3449 if (lrui < mLruProcessActivityStart) { 3450 mLruProcessActivityStart--; 3451 } 3452 if (lrui < mLruProcessServiceStart) { 3453 mLruProcessServiceStart--; 3454 } 3455 /* 3456 if (addIndex > lrui) { 3457 addIndex--; 3458 } 3459 if (nextIndex > lrui) { 3460 nextIndex--; 3461 } 3462 */ 3463 mLruProcesses.remove(lrui); 3464 } 3465 3466 /* 3467 mLruProcesses.add(addIndex, app); 3468 if (inActivity) { 3469 mLruProcessActivityStart++; 3470 } 3471 if (inService) { 3472 mLruProcessActivityStart++; 3473 } 3474 */ 3475 3476 int nextIndex; 3477 if (hasActivity) { 3478 final int N = mLruProcesses.size(); 3479 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) { 3480 // Process doesn't have activities, but has clients with 3481 // activities... move it up, but one below the top (the top 3482 // should always have a real activity). 3483 if (DEBUG_LRU) Slog.d(TAG_LRU, 3484 "Adding to second-top of LRU activity list: " + app); 3485 mLruProcesses.add(N - 1, app); 3486 // To keep it from spamming the LRU list (by making a bunch of clients), 3487 // we will push down any other entries owned by the app. 3488 final int uid = app.info.uid; 3489 for (int i = N - 2; i > mLruProcessActivityStart; i--) { 3490 ProcessRecord subProc = mLruProcesses.get(i); 3491 if (subProc.info.uid == uid) { 3492 // We want to push this one down the list. If the process after 3493 // it is for the same uid, however, don't do so, because we don't 3494 // want them internally to be re-ordered. 3495 if (mLruProcesses.get(i - 1).info.uid != uid) { 3496 if (DEBUG_LRU) Slog.d(TAG_LRU, 3497 "Pushing uid " + uid + " swapping at " + i + ": " 3498 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1)); 3499 ProcessRecord tmp = mLruProcesses.get(i); 3500 mLruProcesses.set(i, mLruProcesses.get(i - 1)); 3501 mLruProcesses.set(i - 1, tmp); 3502 i--; 3503 } 3504 } else { 3505 // A gap, we can stop here. 3506 break; 3507 } 3508 } 3509 } else { 3510 // Process has activities, put it at the very tipsy-top. 3511 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app); 3512 mLruProcesses.add(app); 3513 } 3514 nextIndex = mLruProcessServiceStart; 3515 } else if (hasService) { 3516 // Process has services, put it at the top of the service list. 3517 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app); 3518 mLruProcesses.add(mLruProcessActivityStart, app); 3519 nextIndex = mLruProcessServiceStart; 3520 mLruProcessActivityStart++; 3521 } else { 3522 // Process not otherwise of interest, it goes to the top of the non-service area. 3523 int index = mLruProcessServiceStart; 3524 if (client != null) { 3525 // If there is a client, don't allow the process to be moved up higher 3526 // in the list than that client. 3527 int clientIndex = mLruProcesses.lastIndexOf(client); 3528 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client 3529 + " when updating " + app); 3530 if (clientIndex <= lrui) { 3531 // Don't allow the client index restriction to push it down farther in the 3532 // list than it already is. 3533 clientIndex = lrui; 3534 } 3535 if (clientIndex >= 0 && index > clientIndex) { 3536 index = clientIndex; 3537 } 3538 } 3539 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app); 3540 mLruProcesses.add(index, app); 3541 nextIndex = index-1; 3542 mLruProcessActivityStart++; 3543 mLruProcessServiceStart++; 3544 } 3545 3546 // If the app is currently using a content provider or service, 3547 // bump those processes as well. 3548 for (int j=app.connections.size()-1; j>=0; j--) { 3549 ConnectionRecord cr = app.connections.valueAt(j); 3550 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 3551 && cr.binding.service.app != null 3552 && cr.binding.service.app.lruSeq != mLruSeq 3553 && !cr.binding.service.app.persistent) { 3554 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 3555 "service connection", cr, app); 3556 } 3557 } 3558 for (int j=app.conProviders.size()-1; j>=0; j--) { 3559 ContentProviderRecord cpr = app.conProviders.get(j).provider; 3560 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 3561 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 3562 "provider reference", cpr, app); 3563 } 3564 } 3565 } 3566 3567 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 3568 if (uid == SYSTEM_UID) { 3569 // The system gets to run in any process. If there are multiple 3570 // processes with the same uid, just pick the first (this 3571 // should never happen). 3572 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 3573 if (procs == null) return null; 3574 final int procCount = procs.size(); 3575 for (int i = 0; i < procCount; i++) { 3576 final int procUid = procs.keyAt(i); 3577 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) { 3578 // Don't use an app process or different user process for system component. 3579 continue; 3580 } 3581 return procs.valueAt(i); 3582 } 3583 } 3584 ProcessRecord proc = mProcessNames.get(processName, uid); 3585 if (false && proc != null && !keepIfLarge 3586 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 3587 && proc.lastCachedPss >= 4000) { 3588 // Turn this condition on to cause killing to happen regularly, for testing. 3589 if (proc.baseProcessTracker != null) { 3590 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 3591 } 3592 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 3593 } else if (proc != null && !keepIfLarge 3594 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 3595 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 3596 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 3597 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 3598 if (proc.baseProcessTracker != null) { 3599 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 3600 } 3601 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 3602 } 3603 } 3604 return proc; 3605 } 3606 3607 void notifyPackageUse(String packageName, int reason) { 3608 synchronized(this) { 3609 getPackageManagerInternalLocked().notifyPackageUse(packageName, reason); 3610 } 3611 } 3612 3613 boolean isNextTransitionForward() { 3614 int transit = mWindowManager.getPendingAppTransition(); 3615 return transit == TRANSIT_ACTIVITY_OPEN 3616 || transit == TRANSIT_TASK_OPEN 3617 || transit == TRANSIT_TASK_TO_FRONT; 3618 } 3619 3620 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 3621 String processName, String abiOverride, int uid, Runnable crashHandler) { 3622 synchronized(this) { 3623 ApplicationInfo info = new ApplicationInfo(); 3624 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 3625 // For isolated processes, the former contains the parent's uid and the latter the 3626 // actual uid of the isolated process. 3627 // In the special case introduced by this method (which is, starting an isolated 3628 // process directly from the SystemServer without an actual parent app process) the 3629 // closest thing to a parent's uid is SYSTEM_UID. 3630 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 3631 // the |isolated| logic in the ProcessRecord constructor. 3632 info.uid = SYSTEM_UID; 3633 info.processName = processName; 3634 info.className = entryPoint; 3635 info.packageName = "android"; 3636 info.seInfoUser = SELinuxUtil.COMPLETE_STR; 3637 ProcessRecord proc = startProcessLocked(processName, info /* info */, 3638 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 3639 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 3640 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 3641 crashHandler); 3642 return proc != null ? proc.pid : 0; 3643 } 3644 } 3645 3646 final ProcessRecord startProcessLocked(String processName, 3647 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 3648 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 3649 boolean isolated, boolean keepIfLarge) { 3650 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 3651 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 3652 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 3653 null /* crashHandler */); 3654 } 3655 3656 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 3657 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 3658 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 3659 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 3660 long startTime = SystemClock.elapsedRealtime(); 3661 ProcessRecord app; 3662 if (!isolated) { 3663 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 3664 checkTime(startTime, "startProcess: after getProcessRecord"); 3665 3666 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) { 3667 // If we are in the background, then check to see if this process 3668 // is bad. If so, we will just silently fail. 3669 if (mAppErrors.isBadProcessLocked(info)) { 3670 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 3671 + "/" + info.processName); 3672 return null; 3673 } 3674 } else { 3675 // When the user is explicitly starting a process, then clear its 3676 // crash count so that we won't make it bad until they see at 3677 // least one crash dialog again, and make the process good again 3678 // if it had been bad. 3679 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 3680 + "/" + info.processName); 3681 mAppErrors.resetProcessCrashTimeLocked(info); 3682 if (mAppErrors.isBadProcessLocked(info)) { 3683 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 3684 UserHandle.getUserId(info.uid), info.uid, 3685 info.processName); 3686 mAppErrors.clearBadProcessLocked(info); 3687 if (app != null) { 3688 app.bad = false; 3689 } 3690 } 3691 } 3692 } else { 3693 // If this is an isolated process, it can't re-use an existing process. 3694 app = null; 3695 } 3696 3697 // We don't have to do anything more if: 3698 // (1) There is an existing application record; and 3699 // (2) The caller doesn't think it is dead, OR there is no thread 3700 // object attached to it so we know it couldn't have crashed; and 3701 // (3) There is a pid assigned to it, so it is either starting or 3702 // already running. 3703 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName 3704 + " app=" + app + " knownToBeDead=" + knownToBeDead 3705 + " thread=" + (app != null ? app.thread : null) 3706 + " pid=" + (app != null ? app.pid : -1)); 3707 if (app != null && app.pid > 0) { 3708 if ((!knownToBeDead && !app.killed) || app.thread == null) { 3709 // We already have the app running, or are waiting for it to 3710 // come up (we have a pid but not yet its thread), so keep it. 3711 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app); 3712 // If this is a new package in the process, add the package to the list 3713 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3714 checkTime(startTime, "startProcess: done, added package to proc"); 3715 return app; 3716 } 3717 3718 // An application record is attached to a previous process, 3719 // clean it up now. 3720 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app); 3721 checkTime(startTime, "startProcess: bad proc running, killing"); 3722 killProcessGroup(app.uid, app.pid); 3723 handleAppDiedLocked(app, true, true); 3724 checkTime(startTime, "startProcess: done killing old proc"); 3725 } 3726 3727 String hostingNameStr = hostingName != null 3728 ? hostingName.flattenToShortString() : null; 3729 3730 if (app == null) { 3731 checkTime(startTime, "startProcess: creating new process record"); 3732 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 3733 if (app == null) { 3734 Slog.w(TAG, "Failed making new process record for " 3735 + processName + "/" + info.uid + " isolated=" + isolated); 3736 return null; 3737 } 3738 app.crashHandler = crashHandler; 3739 checkTime(startTime, "startProcess: done creating new process record"); 3740 } else { 3741 // If this is a new package in the process, add the package to the list 3742 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3743 checkTime(startTime, "startProcess: added package to existing proc"); 3744 } 3745 3746 // If the system is not ready yet, then hold off on starting this 3747 // process until it is. 3748 if (!mProcessesReady 3749 && !isAllowedWhileBooting(info) 3750 && !allowWhileBooting) { 3751 if (!mProcessesOnHold.contains(app)) { 3752 mProcessesOnHold.add(app); 3753 } 3754 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, 3755 "System not ready, putting on hold: " + app); 3756 checkTime(startTime, "startProcess: returning with proc on hold"); 3757 return app; 3758 } 3759 3760 checkTime(startTime, "startProcess: stepping in to startProcess"); 3761 startProcessLocked( 3762 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3763 checkTime(startTime, "startProcess: done starting proc!"); 3764 return (app.pid != 0) ? app : null; 3765 } 3766 3767 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3768 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3769 } 3770 3771 private final void startProcessLocked(ProcessRecord app, 3772 String hostingType, String hostingNameStr) { 3773 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3774 null /* entryPoint */, null /* entryPointArgs */); 3775 } 3776 3777 private final void startProcessLocked(ProcessRecord app, String hostingType, 3778 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3779 long startTime = SystemClock.elapsedRealtime(); 3780 if (app.pid > 0 && app.pid != MY_PID) { 3781 checkTime(startTime, "startProcess: removing from pids map"); 3782 synchronized (mPidsSelfLocked) { 3783 mPidsSelfLocked.remove(app.pid); 3784 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3785 } 3786 checkTime(startTime, "startProcess: done removing from pids map"); 3787 app.setPid(0); 3788 } 3789 3790 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES, 3791 "startProcessLocked removing on hold: " + app); 3792 mProcessesOnHold.remove(app); 3793 3794 checkTime(startTime, "startProcess: starting to update cpu stats"); 3795 updateCpuStats(); 3796 checkTime(startTime, "startProcess: done updating cpu stats"); 3797 3798 try { 3799 try { 3800 final int userId = UserHandle.getUserId(app.uid); 3801 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId); 3802 } catch (RemoteException e) { 3803 throw e.rethrowAsRuntimeException(); 3804 } 3805 3806 int uid = app.uid; 3807 int[] gids = null; 3808 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3809 if (!app.isolated) { 3810 int[] permGids = null; 3811 try { 3812 checkTime(startTime, "startProcess: getting gids from package manager"); 3813 final IPackageManager pm = AppGlobals.getPackageManager(); 3814 permGids = pm.getPackageGids(app.info.packageName, 3815 MATCH_DEBUG_TRIAGED_MISSING, app.userId); 3816 StorageManagerInternal storageManagerInternal = LocalServices.getService( 3817 StorageManagerInternal.class); 3818 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid, 3819 app.info.packageName); 3820 } catch (RemoteException e) { 3821 throw e.rethrowAsRuntimeException(); 3822 } 3823 3824 /* 3825 * Add shared application and profile GIDs so applications can share some 3826 * resources like shared libraries and access user-wide resources 3827 */ 3828 if (ArrayUtils.isEmpty(permGids)) { 3829 gids = new int[3]; 3830 } else { 3831 gids = new int[permGids.length + 3]; 3832 System.arraycopy(permGids, 0, gids, 3, permGids.length); 3833 } 3834 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3835 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid)); 3836 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3837 } 3838 checkTime(startTime, "startProcess: building args"); 3839 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3840 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3841 && mTopComponent != null 3842 && app.processName.equals(mTopComponent.getPackageName())) { 3843 uid = 0; 3844 } 3845 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3846 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3847 uid = 0; 3848 } 3849 } 3850 int debugFlags = 0; 3851 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3852 debugFlags |= Zygote.DEBUG_ENABLE_JDWP; 3853 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE; 3854 // Also turn on CheckJNI for debuggable apps. It's quite 3855 // awkward to turn on otherwise. 3856 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3857 } 3858 // Run the app in safe mode if its manifest requests so or the 3859 // system is booted in safe mode. 3860 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3861 mSafeMode == true) { 3862 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3863 } 3864 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3865 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3866 } 3867 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info"); 3868 if ("true".equals(genDebugInfoProperty)) { 3869 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; 3870 } 3871 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3872 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3873 } 3874 if ("1".equals(SystemProperties.get("debug.assert"))) { 3875 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3876 } 3877 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) { 3878 // Enable all debug flags required by the native debugger. 3879 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything 3880 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info 3881 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations 3882 mNativeDebuggingApp = null; 3883 } 3884 3885 String invokeWith = null; 3886 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3887 // Debuggable apps may include a wrapper script with their library directory. 3888 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh"; 3889 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3890 try { 3891 if (new File(wrapperFileName).exists()) { 3892 invokeWith = "/system/bin/logwrapper " + wrapperFileName; 3893 } 3894 } finally { 3895 StrictMode.setThreadPolicy(oldPolicy); 3896 } 3897 } 3898 3899 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3900 if (requiredAbi == null) { 3901 requiredAbi = Build.SUPPORTED_ABIS[0]; 3902 } 3903 3904 String instructionSet = null; 3905 if (app.info.primaryCpuAbi != null) { 3906 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3907 } 3908 3909 app.gids = gids; 3910 app.requiredAbi = requiredAbi; 3911 app.instructionSet = instructionSet; 3912 3913 // the per-user SELinux context must be set 3914 if (TextUtils.isEmpty(app.info.seInfoUser)) { 3915 Slog.wtf(TAG, "SELinux tag not defined", 3916 new IllegalStateException("SELinux tag not defined for " 3917 + app.info.packageName + " (uid " + app.uid + ")")); 3918 } 3919 final String seInfo = app.info.seInfo 3920 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser); 3921 // Start the process. It will either succeed and return a result containing 3922 // the PID of the new process, or else throw a RuntimeException. 3923 boolean isActivityProcess = (entryPoint == null); 3924 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3925 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + 3926 app.processName); 3927 checkTime(startTime, "startProcess: asking zygote to start proc"); 3928 ProcessStartResult startResult; 3929 if (hostingType.equals("webview_service")) { 3930 startResult = startWebView(entryPoint, 3931 app.processName, uid, uid, gids, debugFlags, mountExternal, 3932 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 3933 app.info.dataDir, null, entryPointArgs); 3934 } else { 3935 startResult = Process.start(entryPoint, 3936 app.processName, uid, uid, gids, debugFlags, mountExternal, 3937 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 3938 app.info.dataDir, invokeWith, entryPointArgs); 3939 } 3940 checkTime(startTime, "startProcess: returned from zygote!"); 3941 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 3942 3943 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3944 checkTime(startTime, "startProcess: done updating battery stats"); 3945 3946 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3947 UserHandle.getUserId(uid), startResult.pid, uid, 3948 app.processName, hostingType, 3949 hostingNameStr != null ? hostingNameStr : ""); 3950 3951 try { 3952 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid, 3953 seInfo, app.info.sourceDir, startResult.pid); 3954 } catch (RemoteException ex) { 3955 // Ignore 3956 } 3957 3958 if (app.persistent) { 3959 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3960 } 3961 3962 checkTime(startTime, "startProcess: building log message"); 3963 StringBuilder buf = mStringBuilder; 3964 buf.setLength(0); 3965 buf.append("Start proc "); 3966 buf.append(startResult.pid); 3967 buf.append(':'); 3968 buf.append(app.processName); 3969 buf.append('/'); 3970 UserHandle.formatUid(buf, uid); 3971 if (!isActivityProcess) { 3972 buf.append(" ["); 3973 buf.append(entryPoint); 3974 buf.append("]"); 3975 } 3976 buf.append(" for "); 3977 buf.append(hostingType); 3978 if (hostingNameStr != null) { 3979 buf.append(" "); 3980 buf.append(hostingNameStr); 3981 } 3982 Slog.i(TAG, buf.toString()); 3983 app.setPid(startResult.pid); 3984 app.usingWrapper = startResult.usingWrapper; 3985 app.removed = false; 3986 app.killed = false; 3987 app.killedByAm = false; 3988 checkTime(startTime, "startProcess: starting to update pids map"); 3989 ProcessRecord oldApp; 3990 synchronized (mPidsSelfLocked) { 3991 oldApp = mPidsSelfLocked.get(startResult.pid); 3992 } 3993 // If there is already an app occupying that pid that hasn't been cleaned up 3994 if (oldApp != null && !app.isolated) { 3995 // Clean up anything relating to this pid first 3996 Slog.w(TAG, "Reusing pid " + startResult.pid 3997 + " while app is still mapped to it"); 3998 cleanUpApplicationRecordLocked(oldApp, false, false, -1, 3999 true /*replacingPid*/); 4000 } 4001 synchronized (mPidsSelfLocked) { 4002 this.mPidsSelfLocked.put(startResult.pid, app); 4003 if (isActivityProcess) { 4004 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 4005 msg.obj = app; 4006 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 4007 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 4008 } 4009 } 4010 checkTime(startTime, "startProcess: done updating pids map"); 4011 } catch (RuntimeException e) { 4012 Slog.e(TAG, "Failure starting process " + app.processName, e); 4013 4014 // Something went very wrong while trying to start this process; one 4015 // common case is when the package is frozen due to an active 4016 // upgrade. To recover, clean up any active bookkeeping related to 4017 // starting this process. (We already invoked this method once when 4018 // the package was initially frozen through KILL_APPLICATION_MSG, so 4019 // it doesn't hurt to use it again.) 4020 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false, 4021 false, true, false, false, UserHandle.getUserId(app.userId), "start failure"); 4022 } 4023 } 4024 4025 void updateUsageStats(ActivityRecord component, boolean resumed) { 4026 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, 4027 "updateUsageStats: comp=" + component + "res=" + resumed); 4028 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4029 if (resumed) { 4030 if (mUsageStatsService != null) { 4031 mUsageStatsService.reportEvent(component.realActivity, component.userId, 4032 UsageEvents.Event.MOVE_TO_FOREGROUND); 4033 } 4034 synchronized (stats) { 4035 stats.noteActivityResumedLocked(component.app.uid); 4036 } 4037 } else { 4038 if (mUsageStatsService != null) { 4039 mUsageStatsService.reportEvent(component.realActivity, component.userId, 4040 UsageEvents.Event.MOVE_TO_BACKGROUND); 4041 } 4042 synchronized (stats) { 4043 stats.noteActivityPausedLocked(component.app.uid); 4044 } 4045 } 4046 } 4047 4048 Intent getHomeIntent() { 4049 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 4050 intent.setComponent(mTopComponent); 4051 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING); 4052 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 4053 intent.addCategory(Intent.CATEGORY_HOME); 4054 } 4055 return intent; 4056 } 4057 4058 boolean startHomeActivityLocked(int userId, String reason) { 4059 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 4060 && mTopAction == null) { 4061 // We are running in factory test mode, but unable to find 4062 // the factory test app, so just sit around displaying the 4063 // error message and don't try to start anything. 4064 return false; 4065 } 4066 Intent intent = getHomeIntent(); 4067 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 4068 if (aInfo != null) { 4069 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name)); 4070 // Don't do this if the home app is currently being 4071 // instrumented. 4072 aInfo = new ActivityInfo(aInfo); 4073 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 4074 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 4075 aInfo.applicationInfo.uid, true); 4076 if (app == null || app.instr == null) { 4077 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 4078 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid); 4079 // For ANR debugging to verify if the user activity is the one that actually 4080 // launched. 4081 final String myReason = reason + ":" + userId + ":" + resolvedUserId; 4082 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason); 4083 } 4084 } else { 4085 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable()); 4086 } 4087 4088 return true; 4089 } 4090 4091 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 4092 ActivityInfo ai = null; 4093 ComponentName comp = intent.getComponent(); 4094 try { 4095 if (comp != null) { 4096 // Factory test. 4097 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 4098 } else { 4099 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 4100 intent, 4101 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 4102 flags, userId); 4103 4104 if (info != null) { 4105 ai = info.activityInfo; 4106 } 4107 } 4108 } catch (RemoteException e) { 4109 // ignore 4110 } 4111 4112 return ai; 4113 } 4114 4115 /** 4116 * Starts the "new version setup screen" if appropriate. 4117 */ 4118 void startSetupActivityLocked() { 4119 // Only do this once per boot. 4120 if (mCheckedForSetup) { 4121 return; 4122 } 4123 4124 // We will show this screen if the current one is a different 4125 // version than the last one shown, and we are not running in 4126 // low-level factory test mode. 4127 final ContentResolver resolver = mContext.getContentResolver(); 4128 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 4129 Settings.Global.getInt(resolver, 4130 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 4131 mCheckedForSetup = true; 4132 4133 // See if we should be showing the platform update setup UI. 4134 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 4135 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent, 4136 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA); 4137 if (!ris.isEmpty()) { 4138 final ResolveInfo ri = ris.get(0); 4139 String vers = ri.activityInfo.metaData != null 4140 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 4141 : null; 4142 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 4143 vers = ri.activityInfo.applicationInfo.metaData.getString( 4144 Intent.METADATA_SETUP_VERSION); 4145 } 4146 String lastVers = Settings.Secure.getString( 4147 resolver, Settings.Secure.LAST_SETUP_SHOWN); 4148 if (vers != null && !vers.equals(lastVers)) { 4149 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 4150 intent.setComponent(new ComponentName( 4151 ri.activityInfo.packageName, ri.activityInfo.name)); 4152 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/, 4153 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0, 4154 null, 0, 0, 0, null, false, false, null, null, "startSetupActivity"); 4155 } 4156 } 4157 } 4158 } 4159 4160 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 4161 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 4162 } 4163 4164 void enforceNotIsolatedCaller(String caller) { 4165 if (UserHandle.isIsolated(Binder.getCallingUid())) { 4166 throw new SecurityException("Isolated process not allowed to call " + caller); 4167 } 4168 } 4169 4170 void enforceShellRestriction(String restriction, int userHandle) { 4171 if (Binder.getCallingUid() == SHELL_UID) { 4172 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) { 4173 throw new SecurityException("Shell does not have permission to access user " 4174 + userHandle); 4175 } 4176 } 4177 } 4178 4179 @Override 4180 public int getFrontActivityScreenCompatMode() { 4181 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 4182 synchronized (this) { 4183 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 4184 } 4185 } 4186 4187 @Override 4188 public void setFrontActivityScreenCompatMode(int mode) { 4189 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 4190 "setFrontActivityScreenCompatMode"); 4191 synchronized (this) { 4192 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 4193 } 4194 } 4195 4196 @Override 4197 public int getPackageScreenCompatMode(String packageName) { 4198 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 4199 synchronized (this) { 4200 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 4201 } 4202 } 4203 4204 @Override 4205 public void setPackageScreenCompatMode(String packageName, int mode) { 4206 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 4207 "setPackageScreenCompatMode"); 4208 synchronized (this) { 4209 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 4210 } 4211 } 4212 4213 @Override 4214 public boolean getPackageAskScreenCompat(String packageName) { 4215 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 4216 synchronized (this) { 4217 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 4218 } 4219 } 4220 4221 @Override 4222 public void setPackageAskScreenCompat(String packageName, boolean ask) { 4223 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 4224 "setPackageAskScreenCompat"); 4225 synchronized (this) { 4226 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 4227 } 4228 } 4229 4230 private boolean hasUsageStatsPermission(String callingPackage) { 4231 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS, 4232 Binder.getCallingUid(), callingPackage); 4233 if (mode == AppOpsManager.MODE_DEFAULT) { 4234 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS) 4235 == PackageManager.PERMISSION_GRANTED; 4236 } 4237 return mode == AppOpsManager.MODE_ALLOWED; 4238 } 4239 4240 @Override 4241 public int getPackageProcessState(String packageName, String callingPackage) { 4242 if (!hasUsageStatsPermission(callingPackage)) { 4243 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, 4244 "getPackageProcessState"); 4245 } 4246 4247 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT; 4248 synchronized (this) { 4249 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4250 final ProcessRecord proc = mLruProcesses.get(i); 4251 if (procState > proc.setProcState) { 4252 if (proc.pkgList.containsKey(packageName) || 4253 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) { 4254 procState = proc.setProcState; 4255 } 4256 } 4257 } 4258 } 4259 return procState; 4260 } 4261 4262 @Override 4263 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) 4264 throws RemoteException { 4265 synchronized (this) { 4266 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel"); 4267 if (app == null) { 4268 throw new IllegalArgumentException("Unknown process: " + process); 4269 } 4270 if (app.thread == null) { 4271 throw new IllegalArgumentException("Process has no app thread"); 4272 } 4273 if (app.trimMemoryLevel >= level) { 4274 throw new IllegalArgumentException( 4275 "Unable to set a higher trim level than current level"); 4276 } 4277 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN || 4278 app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) { 4279 throw new IllegalArgumentException("Unable to set a background trim level " 4280 + "on a foreground process"); 4281 } 4282 app.thread.scheduleTrimMemory(level); 4283 app.trimMemoryLevel = level; 4284 return true; 4285 } 4286 } 4287 4288 private void dispatchProcessesChanged() { 4289 int N; 4290 synchronized (this) { 4291 N = mPendingProcessChanges.size(); 4292 if (mActiveProcessChanges.length < N) { 4293 mActiveProcessChanges = new ProcessChangeItem[N]; 4294 } 4295 mPendingProcessChanges.toArray(mActiveProcessChanges); 4296 mPendingProcessChanges.clear(); 4297 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 4298 "*** Delivering " + N + " process changes"); 4299 } 4300 4301 int i = mProcessObservers.beginBroadcast(); 4302 while (i > 0) { 4303 i--; 4304 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 4305 if (observer != null) { 4306 try { 4307 for (int j=0; j<N; j++) { 4308 ProcessChangeItem item = mActiveProcessChanges[j]; 4309 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 4310 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 4311 "ACTIVITIES CHANGED pid=" + item.pid + " uid=" 4312 + item.uid + ": " + item.foregroundActivities); 4313 observer.onForegroundActivitiesChanged(item.pid, item.uid, 4314 item.foregroundActivities); 4315 } 4316 } 4317 } catch (RemoteException e) { 4318 } 4319 } 4320 } 4321 mProcessObservers.finishBroadcast(); 4322 4323 synchronized (this) { 4324 for (int j=0; j<N; j++) { 4325 mAvailProcessChanges.add(mActiveProcessChanges[j]); 4326 } 4327 } 4328 } 4329 4330 private void dispatchProcessDied(int pid, int uid) { 4331 int i = mProcessObservers.beginBroadcast(); 4332 while (i > 0) { 4333 i--; 4334 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 4335 if (observer != null) { 4336 try { 4337 observer.onProcessDied(pid, uid); 4338 } catch (RemoteException e) { 4339 } 4340 } 4341 } 4342 mProcessObservers.finishBroadcast(); 4343 } 4344 4345 @VisibleForTesting 4346 void dispatchUidsChanged() { 4347 int N; 4348 synchronized (this) { 4349 N = mPendingUidChanges.size(); 4350 if (mActiveUidChanges.length < N) { 4351 mActiveUidChanges = new UidRecord.ChangeItem[N]; 4352 } 4353 for (int i=0; i<N; i++) { 4354 final UidRecord.ChangeItem change = mPendingUidChanges.get(i); 4355 mActiveUidChanges[i] = change; 4356 if (change.uidRecord != null) { 4357 change.uidRecord.pendingChange = null; 4358 change.uidRecord = null; 4359 } 4360 } 4361 mPendingUidChanges.clear(); 4362 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4363 "*** Delivering " + N + " uid changes"); 4364 } 4365 4366 int i = mUidObservers.beginBroadcast(); 4367 while (i > 0) { 4368 i--; 4369 dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i), 4370 (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N); 4371 } 4372 mUidObservers.finishBroadcast(); 4373 4374 if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) { 4375 for (int j = 0; j < N; ++j) { 4376 final UidRecord.ChangeItem item = mActiveUidChanges[j]; 4377 if ((item.change & UidRecord.CHANGE_GONE) != 0) { 4378 mValidateUids.remove(item.uid); 4379 } else { 4380 UidRecord validateUid = mValidateUids.get(item.uid); 4381 if (validateUid == null) { 4382 validateUid = new UidRecord(item.uid); 4383 mValidateUids.put(item.uid, validateUid); 4384 } 4385 if ((item.change & UidRecord.CHANGE_IDLE) != 0) { 4386 validateUid.idle = true; 4387 } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) { 4388 validateUid.idle = false; 4389 } 4390 validateUid.curProcState = validateUid.setProcState = item.processState; 4391 validateUid.lastDispatchedProcStateSeq = item.procStateSeq; 4392 } 4393 } 4394 } 4395 4396 synchronized (this) { 4397 for (int j = 0; j < N; j++) { 4398 mAvailUidChanges.add(mActiveUidChanges[j]); 4399 } 4400 } 4401 } 4402 4403 private void dispatchUidsChangedForObserver(IUidObserver observer, 4404 UidObserverRegistration reg, int changesSize) { 4405 if (observer == null) { 4406 return; 4407 } 4408 try { 4409 for (int j = 0; j < changesSize; j++) { 4410 UidRecord.ChangeItem item = mActiveUidChanges[j]; 4411 final int change = item.change; 4412 if (change == UidRecord.CHANGE_PROCSTATE && 4413 (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) { 4414 // No-op common case: no significant change, the observer is not 4415 // interested in all proc state changes. 4416 continue; 4417 } 4418 if ((change & UidRecord.CHANGE_IDLE) != 0) { 4419 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) { 4420 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4421 "UID idle uid=" + item.uid); 4422 observer.onUidIdle(item.uid, item.ephemeral); 4423 } 4424 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) { 4425 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) { 4426 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4427 "UID active uid=" + item.uid); 4428 observer.onUidActive(item.uid); 4429 } 4430 } 4431 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) { 4432 if ((change & UidRecord.CHANGE_CACHED) != 0) { 4433 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4434 "UID cached uid=" + item.uid); 4435 observer.onUidCachedChanged(item.uid, true); 4436 } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) { 4437 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4438 "UID active uid=" + item.uid); 4439 observer.onUidCachedChanged(item.uid, false); 4440 } 4441 } 4442 if ((change & UidRecord.CHANGE_GONE) != 0) { 4443 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) { 4444 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4445 "UID gone uid=" + item.uid); 4446 observer.onUidGone(item.uid, item.ephemeral); 4447 } 4448 if (reg.lastProcStates != null) { 4449 reg.lastProcStates.delete(item.uid); 4450 } 4451 } else { 4452 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) { 4453 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4454 "UID CHANGED uid=" + item.uid 4455 + ": " + item.processState); 4456 boolean doReport = true; 4457 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) { 4458 final int lastState = reg.lastProcStates.get(item.uid, 4459 ActivityManager.PROCESS_STATE_UNKNOWN); 4460 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) { 4461 final boolean lastAboveCut = lastState <= reg.cutpoint; 4462 final boolean newAboveCut = item.processState <= reg.cutpoint; 4463 doReport = lastAboveCut != newAboveCut; 4464 } else { 4465 doReport = item.processState 4466 != ActivityManager.PROCESS_STATE_NONEXISTENT; 4467 } 4468 } 4469 if (doReport) { 4470 if (reg.lastProcStates != null) { 4471 reg.lastProcStates.put(item.uid, item.processState); 4472 } 4473 observer.onUidStateChanged(item.uid, item.processState, 4474 item.procStateSeq); 4475 } 4476 } 4477 } 4478 } 4479 } catch (RemoteException e) { 4480 } 4481 } 4482 4483 void dispatchOomAdjObserver(String msg) { 4484 OomAdjObserver observer; 4485 synchronized (this) { 4486 observer = mCurOomAdjObserver; 4487 } 4488 4489 if (observer != null) { 4490 observer.onOomAdjMessage(msg); 4491 } 4492 } 4493 4494 void setOomAdjObserver(int uid, OomAdjObserver observer) { 4495 synchronized (this) { 4496 mCurOomAdjUid = uid; 4497 mCurOomAdjObserver = observer; 4498 } 4499 } 4500 4501 void clearOomAdjObserver() { 4502 synchronized (this) { 4503 mCurOomAdjUid = -1; 4504 mCurOomAdjObserver = null; 4505 } 4506 } 4507 4508 void reportOomAdjMessageLocked(String tag, String msg) { 4509 Slog.d(tag, msg); 4510 if (mCurOomAdjObserver != null) { 4511 mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget(); 4512 } 4513 } 4514 4515 @Override 4516 public final int startActivity(IApplicationThread caller, String callingPackage, 4517 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4518 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { 4519 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 4520 resultWho, requestCode, startFlags, profilerInfo, bOptions, 4521 UserHandle.getCallingUserId()); 4522 } 4523 4524 @Override 4525 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 4526 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4527 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { 4528 enforceNotIsolatedCaller("startActivity"); 4529 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4530 userId, false, ALLOW_FULL_ONLY, "startActivity", null); 4531 // TODO: Switch to user app stacks here. 4532 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, 4533 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 4534 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser"); 4535 } 4536 4537 @Override 4538 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 4539 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4540 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity, 4541 int userId) { 4542 4543 // This is very dangerous -- it allows you to perform a start activity (including 4544 // permission grants) as any app that may launch one of your own activities. So 4545 // we will only allow this to be done from activities that are part of the core framework, 4546 // and then only when they are running as the system. 4547 final ActivityRecord sourceRecord; 4548 final int targetUid; 4549 final String targetPackage; 4550 synchronized (this) { 4551 if (resultTo == null) { 4552 throw new SecurityException("Must be called from an activity"); 4553 } 4554 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 4555 if (sourceRecord == null) { 4556 throw new SecurityException("Called with bad activity token: " + resultTo); 4557 } 4558 if (!sourceRecord.info.packageName.equals("android")) { 4559 throw new SecurityException( 4560 "Must be called from an activity that is declared in the android package"); 4561 } 4562 if (sourceRecord.app == null) { 4563 throw new SecurityException("Called without a process attached to activity"); 4564 } 4565 if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) { 4566 // This is still okay, as long as this activity is running under the 4567 // uid of the original calling activity. 4568 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 4569 throw new SecurityException( 4570 "Calling activity in uid " + sourceRecord.app.uid 4571 + " must be system uid or original calling uid " 4572 + sourceRecord.launchedFromUid); 4573 } 4574 } 4575 if (ignoreTargetSecurity) { 4576 if (intent.getComponent() == null) { 4577 throw new SecurityException( 4578 "Component must be specified with ignoreTargetSecurity"); 4579 } 4580 if (intent.getSelector() != null) { 4581 throw new SecurityException( 4582 "Selector not allowed with ignoreTargetSecurity"); 4583 } 4584 } 4585 targetUid = sourceRecord.launchedFromUid; 4586 targetPackage = sourceRecord.launchedFromPackage; 4587 } 4588 4589 if (userId == UserHandle.USER_NULL) { 4590 userId = UserHandle.getUserId(sourceRecord.app.uid); 4591 } 4592 4593 // TODO: Switch to user app stacks here. 4594 try { 4595 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent, 4596 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 4597 null, null, bOptions, ignoreTargetSecurity, userId, null, 4598 "startActivityAsCaller"); 4599 return ret; 4600 } catch (SecurityException e) { 4601 // XXX need to figure out how to propagate to original app. 4602 // A SecurityException here is generally actually a fault of the original 4603 // calling activity (such as a fairly granting permissions), so propagate it 4604 // back to them. 4605 /* 4606 StringBuilder msg = new StringBuilder(); 4607 msg.append("While launching"); 4608 msg.append(intent.toString()); 4609 msg.append(": "); 4610 msg.append(e.getMessage()); 4611 */ 4612 throw e; 4613 } 4614 } 4615 4616 @Override 4617 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 4618 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4619 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { 4620 enforceNotIsolatedCaller("startActivityAndWait"); 4621 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4622 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 4623 WaitResult res = new WaitResult(); 4624 // TODO: Switch to user app stacks here. 4625 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 4626 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 4627 bOptions, false, userId, null, "startActivityAndWait"); 4628 return res; 4629 } 4630 4631 @Override 4632 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 4633 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4634 int startFlags, Configuration config, Bundle bOptions, int userId) { 4635 enforceNotIsolatedCaller("startActivityWithConfig"); 4636 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4637 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 4638 // TODO: Switch to user app stacks here. 4639 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, 4640 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 4641 null, null, config, bOptions, false, userId, null, "startActivityWithConfig"); 4642 return ret; 4643 } 4644 4645 @Override 4646 public int startActivityIntentSender(IApplicationThread caller, IIntentSender target, 4647 IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo, 4648 String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) 4649 throws TransactionTooLargeException { 4650 enforceNotIsolatedCaller("startActivityIntentSender"); 4651 // Refuse possible leaked file descriptors 4652 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 4653 throw new IllegalArgumentException("File descriptors passed in Intent"); 4654 } 4655 4656 if (!(target instanceof PendingIntentRecord)) { 4657 throw new IllegalArgumentException("Bad PendingIntent object"); 4658 } 4659 4660 PendingIntentRecord pir = (PendingIntentRecord)target; 4661 4662 synchronized (this) { 4663 // If this is coming from the currently resumed activity, it is 4664 // effectively saying that app switches are allowed at this point. 4665 final ActivityStack stack = getFocusedStack(); 4666 if (stack.mResumedActivity != null && 4667 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 4668 mAppSwitchesAllowedTime = 0; 4669 } 4670 } 4671 int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null, 4672 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions); 4673 return ret; 4674 } 4675 4676 @Override 4677 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 4678 Intent intent, String resolvedType, IVoiceInteractionSession session, 4679 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 4680 Bundle bOptions, int userId) { 4681 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 4682 != PackageManager.PERMISSION_GRANTED) { 4683 String msg = "Permission Denial: startVoiceActivity() from pid=" 4684 + Binder.getCallingPid() 4685 + ", uid=" + Binder.getCallingUid() 4686 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 4687 Slog.w(TAG, msg); 4688 throw new SecurityException(msg); 4689 } 4690 if (session == null || interactor == null) { 4691 throw new NullPointerException("null session or interactor"); 4692 } 4693 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false, 4694 ALLOW_FULL_ONLY, "startVoiceActivity", null); 4695 // TODO: Switch to user app stacks here. 4696 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent, 4697 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 4698 null, bOptions, false, userId, null, "startVoiceActivity"); 4699 } 4700 4701 @Override 4702 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid, 4703 Intent intent, String resolvedType, Bundle bOptions, int userId) { 4704 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 4705 != PackageManager.PERMISSION_GRANTED) { 4706 final String msg = "Permission Denial: startAssistantActivity() from pid=" 4707 + Binder.getCallingPid() 4708 + ", uid=" + Binder.getCallingUid() 4709 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION; 4710 Slog.w(TAG, msg); 4711 throw new SecurityException(msg); 4712 } 4713 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false, 4714 ALLOW_FULL_ONLY, "startAssistantActivity", null); 4715 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent, 4716 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false, 4717 userId, null, "startAssistantActivity"); 4718 } 4719 4720 @Override 4721 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) 4722 throws RemoteException { 4723 Slog.i(TAG, "Activity tried to startVoiceInteraction"); 4724 synchronized (this) { 4725 ActivityRecord activity = getFocusedStack().topActivity(); 4726 if (ActivityRecord.forTokenLocked(callingActivity) != activity) { 4727 throw new SecurityException("Only focused activity can call startVoiceInteraction"); 4728 } 4729 if (mRunningVoice != null || activity.getTask().voiceSession != null 4730 || activity.voiceSession != null) { 4731 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction"); 4732 return; 4733 } 4734 if (activity.pendingVoiceInteractionStart) { 4735 Slog.w(TAG, "Pending start of voice interaction already."); 4736 return; 4737 } 4738 activity.pendingVoiceInteractionStart = true; 4739 } 4740 LocalServices.getService(VoiceInteractionManagerInternal.class) 4741 .startLocalVoiceInteraction(callingActivity, options); 4742 } 4743 4744 @Override 4745 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException { 4746 LocalServices.getService(VoiceInteractionManagerInternal.class) 4747 .stopLocalVoiceInteraction(callingActivity); 4748 } 4749 4750 @Override 4751 public boolean supportsLocalVoiceInteraction() throws RemoteException { 4752 return LocalServices.getService(VoiceInteractionManagerInternal.class) 4753 .supportsLocalVoiceInteraction(); 4754 } 4755 4756 void onLocalVoiceInteractionStartedLocked(IBinder activity, 4757 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) { 4758 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity); 4759 if (activityToCallback == null) return; 4760 activityToCallback.setVoiceSessionLocked(voiceSession); 4761 4762 // Inform the activity 4763 try { 4764 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity, 4765 voiceInteractor); 4766 long token = Binder.clearCallingIdentity(); 4767 try { 4768 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid); 4769 } finally { 4770 Binder.restoreCallingIdentity(token); 4771 } 4772 // TODO: VI Should we cache the activity so that it's easier to find later 4773 // rather than scan through all the stacks and activities? 4774 } catch (RemoteException re) { 4775 activityToCallback.clearVoiceSessionLocked(); 4776 // TODO: VI Should this terminate the voice session? 4777 } 4778 } 4779 4780 @Override 4781 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) { 4782 synchronized (this) { 4783 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) { 4784 if (keepAwake) { 4785 mVoiceWakeLock.acquire(); 4786 } else { 4787 mVoiceWakeLock.release(); 4788 } 4789 } 4790 } 4791 } 4792 4793 @Override 4794 public boolean startNextMatchingActivity(IBinder callingActivity, 4795 Intent intent, Bundle bOptions) { 4796 // Refuse possible leaked file descriptors 4797 if (intent != null && intent.hasFileDescriptors() == true) { 4798 throw new IllegalArgumentException("File descriptors passed in Intent"); 4799 } 4800 ActivityOptions options = ActivityOptions.fromBundle(bOptions); 4801 4802 synchronized (this) { 4803 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 4804 if (r == null) { 4805 ActivityOptions.abort(options); 4806 return false; 4807 } 4808 if (r.app == null || r.app.thread == null) { 4809 // The caller is not running... d'oh! 4810 ActivityOptions.abort(options); 4811 return false; 4812 } 4813 intent = new Intent(intent); 4814 // The caller is not allowed to change the data. 4815 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 4816 // And we are resetting to find the next component... 4817 intent.setComponent(null); 4818 4819 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4820 4821 ActivityInfo aInfo = null; 4822 try { 4823 List<ResolveInfo> resolves = 4824 AppGlobals.getPackageManager().queryIntentActivities( 4825 intent, r.resolvedType, 4826 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 4827 UserHandle.getCallingUserId()).getList(); 4828 4829 // Look for the original activity in the list... 4830 final int N = resolves != null ? resolves.size() : 0; 4831 for (int i=0; i<N; i++) { 4832 ResolveInfo rInfo = resolves.get(i); 4833 if (rInfo.activityInfo.packageName.equals(r.packageName) 4834 && rInfo.activityInfo.name.equals(r.info.name)) { 4835 // We found the current one... the next matching is 4836 // after it. 4837 i++; 4838 if (i<N) { 4839 aInfo = resolves.get(i).activityInfo; 4840 } 4841 if (debug) { 4842 Slog.v(TAG, "Next matching activity: found current " + r.packageName 4843 + "/" + r.info.name); 4844 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null) 4845 ? "null" : aInfo.packageName + "/" + aInfo.name)); 4846 } 4847 break; 4848 } 4849 } 4850 } catch (RemoteException e) { 4851 } 4852 4853 if (aInfo == null) { 4854 // Nobody who is next! 4855 ActivityOptions.abort(options); 4856 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 4857 return false; 4858 } 4859 4860 intent.setComponent(new ComponentName( 4861 aInfo.applicationInfo.packageName, aInfo.name)); 4862 intent.setFlags(intent.getFlags()&~( 4863 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 4864 Intent.FLAG_ACTIVITY_CLEAR_TOP| 4865 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 4866 Intent.FLAG_ACTIVITY_NEW_TASK)); 4867 4868 // Okay now we need to start the new activity, replacing the 4869 // currently running activity. This is a little tricky because 4870 // we want to start the new one as if the current one is finished, 4871 // but not finish the current one first so that there is no flicker. 4872 // And thus... 4873 final boolean wasFinishing = r.finishing; 4874 r.finishing = true; 4875 4876 // Propagate reply information over to the new activity. 4877 final ActivityRecord resultTo = r.resultTo; 4878 final String resultWho = r.resultWho; 4879 final int requestCode = r.requestCode; 4880 r.resultTo = null; 4881 if (resultTo != null) { 4882 resultTo.removeResultsLocked(r, resultWho, requestCode); 4883 } 4884 4885 final long origId = Binder.clearCallingIdentity(); 4886 int res = mActivityStarter.startActivityLocked(r.app.thread, intent, 4887 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null, 4888 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1, 4889 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options, 4890 false, false, null, null, "startNextMatchingActivity"); 4891 Binder.restoreCallingIdentity(origId); 4892 4893 r.finishing = wasFinishing; 4894 if (res != ActivityManager.START_SUCCESS) { 4895 return false; 4896 } 4897 return true; 4898 } 4899 } 4900 4901 @Override 4902 public final int startActivityFromRecents(int taskId, Bundle bOptions) { 4903 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 4904 String msg = "Permission Denial: startActivityFromRecents called without " + 4905 START_TASKS_FROM_RECENTS; 4906 Slog.w(TAG, msg); 4907 throw new SecurityException(msg); 4908 } 4909 final long origId = Binder.clearCallingIdentity(); 4910 try { 4911 synchronized (this) { 4912 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions); 4913 } 4914 } finally { 4915 Binder.restoreCallingIdentity(origId); 4916 } 4917 } 4918 4919 final int startActivityInPackage(int uid, String callingPackage, 4920 Intent intent, String resolvedType, IBinder resultTo, 4921 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId, 4922 TaskRecord inTask, String reason) { 4923 4924 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4925 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 4926 4927 // TODO: Switch to user app stacks here. 4928 return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent, 4929 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 4930 null, null, null, bOptions, false, userId, inTask, reason); 4931 } 4932 4933 @Override 4934 public final int startActivities(IApplicationThread caller, String callingPackage, 4935 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions, 4936 int userId) { 4937 final String reason = "startActivities"; 4938 enforceNotIsolatedCaller(reason); 4939 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4940 userId, false, ALLOW_FULL_ONLY, reason, null); 4941 // TODO: Switch to user app stacks here. 4942 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents, 4943 resolvedTypes, resultTo, bOptions, userId, reason); 4944 return ret; 4945 } 4946 4947 final int startActivitiesInPackage(int uid, String callingPackage, 4948 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 4949 Bundle bOptions, int userId) { 4950 4951 final String reason = "startActivityInPackage"; 4952 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4953 userId, false, ALLOW_FULL_ONLY, reason, null); 4954 // TODO: Switch to user app stacks here. 4955 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes, 4956 resultTo, bOptions, userId, reason); 4957 return ret; 4958 } 4959 4960 @Override 4961 public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) { 4962 synchronized (this) { 4963 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4964 if (r == null) { 4965 return; 4966 } 4967 r.reportFullyDrawnLocked(restoredFromBundle); 4968 } 4969 } 4970 4971 @Override 4972 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4973 synchronized (this) { 4974 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4975 if (r == null) { 4976 return; 4977 } 4978 final long origId = Binder.clearCallingIdentity(); 4979 try { 4980 r.setRequestedOrientation(requestedOrientation); 4981 } finally { 4982 Binder.restoreCallingIdentity(origId); 4983 } 4984 } 4985 } 4986 4987 @Override 4988 public int getRequestedOrientation(IBinder token) { 4989 synchronized (this) { 4990 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4991 if (r == null) { 4992 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4993 } 4994 return r.getRequestedOrientation(); 4995 } 4996 } 4997 4998 @Override 4999 public final void requestActivityRelaunch(IBinder token) { 5000 synchronized(this) { 5001 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5002 if (r == null) { 5003 return; 5004 } 5005 final long origId = Binder.clearCallingIdentity(); 5006 try { 5007 r.forceNewConfig = true; 5008 r.ensureActivityConfigurationLocked(0 /* globalChanges */, 5009 true /* preserveWindow */); 5010 } finally { 5011 Binder.restoreCallingIdentity(origId); 5012 } 5013 } 5014 } 5015 5016 /** 5017 * This is the internal entry point for handling Activity.finish(). 5018 * 5019 * @param token The Binder token referencing the Activity we want to finish. 5020 * @param resultCode Result code, if any, from this Activity. 5021 * @param resultData Result data (Intent), if any, from this Activity. 5022 * @param finishTask Whether to finish the task associated with this Activity. 5023 * 5024 * @return Returns true if the activity successfully finished, or false if it is still running. 5025 */ 5026 @Override 5027 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 5028 int finishTask) { 5029 // Refuse possible leaked file descriptors 5030 if (resultData != null && resultData.hasFileDescriptors() == true) { 5031 throw new IllegalArgumentException("File descriptors passed in Intent"); 5032 } 5033 5034 synchronized(this) { 5035 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5036 if (r == null) { 5037 return true; 5038 } 5039 // Keep track of the root activity of the task before we finish it 5040 TaskRecord tr = r.getTask(); 5041 ActivityRecord rootR = tr.getRootActivity(); 5042 if (rootR == null) { 5043 Slog.w(TAG, "Finishing task with all activities already finished"); 5044 } 5045 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can 5046 // finish. 5047 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r && 5048 mStackSupervisor.isLastLockedTask(tr)) { 5049 Slog.i(TAG, "Not finishing task in lock task mode"); 5050 mStackSupervisor.showLockTaskToast(); 5051 return false; 5052 } 5053 if (mController != null) { 5054 // Find the first activity that is not finishing. 5055 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0); 5056 if (next != null) { 5057 // ask watcher if this is allowed 5058 boolean resumeOK = true; 5059 try { 5060 resumeOK = mController.activityResuming(next.packageName); 5061 } catch (RemoteException e) { 5062 mController = null; 5063 Watchdog.getInstance().setActivityController(null); 5064 } 5065 5066 if (!resumeOK) { 5067 Slog.i(TAG, "Not finishing activity because controller resumed"); 5068 return false; 5069 } 5070 } 5071 } 5072 final long origId = Binder.clearCallingIdentity(); 5073 try { 5074 boolean res; 5075 final boolean finishWithRootActivity = 5076 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY; 5077 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY 5078 || (finishWithRootActivity && r == rootR)) { 5079 // If requested, remove the task that is associated to this activity only if it 5080 // was the root activity in the task. The result code and data is ignored 5081 // because we don't support returning them across task boundaries. Also, to 5082 // keep backwards compatibility we remove the task from recents when finishing 5083 // task with root activity. 5084 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity); 5085 if (!res) { 5086 Slog.i(TAG, "Removing task failed to finish activity"); 5087 } 5088 } else { 5089 res = tr.getStack().requestFinishActivityLocked(token, resultCode, 5090 resultData, "app-request", true); 5091 if (!res) { 5092 Slog.i(TAG, "Failed to finish by app-request"); 5093 } 5094 } 5095 return res; 5096 } finally { 5097 Binder.restoreCallingIdentity(origId); 5098 } 5099 } 5100 } 5101 5102 @Override 5103 public final void finishHeavyWeightApp() { 5104 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5105 != PackageManager.PERMISSION_GRANTED) { 5106 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 5107 + Binder.getCallingPid() 5108 + ", uid=" + Binder.getCallingUid() 5109 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5110 Slog.w(TAG, msg); 5111 throw new SecurityException(msg); 5112 } 5113 5114 synchronized(this) { 5115 if (mHeavyWeightProcess == null) { 5116 return; 5117 } 5118 5119 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities); 5120 for (int i = 0; i < activities.size(); i++) { 5121 ActivityRecord r = activities.get(i); 5122 if (!r.finishing && r.isInStackLocked()) { 5123 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED, 5124 null, "finish-heavy", true); 5125 } 5126 } 5127 5128 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5129 mHeavyWeightProcess.userId, 0)); 5130 mHeavyWeightProcess = null; 5131 } 5132 } 5133 5134 @Override 5135 public void crashApplication(int uid, int initialPid, String packageName, int userId, 5136 String message) { 5137 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5138 != PackageManager.PERMISSION_GRANTED) { 5139 String msg = "Permission Denial: crashApplication() from pid=" 5140 + Binder.getCallingPid() 5141 + ", uid=" + Binder.getCallingUid() 5142 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5143 Slog.w(TAG, msg); 5144 throw new SecurityException(msg); 5145 } 5146 5147 synchronized(this) { 5148 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message); 5149 } 5150 } 5151 5152 @Override 5153 public final void finishSubActivity(IBinder token, String resultWho, 5154 int requestCode) { 5155 synchronized(this) { 5156 final long origId = Binder.clearCallingIdentity(); 5157 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5158 if (r != null) { 5159 r.getStack().finishSubActivityLocked(r, resultWho, requestCode); 5160 } 5161 Binder.restoreCallingIdentity(origId); 5162 } 5163 } 5164 5165 @Override 5166 public boolean finishActivityAffinity(IBinder token) { 5167 synchronized(this) { 5168 final long origId = Binder.clearCallingIdentity(); 5169 try { 5170 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5171 if (r == null) { 5172 return false; 5173 } 5174 5175 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps 5176 // can finish. 5177 final TaskRecord task = r.getTask(); 5178 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && 5179 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) { 5180 mStackSupervisor.showLockTaskToast(); 5181 return false; 5182 } 5183 return task.getStack().finishActivityAffinityLocked(r); 5184 } finally { 5185 Binder.restoreCallingIdentity(origId); 5186 } 5187 } 5188 } 5189 5190 @Override 5191 public void finishVoiceTask(IVoiceInteractionSession session) { 5192 synchronized (this) { 5193 final long origId = Binder.clearCallingIdentity(); 5194 try { 5195 // TODO: VI Consider treating local voice interactions and voice tasks 5196 // differently here 5197 mStackSupervisor.finishVoiceTask(session); 5198 } finally { 5199 Binder.restoreCallingIdentity(origId); 5200 } 5201 } 5202 5203 } 5204 5205 @Override 5206 public boolean releaseActivityInstance(IBinder token) { 5207 synchronized(this) { 5208 final long origId = Binder.clearCallingIdentity(); 5209 try { 5210 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5211 if (r == null) { 5212 return false; 5213 } 5214 return r.getStack().safelyDestroyActivityLocked(r, "app-req"); 5215 } finally { 5216 Binder.restoreCallingIdentity(origId); 5217 } 5218 } 5219 } 5220 5221 @Override 5222 public void releaseSomeActivities(IApplicationThread appInt) { 5223 synchronized(this) { 5224 final long origId = Binder.clearCallingIdentity(); 5225 try { 5226 ProcessRecord app = getRecordForAppLocked(appInt); 5227 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 5228 } finally { 5229 Binder.restoreCallingIdentity(origId); 5230 } 5231 } 5232 } 5233 5234 @Override 5235 public boolean willActivityBeVisible(IBinder token) { 5236 synchronized(this) { 5237 ActivityStack stack = ActivityRecord.getStackLocked(token); 5238 if (stack != null) { 5239 return stack.willActivityBeVisibleLocked(token); 5240 } 5241 return false; 5242 } 5243 } 5244 5245 @Override 5246 public void overridePendingTransition(IBinder token, String packageName, 5247 int enterAnim, int exitAnim) { 5248 synchronized(this) { 5249 ActivityRecord self = ActivityRecord.isInStackLocked(token); 5250 if (self == null) { 5251 return; 5252 } 5253 5254 final long origId = Binder.clearCallingIdentity(); 5255 5256 if (self.state == ActivityState.RESUMED 5257 || self.state == ActivityState.PAUSING) { 5258 mWindowManager.overridePendingAppTransition(packageName, 5259 enterAnim, exitAnim, null); 5260 } 5261 5262 Binder.restoreCallingIdentity(origId); 5263 } 5264 } 5265 5266 /** 5267 * Main function for removing an existing process from the activity manager 5268 * as a result of that process going away. Clears out all connections 5269 * to the process. 5270 */ 5271 private final void handleAppDiedLocked(ProcessRecord app, 5272 boolean restarting, boolean allowRestart) { 5273 int pid = app.pid; 5274 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1, 5275 false /*replacingPid*/); 5276 if (!kept && !restarting) { 5277 removeLruProcessLocked(app); 5278 if (pid > 0) { 5279 ProcessList.remove(pid); 5280 } 5281 } 5282 5283 if (mProfileProc == app) { 5284 clearProfilerLocked(); 5285 } 5286 5287 // Remove this application's activities from active lists. 5288 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 5289 5290 app.activities.clear(); 5291 5292 if (app.instr != null) { 5293 Slog.w(TAG, "Crash of app " + app.processName 5294 + " running instrumentation " + app.instr.mClass); 5295 Bundle info = new Bundle(); 5296 info.putString("shortMsg", "Process crashed."); 5297 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 5298 } 5299 5300 mWindowManager.deferSurfaceLayout(); 5301 try { 5302 if (!restarting && hasVisibleActivities 5303 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) { 5304 // If there was nothing to resume, and we are not already restarting this process, but 5305 // there is a visible activity that is hosted by the process... then make sure all 5306 // visible activities are running, taking care of restarting this process. 5307 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 5308 } 5309 } finally { 5310 mWindowManager.continueSurfaceLayout(); 5311 } 5312 } 5313 5314 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 5315 final IBinder threadBinder = thread.asBinder(); 5316 // Find the application record. 5317 for (int i=mLruProcesses.size()-1; i>=0; i--) { 5318 final ProcessRecord rec = mLruProcesses.get(i); 5319 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 5320 return i; 5321 } 5322 } 5323 return -1; 5324 } 5325 5326 final ProcessRecord getRecordForAppLocked( 5327 IApplicationThread thread) { 5328 if (thread == null) { 5329 return null; 5330 } 5331 5332 int appIndex = getLRURecordIndexForAppLocked(thread); 5333 if (appIndex >= 0) { 5334 return mLruProcesses.get(appIndex); 5335 } 5336 5337 // Validation: if it isn't in the LRU list, it shouldn't exist, but let's 5338 // double-check that. 5339 final IBinder threadBinder = thread.asBinder(); 5340 final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 5341 for (int i = pmap.size()-1; i >= 0; i--) { 5342 final SparseArray<ProcessRecord> procs = pmap.valueAt(i); 5343 for (int j = procs.size()-1; j >= 0; j--) { 5344 final ProcessRecord proc = procs.valueAt(j); 5345 if (proc.thread != null && proc.thread.asBinder() == threadBinder) { 5346 Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: " 5347 + proc); 5348 return proc; 5349 } 5350 } 5351 } 5352 5353 return null; 5354 } 5355 5356 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 5357 // If there are no longer any background processes running, 5358 // and the app that died was not running instrumentation, 5359 // then tell everyone we are now low on memory. 5360 boolean haveBg = false; 5361 for (int i=mLruProcesses.size()-1; i>=0; i--) { 5362 ProcessRecord rec = mLruProcesses.get(i); 5363 if (rec.thread != null 5364 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 5365 haveBg = true; 5366 break; 5367 } 5368 } 5369 5370 if (!haveBg) { 5371 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 5372 if (doReport) { 5373 long now = SystemClock.uptimeMillis(); 5374 if (now < (mLastMemUsageReportTime+5*60*1000)) { 5375 doReport = false; 5376 } else { 5377 mLastMemUsageReportTime = now; 5378 } 5379 } 5380 final ArrayList<ProcessMemInfo> memInfos 5381 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 5382 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 5383 long now = SystemClock.uptimeMillis(); 5384 for (int i=mLruProcesses.size()-1; i>=0; i--) { 5385 ProcessRecord rec = mLruProcesses.get(i); 5386 if (rec == dyingProc || rec.thread == null) { 5387 continue; 5388 } 5389 if (doReport) { 5390 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 5391 rec.setProcState, rec.adjType, rec.makeAdjReason())); 5392 } 5393 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) { 5394 // The low memory report is overriding any current 5395 // state for a GC request. Make sure to do 5396 // heavy/important/visible/foreground processes first. 5397 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 5398 rec.lastRequestedGc = 0; 5399 } else { 5400 rec.lastRequestedGc = rec.lastLowMemory; 5401 } 5402 rec.reportLowMemory = true; 5403 rec.lastLowMemory = now; 5404 mProcessesToGc.remove(rec); 5405 addProcessToGcListLocked(rec); 5406 } 5407 } 5408 if (doReport) { 5409 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 5410 mHandler.sendMessage(msg); 5411 } 5412 scheduleAppGcsLocked(); 5413 } 5414 } 5415 5416 final void appDiedLocked(ProcessRecord app) { 5417 appDiedLocked(app, app.pid, app.thread, false); 5418 } 5419 5420 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread, 5421 boolean fromBinderDied) { 5422 // First check if this ProcessRecord is actually active for the pid. 5423 synchronized (mPidsSelfLocked) { 5424 ProcessRecord curProc = mPidsSelfLocked.get(pid); 5425 if (curProc != app) { 5426 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 5427 return; 5428 } 5429 } 5430 5431 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 5432 synchronized (stats) { 5433 stats.noteProcessDiedLocked(app.info.uid, pid); 5434 } 5435 5436 if (!app.killed) { 5437 if (!fromBinderDied) { 5438 killProcessQuiet(pid); 5439 } 5440 killProcessGroup(app.uid, pid); 5441 app.killed = true; 5442 } 5443 5444 // Clean up already done if the process has been re-started. 5445 if (app.pid == pid && app.thread != null && 5446 app.thread.asBinder() == thread.asBinder()) { 5447 boolean doLowMem = app.instr == null; 5448 boolean doOomAdj = doLowMem; 5449 if (!app.killedByAm) { 5450 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: " 5451 + ProcessList.makeOomAdjString(app.setAdj) 5452 + ProcessList.makeProcStateString(app.setProcState)); 5453 mAllowLowerMemLevel = true; 5454 } else { 5455 // Note that we always want to do oom adj to update our state with the 5456 // new number of procs. 5457 mAllowLowerMemLevel = false; 5458 doLowMem = false; 5459 } 5460 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName, 5461 app.setAdj, app.setProcState); 5462 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, 5463 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder()); 5464 handleAppDiedLocked(app, false, true); 5465 5466 if (doOomAdj) { 5467 updateOomAdjLocked(); 5468 } 5469 if (doLowMem) { 5470 doLowMemReportIfNeededLocked(app); 5471 } 5472 } else if (app.pid != pid) { 5473 // A new process has already been started. 5474 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 5475 + ") has died and restarted (pid " + app.pid + ")."); 5476 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 5477 } else if (DEBUG_PROCESSES) { 5478 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread " 5479 + thread.asBinder()); 5480 } 5481 } 5482 5483 /** 5484 * If a stack trace dump file is configured, dump process stack traces. 5485 * @param clearTraces causes the dump file to be erased prior to the new 5486 * traces being written, if true; when false, the new traces will be 5487 * appended to any existing file content. 5488 * @param firstPids of dalvik VM processes to dump stack traces for first 5489 * @param lastPids of dalvik VM processes to dump stack traces for last 5490 * @param nativePids optional list of native pids to dump stack crawls 5491 */ 5492 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 5493 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, 5494 ArrayList<Integer> nativePids) { 5495 ArrayList<Integer> extraPids = null; 5496 5497 // Measure CPU usage as soon as we're called in order to get a realistic sampling 5498 // of the top users at the time of the request. 5499 if (processCpuTracker != null) { 5500 processCpuTracker.init(); 5501 try { 5502 Thread.sleep(200); 5503 } catch (InterruptedException ignored) { 5504 } 5505 5506 processCpuTracker.update(); 5507 5508 // We'll take the stack crawls of just the top apps using CPU. 5509 final int N = processCpuTracker.countWorkingStats(); 5510 extraPids = new ArrayList<>(); 5511 for (int i = 0; i < N && extraPids.size() < 5; i++) { 5512 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 5513 if (lastPids.indexOfKey(stats.pid) >= 0) { 5514 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid); 5515 5516 extraPids.add(stats.pid); 5517 } else if (DEBUG_ANR) { 5518 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: " 5519 + stats.pid); 5520 } 5521 } 5522 } 5523 5524 boolean useTombstonedForJavaTraces = false; 5525 File tracesFile; 5526 5527 final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", ""); 5528 if (tracesDirProp.isEmpty()) { 5529 // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace 5530 // dumping scheme. All traces are written to a global trace file (usually 5531 // "/data/anr/traces.txt") so the code below must take care to unlink and recreate 5532 // the file if requested. 5533 // 5534 // This mode of operation will be removed in the near future. 5535 5536 5537 String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 5538 if (globalTracesPath.isEmpty()) { 5539 Slog.w(TAG, "dumpStackTraces: no trace path configured"); 5540 return null; 5541 } 5542 5543 tracesFile = new File(globalTracesPath); 5544 try { 5545 if (clearTraces && tracesFile.exists()) { 5546 tracesFile.delete(); 5547 } 5548 5549 tracesFile.createNewFile(); 5550 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw- 5551 } catch (IOException e) { 5552 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e); 5553 return null; 5554 } 5555 } else { 5556 File tracesDir = new File(tracesDirProp); 5557 // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme. 5558 // Each set of ANR traces is written to a separate file and dumpstate will process 5559 // all such files and add them to a captured bug report if they're recent enough. 5560 maybePruneOldTraces(tracesDir); 5561 5562 // NOTE: We should consider creating the file in native code atomically once we've 5563 // gotten rid of the old scheme of dumping and lot of the code that deals with paths 5564 // can be removed. 5565 tracesFile = createAnrDumpFile(tracesDir); 5566 if (tracesFile == null) { 5567 return null; 5568 } 5569 5570 useTombstonedForJavaTraces = true; 5571 } 5572 5573 dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids, 5574 useTombstonedForJavaTraces); 5575 return tracesFile; 5576 } 5577 5578 @GuardedBy("ActivityManagerService.class") 5579 private static SimpleDateFormat sAnrFileDateFormat; 5580 5581 private static synchronized File createAnrDumpFile(File tracesDir) { 5582 if (sAnrFileDateFormat == null) { 5583 sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS"); 5584 } 5585 5586 final String formattedDate = sAnrFileDateFormat.format(new Date()); 5587 final File anrFile = new File(tracesDir, "anr_" + formattedDate); 5588 5589 try { 5590 if (anrFile.createNewFile()) { 5591 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw------- 5592 return anrFile; 5593 } else { 5594 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed"); 5595 } 5596 } catch (IOException ioe) { 5597 Slog.w(TAG, "Exception creating ANR dump file:", ioe); 5598 } 5599 5600 return null; 5601 } 5602 5603 /** 5604 * Prune all trace files that are more than a day old. 5605 * 5606 * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a 5607 * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now 5608 * since it's the system_server that creates trace files for most ANRs. 5609 */ 5610 private static void maybePruneOldTraces(File tracesDir) { 5611 final long now = System.currentTimeMillis(); 5612 final File[] traceFiles = tracesDir.listFiles(); 5613 5614 if (traceFiles != null) { 5615 for (File file : traceFiles) { 5616 if ((now - file.lastModified()) > DAY_IN_MILLIS) { 5617 if (!file.delete()) { 5618 Slog.w(TAG, "Unable to prune stale trace file: " + file); 5619 } 5620 } 5621 } 5622 } 5623 } 5624 5625 /** 5626 * Legacy code, do not use. Existing users will be deleted. 5627 * 5628 * @deprecated 5629 */ 5630 @Deprecated 5631 public static class DumpStackFileObserver extends FileObserver { 5632 // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp 5633 private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds 5634 5635 private final String mTracesPath; 5636 private boolean mClosed; 5637 5638 public DumpStackFileObserver(String tracesPath) { 5639 super(tracesPath, FileObserver.CLOSE_WRITE); 5640 mTracesPath = tracesPath; 5641 } 5642 5643 @Override 5644 public synchronized void onEvent(int event, String path) { 5645 mClosed = true; 5646 notify(); 5647 } 5648 5649 public long dumpWithTimeout(int pid, long timeout) { 5650 sendSignal(pid, SIGNAL_QUIT); 5651 final long start = SystemClock.elapsedRealtime(); 5652 5653 final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS); 5654 synchronized (this) { 5655 try { 5656 wait(waitTime); // Wait for traces file to be closed. 5657 } catch (InterruptedException e) { 5658 Slog.wtf(TAG, e); 5659 } 5660 } 5661 5662 // This avoids a corner case of passing a negative time to the native 5663 // trace in case we've already hit the overall timeout. 5664 final long timeWaited = SystemClock.elapsedRealtime() - start; 5665 if (timeWaited >= timeout) { 5666 return timeWaited; 5667 } 5668 5669 if (!mClosed) { 5670 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid + 5671 ". Attempting native stack collection."); 5672 5673 final long nativeDumpTimeoutMs = Math.min( 5674 NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited); 5675 5676 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath, 5677 (int) (nativeDumpTimeoutMs / 1000)); 5678 } 5679 5680 final long end = SystemClock.elapsedRealtime(); 5681 mClosed = false; 5682 5683 return (end - start); 5684 } 5685 } 5686 5687 /** 5688 * Dump java traces for process {@code pid} to the specified file. If java trace dumping 5689 * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies 5690 * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent 5691 * attempting to obtain native traces in the case of a failure. Returns the total time spent 5692 * capturing traces. 5693 */ 5694 private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) { 5695 final long timeStart = SystemClock.elapsedRealtime(); 5696 if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) { 5697 Debug.dumpNativeBacktraceToFileTimeout(pid, fileName, 5698 (NATIVE_DUMP_TIMEOUT_MS / 1000)); 5699 } 5700 5701 return SystemClock.elapsedRealtime() - timeStart; 5702 } 5703 5704 private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids, 5705 ArrayList<Integer> nativePids, ArrayList<Integer> extraPids, 5706 boolean useTombstonedForJavaTraces) { 5707 5708 // We don't need any sort of inotify based monitoring when we're dumping traces via 5709 // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full 5710 // control of all writes to the file in question. 5711 final DumpStackFileObserver observer; 5712 if (useTombstonedForJavaTraces) { 5713 observer = null; 5714 } else { 5715 // Use a FileObserver to detect when traces finish writing. 5716 // The order of traces is considered important to maintain for legibility. 5717 observer = new DumpStackFileObserver(tracesFile); 5718 } 5719 5720 // We must complete all stack dumps within 20 seconds. 5721 long remainingTime = 20 * 1000; 5722 try { 5723 if (observer != null) { 5724 observer.startWatching(); 5725 } 5726 5727 // First collect all of the stacks of the most important pids. 5728 if (firstPids != null) { 5729 int num = firstPids.size(); 5730 for (int i = 0; i < num; i++) { 5731 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid " 5732 + firstPids.get(i)); 5733 final long timeTaken; 5734 if (useTombstonedForJavaTraces) { 5735 timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime); 5736 } else { 5737 timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime); 5738 } 5739 5740 remainingTime -= timeTaken; 5741 if (remainingTime <= 0) { 5742 Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) + 5743 "); deadline exceeded."); 5744 return; 5745 } 5746 5747 if (DEBUG_ANR) { 5748 Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms"); 5749 } 5750 } 5751 } 5752 5753 // Next collect the stacks of the native pids 5754 if (nativePids != null) { 5755 for (int pid : nativePids) { 5756 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid); 5757 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime); 5758 5759 final long start = SystemClock.elapsedRealtime(); 5760 Debug.dumpNativeBacktraceToFileTimeout( 5761 pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000)); 5762 final long timeTaken = SystemClock.elapsedRealtime() - start; 5763 5764 remainingTime -= timeTaken; 5765 if (remainingTime <= 0) { 5766 Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid + 5767 "); deadline exceeded."); 5768 return; 5769 } 5770 5771 if (DEBUG_ANR) { 5772 Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms"); 5773 } 5774 } 5775 } 5776 5777 // Lastly, dump stacks for all extra PIDs from the CPU tracker. 5778 if (extraPids != null) { 5779 for (int pid : extraPids) { 5780 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid); 5781 5782 final long timeTaken; 5783 if (useTombstonedForJavaTraces) { 5784 timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime); 5785 } else { 5786 timeTaken = observer.dumpWithTimeout(pid, remainingTime); 5787 } 5788 5789 remainingTime -= timeTaken; 5790 if (remainingTime <= 0) { 5791 Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid + 5792 "); deadline exceeded."); 5793 return; 5794 } 5795 5796 if (DEBUG_ANR) { 5797 Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms"); 5798 } 5799 } 5800 } 5801 } finally { 5802 if (observer != null) { 5803 observer.stopWatching(); 5804 } 5805 } 5806 } 5807 5808 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 5809 if (true || Build.IS_USER) { 5810 return; 5811 } 5812 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 5813 if (tracesPath == null || tracesPath.length() == 0) { 5814 return; 5815 } 5816 5817 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 5818 StrictMode.allowThreadDiskWrites(); 5819 try { 5820 final File tracesFile = new File(tracesPath); 5821 final File tracesDir = tracesFile.getParentFile(); 5822 final File tracesTmp = new File(tracesDir, "__tmp__"); 5823 try { 5824 if (tracesFile.exists()) { 5825 tracesTmp.delete(); 5826 tracesFile.renameTo(tracesTmp); 5827 } 5828 StringBuilder sb = new StringBuilder(); 5829 Time tobj = new Time(); 5830 tobj.set(System.currentTimeMillis()); 5831 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5832 sb.append(": "); 5833 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5834 sb.append(" since "); 5835 sb.append(msg); 5836 FileOutputStream fos = new FileOutputStream(tracesFile); 5837 fos.write(sb.toString().getBytes()); 5838 if (app == null) { 5839 fos.write("\n*** No application process!".getBytes()); 5840 } 5841 fos.close(); 5842 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5843 } catch (IOException e) { 5844 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5845 return; 5846 } 5847 5848 if (app != null) { 5849 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5850 firstPids.add(app.pid); 5851 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */); 5852 } 5853 5854 File lastTracesFile = null; 5855 File curTracesFile = null; 5856 for (int i=9; i>=0; i--) { 5857 String name = String.format(Locale.US, "slow%02d.txt", i); 5858 curTracesFile = new File(tracesDir, name); 5859 if (curTracesFile.exists()) { 5860 if (lastTracesFile != null) { 5861 curTracesFile.renameTo(lastTracesFile); 5862 } else { 5863 curTracesFile.delete(); 5864 } 5865 } 5866 lastTracesFile = curTracesFile; 5867 } 5868 tracesFile.renameTo(curTracesFile); 5869 if (tracesTmp.exists()) { 5870 tracesTmp.renameTo(tracesFile); 5871 } 5872 } finally { 5873 StrictMode.setThreadPolicy(oldPolicy); 5874 } 5875 } 5876 5877 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5878 if (!mLaunchWarningShown) { 5879 mLaunchWarningShown = true; 5880 mUiHandler.post(new Runnable() { 5881 @Override 5882 public void run() { 5883 synchronized (ActivityManagerService.this) { 5884 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5885 d.show(); 5886 mUiHandler.postDelayed(new Runnable() { 5887 @Override 5888 public void run() { 5889 synchronized (ActivityManagerService.this) { 5890 d.dismiss(); 5891 mLaunchWarningShown = false; 5892 } 5893 } 5894 }, 4000); 5895 } 5896 } 5897 }); 5898 } 5899 } 5900 5901 @Override 5902 public boolean clearApplicationUserData(final String packageName, 5903 final IPackageDataObserver observer, int userId) { 5904 enforceNotIsolatedCaller("clearApplicationUserData"); 5905 int uid = Binder.getCallingUid(); 5906 int pid = Binder.getCallingPid(); 5907 final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false, 5908 ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5909 5910 final ApplicationInfo appInfo; 5911 final boolean isInstantApp; 5912 5913 long callingId = Binder.clearCallingIdentity(); 5914 try { 5915 IPackageManager pm = AppGlobals.getPackageManager(); 5916 synchronized(this) { 5917 // Instant packages are not protected 5918 if (getPackageManagerInternalLocked().isPackageDataProtected( 5919 resolvedUserId, packageName)) { 5920 throw new SecurityException( 5921 "Cannot clear data for a protected package: " + packageName); 5922 } 5923 5924 ApplicationInfo applicationInfo = null; 5925 try { 5926 applicationInfo = pm.getApplicationInfo(packageName, 5927 MATCH_UNINSTALLED_PACKAGES, resolvedUserId); 5928 } catch (RemoteException e) { 5929 /* ignore */ 5930 } 5931 appInfo = applicationInfo; 5932 5933 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid; 5934 5935 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA, 5936 pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) { 5937 throw new SecurityException("PID " + pid + " does not have permission " 5938 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5939 + " of package " + packageName); 5940 } 5941 5942 final boolean hasInstantMetadata = getPackageManagerInternalLocked() 5943 .hasInstantApplicationMetadata(packageName, resolvedUserId); 5944 final boolean isUninstalledAppWithoutInstantMetadata = 5945 (appInfo == null && !hasInstantMetadata); 5946 isInstantApp = (appInfo != null && appInfo.isInstantApp()) 5947 || hasInstantMetadata; 5948 final boolean canAccessInstantApps = checkComponentPermission( 5949 permission.ACCESS_INSTANT_APPS, pid, uid, -1, true) 5950 == PackageManager.PERMISSION_GRANTED; 5951 5952 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp 5953 && !canAccessInstantApps)) { 5954 Slog.w(TAG, "Invalid packageName: " + packageName); 5955 if (observer != null) { 5956 try { 5957 observer.onRemoveCompleted(packageName, false); 5958 } catch (RemoteException e) { 5959 Slog.i(TAG, "Observer no longer exists."); 5960 } 5961 } 5962 return false; 5963 } 5964 5965 if (appInfo != null) { 5966 forceStopPackageLocked(packageName, appInfo.uid, "clear data"); 5967 // Remove all tasks match the cleared application package and user 5968 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5969 final TaskRecord tr = mRecentTasks.get(i); 5970 final String taskPackageName = 5971 tr.getBaseIntent().getComponent().getPackageName(); 5972 if (tr.userId != resolvedUserId) continue; 5973 if (!taskPackageName.equals(packageName)) continue; 5974 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, 5975 REMOVE_FROM_RECENTS); 5976 } 5977 } 5978 } 5979 5980 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() { 5981 @Override 5982 public void onRemoveCompleted(String packageName, boolean succeeded) 5983 throws RemoteException { 5984 if (appInfo != null) { 5985 synchronized (ActivityManagerService.this) { 5986 finishForceStopPackageLocked(packageName, appInfo.uid); 5987 } 5988 } 5989 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5990 Uri.fromParts("package", packageName, null)); 5991 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 5992 intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1); 5993 intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId); 5994 if (isInstantApp) { 5995 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); 5996 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0, 5997 null, null, permission.ACCESS_INSTANT_APPS, null, false, false, 5998 resolvedUserId); 5999 } else { 6000 broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0, 6001 null, null, null, null, false, false, resolvedUserId); 6002 } 6003 6004 if (observer != null) { 6005 observer.onRemoveCompleted(packageName, succeeded); 6006 } 6007 } 6008 }; 6009 6010 try { 6011 // Clear application user data 6012 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId); 6013 6014 if (appInfo != null) { 6015 synchronized (this) { 6016 // Remove all permissions granted from/to this package 6017 removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true); 6018 } 6019 6020 // Reset notification settings. 6021 INotificationManager inm = NotificationManager.getService(); 6022 inm.clearData(packageName, appInfo.uid, uid == appInfo.uid); 6023 } 6024 } catch (RemoteException e) { 6025 } 6026 } finally { 6027 Binder.restoreCallingIdentity(callingId); 6028 } 6029 return true; 6030 } 6031 6032 @Override 6033 public void killBackgroundProcesses(final String packageName, int userId) { 6034 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 6035 != PackageManager.PERMISSION_GRANTED && 6036 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 6037 != PackageManager.PERMISSION_GRANTED) { 6038 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 6039 + Binder.getCallingPid() 6040 + ", uid=" + Binder.getCallingUid() 6041 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 6042 Slog.w(TAG, msg); 6043 throw new SecurityException(msg); 6044 } 6045 6046 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 6047 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 6048 long callingId = Binder.clearCallingIdentity(); 6049 try { 6050 IPackageManager pm = AppGlobals.getPackageManager(); 6051 synchronized(this) { 6052 int appId = -1; 6053 try { 6054 appId = UserHandle.getAppId( 6055 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId)); 6056 } catch (RemoteException e) { 6057 } 6058 if (appId == -1) { 6059 Slog.w(TAG, "Invalid packageName: " + packageName); 6060 return; 6061 } 6062 killPackageProcessesLocked(packageName, appId, userId, 6063 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 6064 } 6065 } finally { 6066 Binder.restoreCallingIdentity(callingId); 6067 } 6068 } 6069 6070 @Override 6071 public void killAllBackgroundProcesses() { 6072 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 6073 != PackageManager.PERMISSION_GRANTED) { 6074 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 6075 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 6076 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 6077 Slog.w(TAG, msg); 6078 throw new SecurityException(msg); 6079 } 6080 6081 final long callingId = Binder.clearCallingIdentity(); 6082 try { 6083 synchronized (this) { 6084 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 6085 final int NP = mProcessNames.getMap().size(); 6086 for (int ip = 0; ip < NP; ip++) { 6087 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 6088 final int NA = apps.size(); 6089 for (int ia = 0; ia < NA; ia++) { 6090 final ProcessRecord app = apps.valueAt(ia); 6091 if (app.persistent) { 6092 // We don't kill persistent processes. 6093 continue; 6094 } 6095 if (app.removed) { 6096 procs.add(app); 6097 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 6098 app.removed = true; 6099 procs.add(app); 6100 } 6101 } 6102 } 6103 6104 final int N = procs.size(); 6105 for (int i = 0; i < N; i++) { 6106 removeProcessLocked(procs.get(i), false, true, "kill all background"); 6107 } 6108 6109 mAllowLowerMemLevel = true; 6110 6111 updateOomAdjLocked(); 6112 doLowMemReportIfNeededLocked(null); 6113 } 6114 } finally { 6115 Binder.restoreCallingIdentity(callingId); 6116 } 6117 } 6118 6119 /** 6120 * Kills all background processes, except those matching any of the 6121 * specified properties. 6122 * 6123 * @param minTargetSdk the target SDK version at or above which to preserve 6124 * processes, or {@code -1} to ignore the target SDK 6125 * @param maxProcState the process state at or below which to preserve 6126 * processes, or {@code -1} to ignore the process state 6127 */ 6128 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) { 6129 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 6130 != PackageManager.PERMISSION_GRANTED) { 6131 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid=" 6132 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 6133 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 6134 Slog.w(TAG, msg); 6135 throw new SecurityException(msg); 6136 } 6137 6138 final long callingId = Binder.clearCallingIdentity(); 6139 try { 6140 synchronized (this) { 6141 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 6142 final int NP = mProcessNames.getMap().size(); 6143 for (int ip = 0; ip < NP; ip++) { 6144 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 6145 final int NA = apps.size(); 6146 for (int ia = 0; ia < NA; ia++) { 6147 final ProcessRecord app = apps.valueAt(ia); 6148 if (app.removed) { 6149 procs.add(app); 6150 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk) 6151 && (maxProcState < 0 || app.setProcState > maxProcState)) { 6152 app.removed = true; 6153 procs.add(app); 6154 } 6155 } 6156 } 6157 6158 final int N = procs.size(); 6159 for (int i = 0; i < N; i++) { 6160 removeProcessLocked(procs.get(i), false, true, "kill all background except"); 6161 } 6162 } 6163 } finally { 6164 Binder.restoreCallingIdentity(callingId); 6165 } 6166 } 6167 6168 @Override 6169 public void forceStopPackage(final String packageName, int userId) { 6170 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 6171 != PackageManager.PERMISSION_GRANTED) { 6172 String msg = "Permission Denial: forceStopPackage() from pid=" 6173 + Binder.getCallingPid() 6174 + ", uid=" + Binder.getCallingUid() 6175 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 6176 Slog.w(TAG, msg); 6177 throw new SecurityException(msg); 6178 } 6179 final int callingPid = Binder.getCallingPid(); 6180 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(), 6181 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 6182 long callingId = Binder.clearCallingIdentity(); 6183 try { 6184 IPackageManager pm = AppGlobals.getPackageManager(); 6185 synchronized(this) { 6186 int[] users = userId == UserHandle.USER_ALL 6187 ? mUserController.getUsers() : new int[] { userId }; 6188 for (int user : users) { 6189 int pkgUid = -1; 6190 try { 6191 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 6192 user); 6193 } catch (RemoteException e) { 6194 } 6195 if (pkgUid == -1) { 6196 Slog.w(TAG, "Invalid packageName: " + packageName); 6197 continue; 6198 } 6199 try { 6200 pm.setPackageStoppedState(packageName, true, user); 6201 } catch (RemoteException e) { 6202 } catch (IllegalArgumentException e) { 6203 Slog.w(TAG, "Failed trying to unstop package " 6204 + packageName + ": " + e); 6205 } 6206 if (mUserController.isUserRunningLocked(user, 0)) { 6207 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 6208 finishForceStopPackageLocked(packageName, pkgUid); 6209 } 6210 } 6211 } 6212 } finally { 6213 Binder.restoreCallingIdentity(callingId); 6214 } 6215 } 6216 6217 @Override 6218 public void addPackageDependency(String packageName) { 6219 synchronized (this) { 6220 int callingPid = Binder.getCallingPid(); 6221 if (callingPid == myPid()) { 6222 // Yeah, um, no. 6223 return; 6224 } 6225 ProcessRecord proc; 6226 synchronized (mPidsSelfLocked) { 6227 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 6228 } 6229 if (proc != null) { 6230 if (proc.pkgDeps == null) { 6231 proc.pkgDeps = new ArraySet<String>(1); 6232 } 6233 proc.pkgDeps.add(packageName); 6234 } 6235 } 6236 } 6237 6238 /* 6239 * The pkg name and app id have to be specified. 6240 */ 6241 @Override 6242 public void killApplication(String pkg, int appId, int userId, String reason) { 6243 if (pkg == null) { 6244 return; 6245 } 6246 // Make sure the uid is valid. 6247 if (appId < 0) { 6248 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 6249 return; 6250 } 6251 int callerUid = Binder.getCallingUid(); 6252 // Only the system server can kill an application 6253 if (UserHandle.getAppId(callerUid) == SYSTEM_UID) { 6254 // Post an aysnc message to kill the application 6255 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 6256 msg.arg1 = appId; 6257 msg.arg2 = userId; 6258 Bundle bundle = new Bundle(); 6259 bundle.putString("pkg", pkg); 6260 bundle.putString("reason", reason); 6261 msg.obj = bundle; 6262 mHandler.sendMessage(msg); 6263 } else { 6264 throw new SecurityException(callerUid + " cannot kill pkg: " + 6265 pkg); 6266 } 6267 } 6268 6269 @Override 6270 public void closeSystemDialogs(String reason) { 6271 enforceNotIsolatedCaller("closeSystemDialogs"); 6272 6273 final int pid = Binder.getCallingPid(); 6274 final int uid = Binder.getCallingUid(); 6275 final long origId = Binder.clearCallingIdentity(); 6276 try { 6277 synchronized (this) { 6278 // Only allow this from foreground processes, so that background 6279 // applications can't abuse it to prevent system UI from being shown. 6280 if (uid >= FIRST_APPLICATION_UID) { 6281 ProcessRecord proc; 6282 synchronized (mPidsSelfLocked) { 6283 proc = mPidsSelfLocked.get(pid); 6284 } 6285 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 6286 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 6287 + " from background process " + proc); 6288 return; 6289 } 6290 } 6291 closeSystemDialogsLocked(reason); 6292 } 6293 } finally { 6294 Binder.restoreCallingIdentity(origId); 6295 } 6296 } 6297 6298 void closeSystemDialogsLocked(String reason) { 6299 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 6300 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 6301 | Intent.FLAG_RECEIVER_FOREGROUND); 6302 if (reason != null) { 6303 intent.putExtra("reason", reason); 6304 } 6305 mWindowManager.closeSystemDialogs(reason); 6306 6307 mStackSupervisor.closeSystemDialogsLocked(); 6308 6309 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 6310 AppOpsManager.OP_NONE, null, false, false, 6311 -1, SYSTEM_UID, UserHandle.USER_ALL); 6312 } 6313 6314 @Override 6315 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 6316 enforceNotIsolatedCaller("getProcessMemoryInfo"); 6317 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 6318 for (int i=pids.length-1; i>=0; i--) { 6319 ProcessRecord proc; 6320 int oomAdj; 6321 synchronized (this) { 6322 synchronized (mPidsSelfLocked) { 6323 proc = mPidsSelfLocked.get(pids[i]); 6324 oomAdj = proc != null ? proc.setAdj : 0; 6325 } 6326 } 6327 infos[i] = new Debug.MemoryInfo(); 6328 Debug.getMemoryInfo(pids[i], infos[i]); 6329 if (proc != null) { 6330 synchronized (this) { 6331 if (proc.thread != null && proc.setAdj == oomAdj) { 6332 // Record this for posterity if the process has been stable. 6333 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 6334 infos[i].getTotalUss(), false, proc.pkgList); 6335 } 6336 } 6337 } 6338 } 6339 return infos; 6340 } 6341 6342 @Override 6343 public long[] getProcessPss(int[] pids) { 6344 enforceNotIsolatedCaller("getProcessPss"); 6345 long[] pss = new long[pids.length]; 6346 for (int i=pids.length-1; i>=0; i--) { 6347 ProcessRecord proc; 6348 int oomAdj; 6349 synchronized (this) { 6350 synchronized (mPidsSelfLocked) { 6351 proc = mPidsSelfLocked.get(pids[i]); 6352 oomAdj = proc != null ? proc.setAdj : 0; 6353 } 6354 } 6355 long[] tmpUss = new long[1]; 6356 pss[i] = Debug.getPss(pids[i], tmpUss, null); 6357 if (proc != null) { 6358 synchronized (this) { 6359 if (proc.thread != null && proc.setAdj == oomAdj) { 6360 // Record this for posterity if the process has been stable. 6361 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 6362 } 6363 } 6364 } 6365 } 6366 return pss; 6367 } 6368 6369 @Override 6370 public void killApplicationProcess(String processName, int uid) { 6371 if (processName == null) { 6372 return; 6373 } 6374 6375 int callerUid = Binder.getCallingUid(); 6376 // Only the system server can kill an application 6377 if (callerUid == SYSTEM_UID) { 6378 synchronized (this) { 6379 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 6380 if (app != null && app.thread != null) { 6381 try { 6382 app.thread.scheduleSuicide(); 6383 } catch (RemoteException e) { 6384 // If the other end already died, then our work here is done. 6385 } 6386 } else { 6387 Slog.w(TAG, "Process/uid not found attempting kill of " 6388 + processName + " / " + uid); 6389 } 6390 } 6391 } else { 6392 throw new SecurityException(callerUid + " cannot kill app process: " + 6393 processName); 6394 } 6395 } 6396 6397 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 6398 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 6399 false, true, false, false, UserHandle.getUserId(uid), reason); 6400 } 6401 6402 private void finishForceStopPackageLocked(final String packageName, int uid) { 6403 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 6404 Uri.fromParts("package", packageName, null)); 6405 if (!mProcessesReady) { 6406 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 6407 | Intent.FLAG_RECEIVER_FOREGROUND); 6408 } 6409 intent.putExtra(Intent.EXTRA_UID, uid); 6410 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 6411 broadcastIntentLocked(null, null, intent, 6412 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 6413 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid)); 6414 } 6415 6416 6417 private final boolean killPackageProcessesLocked(String packageName, int appId, 6418 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 6419 boolean doit, boolean evenPersistent, String reason) { 6420 ArrayList<ProcessRecord> procs = new ArrayList<>(); 6421 6422 // Remove all processes this package may have touched: all with the 6423 // same UID (except for the system or root user), and all whose name 6424 // matches the package name. 6425 final int NP = mProcessNames.getMap().size(); 6426 for (int ip=0; ip<NP; ip++) { 6427 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 6428 final int NA = apps.size(); 6429 for (int ia=0; ia<NA; ia++) { 6430 ProcessRecord app = apps.valueAt(ia); 6431 if (app.persistent && !evenPersistent) { 6432 // we don't kill persistent processes 6433 continue; 6434 } 6435 if (app.removed) { 6436 if (doit) { 6437 procs.add(app); 6438 } 6439 continue; 6440 } 6441 6442 // Skip process if it doesn't meet our oom adj requirement. 6443 if (app.setAdj < minOomAdj) { 6444 continue; 6445 } 6446 6447 // If no package is specified, we call all processes under the 6448 // give user id. 6449 if (packageName == null) { 6450 if (userId != UserHandle.USER_ALL && app.userId != userId) { 6451 continue; 6452 } 6453 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 6454 continue; 6455 } 6456 // Package has been specified, we want to hit all processes 6457 // that match it. We need to qualify this by the processes 6458 // that are running under the specified app and user ID. 6459 } else { 6460 final boolean isDep = app.pkgDeps != null 6461 && app.pkgDeps.contains(packageName); 6462 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 6463 continue; 6464 } 6465 if (userId != UserHandle.USER_ALL && app.userId != userId) { 6466 continue; 6467 } 6468 if (!app.pkgList.containsKey(packageName) && !isDep) { 6469 continue; 6470 } 6471 } 6472 6473 // Process has passed all conditions, kill it! 6474 if (!doit) { 6475 return true; 6476 } 6477 app.removed = true; 6478 procs.add(app); 6479 } 6480 } 6481 6482 int N = procs.size(); 6483 for (int i=0; i<N; i++) { 6484 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 6485 } 6486 updateOomAdjLocked(); 6487 return N > 0; 6488 } 6489 6490 private void cleanupDisabledPackageComponentsLocked( 6491 String packageName, int userId, boolean killProcess, String[] changedClasses) { 6492 6493 Set<String> disabledClasses = null; 6494 boolean packageDisabled = false; 6495 IPackageManager pm = AppGlobals.getPackageManager(); 6496 6497 if (changedClasses == null) { 6498 // Nothing changed... 6499 return; 6500 } 6501 6502 // Determine enable/disable state of the package and its components. 6503 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 6504 for (int i = changedClasses.length - 1; i >= 0; i--) { 6505 final String changedClass = changedClasses[i]; 6506 6507 if (changedClass.equals(packageName)) { 6508 try { 6509 // Entire package setting changed 6510 enabled = pm.getApplicationEnabledSetting(packageName, 6511 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM); 6512 } catch (Exception e) { 6513 // No such package/component; probably racing with uninstall. In any 6514 // event it means we have nothing further to do here. 6515 return; 6516 } 6517 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED 6518 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 6519 if (packageDisabled) { 6520 // Entire package is disabled. 6521 // No need to continue to check component states. 6522 disabledClasses = null; 6523 break; 6524 } 6525 } else { 6526 try { 6527 enabled = pm.getComponentEnabledSetting( 6528 new ComponentName(packageName, changedClass), 6529 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM); 6530 } catch (Exception e) { 6531 // As above, probably racing with uninstall. 6532 return; 6533 } 6534 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED 6535 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) { 6536 if (disabledClasses == null) { 6537 disabledClasses = new ArraySet<>(changedClasses.length); 6538 } 6539 disabledClasses.add(changedClass); 6540 } 6541 } 6542 } 6543 6544 if (!packageDisabled && disabledClasses == null) { 6545 // Nothing to do here... 6546 return; 6547 } 6548 6549 // Clean-up disabled activities. 6550 if (mStackSupervisor.finishDisabledPackageActivitiesLocked( 6551 packageName, disabledClasses, true, false, userId) && mBooted) { 6552 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 6553 mStackSupervisor.scheduleIdleLocked(); 6554 } 6555 6556 // Clean-up disabled tasks 6557 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId); 6558 6559 // Clean-up disabled services. 6560 mServices.bringDownDisabledPackageServicesLocked( 6561 packageName, disabledClasses, userId, false, killProcess, true); 6562 6563 // Clean-up disabled providers. 6564 ArrayList<ContentProviderRecord> providers = new ArrayList<>(); 6565 mProviderMap.collectPackageProvidersLocked( 6566 packageName, disabledClasses, true, false, userId, providers); 6567 for (int i = providers.size() - 1; i >= 0; i--) { 6568 removeDyingProviderLocked(null, providers.get(i), true); 6569 } 6570 6571 // Clean-up disabled broadcast receivers. 6572 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) { 6573 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked( 6574 packageName, disabledClasses, userId, true); 6575 } 6576 6577 } 6578 6579 final boolean clearBroadcastQueueForUserLocked(int userId) { 6580 boolean didSomething = false; 6581 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) { 6582 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked( 6583 null, null, userId, true); 6584 } 6585 return didSomething; 6586 } 6587 6588 final boolean forceStopPackageLocked(String packageName, int appId, 6589 boolean callerWillRestart, boolean purgeCache, boolean doit, 6590 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 6591 int i; 6592 6593 if (userId == UserHandle.USER_ALL && packageName == null) { 6594 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 6595 } 6596 6597 if (appId < 0 && packageName != null) { 6598 try { 6599 appId = UserHandle.getAppId(AppGlobals.getPackageManager() 6600 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0)); 6601 } catch (RemoteException e) { 6602 } 6603 } 6604 6605 if (doit) { 6606 if (packageName != null) { 6607 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId 6608 + " user=" + userId + ": " + reason); 6609 } else { 6610 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 6611 } 6612 6613 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId); 6614 } 6615 6616 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId, 6617 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent, 6618 packageName == null ? ("stop user " + userId) : ("stop " + packageName)); 6619 6620 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName); 6621 6622 if (mStackSupervisor.finishDisabledPackageActivitiesLocked( 6623 packageName, null, doit, evenPersistent, userId)) { 6624 if (!doit) { 6625 return true; 6626 } 6627 didSomething = true; 6628 } 6629 6630 if (mServices.bringDownDisabledPackageServicesLocked( 6631 packageName, null, userId, evenPersistent, true, doit)) { 6632 if (!doit) { 6633 return true; 6634 } 6635 didSomething = true; 6636 } 6637 6638 if (packageName == null) { 6639 // Remove all sticky broadcasts from this user. 6640 mStickyBroadcasts.remove(userId); 6641 } 6642 6643 ArrayList<ContentProviderRecord> providers = new ArrayList<>(); 6644 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent, 6645 userId, providers)) { 6646 if (!doit) { 6647 return true; 6648 } 6649 didSomething = true; 6650 } 6651 for (i = providers.size() - 1; i >= 0; i--) { 6652 removeDyingProviderLocked(null, providers.get(i), true); 6653 } 6654 6655 // Remove transient permissions granted from/to this package/user 6656 removeUriPermissionsForPackageLocked(packageName, userId, false); 6657 6658 if (doit) { 6659 for (i = mBroadcastQueues.length - 1; i >= 0; i--) { 6660 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked( 6661 packageName, null, userId, doit); 6662 } 6663 } 6664 6665 if (packageName == null || uninstalling) { 6666 // Remove pending intents. For now we only do this when force 6667 // stopping users, because we have some problems when doing this 6668 // for packages -- app widgets are not currently cleaned up for 6669 // such packages, so they can be left with bad pending intents. 6670 if (mIntentSenderRecords.size() > 0) { 6671 Iterator<WeakReference<PendingIntentRecord>> it 6672 = mIntentSenderRecords.values().iterator(); 6673 while (it.hasNext()) { 6674 WeakReference<PendingIntentRecord> wpir = it.next(); 6675 if (wpir == null) { 6676 it.remove(); 6677 continue; 6678 } 6679 PendingIntentRecord pir = wpir.get(); 6680 if (pir == null) { 6681 it.remove(); 6682 continue; 6683 } 6684 if (packageName == null) { 6685 // Stopping user, remove all objects for the user. 6686 if (pir.key.userId != userId) { 6687 // Not the same user, skip it. 6688 continue; 6689 } 6690 } else { 6691 if (UserHandle.getAppId(pir.uid) != appId) { 6692 // Different app id, skip it. 6693 continue; 6694 } 6695 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 6696 // Different user, skip it. 6697 continue; 6698 } 6699 if (!pir.key.packageName.equals(packageName)) { 6700 // Different package, skip it. 6701 continue; 6702 } 6703 } 6704 if (!doit) { 6705 return true; 6706 } 6707 didSomething = true; 6708 it.remove(); 6709 makeIntentSenderCanceledLocked(pir); 6710 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 6711 pir.key.activity.pendingResults.remove(pir.ref); 6712 } 6713 } 6714 } 6715 } 6716 6717 if (doit) { 6718 if (purgeCache && packageName != null) { 6719 AttributeCache ac = AttributeCache.instance(); 6720 if (ac != null) { 6721 ac.removePackage(packageName); 6722 } 6723 } 6724 if (mBooted) { 6725 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 6726 mStackSupervisor.scheduleIdleLocked(); 6727 } 6728 } 6729 6730 return didSomething; 6731 } 6732 6733 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) { 6734 return removeProcessNameLocked(name, uid, null); 6735 } 6736 6737 private final ProcessRecord removeProcessNameLocked(final String name, final int uid, 6738 final ProcessRecord expecting) { 6739 ProcessRecord old = mProcessNames.get(name, uid); 6740 // Only actually remove when the currently recorded value matches the 6741 // record that we expected; if it doesn't match then we raced with a 6742 // newly created process and we don't want to destroy the new one. 6743 if ((expecting == null) || (old == expecting)) { 6744 mProcessNames.remove(name, uid); 6745 } 6746 if (old != null && old.uidRecord != null) { 6747 old.uidRecord.numProcs--; 6748 if (old.uidRecord.numProcs == 0) { 6749 // No more processes using this uid, tell clients it is gone. 6750 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 6751 "No more processes in " + old.uidRecord); 6752 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE); 6753 EventLogTags.writeAmUidStopped(uid); 6754 mActiveUids.remove(uid); 6755 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT); 6756 } 6757 old.uidRecord = null; 6758 } 6759 mIsolatedProcesses.remove(uid); 6760 return old; 6761 } 6762 6763 private final void addProcessNameLocked(ProcessRecord proc) { 6764 // We shouldn't already have a process under this name, but just in case we 6765 // need to clean up whatever may be there now. 6766 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid); 6767 if (old == proc && proc.persistent) { 6768 // We are re-adding a persistent process. Whatevs! Just leave it there. 6769 Slog.w(TAG, "Re-adding persistent process " + proc); 6770 } else if (old != null) { 6771 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc); 6772 } 6773 UidRecord uidRec = mActiveUids.get(proc.uid); 6774 if (uidRec == null) { 6775 uidRec = new UidRecord(proc.uid); 6776 // This is the first appearance of the uid, report it now! 6777 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 6778 "Creating new process uid: " + uidRec); 6779 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0 6780 || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) { 6781 uidRec.setWhitelist = uidRec.curWhitelist = true; 6782 } 6783 uidRec.updateHasInternetPermission(); 6784 mActiveUids.put(proc.uid, uidRec); 6785 EventLogTags.writeAmUidRunning(uidRec.uid); 6786 noteUidProcessState(uidRec.uid, uidRec.curProcState); 6787 } 6788 proc.uidRecord = uidRec; 6789 6790 // Reset render thread tid if it was already set, so new process can set it again. 6791 proc.renderThreadTid = 0; 6792 uidRec.numProcs++; 6793 mProcessNames.put(proc.processName, proc.uid, proc); 6794 if (proc.isolated) { 6795 mIsolatedProcesses.put(proc.uid, proc); 6796 } 6797 } 6798 6799 boolean removeProcessLocked(ProcessRecord app, 6800 boolean callerWillRestart, boolean allowRestart, String reason) { 6801 final String name = app.processName; 6802 final int uid = app.uid; 6803 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES, 6804 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")"); 6805 6806 ProcessRecord old = mProcessNames.get(name, uid); 6807 if (old != app) { 6808 // This process is no longer active, so nothing to do. 6809 Slog.w(TAG, "Ignoring remove of inactive process: " + app); 6810 return false; 6811 } 6812 removeProcessNameLocked(name, uid); 6813 if (mHeavyWeightProcess == app) { 6814 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 6815 mHeavyWeightProcess.userId, 0)); 6816 mHeavyWeightProcess = null; 6817 } 6818 boolean needRestart = false; 6819 if (app.pid > 0 && app.pid != MY_PID) { 6820 int pid = app.pid; 6821 synchronized (mPidsSelfLocked) { 6822 mPidsSelfLocked.remove(pid); 6823 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6824 } 6825 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 6826 boolean willRestart = false; 6827 if (app.persistent && !app.isolated) { 6828 if (!callerWillRestart) { 6829 willRestart = true; 6830 } else { 6831 needRestart = true; 6832 } 6833 } 6834 app.kill(reason, true); 6835 if (app.isolated) { 6836 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 6837 getPackageManagerInternalLocked().removeIsolatedUid(app.uid); 6838 } 6839 handleAppDiedLocked(app, willRestart, allowRestart); 6840 if (willRestart) { 6841 removeLruProcessLocked(app); 6842 addAppLocked(app.info, null, false, null /* ABI override */); 6843 } 6844 } else { 6845 mRemovedProcesses.add(app); 6846 } 6847 6848 return needRestart; 6849 } 6850 6851 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) { 6852 cleanupAppInLaunchingProvidersLocked(app, true); 6853 removeProcessLocked(app, false, true, "timeout publishing content providers"); 6854 } 6855 6856 private final void processStartTimedOutLocked(ProcessRecord app) { 6857 final int pid = app.pid; 6858 boolean gone = false; 6859 synchronized (mPidsSelfLocked) { 6860 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 6861 if (knownApp != null && knownApp.thread == null) { 6862 mPidsSelfLocked.remove(pid); 6863 gone = true; 6864 } 6865 } 6866 6867 if (gone) { 6868 Slog.w(TAG, "Process " + app + " failed to attach"); 6869 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 6870 pid, app.uid, app.processName); 6871 removeProcessNameLocked(app.processName, app.uid); 6872 if (mHeavyWeightProcess == app) { 6873 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 6874 mHeavyWeightProcess.userId, 0)); 6875 mHeavyWeightProcess = null; 6876 } 6877 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 6878 // Take care of any launching providers waiting for this process. 6879 cleanupAppInLaunchingProvidersLocked(app, true); 6880 // Take care of any services that are waiting for the process. 6881 mServices.processStartTimedOutLocked(app); 6882 app.kill("start timeout", true); 6883 if (app.isolated) { 6884 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 6885 } 6886 removeLruProcessLocked(app); 6887 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 6888 Slog.w(TAG, "Unattached app died before backup, skipping"); 6889 mHandler.post(new Runnable() { 6890 @Override 6891 public void run(){ 6892 try { 6893 IBackupManager bm = IBackupManager.Stub.asInterface( 6894 ServiceManager.getService(Context.BACKUP_SERVICE)); 6895 bm.agentDisconnected(app.info.packageName); 6896 } catch (RemoteException e) { 6897 // Can't happen; the backup manager is local 6898 } 6899 } 6900 }); 6901 } 6902 if (isPendingBroadcastProcessLocked(pid)) { 6903 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 6904 skipPendingBroadcastLocked(pid); 6905 } 6906 } else { 6907 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 6908 } 6909 } 6910 6911 private final boolean attachApplicationLocked(IApplicationThread thread, 6912 int pid) { 6913 6914 // Find the application record that is being attached... either via 6915 // the pid if we are running in multiple processes, or just pull the 6916 // next app record if we are emulating process with anonymous threads. 6917 ProcessRecord app; 6918 long startTime = SystemClock.uptimeMillis(); 6919 if (pid != MY_PID && pid >= 0) { 6920 synchronized (mPidsSelfLocked) { 6921 app = mPidsSelfLocked.get(pid); 6922 } 6923 } else { 6924 app = null; 6925 } 6926 6927 if (app == null) { 6928 Slog.w(TAG, "No pending application record for pid " + pid 6929 + " (IApplicationThread " + thread + "); dropping process"); 6930 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 6931 if (pid > 0 && pid != MY_PID) { 6932 killProcessQuiet(pid); 6933 //TODO: killProcessGroup(app.info.uid, pid); 6934 } else { 6935 try { 6936 thread.scheduleExit(); 6937 } catch (Exception e) { 6938 // Ignore exceptions. 6939 } 6940 } 6941 return false; 6942 } 6943 6944 // If this application record is still attached to a previous 6945 // process, clean it up now. 6946 if (app.thread != null) { 6947 handleAppDiedLocked(app, true, true); 6948 } 6949 6950 // Tell the process all about itself. 6951 6952 if (DEBUG_ALL) Slog.v( 6953 TAG, "Binding process pid " + pid + " to record " + app); 6954 6955 final String processName = app.processName; 6956 try { 6957 AppDeathRecipient adr = new AppDeathRecipient( 6958 app, pid, thread); 6959 thread.asBinder().linkToDeath(adr, 0); 6960 app.deathRecipient = adr; 6961 } catch (RemoteException e) { 6962 app.resetPackageList(mProcessStats); 6963 startProcessLocked(app, "link fail", processName); 6964 return false; 6965 } 6966 6967 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6968 6969 app.makeActive(thread, mProcessStats); 6970 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ; 6971 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT; 6972 app.forcingToImportant = null; 6973 updateProcessForegroundLocked(app, false, false); 6974 app.hasShownUi = false; 6975 app.debugging = false; 6976 app.cached = false; 6977 app.killedByAm = false; 6978 app.killed = false; 6979 6980 6981 // We carefully use the same state that PackageManager uses for 6982 // filtering, since we use this flag to decide if we need to install 6983 // providers when user is unlocked later 6984 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId); 6985 6986 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6987 6988 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6989 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6990 6991 if (providers != null && checkAppInLaunchingProvidersLocked(app)) { 6992 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG); 6993 msg.obj = app; 6994 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT); 6995 } 6996 6997 checkTime(startTime, "attachApplicationLocked: before bindApplication"); 6998 6999 if (!normalMode) { 7000 Slog.i(TAG, "Launching preboot mode app: " + app); 7001 } 7002 7003 if (DEBUG_ALL) Slog.v( 7004 TAG, "New app record " + app 7005 + " thread=" + thread.asBinder() + " pid=" + pid); 7006 try { 7007 int testMode = ApplicationThreadConstants.DEBUG_OFF; 7008 if (mDebugApp != null && mDebugApp.equals(processName)) { 7009 testMode = mWaitForDebugger 7010 ? ApplicationThreadConstants.DEBUG_WAIT 7011 : ApplicationThreadConstants.DEBUG_ON; 7012 app.debugging = true; 7013 if (mDebugTransient) { 7014 mDebugApp = mOrigDebugApp; 7015 mWaitForDebugger = mOrigWaitForDebugger; 7016 } 7017 } 7018 7019 ProfilerInfo profilerInfo = null; 7020 String agent = null; 7021 if (mProfileApp != null && mProfileApp.equals(processName)) { 7022 mProfileProc = app; 7023 profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ? 7024 new ProfilerInfo(mProfilerInfo) : null; 7025 agent = mProfilerInfo != null ? mProfilerInfo.agent : null; 7026 } else if (app.instr != null && app.instr.mProfileFile != null) { 7027 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false, 7028 null); 7029 } 7030 7031 boolean enableTrackAllocation = false; 7032 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) { 7033 enableTrackAllocation = true; 7034 mTrackAllocationApp = null; 7035 } 7036 7037 // If the app is being launched for restore or full backup, set it up specially 7038 boolean isRestrictedBackupMode = false; 7039 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 7040 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID 7041 && ((mBackupTarget.backupMode == BackupRecord.RESTORE) 7042 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 7043 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL)); 7044 } 7045 7046 if (app.instr != null) { 7047 notifyPackageUse(app.instr.mClass.getPackageName(), 7048 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION); 7049 } 7050 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc " 7051 + processName + " with config " + getGlobalConfiguration()); 7052 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info; 7053 app.compat = compatibilityInfoForPackageLocked(appInfo); 7054 7055 if (profilerInfo != null && profilerInfo.profileFd != null) { 7056 profilerInfo.profileFd = profilerInfo.profileFd.dup(); 7057 } 7058 7059 // We deprecated Build.SERIAL and it is not accessible to 7060 // apps that target the v2 security sandbox. Since access to 7061 // the serial is now behind a permission we push down the value. 7062 String buildSerial = appInfo.targetSandboxVersion < 2 7063 ? sTheRealBuildSerial : Build.UNKNOWN; 7064 7065 // Check if this is a secondary process that should be incorporated into some 7066 // currently active instrumentation. (Note we do this AFTER all of the profiling 7067 // stuff above because profiling can currently happen only in the primary 7068 // instrumentation process.) 7069 if (mActiveInstrumentation.size() > 0 && app.instr == null) { 7070 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) { 7071 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i); 7072 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) { 7073 if (aInstr.mTargetProcesses.length == 0) { 7074 // This is the wildcard mode, where every process brought up for 7075 // the target instrumentation should be included. 7076 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) { 7077 app.instr = aInstr; 7078 aInstr.mRunningProcesses.add(app); 7079 } 7080 } else { 7081 for (String proc : aInstr.mTargetProcesses) { 7082 if (proc.equals(app.processName)) { 7083 app.instr = aInstr; 7084 aInstr.mRunningProcesses.add(app); 7085 break; 7086 } 7087 } 7088 } 7089 } 7090 } 7091 } 7092 7093 // If we were asked to attach an agent on startup, do so now, before we're binding 7094 // application code. 7095 if (agent != null) { 7096 thread.attachAgent(agent); 7097 } 7098 7099 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication"); 7100 mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app); 7101 if (app.instr != null) { 7102 thread.bindApplication(processName, appInfo, providers, 7103 app.instr.mClass, 7104 profilerInfo, app.instr.mArguments, 7105 app.instr.mWatcher, 7106 app.instr.mUiAutomationConnection, testMode, 7107 mBinderTransactionTrackingEnabled, enableTrackAllocation, 7108 isRestrictedBackupMode || !normalMode, app.persistent, 7109 new Configuration(getGlobalConfiguration()), app.compat, 7110 getCommonServicesLocked(app.isolated), 7111 mCoreSettingsObserver.getCoreSettingsLocked(), 7112 buildSerial); 7113 } else { 7114 thread.bindApplication(processName, appInfo, providers, null, profilerInfo, 7115 null, null, null, testMode, 7116 mBinderTransactionTrackingEnabled, enableTrackAllocation, 7117 isRestrictedBackupMode || !normalMode, app.persistent, 7118 new Configuration(getGlobalConfiguration()), app.compat, 7119 getCommonServicesLocked(app.isolated), 7120 mCoreSettingsObserver.getCoreSettingsLocked(), 7121 buildSerial); 7122 } 7123 7124 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication"); 7125 updateLruProcessLocked(app, false, null); 7126 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked"); 7127 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 7128 } catch (Exception e) { 7129 // todo: Yikes! What should we do? For now we will try to 7130 // start another process, but that could easily get us in 7131 // an infinite loop of restarting processes... 7132 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 7133 7134 app.resetPackageList(mProcessStats); 7135 app.unlinkDeathRecipient(); 7136 startProcessLocked(app, "bind fail", processName); 7137 return false; 7138 } 7139 7140 // Remove this record from the list of starting applications. 7141 mPersistentStartingProcesses.remove(app); 7142 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES, 7143 "Attach application locked removing on hold: " + app); 7144 mProcessesOnHold.remove(app); 7145 7146 boolean badApp = false; 7147 boolean didSomething = false; 7148 7149 // See if the top visible activity is waiting to run in this process... 7150 if (normalMode) { 7151 try { 7152 if (mStackSupervisor.attachApplicationLocked(app)) { 7153 didSomething = true; 7154 } 7155 } catch (Exception e) { 7156 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 7157 badApp = true; 7158 } 7159 } 7160 7161 // Find any services that should be running in this process... 7162 if (!badApp) { 7163 try { 7164 didSomething |= mServices.attachApplicationLocked(app, processName); 7165 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked"); 7166 } catch (Exception e) { 7167 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 7168 badApp = true; 7169 } 7170 } 7171 7172 // Check if a next-broadcast receiver is in this process... 7173 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 7174 try { 7175 didSomething |= sendPendingBroadcastsLocked(app); 7176 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked"); 7177 } catch (Exception e) { 7178 // If the app died trying to launch the receiver we declare it 'bad' 7179 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 7180 badApp = true; 7181 } 7182 } 7183 7184 // Check whether the next backup agent is in this process... 7185 if (!badApp && mBackupTarget != null && mBackupTarget.app == app) { 7186 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, 7187 "New app is backup target, launching agent for " + app); 7188 notifyPackageUse(mBackupTarget.appInfo.packageName, 7189 PackageManager.NOTIFY_PACKAGE_USE_BACKUP); 7190 try { 7191 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 7192 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 7193 mBackupTarget.backupMode); 7194 } catch (Exception e) { 7195 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 7196 badApp = true; 7197 } 7198 } 7199 7200 if (badApp) { 7201 app.kill("error during init", true); 7202 handleAppDiedLocked(app, false, true); 7203 return false; 7204 } 7205 7206 if (!didSomething) { 7207 updateOomAdjLocked(); 7208 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked"); 7209 } 7210 7211 return true; 7212 } 7213 7214 @Override 7215 public final void attachApplication(IApplicationThread thread) { 7216 synchronized (this) { 7217 int callingPid = Binder.getCallingPid(); 7218 final long origId = Binder.clearCallingIdentity(); 7219 attachApplicationLocked(thread, callingPid); 7220 Binder.restoreCallingIdentity(origId); 7221 } 7222 } 7223 7224 @Override 7225 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 7226 final long origId = Binder.clearCallingIdentity(); 7227 synchronized (this) { 7228 ActivityStack stack = ActivityRecord.getStackLocked(token); 7229 if (stack != null) { 7230 ActivityRecord r = 7231 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */, 7232 false /* processPausingActivities */, config); 7233 if (stopProfiling) { 7234 if ((mProfileProc == r.app) && mProfilerInfo != null) { 7235 clearProfilerLocked(); 7236 } 7237 } 7238 } 7239 } 7240 Binder.restoreCallingIdentity(origId); 7241 } 7242 7243 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 7244 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 7245 finishBooting ? 1 : 0, enableScreen ? 1 : 0)); 7246 } 7247 7248 void enableScreenAfterBoot() { 7249 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 7250 SystemClock.uptimeMillis()); 7251 mWindowManager.enableScreenAfterBoot(); 7252 7253 synchronized (this) { 7254 updateEventDispatchingLocked(); 7255 } 7256 } 7257 7258 @Override 7259 public void showBootMessage(final CharSequence msg, final boolean always) { 7260 if (Binder.getCallingUid() != myUid()) { 7261 throw new SecurityException(); 7262 } 7263 mWindowManager.showBootMessage(msg, always); 7264 } 7265 7266 @Override 7267 public void keyguardGoingAway(int flags) { 7268 enforceNotIsolatedCaller("keyguardGoingAway"); 7269 final long token = Binder.clearCallingIdentity(); 7270 try { 7271 synchronized (this) { 7272 mKeyguardController.keyguardGoingAway(flags); 7273 } 7274 } finally { 7275 Binder.restoreCallingIdentity(token); 7276 } 7277 } 7278 7279 /** 7280 * @return whther the keyguard is currently locked. 7281 */ 7282 boolean isKeyguardLocked() { 7283 return mKeyguardController.isKeyguardLocked(); 7284 } 7285 7286 final void finishBooting() { 7287 synchronized (this) { 7288 if (!mBootAnimationComplete) { 7289 mCallFinishBooting = true; 7290 return; 7291 } 7292 mCallFinishBooting = false; 7293 } 7294 7295 ArraySet<String> completedIsas = new ArraySet<String>(); 7296 for (String abi : Build.SUPPORTED_ABIS) { 7297 zygoteProcess.establishZygoteConnectionForAbi(abi); 7298 final String instructionSet = VMRuntime.getInstructionSet(abi); 7299 if (!completedIsas.contains(instructionSet)) { 7300 try { 7301 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)); 7302 } catch (InstallerException e) { 7303 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" + 7304 e.getMessage() +")"); 7305 } 7306 completedIsas.add(instructionSet); 7307 } 7308 } 7309 7310 IntentFilter pkgFilter = new IntentFilter(); 7311 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 7312 pkgFilter.addDataScheme("package"); 7313 mContext.registerReceiver(new BroadcastReceiver() { 7314 @Override 7315 public void onReceive(Context context, Intent intent) { 7316 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 7317 if (pkgs != null) { 7318 for (String pkg : pkgs) { 7319 synchronized (ActivityManagerService.this) { 7320 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 7321 0, "query restart")) { 7322 setResultCode(Activity.RESULT_OK); 7323 return; 7324 } 7325 } 7326 } 7327 } 7328 } 7329 }, pkgFilter); 7330 7331 IntentFilter dumpheapFilter = new IntentFilter(); 7332 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP); 7333 mContext.registerReceiver(new BroadcastReceiver() { 7334 @Override 7335 public void onReceive(Context context, Intent intent) { 7336 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) { 7337 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000); 7338 } else { 7339 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG); 7340 } 7341 } 7342 }, dumpheapFilter); 7343 7344 // Let system services know. 7345 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 7346 7347 synchronized (this) { 7348 // Ensure that any processes we had put on hold are now started 7349 // up. 7350 final int NP = mProcessesOnHold.size(); 7351 if (NP > 0) { 7352 ArrayList<ProcessRecord> procs = 7353 new ArrayList<ProcessRecord>(mProcessesOnHold); 7354 for (int ip=0; ip<NP; ip++) { 7355 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: " 7356 + procs.get(ip)); 7357 startProcessLocked(procs.get(ip), "on-hold", null); 7358 } 7359 } 7360 7361 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 7362 // Start looking for apps that are abusing wake locks. 7363 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG); 7364 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL); 7365 // Tell anyone interested that we are done booting! 7366 SystemProperties.set("sys.boot_completed", "1"); 7367 7368 // And trigger dev.bootcomplete if we are not showing encryption progress 7369 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 7370 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 7371 SystemProperties.set("dev.bootcomplete", "1"); 7372 } 7373 mUserController.sendBootCompletedLocked( 7374 new IIntentReceiver.Stub() { 7375 @Override 7376 public void performReceive(Intent intent, int resultCode, 7377 String data, Bundle extras, boolean ordered, 7378 boolean sticky, int sendingUser) { 7379 synchronized (ActivityManagerService.this) { 7380 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 7381 true, false); 7382 } 7383 } 7384 }); 7385 scheduleStartProfilesLocked(); 7386 } 7387 } 7388 } 7389 7390 @Override 7391 public void bootAnimationComplete() { 7392 final boolean callFinishBooting; 7393 synchronized (this) { 7394 callFinishBooting = mCallFinishBooting; 7395 mBootAnimationComplete = true; 7396 } 7397 if (callFinishBooting) { 7398 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting"); 7399 finishBooting(); 7400 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 7401 } 7402 } 7403 7404 final void ensureBootCompleted() { 7405 boolean booting; 7406 boolean enableScreen; 7407 synchronized (this) { 7408 booting = mBooting; 7409 mBooting = false; 7410 enableScreen = !mBooted; 7411 mBooted = true; 7412 } 7413 7414 if (booting) { 7415 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting"); 7416 finishBooting(); 7417 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 7418 } 7419 7420 if (enableScreen) { 7421 enableScreenAfterBoot(); 7422 } 7423 } 7424 7425 @Override 7426 public final void activityResumed(IBinder token) { 7427 final long origId = Binder.clearCallingIdentity(); 7428 synchronized(this) { 7429 ActivityRecord.activityResumedLocked(token); 7430 mWindowManager.notifyAppResumedFinished(token); 7431 } 7432 Binder.restoreCallingIdentity(origId); 7433 } 7434 7435 @Override 7436 public final void activityPaused(IBinder token) { 7437 final long origId = Binder.clearCallingIdentity(); 7438 synchronized(this) { 7439 ActivityStack stack = ActivityRecord.getStackLocked(token); 7440 if (stack != null) { 7441 stack.activityPausedLocked(token, false); 7442 } 7443 } 7444 Binder.restoreCallingIdentity(origId); 7445 } 7446 7447 @Override 7448 public final void activityStopped(IBinder token, Bundle icicle, 7449 PersistableBundle persistentState, CharSequence description) { 7450 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token); 7451 7452 // Refuse possible leaked file descriptors 7453 if (icicle != null && icicle.hasFileDescriptors()) { 7454 throw new IllegalArgumentException("File descriptors passed in Bundle"); 7455 } 7456 7457 final long origId = Binder.clearCallingIdentity(); 7458 7459 synchronized (this) { 7460 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 7461 if (r != null) { 7462 r.activityStoppedLocked(icicle, persistentState, description); 7463 } 7464 } 7465 7466 trimApplications(); 7467 7468 Binder.restoreCallingIdentity(origId); 7469 } 7470 7471 @Override 7472 public final void activityDestroyed(IBinder token) { 7473 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token); 7474 synchronized (this) { 7475 ActivityStack stack = ActivityRecord.getStackLocked(token); 7476 if (stack != null) { 7477 stack.activityDestroyedLocked(token, "activityDestroyed"); 7478 } 7479 } 7480 } 7481 7482 @Override 7483 public final void activityRelaunched(IBinder token) { 7484 final long origId = Binder.clearCallingIdentity(); 7485 synchronized (this) { 7486 mStackSupervisor.activityRelaunchedLocked(token); 7487 } 7488 Binder.restoreCallingIdentity(origId); 7489 } 7490 7491 @Override 7492 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration, 7493 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) { 7494 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " " 7495 + horizontalSizeConfiguration + " " + verticalSizeConfigurations); 7496 synchronized (this) { 7497 ActivityRecord record = ActivityRecord.isInStackLocked(token); 7498 if (record == null) { 7499 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not " 7500 + "found for: " + token); 7501 } 7502 record.setSizeConfigurations(horizontalSizeConfiguration, 7503 verticalSizeConfigurations, smallestSizeConfigurations); 7504 } 7505 } 7506 7507 @Override 7508 public final void notifyLaunchTaskBehindComplete(IBinder token) { 7509 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 7510 } 7511 7512 @Override 7513 public final void notifyEnterAnimationComplete(IBinder token) { 7514 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 7515 } 7516 7517 @Override 7518 public String getCallingPackage(IBinder token) { 7519 synchronized (this) { 7520 ActivityRecord r = getCallingRecordLocked(token); 7521 return r != null ? r.info.packageName : null; 7522 } 7523 } 7524 7525 @Override 7526 public ComponentName getCallingActivity(IBinder token) { 7527 synchronized (this) { 7528 ActivityRecord r = getCallingRecordLocked(token); 7529 return r != null ? r.intent.getComponent() : null; 7530 } 7531 } 7532 7533 private ActivityRecord getCallingRecordLocked(IBinder token) { 7534 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7535 if (r == null) { 7536 return null; 7537 } 7538 return r.resultTo; 7539 } 7540 7541 @Override 7542 public ComponentName getActivityClassForToken(IBinder token) { 7543 synchronized(this) { 7544 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7545 if (r == null) { 7546 return null; 7547 } 7548 return r.intent.getComponent(); 7549 } 7550 } 7551 7552 @Override 7553 public String getPackageForToken(IBinder token) { 7554 synchronized(this) { 7555 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7556 if (r == null) { 7557 return null; 7558 } 7559 return r.packageName; 7560 } 7561 } 7562 7563 @Override 7564 public boolean isRootVoiceInteraction(IBinder token) { 7565 synchronized(this) { 7566 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7567 if (r == null) { 7568 return false; 7569 } 7570 return r.rootVoiceInteraction; 7571 } 7572 } 7573 7574 @Override 7575 public IIntentSender getIntentSender(int type, 7576 String packageName, IBinder token, String resultWho, 7577 int requestCode, Intent[] intents, String[] resolvedTypes, 7578 int flags, Bundle bOptions, int userId) { 7579 enforceNotIsolatedCaller("getIntentSender"); 7580 // Refuse possible leaked file descriptors 7581 if (intents != null) { 7582 if (intents.length < 1) { 7583 throw new IllegalArgumentException("Intents array length must be >= 1"); 7584 } 7585 for (int i=0; i<intents.length; i++) { 7586 Intent intent = intents[i]; 7587 if (intent != null) { 7588 if (intent.hasFileDescriptors()) { 7589 throw new IllegalArgumentException("File descriptors passed in Intent"); 7590 } 7591 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 7592 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 7593 throw new IllegalArgumentException( 7594 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 7595 } 7596 intents[i] = new Intent(intent); 7597 } 7598 } 7599 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 7600 throw new IllegalArgumentException( 7601 "Intent array length does not match resolvedTypes length"); 7602 } 7603 } 7604 if (bOptions != null) { 7605 if (bOptions.hasFileDescriptors()) { 7606 throw new IllegalArgumentException("File descriptors passed in options"); 7607 } 7608 } 7609 7610 synchronized(this) { 7611 int callingUid = Binder.getCallingUid(); 7612 int origUserId = userId; 7613 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7614 type == ActivityManager.INTENT_SENDER_BROADCAST, 7615 ALLOW_NON_FULL, "getIntentSender", null); 7616 if (origUserId == UserHandle.USER_CURRENT) { 7617 // We don't want to evaluate this until the pending intent is 7618 // actually executed. However, we do want to always do the 7619 // security checking for it above. 7620 userId = UserHandle.USER_CURRENT; 7621 } 7622 try { 7623 if (callingUid != 0 && callingUid != SYSTEM_UID) { 7624 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName, 7625 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid)); 7626 if (!UserHandle.isSameApp(callingUid, uid)) { 7627 String msg = "Permission Denial: getIntentSender() from pid=" 7628 + Binder.getCallingPid() 7629 + ", uid=" + Binder.getCallingUid() 7630 + ", (need uid=" + uid + ")" 7631 + " is not allowed to send as package " + packageName; 7632 Slog.w(TAG, msg); 7633 throw new SecurityException(msg); 7634 } 7635 } 7636 7637 return getIntentSenderLocked(type, packageName, callingUid, userId, 7638 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions); 7639 7640 } catch (RemoteException e) { 7641 throw new SecurityException(e); 7642 } 7643 } 7644 } 7645 7646 IIntentSender getIntentSenderLocked(int type, String packageName, 7647 int callingUid, int userId, IBinder token, String resultWho, 7648 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 7649 Bundle bOptions) { 7650 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 7651 ActivityRecord activity = null; 7652 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 7653 activity = ActivityRecord.isInStackLocked(token); 7654 if (activity == null) { 7655 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack"); 7656 return null; 7657 } 7658 if (activity.finishing) { 7659 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing"); 7660 return null; 7661 } 7662 } 7663 7664 // We're going to be splicing together extras before sending, so we're 7665 // okay poking into any contained extras. 7666 if (intents != null) { 7667 for (int i = 0; i < intents.length; i++) { 7668 intents[i].setDefusable(true); 7669 } 7670 } 7671 Bundle.setDefusable(bOptions, true); 7672 7673 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 7674 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 7675 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 7676 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 7677 |PendingIntent.FLAG_UPDATE_CURRENT); 7678 7679 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 7680 type, packageName, activity, resultWho, 7681 requestCode, intents, resolvedTypes, flags, bOptions, userId); 7682 WeakReference<PendingIntentRecord> ref; 7683 ref = mIntentSenderRecords.get(key); 7684 PendingIntentRecord rec = ref != null ? ref.get() : null; 7685 if (rec != null) { 7686 if (!cancelCurrent) { 7687 if (updateCurrent) { 7688 if (rec.key.requestIntent != null) { 7689 rec.key.requestIntent.replaceExtras(intents != null ? 7690 intents[intents.length - 1] : null); 7691 } 7692 if (intents != null) { 7693 intents[intents.length-1] = rec.key.requestIntent; 7694 rec.key.allIntents = intents; 7695 rec.key.allResolvedTypes = resolvedTypes; 7696 } else { 7697 rec.key.allIntents = null; 7698 rec.key.allResolvedTypes = null; 7699 } 7700 } 7701 return rec; 7702 } 7703 makeIntentSenderCanceledLocked(rec); 7704 mIntentSenderRecords.remove(key); 7705 } 7706 if (noCreate) { 7707 return rec; 7708 } 7709 rec = new PendingIntentRecord(this, key, callingUid); 7710 mIntentSenderRecords.put(key, rec.ref); 7711 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 7712 if (activity.pendingResults == null) { 7713 activity.pendingResults 7714 = new HashSet<WeakReference<PendingIntentRecord>>(); 7715 } 7716 activity.pendingResults.add(rec.ref); 7717 } 7718 return rec; 7719 } 7720 7721 @Override 7722 public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code, 7723 Intent intent, String resolvedType, 7724 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 7725 if (target instanceof PendingIntentRecord) { 7726 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType, 7727 whitelistToken, finishedReceiver, requiredPermission, options); 7728 } else { 7729 if (intent == null) { 7730 // Weird case: someone has given us their own custom IIntentSender, and now 7731 // they have someone else trying to send to it but of course this isn't 7732 // really a PendingIntent, so there is no base Intent, and the caller isn't 7733 // supplying an Intent... but we never want to dispatch a null Intent to 7734 // a receiver, so um... let's make something up. 7735 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call"); 7736 intent = new Intent(Intent.ACTION_MAIN); 7737 } 7738 try { 7739 target.send(code, intent, resolvedType, whitelistToken, null, 7740 requiredPermission, options); 7741 } catch (RemoteException e) { 7742 } 7743 // Platform code can rely on getting a result back when the send is done, but if 7744 // this intent sender is from outside of the system we can't rely on it doing that. 7745 // So instead we don't give it the result receiver, and instead just directly 7746 // report the finish immediately. 7747 if (finishedReceiver != null) { 7748 try { 7749 finishedReceiver.performReceive(intent, 0, 7750 null, null, false, false, UserHandle.getCallingUserId()); 7751 } catch (RemoteException e) { 7752 } 7753 } 7754 return 0; 7755 } 7756 } 7757 7758 @Override 7759 public void cancelIntentSender(IIntentSender sender) { 7760 if (!(sender instanceof PendingIntentRecord)) { 7761 return; 7762 } 7763 synchronized(this) { 7764 PendingIntentRecord rec = (PendingIntentRecord)sender; 7765 try { 7766 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName, 7767 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId()); 7768 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 7769 String msg = "Permission Denial: cancelIntentSender() from pid=" 7770 + Binder.getCallingPid() 7771 + ", uid=" + Binder.getCallingUid() 7772 + " is not allowed to cancel package " 7773 + rec.key.packageName; 7774 Slog.w(TAG, msg); 7775 throw new SecurityException(msg); 7776 } 7777 } catch (RemoteException e) { 7778 throw new SecurityException(e); 7779 } 7780 cancelIntentSenderLocked(rec, true); 7781 } 7782 } 7783 7784 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 7785 makeIntentSenderCanceledLocked(rec); 7786 mIntentSenderRecords.remove(rec.key); 7787 if (cleanActivity && rec.key.activity != null) { 7788 rec.key.activity.pendingResults.remove(rec.ref); 7789 } 7790 } 7791 7792 void makeIntentSenderCanceledLocked(PendingIntentRecord rec) { 7793 rec.canceled = true; 7794 RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked(); 7795 if (callbacks != null) { 7796 mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget(); 7797 } 7798 } 7799 7800 @Override 7801 public String getPackageForIntentSender(IIntentSender pendingResult) { 7802 if (!(pendingResult instanceof PendingIntentRecord)) { 7803 return null; 7804 } 7805 try { 7806 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7807 return res.key.packageName; 7808 } catch (ClassCastException e) { 7809 } 7810 return null; 7811 } 7812 7813 @Override 7814 public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) { 7815 if (!(sender instanceof PendingIntentRecord)) { 7816 return; 7817 } 7818 synchronized(this) { 7819 ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver); 7820 } 7821 } 7822 7823 @Override 7824 public void unregisterIntentSenderCancelListener(IIntentSender sender, 7825 IResultReceiver receiver) { 7826 if (!(sender instanceof PendingIntentRecord)) { 7827 return; 7828 } 7829 synchronized(this) { 7830 ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver); 7831 } 7832 } 7833 7834 @Override 7835 public int getUidForIntentSender(IIntentSender sender) { 7836 if (sender instanceof PendingIntentRecord) { 7837 try { 7838 PendingIntentRecord res = (PendingIntentRecord)sender; 7839 return res.uid; 7840 } catch (ClassCastException e) { 7841 } 7842 } 7843 return -1; 7844 } 7845 7846 @Override 7847 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 7848 if (!(pendingResult instanceof PendingIntentRecord)) { 7849 return false; 7850 } 7851 try { 7852 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7853 if (res.key.allIntents == null) { 7854 return false; 7855 } 7856 for (int i=0; i<res.key.allIntents.length; i++) { 7857 Intent intent = res.key.allIntents[i]; 7858 if (intent.getPackage() != null && intent.getComponent() != null) { 7859 return false; 7860 } 7861 } 7862 return true; 7863 } catch (ClassCastException e) { 7864 } 7865 return false; 7866 } 7867 7868 @Override 7869 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 7870 if (!(pendingResult instanceof PendingIntentRecord)) { 7871 return false; 7872 } 7873 try { 7874 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7875 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 7876 return true; 7877 } 7878 return false; 7879 } catch (ClassCastException e) { 7880 } 7881 return false; 7882 } 7883 7884 @Override 7885 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 7886 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT, 7887 "getIntentForIntentSender()"); 7888 if (!(pendingResult instanceof PendingIntentRecord)) { 7889 return null; 7890 } 7891 try { 7892 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7893 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 7894 } catch (ClassCastException e) { 7895 } 7896 return null; 7897 } 7898 7899 @Override 7900 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 7901 if (!(pendingResult instanceof PendingIntentRecord)) { 7902 return null; 7903 } 7904 try { 7905 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7906 synchronized (this) { 7907 return getTagForIntentSenderLocked(res, prefix); 7908 } 7909 } catch (ClassCastException e) { 7910 } 7911 return null; 7912 } 7913 7914 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) { 7915 final Intent intent = res.key.requestIntent; 7916 if (intent != null) { 7917 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 7918 || res.lastTagPrefix.equals(prefix))) { 7919 return res.lastTag; 7920 } 7921 res.lastTagPrefix = prefix; 7922 final StringBuilder sb = new StringBuilder(128); 7923 if (prefix != null) { 7924 sb.append(prefix); 7925 } 7926 if (intent.getAction() != null) { 7927 sb.append(intent.getAction()); 7928 } else if (intent.getComponent() != null) { 7929 intent.getComponent().appendShortString(sb); 7930 } else { 7931 sb.append("?"); 7932 } 7933 return res.lastTag = sb.toString(); 7934 } 7935 return null; 7936 } 7937 7938 @Override 7939 public void setProcessLimit(int max) { 7940 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 7941 "setProcessLimit()"); 7942 synchronized (this) { 7943 mConstants.setOverrideMaxCachedProcesses(max); 7944 } 7945 trimApplications(); 7946 } 7947 7948 @Override 7949 public int getProcessLimit() { 7950 synchronized (this) { 7951 return mConstants.getOverrideMaxCachedProcesses(); 7952 } 7953 } 7954 7955 void importanceTokenDied(ImportanceToken token) { 7956 synchronized (ActivityManagerService.this) { 7957 synchronized (mPidsSelfLocked) { 7958 ImportanceToken cur 7959 = mImportantProcesses.get(token.pid); 7960 if (cur != token) { 7961 return; 7962 } 7963 mImportantProcesses.remove(token.pid); 7964 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 7965 if (pr == null) { 7966 return; 7967 } 7968 pr.forcingToImportant = null; 7969 updateProcessForegroundLocked(pr, false, false); 7970 } 7971 updateOomAdjLocked(); 7972 } 7973 } 7974 7975 @Override 7976 public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) { 7977 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 7978 "setProcessImportant()"); 7979 synchronized(this) { 7980 boolean changed = false; 7981 7982 synchronized (mPidsSelfLocked) { 7983 ProcessRecord pr = mPidsSelfLocked.get(pid); 7984 if (pr == null && isForeground) { 7985 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 7986 return; 7987 } 7988 ImportanceToken oldToken = mImportantProcesses.get(pid); 7989 if (oldToken != null) { 7990 oldToken.token.unlinkToDeath(oldToken, 0); 7991 mImportantProcesses.remove(pid); 7992 if (pr != null) { 7993 pr.forcingToImportant = null; 7994 } 7995 changed = true; 7996 } 7997 if (isForeground && token != null) { 7998 ImportanceToken newToken = new ImportanceToken(pid, token, reason) { 7999 @Override 8000 public void binderDied() { 8001 importanceTokenDied(this); 8002 } 8003 }; 8004 try { 8005 token.linkToDeath(newToken, 0); 8006 mImportantProcesses.put(pid, newToken); 8007 pr.forcingToImportant = newToken; 8008 changed = true; 8009 } catch (RemoteException e) { 8010 // If the process died while doing this, we will later 8011 // do the cleanup with the process death link. 8012 } 8013 } 8014 } 8015 8016 if (changed) { 8017 updateOomAdjLocked(); 8018 } 8019 } 8020 } 8021 8022 @Override 8023 public boolean isAppForeground(int uid) throws RemoteException { 8024 synchronized (this) { 8025 UidRecord uidRec = mActiveUids.get(uid); 8026 if (uidRec == null || uidRec.idle) { 8027 return false; 8028 } 8029 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 8030 } 8031 } 8032 8033 // NOTE: this is an internal method used by the OnShellCommand implementation only and should 8034 // be guarded by permission checking. 8035 int getUidState(int uid) { 8036 synchronized (this) { 8037 return getUidStateLocked(uid); 8038 } 8039 } 8040 8041 int getUidStateLocked(int uid) { 8042 UidRecord uidRec = mActiveUids.get(uid); 8043 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState; 8044 } 8045 8046 @Override 8047 public boolean isInMultiWindowMode(IBinder token) { 8048 final long origId = Binder.clearCallingIdentity(); 8049 try { 8050 synchronized(this) { 8051 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8052 if (r == null) { 8053 return false; 8054 } 8055 // An activity is consider to be in multi-window mode if its task isn't fullscreen. 8056 return !r.getTask().mFullscreen; 8057 } 8058 } finally { 8059 Binder.restoreCallingIdentity(origId); 8060 } 8061 } 8062 8063 @Override 8064 public boolean isInPictureInPictureMode(IBinder token) { 8065 final long origId = Binder.clearCallingIdentity(); 8066 try { 8067 synchronized(this) { 8068 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token)); 8069 } 8070 } finally { 8071 Binder.restoreCallingIdentity(origId); 8072 } 8073 } 8074 8075 private boolean isInPictureInPictureMode(ActivityRecord r) { 8076 if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() || 8077 r.getStack().isInStackLocked(r) == null) { 8078 return false; 8079 } 8080 8081 // If we are animating to fullscreen then we have already dispatched the PIP mode 8082 // changed, so we should reflect that check here as well. 8083 final PinnedActivityStack stack = r.getStack(); 8084 final PinnedStackWindowController windowController = stack.getWindowContainerController(); 8085 return !windowController.isAnimatingBoundsToFullscreen(); 8086 } 8087 8088 @Override 8089 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) { 8090 final long origId = Binder.clearCallingIdentity(); 8091 try { 8092 synchronized(this) { 8093 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked( 8094 "enterPictureInPictureMode", token, params); 8095 8096 // If the activity is already in picture in picture mode, then just return early 8097 if (isInPictureInPictureMode(r)) { 8098 return true; 8099 } 8100 8101 // Activity supports picture-in-picture, now check that we can enter PiP at this 8102 // point, if it is 8103 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode", 8104 false /* beforeStopping */)) { 8105 return false; 8106 } 8107 8108 final Runnable enterPipRunnable = () -> { 8109 // Only update the saved args from the args that are set 8110 r.pictureInPictureArgs.copyOnlySet(params); 8111 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio(); 8112 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions(); 8113 // Adjust the source bounds by the insets for the transition down 8114 final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint()); 8115 mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio, 8116 true /* moveHomeStackToFront */, "enterPictureInPictureMode"); 8117 final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID); 8118 stack.setPictureInPictureAspectRatio(aspectRatio); 8119 stack.setPictureInPictureActions(actions); 8120 8121 MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED, 8122 r.supportsEnterPipOnTaskSwitch); 8123 logPictureInPictureArgs(params); 8124 }; 8125 8126 if (isKeyguardLocked()) { 8127 // If the keyguard is showing or occluded, then try and dismiss it before 8128 // entering picture-in-picture (this will prompt the user to authenticate if the 8129 // device is currently locked). 8130 try { 8131 dismissKeyguard(token, new IKeyguardDismissCallback.Stub() { 8132 @Override 8133 public void onDismissError() throws RemoteException { 8134 // Do nothing 8135 } 8136 8137 @Override 8138 public void onDismissSucceeded() throws RemoteException { 8139 mHandler.post(enterPipRunnable); 8140 } 8141 8142 @Override 8143 public void onDismissCancelled() throws RemoteException { 8144 // Do nothing 8145 } 8146 }); 8147 } catch (RemoteException e) { 8148 // Local call 8149 } 8150 } else { 8151 // Enter picture in picture immediately otherwise 8152 enterPipRunnable.run(); 8153 } 8154 return true; 8155 } 8156 } finally { 8157 Binder.restoreCallingIdentity(origId); 8158 } 8159 } 8160 8161 @Override 8162 public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) { 8163 final long origId = Binder.clearCallingIdentity(); 8164 try { 8165 synchronized(this) { 8166 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked( 8167 "setPictureInPictureParams", token, params); 8168 8169 // Only update the saved args from the args that are set 8170 r.pictureInPictureArgs.copyOnlySet(params); 8171 if (r.getStack().getStackId() == PINNED_STACK_ID) { 8172 // If the activity is already in picture-in-picture, update the pinned stack now 8173 // if it is not already expanding to fullscreen. Otherwise, the arguments will 8174 // be used the next time the activity enters PiP 8175 final PinnedActivityStack stack = r.getStack(); 8176 if (!stack.isAnimatingBoundsToFullscreen()) { 8177 stack.setPictureInPictureAspectRatio( 8178 r.pictureInPictureArgs.getAspectRatio()); 8179 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions()); 8180 } 8181 } 8182 logPictureInPictureArgs(params); 8183 } 8184 } finally { 8185 Binder.restoreCallingIdentity(origId); 8186 } 8187 } 8188 8189 @Override 8190 public int getMaxNumPictureInPictureActions(IBinder token) { 8191 // Currently, this is a static constant, but later, we may change this to be dependent on 8192 // the context of the activity 8193 return 3; 8194 } 8195 8196 private void logPictureInPictureArgs(PictureInPictureParams params) { 8197 if (params.hasSetActions()) { 8198 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count", 8199 params.getActions().size()); 8200 } 8201 if (params.hasSetAspectRatio()) { 8202 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED); 8203 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio()); 8204 MetricsLogger.action(lm); 8205 } 8206 } 8207 8208 /** 8209 * Checks the state of the system and the activity associated with the given {@param token} to 8210 * verify that picture-in-picture is supported for that activity. 8211 * 8212 * @return the activity record for the given {@param token} if all the checks pass. 8213 */ 8214 private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller, 8215 IBinder token, PictureInPictureParams params) { 8216 if (!mSupportsPictureInPicture) { 8217 throw new IllegalStateException(caller 8218 + ": Device doesn't support picture-in-picture mode."); 8219 } 8220 8221 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 8222 if (r == null) { 8223 throw new IllegalStateException(caller 8224 + ": Can't find activity for token=" + token); 8225 } 8226 8227 if (!r.supportsPictureInPicture()) { 8228 throw new IllegalStateException(caller 8229 + ": Current activity does not support picture-in-picture."); 8230 } 8231 8232 if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) { 8233 throw new IllegalStateException(caller 8234 + ": Activities on the home, assistant, or recents stack not supported"); 8235 } 8236 8237 if (params.hasSetAspectRatio() 8238 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId, 8239 params.getAspectRatio())) { 8240 final float minAspectRatio = mContext.getResources().getFloat( 8241 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio); 8242 final float maxAspectRatio = mContext.getResources().getFloat( 8243 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio); 8244 throw new IllegalArgumentException(String.format(caller 8245 + ": Aspect ratio is too extreme (must be between %f and %f).", 8246 minAspectRatio, maxAspectRatio)); 8247 } 8248 8249 // Truncate the number of actions if necessary 8250 params.truncateActions(getMaxNumPictureInPictureActions(token)); 8251 8252 return r; 8253 } 8254 8255 // ========================================================= 8256 // PROCESS INFO 8257 // ========================================================= 8258 8259 static class ProcessInfoService extends IProcessInfoService.Stub { 8260 final ActivityManagerService mActivityManagerService; 8261 ProcessInfoService(ActivityManagerService activityManagerService) { 8262 mActivityManagerService = activityManagerService; 8263 } 8264 8265 @Override 8266 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) { 8267 mActivityManagerService.getProcessStatesAndOomScoresForPIDs( 8268 /*in*/ pids, /*out*/ states, null); 8269 } 8270 8271 @Override 8272 public void getProcessStatesAndOomScoresFromPids( 8273 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) { 8274 mActivityManagerService.getProcessStatesAndOomScoresForPIDs( 8275 /*in*/ pids, /*out*/ states, /*out*/ scores); 8276 } 8277 } 8278 8279 /** 8280 * For each PID in the given input array, write the current process state 8281 * for that process into the states array, or -1 to indicate that no 8282 * process with the given PID exists. If scores array is provided, write 8283 * the oom score for the process into the scores array, with INVALID_ADJ 8284 * indicating the PID doesn't exist. 8285 */ 8286 public void getProcessStatesAndOomScoresForPIDs( 8287 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) { 8288 if (scores != null) { 8289 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE, 8290 "getProcessStatesAndOomScoresForPIDs()"); 8291 } 8292 8293 if (pids == null) { 8294 throw new NullPointerException("pids"); 8295 } else if (states == null) { 8296 throw new NullPointerException("states"); 8297 } else if (pids.length != states.length) { 8298 throw new IllegalArgumentException("pids and states arrays have different lengths!"); 8299 } else if (scores != null && pids.length != scores.length) { 8300 throw new IllegalArgumentException("pids and scores arrays have different lengths!"); 8301 } 8302 8303 synchronized (mPidsSelfLocked) { 8304 for (int i = 0; i < pids.length; i++) { 8305 ProcessRecord pr = mPidsSelfLocked.get(pids[i]); 8306 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT : 8307 pr.curProcState; 8308 if (scores != null) { 8309 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj; 8310 } 8311 } 8312 } 8313 } 8314 8315 // ========================================================= 8316 // PERMISSIONS 8317 // ========================================================= 8318 8319 static class PermissionController extends IPermissionController.Stub { 8320 ActivityManagerService mActivityManagerService; 8321 PermissionController(ActivityManagerService activityManagerService) { 8322 mActivityManagerService = activityManagerService; 8323 } 8324 8325 @Override 8326 public boolean checkPermission(String permission, int pid, int uid) { 8327 return mActivityManagerService.checkPermission(permission, pid, 8328 uid) == PackageManager.PERMISSION_GRANTED; 8329 } 8330 8331 @Override 8332 public String[] getPackagesForUid(int uid) { 8333 return mActivityManagerService.mContext.getPackageManager() 8334 .getPackagesForUid(uid); 8335 } 8336 8337 @Override 8338 public boolean isRuntimePermission(String permission) { 8339 try { 8340 PermissionInfo info = mActivityManagerService.mContext.getPackageManager() 8341 .getPermissionInfo(permission, 0); 8342 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) 8343 == PermissionInfo.PROTECTION_DANGEROUS; 8344 } catch (NameNotFoundException nnfe) { 8345 Slog.e(TAG, "No such permission: "+ permission, nnfe); 8346 } 8347 return false; 8348 } 8349 } 8350 8351 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 8352 @Override 8353 public int checkComponentPermission(String permission, int pid, int uid, 8354 int owningUid, boolean exported) { 8355 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 8356 owningUid, exported); 8357 } 8358 8359 @Override 8360 public Object getAMSLock() { 8361 return ActivityManagerService.this; 8362 } 8363 } 8364 8365 /** 8366 * This can be called with or without the global lock held. 8367 */ 8368 int checkComponentPermission(String permission, int pid, int uid, 8369 int owningUid, boolean exported) { 8370 if (pid == MY_PID) { 8371 return PackageManager.PERMISSION_GRANTED; 8372 } 8373 return ActivityManager.checkComponentPermission(permission, uid, 8374 owningUid, exported); 8375 } 8376 8377 /** 8378 * As the only public entry point for permissions checking, this method 8379 * can enforce the semantic that requesting a check on a null global 8380 * permission is automatically denied. (Internally a null permission 8381 * string is used when calling {@link #checkComponentPermission} in cases 8382 * when only uid-based security is needed.) 8383 * 8384 * This can be called with or without the global lock held. 8385 */ 8386 @Override 8387 public int checkPermission(String permission, int pid, int uid) { 8388 if (permission == null) { 8389 return PackageManager.PERMISSION_DENIED; 8390 } 8391 return checkComponentPermission(permission, pid, uid, -1, true); 8392 } 8393 8394 @Override 8395 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 8396 if (permission == null) { 8397 return PackageManager.PERMISSION_DENIED; 8398 } 8399 8400 // We might be performing an operation on behalf of an indirect binder 8401 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 8402 // client identity accordingly before proceeding. 8403 Identity tlsIdentity = sCallerIdentity.get(); 8404 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 8405 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 8406 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 8407 uid = tlsIdentity.uid; 8408 pid = tlsIdentity.pid; 8409 } 8410 8411 return checkComponentPermission(permission, pid, uid, -1, true); 8412 } 8413 8414 /** 8415 * Binder IPC calls go through the public entry point. 8416 * This can be called with or without the global lock held. 8417 */ 8418 int checkCallingPermission(String permission) { 8419 return checkPermission(permission, 8420 Binder.getCallingPid(), 8421 UserHandle.getAppId(Binder.getCallingUid())); 8422 } 8423 8424 /** 8425 * This can be called with or without the global lock held. 8426 */ 8427 void enforceCallingPermission(String permission, String func) { 8428 if (checkCallingPermission(permission) 8429 == PackageManager.PERMISSION_GRANTED) { 8430 return; 8431 } 8432 8433 String msg = "Permission Denial: " + func + " from pid=" 8434 + Binder.getCallingPid() 8435 + ", uid=" + Binder.getCallingUid() 8436 + " requires " + permission; 8437 Slog.w(TAG, msg); 8438 throw new SecurityException(msg); 8439 } 8440 8441 /** 8442 * Determine if UID is holding permissions required to access {@link Uri} in 8443 * the given {@link ProviderInfo}. Final permission checking is always done 8444 * in {@link ContentProvider}. 8445 */ 8446 private final boolean checkHoldingPermissionsLocked( 8447 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 8448 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8449 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 8450 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 8451 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 8452 != PERMISSION_GRANTED) { 8453 return false; 8454 } 8455 } 8456 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 8457 } 8458 8459 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 8460 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 8461 if (pi.applicationInfo.uid == uid) { 8462 return true; 8463 } else if (!pi.exported) { 8464 return false; 8465 } 8466 8467 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 8468 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 8469 try { 8470 // check if target holds top-level <provider> permissions 8471 if (!readMet && pi.readPermission != null && considerUidPermissions 8472 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 8473 readMet = true; 8474 } 8475 if (!writeMet && pi.writePermission != null && considerUidPermissions 8476 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 8477 writeMet = true; 8478 } 8479 8480 // track if unprotected read/write is allowed; any denied 8481 // <path-permission> below removes this ability 8482 boolean allowDefaultRead = pi.readPermission == null; 8483 boolean allowDefaultWrite = pi.writePermission == null; 8484 8485 // check if target holds any <path-permission> that match uri 8486 final PathPermission[] pps = pi.pathPermissions; 8487 if (pps != null) { 8488 final String path = grantUri.uri.getPath(); 8489 int i = pps.length; 8490 while (i > 0 && (!readMet || !writeMet)) { 8491 i--; 8492 PathPermission pp = pps[i]; 8493 if (pp.match(path)) { 8494 if (!readMet) { 8495 final String pprperm = pp.getReadPermission(); 8496 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8497 "Checking read perm for " + pprperm + " for " + pp.getPath() 8498 + ": match=" + pp.match(path) 8499 + " check=" + pm.checkUidPermission(pprperm, uid)); 8500 if (pprperm != null) { 8501 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 8502 == PERMISSION_GRANTED) { 8503 readMet = true; 8504 } else { 8505 allowDefaultRead = false; 8506 } 8507 } 8508 } 8509 if (!writeMet) { 8510 final String ppwperm = pp.getWritePermission(); 8511 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8512 "Checking write perm " + ppwperm + " for " + pp.getPath() 8513 + ": match=" + pp.match(path) 8514 + " check=" + pm.checkUidPermission(ppwperm, uid)); 8515 if (ppwperm != null) { 8516 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 8517 == PERMISSION_GRANTED) { 8518 writeMet = true; 8519 } else { 8520 allowDefaultWrite = false; 8521 } 8522 } 8523 } 8524 } 8525 } 8526 } 8527 8528 // grant unprotected <provider> read/write, if not blocked by 8529 // <path-permission> above 8530 if (allowDefaultRead) readMet = true; 8531 if (allowDefaultWrite) writeMet = true; 8532 8533 } catch (RemoteException e) { 8534 return false; 8535 } 8536 8537 return readMet && writeMet; 8538 } 8539 8540 public boolean isAppStartModeDisabled(int uid, String packageName) { 8541 synchronized (this) { 8542 return getAppStartModeLocked(uid, packageName, 0, -1, false, true) 8543 == ActivityManager.APP_START_MODE_DISABLED; 8544 } 8545 } 8546 8547 // Unified app-op and target sdk check 8548 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) { 8549 // Apps that target O+ are always subject to background check 8550 if (packageTargetSdk >= Build.VERSION_CODES.O) { 8551 if (DEBUG_BACKGROUND_CHECK) { 8552 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted"); 8553 } 8554 return ActivityManager.APP_START_MODE_DELAYED_RIGID; 8555 } 8556 // ...and legacy apps get an AppOp check 8557 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, 8558 uid, packageName); 8559 if (DEBUG_BACKGROUND_CHECK) { 8560 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop); 8561 } 8562 switch (appop) { 8563 case AppOpsManager.MODE_ALLOWED: 8564 return ActivityManager.APP_START_MODE_NORMAL; 8565 case AppOpsManager.MODE_IGNORED: 8566 return ActivityManager.APP_START_MODE_DELAYED; 8567 default: 8568 return ActivityManager.APP_START_MODE_DELAYED_RIGID; 8569 } 8570 } 8571 8572 // Service launch is available to apps with run-in-background exemptions but 8573 // some other background operations are not. If we're doing a check 8574 // of service-launch policy, allow those callers to proceed unrestricted. 8575 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) { 8576 // Persistent app? 8577 if (mPackageManagerInt.isPackagePersistent(packageName)) { 8578 if (DEBUG_BACKGROUND_CHECK) { 8579 Slog.i(TAG, "App " + uid + "/" + packageName 8580 + " is persistent; not restricted in background"); 8581 } 8582 return ActivityManager.APP_START_MODE_NORMAL; 8583 } 8584 8585 // Non-persistent but background whitelisted? 8586 if (uidOnBackgroundWhitelist(uid)) { 8587 if (DEBUG_BACKGROUND_CHECK) { 8588 Slog.i(TAG, "App " + uid + "/" + packageName 8589 + " on background whitelist; not restricted in background"); 8590 } 8591 return ActivityManager.APP_START_MODE_NORMAL; 8592 } 8593 8594 // Is this app on the battery whitelist? 8595 if (isOnDeviceIdleWhitelistLocked(uid)) { 8596 if (DEBUG_BACKGROUND_CHECK) { 8597 Slog.i(TAG, "App " + uid + "/" + packageName 8598 + " on idle whitelist; not restricted in background"); 8599 } 8600 return ActivityManager.APP_START_MODE_NORMAL; 8601 } 8602 8603 // None of the service-policy criteria apply, so we apply the common criteria 8604 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk); 8605 } 8606 8607 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk, 8608 int callingPid, boolean alwaysRestrict, boolean disabledOnly) { 8609 UidRecord uidRec = mActiveUids.get(uid); 8610 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg=" 8611 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle=" 8612 + (uidRec != null ? uidRec.idle : false)); 8613 if (uidRec == null || alwaysRestrict || uidRec.idle) { 8614 boolean ephemeral; 8615 if (uidRec == null) { 8616 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral( 8617 UserHandle.getUserId(uid), packageName); 8618 } else { 8619 ephemeral = uidRec.ephemeral; 8620 } 8621 8622 if (ephemeral) { 8623 // We are hard-core about ephemeral apps not running in the background. 8624 return ActivityManager.APP_START_MODE_DISABLED; 8625 } else { 8626 if (disabledOnly) { 8627 // The caller is only interested in whether app starts are completely 8628 // disabled for the given package (that is, it is an instant app). So 8629 // we don't need to go further, which is all just seeing if we should 8630 // apply a "delayed" mode for a regular app. 8631 return ActivityManager.APP_START_MODE_NORMAL; 8632 } 8633 final int startMode = (alwaysRestrict) 8634 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk) 8635 : appServicesRestrictedInBackgroundLocked(uid, packageName, 8636 packageTargetSdk); 8637 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid 8638 + " pkg=" + packageName + " startMode=" + startMode 8639 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid)); 8640 if (startMode == ActivityManager.APP_START_MODE_DELAYED) { 8641 // This is an old app that has been forced into a "compatible as possible" 8642 // mode of background check. To increase compatibility, we will allow other 8643 // foreground apps to cause its services to start. 8644 if (callingPid >= 0) { 8645 ProcessRecord proc; 8646 synchronized (mPidsSelfLocked) { 8647 proc = mPidsSelfLocked.get(callingPid); 8648 } 8649 if (proc != null && 8650 !ActivityManager.isProcStateBackground(proc.curProcState)) { 8651 // Whoever is instigating this is in the foreground, so we will allow it 8652 // to go through. 8653 return ActivityManager.APP_START_MODE_NORMAL; 8654 } 8655 } 8656 } 8657 return startMode; 8658 } 8659 } 8660 return ActivityManager.APP_START_MODE_NORMAL; 8661 } 8662 8663 boolean isOnDeviceIdleWhitelistLocked(int uid) { 8664 final int appId = UserHandle.getAppId(uid); 8665 return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0 8666 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0 8667 || mPendingTempWhitelist.indexOfKey(uid) >= 0; 8668 } 8669 8670 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) { 8671 ProviderInfo pi = null; 8672 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 8673 if (cpr != null) { 8674 pi = cpr.info; 8675 } else { 8676 try { 8677 pi = AppGlobals.getPackageManager().resolveContentProvider( 8678 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags, 8679 userHandle); 8680 } catch (RemoteException ex) { 8681 } 8682 } 8683 return pi; 8684 } 8685 8686 void grantEphemeralAccessLocked(int userId, Intent intent, 8687 int targetAppId, int ephemeralAppId) { 8688 getPackageManagerInternalLocked(). 8689 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId); 8690 } 8691 8692 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 8693 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 8694 if (targetUris != null) { 8695 return targetUris.get(grantUri); 8696 } 8697 return null; 8698 } 8699 8700 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 8701 String targetPkg, int targetUid, GrantUri grantUri) { 8702 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 8703 if (targetUris == null) { 8704 targetUris = Maps.newArrayMap(); 8705 mGrantedUriPermissions.put(targetUid, targetUris); 8706 } 8707 8708 UriPermission perm = targetUris.get(grantUri); 8709 if (perm == null) { 8710 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 8711 targetUris.put(grantUri, perm); 8712 } 8713 8714 return perm; 8715 } 8716 8717 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 8718 final int modeFlags) { 8719 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 8720 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 8721 : UriPermission.STRENGTH_OWNED; 8722 8723 // Root gets to do everything. 8724 if (uid == 0) { 8725 return true; 8726 } 8727 8728 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 8729 if (perms == null) return false; 8730 8731 // First look for exact match 8732 final UriPermission exactPerm = perms.get(grantUri); 8733 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 8734 return true; 8735 } 8736 8737 // No exact match, look for prefixes 8738 final int N = perms.size(); 8739 for (int i = 0; i < N; i++) { 8740 final UriPermission perm = perms.valueAt(i); 8741 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 8742 && perm.getStrength(modeFlags) >= minStrength) { 8743 return true; 8744 } 8745 } 8746 8747 return false; 8748 } 8749 8750 /** 8751 * @param uri This uri must NOT contain an embedded userId. 8752 * @param userId The userId in which the uri is to be resolved. 8753 */ 8754 @Override 8755 public int checkUriPermission(Uri uri, int pid, int uid, 8756 final int modeFlags, int userId, IBinder callerToken) { 8757 enforceNotIsolatedCaller("checkUriPermission"); 8758 8759 // Another redirected-binder-call permissions check as in 8760 // {@link checkPermissionWithToken}. 8761 Identity tlsIdentity = sCallerIdentity.get(); 8762 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 8763 uid = tlsIdentity.uid; 8764 pid = tlsIdentity.pid; 8765 } 8766 8767 // Our own process gets to do everything. 8768 if (pid == MY_PID) { 8769 return PackageManager.PERMISSION_GRANTED; 8770 } 8771 synchronized (this) { 8772 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 8773 ? PackageManager.PERMISSION_GRANTED 8774 : PackageManager.PERMISSION_DENIED; 8775 } 8776 } 8777 8778 /** 8779 * Check if the targetPkg can be granted permission to access uri by 8780 * the callingUid using the given modeFlags. Throws a security exception 8781 * if callingUid is not allowed to do this. Returns the uid of the target 8782 * if the URI permission grant should be performed; returns -1 if it is not 8783 * needed (for example targetPkg already has permission to access the URI). 8784 * If you already know the uid of the target, you can supply it in 8785 * lastTargetUid else set that to -1. 8786 */ 8787 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 8788 final int modeFlags, int lastTargetUid) { 8789 if (!Intent.isAccessUriMode(modeFlags)) { 8790 return -1; 8791 } 8792 8793 if (targetPkg != null) { 8794 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8795 "Checking grant " + targetPkg + " permission to " + grantUri); 8796 } 8797 8798 final IPackageManager pm = AppGlobals.getPackageManager(); 8799 8800 // If this is not a content: uri, we can't do anything with it. 8801 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 8802 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8803 "Can't grant URI permission for non-content URI: " + grantUri); 8804 return -1; 8805 } 8806 8807 // Bail early if system is trying to hand out permissions directly; it 8808 // must always grant permissions on behalf of someone explicit. 8809 final int callingAppId = UserHandle.getAppId(callingUid); 8810 if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) { 8811 if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) { 8812 // Exempted authority for cropping user photos in Settings app 8813 } else { 8814 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission" 8815 + " grant to " + grantUri + "; use startActivityAsCaller() instead"); 8816 return -1; 8817 } 8818 } 8819 8820 final String authority = grantUri.uri.getAuthority(); 8821 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId, 8822 MATCH_DEBUG_TRIAGED_MISSING); 8823 if (pi == null) { 8824 Slog.w(TAG, "No content provider found for permission check: " + 8825 grantUri.uri.toSafeString()); 8826 return -1; 8827 } 8828 8829 int targetUid = lastTargetUid; 8830 if (targetUid < 0 && targetPkg != null) { 8831 try { 8832 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, 8833 UserHandle.getUserId(callingUid)); 8834 if (targetUid < 0) { 8835 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8836 "Can't grant URI permission no uid for: " + targetPkg); 8837 return -1; 8838 } 8839 } catch (RemoteException ex) { 8840 return -1; 8841 } 8842 } 8843 8844 // If we're extending a persistable grant, then we always need to create 8845 // the grant data structure so that take/release APIs work 8846 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) { 8847 return targetUid; 8848 } 8849 8850 if (targetUid >= 0) { 8851 // First... does the target actually need this permission? 8852 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 8853 // No need to grant the target this permission. 8854 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8855 "Target " + targetPkg + " already has full permission to " + grantUri); 8856 return -1; 8857 } 8858 } else { 8859 // First... there is no target package, so can anyone access it? 8860 boolean allowed = pi.exported; 8861 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 8862 if (pi.readPermission != null) { 8863 allowed = false; 8864 } 8865 } 8866 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 8867 if (pi.writePermission != null) { 8868 allowed = false; 8869 } 8870 } 8871 if (allowed) { 8872 return -1; 8873 } 8874 } 8875 8876 /* There is a special cross user grant if: 8877 * - The target is on another user. 8878 * - Apps on the current user can access the uri without any uid permissions. 8879 * In this case, we grant a uri permission, even if the ContentProvider does not normally 8880 * grant uri permissions. 8881 */ 8882 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 8883 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 8884 modeFlags, false /*without considering the uid permissions*/); 8885 8886 // Second... is the provider allowing granting of URI permissions? 8887 if (!specialCrossUserGrant) { 8888 if (!pi.grantUriPermissions) { 8889 throw new SecurityException("Provider " + pi.packageName 8890 + "/" + pi.name 8891 + " does not allow granting of Uri permissions (uri " 8892 + grantUri + ")"); 8893 } 8894 if (pi.uriPermissionPatterns != null) { 8895 final int N = pi.uriPermissionPatterns.length; 8896 boolean allowed = false; 8897 for (int i=0; i<N; i++) { 8898 if (pi.uriPermissionPatterns[i] != null 8899 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 8900 allowed = true; 8901 break; 8902 } 8903 } 8904 if (!allowed) { 8905 throw new SecurityException("Provider " + pi.packageName 8906 + "/" + pi.name 8907 + " does not allow granting of permission to path of Uri " 8908 + grantUri); 8909 } 8910 } 8911 } 8912 8913 // Third... does the caller itself have permission to access 8914 // this uri? 8915 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 8916 // Require they hold a strong enough Uri permission 8917 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 8918 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) { 8919 throw new SecurityException( 8920 "UID " + callingUid + " does not have permission to " + grantUri 8921 + "; you could obtain access using ACTION_OPEN_DOCUMENT " 8922 + "or related APIs"); 8923 } else { 8924 throw new SecurityException( 8925 "UID " + callingUid + " does not have permission to " + grantUri); 8926 } 8927 } 8928 } 8929 return targetUid; 8930 } 8931 8932 /** 8933 * @param uri This uri must NOT contain an embedded userId. 8934 * @param userId The userId in which the uri is to be resolved. 8935 */ 8936 @Override 8937 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 8938 final int modeFlags, int userId) { 8939 enforceNotIsolatedCaller("checkGrantUriPermission"); 8940 synchronized(this) { 8941 return checkGrantUriPermissionLocked(callingUid, targetPkg, 8942 new GrantUri(userId, uri, false), modeFlags, -1); 8943 } 8944 } 8945 8946 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 8947 final int modeFlags, UriPermissionOwner owner) { 8948 if (!Intent.isAccessUriMode(modeFlags)) { 8949 return; 8950 } 8951 8952 // So here we are: the caller has the assumed permission 8953 // to the uri, and the target doesn't. Let's now give this to 8954 // the target. 8955 8956 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8957 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 8958 8959 final String authority = grantUri.uri.getAuthority(); 8960 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId, 8961 MATCH_DEBUG_TRIAGED_MISSING); 8962 if (pi == null) { 8963 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 8964 return; 8965 } 8966 8967 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 8968 grantUri.prefix = true; 8969 } 8970 final UriPermission perm = findOrCreateUriPermissionLocked( 8971 pi.packageName, targetPkg, targetUid, grantUri); 8972 perm.grantModes(modeFlags, owner); 8973 } 8974 8975 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 8976 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 8977 if (targetPkg == null) { 8978 throw new NullPointerException("targetPkg"); 8979 } 8980 int targetUid; 8981 final IPackageManager pm = AppGlobals.getPackageManager(); 8982 try { 8983 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId); 8984 } catch (RemoteException ex) { 8985 return; 8986 } 8987 8988 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 8989 targetUid); 8990 if (targetUid < 0) { 8991 return; 8992 } 8993 8994 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 8995 owner); 8996 } 8997 8998 static class NeededUriGrants extends ArrayList<GrantUri> { 8999 final String targetPkg; 9000 final int targetUid; 9001 final int flags; 9002 9003 NeededUriGrants(String targetPkg, int targetUid, int flags) { 9004 this.targetPkg = targetPkg; 9005 this.targetUid = targetUid; 9006 this.flags = flags; 9007 } 9008 } 9009 9010 /** 9011 * Like checkGrantUriPermissionLocked, but takes an Intent. 9012 */ 9013 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 9014 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 9015 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9016 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 9017 + " clip=" + (intent != null ? intent.getClipData() : null) 9018 + " from " + intent + "; flags=0x" 9019 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 9020 9021 if (targetPkg == null) { 9022 throw new NullPointerException("targetPkg"); 9023 } 9024 9025 if (intent == null) { 9026 return null; 9027 } 9028 Uri data = intent.getData(); 9029 ClipData clip = intent.getClipData(); 9030 if (data == null && clip == null) { 9031 return null; 9032 } 9033 // Default userId for uris in the intent (if they don't specify it themselves) 9034 int contentUserHint = intent.getContentUserHint(); 9035 if (contentUserHint == UserHandle.USER_CURRENT) { 9036 contentUserHint = UserHandle.getUserId(callingUid); 9037 } 9038 final IPackageManager pm = AppGlobals.getPackageManager(); 9039 int targetUid; 9040 if (needed != null) { 9041 targetUid = needed.targetUid; 9042 } else { 9043 try { 9044 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, 9045 targetUserId); 9046 } catch (RemoteException ex) { 9047 return null; 9048 } 9049 if (targetUid < 0) { 9050 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9051 "Can't grant URI permission no uid for: " + targetPkg 9052 + " on user " + targetUserId); 9053 return null; 9054 } 9055 } 9056 if (data != null) { 9057 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 9058 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 9059 targetUid); 9060 if (targetUid > 0) { 9061 if (needed == null) { 9062 needed = new NeededUriGrants(targetPkg, targetUid, mode); 9063 } 9064 needed.add(grantUri); 9065 } 9066 } 9067 if (clip != null) { 9068 for (int i=0; i<clip.getItemCount(); i++) { 9069 Uri uri = clip.getItemAt(i).getUri(); 9070 if (uri != null) { 9071 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 9072 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 9073 targetUid); 9074 if (targetUid > 0) { 9075 if (needed == null) { 9076 needed = new NeededUriGrants(targetPkg, targetUid, mode); 9077 } 9078 needed.add(grantUri); 9079 } 9080 } else { 9081 Intent clipIntent = clip.getItemAt(i).getIntent(); 9082 if (clipIntent != null) { 9083 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 9084 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 9085 if (newNeeded != null) { 9086 needed = newNeeded; 9087 } 9088 } 9089 } 9090 } 9091 } 9092 9093 return needed; 9094 } 9095 9096 /** 9097 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 9098 */ 9099 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 9100 UriPermissionOwner owner) { 9101 if (needed != null) { 9102 for (int i=0; i<needed.size(); i++) { 9103 GrantUri grantUri = needed.get(i); 9104 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 9105 grantUri, needed.flags, owner); 9106 } 9107 } 9108 } 9109 9110 void grantUriPermissionFromIntentLocked(int callingUid, 9111 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 9112 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 9113 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 9114 if (needed == null) { 9115 return; 9116 } 9117 9118 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 9119 } 9120 9121 /** 9122 * @param uri This uri must NOT contain an embedded userId. 9123 * @param userId The userId in which the uri is to be resolved. 9124 */ 9125 @Override 9126 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 9127 final int modeFlags, int userId) { 9128 enforceNotIsolatedCaller("grantUriPermission"); 9129 GrantUri grantUri = new GrantUri(userId, uri, false); 9130 synchronized(this) { 9131 final ProcessRecord r = getRecordForAppLocked(caller); 9132 if (r == null) { 9133 throw new SecurityException("Unable to find app for caller " 9134 + caller 9135 + " when granting permission to uri " + grantUri); 9136 } 9137 if (targetPkg == null) { 9138 throw new IllegalArgumentException("null target"); 9139 } 9140 if (grantUri == null) { 9141 throw new IllegalArgumentException("null uri"); 9142 } 9143 9144 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 9145 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 9146 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 9147 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 9148 9149 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 9150 UserHandle.getUserId(r.uid)); 9151 } 9152 } 9153 9154 void removeUriPermissionIfNeededLocked(UriPermission perm) { 9155 if (perm.modeFlags == 0) { 9156 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 9157 perm.targetUid); 9158 if (perms != null) { 9159 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9160 "Removing " + perm.targetUid + " permission to " + perm.uri); 9161 9162 perms.remove(perm.uri); 9163 if (perms.isEmpty()) { 9164 mGrantedUriPermissions.remove(perm.targetUid); 9165 } 9166 } 9167 } 9168 } 9169 9170 private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri, 9171 final int modeFlags) { 9172 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9173 "Revoking all granted permissions to " + grantUri); 9174 9175 final IPackageManager pm = AppGlobals.getPackageManager(); 9176 final String authority = grantUri.uri.getAuthority(); 9177 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId, 9178 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE); 9179 if (pi == null) { 9180 Slog.w(TAG, "No content provider found for permission revoke: " 9181 + grantUri.toSafeString()); 9182 return; 9183 } 9184 9185 // Does the caller have this permission on the URI? 9186 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 9187 // If they don't have direct access to the URI, then revoke any 9188 // ownerless URI permissions that have been granted to them. 9189 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9190 if (perms != null) { 9191 boolean persistChanged = false; 9192 for (int i = perms.size()-1; i >= 0; i--) { 9193 final UriPermission perm = perms.valueAt(i); 9194 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) { 9195 continue; 9196 } 9197 if (perm.uri.sourceUserId == grantUri.sourceUserId 9198 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 9199 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9200 "Revoking non-owned " + perm.targetUid 9201 + " permission to " + perm.uri); 9202 persistChanged |= perm.revokeModes( 9203 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 9204 if (perm.modeFlags == 0) { 9205 perms.removeAt(i); 9206 } 9207 } 9208 } 9209 if (perms.isEmpty()) { 9210 mGrantedUriPermissions.remove(callingUid); 9211 } 9212 if (persistChanged) { 9213 schedulePersistUriGrants(); 9214 } 9215 } 9216 return; 9217 } 9218 9219 boolean persistChanged = false; 9220 9221 // Go through all of the permissions and remove any that match. 9222 for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) { 9223 final int targetUid = mGrantedUriPermissions.keyAt(i); 9224 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 9225 9226 for (int j = perms.size()-1; j >= 0; j--) { 9227 final UriPermission perm = perms.valueAt(j); 9228 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) { 9229 continue; 9230 } 9231 if (perm.uri.sourceUserId == grantUri.sourceUserId 9232 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 9233 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9234 "Revoking " + perm.targetUid + " permission to " + perm.uri); 9235 persistChanged |= perm.revokeModes( 9236 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, 9237 targetPackage == null); 9238 if (perm.modeFlags == 0) { 9239 perms.removeAt(j); 9240 } 9241 } 9242 } 9243 9244 if (perms.isEmpty()) { 9245 mGrantedUriPermissions.removeAt(i); 9246 } 9247 } 9248 9249 if (persistChanged) { 9250 schedulePersistUriGrants(); 9251 } 9252 } 9253 9254 /** 9255 * @param uri This uri must NOT contain an embedded userId. 9256 * @param userId The userId in which the uri is to be resolved. 9257 */ 9258 @Override 9259 public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri, 9260 final int modeFlags, int userId) { 9261 enforceNotIsolatedCaller("revokeUriPermission"); 9262 synchronized(this) { 9263 final ProcessRecord r = getRecordForAppLocked(caller); 9264 if (r == null) { 9265 throw new SecurityException("Unable to find app for caller " 9266 + caller 9267 + " when revoking permission to uri " + uri); 9268 } 9269 if (uri == null) { 9270 Slog.w(TAG, "revokeUriPermission: null uri"); 9271 return; 9272 } 9273 9274 if (!Intent.isAccessUriMode(modeFlags)) { 9275 return; 9276 } 9277 9278 final String authority = uri.getAuthority(); 9279 final ProviderInfo pi = getProviderInfoLocked(authority, userId, 9280 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE); 9281 if (pi == null) { 9282 Slog.w(TAG, "No content provider found for permission revoke: " 9283 + uri.toSafeString()); 9284 return; 9285 } 9286 9287 revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false), 9288 modeFlags); 9289 } 9290 } 9291 9292 /** 9293 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 9294 * given package. 9295 * 9296 * @param packageName Package name to match, or {@code null} to apply to all 9297 * packages. 9298 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 9299 * to all users. 9300 * @param persistable If persistable grants should be removed. 9301 */ 9302 private void removeUriPermissionsForPackageLocked( 9303 String packageName, int userHandle, boolean persistable) { 9304 if (userHandle == UserHandle.USER_ALL && packageName == null) { 9305 throw new IllegalArgumentException("Must narrow by either package or user"); 9306 } 9307 9308 boolean persistChanged = false; 9309 9310 int N = mGrantedUriPermissions.size(); 9311 for (int i = 0; i < N; i++) { 9312 final int targetUid = mGrantedUriPermissions.keyAt(i); 9313 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 9314 9315 // Only inspect grants matching user 9316 if (userHandle == UserHandle.USER_ALL 9317 || userHandle == UserHandle.getUserId(targetUid)) { 9318 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 9319 final UriPermission perm = it.next(); 9320 9321 // Only inspect grants matching package 9322 if (packageName == null || perm.sourcePkg.equals(packageName) 9323 || perm.targetPkg.equals(packageName)) { 9324 // Hacky solution as part of fixing a security bug; ignore 9325 // grants associated with DownloadManager so we don't have 9326 // to immediately launch it to regrant the permissions 9327 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority()) 9328 && !persistable) continue; 9329 9330 persistChanged |= perm.revokeModes(persistable 9331 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 9332 9333 // Only remove when no modes remain; any persisted grants 9334 // will keep this alive. 9335 if (perm.modeFlags == 0) { 9336 it.remove(); 9337 } 9338 } 9339 } 9340 9341 if (perms.isEmpty()) { 9342 mGrantedUriPermissions.remove(targetUid); 9343 N--; 9344 i--; 9345 } 9346 } 9347 } 9348 9349 if (persistChanged) { 9350 schedulePersistUriGrants(); 9351 } 9352 } 9353 9354 @Override 9355 public IBinder newUriPermissionOwner(String name) { 9356 enforceNotIsolatedCaller("newUriPermissionOwner"); 9357 synchronized(this) { 9358 UriPermissionOwner owner = new UriPermissionOwner(this, name); 9359 return owner.getExternalTokenLocked(); 9360 } 9361 } 9362 9363 @Override 9364 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) { 9365 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity"); 9366 synchronized(this) { 9367 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 9368 if (r == null) { 9369 throw new IllegalArgumentException("Activity does not exist; token=" 9370 + activityToken); 9371 } 9372 return r.getUriPermissionsLocked().getExternalTokenLocked(); 9373 } 9374 } 9375 /** 9376 * @param uri This uri must NOT contain an embedded userId. 9377 * @param sourceUserId The userId in which the uri is to be resolved. 9378 * @param targetUserId The userId of the app that receives the grant. 9379 */ 9380 @Override 9381 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 9382 final int modeFlags, int sourceUserId, int targetUserId) { 9383 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(), 9384 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY, 9385 "grantUriPermissionFromOwner", null); 9386 synchronized(this) { 9387 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 9388 if (owner == null) { 9389 throw new IllegalArgumentException("Unknown owner: " + token); 9390 } 9391 if (fromUid != Binder.getCallingUid()) { 9392 if (Binder.getCallingUid() != myUid()) { 9393 // Only system code can grant URI permissions on behalf 9394 // of other users. 9395 throw new SecurityException("nice try"); 9396 } 9397 } 9398 if (targetPkg == null) { 9399 throw new IllegalArgumentException("null target"); 9400 } 9401 if (uri == null) { 9402 throw new IllegalArgumentException("null uri"); 9403 } 9404 9405 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 9406 modeFlags, owner, targetUserId); 9407 } 9408 } 9409 9410 /** 9411 * @param uri This uri must NOT contain an embedded userId. 9412 * @param userId The userId in which the uri is to be resolved. 9413 */ 9414 @Override 9415 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 9416 synchronized(this) { 9417 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 9418 if (owner == null) { 9419 throw new IllegalArgumentException("Unknown owner: " + token); 9420 } 9421 9422 if (uri == null) { 9423 owner.removeUriPermissionsLocked(mode); 9424 } else { 9425 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 9426 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode); 9427 } 9428 } 9429 } 9430 9431 private void schedulePersistUriGrants() { 9432 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 9433 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 9434 10 * DateUtils.SECOND_IN_MILLIS); 9435 } 9436 } 9437 9438 private void writeGrantedUriPermissions() { 9439 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()"); 9440 9441 // Snapshot permissions so we can persist without lock 9442 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 9443 synchronized (this) { 9444 final int size = mGrantedUriPermissions.size(); 9445 for (int i = 0; i < size; i++) { 9446 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 9447 for (UriPermission perm : perms.values()) { 9448 if (perm.persistedModeFlags != 0) { 9449 persist.add(perm.snapshot()); 9450 } 9451 } 9452 } 9453 } 9454 9455 FileOutputStream fos = null; 9456 try { 9457 fos = mGrantFile.startWrite(); 9458 9459 XmlSerializer out = new FastXmlSerializer(); 9460 out.setOutput(fos, StandardCharsets.UTF_8.name()); 9461 out.startDocument(null, true); 9462 out.startTag(null, TAG_URI_GRANTS); 9463 for (UriPermission.Snapshot perm : persist) { 9464 out.startTag(null, TAG_URI_GRANT); 9465 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 9466 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 9467 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 9468 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 9469 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 9470 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 9471 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 9472 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 9473 out.endTag(null, TAG_URI_GRANT); 9474 } 9475 out.endTag(null, TAG_URI_GRANTS); 9476 out.endDocument(); 9477 9478 mGrantFile.finishWrite(fos); 9479 } catch (IOException e) { 9480 if (fos != null) { 9481 mGrantFile.failWrite(fos); 9482 } 9483 } 9484 } 9485 9486 private void readGrantedUriPermissionsLocked() { 9487 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()"); 9488 9489 final long now = System.currentTimeMillis(); 9490 9491 FileInputStream fis = null; 9492 try { 9493 fis = mGrantFile.openRead(); 9494 final XmlPullParser in = Xml.newPullParser(); 9495 in.setInput(fis, StandardCharsets.UTF_8.name()); 9496 9497 int type; 9498 while ((type = in.next()) != END_DOCUMENT) { 9499 final String tag = in.getName(); 9500 if (type == START_TAG) { 9501 if (TAG_URI_GRANT.equals(tag)) { 9502 final int sourceUserId; 9503 final int targetUserId; 9504 final int userHandle = readIntAttribute(in, 9505 ATTR_USER_HANDLE, UserHandle.USER_NULL); 9506 if (userHandle != UserHandle.USER_NULL) { 9507 // For backwards compatibility. 9508 sourceUserId = userHandle; 9509 targetUserId = userHandle; 9510 } else { 9511 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 9512 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 9513 } 9514 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 9515 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 9516 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 9517 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 9518 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 9519 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 9520 9521 // Sanity check that provider still belongs to source package 9522 // Both direct boot aware and unaware packages are fine as we 9523 // will do filtering at query time to avoid multiple parsing. 9524 final ProviderInfo pi = getProviderInfoLocked( 9525 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE 9526 | MATCH_DIRECT_BOOT_UNAWARE); 9527 if (pi != null && sourcePkg.equals(pi.packageName)) { 9528 int targetUid = -1; 9529 try { 9530 targetUid = AppGlobals.getPackageManager().getPackageUid( 9531 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId); 9532 } catch (RemoteException e) { 9533 } 9534 if (targetUid != -1) { 9535 final UriPermission perm = findOrCreateUriPermissionLocked( 9536 sourcePkg, targetPkg, targetUid, 9537 new GrantUri(sourceUserId, uri, prefix)); 9538 perm.initPersistedModes(modeFlags, createdTime); 9539 } 9540 } else { 9541 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 9542 + " but instead found " + pi); 9543 } 9544 } 9545 } 9546 } 9547 } catch (FileNotFoundException e) { 9548 // Missing grants is okay 9549 } catch (IOException e) { 9550 Slog.wtf(TAG, "Failed reading Uri grants", e); 9551 } catch (XmlPullParserException e) { 9552 Slog.wtf(TAG, "Failed reading Uri grants", e); 9553 } finally { 9554 IoUtils.closeQuietly(fis); 9555 } 9556 } 9557 9558 /** 9559 * @param uri This uri must NOT contain an embedded userId. 9560 * @param userId The userId in which the uri is to be resolved. 9561 */ 9562 @Override 9563 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 9564 enforceNotIsolatedCaller("takePersistableUriPermission"); 9565 9566 Preconditions.checkFlagsArgument(modeFlags, 9567 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 9568 9569 synchronized (this) { 9570 final int callingUid = Binder.getCallingUid(); 9571 boolean persistChanged = false; 9572 GrantUri grantUri = new GrantUri(userId, uri, false); 9573 9574 UriPermission exactPerm = findUriPermissionLocked(callingUid, 9575 new GrantUri(userId, uri, false)); 9576 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 9577 new GrantUri(userId, uri, true)); 9578 9579 final boolean exactValid = (exactPerm != null) 9580 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 9581 final boolean prefixValid = (prefixPerm != null) 9582 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 9583 9584 if (!(exactValid || prefixValid)) { 9585 throw new SecurityException("No persistable permission grants found for UID " 9586 + callingUid + " and Uri " + grantUri.toSafeString()); 9587 } 9588 9589 if (exactValid) { 9590 persistChanged |= exactPerm.takePersistableModes(modeFlags); 9591 } 9592 if (prefixValid) { 9593 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 9594 } 9595 9596 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 9597 9598 if (persistChanged) { 9599 schedulePersistUriGrants(); 9600 } 9601 } 9602 } 9603 9604 /** 9605 * @param uri This uri must NOT contain an embedded userId. 9606 * @param userId The userId in which the uri is to be resolved. 9607 */ 9608 @Override 9609 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 9610 enforceNotIsolatedCaller("releasePersistableUriPermission"); 9611 9612 Preconditions.checkFlagsArgument(modeFlags, 9613 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 9614 9615 synchronized (this) { 9616 final int callingUid = Binder.getCallingUid(); 9617 boolean persistChanged = false; 9618 9619 UriPermission exactPerm = findUriPermissionLocked(callingUid, 9620 new GrantUri(userId, uri, false)); 9621 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 9622 new GrantUri(userId, uri, true)); 9623 if (exactPerm == null && prefixPerm == null) { 9624 throw new SecurityException("No permission grants found for UID " + callingUid 9625 + " and Uri " + uri.toSafeString()); 9626 } 9627 9628 if (exactPerm != null) { 9629 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 9630 removeUriPermissionIfNeededLocked(exactPerm); 9631 } 9632 if (prefixPerm != null) { 9633 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 9634 removeUriPermissionIfNeededLocked(prefixPerm); 9635 } 9636 9637 if (persistChanged) { 9638 schedulePersistUriGrants(); 9639 } 9640 } 9641 } 9642 9643 /** 9644 * Prune any older {@link UriPermission} for the given UID until outstanding 9645 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 9646 * 9647 * @return if any mutations occured that require persisting. 9648 */ 9649 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 9650 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 9651 if (perms == null) return false; 9652 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 9653 9654 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 9655 for (UriPermission perm : perms.values()) { 9656 if (perm.persistedModeFlags != 0) { 9657 persisted.add(perm); 9658 } 9659 } 9660 9661 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 9662 if (trimCount <= 0) return false; 9663 9664 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 9665 for (int i = 0; i < trimCount; i++) { 9666 final UriPermission perm = persisted.get(i); 9667 9668 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9669 "Trimming grant created at " + perm.persistedCreateTime); 9670 9671 perm.releasePersistableModes(~0); 9672 removeUriPermissionIfNeededLocked(perm); 9673 } 9674 9675 return true; 9676 } 9677 9678 @Override 9679 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 9680 String packageName, boolean incoming) { 9681 enforceNotIsolatedCaller("getPersistedUriPermissions"); 9682 Preconditions.checkNotNull(packageName, "packageName"); 9683 9684 final int callingUid = Binder.getCallingUid(); 9685 final int callingUserId = UserHandle.getUserId(callingUid); 9686 final IPackageManager pm = AppGlobals.getPackageManager(); 9687 try { 9688 final int packageUid = pm.getPackageUid(packageName, 9689 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId); 9690 if (packageUid != callingUid) { 9691 throw new SecurityException( 9692 "Package " + packageName + " does not belong to calling UID " + callingUid); 9693 } 9694 } catch (RemoteException e) { 9695 throw new SecurityException("Failed to verify package name ownership"); 9696 } 9697 9698 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 9699 synchronized (this) { 9700 if (incoming) { 9701 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 9702 callingUid); 9703 if (perms == null) { 9704 Slog.w(TAG, "No permission grants found for " + packageName); 9705 } else { 9706 for (UriPermission perm : perms.values()) { 9707 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 9708 result.add(perm.buildPersistedPublicApiObject()); 9709 } 9710 } 9711 } 9712 } else { 9713 final int size = mGrantedUriPermissions.size(); 9714 for (int i = 0; i < size; i++) { 9715 final ArrayMap<GrantUri, UriPermission> perms = 9716 mGrantedUriPermissions.valueAt(i); 9717 for (UriPermission perm : perms.values()) { 9718 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 9719 result.add(perm.buildPersistedPublicApiObject()); 9720 } 9721 } 9722 } 9723 } 9724 } 9725 return new ParceledListSlice<android.content.UriPermission>(result); 9726 } 9727 9728 @Override 9729 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions( 9730 String packageName, int userId) { 9731 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS, 9732 "getGrantedUriPermissions"); 9733 9734 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 9735 synchronized (this) { 9736 final int size = mGrantedUriPermissions.size(); 9737 for (int i = 0; i < size; i++) { 9738 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 9739 for (UriPermission perm : perms.values()) { 9740 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId 9741 && perm.persistedModeFlags != 0) { 9742 result.add(perm.buildPersistedPublicApiObject()); 9743 } 9744 } 9745 } 9746 } 9747 return new ParceledListSlice<android.content.UriPermission>(result); 9748 } 9749 9750 @Override 9751 public void clearGrantedUriPermissions(String packageName, int userId) { 9752 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS, 9753 "clearGrantedUriPermissions"); 9754 removeUriPermissionsForPackageLocked(packageName, userId, true); 9755 } 9756 9757 @Override 9758 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 9759 synchronized (this) { 9760 ProcessRecord app = 9761 who != null ? getRecordForAppLocked(who) : null; 9762 if (app == null) return; 9763 9764 Message msg = Message.obtain(); 9765 msg.what = WAIT_FOR_DEBUGGER_UI_MSG; 9766 msg.obj = app; 9767 msg.arg1 = waiting ? 1 : 0; 9768 mUiHandler.sendMessage(msg); 9769 } 9770 } 9771 9772 @Override 9773 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 9774 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 9775 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 9776 outInfo.availMem = getFreeMemory(); 9777 outInfo.totalMem = getTotalMemory(); 9778 outInfo.threshold = homeAppMem; 9779 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 9780 outInfo.hiddenAppThreshold = cachedAppMem; 9781 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 9782 ProcessList.SERVICE_ADJ); 9783 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 9784 ProcessList.VISIBLE_APP_ADJ); 9785 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 9786 ProcessList.FOREGROUND_APP_ADJ); 9787 } 9788 9789 // ========================================================= 9790 // TASK MANAGEMENT 9791 // ========================================================= 9792 9793 @Override 9794 public List<IBinder> getAppTasks(String callingPackage) { 9795 int callingUid = Binder.getCallingUid(); 9796 long ident = Binder.clearCallingIdentity(); 9797 9798 synchronized(this) { 9799 ArrayList<IBinder> list = new ArrayList<IBinder>(); 9800 try { 9801 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks"); 9802 9803 final int N = mRecentTasks.size(); 9804 for (int i = 0; i < N; i++) { 9805 TaskRecord tr = mRecentTasks.get(i); 9806 // Skip tasks that do not match the caller. We don't need to verify 9807 // callingPackage, because we are also limiting to callingUid and know 9808 // that will limit to the correct security sandbox. 9809 if (tr.effectiveUid != callingUid) { 9810 continue; 9811 } 9812 Intent intent = tr.getBaseIntent(); 9813 if (intent == null || 9814 !callingPackage.equals(intent.getComponent().getPackageName())) { 9815 continue; 9816 } 9817 ActivityManager.RecentTaskInfo taskInfo = 9818 createRecentTaskInfoFromTaskRecord(tr); 9819 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 9820 list.add(taskImpl.asBinder()); 9821 } 9822 } finally { 9823 Binder.restoreCallingIdentity(ident); 9824 } 9825 return list; 9826 } 9827 } 9828 9829 @Override 9830 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 9831 final int callingUid = Binder.getCallingUid(); 9832 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 9833 9834 synchronized(this) { 9835 if (DEBUG_ALL) Slog.v( 9836 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 9837 9838 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 9839 callingUid); 9840 9841 // TODO: Improve with MRU list from all ActivityStacks. 9842 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 9843 } 9844 9845 return list; 9846 } 9847 9848 /** 9849 * Creates a new RecentTaskInfo from a TaskRecord. 9850 */ 9851 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 9852 // Update the task description to reflect any changes in the task stack 9853 tr.updateTaskDescription(); 9854 9855 // Compose the recent task info 9856 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 9857 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 9858 rti.persistentId = tr.taskId; 9859 rti.baseIntent = new Intent(tr.getBaseIntent()); 9860 rti.origActivity = tr.origActivity; 9861 rti.realActivity = tr.realActivity; 9862 rti.description = tr.lastDescription; 9863 rti.stackId = tr.getStackId(); 9864 rti.userId = tr.userId; 9865 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 9866 rti.firstActiveTime = tr.firstActiveTime; 9867 rti.lastActiveTime = tr.lastActiveTime; 9868 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 9869 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 9870 rti.numActivities = 0; 9871 if (tr.mBounds != null) { 9872 rti.bounds = new Rect(tr.mBounds); 9873 } 9874 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen(); 9875 rti.resizeMode = tr.mResizeMode; 9876 9877 ActivityRecord base = null; 9878 ActivityRecord top = null; 9879 ActivityRecord tmp; 9880 9881 for (int i = tr.mActivities.size() - 1; i >= 0; --i) { 9882 tmp = tr.mActivities.get(i); 9883 if (tmp.finishing) { 9884 continue; 9885 } 9886 base = tmp; 9887 if (top == null || (top.state == ActivityState.INITIALIZING)) { 9888 top = base; 9889 } 9890 rti.numActivities++; 9891 } 9892 9893 rti.baseActivity = (base != null) ? base.intent.getComponent() : null; 9894 rti.topActivity = (top != null) ? top.intent.getComponent() : null; 9895 9896 return rti; 9897 } 9898 9899 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 9900 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 9901 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 9902 if (!allowed) { 9903 if (checkPermission(android.Manifest.permission.GET_TASKS, 9904 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 9905 // Temporary compatibility: some existing apps on the system image may 9906 // still be requesting the old permission and not switched to the new 9907 // one; if so, we'll still allow them full access. This means we need 9908 // to see if they are holding the old permission and are a system app. 9909 try { 9910 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 9911 allowed = true; 9912 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid 9913 + " is using old GET_TASKS but privileged; allowing"); 9914 } 9915 } catch (RemoteException e) { 9916 } 9917 } 9918 } 9919 if (!allowed) { 9920 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid 9921 + " does not hold REAL_GET_TASKS; limiting output"); 9922 } 9923 return allowed; 9924 } 9925 9926 @Override 9927 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, 9928 int userId) { 9929 final int callingUid = Binder.getCallingUid(); 9930 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 9931 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 9932 9933 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 9934 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 9935 synchronized (this) { 9936 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 9937 callingUid); 9938 final boolean detailed = checkCallingPermission( 9939 android.Manifest.permission.GET_DETAILED_TASKS) 9940 == PackageManager.PERMISSION_GRANTED; 9941 9942 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) { 9943 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents"); 9944 return ParceledListSlice.emptyList(); 9945 } 9946 mRecentTasks.loadUserRecentsLocked(userId); 9947 9948 final int recentsCount = mRecentTasks.size(); 9949 ArrayList<ActivityManager.RecentTaskInfo> res = 9950 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount); 9951 9952 final Set<Integer> includedUsers; 9953 if (includeProfiles) { 9954 includedUsers = mUserController.getProfileIds(userId); 9955 } else { 9956 includedUsers = new HashSet<>(); 9957 } 9958 includedUsers.add(Integer.valueOf(userId)); 9959 9960 for (int i = 0; i < recentsCount && maxNum > 0; i++) { 9961 TaskRecord tr = mRecentTasks.get(i); 9962 // Only add calling user or related users recent tasks 9963 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 9964 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr); 9965 continue; 9966 } 9967 9968 if (tr.realActivitySuspended) { 9969 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr); 9970 continue; 9971 } 9972 9973 // Return the entry if desired by the caller. We always return 9974 // the first entry, because callers always expect this to be the 9975 // foreground app. We may filter others if the caller has 9976 // not supplied RECENT_WITH_EXCLUDED and there is some reason 9977 // we should exclude the entry. 9978 9979 if (i == 0 9980 || withExcluded 9981 || (tr.intent == null) 9982 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 9983 == 0)) { 9984 if (!allowed) { 9985 // If the caller doesn't have the GET_TASKS permission, then only 9986 // allow them to see a small subset of tasks -- their own and home. 9987 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 9988 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr); 9989 continue; 9990 } 9991 } 9992 final ActivityStack stack = tr.getStack(); 9993 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) { 9994 if (stack != null && stack.isHomeOrRecentsStack()) { 9995 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 9996 "Skipping, home or recents stack task: " + tr); 9997 continue; 9998 } 9999 } 10000 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) { 10001 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) { 10002 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 10003 "Skipping, top task in docked stack: " + tr); 10004 continue; 10005 } 10006 } 10007 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) { 10008 if (stack != null && stack.isPinnedStack()) { 10009 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 10010 "Skipping, pinned stack task: " + tr); 10011 continue; 10012 } 10013 } 10014 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 10015 // Don't include auto remove tasks that are finished or finishing. 10016 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 10017 "Skipping, auto-remove without activity: " + tr); 10018 continue; 10019 } 10020 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 10021 && !tr.isAvailable) { 10022 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 10023 "Skipping, unavail real act: " + tr); 10024 continue; 10025 } 10026 10027 if (!tr.mUserSetupComplete) { 10028 // Don't include task launched while user is not done setting-up. 10029 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 10030 "Skipping, user setup not complete: " + tr); 10031 continue; 10032 } 10033 10034 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 10035 if (!detailed) { 10036 rti.baseIntent.replaceExtras((Bundle)null); 10037 } 10038 10039 res.add(rti); 10040 maxNum--; 10041 } 10042 } 10043 return new ParceledListSlice<>(res); 10044 } 10045 } 10046 10047 @Override 10048 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 10049 synchronized (this) { 10050 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 10051 "getTaskThumbnail()"); 10052 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked( 10053 id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID); 10054 if (tr != null) { 10055 return tr.getTaskThumbnailLocked(); 10056 } 10057 } 10058 return null; 10059 } 10060 10061 @Override 10062 public ActivityManager.TaskDescription getTaskDescription(int id) { 10063 synchronized (this) { 10064 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 10065 "getTaskDescription()"); 10066 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, 10067 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID); 10068 if (tr != null) { 10069 return tr.lastTaskDescription; 10070 } 10071 } 10072 return null; 10073 } 10074 10075 @Override 10076 public int addAppTask(IBinder activityToken, Intent intent, 10077 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 10078 final int callingUid = Binder.getCallingUid(); 10079 final long callingIdent = Binder.clearCallingIdentity(); 10080 10081 try { 10082 synchronized (this) { 10083 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 10084 if (r == null) { 10085 throw new IllegalArgumentException("Activity does not exist; token=" 10086 + activityToken); 10087 } 10088 ComponentName comp = intent.getComponent(); 10089 if (comp == null) { 10090 throw new IllegalArgumentException("Intent " + intent 10091 + " must specify explicit component"); 10092 } 10093 if (thumbnail.getWidth() != mThumbnailWidth 10094 || thumbnail.getHeight() != mThumbnailHeight) { 10095 throw new IllegalArgumentException("Bad thumbnail size: got " 10096 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 10097 + mThumbnailWidth + "x" + mThumbnailHeight); 10098 } 10099 if (intent.getSelector() != null) { 10100 intent.setSelector(null); 10101 } 10102 if (intent.getSourceBounds() != null) { 10103 intent.setSourceBounds(null); 10104 } 10105 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 10106 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 10107 // The caller has added this as an auto-remove task... that makes no 10108 // sense, so turn off auto-remove. 10109 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 10110 } 10111 } 10112 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 10113 mLastAddedTaskActivity = null; 10114 } 10115 ActivityInfo ainfo = mLastAddedTaskActivity; 10116 if (ainfo == null) { 10117 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 10118 comp, 0, UserHandle.getUserId(callingUid)); 10119 if (ainfo.applicationInfo.uid != callingUid) { 10120 throw new SecurityException( 10121 "Can't add task for another application: target uid=" 10122 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 10123 } 10124 } 10125 10126 TaskRecord task = new TaskRecord(this, 10127 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), 10128 ainfo, intent, description, new TaskThumbnailInfo()); 10129 10130 int trimIdx = mRecentTasks.trimForTaskLocked(task, false); 10131 if (trimIdx >= 0) { 10132 // If this would have caused a trim, then we'll abort because that 10133 // means it would be added at the end of the list but then just removed. 10134 return INVALID_TASK_ID; 10135 } 10136 10137 final int N = mRecentTasks.size(); 10138 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 10139 final TaskRecord tr = mRecentTasks.remove(N - 1); 10140 tr.removedFromRecents(); 10141 } 10142 10143 task.inRecents = true; 10144 mRecentTasks.add(task); 10145 r.getStack().addTask(task, false, "addAppTask"); 10146 10147 task.setLastThumbnailLocked(thumbnail); 10148 task.freeLastThumbnail(); 10149 return task.taskId; 10150 } 10151 } finally { 10152 Binder.restoreCallingIdentity(callingIdent); 10153 } 10154 } 10155 10156 @Override 10157 public Point getAppTaskThumbnailSize() { 10158 synchronized (this) { 10159 return new Point(mThumbnailWidth, mThumbnailHeight); 10160 } 10161 } 10162 10163 @Override 10164 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 10165 synchronized (this) { 10166 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10167 if (r != null) { 10168 r.setTaskDescription(td); 10169 final TaskRecord task = r.getTask(); 10170 task.updateTaskDescription(); 10171 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td); 10172 } 10173 } 10174 } 10175 10176 @Override 10177 public void setTaskResizeable(int taskId, int resizeableMode) { 10178 synchronized (this) { 10179 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked( 10180 taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID); 10181 if (task == null) { 10182 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found"); 10183 return; 10184 } 10185 task.setResizeMode(resizeableMode); 10186 } 10187 } 10188 10189 @Override 10190 public void resizeTask(int taskId, Rect bounds, int resizeMode) { 10191 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()"); 10192 long ident = Binder.clearCallingIdentity(); 10193 try { 10194 synchronized (this) { 10195 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10196 if (task == null) { 10197 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found"); 10198 return; 10199 } 10200 // Place the task in the right stack if it isn't there already based on 10201 // the requested bounds. 10202 // The stack transition logic is: 10203 // - a null bounds on a freeform task moves that task to fullscreen 10204 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves 10205 // that task to freeform 10206 // - otherwise the task is not moved 10207 int stackId = task.getStackId(); 10208 if (!StackId.isTaskResizeAllowed(stackId)) { 10209 throw new IllegalArgumentException("resizeTask not allowed on task=" + task); 10210 } 10211 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) { 10212 stackId = FULLSCREEN_WORKSPACE_STACK_ID; 10213 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) { 10214 stackId = FREEFORM_WORKSPACE_STACK_ID; 10215 } 10216 10217 // Reparent the task to the right stack if necessary 10218 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0; 10219 if (stackId != task.getStackId()) { 10220 // Defer resume until the task is resized below 10221 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, 10222 DEFER_RESUME, "resizeTask"); 10223 preserveWindow = false; 10224 } 10225 10226 // After reparenting (which only resizes the task to the stack bounds), resize the 10227 // task to the actual bounds provided 10228 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME); 10229 } 10230 } finally { 10231 Binder.restoreCallingIdentity(ident); 10232 } 10233 } 10234 10235 @Override 10236 public Rect getTaskBounds(int taskId) { 10237 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()"); 10238 long ident = Binder.clearCallingIdentity(); 10239 Rect rect = new Rect(); 10240 try { 10241 synchronized (this) { 10242 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, 10243 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID); 10244 if (task == null) { 10245 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found"); 10246 return rect; 10247 } 10248 if (task.getStack() != null) { 10249 // Return the bounds from window manager since it will be adjusted for various 10250 // things like the presense of a docked stack for tasks that aren't resizeable. 10251 task.getWindowContainerBounds(rect); 10252 } else { 10253 // Task isn't in window manager yet since it isn't associated with a stack. 10254 // Return the persist value from activity manager 10255 if (task.mBounds != null) { 10256 rect.set(task.mBounds); 10257 } else if (task.mLastNonFullscreenBounds != null) { 10258 rect.set(task.mLastNonFullscreenBounds); 10259 } 10260 } 10261 } 10262 } finally { 10263 Binder.restoreCallingIdentity(ident); 10264 } 10265 return rect; 10266 } 10267 10268 @Override 10269 public void cancelTaskWindowTransition(int taskId) { 10270 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()"); 10271 final long ident = Binder.clearCallingIdentity(); 10272 try { 10273 synchronized (this) { 10274 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, 10275 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID); 10276 if (task == null) { 10277 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found"); 10278 return; 10279 } 10280 task.cancelWindowTransition(); 10281 } 10282 } finally { 10283 Binder.restoreCallingIdentity(ident); 10284 } 10285 } 10286 10287 @Override 10288 public void cancelTaskThumbnailTransition(int taskId) { 10289 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()"); 10290 final long ident = Binder.clearCallingIdentity(); 10291 try { 10292 synchronized (this) { 10293 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, 10294 MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID); 10295 if (task == null) { 10296 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found"); 10297 return; 10298 } 10299 task.cancelThumbnailTransition(); 10300 } 10301 } finally { 10302 Binder.restoreCallingIdentity(ident); 10303 } 10304 } 10305 10306 @Override 10307 public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) { 10308 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()"); 10309 final long ident = Binder.clearCallingIdentity(); 10310 try { 10311 final TaskRecord task; 10312 synchronized (this) { 10313 task = mStackSupervisor.anyTaskForIdLocked(taskId, 10314 MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID); 10315 if (task == null) { 10316 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found"); 10317 return null; 10318 } 10319 } 10320 // Don't call this while holding the lock as this operation might hit the disk. 10321 return task.getSnapshot(reducedResolution); 10322 } finally { 10323 Binder.restoreCallingIdentity(ident); 10324 } 10325 } 10326 10327 @Override 10328 public Bitmap getTaskDescriptionIcon(String filePath, int userId) { 10329 if (userId != UserHandle.getCallingUserId()) { 10330 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10331 "getTaskDescriptionIcon"); 10332 } 10333 final File passedIconFile = new File(filePath); 10334 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId), 10335 passedIconFile.getName()); 10336 if (!legitIconFile.getPath().equals(filePath) 10337 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 10338 throw new IllegalArgumentException("Bad file path: " + filePath 10339 + " passed for userId " + userId); 10340 } 10341 return mRecentTasks.getTaskDescriptionIcon(filePath); 10342 } 10343 10344 @Override 10345 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) 10346 throws RemoteException { 10347 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts); 10348 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 10349 activityOptions.getCustomInPlaceResId() == 0) { 10350 throw new IllegalArgumentException("Expected in-place ActivityOption " + 10351 "with valid animation"); 10352 } 10353 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false); 10354 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(), 10355 activityOptions.getCustomInPlaceResId()); 10356 mWindowManager.executeAppTransition(); 10357 } 10358 10359 private void removeTasksByPackageNameLocked(String packageName, int userId) { 10360 // Remove all tasks with activities in the specified package from the list of recent tasks 10361 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 10362 TaskRecord tr = mRecentTasks.get(i); 10363 if (tr.userId != userId) continue; 10364 10365 ComponentName cn = tr.intent.getComponent(); 10366 if (cn != null && cn.getPackageName().equals(packageName)) { 10367 // If the package name matches, remove the task. 10368 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS); 10369 } 10370 } 10371 } 10372 10373 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses, 10374 int userId) { 10375 10376 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 10377 TaskRecord tr = mRecentTasks.get(i); 10378 if (userId != UserHandle.USER_ALL && tr.userId != userId) { 10379 continue; 10380 } 10381 10382 ComponentName cn = tr.intent.getComponent(); 10383 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName) 10384 && (filterByClasses == null || filterByClasses.contains(cn.getClassName())); 10385 if (sameComponent) { 10386 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS); 10387 } 10388 } 10389 } 10390 10391 @Override 10392 public void removeStack(int stackId) { 10393 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()"); 10394 if (StackId.isHomeOrRecentsStack(stackId)) { 10395 throw new IllegalArgumentException("Removing home or recents stack is not allowed."); 10396 } 10397 10398 synchronized (this) { 10399 final long ident = Binder.clearCallingIdentity(); 10400 try { 10401 mStackSupervisor.removeStackLocked(stackId); 10402 } finally { 10403 Binder.restoreCallingIdentity(ident); 10404 } 10405 } 10406 } 10407 10408 @Override 10409 public void moveStackToDisplay(int stackId, int displayId) { 10410 enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()"); 10411 10412 synchronized (this) { 10413 final long ident = Binder.clearCallingIdentity(); 10414 try { 10415 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId 10416 + " to displayId=" + displayId); 10417 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP); 10418 } finally { 10419 Binder.restoreCallingIdentity(ident); 10420 } 10421 } 10422 } 10423 10424 @Override 10425 public boolean removeTask(int taskId) { 10426 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()"); 10427 synchronized (this) { 10428 final long ident = Binder.clearCallingIdentity(); 10429 try { 10430 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS); 10431 } finally { 10432 Binder.restoreCallingIdentity(ident); 10433 } 10434 } 10435 } 10436 10437 /** 10438 * TODO: Add mController hook 10439 */ 10440 @Override 10441 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) { 10442 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()"); 10443 10444 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId); 10445 synchronized(this) { 10446 moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */); 10447 } 10448 } 10449 10450 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) { 10451 ActivityOptions options = ActivityOptions.fromBundle(bOptions); 10452 10453 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 10454 Binder.getCallingUid(), -1, -1, "Task to front")) { 10455 ActivityOptions.abort(options); 10456 return; 10457 } 10458 final long origId = Binder.clearCallingIdentity(); 10459 try { 10460 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10461 if (task == null) { 10462 Slog.d(TAG, "Could not find task for id: "+ taskId); 10463 return; 10464 } 10465 if (mStackSupervisor.isLockTaskModeViolation(task)) { 10466 mStackSupervisor.showLockTaskToast(); 10467 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 10468 return; 10469 } 10470 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 10471 if (prev != null) { 10472 task.setTaskToReturnTo(prev); 10473 } 10474 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront", 10475 false /* forceNonResizable */); 10476 10477 final ActivityRecord topActivity = task.getTopActivity(); 10478 if (topActivity != null) { 10479 10480 // We are reshowing a task, use a starting window to hide the initial draw delay 10481 // so the transition can start earlier. 10482 topActivity.showStartingWindow(null /* prev */, false /* newTask */, 10483 true /* taskSwitch */, fromRecents); 10484 } 10485 } finally { 10486 Binder.restoreCallingIdentity(origId); 10487 } 10488 ActivityOptions.abort(options); 10489 } 10490 10491 /** 10492 * Attempts to move a task backwards in z-order (the order of activities within the task is 10493 * unchanged). 10494 * 10495 * There are several possible results of this call: 10496 * - if the task is locked, then we will show the lock toast 10497 * - if there is a task behind the provided task, then that task is made visible and resumed as 10498 * this task is moved to the back 10499 * - otherwise, if there are no other tasks in the stack: 10500 * - if this task is in the pinned stack, then we remove the stack completely, which will 10501 * have the effect of moving the task to the top or bottom of the fullscreen stack 10502 * (depending on whether it is visible) 10503 * - otherwise, we simply return home and hide this task 10504 * 10505 * @param token A reference to the activity we wish to move 10506 * @param nonRoot If false then this only works if the activity is the root 10507 * of a task; if true it will work for any activity in a task. 10508 * @return Returns true if the move completed, false if not. 10509 */ 10510 @Override 10511 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 10512 enforceNotIsolatedCaller("moveActivityTaskToBack"); 10513 synchronized(this) { 10514 final long origId = Binder.clearCallingIdentity(); 10515 try { 10516 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 10517 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10518 if (task != null) { 10519 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId); 10520 } 10521 } finally { 10522 Binder.restoreCallingIdentity(origId); 10523 } 10524 } 10525 return false; 10526 } 10527 10528 @Override 10529 public void moveTaskBackwards(int task) { 10530 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 10531 "moveTaskBackwards()"); 10532 10533 synchronized(this) { 10534 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 10535 Binder.getCallingUid(), -1, -1, "Task backwards")) { 10536 return; 10537 } 10538 final long origId = Binder.clearCallingIdentity(); 10539 moveTaskBackwardsLocked(task); 10540 Binder.restoreCallingIdentity(origId); 10541 } 10542 } 10543 10544 private final void moveTaskBackwardsLocked(int task) { 10545 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 10546 } 10547 10548 @Override 10549 public int createStackOnDisplay(int displayId) throws RemoteException { 10550 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()"); 10551 synchronized (this) { 10552 final int stackId = mStackSupervisor.getNextStackId(); 10553 final ActivityStack stack = 10554 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/); 10555 if (stack == null) { 10556 return INVALID_STACK_ID; 10557 } 10558 return stack.mStackId; 10559 } 10560 } 10561 10562 @Override 10563 public int getActivityDisplayId(IBinder activityToken) throws RemoteException { 10564 synchronized (this) { 10565 final ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 10566 if (stack != null && stack.mDisplayId != INVALID_DISPLAY) { 10567 return stack.mDisplayId; 10568 } 10569 return DEFAULT_DISPLAY; 10570 } 10571 } 10572 10573 @Override 10574 public int getActivityStackId(IBinder token) throws RemoteException { 10575 synchronized (this) { 10576 ActivityStack stack = ActivityRecord.getStackLocked(token); 10577 if (stack == null) { 10578 return INVALID_STACK_ID; 10579 } 10580 return stack.mStackId; 10581 } 10582 } 10583 10584 @Override 10585 public void exitFreeformMode(IBinder token) throws RemoteException { 10586 synchronized (this) { 10587 long ident = Binder.clearCallingIdentity(); 10588 try { 10589 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 10590 if (r == null) { 10591 throw new IllegalArgumentException( 10592 "exitFreeformMode: No activity record matching token=" + token); 10593 } 10594 10595 final ActivityStack stack = r.getStack(); 10596 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) { 10597 throw new IllegalStateException( 10598 "exitFreeformMode: You can only go fullscreen from freeform."); 10599 } 10600 10601 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r); 10602 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, 10603 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode"); 10604 } finally { 10605 Binder.restoreCallingIdentity(ident); 10606 } 10607 } 10608 } 10609 10610 @Override 10611 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 10612 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()"); 10613 if (StackId.isHomeOrRecentsStack(stackId)) { 10614 throw new IllegalArgumentException( 10615 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId); 10616 } 10617 synchronized (this) { 10618 long ident = Binder.clearCallingIdentity(); 10619 try { 10620 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10621 if (task == null) { 10622 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId); 10623 return; 10624 } 10625 10626 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId 10627 + " to stackId=" + stackId + " toTop=" + toTop); 10628 if (stackId == DOCKED_STACK_ID) { 10629 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, 10630 null /* initialBounds */); 10631 } 10632 task.reparent(stackId, toTop, 10633 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack"); 10634 } finally { 10635 Binder.restoreCallingIdentity(ident); 10636 } 10637 } 10638 } 10639 10640 @Override 10641 public void swapDockedAndFullscreenStack() throws RemoteException { 10642 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()"); 10643 synchronized (this) { 10644 long ident = Binder.clearCallingIdentity(); 10645 try { 10646 final ActivityStack fullscreenStack = mStackSupervisor.getStack( 10647 FULLSCREEN_WORKSPACE_STACK_ID); 10648 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask() 10649 : null; 10650 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID); 10651 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks() 10652 : null; 10653 if (topTask == null || tasks == null || tasks.size() == 0) { 10654 Slog.w(TAG, 10655 "Unable to swap tasks, either docked or fullscreen stack is empty."); 10656 return; 10657 } 10658 10659 // TODO: App transition 10660 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false); 10661 10662 // Defer the resume until we move all the docked tasks to the fullscreen stack below 10663 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, 10664 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK"); 10665 final int size = tasks.size(); 10666 for (int i = 0; i < size; i++) { 10667 final int id = tasks.get(i).taskId; 10668 if (id == topTask.taskId) { 10669 continue; 10670 } 10671 10672 // Defer the resume until after all the tasks have been moved 10673 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, 10674 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME, 10675 "swapDockedAndFullscreenStack - FULLSCREEN_STACK"); 10676 } 10677 10678 // Because we deferred the resume to avoid conflicts with stack switches while 10679 // resuming, we need to do it after all the tasks are moved. 10680 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 10681 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 10682 10683 mWindowManager.executeAppTransition(); 10684 } finally { 10685 Binder.restoreCallingIdentity(ident); 10686 } 10687 } 10688 } 10689 10690 /** 10691 * Moves the input task to the docked stack. 10692 * 10693 * @param taskId Id of task to move. 10694 * @param createMode The mode the docked stack should be created in if it doesn't exist 10695 * already. See 10696 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT} 10697 * and 10698 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT} 10699 * @param toTop If the task and stack should be moved to the top. 10700 * @param animate Whether we should play an animation for the moving the task 10701 * @param initialBounds If the docked stack gets created, it will use these bounds for the 10702 * docked stack. Pass {@code null} to use default bounds. 10703 */ 10704 @Override 10705 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate, 10706 Rect initialBounds) { 10707 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()"); 10708 synchronized (this) { 10709 long ident = Binder.clearCallingIdentity(); 10710 try { 10711 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10712 if (task == null) { 10713 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId); 10714 return false; 10715 } 10716 10717 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId 10718 + " to createMode=" + createMode + " toTop=" + toTop); 10719 mWindowManager.setDockedStackCreateState(createMode, initialBounds); 10720 10721 // Defer resuming until we move the home stack to the front below 10722 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop, 10723 REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME, 10724 "moveTaskToDockedStack"); 10725 if (moved) { 10726 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 10727 } 10728 return moved; 10729 } finally { 10730 Binder.restoreCallingIdentity(ident); 10731 } 10732 } 10733 } 10734 10735 /** 10736 * Moves the top activity in the input stackId to the pinned stack. 10737 * 10738 * @param stackId Id of stack to move the top activity to pinned stack. 10739 * @param bounds Bounds to use for pinned stack. 10740 * 10741 * @return True if the top activity of the input stack was successfully moved to the pinned 10742 * stack. 10743 */ 10744 @Override 10745 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) { 10746 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()"); 10747 synchronized (this) { 10748 if (!mSupportsPictureInPicture) { 10749 throw new IllegalStateException("moveTopActivityToPinnedStack:" 10750 + "Device doesn't support picture-in-picture mode"); 10751 } 10752 10753 long ident = Binder.clearCallingIdentity(); 10754 try { 10755 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds); 10756 } finally { 10757 Binder.restoreCallingIdentity(ident); 10758 } 10759 } 10760 } 10761 10762 @Override 10763 public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode, 10764 boolean preserveWindows, boolean animate, int animationDuration) { 10765 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()"); 10766 long ident = Binder.clearCallingIdentity(); 10767 try { 10768 synchronized (this) { 10769 if (animate) { 10770 if (stackId == PINNED_STACK_ID) { 10771 final PinnedActivityStack pinnedStack = 10772 mStackSupervisor.getStack(PINNED_STACK_ID); 10773 if (pinnedStack != null) { 10774 pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */, 10775 destBounds, animationDuration, false /* fromFullscreen */); 10776 } 10777 } else { 10778 throw new IllegalArgumentException("Stack: " + stackId 10779 + " doesn't support animated resize."); 10780 } 10781 } else { 10782 mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */, 10783 null /* tempTaskInsetBounds */, preserveWindows, 10784 allowResizeInDockedMode, !DEFER_RESUME); 10785 } 10786 } 10787 } finally { 10788 Binder.restoreCallingIdentity(ident); 10789 } 10790 } 10791 10792 @Override 10793 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds, 10794 Rect tempDockedTaskInsetBounds, 10795 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) { 10796 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 10797 "resizeDockedStack()"); 10798 long ident = Binder.clearCallingIdentity(); 10799 try { 10800 synchronized (this) { 10801 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds, 10802 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds, 10803 PRESERVE_WINDOWS); 10804 } 10805 } finally { 10806 Binder.restoreCallingIdentity(ident); 10807 } 10808 } 10809 10810 @Override 10811 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) { 10812 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 10813 "resizePinnedStack()"); 10814 final long ident = Binder.clearCallingIdentity(); 10815 try { 10816 synchronized (this) { 10817 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds); 10818 } 10819 } finally { 10820 Binder.restoreCallingIdentity(ident); 10821 } 10822 } 10823 10824 /** 10825 * Try to place task to provided position. The final position might be different depending on 10826 * current user and stacks state. The task will be moved to target stack if it's currently in 10827 * different stack. 10828 */ 10829 @Override 10830 public void positionTaskInStack(int taskId, int stackId, int position) { 10831 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()"); 10832 if (StackId.isHomeOrRecentsStack(stackId)) { 10833 throw new IllegalArgumentException( 10834 "positionTaskInStack: Attempt to change the position of task " 10835 + taskId + " in/to home/recents stack"); 10836 } 10837 synchronized (this) { 10838 long ident = Binder.clearCallingIdentity(); 10839 try { 10840 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task=" 10841 + taskId + " in stackId=" + stackId + " at position=" + position); 10842 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10843 if (task == null) { 10844 throw new IllegalArgumentException("positionTaskInStack: no task for id=" 10845 + taskId); 10846 } 10847 10848 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED, 10849 !ON_TOP); 10850 10851 // TODO: Have the callers of this API call a separate reparent method if that is 10852 // what they intended to do vs. having this method also do reparenting. 10853 if (task.getStack() == stack) { 10854 // Change position in current stack. 10855 stack.positionChildAt(task, position); 10856 } else { 10857 // Reparent to new stack. 10858 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE, 10859 !ANIMATE, !DEFER_RESUME, "positionTaskInStack"); 10860 } 10861 } finally { 10862 Binder.restoreCallingIdentity(ident); 10863 } 10864 } 10865 } 10866 10867 @Override 10868 public List<StackInfo> getAllStackInfos() { 10869 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()"); 10870 long ident = Binder.clearCallingIdentity(); 10871 try { 10872 synchronized (this) { 10873 return mStackSupervisor.getAllStackInfosLocked(); 10874 } 10875 } finally { 10876 Binder.restoreCallingIdentity(ident); 10877 } 10878 } 10879 10880 @Override 10881 public StackInfo getStackInfo(int stackId) { 10882 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); 10883 long ident = Binder.clearCallingIdentity(); 10884 try { 10885 synchronized (this) { 10886 return mStackSupervisor.getStackInfoLocked(stackId); 10887 } 10888 } finally { 10889 Binder.restoreCallingIdentity(ident); 10890 } 10891 } 10892 10893 @Override 10894 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 10895 synchronized(this) { 10896 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 10897 } 10898 } 10899 10900 @Override 10901 public void updateDeviceOwner(String packageName) { 10902 final int callingUid = Binder.getCallingUid(); 10903 if (callingUid != 0 && callingUid != SYSTEM_UID) { 10904 throw new SecurityException("updateDeviceOwner called from non-system process"); 10905 } 10906 synchronized (this) { 10907 mDeviceOwnerName = packageName; 10908 } 10909 } 10910 10911 @Override 10912 public void updateLockTaskPackages(int userId, String[] packages) { 10913 final int callingUid = Binder.getCallingUid(); 10914 if (callingUid != 0 && callingUid != SYSTEM_UID) { 10915 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES, 10916 "updateLockTaskPackages()"); 10917 } 10918 synchronized (this) { 10919 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" + 10920 Arrays.toString(packages)); 10921 mLockTaskPackages.put(userId, packages); 10922 mStackSupervisor.onLockTaskPackagesUpdatedLocked(); 10923 } 10924 } 10925 10926 10927 void startLockTaskModeLocked(TaskRecord task) { 10928 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task); 10929 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { 10930 return; 10931 } 10932 10933 // When a task is locked, dismiss the pinned stack if it exists 10934 final PinnedActivityStack pinnedStack = mStackSupervisor.getStack( 10935 PINNED_STACK_ID); 10936 if (pinnedStack != null) { 10937 mStackSupervisor.removeStackLocked(PINNED_STACK_ID); 10938 } 10939 10940 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode 10941 // is initiated by system after the pinning request was shown and locked mode is initiated 10942 // by an authorized app directly 10943 final int callingUid = Binder.getCallingUid(); 10944 boolean isSystemInitiated = callingUid == SYSTEM_UID; 10945 long ident = Binder.clearCallingIdentity(); 10946 try { 10947 if (!isSystemInitiated) { 10948 task.mLockTaskUid = callingUid; 10949 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) { 10950 // startLockTask() called by app and task mode is lockTaskModeDefault. 10951 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user"); 10952 StatusBarManagerInternal statusBarManager = 10953 LocalServices.getService(StatusBarManagerInternal.class); 10954 if (statusBarManager != null) { 10955 statusBarManager.showScreenPinningRequest(task.taskId); 10956 } 10957 return; 10958 } 10959 10960 final ActivityStack stack = mStackSupervisor.getFocusedStack(); 10961 if (stack == null || task != stack.topTask()) { 10962 throw new IllegalArgumentException("Invalid task, not in foreground"); 10963 } 10964 } 10965 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" : 10966 "Locking fully"); 10967 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ? 10968 ActivityManager.LOCK_TASK_MODE_PINNED : 10969 ActivityManager.LOCK_TASK_MODE_LOCKED, 10970 "startLockTask", true); 10971 } finally { 10972 Binder.restoreCallingIdentity(ident); 10973 } 10974 } 10975 10976 @Override 10977 public void startLockTaskModeById(int taskId) { 10978 synchronized (this) { 10979 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10980 if (task != null) { 10981 startLockTaskModeLocked(task); 10982 } 10983 } 10984 } 10985 10986 @Override 10987 public void startLockTaskModeByToken(IBinder token) { 10988 synchronized (this) { 10989 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 10990 if (r == null) { 10991 return; 10992 } 10993 final TaskRecord task = r.getTask(); 10994 if (task != null) { 10995 startLockTaskModeLocked(task); 10996 } 10997 } 10998 } 10999 11000 @Override 11001 public void startSystemLockTaskMode(int taskId) throws RemoteException { 11002 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode"); 11003 // This makes inner call to look as if it was initiated by system. 11004 long ident = Binder.clearCallingIdentity(); 11005 try { 11006 synchronized (this) { 11007 startLockTaskModeById(taskId); 11008 } 11009 } finally { 11010 Binder.restoreCallingIdentity(ident); 11011 } 11012 } 11013 11014 @Override 11015 public void stopLockTaskMode() { 11016 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked(); 11017 if (lockTask == null) { 11018 // Our work here is done. 11019 return; 11020 } 11021 11022 final int callingUid = Binder.getCallingUid(); 11023 final int lockTaskUid = lockTask.mLockTaskUid; 11024 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState(); 11025 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) { 11026 // Done. 11027 return; 11028 } else { 11029 // Ensure the same caller for startLockTaskMode and stopLockTaskMode. 11030 // It is possible lockTaskMode was started by the system process because 11031 // android:lockTaskMode is set to a locking value in the application manifest 11032 // instead of the app calling startLockTaskMode. In this case 11033 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the 11034 // {@link TaskRecord.effectiveUid} instead. Also caller with 11035 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task. 11036 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED 11037 && callingUid != lockTaskUid 11038 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) { 11039 throw new SecurityException("Invalid uid, expected " + lockTaskUid 11040 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid); 11041 } 11042 } 11043 long ident = Binder.clearCallingIdentity(); 11044 try { 11045 Log.d(TAG, "stopLockTaskMode"); 11046 // Stop lock task 11047 synchronized (this) { 11048 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE, 11049 "stopLockTask", true); 11050 } 11051 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 11052 if (tm != null) { 11053 tm.showInCallScreen(false); 11054 } 11055 } finally { 11056 Binder.restoreCallingIdentity(ident); 11057 } 11058 } 11059 11060 /** 11061 * This API should be called by SystemUI only when user perform certain action to dismiss 11062 * lock task mode. We should only dismiss pinned lock task mode in this case. 11063 */ 11064 @Override 11065 public void stopSystemLockTaskMode() throws RemoteException { 11066 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) { 11067 stopLockTaskMode(); 11068 } else { 11069 mStackSupervisor.showLockTaskToast(); 11070 } 11071 } 11072 11073 @Override 11074 public boolean isInLockTaskMode() { 11075 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE; 11076 } 11077 11078 @Override 11079 public int getLockTaskModeState() { 11080 synchronized (this) { 11081 return mStackSupervisor.getLockTaskModeState(); 11082 } 11083 } 11084 11085 @Override 11086 public void showLockTaskEscapeMessage(IBinder token) { 11087 synchronized (this) { 11088 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 11089 if (r == null) { 11090 return; 11091 } 11092 mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask()); 11093 } 11094 } 11095 11096 @Override 11097 public void setDisablePreviewScreenshots(IBinder token, boolean disable) 11098 throws RemoteException { 11099 synchronized (this) { 11100 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 11101 if (r == null) { 11102 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token=" 11103 + token); 11104 return; 11105 } 11106 final long origId = Binder.clearCallingIdentity(); 11107 try { 11108 r.setDisablePreviewScreenshots(disable); 11109 } finally { 11110 Binder.restoreCallingIdentity(origId); 11111 } 11112 } 11113 } 11114 11115 // ========================================================= 11116 // CONTENT PROVIDERS 11117 // ========================================================= 11118 11119 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 11120 List<ProviderInfo> providers = null; 11121 try { 11122 providers = AppGlobals.getPackageManager() 11123 .queryContentProviders(app.processName, app.uid, 11124 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS 11125 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null) 11126 .getList(); 11127 } catch (RemoteException ex) { 11128 } 11129 if (DEBUG_MU) Slog.v(TAG_MU, 11130 "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 11131 int userId = app.userId; 11132 if (providers != null) { 11133 int N = providers.size(); 11134 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 11135 for (int i=0; i<N; i++) { 11136 // TODO: keep logic in sync with installEncryptionUnawareProviders 11137 ProviderInfo cpi = 11138 (ProviderInfo)providers.get(i); 11139 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 11140 cpi.name, cpi.flags); 11141 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) { 11142 // This is a singleton provider, but a user besides the 11143 // default user is asking to initialize a process it runs 11144 // in... well, no, it doesn't actually run in this process, 11145 // it runs in the process of the default user. Get rid of it. 11146 providers.remove(i); 11147 N--; 11148 i--; 11149 continue; 11150 } 11151 11152 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 11153 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 11154 if (cpr == null) { 11155 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 11156 mProviderMap.putProviderByClass(comp, cpr); 11157 } 11158 if (DEBUG_MU) Slog.v(TAG_MU, 11159 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 11160 app.pubProviders.put(cpi.name, cpr); 11161 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 11162 // Don't add this if it is a platform component that is marked 11163 // to run in multiple processes, because this is actually 11164 // part of the framework so doesn't make sense to track as a 11165 // separate apk in the process. 11166 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 11167 mProcessStats); 11168 } 11169 notifyPackageUse(cpi.applicationInfo.packageName, 11170 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER); 11171 } 11172 } 11173 return providers; 11174 } 11175 11176 /** 11177 * Check if the calling UID has a possible chance at accessing the provider 11178 * at the given authority and user. 11179 */ 11180 public String checkContentProviderAccess(String authority, int userId) { 11181 if (userId == UserHandle.USER_ALL) { 11182 mContext.enforceCallingOrSelfPermission( 11183 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG); 11184 userId = UserHandle.getCallingUserId(); 11185 } 11186 11187 ProviderInfo cpi = null; 11188 try { 11189 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority, 11190 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS 11191 | PackageManager.MATCH_DISABLED_COMPONENTS 11192 | PackageManager.MATCH_DIRECT_BOOT_AWARE 11193 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 11194 userId); 11195 } catch (RemoteException ignored) { 11196 } 11197 if (cpi == null) { 11198 return "Failed to find provider " + authority + " for user " + userId 11199 + "; expected to find a valid ContentProvider for this authority"; 11200 } 11201 11202 ProcessRecord r = null; 11203 synchronized (mPidsSelfLocked) { 11204 r = mPidsSelfLocked.get(Binder.getCallingPid()); 11205 } 11206 if (r == null) { 11207 return "Failed to find PID " + Binder.getCallingPid(); 11208 } 11209 11210 synchronized (this) { 11211 return checkContentProviderPermissionLocked(cpi, r, userId, true); 11212 } 11213 } 11214 11215 /** 11216 * Check if {@link ProcessRecord} has a possible chance at accessing the 11217 * given {@link ProviderInfo}. Final permission checking is always done 11218 * in {@link ContentProvider}. 11219 */ 11220 private final String checkContentProviderPermissionLocked( 11221 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 11222 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 11223 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 11224 boolean checkedGrants = false; 11225 if (checkUser) { 11226 // Looking for cross-user grants before enforcing the typical cross-users permissions 11227 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId); 11228 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 11229 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 11230 return null; 11231 } 11232 checkedGrants = true; 11233 } 11234 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false, 11235 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null); 11236 if (userId != tmpTargetUserId) { 11237 // When we actually went to determine the final targer user ID, this ended 11238 // up different than our initial check for the authority. This is because 11239 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 11240 // SELF. So we need to re-check the grants again. 11241 checkedGrants = false; 11242 } 11243 } 11244 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 11245 cpi.applicationInfo.uid, cpi.exported) 11246 == PackageManager.PERMISSION_GRANTED) { 11247 return null; 11248 } 11249 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 11250 cpi.applicationInfo.uid, cpi.exported) 11251 == PackageManager.PERMISSION_GRANTED) { 11252 return null; 11253 } 11254 11255 PathPermission[] pps = cpi.pathPermissions; 11256 if (pps != null) { 11257 int i = pps.length; 11258 while (i > 0) { 11259 i--; 11260 PathPermission pp = pps[i]; 11261 String pprperm = pp.getReadPermission(); 11262 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 11263 cpi.applicationInfo.uid, cpi.exported) 11264 == PackageManager.PERMISSION_GRANTED) { 11265 return null; 11266 } 11267 String ppwperm = pp.getWritePermission(); 11268 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 11269 cpi.applicationInfo.uid, cpi.exported) 11270 == PackageManager.PERMISSION_GRANTED) { 11271 return null; 11272 } 11273 } 11274 } 11275 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 11276 return null; 11277 } 11278 11279 final String suffix; 11280 if (!cpi.exported) { 11281 suffix = " that is not exported from UID " + cpi.applicationInfo.uid; 11282 } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) { 11283 suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs"; 11284 } else { 11285 suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission; 11286 } 11287 final String msg = "Permission Denial: opening provider " + cpi.name 11288 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 11289 + ", uid=" + callingUid + ")" + suffix; 11290 Slog.w(TAG, msg); 11291 return msg; 11292 } 11293 11294 /** 11295 * Returns if the ContentProvider has granted a uri to callingUid 11296 */ 11297 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 11298 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 11299 if (perms != null) { 11300 for (int i=perms.size()-1; i>=0; i--) { 11301 GrantUri grantUri = perms.keyAt(i); 11302 if (grantUri.sourceUserId == userId || !checkUser) { 11303 if (matchesProvider(grantUri.uri, cpi)) { 11304 return true; 11305 } 11306 } 11307 } 11308 } 11309 return false; 11310 } 11311 11312 /** 11313 * Returns true if the uri authority is one of the authorities specified in the provider. 11314 */ 11315 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 11316 String uriAuth = uri.getAuthority(); 11317 String cpiAuth = cpi.authority; 11318 if (cpiAuth.indexOf(';') == -1) { 11319 return cpiAuth.equals(uriAuth); 11320 } 11321 String[] cpiAuths = cpiAuth.split(";"); 11322 int length = cpiAuths.length; 11323 for (int i = 0; i < length; i++) { 11324 if (cpiAuths[i].equals(uriAuth)) return true; 11325 } 11326 return false; 11327 } 11328 11329 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 11330 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 11331 if (r != null) { 11332 for (int i=0; i<r.conProviders.size(); i++) { 11333 ContentProviderConnection conn = r.conProviders.get(i); 11334 if (conn.provider == cpr) { 11335 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER, 11336 "Adding provider requested by " 11337 + r.processName + " from process " 11338 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 11339 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 11340 if (stable) { 11341 conn.stableCount++; 11342 conn.numStableIncs++; 11343 } else { 11344 conn.unstableCount++; 11345 conn.numUnstableIncs++; 11346 } 11347 return conn; 11348 } 11349 } 11350 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 11351 if (stable) { 11352 conn.stableCount = 1; 11353 conn.numStableIncs = 1; 11354 } else { 11355 conn.unstableCount = 1; 11356 conn.numUnstableIncs = 1; 11357 } 11358 cpr.connections.add(conn); 11359 r.conProviders.add(conn); 11360 startAssociationLocked(r.uid, r.processName, r.curProcState, 11361 cpr.uid, cpr.name, cpr.info.processName); 11362 return conn; 11363 } 11364 cpr.addExternalProcessHandleLocked(externalProcessToken); 11365 return null; 11366 } 11367 11368 boolean decProviderCountLocked(ContentProviderConnection conn, 11369 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 11370 if (conn != null) { 11371 cpr = conn.provider; 11372 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER, 11373 "Removing provider requested by " 11374 + conn.client.processName + " from process " 11375 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 11376 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 11377 if (stable) { 11378 conn.stableCount--; 11379 } else { 11380 conn.unstableCount--; 11381 } 11382 if (conn.stableCount == 0 && conn.unstableCount == 0) { 11383 cpr.connections.remove(conn); 11384 conn.client.conProviders.remove(conn); 11385 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 11386 // The client is more important than last activity -- note the time this 11387 // is happening, so we keep the old provider process around a bit as last 11388 // activity to avoid thrashing it. 11389 if (cpr.proc != null) { 11390 cpr.proc.lastProviderTime = SystemClock.uptimeMillis(); 11391 } 11392 } 11393 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name); 11394 return true; 11395 } 11396 return false; 11397 } 11398 cpr.removeExternalProcessHandleLocked(externalProcessToken); 11399 return false; 11400 } 11401 11402 private void checkTime(long startTime, String where) { 11403 long now = SystemClock.uptimeMillis(); 11404 if ((now-startTime) > 50) { 11405 // If we are taking more than 50ms, log about it. 11406 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 11407 } 11408 } 11409 11410 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] { 11411 PROC_SPACE_TERM, 11412 PROC_SPACE_TERM|PROC_PARENS, 11413 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state 11414 }; 11415 11416 private final long[] mProcessStateStatsLongs = new long[1]; 11417 11418 boolean isProcessAliveLocked(ProcessRecord proc) { 11419 if (proc.procStatFile == null) { 11420 proc.procStatFile = "/proc/" + proc.pid + "/stat"; 11421 } 11422 mProcessStateStatsLongs[0] = 0; 11423 if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null, 11424 mProcessStateStatsLongs, null)) { 11425 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile); 11426 return false; 11427 } 11428 final long state = mProcessStateStatsLongs[0]; 11429 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": " 11430 + (char)state); 11431 return state != 'Z' && state != 'X' && state != 'x' && state != 'K'; 11432 } 11433 11434 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 11435 String name, IBinder token, boolean stable, int userId) { 11436 ContentProviderRecord cpr; 11437 ContentProviderConnection conn = null; 11438 ProviderInfo cpi = null; 11439 11440 synchronized(this) { 11441 long startTime = SystemClock.uptimeMillis(); 11442 11443 ProcessRecord r = null; 11444 if (caller != null) { 11445 r = getRecordForAppLocked(caller); 11446 if (r == null) { 11447 throw new SecurityException( 11448 "Unable to find app for caller " + caller 11449 + " (pid=" + Binder.getCallingPid() 11450 + ") when getting content provider " + name); 11451 } 11452 } 11453 11454 boolean checkCrossUser = true; 11455 11456 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 11457 11458 // First check if this content provider has been published... 11459 cpr = mProviderMap.getProviderByName(name, userId); 11460 // If that didn't work, check if it exists for user 0 and then 11461 // verify that it's a singleton provider before using it. 11462 if (cpr == null && userId != UserHandle.USER_SYSTEM) { 11463 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM); 11464 if (cpr != null) { 11465 cpi = cpr.info; 11466 if (isSingleton(cpi.processName, cpi.applicationInfo, 11467 cpi.name, cpi.flags) 11468 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 11469 userId = UserHandle.USER_SYSTEM; 11470 checkCrossUser = false; 11471 } else { 11472 cpr = null; 11473 cpi = null; 11474 } 11475 } 11476 } 11477 11478 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed; 11479 if (providerRunning) { 11480 cpi = cpr.info; 11481 String msg; 11482 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 11483 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 11484 != null) { 11485 throw new SecurityException(msg); 11486 } 11487 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 11488 11489 if (r != null && cpr.canRunHere(r)) { 11490 // This provider has been published or is in the process 11491 // of being published... but it is also allowed to run 11492 // in the caller's process, so don't make a connection 11493 // and just let the caller instantiate its own instance. 11494 ContentProviderHolder holder = cpr.newHolder(null); 11495 // don't give caller the provider object, it needs 11496 // to make its own. 11497 holder.provider = null; 11498 return holder; 11499 } 11500 // Don't expose providers between normal apps and instant apps 11501 try { 11502 if (AppGlobals.getPackageManager() 11503 .resolveContentProvider(name, 0 /*flags*/, userId) == null) { 11504 return null; 11505 } 11506 } catch (RemoteException e) { 11507 } 11508 11509 final long origId = Binder.clearCallingIdentity(); 11510 11511 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 11512 11513 // In this case the provider instance already exists, so we can 11514 // return it right away. 11515 conn = incProviderCountLocked(r, cpr, token, stable); 11516 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 11517 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 11518 // If this is a perceptible app accessing the provider, 11519 // make sure to count it as being accessed and thus 11520 // back up on the LRU list. This is good because 11521 // content providers are often expensive to start. 11522 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 11523 updateLruProcessLocked(cpr.proc, false, null); 11524 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 11525 } 11526 } 11527 11528 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 11529 final int verifiedAdj = cpr.proc.verifiedAdj; 11530 boolean success = updateOomAdjLocked(cpr.proc, true); 11531 // XXX things have changed so updateOomAdjLocked doesn't actually tell us 11532 // if the process has been successfully adjusted. So to reduce races with 11533 // it, we will check whether the process still exists. Note that this doesn't 11534 // completely get rid of races with LMK killing the process, but should make 11535 // them much smaller. 11536 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) { 11537 success = false; 11538 } 11539 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name); 11540 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 11541 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success); 11542 // NOTE: there is still a race here where a signal could be 11543 // pending on the process even though we managed to update its 11544 // adj level. Not sure what to do about this, but at least 11545 // the race is now smaller. 11546 if (!success) { 11547 // Uh oh... it looks like the provider's process 11548 // has been killed on us. We need to wait for a new 11549 // process to be started, and make sure its death 11550 // doesn't kill our process. 11551 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString() 11552 + " is crashing; detaching " + r); 11553 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 11554 checkTime(startTime, "getContentProviderImpl: before appDied"); 11555 appDiedLocked(cpr.proc); 11556 checkTime(startTime, "getContentProviderImpl: after appDied"); 11557 if (!lastRef) { 11558 // This wasn't the last ref our process had on 11559 // the provider... we have now been killed, bail. 11560 return null; 11561 } 11562 providerRunning = false; 11563 conn = null; 11564 } else { 11565 cpr.proc.verifiedAdj = cpr.proc.setAdj; 11566 } 11567 11568 Binder.restoreCallingIdentity(origId); 11569 } 11570 11571 if (!providerRunning) { 11572 try { 11573 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 11574 cpi = AppGlobals.getPackageManager(). 11575 resolveContentProvider(name, 11576 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 11577 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 11578 } catch (RemoteException ex) { 11579 } 11580 if (cpi == null) { 11581 return null; 11582 } 11583 // If the provider is a singleton AND 11584 // (it's a call within the same user || the provider is a 11585 // privileged app) 11586 // Then allow connecting to the singleton provider 11587 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 11588 cpi.name, cpi.flags) 11589 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 11590 if (singleton) { 11591 userId = UserHandle.USER_SYSTEM; 11592 } 11593 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 11594 checkTime(startTime, "getContentProviderImpl: got app info for user"); 11595 11596 String msg; 11597 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 11598 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 11599 != null) { 11600 throw new SecurityException(msg); 11601 } 11602 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 11603 11604 if (!mProcessesReady 11605 && !cpi.processName.equals("system")) { 11606 // If this content provider does not run in the system 11607 // process, and the system is not yet ready to run other 11608 // processes, then fail fast instead of hanging. 11609 throw new IllegalArgumentException( 11610 "Attempt to launch content provider before system ready"); 11611 } 11612 11613 // Make sure that the user who owns this provider is running. If not, 11614 // we don't want to allow it to run. 11615 if (!mUserController.isUserRunningLocked(userId, 0)) { 11616 Slog.w(TAG, "Unable to launch app " 11617 + cpi.applicationInfo.packageName + "/" 11618 + cpi.applicationInfo.uid + " for provider " 11619 + name + ": user " + userId + " is stopped"); 11620 return null; 11621 } 11622 11623 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 11624 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 11625 cpr = mProviderMap.getProviderByClass(comp, userId); 11626 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 11627 final boolean firstClass = cpr == null; 11628 if (firstClass) { 11629 final long ident = Binder.clearCallingIdentity(); 11630 11631 // If permissions need a review before any of the app components can run, 11632 // we return no provider and launch a review activity if the calling app 11633 // is in the foreground. 11634 if (mPermissionReviewRequired) { 11635 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) { 11636 return null; 11637 } 11638 } 11639 11640 try { 11641 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 11642 ApplicationInfo ai = 11643 AppGlobals.getPackageManager(). 11644 getApplicationInfo( 11645 cpi.applicationInfo.packageName, 11646 STOCK_PM_FLAGS, userId); 11647 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 11648 if (ai == null) { 11649 Slog.w(TAG, "No package info for content provider " 11650 + cpi.name); 11651 return null; 11652 } 11653 ai = getAppInfoForUser(ai, userId); 11654 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 11655 } catch (RemoteException ex) { 11656 // pm is in same process, this will never happen. 11657 } finally { 11658 Binder.restoreCallingIdentity(ident); 11659 } 11660 } 11661 11662 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 11663 11664 if (r != null && cpr.canRunHere(r)) { 11665 // If this is a multiprocess provider, then just return its 11666 // info and allow the caller to instantiate it. Only do 11667 // this if the provider is the same user as the caller's 11668 // process, or can run as root (so can be in any process). 11669 return cpr.newHolder(null); 11670 } 11671 11672 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid " 11673 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): " 11674 + cpr.info.name + " callers=" + Debug.getCallers(6)); 11675 11676 // This is single process, and our app is now connecting to it. 11677 // See if we are already in the process of launching this 11678 // provider. 11679 final int N = mLaunchingProviders.size(); 11680 int i; 11681 for (i = 0; i < N; i++) { 11682 if (mLaunchingProviders.get(i) == cpr) { 11683 break; 11684 } 11685 } 11686 11687 // If the provider is not already being launched, then get it 11688 // started. 11689 if (i >= N) { 11690 final long origId = Binder.clearCallingIdentity(); 11691 11692 try { 11693 // Content provider is now in use, its package can't be stopped. 11694 try { 11695 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 11696 AppGlobals.getPackageManager().setPackageStoppedState( 11697 cpr.appInfo.packageName, false, userId); 11698 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 11699 } catch (RemoteException e) { 11700 } catch (IllegalArgumentException e) { 11701 Slog.w(TAG, "Failed trying to unstop package " 11702 + cpr.appInfo.packageName + ": " + e); 11703 } 11704 11705 // Use existing process if already started 11706 checkTime(startTime, "getContentProviderImpl: looking for process record"); 11707 ProcessRecord proc = getProcessRecordLocked( 11708 cpi.processName, cpr.appInfo.uid, false); 11709 if (proc != null && proc.thread != null && !proc.killed) { 11710 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER, 11711 "Installing in existing process " + proc); 11712 if (!proc.pubProviders.containsKey(cpi.name)) { 11713 checkTime(startTime, "getContentProviderImpl: scheduling install"); 11714 proc.pubProviders.put(cpi.name, cpr); 11715 try { 11716 proc.thread.scheduleInstallProvider(cpi); 11717 } catch (RemoteException e) { 11718 } 11719 } 11720 } else { 11721 checkTime(startTime, "getContentProviderImpl: before start process"); 11722 proc = startProcessLocked(cpi.processName, 11723 cpr.appInfo, false, 0, "content provider", 11724 new ComponentName(cpi.applicationInfo.packageName, 11725 cpi.name), false, false, false); 11726 checkTime(startTime, "getContentProviderImpl: after start process"); 11727 if (proc == null) { 11728 Slog.w(TAG, "Unable to launch app " 11729 + cpi.applicationInfo.packageName + "/" 11730 + cpi.applicationInfo.uid + " for provider " 11731 + name + ": process is bad"); 11732 return null; 11733 } 11734 } 11735 cpr.launchingApp = proc; 11736 mLaunchingProviders.add(cpr); 11737 } finally { 11738 Binder.restoreCallingIdentity(origId); 11739 } 11740 } 11741 11742 checkTime(startTime, "getContentProviderImpl: updating data structures"); 11743 11744 // Make sure the provider is published (the same provider class 11745 // may be published under multiple names). 11746 if (firstClass) { 11747 mProviderMap.putProviderByClass(comp, cpr); 11748 } 11749 11750 mProviderMap.putProviderByName(name, cpr); 11751 conn = incProviderCountLocked(r, cpr, token, stable); 11752 if (conn != null) { 11753 conn.waiting = true; 11754 } 11755 } 11756 checkTime(startTime, "getContentProviderImpl: done!"); 11757 11758 grantEphemeralAccessLocked(userId, null /*intent*/, 11759 cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid())); 11760 } 11761 11762 // Wait for the provider to be published... 11763 synchronized (cpr) { 11764 while (cpr.provider == null) { 11765 if (cpr.launchingApp == null) { 11766 Slog.w(TAG, "Unable to launch app " 11767 + cpi.applicationInfo.packageName + "/" 11768 + cpi.applicationInfo.uid + " for provider " 11769 + name + ": launching app became null"); 11770 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 11771 UserHandle.getUserId(cpi.applicationInfo.uid), 11772 cpi.applicationInfo.packageName, 11773 cpi.applicationInfo.uid, name); 11774 return null; 11775 } 11776 try { 11777 if (DEBUG_MU) Slog.v(TAG_MU, 11778 "Waiting to start provider " + cpr 11779 + " launchingApp=" + cpr.launchingApp); 11780 if (conn != null) { 11781 conn.waiting = true; 11782 } 11783 cpr.wait(); 11784 } catch (InterruptedException ex) { 11785 } finally { 11786 if (conn != null) { 11787 conn.waiting = false; 11788 } 11789 } 11790 } 11791 } 11792 return cpr != null ? cpr.newHolder(conn) : null; 11793 } 11794 11795 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi, 11796 ProcessRecord r, final int userId) { 11797 if (getPackageManagerInternalLocked().isPermissionsReviewRequired( 11798 cpi.packageName, userId)) { 11799 11800 final boolean callerForeground = r == null || r.setSchedGroup 11801 != ProcessList.SCHED_GROUP_BACKGROUND; 11802 11803 // Show a permission review UI only for starting from a foreground app 11804 if (!callerForeground) { 11805 Slog.w(TAG, "u" + userId + " Instantiating a provider in package" 11806 + cpi.packageName + " requires a permissions review"); 11807 return false; 11808 } 11809 11810 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS); 11811 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 11812 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 11813 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName); 11814 11815 if (DEBUG_PERMISSIONS_REVIEW) { 11816 Slog.i(TAG, "u" + userId + " Launching permission review " 11817 + "for package " + cpi.packageName); 11818 } 11819 11820 final UserHandle userHandle = new UserHandle(userId); 11821 mHandler.post(new Runnable() { 11822 @Override 11823 public void run() { 11824 mContext.startActivityAsUser(intent, userHandle); 11825 } 11826 }); 11827 11828 return false; 11829 } 11830 11831 return true; 11832 } 11833 11834 PackageManagerInternal getPackageManagerInternalLocked() { 11835 if (mPackageManagerInt == null) { 11836 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class); 11837 } 11838 return mPackageManagerInt; 11839 } 11840 11841 @Override 11842 public final ContentProviderHolder getContentProvider( 11843 IApplicationThread caller, String name, int userId, boolean stable) { 11844 enforceNotIsolatedCaller("getContentProvider"); 11845 if (caller == null) { 11846 String msg = "null IApplicationThread when getting content provider " 11847 + name; 11848 Slog.w(TAG, msg); 11849 throw new SecurityException(msg); 11850 } 11851 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 11852 // with cross-user grant. 11853 return getContentProviderImpl(caller, name, null, stable, userId); 11854 } 11855 11856 public ContentProviderHolder getContentProviderExternal( 11857 String name, int userId, IBinder token) { 11858 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 11859 "Do not have permission in call getContentProviderExternal()"); 11860 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 11861 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null); 11862 return getContentProviderExternalUnchecked(name, token, userId); 11863 } 11864 11865 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 11866 IBinder token, int userId) { 11867 return getContentProviderImpl(null, name, token, true, userId); 11868 } 11869 11870 /** 11871 * Drop a content provider from a ProcessRecord's bookkeeping 11872 */ 11873 public void removeContentProvider(IBinder connection, boolean stable) { 11874 enforceNotIsolatedCaller("removeContentProvider"); 11875 long ident = Binder.clearCallingIdentity(); 11876 try { 11877 synchronized (this) { 11878 ContentProviderConnection conn; 11879 try { 11880 conn = (ContentProviderConnection)connection; 11881 } catch (ClassCastException e) { 11882 String msg ="removeContentProvider: " + connection 11883 + " not a ContentProviderConnection"; 11884 Slog.w(TAG, msg); 11885 throw new IllegalArgumentException(msg); 11886 } 11887 if (conn == null) { 11888 throw new NullPointerException("connection is null"); 11889 } 11890 if (decProviderCountLocked(conn, null, null, stable)) { 11891 updateOomAdjLocked(); 11892 } 11893 } 11894 } finally { 11895 Binder.restoreCallingIdentity(ident); 11896 } 11897 } 11898 11899 public void removeContentProviderExternal(String name, IBinder token) { 11900 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 11901 "Do not have permission in call removeContentProviderExternal()"); 11902 int userId = UserHandle.getCallingUserId(); 11903 long ident = Binder.clearCallingIdentity(); 11904 try { 11905 removeContentProviderExternalUnchecked(name, token, userId); 11906 } finally { 11907 Binder.restoreCallingIdentity(ident); 11908 } 11909 } 11910 11911 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 11912 synchronized (this) { 11913 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 11914 if(cpr == null) { 11915 //remove from mProvidersByClass 11916 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list"); 11917 return; 11918 } 11919 11920 //update content provider record entry info 11921 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 11922 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 11923 if (localCpr.hasExternalProcessHandles()) { 11924 if (localCpr.removeExternalProcessHandleLocked(token)) { 11925 updateOomAdjLocked(); 11926 } else { 11927 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 11928 + " with no external reference for token: " 11929 + token + "."); 11930 } 11931 } else { 11932 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 11933 + " with no external references."); 11934 } 11935 } 11936 } 11937 11938 public final void publishContentProviders(IApplicationThread caller, 11939 List<ContentProviderHolder> providers) { 11940 if (providers == null) { 11941 return; 11942 } 11943 11944 enforceNotIsolatedCaller("publishContentProviders"); 11945 synchronized (this) { 11946 final ProcessRecord r = getRecordForAppLocked(caller); 11947 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 11948 if (r == null) { 11949 throw new SecurityException( 11950 "Unable to find app for caller " + caller 11951 + " (pid=" + Binder.getCallingPid() 11952 + ") when publishing content providers"); 11953 } 11954 11955 final long origId = Binder.clearCallingIdentity(); 11956 11957 final int N = providers.size(); 11958 for (int i = 0; i < N; i++) { 11959 ContentProviderHolder src = providers.get(i); 11960 if (src == null || src.info == null || src.provider == null) { 11961 continue; 11962 } 11963 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 11964 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 11965 if (dst != null) { 11966 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 11967 mProviderMap.putProviderByClass(comp, dst); 11968 String names[] = dst.info.authority.split(";"); 11969 for (int j = 0; j < names.length; j++) { 11970 mProviderMap.putProviderByName(names[j], dst); 11971 } 11972 11973 int launchingCount = mLaunchingProviders.size(); 11974 int j; 11975 boolean wasInLaunchingProviders = false; 11976 for (j = 0; j < launchingCount; j++) { 11977 if (mLaunchingProviders.get(j) == dst) { 11978 mLaunchingProviders.remove(j); 11979 wasInLaunchingProviders = true; 11980 j--; 11981 launchingCount--; 11982 } 11983 } 11984 if (wasInLaunchingProviders) { 11985 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r); 11986 } 11987 synchronized (dst) { 11988 dst.provider = src.provider; 11989 dst.proc = r; 11990 dst.notifyAll(); 11991 } 11992 updateOomAdjLocked(r, true); 11993 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName, 11994 src.info.authority); 11995 } 11996 } 11997 11998 Binder.restoreCallingIdentity(origId); 11999 } 12000 } 12001 12002 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 12003 ContentProviderConnection conn; 12004 try { 12005 conn = (ContentProviderConnection)connection; 12006 } catch (ClassCastException e) { 12007 String msg ="refContentProvider: " + connection 12008 + " not a ContentProviderConnection"; 12009 Slog.w(TAG, msg); 12010 throw new IllegalArgumentException(msg); 12011 } 12012 if (conn == null) { 12013 throw new NullPointerException("connection is null"); 12014 } 12015 12016 synchronized (this) { 12017 if (stable > 0) { 12018 conn.numStableIncs += stable; 12019 } 12020 stable = conn.stableCount + stable; 12021 if (stable < 0) { 12022 throw new IllegalStateException("stableCount < 0: " + stable); 12023 } 12024 12025 if (unstable > 0) { 12026 conn.numUnstableIncs += unstable; 12027 } 12028 unstable = conn.unstableCount + unstable; 12029 if (unstable < 0) { 12030 throw new IllegalStateException("unstableCount < 0: " + unstable); 12031 } 12032 12033 if ((stable+unstable) <= 0) { 12034 throw new IllegalStateException("ref counts can't go to zero here: stable=" 12035 + stable + " unstable=" + unstable); 12036 } 12037 conn.stableCount = stable; 12038 conn.unstableCount = unstable; 12039 return !conn.dead; 12040 } 12041 } 12042 12043 public void unstableProviderDied(IBinder connection) { 12044 ContentProviderConnection conn; 12045 try { 12046 conn = (ContentProviderConnection)connection; 12047 } catch (ClassCastException e) { 12048 String msg ="refContentProvider: " + connection 12049 + " not a ContentProviderConnection"; 12050 Slog.w(TAG, msg); 12051 throw new IllegalArgumentException(msg); 12052 } 12053 if (conn == null) { 12054 throw new NullPointerException("connection is null"); 12055 } 12056 12057 // Safely retrieve the content provider associated with the connection. 12058 IContentProvider provider; 12059 synchronized (this) { 12060 provider = conn.provider.provider; 12061 } 12062 12063 if (provider == null) { 12064 // Um, yeah, we're way ahead of you. 12065 return; 12066 } 12067 12068 // Make sure the caller is being honest with us. 12069 if (provider.asBinder().pingBinder()) { 12070 // Er, no, still looks good to us. 12071 synchronized (this) { 12072 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 12073 + " says " + conn + " died, but we don't agree"); 12074 return; 12075 } 12076 } 12077 12078 // Well look at that! It's dead! 12079 synchronized (this) { 12080 if (conn.provider.provider != provider) { 12081 // But something changed... good enough. 12082 return; 12083 } 12084 12085 ProcessRecord proc = conn.provider.proc; 12086 if (proc == null || proc.thread == null) { 12087 // Seems like the process is already cleaned up. 12088 return; 12089 } 12090 12091 // As far as we're concerned, this is just like receiving a 12092 // death notification... just a bit prematurely. 12093 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 12094 + ") early provider death"); 12095 final long ident = Binder.clearCallingIdentity(); 12096 try { 12097 appDiedLocked(proc); 12098 } finally { 12099 Binder.restoreCallingIdentity(ident); 12100 } 12101 } 12102 } 12103 12104 @Override 12105 public void appNotRespondingViaProvider(IBinder connection) { 12106 enforceCallingPermission( 12107 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 12108 12109 final ContentProviderConnection conn = (ContentProviderConnection) connection; 12110 if (conn == null) { 12111 Slog.w(TAG, "ContentProviderConnection is null"); 12112 return; 12113 } 12114 12115 final ProcessRecord host = conn.provider.proc; 12116 if (host == null) { 12117 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 12118 return; 12119 } 12120 12121 mHandler.post(new Runnable() { 12122 @Override 12123 public void run() { 12124 mAppErrors.appNotResponding(host, null, null, false, 12125 "ContentProvider not responding"); 12126 } 12127 }); 12128 } 12129 12130 public final void installSystemProviders() { 12131 List<ProviderInfo> providers; 12132 synchronized (this) { 12133 ProcessRecord app = mProcessNames.get("system", SYSTEM_UID); 12134 providers = generateApplicationProvidersLocked(app); 12135 if (providers != null) { 12136 for (int i=providers.size()-1; i>=0; i--) { 12137 ProviderInfo pi = (ProviderInfo)providers.get(i); 12138 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 12139 Slog.w(TAG, "Not installing system proc provider " + pi.name 12140 + ": not system .apk"); 12141 providers.remove(i); 12142 } 12143 } 12144 } 12145 } 12146 if (providers != null) { 12147 mSystemThread.installSystemProviders(providers); 12148 } 12149 12150 mConstants.start(mContext.getContentResolver()); 12151 mCoreSettingsObserver = new CoreSettingsObserver(this); 12152 mFontScaleSettingObserver = new FontScaleSettingObserver(); 12153 12154 // Now that the settings provider is published we can consider sending 12155 // in a rescue party. 12156 RescueParty.onSettingsProviderPublished(mContext); 12157 12158 //mUsageStatsService.monitorPackages(); 12159 } 12160 12161 private void startPersistentApps(int matchFlags) { 12162 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return; 12163 12164 synchronized (this) { 12165 try { 12166 final List<ApplicationInfo> apps = AppGlobals.getPackageManager() 12167 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList(); 12168 for (ApplicationInfo app : apps) { 12169 if (!"android".equals(app.packageName)) { 12170 addAppLocked(app, null, false, null /* ABI override */); 12171 } 12172 } 12173 } catch (RemoteException ex) { 12174 } 12175 } 12176 } 12177 12178 /** 12179 * When a user is unlocked, we need to install encryption-unaware providers 12180 * belonging to any running apps. 12181 */ 12182 private void installEncryptionUnawareProviders(int userId) { 12183 // We're only interested in providers that are encryption unaware, and 12184 // we don't care about uninstalled apps, since there's no way they're 12185 // running at this point. 12186 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE; 12187 12188 synchronized (this) { 12189 final int NP = mProcessNames.getMap().size(); 12190 for (int ip = 0; ip < NP; ip++) { 12191 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 12192 final int NA = apps.size(); 12193 for (int ia = 0; ia < NA; ia++) { 12194 final ProcessRecord app = apps.valueAt(ia); 12195 if (app.userId != userId || app.thread == null || app.unlocked) continue; 12196 12197 final int NG = app.pkgList.size(); 12198 for (int ig = 0; ig < NG; ig++) { 12199 try { 12200 final String pkgName = app.pkgList.keyAt(ig); 12201 final PackageInfo pkgInfo = AppGlobals.getPackageManager() 12202 .getPackageInfo(pkgName, matchFlags, userId); 12203 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) { 12204 for (ProviderInfo pi : pkgInfo.providers) { 12205 // TODO: keep in sync with generateApplicationProvidersLocked 12206 final boolean processMatch = Objects.equals(pi.processName, 12207 app.processName) || pi.multiprocess; 12208 final boolean userMatch = isSingleton(pi.processName, 12209 pi.applicationInfo, pi.name, pi.flags) 12210 ? (app.userId == UserHandle.USER_SYSTEM) : true; 12211 if (processMatch && userMatch) { 12212 Log.v(TAG, "Installing " + pi); 12213 app.thread.scheduleInstallProvider(pi); 12214 } else { 12215 Log.v(TAG, "Skipping " + pi); 12216 } 12217 } 12218 } 12219 } catch (RemoteException ignored) { 12220 } 12221 } 12222 } 12223 } 12224 } 12225 } 12226 12227 /** 12228 * Allows apps to retrieve the MIME type of a URI. 12229 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 12230 * users, then it does not need permission to access the ContentProvider. 12231 * Either, it needs cross-user uri grants. 12232 * 12233 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 12234 * 12235 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 12236 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 12237 */ 12238 public String getProviderMimeType(Uri uri, int userId) { 12239 enforceNotIsolatedCaller("getProviderMimeType"); 12240 final String name = uri.getAuthority(); 12241 int callingUid = Binder.getCallingUid(); 12242 int callingPid = Binder.getCallingPid(); 12243 long ident = 0; 12244 boolean clearedIdentity = false; 12245 synchronized (this) { 12246 userId = mUserController.unsafeConvertIncomingUserLocked(userId); 12247 } 12248 if (canClearIdentity(callingPid, callingUid, userId)) { 12249 clearedIdentity = true; 12250 ident = Binder.clearCallingIdentity(); 12251 } 12252 ContentProviderHolder holder = null; 12253 try { 12254 holder = getContentProviderExternalUnchecked(name, null, userId); 12255 if (holder != null) { 12256 return holder.provider.getType(uri); 12257 } 12258 } catch (RemoteException e) { 12259 Log.w(TAG, "Content provider dead retrieving " + uri, e); 12260 return null; 12261 } catch (Exception e) { 12262 Log.w(TAG, "Exception while determining type of " + uri, e); 12263 return null; 12264 } finally { 12265 // We need to clear the identity to call removeContentProviderExternalUnchecked 12266 if (!clearedIdentity) { 12267 ident = Binder.clearCallingIdentity(); 12268 } 12269 try { 12270 if (holder != null) { 12271 removeContentProviderExternalUnchecked(name, null, userId); 12272 } 12273 } finally { 12274 Binder.restoreCallingIdentity(ident); 12275 } 12276 } 12277 12278 return null; 12279 } 12280 12281 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 12282 if (UserHandle.getUserId(callingUid) == userId) { 12283 return true; 12284 } 12285 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 12286 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 12287 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 12288 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 12289 return true; 12290 } 12291 return false; 12292 } 12293 12294 // ========================================================= 12295 // GLOBAL MANAGEMENT 12296 // ========================================================= 12297 12298 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 12299 boolean isolated, int isolatedUid) { 12300 String proc = customProcess != null ? customProcess : info.processName; 12301 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12302 final int userId = UserHandle.getUserId(info.uid); 12303 int uid = info.uid; 12304 if (isolated) { 12305 if (isolatedUid == 0) { 12306 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1; 12307 while (true) { 12308 if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID 12309 || mNextIsolatedProcessUid > LAST_ISOLATED_UID) { 12310 mNextIsolatedProcessUid = FIRST_ISOLATED_UID; 12311 } 12312 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 12313 mNextIsolatedProcessUid++; 12314 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 12315 // No process for this uid, use it. 12316 break; 12317 } 12318 stepsLeft--; 12319 if (stepsLeft <= 0) { 12320 return null; 12321 } 12322 } 12323 } else { 12324 // Special case for startIsolatedProcess (internal only), where 12325 // the uid of the isolated process is specified by the caller. 12326 uid = isolatedUid; 12327 } 12328 getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid); 12329 12330 // Register the isolated UID with this application so BatteryStats knows to 12331 // attribute resource usage to the application. 12332 // 12333 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats 12334 // about the process state of the isolated UID *before* it is registered with the 12335 // owning application. 12336 mBatteryStatsService.addIsolatedUid(uid, info.uid); 12337 } 12338 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid); 12339 if (!mBooted && !mBooting 12340 && userId == UserHandle.USER_SYSTEM 12341 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { 12342 r.persistent = true; 12343 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 12344 } 12345 addProcessNameLocked(r); 12346 return r; 12347 } 12348 12349 private boolean uidOnBackgroundWhitelist(final int uid) { 12350 final int appId = UserHandle.getAppId(uid); 12351 final int[] whitelist = mBackgroundAppIdWhitelist; 12352 final int N = whitelist.length; 12353 for (int i = 0; i < N; i++) { 12354 if (appId == whitelist[i]) { 12355 return true; 12356 } 12357 } 12358 return false; 12359 } 12360 12361 @Override 12362 public void backgroundWhitelistUid(final int uid) { 12363 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 12364 throw new SecurityException("Only the OS may call backgroundWhitelistUid()"); 12365 } 12366 12367 if (DEBUG_BACKGROUND_CHECK) { 12368 Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist"); 12369 } 12370 synchronized (this) { 12371 final int N = mBackgroundAppIdWhitelist.length; 12372 int[] newList = new int[N+1]; 12373 System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N); 12374 newList[N] = UserHandle.getAppId(uid); 12375 mBackgroundAppIdWhitelist = newList; 12376 } 12377 } 12378 12379 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated, 12380 String abiOverride) { 12381 ProcessRecord app; 12382 if (!isolated) { 12383 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName, 12384 info.uid, true); 12385 } else { 12386 app = null; 12387 } 12388 12389 if (app == null) { 12390 app = newProcessRecordLocked(info, customProcess, isolated, 0); 12391 updateLruProcessLocked(app, false, null); 12392 updateOomAdjLocked(); 12393 } 12394 12395 // This package really, really can not be stopped. 12396 try { 12397 AppGlobals.getPackageManager().setPackageStoppedState( 12398 info.packageName, false, UserHandle.getUserId(app.uid)); 12399 } catch (RemoteException e) { 12400 } catch (IllegalArgumentException e) { 12401 Slog.w(TAG, "Failed trying to unstop package " 12402 + info.packageName + ": " + e); 12403 } 12404 12405 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { 12406 app.persistent = true; 12407 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 12408 } 12409 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 12410 mPersistentStartingProcesses.add(app); 12411 startProcessLocked(app, "added application", 12412 customProcess != null ? customProcess : app.processName, abiOverride, 12413 null /* entryPoint */, null /* entryPointArgs */); 12414 } 12415 12416 return app; 12417 } 12418 12419 public void unhandledBack() { 12420 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 12421 "unhandledBack()"); 12422 12423 synchronized(this) { 12424 final long origId = Binder.clearCallingIdentity(); 12425 try { 12426 getFocusedStack().unhandledBackLocked(); 12427 } finally { 12428 Binder.restoreCallingIdentity(origId); 12429 } 12430 } 12431 } 12432 12433 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException { 12434 enforceNotIsolatedCaller("openContentUri"); 12435 final int userId = UserHandle.getCallingUserId(); 12436 final Uri uri = Uri.parse(uriString); 12437 String name = uri.getAuthority(); 12438 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 12439 ParcelFileDescriptor pfd = null; 12440 if (cph != null) { 12441 // We record the binder invoker's uid in thread-local storage before 12442 // going to the content provider to open the file. Later, in the code 12443 // that handles all permissions checks, we look for this uid and use 12444 // that rather than the Activity Manager's own uid. The effect is that 12445 // we do the check against the caller's permissions even though it looks 12446 // to the content provider like the Activity Manager itself is making 12447 // the request. 12448 Binder token = new Binder(); 12449 sCallerIdentity.set(new Identity( 12450 token, Binder.getCallingPid(), Binder.getCallingUid())); 12451 try { 12452 pfd = cph.provider.openFile(null, uri, "r", null, token); 12453 } catch (FileNotFoundException e) { 12454 // do nothing; pfd will be returned null 12455 } finally { 12456 // Ensure that whatever happens, we clean up the identity state 12457 sCallerIdentity.remove(); 12458 // Ensure we're done with the provider. 12459 removeContentProviderExternalUnchecked(name, null, userId); 12460 } 12461 } else { 12462 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 12463 } 12464 return pfd; 12465 } 12466 12467 // Actually is sleeping or shutting down or whatever else in the future 12468 // is an inactive state. 12469 boolean isSleepingOrShuttingDownLocked() { 12470 return isSleepingLocked() || mShuttingDown; 12471 } 12472 12473 boolean isShuttingDownLocked() { 12474 return mShuttingDown; 12475 } 12476 12477 boolean isSleepingLocked() { 12478 return mSleeping; 12479 } 12480 12481 void onWakefulnessChanged(int wakefulness) { 12482 synchronized(this) { 12483 boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE; 12484 boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE; 12485 mWakefulness = wakefulness; 12486 12487 if (wasAwake != isAwake) { 12488 // Also update state in a special way for running foreground services UI. 12489 mServices.updateScreenStateLocked(isAwake); 12490 sendNotifyVrManagerOfSleepState(!isAwake); 12491 } 12492 } 12493 } 12494 12495 void finishRunningVoiceLocked() { 12496 if (mRunningVoice != null) { 12497 mRunningVoice = null; 12498 mVoiceWakeLock.release(); 12499 updateSleepIfNeededLocked(); 12500 } 12501 } 12502 12503 void startTimeTrackingFocusedActivityLocked() { 12504 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked(); 12505 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) { 12506 mCurAppTimeTracker.start(resumedActivity.packageName); 12507 } 12508 } 12509 12510 void updateSleepIfNeededLocked() { 12511 final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay(); 12512 final boolean wasSleeping = mSleeping; 12513 12514 if (!shouldSleep) { 12515 // If wasSleeping is true, we need to wake up activity manager state from when 12516 // we started sleeping. In either case, we need to apply the sleep tokens, which 12517 // will wake up stacks or put them to sleep as appropriate. 12518 if (wasSleeping) { 12519 mSleeping = false; 12520 startTimeTrackingFocusedActivityLocked(); 12521 mTopProcessState = ActivityManager.PROCESS_STATE_TOP; 12522 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 12523 } 12524 mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */); 12525 if (wasSleeping) { 12526 updateOomAdjLocked(); 12527 } 12528 } else if (!mSleeping && shouldSleep) { 12529 mSleeping = true; 12530 if (mCurAppTimeTracker != null) { 12531 mCurAppTimeTracker.stop(); 12532 } 12533 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING; 12534 mStackSupervisor.goingToSleepLocked(); 12535 updateOomAdjLocked(); 12536 } 12537 } 12538 12539 /** Pokes the task persister. */ 12540 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 12541 mRecentTasks.notifyTaskPersisterLocked(task, flush); 12542 } 12543 12544 /** 12545 * Notifies all listeners when the pinned stack animation starts. 12546 */ 12547 @Override 12548 public void notifyPinnedStackAnimationStarted() { 12549 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted(); 12550 } 12551 12552 /** 12553 * Notifies all listeners when the pinned stack animation ends. 12554 */ 12555 @Override 12556 public void notifyPinnedStackAnimationEnded() { 12557 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded(); 12558 } 12559 12560 @Override 12561 public void notifyCleartextNetwork(int uid, byte[] firstPacket) { 12562 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget(); 12563 } 12564 12565 @Override 12566 public boolean shutdown(int timeout) { 12567 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 12568 != PackageManager.PERMISSION_GRANTED) { 12569 throw new SecurityException("Requires permission " 12570 + android.Manifest.permission.SHUTDOWN); 12571 } 12572 12573 boolean timedout = false; 12574 12575 synchronized(this) { 12576 mShuttingDown = true; 12577 mStackSupervisor.prepareForShutdownLocked(); 12578 updateEventDispatchingLocked(); 12579 timedout = mStackSupervisor.shutdownLocked(timeout); 12580 } 12581 12582 mAppOpsService.shutdown(); 12583 if (mUsageStatsService != null) { 12584 mUsageStatsService.prepareShutdown(); 12585 } 12586 mBatteryStatsService.shutdown(); 12587 synchronized (this) { 12588 mProcessStats.shutdownLocked(); 12589 notifyTaskPersisterLocked(null, true); 12590 } 12591 12592 return timedout; 12593 } 12594 12595 public final void activitySlept(IBinder token) { 12596 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token); 12597 12598 final long origId = Binder.clearCallingIdentity(); 12599 12600 synchronized (this) { 12601 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 12602 if (r != null) { 12603 mStackSupervisor.activitySleptLocked(r); 12604 } 12605 } 12606 12607 Binder.restoreCallingIdentity(origId); 12608 } 12609 12610 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) { 12611 Slog.d(TAG, "<<< startRunningVoiceLocked()"); 12612 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid)); 12613 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) { 12614 boolean wasRunningVoice = mRunningVoice != null; 12615 mRunningVoice = session; 12616 if (!wasRunningVoice) { 12617 mVoiceWakeLock.acquire(); 12618 updateSleepIfNeededLocked(); 12619 } 12620 } 12621 } 12622 12623 private void updateEventDispatchingLocked() { 12624 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 12625 } 12626 12627 @Override 12628 public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) { 12629 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 12630 != PackageManager.PERMISSION_GRANTED) { 12631 throw new SecurityException("Requires permission " 12632 + android.Manifest.permission.DEVICE_POWER); 12633 } 12634 12635 synchronized(this) { 12636 long ident = Binder.clearCallingIdentity(); 12637 try { 12638 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing); 12639 } finally { 12640 Binder.restoreCallingIdentity(ident); 12641 } 12642 } 12643 sendNotifyVrManagerOfKeyguardState(showing); 12644 } 12645 12646 @Override 12647 public void notifyLockedProfile(@UserIdInt int userId) { 12648 try { 12649 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) { 12650 throw new SecurityException("Only privileged app can call notifyLockedProfile"); 12651 } 12652 } catch (RemoteException ex) { 12653 throw new SecurityException("Fail to check is caller a privileged app", ex); 12654 } 12655 12656 synchronized (this) { 12657 final long ident = Binder.clearCallingIdentity(); 12658 try { 12659 if (mUserController.shouldConfirmCredentials(userId)) { 12660 if (mKeyguardController.isKeyguardLocked()) { 12661 // Showing launcher to avoid user entering credential twice. 12662 final int currentUserId = mUserController.getCurrentUserIdLocked(); 12663 startHomeActivityLocked(currentUserId, "notifyLockedProfile"); 12664 } 12665 mStackSupervisor.lockAllProfileTasks(userId); 12666 } 12667 } finally { 12668 Binder.restoreCallingIdentity(ident); 12669 } 12670 } 12671 } 12672 12673 @Override 12674 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) { 12675 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent"); 12676 synchronized (this) { 12677 final long ident = Binder.clearCallingIdentity(); 12678 try { 12679 mActivityStarter.startConfirmCredentialIntent(intent, options); 12680 } finally { 12681 Binder.restoreCallingIdentity(ident); 12682 } 12683 } 12684 } 12685 12686 @Override 12687 public void stopAppSwitches() { 12688 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 12689 != PackageManager.PERMISSION_GRANTED) { 12690 throw new SecurityException("viewquires permission " 12691 + android.Manifest.permission.STOP_APP_SWITCHES); 12692 } 12693 12694 synchronized(this) { 12695 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 12696 + APP_SWITCH_DELAY_TIME; 12697 mDidAppSwitch = false; 12698 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 12699 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 12700 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 12701 } 12702 } 12703 12704 public void resumeAppSwitches() { 12705 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 12706 != PackageManager.PERMISSION_GRANTED) { 12707 throw new SecurityException("Requires permission " 12708 + android.Manifest.permission.STOP_APP_SWITCHES); 12709 } 12710 12711 synchronized(this) { 12712 // Note that we don't execute any pending app switches... we will 12713 // let those wait until either the timeout, or the next start 12714 // activity request. 12715 mAppSwitchesAllowedTime = 0; 12716 } 12717 } 12718 12719 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 12720 int callingPid, int callingUid, String name) { 12721 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 12722 return true; 12723 } 12724 12725 int perm = checkComponentPermission( 12726 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 12727 sourceUid, -1, true); 12728 if (perm == PackageManager.PERMISSION_GRANTED) { 12729 return true; 12730 } 12731 12732 // If the actual IPC caller is different from the logical source, then 12733 // also see if they are allowed to control app switches. 12734 if (callingUid != -1 && callingUid != sourceUid) { 12735 perm = checkComponentPermission( 12736 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 12737 callingUid, -1, true); 12738 if (perm == PackageManager.PERMISSION_GRANTED) { 12739 return true; 12740 } 12741 } 12742 12743 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 12744 return false; 12745 } 12746 12747 public void setDebugApp(String packageName, boolean waitForDebugger, 12748 boolean persistent) { 12749 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 12750 "setDebugApp()"); 12751 12752 long ident = Binder.clearCallingIdentity(); 12753 try { 12754 // Note that this is not really thread safe if there are multiple 12755 // callers into it at the same time, but that's not a situation we 12756 // care about. 12757 if (persistent) { 12758 final ContentResolver resolver = mContext.getContentResolver(); 12759 Settings.Global.putString( 12760 resolver, Settings.Global.DEBUG_APP, 12761 packageName); 12762 Settings.Global.putInt( 12763 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 12764 waitForDebugger ? 1 : 0); 12765 } 12766 12767 synchronized (this) { 12768 if (!persistent) { 12769 mOrigDebugApp = mDebugApp; 12770 mOrigWaitForDebugger = mWaitForDebugger; 12771 } 12772 mDebugApp = packageName; 12773 mWaitForDebugger = waitForDebugger; 12774 mDebugTransient = !persistent; 12775 if (packageName != null) { 12776 forceStopPackageLocked(packageName, -1, false, false, true, true, 12777 false, UserHandle.USER_ALL, "set debug app"); 12778 } 12779 } 12780 } finally { 12781 Binder.restoreCallingIdentity(ident); 12782 } 12783 } 12784 12785 void setTrackAllocationApp(ApplicationInfo app, String processName) { 12786 synchronized (this) { 12787 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 12788 if (!isDebuggable) { 12789 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 12790 throw new SecurityException("Process not debuggable: " + app.packageName); 12791 } 12792 } 12793 12794 mTrackAllocationApp = processName; 12795 } 12796 } 12797 12798 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 12799 synchronized (this) { 12800 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 12801 if (!isDebuggable) { 12802 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 12803 throw new SecurityException("Process not debuggable: " + app.packageName); 12804 } 12805 } 12806 mProfileApp = processName; 12807 12808 if (mProfilerInfo != null) { 12809 if (mProfilerInfo.profileFd != null) { 12810 try { 12811 mProfilerInfo.profileFd.close(); 12812 } catch (IOException e) { 12813 } 12814 } 12815 } 12816 mProfilerInfo = new ProfilerInfo(profilerInfo); 12817 mProfileType = 0; 12818 } 12819 } 12820 12821 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) { 12822 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 12823 if (!isDebuggable) { 12824 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 12825 throw new SecurityException("Process not debuggable: " + app.packageName); 12826 } 12827 } 12828 mNativeDebuggingApp = processName; 12829 } 12830 12831 @Override 12832 public void setAlwaysFinish(boolean enabled) { 12833 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 12834 "setAlwaysFinish()"); 12835 12836 long ident = Binder.clearCallingIdentity(); 12837 try { 12838 Settings.Global.putInt( 12839 mContext.getContentResolver(), 12840 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 12841 12842 synchronized (this) { 12843 mAlwaysFinishActivities = enabled; 12844 } 12845 } finally { 12846 Binder.restoreCallingIdentity(ident); 12847 } 12848 } 12849 12850 @Override 12851 public void setActivityController(IActivityController controller, boolean imAMonkey) { 12852 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 12853 "setActivityController()"); 12854 synchronized (this) { 12855 mController = controller; 12856 mControllerIsAMonkey = imAMonkey; 12857 Watchdog.getInstance().setActivityController(controller); 12858 } 12859 } 12860 12861 @Override 12862 public void setUserIsMonkey(boolean userIsMonkey) { 12863 synchronized (this) { 12864 synchronized (mPidsSelfLocked) { 12865 final int callingPid = Binder.getCallingPid(); 12866 ProcessRecord proc = mPidsSelfLocked.get(callingPid); 12867 if (proc == null) { 12868 throw new SecurityException("Unknown process: " + callingPid); 12869 } 12870 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) { 12871 throw new SecurityException("Only an instrumentation process " 12872 + "with a UiAutomation can call setUserIsMonkey"); 12873 } 12874 } 12875 mUserIsMonkey = userIsMonkey; 12876 } 12877 } 12878 12879 @Override 12880 public boolean isUserAMonkey() { 12881 synchronized (this) { 12882 // If there is a controller also implies the user is a monkey. 12883 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey)); 12884 } 12885 } 12886 12887 /** 12888 * @deprecated This method is only used by a few internal components and it will soon be 12889 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps). 12890 * No new code should be calling it. 12891 */ 12892 @Deprecated 12893 @Override 12894 public void requestBugReport(int bugreportType) { 12895 String extraOptions = null; 12896 switch (bugreportType) { 12897 case ActivityManager.BUGREPORT_OPTION_FULL: 12898 // Default options. 12899 break; 12900 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE: 12901 extraOptions = "bugreportplus"; 12902 break; 12903 case ActivityManager.BUGREPORT_OPTION_REMOTE: 12904 extraOptions = "bugreportremote"; 12905 break; 12906 case ActivityManager.BUGREPORT_OPTION_WEAR: 12907 extraOptions = "bugreportwear"; 12908 break; 12909 case ActivityManager.BUGREPORT_OPTION_TELEPHONY: 12910 extraOptions = "bugreporttelephony"; 12911 break; 12912 default: 12913 throw new IllegalArgumentException("Provided bugreport type is not correct, value: " 12914 + bugreportType); 12915 } 12916 // Always log caller, even if it does not have permission to dump. 12917 String type = extraOptions == null ? "bugreport" : extraOptions; 12918 Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid()); 12919 12920 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 12921 if (extraOptions != null) { 12922 SystemProperties.set("dumpstate.options", extraOptions); 12923 } 12924 SystemProperties.set("ctl.start", "bugreport"); 12925 } 12926 12927 /** 12928 * @deprecated This method is only used by a few internal components and it will soon be 12929 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps). 12930 * No new code should be calling it. 12931 */ 12932 @Deprecated 12933 @Override 12934 public void requestTelephonyBugReport(String shareTitle, String shareDescription) { 12935 12936 if (!TextUtils.isEmpty(shareTitle)) { 12937 if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) { 12938 String errorStr = "shareTitle should be less than " + 12939 MAX_BUGREPORT_TITLE_SIZE + " characters"; 12940 throw new IllegalArgumentException(errorStr); 12941 } else { 12942 if (!TextUtils.isEmpty(shareDescription)) { 12943 int length; 12944 try { 12945 length = shareDescription.getBytes("UTF-8").length; 12946 } catch (UnsupportedEncodingException e) { 12947 String errorStr = "shareDescription: UnsupportedEncodingException"; 12948 throw new IllegalArgumentException(errorStr); 12949 } 12950 if (length > SystemProperties.PROP_VALUE_MAX) { 12951 String errorStr = "shareTitle should be less than " + 12952 SystemProperties.PROP_VALUE_MAX + " bytes"; 12953 throw new IllegalArgumentException(errorStr); 12954 } else { 12955 SystemProperties.set("dumpstate.options.description", shareDescription); 12956 } 12957 } 12958 SystemProperties.set("dumpstate.options.title", shareTitle); 12959 } 12960 } 12961 12962 Slog.d(TAG, "Bugreport notification title " + shareTitle 12963 + " description " + shareDescription); 12964 requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY); 12965 } 12966 12967 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 12968 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 12969 } 12970 12971 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 12972 if (r != null && (r.instr != null || r.usingWrapper)) { 12973 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 12974 } 12975 return KEY_DISPATCHING_TIMEOUT; 12976 } 12977 12978 @Override 12979 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 12980 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 12981 != PackageManager.PERMISSION_GRANTED) { 12982 throw new SecurityException("Requires permission " 12983 + android.Manifest.permission.FILTER_EVENTS); 12984 } 12985 ProcessRecord proc; 12986 long timeout; 12987 synchronized (this) { 12988 synchronized (mPidsSelfLocked) { 12989 proc = mPidsSelfLocked.get(pid); 12990 } 12991 timeout = getInputDispatchingTimeoutLocked(proc); 12992 } 12993 12994 if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 12995 return -1; 12996 } 12997 12998 return timeout; 12999 } 13000 13001 /** 13002 * Handle input dispatching timeouts. 13003 * Returns whether input dispatching should be aborted or not. 13004 */ 13005 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 13006 final ActivityRecord activity, final ActivityRecord parent, 13007 final boolean aboveSystem, String reason) { 13008 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 13009 != PackageManager.PERMISSION_GRANTED) { 13010 throw new SecurityException("Requires permission " 13011 + android.Manifest.permission.FILTER_EVENTS); 13012 } 13013 13014 final String annotation; 13015 if (reason == null) { 13016 annotation = "Input dispatching timed out"; 13017 } else { 13018 annotation = "Input dispatching timed out (" + reason + ")"; 13019 } 13020 13021 if (proc != null) { 13022 synchronized (this) { 13023 if (proc.debugging) { 13024 return false; 13025 } 13026 13027 if (proc.instr != null) { 13028 Bundle info = new Bundle(); 13029 info.putString("shortMsg", "keyDispatchingTimedOut"); 13030 info.putString("longMsg", annotation); 13031 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 13032 return true; 13033 } 13034 } 13035 mHandler.post(new Runnable() { 13036 @Override 13037 public void run() { 13038 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation); 13039 } 13040 }); 13041 } 13042 13043 return true; 13044 } 13045 13046 @Override 13047 public Bundle getAssistContextExtras(int requestType) { 13048 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null, 13049 null, null, true /* focused */, true /* newSessionId */, 13050 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0); 13051 if (pae == null) { 13052 return null; 13053 } 13054 synchronized (pae) { 13055 while (!pae.haveResult) { 13056 try { 13057 pae.wait(); 13058 } catch (InterruptedException e) { 13059 } 13060 } 13061 } 13062 synchronized (this) { 13063 buildAssistBundleLocked(pae, pae.result); 13064 mPendingAssistExtras.remove(pae); 13065 mUiHandler.removeCallbacks(pae); 13066 } 13067 return pae.extras; 13068 } 13069 13070 @Override 13071 public boolean isAssistDataAllowedOnCurrentActivity() { 13072 int userId; 13073 synchronized (this) { 13074 final ActivityStack focusedStack = getFocusedStack(); 13075 if (focusedStack == null || focusedStack.isAssistantStack()) { 13076 return false; 13077 } 13078 13079 final ActivityRecord activity = focusedStack.topActivity(); 13080 if (activity == null) { 13081 return false; 13082 } 13083 userId = activity.userId; 13084 } 13085 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService( 13086 Context.DEVICE_POLICY_SERVICE); 13087 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId)); 13088 } 13089 13090 @Override 13091 public boolean showAssistFromActivity(IBinder token, Bundle args) { 13092 long ident = Binder.clearCallingIdentity(); 13093 try { 13094 synchronized (this) { 13095 ActivityRecord caller = ActivityRecord.forTokenLocked(token); 13096 ActivityRecord top = getFocusedStack().topActivity(); 13097 if (top != caller) { 13098 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller 13099 + " is not current top " + top); 13100 return false; 13101 } 13102 if (!top.nowVisible) { 13103 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller 13104 + " is not visible"); 13105 return false; 13106 } 13107 } 13108 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null, 13109 token); 13110 } finally { 13111 Binder.restoreCallingIdentity(ident); 13112 } 13113 } 13114 13115 @Override 13116 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver, 13117 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) { 13118 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras, 13119 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null, 13120 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null; 13121 } 13122 13123 @Override 13124 public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras, 13125 IBinder activityToken, int flags) { 13126 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null, 13127 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(), 13128 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null; 13129 } 13130 13131 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 13132 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, 13133 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout, 13134 int flags) { 13135 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 13136 "enqueueAssistContext()"); 13137 13138 synchronized (this) { 13139 ActivityRecord activity = getFocusedStack().topActivity(); 13140 if (activity == null) { 13141 Slog.w(TAG, "getAssistContextExtras failed: no top activity"); 13142 return null; 13143 } 13144 if (activity.app == null || activity.app.thread == null) { 13145 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 13146 return null; 13147 } 13148 if (focused) { 13149 if (activityToken != null) { 13150 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken); 13151 if (activity != caller) { 13152 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller 13153 + " is not current top " + activity); 13154 return null; 13155 } 13156 } 13157 } else { 13158 activity = ActivityRecord.forTokenLocked(activityToken); 13159 if (activity == null) { 13160 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken 13161 + " couldn't be found"); 13162 return null; 13163 } 13164 if (activity.app == null || activity.app.thread == null) { 13165 Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity); 13166 return null; 13167 } 13168 } 13169 13170 PendingAssistExtras pae; 13171 Bundle extras = new Bundle(); 13172 if (args != null) { 13173 extras.putAll(args); 13174 } 13175 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 13176 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid); 13177 13178 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras, 13179 userHandle); 13180 pae.isHome = activity.isHomeActivity(); 13181 13182 // Increment the sessionId if necessary 13183 if (newSessionId) { 13184 mViSessionId++; 13185 } 13186 try { 13187 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType, 13188 mViSessionId, flags); 13189 mPendingAssistExtras.add(pae); 13190 mUiHandler.postDelayed(pae, timeout); 13191 } catch (RemoteException e) { 13192 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 13193 return null; 13194 } 13195 return pae; 13196 } 13197 } 13198 13199 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) { 13200 IResultReceiver receiver; 13201 synchronized (this) { 13202 mPendingAssistExtras.remove(pae); 13203 receiver = pae.receiver; 13204 } 13205 if (receiver != null) { 13206 // Caller wants result sent back to them. 13207 Bundle sendBundle = new Bundle(); 13208 // At least return the receiver extras 13209 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS, 13210 pae.receiverExtras); 13211 try { 13212 pae.receiver.send(0, sendBundle); 13213 } catch (RemoteException e) { 13214 } 13215 } 13216 } 13217 13218 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) { 13219 if (result != null) { 13220 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result); 13221 } 13222 if (pae.hint != null) { 13223 pae.extras.putBoolean(pae.hint, true); 13224 } 13225 } 13226 13227 /** Called from an app when assist data is ready. */ 13228 @Override 13229 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure, 13230 AssistContent content, Uri referrer) { 13231 PendingAssistExtras pae = (PendingAssistExtras)token; 13232 synchronized (pae) { 13233 pae.result = extras; 13234 pae.structure = structure; 13235 pae.content = content; 13236 if (referrer != null) { 13237 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer); 13238 } 13239 if (structure != null) { 13240 structure.setHomeActivity(pae.isHome); 13241 } 13242 pae.haveResult = true; 13243 pae.notifyAll(); 13244 if (pae.intent == null && pae.receiver == null) { 13245 // Caller is just waiting for the result. 13246 return; 13247 } 13248 } 13249 // We are now ready to launch the assist activity. 13250 IResultReceiver sendReceiver = null; 13251 Bundle sendBundle = null; 13252 synchronized (this) { 13253 buildAssistBundleLocked(pae, extras); 13254 boolean exists = mPendingAssistExtras.remove(pae); 13255 mUiHandler.removeCallbacks(pae); 13256 if (!exists) { 13257 // Timed out. 13258 return; 13259 } 13260 if ((sendReceiver=pae.receiver) != null) { 13261 // Caller wants result sent back to them. 13262 sendBundle = new Bundle(); 13263 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras); 13264 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure); 13265 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content); 13266 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS, 13267 pae.receiverExtras); 13268 } 13269 } 13270 if (sendReceiver != null) { 13271 try { 13272 sendReceiver.send(0, sendBundle); 13273 } catch (RemoteException e) { 13274 } 13275 return; 13276 } 13277 13278 final long ident = Binder.clearCallingIdentity(); 13279 try { 13280 if (TextUtils.equals(pae.intent.getAction(), 13281 android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) { 13282 pae.intent.putExtras(pae.extras); 13283 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle)); 13284 } else { 13285 pae.intent.replaceExtras(pae.extras); 13286 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 13287 | Intent.FLAG_ACTIVITY_SINGLE_TOP 13288 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 13289 closeSystemDialogs("assist"); 13290 13291 try { 13292 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 13293 } catch (ActivityNotFoundException e) { 13294 Slog.w(TAG, "No activity to handle assist action.", e); 13295 } 13296 } 13297 } finally { 13298 Binder.restoreCallingIdentity(ident); 13299 } 13300 } 13301 13302 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle, 13303 Bundle args) { 13304 return enqueueAssistContext(requestType, intent, hint, null, null, null, 13305 true /* focused */, true /* newSessionId */, userHandle, args, 13306 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null; 13307 } 13308 13309 public void registerProcessObserver(IProcessObserver observer) { 13310 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 13311 "registerProcessObserver()"); 13312 synchronized (this) { 13313 mProcessObservers.register(observer); 13314 } 13315 } 13316 13317 @Override 13318 public void unregisterProcessObserver(IProcessObserver observer) { 13319 synchronized (this) { 13320 mProcessObservers.unregister(observer); 13321 } 13322 } 13323 13324 @Override 13325 public int getUidProcessState(int uid, String callingPackage) { 13326 if (!hasUsageStatsPermission(callingPackage)) { 13327 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, 13328 "getUidProcessState"); 13329 } 13330 13331 synchronized (this) { 13332 UidRecord uidRec = mActiveUids.get(uid); 13333 return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT; 13334 } 13335 } 13336 13337 @Override 13338 public void registerUidObserver(IUidObserver observer, int which, int cutpoint, 13339 String callingPackage) { 13340 if (!hasUsageStatsPermission(callingPackage)) { 13341 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, 13342 "registerUidObserver"); 13343 } 13344 synchronized (this) { 13345 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(), 13346 callingPackage, which, cutpoint)); 13347 } 13348 } 13349 13350 @Override 13351 public void unregisterUidObserver(IUidObserver observer) { 13352 synchronized (this) { 13353 mUidObservers.unregister(observer); 13354 } 13355 } 13356 13357 @Override 13358 public boolean convertFromTranslucent(IBinder token) { 13359 final long origId = Binder.clearCallingIdentity(); 13360 try { 13361 synchronized (this) { 13362 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 13363 if (r == null) { 13364 return false; 13365 } 13366 final boolean translucentChanged = r.changeWindowTranslucency(true); 13367 if (translucentChanged) { 13368 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 13369 } 13370 mWindowManager.setAppFullscreen(token, true); 13371 return translucentChanged; 13372 } 13373 } finally { 13374 Binder.restoreCallingIdentity(origId); 13375 } 13376 } 13377 13378 @Override 13379 public boolean convertToTranslucent(IBinder token, Bundle options) { 13380 final long origId = Binder.clearCallingIdentity(); 13381 try { 13382 synchronized (this) { 13383 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 13384 if (r == null) { 13385 return false; 13386 } 13387 final TaskRecord task = r.getTask(); 13388 int index = task.mActivities.lastIndexOf(r); 13389 if (index > 0) { 13390 ActivityRecord under = task.mActivities.get(index - 1); 13391 under.returningOptions = ActivityOptions.fromBundle(options); 13392 } 13393 final boolean translucentChanged = r.changeWindowTranslucency(false); 13394 if (translucentChanged) { 13395 r.getStack().convertActivityToTranslucent(r); 13396 } 13397 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 13398 mWindowManager.setAppFullscreen(token, false); 13399 return translucentChanged; 13400 } 13401 } finally { 13402 Binder.restoreCallingIdentity(origId); 13403 } 13404 } 13405 13406 @Override 13407 public Bundle getActivityOptions(IBinder token) { 13408 final long origId = Binder.clearCallingIdentity(); 13409 try { 13410 synchronized (this) { 13411 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 13412 if (r != null) { 13413 final ActivityOptions activityOptions = r.takeOptionsLocked(); 13414 return activityOptions == null ? null : activityOptions.toBundle(); 13415 } 13416 return null; 13417 } 13418 } finally { 13419 Binder.restoreCallingIdentity(origId); 13420 } 13421 } 13422 13423 @Override 13424 public void setImmersive(IBinder token, boolean immersive) { 13425 synchronized(this) { 13426 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 13427 if (r == null) { 13428 throw new IllegalArgumentException(); 13429 } 13430 r.immersive = immersive; 13431 13432 // update associated state if we're frontmost 13433 if (r == mStackSupervisor.getResumedActivityLocked()) { 13434 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r); 13435 applyUpdateLockStateLocked(r); 13436 } 13437 } 13438 } 13439 13440 @Override 13441 public boolean isImmersive(IBinder token) { 13442 synchronized (this) { 13443 ActivityRecord r = ActivityRecord.isInStackLocked(token); 13444 if (r == null) { 13445 throw new IllegalArgumentException(); 13446 } 13447 return r.immersive; 13448 } 13449 } 13450 13451 @Override 13452 public void setVrThread(int tid) { 13453 enforceSystemHasVrFeature(); 13454 synchronized (this) { 13455 synchronized (mPidsSelfLocked) { 13456 final int pid = Binder.getCallingPid(); 13457 final ProcessRecord proc = mPidsSelfLocked.get(pid); 13458 mVrController.setVrThreadLocked(tid, pid, proc); 13459 } 13460 } 13461 } 13462 13463 @Override 13464 public void setPersistentVrThread(int tid) { 13465 if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) { 13466 final String msg = "Permission Denial: setPersistentVrThread() from pid=" 13467 + Binder.getCallingPid() 13468 + ", uid=" + Binder.getCallingUid() 13469 + " requires " + permission.RESTRICTED_VR_ACCESS; 13470 Slog.w(TAG, msg); 13471 throw new SecurityException(msg); 13472 } 13473 enforceSystemHasVrFeature(); 13474 synchronized (this) { 13475 synchronized (mPidsSelfLocked) { 13476 final int pid = Binder.getCallingPid(); 13477 final ProcessRecord proc = mPidsSelfLocked.get(pid); 13478 mVrController.setPersistentVrThreadLocked(tid, pid, proc); 13479 } 13480 } 13481 } 13482 13483 /** 13484 * Schedule the given thread a normal scheduling priority. 13485 * 13486 * @param tid the tid of the thread to adjust the scheduling of. 13487 * @param suppressLogs {@code true} if any error logging should be disabled. 13488 * 13489 * @return {@code true} if this succeeded. 13490 */ 13491 static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) { 13492 try { 13493 Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0); 13494 return true; 13495 } catch (IllegalArgumentException e) { 13496 if (!suppressLogs) { 13497 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e); 13498 } 13499 } catch (SecurityException e) { 13500 if (!suppressLogs) { 13501 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e); 13502 } 13503 } 13504 return false; 13505 } 13506 13507 /** 13508 * Schedule the given thread an FIFO scheduling priority. 13509 * 13510 * @param tid the tid of the thread to adjust the scheduling of. 13511 * @param suppressLogs {@code true} if any error logging should be disabled. 13512 * 13513 * @return {@code true} if this succeeded. 13514 */ 13515 static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) { 13516 try { 13517 Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1); 13518 return true; 13519 } catch (IllegalArgumentException e) { 13520 if (!suppressLogs) { 13521 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e); 13522 } 13523 } catch (SecurityException e) { 13524 if (!suppressLogs) { 13525 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e); 13526 } 13527 } 13528 return false; 13529 } 13530 13531 /** 13532 * Check that we have the features required for VR-related API calls, and throw an exception if 13533 * not. 13534 */ 13535 private void enforceSystemHasVrFeature() { 13536 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { 13537 throw new UnsupportedOperationException("VR mode not supported on this device!"); 13538 } 13539 } 13540 13541 @Override 13542 public void setRenderThread(int tid) { 13543 synchronized (this) { 13544 ProcessRecord proc; 13545 int pid = Binder.getCallingPid(); 13546 if (pid == Process.myPid()) { 13547 demoteSystemServerRenderThread(tid); 13548 return; 13549 } 13550 synchronized (mPidsSelfLocked) { 13551 proc = mPidsSelfLocked.get(pid); 13552 if (proc != null && proc.renderThreadTid == 0 && tid > 0) { 13553 // ensure the tid belongs to the process 13554 if (!isThreadInProcess(pid, tid)) { 13555 throw new IllegalArgumentException( 13556 "Render thread does not belong to process"); 13557 } 13558 proc.renderThreadTid = tid; 13559 if (DEBUG_OOM_ADJ) { 13560 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid); 13561 } 13562 // promote to FIFO now 13563 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { 13564 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band"); 13565 if (mUseFifoUiScheduling) { 13566 setThreadScheduler(proc.renderThreadTid, 13567 SCHED_FIFO | SCHED_RESET_ON_FORK, 1); 13568 } else { 13569 setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST); 13570 } 13571 } 13572 } else { 13573 if (DEBUG_OOM_ADJ) { 13574 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " + 13575 "PID: " + pid + ", TID: " + tid + " FIFO: " + 13576 mUseFifoUiScheduling); 13577 } 13578 } 13579 } 13580 } 13581 } 13582 13583 /** 13584 * We only use RenderThread in system_server to store task snapshots to the disk, which should 13585 * happen in the background. Thus, demote render thread from system_server to a lower priority. 13586 * 13587 * @param tid the tid of the RenderThread 13588 */ 13589 private void demoteSystemServerRenderThread(int tid) { 13590 setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND); 13591 } 13592 13593 @Override 13594 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) { 13595 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { 13596 throw new UnsupportedOperationException("VR mode not supported on this device!"); 13597 } 13598 13599 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); 13600 13601 ActivityRecord r; 13602 synchronized (this) { 13603 r = ActivityRecord.isInStackLocked(token); 13604 } 13605 13606 if (r == null) { 13607 throw new IllegalArgumentException(); 13608 } 13609 13610 int err; 13611 if ((err = vrService.hasVrPackage(packageName, r.userId)) != 13612 VrManagerInternal.NO_ERROR) { 13613 return err; 13614 } 13615 13616 synchronized(this) { 13617 r.requestedVrComponent = (enabled) ? packageName : null; 13618 13619 // Update associated state if this activity is currently focused 13620 if (r == mStackSupervisor.getResumedActivityLocked()) { 13621 applyUpdateVrModeLocked(r); 13622 } 13623 return 0; 13624 } 13625 } 13626 13627 @Override 13628 public boolean isVrModePackageEnabled(ComponentName packageName) { 13629 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { 13630 throw new UnsupportedOperationException("VR mode not supported on this device!"); 13631 } 13632 13633 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); 13634 13635 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) == 13636 VrManagerInternal.NO_ERROR; 13637 } 13638 13639 public boolean isTopActivityImmersive() { 13640 enforceNotIsolatedCaller("startActivity"); 13641 synchronized (this) { 13642 ActivityRecord r = getFocusedStack().topRunningActivityLocked(); 13643 return (r != null) ? r.immersive : false; 13644 } 13645 } 13646 13647 /** 13648 * @return whether the system should disable UI modes incompatible with VR mode. 13649 */ 13650 boolean shouldDisableNonVrUiLocked() { 13651 return mVrController.shouldDisableNonVrUiLocked(); 13652 } 13653 13654 @Override 13655 public boolean isTopOfTask(IBinder token) { 13656 synchronized (this) { 13657 ActivityRecord r = ActivityRecord.isInStackLocked(token); 13658 if (r == null) { 13659 throw new IllegalArgumentException(); 13660 } 13661 return r.getTask().getTopActivity() == r; 13662 } 13663 } 13664 13665 @Override 13666 public void setHasTopUi(boolean hasTopUi) throws RemoteException { 13667 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) { 13668 String msg = "Permission Denial: setHasTopUi() from pid=" 13669 + Binder.getCallingPid() 13670 + ", uid=" + Binder.getCallingUid() 13671 + " requires " + permission.INTERNAL_SYSTEM_WINDOW; 13672 Slog.w(TAG, msg); 13673 throw new SecurityException(msg); 13674 } 13675 final int pid = Binder.getCallingPid(); 13676 final long origId = Binder.clearCallingIdentity(); 13677 try { 13678 synchronized (this) { 13679 boolean changed = false; 13680 ProcessRecord pr; 13681 synchronized (mPidsSelfLocked) { 13682 pr = mPidsSelfLocked.get(pid); 13683 if (pr == null) { 13684 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid); 13685 return; 13686 } 13687 if (pr.hasTopUi != hasTopUi) { 13688 if (DEBUG_OOM_ADJ) { 13689 Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid); 13690 } 13691 pr.hasTopUi = hasTopUi; 13692 changed = true; 13693 } 13694 } 13695 if (changed) { 13696 updateOomAdjLocked(pr, true); 13697 } 13698 } 13699 } finally { 13700 Binder.restoreCallingIdentity(origId); 13701 } 13702 } 13703 13704 public final void enterSafeMode() { 13705 synchronized(this) { 13706 // It only makes sense to do this before the system is ready 13707 // and started launching other packages. 13708 if (!mSystemReady) { 13709 try { 13710 AppGlobals.getPackageManager().enterSafeMode(); 13711 } catch (RemoteException e) { 13712 } 13713 } 13714 13715 mSafeMode = true; 13716 } 13717 } 13718 13719 public final void showSafeModeOverlay() { 13720 View v = LayoutInflater.from(mContext).inflate( 13721 com.android.internal.R.layout.safe_mode, null); 13722 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 13723 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 13724 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 13725 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 13726 lp.gravity = Gravity.BOTTOM | Gravity.START; 13727 lp.format = v.getBackground().getOpacity(); 13728 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 13729 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 13730 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 13731 ((WindowManager)mContext.getSystemService( 13732 Context.WINDOW_SERVICE)).addView(v, lp); 13733 } 13734 13735 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) { 13736 if (sender != null && !(sender instanceof PendingIntentRecord)) { 13737 return; 13738 } 13739 final PendingIntentRecord rec = (PendingIntentRecord)sender; 13740 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13741 synchronized (stats) { 13742 if (mBatteryStatsService.isOnBattery()) { 13743 mBatteryStatsService.enforceCallingPermission(); 13744 int MY_UID = Binder.getCallingUid(); 13745 final int uid; 13746 if (sender == null) { 13747 uid = sourceUid; 13748 } else { 13749 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid; 13750 } 13751 BatteryStatsImpl.Uid.Pkg pkg = 13752 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 13753 sourcePkg != null ? sourcePkg : rec.key.packageName); 13754 pkg.noteWakeupAlarmLocked(tag); 13755 } 13756 } 13757 } 13758 13759 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) { 13760 if (sender != null && !(sender instanceof PendingIntentRecord)) { 13761 return; 13762 } 13763 final PendingIntentRecord rec = (PendingIntentRecord)sender; 13764 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13765 synchronized (stats) { 13766 mBatteryStatsService.enforceCallingPermission(); 13767 int MY_UID = Binder.getCallingUid(); 13768 final int uid; 13769 if (sender == null) { 13770 uid = sourceUid; 13771 } else { 13772 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid; 13773 } 13774 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid); 13775 } 13776 } 13777 13778 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) { 13779 if (sender != null && !(sender instanceof PendingIntentRecord)) { 13780 return; 13781 } 13782 final PendingIntentRecord rec = (PendingIntentRecord)sender; 13783 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13784 synchronized (stats) { 13785 mBatteryStatsService.enforceCallingPermission(); 13786 int MY_UID = Binder.getCallingUid(); 13787 final int uid; 13788 if (sender == null) { 13789 uid = sourceUid; 13790 } else { 13791 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid; 13792 } 13793 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid); 13794 } 13795 } 13796 13797 public boolean killPids(int[] pids, String pReason, boolean secure) { 13798 if (Binder.getCallingUid() != SYSTEM_UID) { 13799 throw new SecurityException("killPids only available to the system"); 13800 } 13801 String reason = (pReason == null) ? "Unknown" : pReason; 13802 // XXX Note: don't acquire main activity lock here, because the window 13803 // manager calls in with its locks held. 13804 13805 boolean killed = false; 13806 synchronized (mPidsSelfLocked) { 13807 int worstType = 0; 13808 for (int i=0; i<pids.length; i++) { 13809 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 13810 if (proc != null) { 13811 int type = proc.setAdj; 13812 if (type > worstType) { 13813 worstType = type; 13814 } 13815 } 13816 } 13817 13818 // If the worst oom_adj is somewhere in the cached proc LRU range, 13819 // then constrain it so we will kill all cached procs. 13820 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 13821 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 13822 worstType = ProcessList.CACHED_APP_MIN_ADJ; 13823 } 13824 13825 // If this is not a secure call, don't let it kill processes that 13826 // are important. 13827 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 13828 worstType = ProcessList.SERVICE_ADJ; 13829 } 13830 13831 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 13832 for (int i=0; i<pids.length; i++) { 13833 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 13834 if (proc == null) { 13835 continue; 13836 } 13837 int adj = proc.setAdj; 13838 if (adj >= worstType && !proc.killedByAm) { 13839 proc.kill(reason, true); 13840 killed = true; 13841 } 13842 } 13843 } 13844 return killed; 13845 } 13846 13847 @Override 13848 public void killUid(int appId, int userId, String reason) { 13849 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid"); 13850 synchronized (this) { 13851 final long identity = Binder.clearCallingIdentity(); 13852 try { 13853 killPackageProcessesLocked(null, appId, userId, 13854 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true, 13855 reason != null ? reason : "kill uid"); 13856 } finally { 13857 Binder.restoreCallingIdentity(identity); 13858 } 13859 } 13860 } 13861 13862 @Override 13863 public boolean killProcessesBelowForeground(String reason) { 13864 if (Binder.getCallingUid() != SYSTEM_UID) { 13865 throw new SecurityException("killProcessesBelowForeground() only available to system"); 13866 } 13867 13868 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 13869 } 13870 13871 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 13872 if (Binder.getCallingUid() != SYSTEM_UID) { 13873 throw new SecurityException("killProcessesBelowAdj() only available to system"); 13874 } 13875 13876 boolean killed = false; 13877 synchronized (mPidsSelfLocked) { 13878 final int size = mPidsSelfLocked.size(); 13879 for (int i = 0; i < size; i++) { 13880 final int pid = mPidsSelfLocked.keyAt(i); 13881 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 13882 if (proc == null) continue; 13883 13884 final int adj = proc.setAdj; 13885 if (adj > belowAdj && !proc.killedByAm) { 13886 proc.kill(reason, true); 13887 killed = true; 13888 } 13889 } 13890 } 13891 return killed; 13892 } 13893 13894 @Override 13895 public void hang(final IBinder who, boolean allowRestart) { 13896 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13897 != PackageManager.PERMISSION_GRANTED) { 13898 throw new SecurityException("Requires permission " 13899 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13900 } 13901 13902 final IBinder.DeathRecipient death = new DeathRecipient() { 13903 @Override 13904 public void binderDied() { 13905 synchronized (this) { 13906 notifyAll(); 13907 } 13908 } 13909 }; 13910 13911 try { 13912 who.linkToDeath(death, 0); 13913 } catch (RemoteException e) { 13914 Slog.w(TAG, "hang: given caller IBinder is already dead."); 13915 return; 13916 } 13917 13918 synchronized (this) { 13919 Watchdog.getInstance().setAllowRestart(allowRestart); 13920 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 13921 synchronized (death) { 13922 while (who.isBinderAlive()) { 13923 try { 13924 death.wait(); 13925 } catch (InterruptedException e) { 13926 } 13927 } 13928 } 13929 Watchdog.getInstance().setAllowRestart(true); 13930 } 13931 } 13932 13933 @Override 13934 public void restart() { 13935 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13936 != PackageManager.PERMISSION_GRANTED) { 13937 throw new SecurityException("Requires permission " 13938 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13939 } 13940 13941 Log.i(TAG, "Sending shutdown broadcast..."); 13942 13943 BroadcastReceiver br = new BroadcastReceiver() { 13944 @Override public void onReceive(Context context, Intent intent) { 13945 // Now the broadcast is done, finish up the low-level shutdown. 13946 Log.i(TAG, "Shutting down activity manager..."); 13947 shutdown(10000); 13948 Log.i(TAG, "Shutdown complete, restarting!"); 13949 killProcess(myPid()); 13950 System.exit(10); 13951 } 13952 }; 13953 13954 // First send the high-level shut down broadcast. 13955 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 13956 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 13957 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 13958 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 13959 mContext.sendOrderedBroadcastAsUser(intent, 13960 UserHandle.ALL, null, br, mHandler, 0, null, null); 13961 */ 13962 br.onReceive(mContext, intent); 13963 } 13964 13965 private long getLowRamTimeSinceIdle(long now) { 13966 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 13967 } 13968 13969 @Override 13970 public void performIdleMaintenance() { 13971 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13972 != PackageManager.PERMISSION_GRANTED) { 13973 throw new SecurityException("Requires permission " 13974 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13975 } 13976 13977 synchronized (this) { 13978 final long now = SystemClock.uptimeMillis(); 13979 final long timeSinceLastIdle = now - mLastIdleTime; 13980 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 13981 mLastIdleTime = now; 13982 mLowRamTimeSinceLastIdle = 0; 13983 if (mLowRamStartTime != 0) { 13984 mLowRamStartTime = now; 13985 } 13986 13987 StringBuilder sb = new StringBuilder(128); 13988 sb.append("Idle maintenance over "); 13989 TimeUtils.formatDuration(timeSinceLastIdle, sb); 13990 sb.append(" low RAM for "); 13991 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 13992 Slog.i(TAG, sb.toString()); 13993 13994 // If at least 1/3 of our time since the last idle period has been spent 13995 // with RAM low, then we want to kill processes. 13996 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 13997 13998 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13999 ProcessRecord proc = mLruProcesses.get(i); 14000 if (proc.notCachedSinceIdle) { 14001 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING 14002 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE 14003 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 14004 if (doKilling && proc.initialIdlePss != 0 14005 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 14006 sb = new StringBuilder(128); 14007 sb.append("Kill"); 14008 sb.append(proc.processName); 14009 sb.append(" in idle maint: pss="); 14010 sb.append(proc.lastPss); 14011 sb.append(", swapPss="); 14012 sb.append(proc.lastSwapPss); 14013 sb.append(", initialPss="); 14014 sb.append(proc.initialIdlePss); 14015 sb.append(", period="); 14016 TimeUtils.formatDuration(timeSinceLastIdle, sb); 14017 sb.append(", lowRamPeriod="); 14018 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 14019 Slog.wtfQuiet(TAG, sb.toString()); 14020 proc.kill("idle maint (pss " + proc.lastPss 14021 + " from " + proc.initialIdlePss + ")", true); 14022 } 14023 } 14024 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME 14025 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) { 14026 proc.notCachedSinceIdle = true; 14027 proc.initialIdlePss = 0; 14028 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true, 14029 mTestPssMode, isSleepingLocked(), now); 14030 } 14031 } 14032 14033 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 14034 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 14035 } 14036 } 14037 14038 @Override 14039 public void sendIdleJobTrigger() { 14040 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14041 != PackageManager.PERMISSION_GRANTED) { 14042 throw new SecurityException("Requires permission " 14043 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14044 } 14045 14046 final long ident = Binder.clearCallingIdentity(); 14047 try { 14048 Intent intent = new Intent(ACTION_TRIGGER_IDLE) 14049 .setPackage("android") 14050 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14051 broadcastIntent(null, intent, null, null, 0, null, null, null, 14052 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL); 14053 } finally { 14054 Binder.restoreCallingIdentity(ident); 14055 } 14056 } 14057 14058 private void retrieveSettings() { 14059 final ContentResolver resolver = mContext.getContentResolver(); 14060 final boolean freeformWindowManagement = 14061 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT) 14062 || Settings.Global.getInt( 14063 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0; 14064 14065 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext); 14066 final boolean supportsPictureInPicture = supportsMultiWindow && 14067 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE); 14068 final boolean supportsSplitScreenMultiWindow = 14069 ActivityManager.supportsSplitScreenMultiWindow(mContext); 14070 final boolean supportsMultiDisplay = mContext.getPackageManager() 14071 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS); 14072 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP); 14073 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0; 14074 final boolean alwaysFinishActivities = 14075 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0; 14076 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0; 14077 final boolean forceResizable = Settings.Global.getInt( 14078 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0; 14079 final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver, 14080 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS); 14081 final boolean supportsLeanbackOnly = 14082 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY); 14083 14084 // Transfer any global setting for forcing RTL layout, into a System Property 14085 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 14086 14087 final Configuration configuration = new Configuration(); 14088 Settings.System.getConfiguration(resolver, configuration); 14089 if (forceRtl) { 14090 // This will take care of setting the correct layout direction flags 14091 configuration.setLayoutDirection(configuration.locale); 14092 } 14093 14094 synchronized (this) { 14095 mDebugApp = mOrigDebugApp = debugApp; 14096 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 14097 mAlwaysFinishActivities = alwaysFinishActivities; 14098 mSupportsLeanbackOnly = supportsLeanbackOnly; 14099 mForceResizableActivities = forceResizable; 14100 final boolean multiWindowFormEnabled = freeformWindowManagement 14101 || supportsSplitScreenMultiWindow 14102 || supportsPictureInPicture 14103 || supportsMultiDisplay; 14104 if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) { 14105 mSupportsMultiWindow = true; 14106 mSupportsFreeformWindowManagement = freeformWindowManagement; 14107 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow; 14108 mSupportsPictureInPicture = supportsPictureInPicture; 14109 mSupportsMultiDisplay = supportsMultiDisplay; 14110 } else { 14111 mSupportsMultiWindow = false; 14112 mSupportsFreeformWindowManagement = false; 14113 mSupportsSplitScreenMultiWindow = false; 14114 mSupportsPictureInPicture = false; 14115 mSupportsMultiDisplay = false; 14116 } 14117 mWindowManager.setForceResizableTasks(mForceResizableActivities); 14118 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture); 14119 // This happens before any activities are started, so we can change global configuration 14120 // in-place. 14121 updateConfigurationLocked(configuration, null, true); 14122 final Configuration globalConfig = getGlobalConfiguration(); 14123 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig); 14124 14125 // Load resources only after the current configuration has been set. 14126 final Resources res = mContext.getResources(); 14127 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 14128 mThumbnailWidth = res.getDimensionPixelSize( 14129 com.android.internal.R.dimen.thumbnail_width); 14130 mThumbnailHeight = res.getDimensionPixelSize( 14131 com.android.internal.R.dimen.thumbnail_height); 14132 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString( 14133 com.android.internal.R.string.config_appsNotReportingCrashes)); 14134 mUserController.mUserSwitchUiEnabled = !res.getBoolean( 14135 com.android.internal.R.bool.config_customUserSwitchUi); 14136 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) { 14137 mFullscreenThumbnailScale = (float) res 14138 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) / 14139 (float) globalConfig.screenWidthDp; 14140 } else { 14141 mFullscreenThumbnailScale = res.getFraction( 14142 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1); 14143 } 14144 mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs; 14145 } 14146 } 14147 14148 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { 14149 traceLog.traceBegin("PhaseActivityManagerReady"); 14150 synchronized(this) { 14151 if (mSystemReady) { 14152 // If we're done calling all the receivers, run the next "boot phase" passed in 14153 // by the SystemServer 14154 if (goingCallback != null) { 14155 goingCallback.run(); 14156 } 14157 return; 14158 } 14159 14160 mLocalDeviceIdleController 14161 = LocalServices.getService(DeviceIdleController.LocalService.class); 14162 mAssistUtils = new AssistUtils(mContext); 14163 mVrController.onSystemReady(); 14164 // Make sure we have the current profile info, since it is needed for security checks. 14165 mUserController.onSystemReady(); 14166 mRecentTasks.onSystemReadyLocked(); 14167 mAppOpsService.systemReady(); 14168 mSystemReady = true; 14169 } 14170 14171 try { 14172 sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface( 14173 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE)) 14174 .getSerial(); 14175 } catch (RemoteException e) {} 14176 14177 ArrayList<ProcessRecord> procsToKill = null; 14178 synchronized(mPidsSelfLocked) { 14179 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 14180 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 14181 if (!isAllowedWhileBooting(proc.info)){ 14182 if (procsToKill == null) { 14183 procsToKill = new ArrayList<ProcessRecord>(); 14184 } 14185 procsToKill.add(proc); 14186 } 14187 } 14188 } 14189 14190 synchronized(this) { 14191 if (procsToKill != null) { 14192 for (int i=procsToKill.size()-1; i>=0; i--) { 14193 ProcessRecord proc = procsToKill.get(i); 14194 Slog.i(TAG, "Removing system update proc: " + proc); 14195 removeProcessLocked(proc, true, false, "system update done"); 14196 } 14197 } 14198 14199 // Now that we have cleaned up any update processes, we 14200 // are ready to start launching real processes and know that 14201 // we won't trample on them any more. 14202 mProcessesReady = true; 14203 } 14204 14205 Slog.i(TAG, "System now ready"); 14206 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 14207 SystemClock.uptimeMillis()); 14208 14209 synchronized(this) { 14210 // Make sure we have no pre-ready processes sitting around. 14211 14212 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 14213 ResolveInfo ri = mContext.getPackageManager() 14214 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 14215 STOCK_PM_FLAGS); 14216 CharSequence errorMsg = null; 14217 if (ri != null) { 14218 ActivityInfo ai = ri.activityInfo; 14219 ApplicationInfo app = ai.applicationInfo; 14220 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 14221 mTopAction = Intent.ACTION_FACTORY_TEST; 14222 mTopData = null; 14223 mTopComponent = new ComponentName(app.packageName, 14224 ai.name); 14225 } else { 14226 errorMsg = mContext.getResources().getText( 14227 com.android.internal.R.string.factorytest_not_system); 14228 } 14229 } else { 14230 errorMsg = mContext.getResources().getText( 14231 com.android.internal.R.string.factorytest_no_action); 14232 } 14233 if (errorMsg != null) { 14234 mTopAction = null; 14235 mTopData = null; 14236 mTopComponent = null; 14237 Message msg = Message.obtain(); 14238 msg.what = SHOW_FACTORY_ERROR_UI_MSG; 14239 msg.getData().putCharSequence("msg", errorMsg); 14240 mUiHandler.sendMessage(msg); 14241 } 14242 } 14243 } 14244 14245 retrieveSettings(); 14246 final int currentUserId; 14247 synchronized (this) { 14248 currentUserId = mUserController.getCurrentUserIdLocked(); 14249 readGrantedUriPermissionsLocked(); 14250 } 14251 14252 if (goingCallback != null) goingCallback.run(); 14253 traceLog.traceBegin("ActivityManagerStartApps"); 14254 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 14255 Integer.toString(currentUserId), currentUserId); 14256 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 14257 Integer.toString(currentUserId), currentUserId); 14258 mSystemServiceManager.startUser(currentUserId); 14259 14260 synchronized (this) { 14261 // Only start up encryption-aware persistent apps; once user is 14262 // unlocked we'll come back around and start unaware apps 14263 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE); 14264 14265 // Start up initial activity. 14266 mBooting = true; 14267 // Enable home activity for system user, so that the system can always boot. We don't 14268 // do this when the system user is not setup since the setup wizard should be the one 14269 // to handle home activity in this case. 14270 if (UserManager.isSplitSystemUser() && 14271 Settings.Secure.getInt(mContext.getContentResolver(), 14272 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) { 14273 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class); 14274 try { 14275 AppGlobals.getPackageManager().setComponentEnabledSetting(cName, 14276 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, 14277 UserHandle.USER_SYSTEM); 14278 } catch (RemoteException e) { 14279 throw e.rethrowAsRuntimeException(); 14280 } 14281 } 14282 startHomeActivityLocked(currentUserId, "systemReady"); 14283 14284 try { 14285 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 14286 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 14287 + " data partition or your device will be unstable."); 14288 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget(); 14289 } 14290 } catch (RemoteException e) { 14291 } 14292 14293 if (!Build.isBuildConsistent()) { 14294 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 14295 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget(); 14296 } 14297 14298 long ident = Binder.clearCallingIdentity(); 14299 try { 14300 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 14301 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14302 | Intent.FLAG_RECEIVER_FOREGROUND); 14303 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); 14304 broadcastIntentLocked(null, null, intent, 14305 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14306 null, false, false, MY_PID, SYSTEM_UID, 14307 currentUserId); 14308 intent = new Intent(Intent.ACTION_USER_STARTING); 14309 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14310 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); 14311 broadcastIntentLocked(null, null, intent, 14312 null, new IIntentReceiver.Stub() { 14313 @Override 14314 public void performReceive(Intent intent, int resultCode, String data, 14315 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 14316 throws RemoteException { 14317 } 14318 }, 0, null, null, 14319 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE, 14320 null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL); 14321 } catch (Throwable t) { 14322 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 14323 } finally { 14324 Binder.restoreCallingIdentity(ident); 14325 } 14326 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 14327 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId); 14328 traceLog.traceEnd(); // ActivityManagerStartApps 14329 traceLog.traceEnd(); // PhaseActivityManagerReady 14330 } 14331 } 14332 14333 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 14334 synchronized (this) { 14335 mAppErrors.killAppAtUserRequestLocked(app, fromDialog); 14336 } 14337 } 14338 14339 void skipCurrentReceiverLocked(ProcessRecord app) { 14340 for (BroadcastQueue queue : mBroadcastQueues) { 14341 queue.skipCurrentReceiverLocked(app); 14342 } 14343 } 14344 14345 /** 14346 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 14347 * The application process will exit immediately after this call returns. 14348 * @param app object of the crashing app, null for the system server 14349 * @param crashInfo describing the exception 14350 */ 14351 public void handleApplicationCrash(IBinder app, 14352 ApplicationErrorReport.ParcelableCrashInfo crashInfo) { 14353 ProcessRecord r = findAppProcess(app, "Crash"); 14354 final String processName = app == null ? "system_server" 14355 : (r == null ? "unknown" : r.processName); 14356 14357 handleApplicationCrashInner("crash", r, processName, crashInfo); 14358 } 14359 14360 /* Native crash reporting uses this inner version because it needs to be somewhat 14361 * decoupled from the AM-managed cleanup lifecycle 14362 */ 14363 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 14364 ApplicationErrorReport.CrashInfo crashInfo) { 14365 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 14366 UserHandle.getUserId(Binder.getCallingUid()), processName, 14367 r == null ? -1 : r.info.flags, 14368 crashInfo.exceptionClassName, 14369 crashInfo.exceptionMessage, 14370 crashInfo.throwFileName, 14371 crashInfo.throwLineNumber); 14372 14373 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 14374 14375 mAppErrors.crashApplication(r, crashInfo); 14376 } 14377 14378 public void handleApplicationStrictModeViolation( 14379 IBinder app, 14380 int violationMask, 14381 StrictMode.ViolationInfo info) { 14382 ProcessRecord r = findAppProcess(app, "StrictMode"); 14383 if (r == null) { 14384 return; 14385 } 14386 14387 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 14388 Integer stackFingerprint = info.hashCode(); 14389 boolean logIt = true; 14390 synchronized (mAlreadyLoggedViolatedStacks) { 14391 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 14392 logIt = false; 14393 // TODO: sub-sample into EventLog for these, with 14394 // the info.durationMillis? Then we'd get 14395 // the relative pain numbers, without logging all 14396 // the stack traces repeatedly. We'd want to do 14397 // likewise in the client code, which also does 14398 // dup suppression, before the Binder call. 14399 } else { 14400 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 14401 mAlreadyLoggedViolatedStacks.clear(); 14402 } 14403 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 14404 } 14405 } 14406 if (logIt) { 14407 logStrictModeViolationToDropBox(r, info); 14408 } 14409 } 14410 14411 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 14412 AppErrorResult result = new AppErrorResult(); 14413 synchronized (this) { 14414 final long origId = Binder.clearCallingIdentity(); 14415 14416 Message msg = Message.obtain(); 14417 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG; 14418 HashMap<String, Object> data = new HashMap<String, Object>(); 14419 data.put("result", result); 14420 data.put("app", r); 14421 data.put("violationMask", violationMask); 14422 data.put("info", info); 14423 msg.obj = data; 14424 mUiHandler.sendMessage(msg); 14425 14426 Binder.restoreCallingIdentity(origId); 14427 } 14428 int res = result.get(); 14429 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 14430 } 14431 } 14432 14433 // Depending on the policy in effect, there could be a bunch of 14434 // these in quick succession so we try to batch these together to 14435 // minimize disk writes, number of dropbox entries, and maximize 14436 // compression, by having more fewer, larger records. 14437 private void logStrictModeViolationToDropBox( 14438 ProcessRecord process, 14439 StrictMode.ViolationInfo info) { 14440 if (info == null) { 14441 return; 14442 } 14443 final boolean isSystemApp = process == null || 14444 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 14445 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 14446 final String processName = process == null ? "unknown" : process.processName; 14447 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 14448 final DropBoxManager dbox = (DropBoxManager) 14449 mContext.getSystemService(Context.DROPBOX_SERVICE); 14450 14451 // Exit early if the dropbox isn't configured to accept this report type. 14452 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 14453 14454 boolean bufferWasEmpty; 14455 boolean needsFlush; 14456 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 14457 synchronized (sb) { 14458 bufferWasEmpty = sb.length() == 0; 14459 appendDropBoxProcessHeaders(process, processName, sb); 14460 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 14461 sb.append("System-App: ").append(isSystemApp).append("\n"); 14462 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 14463 if (info.violationNumThisLoop != 0) { 14464 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 14465 } 14466 if (info.numAnimationsRunning != 0) { 14467 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 14468 } 14469 if (info.broadcastIntentAction != null) { 14470 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 14471 } 14472 if (info.durationMillis != -1) { 14473 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 14474 } 14475 if (info.numInstances != -1) { 14476 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 14477 } 14478 if (info.tags != null) { 14479 for (String tag : info.tags) { 14480 sb.append("Span-Tag: ").append(tag).append("\n"); 14481 } 14482 } 14483 sb.append("\n"); 14484 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 14485 sb.append(info.crashInfo.stackTrace); 14486 sb.append("\n"); 14487 } 14488 if (info.message != null) { 14489 sb.append(info.message); 14490 sb.append("\n"); 14491 } 14492 14493 // Only buffer up to ~64k. Various logging bits truncate 14494 // things at 128k. 14495 needsFlush = (sb.length() > 64 * 1024); 14496 } 14497 14498 // Flush immediately if the buffer's grown too large, or this 14499 // is a non-system app. Non-system apps are isolated with a 14500 // different tag & policy and not batched. 14501 // 14502 // Batching is useful during internal testing with 14503 // StrictMode settings turned up high. Without batching, 14504 // thousands of separate files could be created on boot. 14505 if (!isSystemApp || needsFlush) { 14506 new Thread("Error dump: " + dropboxTag) { 14507 @Override 14508 public void run() { 14509 String report; 14510 synchronized (sb) { 14511 report = sb.toString(); 14512 sb.delete(0, sb.length()); 14513 sb.trimToSize(); 14514 } 14515 if (report.length() != 0) { 14516 dbox.addText(dropboxTag, report); 14517 } 14518 } 14519 }.start(); 14520 return; 14521 } 14522 14523 // System app batching: 14524 if (!bufferWasEmpty) { 14525 // An existing dropbox-writing thread is outstanding, so 14526 // we don't need to start it up. The existing thread will 14527 // catch the buffer appends we just did. 14528 return; 14529 } 14530 14531 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 14532 // (After this point, we shouldn't access AMS internal data structures.) 14533 new Thread("Error dump: " + dropboxTag) { 14534 @Override 14535 public void run() { 14536 // 5 second sleep to let stacks arrive and be batched together 14537 try { 14538 Thread.sleep(5000); // 5 seconds 14539 } catch (InterruptedException e) {} 14540 14541 String errorReport; 14542 synchronized (mStrictModeBuffer) { 14543 errorReport = mStrictModeBuffer.toString(); 14544 if (errorReport.length() == 0) { 14545 return; 14546 } 14547 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 14548 mStrictModeBuffer.trimToSize(); 14549 } 14550 dbox.addText(dropboxTag, errorReport); 14551 } 14552 }.start(); 14553 } 14554 14555 /** 14556 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 14557 * @param app object of the crashing app, null for the system server 14558 * @param tag reported by the caller 14559 * @param system whether this wtf is coming from the system 14560 * @param crashInfo describing the context of the error 14561 * @return true if the process should exit immediately (WTF is fatal) 14562 */ 14563 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 14564 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) { 14565 final int callingUid = Binder.getCallingUid(); 14566 final int callingPid = Binder.getCallingPid(); 14567 14568 if (system) { 14569 // If this is coming from the system, we could very well have low-level 14570 // system locks held, so we want to do this all asynchronously. And we 14571 // never want this to become fatal, so there is that too. 14572 mHandler.post(new Runnable() { 14573 @Override public void run() { 14574 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 14575 } 14576 }); 14577 return false; 14578 } 14579 14580 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 14581 crashInfo); 14582 14583 final boolean isFatal = Build.IS_ENG || Settings.Global 14584 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0; 14585 final boolean isSystem = (r == null) || r.persistent; 14586 14587 if (isFatal && !isSystem) { 14588 mAppErrors.crashApplication(r, crashInfo); 14589 return true; 14590 } else { 14591 return false; 14592 } 14593 } 14594 14595 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 14596 final ApplicationErrorReport.CrashInfo crashInfo) { 14597 final ProcessRecord r = findAppProcess(app, "WTF"); 14598 final String processName = app == null ? "system_server" 14599 : (r == null ? "unknown" : r.processName); 14600 14601 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 14602 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 14603 14604 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 14605 14606 return r; 14607 } 14608 14609 /** 14610 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 14611 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 14612 */ 14613 private ProcessRecord findAppProcess(IBinder app, String reason) { 14614 if (app == null) { 14615 return null; 14616 } 14617 14618 synchronized (this) { 14619 final int NP = mProcessNames.getMap().size(); 14620 for (int ip=0; ip<NP; ip++) { 14621 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 14622 final int NA = apps.size(); 14623 for (int ia=0; ia<NA; ia++) { 14624 ProcessRecord p = apps.valueAt(ia); 14625 if (p.thread != null && p.thread.asBinder() == app) { 14626 return p; 14627 } 14628 } 14629 } 14630 14631 Slog.w(TAG, "Can't find mystery application for " + reason 14632 + " from pid=" + Binder.getCallingPid() 14633 + " uid=" + Binder.getCallingUid() + ": " + app); 14634 return null; 14635 } 14636 } 14637 14638 /** 14639 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 14640 * to append various headers to the dropbox log text. 14641 */ 14642 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 14643 StringBuilder sb) { 14644 // Watchdog thread ends up invoking this function (with 14645 // a null ProcessRecord) to add the stack file to dropbox. 14646 // Do not acquire a lock on this (am) in such cases, as it 14647 // could cause a potential deadlock, if and when watchdog 14648 // is invoked due to unavailability of lock on am and it 14649 // would prevent watchdog from killing system_server. 14650 if (process == null) { 14651 sb.append("Process: ").append(processName).append("\n"); 14652 return; 14653 } 14654 // Note: ProcessRecord 'process' is guarded by the service 14655 // instance. (notably process.pkgList, which could otherwise change 14656 // concurrently during execution of this method) 14657 synchronized (this) { 14658 sb.append("Process: ").append(processName).append("\n"); 14659 sb.append("PID: ").append(process.pid).append("\n"); 14660 int flags = process.info.flags; 14661 IPackageManager pm = AppGlobals.getPackageManager(); 14662 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n"); 14663 for (int ip=0; ip<process.pkgList.size(); ip++) { 14664 String pkg = process.pkgList.keyAt(ip); 14665 sb.append("Package: ").append(pkg); 14666 try { 14667 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 14668 if (pi != null) { 14669 sb.append(" v").append(pi.versionCode); 14670 if (pi.versionName != null) { 14671 sb.append(" (").append(pi.versionName).append(")"); 14672 } 14673 } 14674 } catch (RemoteException e) { 14675 Slog.e(TAG, "Error getting package info: " + pkg, e); 14676 } 14677 sb.append("\n"); 14678 } 14679 if (process.info.isInstantApp()) { 14680 sb.append("Instant-App: true\n"); 14681 } 14682 } 14683 } 14684 14685 private static String processClass(ProcessRecord process) { 14686 if (process == null || process.pid == MY_PID) { 14687 return "system_server"; 14688 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 14689 return "system_app"; 14690 } else { 14691 return "data_app"; 14692 } 14693 } 14694 14695 private volatile long mWtfClusterStart; 14696 private volatile int mWtfClusterCount; 14697 14698 /** 14699 * Write a description of an error (crash, WTF, ANR) to the drop box. 14700 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 14701 * @param process which caused the error, null means the system server 14702 * @param activity which triggered the error, null if unknown 14703 * @param parent activity related to the error, null if unknown 14704 * @param subject line related to the error, null if absent 14705 * @param report in long form describing the error, null if absent 14706 * @param dataFile text file to include in the report, null if none 14707 * @param crashInfo giving an application stack trace, null if absent 14708 */ 14709 public void addErrorToDropBox(String eventType, 14710 ProcessRecord process, String processName, ActivityRecord activity, 14711 ActivityRecord parent, String subject, 14712 final String report, final File dataFile, 14713 final ApplicationErrorReport.CrashInfo crashInfo) { 14714 // NOTE -- this must never acquire the ActivityManagerService lock, 14715 // otherwise the watchdog may be prevented from resetting the system. 14716 14717 // Bail early if not published yet 14718 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return; 14719 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class); 14720 14721 // Exit early if the dropbox isn't configured to accept this report type. 14722 final String dropboxTag = processClass(process) + "_" + eventType; 14723 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 14724 14725 // Rate-limit how often we're willing to do the heavy lifting below to 14726 // collect and record logs; currently 5 logs per 10 second period. 14727 final long now = SystemClock.elapsedRealtime(); 14728 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) { 14729 mWtfClusterStart = now; 14730 mWtfClusterCount = 1; 14731 } else { 14732 if (mWtfClusterCount++ >= 5) return; 14733 } 14734 14735 final StringBuilder sb = new StringBuilder(1024); 14736 appendDropBoxProcessHeaders(process, processName, sb); 14737 if (process != null) { 14738 sb.append("Foreground: ") 14739 .append(process.isInterestingToUserLocked() ? "Yes" : "No") 14740 .append("\n"); 14741 } 14742 if (activity != null) { 14743 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 14744 } 14745 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 14746 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 14747 } 14748 if (parent != null && parent != activity) { 14749 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 14750 } 14751 if (subject != null) { 14752 sb.append("Subject: ").append(subject).append("\n"); 14753 } 14754 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 14755 if (Debug.isDebuggerConnected()) { 14756 sb.append("Debugger: Connected\n"); 14757 } 14758 sb.append("\n"); 14759 14760 // Do the rest in a worker thread to avoid blocking the caller on I/O 14761 // (After this point, we shouldn't access AMS internal data structures.) 14762 Thread worker = new Thread("Error dump: " + dropboxTag) { 14763 @Override 14764 public void run() { 14765 if (report != null) { 14766 sb.append(report); 14767 } 14768 14769 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 14770 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 14771 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length() 14772 - lines * RESERVED_BYTES_PER_LOGCAT_LINE; 14773 14774 if (dataFile != null && maxDataFileSize > 0) { 14775 try { 14776 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize, 14777 "\n\n[[TRUNCATED]]")); 14778 } catch (IOException e) { 14779 Slog.e(TAG, "Error reading " + dataFile, e); 14780 } 14781 } 14782 if (crashInfo != null && crashInfo.stackTrace != null) { 14783 sb.append(crashInfo.stackTrace); 14784 } 14785 14786 if (lines > 0) { 14787 sb.append("\n"); 14788 14789 // Merge several logcat streams, and take the last N lines 14790 InputStreamReader input = null; 14791 try { 14792 java.lang.Process logcat = new ProcessBuilder( 14793 "/system/bin/timeout", "-k", "15s", "10s", 14794 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system", 14795 "-b", "main", "-b", "crash", "-t", String.valueOf(lines)) 14796 .redirectErrorStream(true).start(); 14797 14798 try { logcat.getOutputStream().close(); } catch (IOException e) {} 14799 try { logcat.getErrorStream().close(); } catch (IOException e) {} 14800 input = new InputStreamReader(logcat.getInputStream()); 14801 14802 int num; 14803 char[] buf = new char[8192]; 14804 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 14805 } catch (IOException e) { 14806 Slog.e(TAG, "Error running logcat", e); 14807 } finally { 14808 if (input != null) try { input.close(); } catch (IOException e) {} 14809 } 14810 } 14811 14812 dbox.addText(dropboxTag, sb.toString()); 14813 } 14814 }; 14815 14816 if (process == null) { 14817 // If process is null, we are being called from some internal code 14818 // and may be about to die -- run this synchronously. 14819 worker.run(); 14820 } else { 14821 worker.start(); 14822 } 14823 } 14824 14825 @Override 14826 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 14827 enforceNotIsolatedCaller("getProcessesInErrorState"); 14828 // assume our apps are happy - lazy create the list 14829 List<ActivityManager.ProcessErrorStateInfo> errList = null; 14830 14831 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 14832 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 14833 int userId = UserHandle.getUserId(Binder.getCallingUid()); 14834 14835 synchronized (this) { 14836 14837 // iterate across all processes 14838 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14839 ProcessRecord app = mLruProcesses.get(i); 14840 if (!allUsers && app.userId != userId) { 14841 continue; 14842 } 14843 if ((app.thread != null) && (app.crashing || app.notResponding)) { 14844 // This one's in trouble, so we'll generate a report for it 14845 // crashes are higher priority (in case there's a crash *and* an anr) 14846 ActivityManager.ProcessErrorStateInfo report = null; 14847 if (app.crashing) { 14848 report = app.crashingReport; 14849 } else if (app.notResponding) { 14850 report = app.notRespondingReport; 14851 } 14852 14853 if (report != null) { 14854 if (errList == null) { 14855 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 14856 } 14857 errList.add(report); 14858 } else { 14859 Slog.w(TAG, "Missing app error report, app = " + app.processName + 14860 " crashing = " + app.crashing + 14861 " notResponding = " + app.notResponding); 14862 } 14863 } 14864 } 14865 } 14866 14867 return errList; 14868 } 14869 14870 static int procStateToImportance(int procState, int memAdj, 14871 ActivityManager.RunningAppProcessInfo currApp, 14872 int clientTargetSdk) { 14873 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk( 14874 procState, clientTargetSdk); 14875 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 14876 currApp.lru = memAdj; 14877 } else { 14878 currApp.lru = 0; 14879 } 14880 return imp; 14881 } 14882 14883 private void fillInProcMemInfo(ProcessRecord app, 14884 ActivityManager.RunningAppProcessInfo outInfo, 14885 int clientTargetSdk) { 14886 outInfo.pid = app.pid; 14887 outInfo.uid = app.info.uid; 14888 if (mHeavyWeightProcess == app) { 14889 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 14890 } 14891 if (app.persistent) { 14892 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 14893 } 14894 if (app.activities.size() > 0) { 14895 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 14896 } 14897 outInfo.lastTrimLevel = app.trimMemoryLevel; 14898 int adj = app.curAdj; 14899 int procState = app.curProcState; 14900 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk); 14901 outInfo.importanceReasonCode = app.adjTypeCode; 14902 outInfo.processState = app.curProcState; 14903 } 14904 14905 @Override 14906 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 14907 enforceNotIsolatedCaller("getRunningAppProcesses"); 14908 14909 final int callingUid = Binder.getCallingUid(); 14910 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid); 14911 14912 // Lazy instantiation of list 14913 List<ActivityManager.RunningAppProcessInfo> runList = null; 14914 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 14915 callingUid) == PackageManager.PERMISSION_GRANTED; 14916 final int userId = UserHandle.getUserId(callingUid); 14917 final boolean allUids = isGetTasksAllowed( 14918 "getRunningAppProcesses", Binder.getCallingPid(), callingUid); 14919 14920 synchronized (this) { 14921 // Iterate across all processes 14922 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14923 ProcessRecord app = mLruProcesses.get(i); 14924 if ((!allUsers && app.userId != userId) 14925 || (!allUids && app.uid != callingUid)) { 14926 continue; 14927 } 14928 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 14929 // Generate process state info for running application 14930 ActivityManager.RunningAppProcessInfo currApp = 14931 new ActivityManager.RunningAppProcessInfo(app.processName, 14932 app.pid, app.getPackageList()); 14933 fillInProcMemInfo(app, currApp, clientTargetSdk); 14934 if (app.adjSource instanceof ProcessRecord) { 14935 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 14936 currApp.importanceReasonImportance = 14937 ActivityManager.RunningAppProcessInfo.procStateToImportance( 14938 app.adjSourceProcState); 14939 } else if (app.adjSource instanceof ActivityRecord) { 14940 ActivityRecord r = (ActivityRecord)app.adjSource; 14941 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 14942 } 14943 if (app.adjTarget instanceof ComponentName) { 14944 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 14945 } 14946 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 14947 // + " lru=" + currApp.lru); 14948 if (runList == null) { 14949 runList = new ArrayList<>(); 14950 } 14951 runList.add(currApp); 14952 } 14953 } 14954 } 14955 return runList; 14956 } 14957 14958 @Override 14959 public List<ApplicationInfo> getRunningExternalApplications() { 14960 enforceNotIsolatedCaller("getRunningExternalApplications"); 14961 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 14962 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 14963 if (runningApps != null && runningApps.size() > 0) { 14964 Set<String> extList = new HashSet<String>(); 14965 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 14966 if (app.pkgList != null) { 14967 for (String pkg : app.pkgList) { 14968 extList.add(pkg); 14969 } 14970 } 14971 } 14972 IPackageManager pm = AppGlobals.getPackageManager(); 14973 for (String pkg : extList) { 14974 try { 14975 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 14976 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 14977 retList.add(info); 14978 } 14979 } catch (RemoteException e) { 14980 } 14981 } 14982 } 14983 return retList; 14984 } 14985 14986 @Override 14987 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 14988 enforceNotIsolatedCaller("getMyMemoryState"); 14989 14990 final int callingUid = Binder.getCallingUid(); 14991 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid); 14992 14993 synchronized (this) { 14994 ProcessRecord proc; 14995 synchronized (mPidsSelfLocked) { 14996 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 14997 } 14998 fillInProcMemInfo(proc, outInfo, clientTargetSdk); 14999 } 15000 } 15001 15002 @Override 15003 public int getMemoryTrimLevel() { 15004 enforceNotIsolatedCaller("getMyMemoryState"); 15005 synchronized (this) { 15006 return mLastMemoryLevel; 15007 } 15008 } 15009 15010 @Override 15011 public void onShellCommand(FileDescriptor in, FileDescriptor out, 15012 FileDescriptor err, String[] args, ShellCallback callback, 15013 ResultReceiver resultReceiver) { 15014 (new ActivityManagerShellCommand(this, false)).exec( 15015 this, in, out, err, args, callback, resultReceiver); 15016 } 15017 15018 SleepToken acquireSleepToken(String tag, int displayId) { 15019 synchronized (this) { 15020 final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId); 15021 updateSleepIfNeededLocked(); 15022 return token; 15023 } 15024 } 15025 15026 @Override 15027 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 15028 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return; 15029 15030 boolean dumpAll = false; 15031 boolean dumpClient = false; 15032 boolean dumpCheckin = false; 15033 boolean dumpCheckinFormat = false; 15034 boolean dumpVisibleStacksOnly = false; 15035 boolean dumpFocusedStackOnly = false; 15036 String dumpPackage = null; 15037 15038 int opti = 0; 15039 while (opti < args.length) { 15040 String opt = args[opti]; 15041 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 15042 break; 15043 } 15044 opti++; 15045 if ("-a".equals(opt)) { 15046 dumpAll = true; 15047 } else if ("-c".equals(opt)) { 15048 dumpClient = true; 15049 } else if ("-v".equals(opt)) { 15050 dumpVisibleStacksOnly = true; 15051 } else if ("-f".equals(opt)) { 15052 dumpFocusedStackOnly = true; 15053 } else if ("-p".equals(opt)) { 15054 if (opti < args.length) { 15055 dumpPackage = args[opti]; 15056 opti++; 15057 } else { 15058 pw.println("Error: -p option requires package argument"); 15059 return; 15060 } 15061 dumpClient = true; 15062 } else if ("--checkin".equals(opt)) { 15063 dumpCheckin = dumpCheckinFormat = true; 15064 } else if ("-C".equals(opt)) { 15065 dumpCheckinFormat = true; 15066 } else if ("-h".equals(opt)) { 15067 ActivityManagerShellCommand.dumpHelp(pw, true); 15068 return; 15069 } else { 15070 pw.println("Unknown argument: " + opt + "; use -h for help"); 15071 } 15072 } 15073 15074 long origId = Binder.clearCallingIdentity(); 15075 boolean more = false; 15076 // Is the caller requesting to dump a particular piece of data? 15077 if (opti < args.length) { 15078 String cmd = args[opti]; 15079 opti++; 15080 if ("activities".equals(cmd) || "a".equals(cmd)) { 15081 synchronized (this) { 15082 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 15083 } 15084 } else if ("lastanr".equals(cmd)) { 15085 synchronized (this) { 15086 dumpLastANRLocked(pw); 15087 } 15088 } else if ("starter".equals(cmd)) { 15089 synchronized (this) { 15090 dumpActivityStarterLocked(pw, dumpPackage); 15091 } 15092 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 15093 synchronized (this) { 15094 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage); 15095 } 15096 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 15097 String[] newArgs; 15098 String name; 15099 if (opti >= args.length) { 15100 name = null; 15101 newArgs = EMPTY_STRING_ARRAY; 15102 } else { 15103 dumpPackage = args[opti]; 15104 opti++; 15105 newArgs = new String[args.length - opti]; 15106 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 15107 args.length - opti); 15108 } 15109 synchronized (this) { 15110 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); 15111 } 15112 } else if ("broadcast-stats".equals(cmd)) { 15113 String[] newArgs; 15114 String name; 15115 if (opti >= args.length) { 15116 name = null; 15117 newArgs = EMPTY_STRING_ARRAY; 15118 } else { 15119 dumpPackage = args[opti]; 15120 opti++; 15121 newArgs = new String[args.length - opti]; 15122 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 15123 args.length - opti); 15124 } 15125 synchronized (this) { 15126 if (dumpCheckinFormat) { 15127 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, 15128 dumpPackage); 15129 } else { 15130 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage); 15131 } 15132 } 15133 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 15134 String[] newArgs; 15135 String name; 15136 if (opti >= args.length) { 15137 name = null; 15138 newArgs = EMPTY_STRING_ARRAY; 15139 } else { 15140 dumpPackage = args[opti]; 15141 opti++; 15142 newArgs = new String[args.length - opti]; 15143 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 15144 args.length - opti); 15145 } 15146 synchronized (this) { 15147 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); 15148 } 15149 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 15150 String[] newArgs; 15151 String name; 15152 if (opti >= args.length) { 15153 name = null; 15154 newArgs = EMPTY_STRING_ARRAY; 15155 } else { 15156 dumpPackage = args[opti]; 15157 opti++; 15158 newArgs = new String[args.length - opti]; 15159 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 15160 args.length - opti); 15161 } 15162 synchronized (this) { 15163 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); 15164 } 15165 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 15166 synchronized (this) { 15167 dumpOomLocked(fd, pw, args, opti, true); 15168 } 15169 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) { 15170 synchronized (this) { 15171 dumpPermissionsLocked(fd, pw, args, opti, true, null); 15172 } 15173 } else if ("provider".equals(cmd)) { 15174 String[] newArgs; 15175 String name; 15176 if (opti >= args.length) { 15177 name = null; 15178 newArgs = EMPTY_STRING_ARRAY; 15179 } else { 15180 name = args[opti]; 15181 opti++; 15182 newArgs = new String[args.length - opti]; 15183 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 15184 } 15185 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 15186 pw.println("No providers match: " + name); 15187 pw.println("Use -h for help."); 15188 } 15189 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 15190 synchronized (this) { 15191 dumpProvidersLocked(fd, pw, args, opti, true, null); 15192 } 15193 } else if ("service".equals(cmd)) { 15194 String[] newArgs; 15195 String name; 15196 if (opti >= args.length) { 15197 name = null; 15198 newArgs = EMPTY_STRING_ARRAY; 15199 } else { 15200 name = args[opti]; 15201 opti++; 15202 newArgs = new String[args.length - opti]; 15203 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 15204 args.length - opti); 15205 } 15206 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 15207 pw.println("No services match: " + name); 15208 pw.println("Use -h for help."); 15209 } 15210 } else if ("package".equals(cmd)) { 15211 String[] newArgs; 15212 if (opti >= args.length) { 15213 pw.println("package: no package name specified"); 15214 pw.println("Use -h for help."); 15215 } else { 15216 dumpPackage = args[opti]; 15217 opti++; 15218 newArgs = new String[args.length - opti]; 15219 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 15220 args.length - opti); 15221 args = newArgs; 15222 opti = 0; 15223 more = true; 15224 } 15225 } else if ("associations".equals(cmd) || "as".equals(cmd)) { 15226 synchronized (this) { 15227 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 15228 } 15229 } else if ("settings".equals(cmd)) { 15230 synchronized (this) { 15231 mConstants.dump(pw); 15232 } 15233 } else if ("services".equals(cmd) || "s".equals(cmd)) { 15234 if (dumpClient) { 15235 ActiveServices.ServiceDumper dumper; 15236 synchronized (this) { 15237 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true, 15238 dumpPackage); 15239 } 15240 dumper.dumpWithClient(); 15241 } else { 15242 synchronized (this) { 15243 mServices.newServiceDumperLocked(fd, pw, args, opti, true, 15244 dumpPackage).dumpLocked(); 15245 } 15246 } 15247 } else if ("locks".equals(cmd)) { 15248 LockGuard.dump(fd, pw, args); 15249 } else { 15250 // Dumping a single activity? 15251 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly, 15252 dumpFocusedStackOnly)) { 15253 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true); 15254 int res = shell.exec(this, null, fd, null, args, null, 15255 new ResultReceiver(null)); 15256 if (res < 0) { 15257 pw.println("Bad activity command, or no activities match: " + cmd); 15258 pw.println("Use -h for help."); 15259 } 15260 } 15261 } 15262 if (!more) { 15263 Binder.restoreCallingIdentity(origId); 15264 return; 15265 } 15266 } 15267 15268 // No piece of data specified, dump everything. 15269 if (dumpCheckinFormat) { 15270 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage); 15271 } else if (dumpClient) { 15272 ActiveServices.ServiceDumper sdumper; 15273 synchronized (this) { 15274 mConstants.dump(pw); 15275 pw.println(); 15276 if (dumpAll) { 15277 pw.println("-------------------------------------------------------------------------------"); 15278 } 15279 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15280 pw.println(); 15281 if (dumpAll) { 15282 pw.println("-------------------------------------------------------------------------------"); 15283 } 15284 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15285 pw.println(); 15286 if (dumpAll) { 15287 pw.println("-------------------------------------------------------------------------------"); 15288 } 15289 if (dumpAll || dumpPackage != null) { 15290 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15291 pw.println(); 15292 if (dumpAll) { 15293 pw.println("-------------------------------------------------------------------------------"); 15294 } 15295 } 15296 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15297 pw.println(); 15298 if (dumpAll) { 15299 pw.println("-------------------------------------------------------------------------------"); 15300 } 15301 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15302 pw.println(); 15303 if (dumpAll) { 15304 pw.println("-------------------------------------------------------------------------------"); 15305 } 15306 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, 15307 dumpPackage); 15308 } 15309 sdumper.dumpWithClient(); 15310 pw.println(); 15311 synchronized (this) { 15312 if (dumpAll) { 15313 pw.println("-------------------------------------------------------------------------------"); 15314 } 15315 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15316 pw.println(); 15317 if (dumpAll) { 15318 pw.println("-------------------------------------------------------------------------------"); 15319 } 15320 dumpLastANRLocked(pw); 15321 pw.println(); 15322 if (dumpAll) { 15323 pw.println("-------------------------------------------------------------------------------"); 15324 } 15325 dumpActivityStarterLocked(pw, dumpPackage); 15326 pw.println(); 15327 if (dumpAll) { 15328 pw.println("-------------------------------------------------------------------------------"); 15329 } 15330 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 15331 if (mAssociations.size() > 0) { 15332 pw.println(); 15333 if (dumpAll) { 15334 pw.println("-------------------------------------------------------------------------------"); 15335 } 15336 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 15337 } 15338 pw.println(); 15339 if (dumpAll) { 15340 pw.println("-------------------------------------------------------------------------------"); 15341 } 15342 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15343 } 15344 15345 } else { 15346 synchronized (this) { 15347 mConstants.dump(pw); 15348 pw.println(); 15349 if (dumpAll) { 15350 pw.println("-------------------------------------------------------------------------------"); 15351 } 15352 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15353 pw.println(); 15354 if (dumpAll) { 15355 pw.println("-------------------------------------------------------------------------------"); 15356 } 15357 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15358 pw.println(); 15359 if (dumpAll) { 15360 pw.println("-------------------------------------------------------------------------------"); 15361 } 15362 if (dumpAll || dumpPackage != null) { 15363 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15364 pw.println(); 15365 if (dumpAll) { 15366 pw.println("-------------------------------------------------------------------------------"); 15367 } 15368 } 15369 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15370 pw.println(); 15371 if (dumpAll) { 15372 pw.println("-------------------------------------------------------------------------------"); 15373 } 15374 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15375 pw.println(); 15376 if (dumpAll) { 15377 pw.println("-------------------------------------------------------------------------------"); 15378 } 15379 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage) 15380 .dumpLocked(); 15381 pw.println(); 15382 if (dumpAll) { 15383 pw.println("-------------------------------------------------------------------------------"); 15384 } 15385 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15386 pw.println(); 15387 if (dumpAll) { 15388 pw.println("-------------------------------------------------------------------------------"); 15389 } 15390 dumpLastANRLocked(pw); 15391 pw.println(); 15392 if (dumpAll) { 15393 pw.println("-------------------------------------------------------------------------------"); 15394 } 15395 dumpActivityStarterLocked(pw, dumpPackage); 15396 pw.println(); 15397 if (dumpAll) { 15398 pw.println("-------------------------------------------------------------------------------"); 15399 } 15400 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 15401 if (mAssociations.size() > 0) { 15402 pw.println(); 15403 if (dumpAll) { 15404 pw.println("-------------------------------------------------------------------------------"); 15405 } 15406 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 15407 } 15408 pw.println(); 15409 if (dumpAll) { 15410 pw.println("-------------------------------------------------------------------------------"); 15411 } 15412 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 15413 } 15414 } 15415 Binder.restoreCallingIdentity(origId); 15416 } 15417 15418 private void dumpLastANRLocked(PrintWriter pw) { 15419 pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)"); 15420 if (mLastANRState == null) { 15421 pw.println(" <no ANR has occurred since boot>"); 15422 } else { 15423 pw.println(mLastANRState); 15424 } 15425 } 15426 15427 private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) { 15428 pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)"); 15429 mActivityStarter.dump(pw, "", dumpPackage); 15430 } 15431 15432 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15433 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 15434 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage, 15435 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 15436 } 15437 15438 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15439 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) { 15440 pw.println(header); 15441 15442 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 15443 dumpPackage); 15444 boolean needSep = printedAnything; 15445 15446 boolean printed = ActivityStackSupervisor.printThisActivity(pw, 15447 mStackSupervisor.getResumedActivityLocked(), 15448 dumpPackage, needSep, " ResumedActivity: "); 15449 if (printed) { 15450 printedAnything = true; 15451 needSep = false; 15452 } 15453 15454 if (dumpPackage == null) { 15455 if (needSep) { 15456 pw.println(); 15457 } 15458 printedAnything = true; 15459 mStackSupervisor.dump(pw, " "); 15460 } 15461 15462 if (!printedAnything) { 15463 pw.println(" (nothing)"); 15464 } 15465 } 15466 15467 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15468 int opti, boolean dumpAll, String dumpPackage) { 15469 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 15470 15471 boolean printedAnything = false; 15472 15473 if (mRecentTasks != null && mRecentTasks.size() > 0) { 15474 boolean printedHeader = false; 15475 15476 final int N = mRecentTasks.size(); 15477 for (int i=0; i<N; i++) { 15478 TaskRecord tr = mRecentTasks.get(i); 15479 if (dumpPackage != null) { 15480 if (tr.realActivity == null || 15481 !dumpPackage.equals(tr.realActivity.getPackageName())) { 15482 continue; 15483 } 15484 } 15485 if (!printedHeader) { 15486 pw.println(" Recent tasks:"); 15487 printedHeader = true; 15488 printedAnything = true; 15489 } 15490 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 15491 pw.println(tr); 15492 if (dumpAll) { 15493 mRecentTasks.get(i).dump(pw, " "); 15494 } 15495 } 15496 } 15497 15498 if (!printedAnything) { 15499 pw.println(" (nothing)"); 15500 } 15501 } 15502 15503 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15504 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 15505 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)"); 15506 15507 int dumpUid = 0; 15508 if (dumpPackage != null) { 15509 IPackageManager pm = AppGlobals.getPackageManager(); 15510 try { 15511 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0); 15512 } catch (RemoteException e) { 15513 } 15514 } 15515 15516 boolean printedAnything = false; 15517 15518 final long now = SystemClock.uptimeMillis(); 15519 15520 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 15521 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 15522 = mAssociations.valueAt(i1); 15523 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 15524 SparseArray<ArrayMap<String, Association>> sourceUids 15525 = targetComponents.valueAt(i2); 15526 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) { 15527 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3); 15528 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 15529 Association ass = sourceProcesses.valueAt(i4); 15530 if (dumpPackage != null) { 15531 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage) 15532 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) { 15533 continue; 15534 } 15535 } 15536 printedAnything = true; 15537 pw.print(" "); 15538 pw.print(ass.mTargetProcess); 15539 pw.print("/"); 15540 UserHandle.formatUid(pw, ass.mTargetUid); 15541 pw.print(" <- "); 15542 pw.print(ass.mSourceProcess); 15543 pw.print("/"); 15544 UserHandle.formatUid(pw, ass.mSourceUid); 15545 pw.println(); 15546 pw.print(" via "); 15547 pw.print(ass.mTargetComponent.flattenToShortString()); 15548 pw.println(); 15549 pw.print(" "); 15550 long dur = ass.mTime; 15551 if (ass.mNesting > 0) { 15552 dur += now - ass.mStartTime; 15553 } 15554 TimeUtils.formatDuration(dur, pw); 15555 pw.print(" ("); 15556 pw.print(ass.mCount); 15557 pw.print(" times)"); 15558 pw.print(" "); 15559 for (int i=0; i<ass.mStateTimes.length; i++) { 15560 long amt = ass.mStateTimes[i]; 15561 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) { 15562 amt += now - ass.mLastStateUptime; 15563 } 15564 if (amt != 0) { 15565 pw.print(" "); 15566 pw.print(ProcessList.makeProcStateString( 15567 i + ActivityManager.MIN_PROCESS_STATE)); 15568 pw.print("="); 15569 TimeUtils.formatDuration(amt, pw); 15570 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) { 15571 pw.print("*"); 15572 } 15573 } 15574 } 15575 pw.println(); 15576 if (ass.mNesting > 0) { 15577 pw.print(" Currently active: "); 15578 TimeUtils.formatDuration(now - ass.mStartTime, pw); 15579 pw.println(); 15580 } 15581 } 15582 } 15583 } 15584 15585 } 15586 15587 if (!printedAnything) { 15588 pw.println(" (nothing)"); 15589 } 15590 } 15591 15592 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids, 15593 String header, boolean needSep) { 15594 boolean printed = false; 15595 int whichAppId = -1; 15596 if (dumpPackage != null) { 15597 try { 15598 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 15599 dumpPackage, 0); 15600 whichAppId = UserHandle.getAppId(info.uid); 15601 } catch (NameNotFoundException e) { 15602 e.printStackTrace(); 15603 } 15604 } 15605 for (int i=0; i<uids.size(); i++) { 15606 UidRecord uidRec = uids.valueAt(i); 15607 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) { 15608 continue; 15609 } 15610 if (!printed) { 15611 printed = true; 15612 if (needSep) { 15613 pw.println(); 15614 } 15615 pw.print(" "); 15616 pw.println(header); 15617 needSep = true; 15618 } 15619 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid); 15620 pw.print(": "); pw.println(uidRec); 15621 } 15622 return printed; 15623 } 15624 15625 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15626 int opti, boolean dumpAll, String dumpPackage) { 15627 boolean needSep = false; 15628 boolean printedAnything = false; 15629 int numPers = 0; 15630 15631 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 15632 15633 if (dumpAll) { 15634 final int NP = mProcessNames.getMap().size(); 15635 for (int ip=0; ip<NP; ip++) { 15636 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 15637 final int NA = procs.size(); 15638 for (int ia=0; ia<NA; ia++) { 15639 ProcessRecord r = procs.valueAt(ia); 15640 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 15641 continue; 15642 } 15643 if (!needSep) { 15644 pw.println(" All known processes:"); 15645 needSep = true; 15646 printedAnything = true; 15647 } 15648 pw.print(r.persistent ? " *PERS*" : " *APP*"); 15649 pw.print(" UID "); pw.print(procs.keyAt(ia)); 15650 pw.print(" "); pw.println(r); 15651 r.dump(pw, " "); 15652 if (r.persistent) { 15653 numPers++; 15654 } 15655 } 15656 } 15657 } 15658 15659 if (mIsolatedProcesses.size() > 0) { 15660 boolean printed = false; 15661 for (int i=0; i<mIsolatedProcesses.size(); i++) { 15662 ProcessRecord r = mIsolatedProcesses.valueAt(i); 15663 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 15664 continue; 15665 } 15666 if (!printed) { 15667 if (needSep) { 15668 pw.println(); 15669 } 15670 pw.println(" Isolated process list (sorted by uid):"); 15671 printedAnything = true; 15672 printed = true; 15673 needSep = true; 15674 } 15675 pw.print(" Isolated #"); pw.print(i); pw.print(": "); 15676 pw.println(r); 15677 } 15678 } 15679 15680 if (mActiveInstrumentation.size() > 0) { 15681 boolean printed = false; 15682 for (int i=0; i<mActiveInstrumentation.size(); i++) { 15683 ActiveInstrumentation ai = mActiveInstrumentation.get(i); 15684 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage) 15685 && !ai.mTargetInfo.packageName.equals(dumpPackage)) { 15686 continue; 15687 } 15688 if (!printed) { 15689 if (needSep) { 15690 pw.println(); 15691 } 15692 pw.println(" Active instrumentation:"); 15693 printedAnything = true; 15694 printed = true; 15695 needSep = true; 15696 } 15697 pw.print(" Instrumentation #"); pw.print(i); pw.print(": "); 15698 pw.println(ai); 15699 ai.dump(pw, " "); 15700 } 15701 } 15702 15703 if (mActiveUids.size() > 0) { 15704 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) { 15705 printedAnything = needSep = true; 15706 } 15707 } 15708 if (dumpAll) { 15709 if (mValidateUids.size() > 0) { 15710 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) { 15711 printedAnything = needSep = true; 15712 } 15713 } 15714 } 15715 15716 if (mLruProcesses.size() > 0) { 15717 if (needSep) { 15718 pw.println(); 15719 } 15720 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 15721 pw.print(" total, non-act at "); 15722 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 15723 pw.print(", non-svc at "); 15724 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 15725 pw.println("):"); 15726 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 15727 needSep = true; 15728 printedAnything = true; 15729 } 15730 15731 if (dumpAll || dumpPackage != null) { 15732 synchronized (mPidsSelfLocked) { 15733 boolean printed = false; 15734 for (int i=0; i<mPidsSelfLocked.size(); i++) { 15735 ProcessRecord r = mPidsSelfLocked.valueAt(i); 15736 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 15737 continue; 15738 } 15739 if (!printed) { 15740 if (needSep) pw.println(); 15741 needSep = true; 15742 pw.println(" PID mappings:"); 15743 printed = true; 15744 printedAnything = true; 15745 } 15746 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 15747 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 15748 } 15749 } 15750 } 15751 15752 if (mImportantProcesses.size() > 0) { 15753 synchronized (mPidsSelfLocked) { 15754 boolean printed = false; 15755 for (int i = 0; i< mImportantProcesses.size(); i++) { 15756 ProcessRecord r = mPidsSelfLocked.get( 15757 mImportantProcesses.valueAt(i).pid); 15758 if (dumpPackage != null && (r == null 15759 || !r.pkgList.containsKey(dumpPackage))) { 15760 continue; 15761 } 15762 if (!printed) { 15763 if (needSep) pw.println(); 15764 needSep = true; 15765 pw.println(" Foreground Processes:"); 15766 printed = true; 15767 printedAnything = true; 15768 } 15769 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i)); 15770 pw.print(": "); pw.println(mImportantProcesses.valueAt(i)); 15771 } 15772 } 15773 } 15774 15775 if (mPersistentStartingProcesses.size() > 0) { 15776 if (needSep) pw.println(); 15777 needSep = true; 15778 printedAnything = true; 15779 pw.println(" Persisent processes that are starting:"); 15780 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 15781 "Starting Norm", "Restarting PERS", dumpPackage); 15782 } 15783 15784 if (mRemovedProcesses.size() > 0) { 15785 if (needSep) pw.println(); 15786 needSep = true; 15787 printedAnything = true; 15788 pw.println(" Processes that are being removed:"); 15789 dumpProcessList(pw, this, mRemovedProcesses, " ", 15790 "Removed Norm", "Removed PERS", dumpPackage); 15791 } 15792 15793 if (mProcessesOnHold.size() > 0) { 15794 if (needSep) pw.println(); 15795 needSep = true; 15796 printedAnything = true; 15797 pw.println(" Processes that are on old until the system is ready:"); 15798 dumpProcessList(pw, this, mProcessesOnHold, " ", 15799 "OnHold Norm", "OnHold PERS", dumpPackage); 15800 } 15801 15802 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 15803 15804 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage); 15805 if (needSep) { 15806 printedAnything = true; 15807 } 15808 15809 if (dumpPackage == null) { 15810 pw.println(); 15811 needSep = false; 15812 mUserController.dump(pw, dumpAll); 15813 } 15814 if (mHomeProcess != null && (dumpPackage == null 15815 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 15816 if (needSep) { 15817 pw.println(); 15818 needSep = false; 15819 } 15820 pw.println(" mHomeProcess: " + mHomeProcess); 15821 } 15822 if (mPreviousProcess != null && (dumpPackage == null 15823 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 15824 if (needSep) { 15825 pw.println(); 15826 needSep = false; 15827 } 15828 pw.println(" mPreviousProcess: " + mPreviousProcess); 15829 } 15830 if (dumpAll) { 15831 StringBuilder sb = new StringBuilder(128); 15832 sb.append(" mPreviousProcessVisibleTime: "); 15833 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 15834 pw.println(sb); 15835 } 15836 if (mHeavyWeightProcess != null && (dumpPackage == null 15837 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 15838 if (needSep) { 15839 pw.println(); 15840 needSep = false; 15841 } 15842 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 15843 } 15844 if (dumpPackage == null) { 15845 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration()); 15846 mStackSupervisor.dumpDisplayConfigs(pw, " "); 15847 } 15848 if (dumpAll) { 15849 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 15850 if (mCompatModePackages.getPackages().size() > 0) { 15851 boolean printed = false; 15852 for (Map.Entry<String, Integer> entry 15853 : mCompatModePackages.getPackages().entrySet()) { 15854 String pkg = entry.getKey(); 15855 int mode = entry.getValue(); 15856 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 15857 continue; 15858 } 15859 if (!printed) { 15860 pw.println(" mScreenCompatPackages:"); 15861 printed = true; 15862 } 15863 pw.print(" "); pw.print(pkg); pw.print(": "); 15864 pw.print(mode); pw.println(); 15865 } 15866 } 15867 final int NI = mUidObservers.getRegisteredCallbackCount(); 15868 boolean printed = false; 15869 for (int i=0; i<NI; i++) { 15870 final UidObserverRegistration reg = (UidObserverRegistration) 15871 mUidObservers.getRegisteredCallbackCookie(i); 15872 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) { 15873 if (!printed) { 15874 pw.println(" mUidObservers:"); 15875 printed = true; 15876 } 15877 pw.print(" "); UserHandle.formatUid(pw, reg.uid); 15878 pw.print(" "); pw.print(reg.pkg); pw.print(":"); 15879 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) { 15880 pw.print(" IDLE"); 15881 } 15882 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) { 15883 pw.print(" ACT" ); 15884 } 15885 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) { 15886 pw.print(" GONE"); 15887 } 15888 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) { 15889 pw.print(" STATE"); 15890 pw.print(" (cut="); pw.print(reg.cutpoint); 15891 pw.print(")"); 15892 } 15893 pw.println(); 15894 if (reg.lastProcStates != null) { 15895 final int NJ = reg.lastProcStates.size(); 15896 for (int j=0; j<NJ; j++) { 15897 pw.print(" Last "); 15898 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j)); 15899 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j)); 15900 } 15901 } 15902 } 15903 } 15904 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist)); 15905 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist)); 15906 if (mPendingTempWhitelist.size() > 0) { 15907 pw.println(" mPendingTempWhitelist:"); 15908 for (int i = 0; i < mPendingTempWhitelist.size(); i++) { 15909 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i); 15910 pw.print(" "); 15911 UserHandle.formatUid(pw, ptw.targetUid); 15912 pw.print(": "); 15913 TimeUtils.formatDuration(ptw.duration, pw); 15914 pw.print(" "); 15915 pw.println(ptw.tag); 15916 } 15917 } 15918 } 15919 if (dumpPackage == null) { 15920 pw.println(" mWakefulness=" 15921 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 15922 pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens); 15923 pw.println(" mSleeping=" + mSleeping); 15924 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode); 15925 if (mRunningVoice != null) { 15926 pw.println(" mRunningVoice=" + mRunningVoice); 15927 pw.println(" mVoiceWakeLock" + mVoiceWakeLock); 15928 } 15929 } 15930 pw.println(" mVrController=" + mVrController); 15931 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 15932 || mOrigWaitForDebugger) { 15933 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 15934 || dumpPackage.equals(mOrigDebugApp)) { 15935 if (needSep) { 15936 pw.println(); 15937 needSep = false; 15938 } 15939 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 15940 + " mDebugTransient=" + mDebugTransient 15941 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 15942 } 15943 } 15944 if (mCurAppTimeTracker != null) { 15945 mCurAppTimeTracker.dumpWithHeader(pw, " ", true); 15946 } 15947 if (mMemWatchProcesses.getMap().size() > 0) { 15948 pw.println(" Mem watch processes:"); 15949 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs 15950 = mMemWatchProcesses.getMap(); 15951 for (int i=0; i<procs.size(); i++) { 15952 final String proc = procs.keyAt(i); 15953 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i); 15954 for (int j=0; j<uids.size(); j++) { 15955 if (needSep) { 15956 pw.println(); 15957 needSep = false; 15958 } 15959 StringBuilder sb = new StringBuilder(); 15960 sb.append(" ").append(proc).append('/'); 15961 UserHandle.formatUid(sb, uids.keyAt(j)); 15962 Pair<Long, String> val = uids.valueAt(j); 15963 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb); 15964 if (val.second != null) { 15965 sb.append(", report to ").append(val.second); 15966 } 15967 pw.println(sb.toString()); 15968 } 15969 } 15970 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName); 15971 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile); 15972 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid); 15973 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid); 15974 } 15975 if (mTrackAllocationApp != null) { 15976 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) { 15977 if (needSep) { 15978 pw.println(); 15979 needSep = false; 15980 } 15981 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp); 15982 } 15983 } 15984 if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null && 15985 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) { 15986 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 15987 if (needSep) { 15988 pw.println(); 15989 needSep = false; 15990 } 15991 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 15992 if (mProfilerInfo != null) { 15993 pw.println(" mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" + 15994 mProfilerInfo.profileFd); 15995 pw.println(" mSamplingInterval=" + mProfilerInfo.samplingInterval + 15996 " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler + 15997 " mStreamingOutput=" + mProfilerInfo.streamingOutput); 15998 pw.println(" mProfileType=" + mProfileType); 15999 } 16000 } 16001 } 16002 if (mNativeDebuggingApp != null) { 16003 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) { 16004 if (needSep) { 16005 pw.println(); 16006 needSep = false; 16007 } 16008 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp); 16009 } 16010 } 16011 if (dumpPackage == null) { 16012 if (mAlwaysFinishActivities) { 16013 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities); 16014 } 16015 if (mController != null) { 16016 pw.println(" mController=" + mController 16017 + " mControllerIsAMonkey=" + mControllerIsAMonkey); 16018 } 16019 if (dumpAll) { 16020 pw.println(" Total persistent processes: " + numPers); 16021 pw.println(" mProcessesReady=" + mProcessesReady 16022 + " mSystemReady=" + mSystemReady 16023 + " mBooted=" + mBooted 16024 + " mFactoryTest=" + mFactoryTest); 16025 pw.println(" mBooting=" + mBooting 16026 + " mCallFinishBooting=" + mCallFinishBooting 16027 + " mBootAnimationComplete=" + mBootAnimationComplete); 16028 pw.print(" mLastPowerCheckUptime="); 16029 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 16030 pw.println(""); 16031 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 16032 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 16033 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 16034 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 16035 + " (" + mLruProcesses.size() + " total)" 16036 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 16037 + " mNumServiceProcs=" + mNumServiceProcs 16038 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 16039 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 16040 + " mLastMemoryLevel=" + mLastMemoryLevel 16041 + " mLastNumProcesses=" + mLastNumProcesses); 16042 long now = SystemClock.uptimeMillis(); 16043 pw.print(" mLastIdleTime="); 16044 TimeUtils.formatDuration(now, mLastIdleTime, pw); 16045 pw.print(" mLowRamSinceLastIdle="); 16046 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 16047 pw.println(); 16048 } 16049 } 16050 16051 if (!printedAnything) { 16052 pw.println(" (nothing)"); 16053 } 16054 } 16055 16056 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 16057 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 16058 if (mProcessesToGc.size() > 0) { 16059 boolean printed = false; 16060 long now = SystemClock.uptimeMillis(); 16061 for (int i=0; i<mProcessesToGc.size(); i++) { 16062 ProcessRecord proc = mProcessesToGc.get(i); 16063 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 16064 continue; 16065 } 16066 if (!printed) { 16067 if (needSep) pw.println(); 16068 needSep = true; 16069 pw.println(" Processes that are waiting to GC:"); 16070 printed = true; 16071 } 16072 pw.print(" Process "); pw.println(proc); 16073 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 16074 pw.print(", last gced="); 16075 pw.print(now-proc.lastRequestedGc); 16076 pw.print(" ms ago, last lowMem="); 16077 pw.print(now-proc.lastLowMemory); 16078 pw.println(" ms ago"); 16079 16080 } 16081 } 16082 return needSep; 16083 } 16084 16085 void printOomLevel(PrintWriter pw, String name, int adj) { 16086 pw.print(" "); 16087 if (adj >= 0) { 16088 pw.print(' '); 16089 if (adj < 10) pw.print(' '); 16090 } else { 16091 if (adj > -10) pw.print(' '); 16092 } 16093 pw.print(adj); 16094 pw.print(": "); 16095 pw.print(name); 16096 pw.print(" ("); 16097 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024)); 16098 pw.println(")"); 16099 } 16100 16101 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16102 int opti, boolean dumpAll) { 16103 boolean needSep = false; 16104 16105 if (mLruProcesses.size() > 0) { 16106 if (needSep) pw.println(); 16107 needSep = true; 16108 pw.println(" OOM levels:"); 16109 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 16110 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 16111 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 16112 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 16113 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 16114 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 16115 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 16116 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 16117 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 16118 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 16119 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 16120 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 16121 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 16122 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 16123 16124 if (needSep) pw.println(); 16125 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 16126 pw.print(" total, non-act at "); 16127 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 16128 pw.print(", non-svc at "); 16129 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 16130 pw.println("):"); 16131 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 16132 needSep = true; 16133 } 16134 16135 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 16136 16137 pw.println(); 16138 pw.println(" mHomeProcess: " + mHomeProcess); 16139 pw.println(" mPreviousProcess: " + mPreviousProcess); 16140 if (mHeavyWeightProcess != null) { 16141 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 16142 } 16143 16144 return true; 16145 } 16146 16147 /** 16148 * There are three ways to call this: 16149 * - no provider specified: dump all the providers 16150 * - a flattened component name that matched an existing provider was specified as the 16151 * first arg: dump that one provider 16152 * - the first arg isn't the flattened component name of an existing provider: 16153 * dump all providers whose component contains the first arg as a substring 16154 */ 16155 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 16156 int opti, boolean dumpAll) { 16157 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 16158 } 16159 16160 static class ItemMatcher { 16161 ArrayList<ComponentName> components; 16162 ArrayList<String> strings; 16163 ArrayList<Integer> objects; 16164 boolean all; 16165 16166 ItemMatcher() { 16167 all = true; 16168 } 16169 16170 void build(String name) { 16171 ComponentName componentName = ComponentName.unflattenFromString(name); 16172 if (componentName != null) { 16173 if (components == null) { 16174 components = new ArrayList<ComponentName>(); 16175 } 16176 components.add(componentName); 16177 all = false; 16178 } else { 16179 int objectId = 0; 16180 // Not a '/' separated full component name; maybe an object ID? 16181 try { 16182 objectId = Integer.parseInt(name, 16); 16183 if (objects == null) { 16184 objects = new ArrayList<Integer>(); 16185 } 16186 objects.add(objectId); 16187 all = false; 16188 } catch (RuntimeException e) { 16189 // Not an integer; just do string match. 16190 if (strings == null) { 16191 strings = new ArrayList<String>(); 16192 } 16193 strings.add(name); 16194 all = false; 16195 } 16196 } 16197 } 16198 16199 int build(String[] args, int opti) { 16200 for (; opti<args.length; opti++) { 16201 String name = args[opti]; 16202 if ("--".equals(name)) { 16203 return opti+1; 16204 } 16205 build(name); 16206 } 16207 return opti; 16208 } 16209 16210 boolean match(Object object, ComponentName comp) { 16211 if (all) { 16212 return true; 16213 } 16214 if (components != null) { 16215 for (int i=0; i<components.size(); i++) { 16216 if (components.get(i).equals(comp)) { 16217 return true; 16218 } 16219 } 16220 } 16221 if (objects != null) { 16222 for (int i=0; i<objects.size(); i++) { 16223 if (System.identityHashCode(object) == objects.get(i)) { 16224 return true; 16225 } 16226 } 16227 } 16228 if (strings != null) { 16229 String flat = comp.flattenToString(); 16230 for (int i=0; i<strings.size(); i++) { 16231 if (flat.contains(strings.get(i))) { 16232 return true; 16233 } 16234 } 16235 } 16236 return false; 16237 } 16238 } 16239 16240 /** 16241 * There are three things that cmd can be: 16242 * - a flattened component name that matches an existing activity 16243 * - the cmd arg isn't the flattened component name of an existing activity: 16244 * dump all activity whose component contains the cmd as a substring 16245 * - A hex number of the ActivityRecord object instance. 16246 * 16247 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack 16248 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack 16249 */ 16250 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 16251 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) { 16252 ArrayList<ActivityRecord> activities; 16253 16254 synchronized (this) { 16255 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly, 16256 dumpFocusedStackOnly); 16257 } 16258 16259 if (activities.size() <= 0) { 16260 return false; 16261 } 16262 16263 String[] newArgs = new String[args.length - opti]; 16264 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 16265 16266 TaskRecord lastTask = null; 16267 boolean needSep = false; 16268 for (int i=activities.size()-1; i>=0; i--) { 16269 ActivityRecord r = activities.get(i); 16270 if (needSep) { 16271 pw.println(); 16272 } 16273 needSep = true; 16274 synchronized (this) { 16275 final TaskRecord task = r.getTask(); 16276 if (lastTask != task) { 16277 lastTask = task; 16278 pw.print("TASK "); pw.print(lastTask.affinity); 16279 pw.print(" id="); pw.print(lastTask.taskId); 16280 pw.print(" userId="); pw.println(lastTask.userId); 16281 if (dumpAll) { 16282 lastTask.dump(pw, " "); 16283 } 16284 } 16285 } 16286 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 16287 } 16288 return true; 16289 } 16290 16291 /** 16292 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 16293 * there is a thread associated with the activity. 16294 */ 16295 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 16296 final ActivityRecord r, String[] args, boolean dumpAll) { 16297 String innerPrefix = prefix + " "; 16298 synchronized (this) { 16299 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 16300 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 16301 pw.print(" pid="); 16302 if (r.app != null) pw.println(r.app.pid); 16303 else pw.println("(not running)"); 16304 if (dumpAll) { 16305 r.dump(pw, innerPrefix); 16306 } 16307 } 16308 if (r.app != null && r.app.thread != null) { 16309 // flush anything that is already in the PrintWriter since the thread is going 16310 // to write to the file descriptor directly 16311 pw.flush(); 16312 try { 16313 TransferPipe tp = new TransferPipe(); 16314 try { 16315 r.app.thread.dumpActivity(tp.getWriteFd(), 16316 r.appToken, innerPrefix, args); 16317 tp.go(fd); 16318 } finally { 16319 tp.kill(); 16320 } 16321 } catch (IOException e) { 16322 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 16323 } catch (RemoteException e) { 16324 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 16325 } 16326 } 16327 } 16328 16329 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16330 int opti, boolean dumpAll, String dumpPackage) { 16331 boolean needSep = false; 16332 boolean onlyHistory = false; 16333 boolean printedAnything = false; 16334 16335 if ("history".equals(dumpPackage)) { 16336 if (opti < args.length && "-s".equals(args[opti])) { 16337 dumpAll = false; 16338 } 16339 onlyHistory = true; 16340 dumpPackage = null; 16341 } 16342 16343 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 16344 if (!onlyHistory && dumpAll) { 16345 if (mRegisteredReceivers.size() > 0) { 16346 boolean printed = false; 16347 Iterator it = mRegisteredReceivers.values().iterator(); 16348 while (it.hasNext()) { 16349 ReceiverList r = (ReceiverList)it.next(); 16350 if (dumpPackage != null && (r.app == null || 16351 !dumpPackage.equals(r.app.info.packageName))) { 16352 continue; 16353 } 16354 if (!printed) { 16355 pw.println(" Registered Receivers:"); 16356 needSep = true; 16357 printed = true; 16358 printedAnything = true; 16359 } 16360 pw.print(" * "); pw.println(r); 16361 r.dump(pw, " "); 16362 } 16363 } 16364 16365 if (mReceiverResolver.dump(pw, needSep ? 16366 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 16367 " ", dumpPackage, false, false)) { 16368 needSep = true; 16369 printedAnything = true; 16370 } 16371 } 16372 16373 for (BroadcastQueue q : mBroadcastQueues) { 16374 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 16375 printedAnything |= needSep; 16376 } 16377 16378 needSep = true; 16379 16380 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 16381 for (int user=0; user<mStickyBroadcasts.size(); user++) { 16382 if (needSep) { 16383 pw.println(); 16384 } 16385 needSep = true; 16386 printedAnything = true; 16387 pw.print(" Sticky broadcasts for user "); 16388 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 16389 StringBuilder sb = new StringBuilder(128); 16390 for (Map.Entry<String, ArrayList<Intent>> ent 16391 : mStickyBroadcasts.valueAt(user).entrySet()) { 16392 pw.print(" * Sticky action "); pw.print(ent.getKey()); 16393 if (dumpAll) { 16394 pw.println(":"); 16395 ArrayList<Intent> intents = ent.getValue(); 16396 final int N = intents.size(); 16397 for (int i=0; i<N; i++) { 16398 sb.setLength(0); 16399 sb.append(" Intent: "); 16400 intents.get(i).toShortString(sb, false, true, false, false); 16401 pw.println(sb.toString()); 16402 Bundle bundle = intents.get(i).getExtras(); 16403 if (bundle != null) { 16404 pw.print(" "); 16405 pw.println(bundle.toString()); 16406 } 16407 } 16408 } else { 16409 pw.println(""); 16410 } 16411 } 16412 } 16413 } 16414 16415 if (!onlyHistory && dumpAll) { 16416 pw.println(); 16417 for (BroadcastQueue queue : mBroadcastQueues) { 16418 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 16419 + queue.mBroadcastsScheduled); 16420 } 16421 pw.println(" mHandler:"); 16422 mHandler.dump(new PrintWriterPrinter(pw), " "); 16423 needSep = true; 16424 printedAnything = true; 16425 } 16426 16427 if (!printedAnything) { 16428 pw.println(" (nothing)"); 16429 } 16430 } 16431 16432 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16433 int opti, boolean dumpAll, String dumpPackage) { 16434 if (mCurBroadcastStats == null) { 16435 return; 16436 } 16437 16438 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)"); 16439 final long now = SystemClock.elapsedRealtime(); 16440 if (mLastBroadcastStats != null) { 16441 pw.print(" Last stats (from "); 16442 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw); 16443 pw.print(" to "); 16444 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw); 16445 pw.print(", "); 16446 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime 16447 - mLastBroadcastStats.mStartUptime, pw); 16448 pw.println(" uptime):"); 16449 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) { 16450 pw.println(" (nothing)"); 16451 } 16452 pw.println(); 16453 } 16454 pw.print(" Current stats (from "); 16455 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw); 16456 pw.print(" to now, "); 16457 TimeUtils.formatDuration(SystemClock.uptimeMillis() 16458 - mCurBroadcastStats.mStartUptime, pw); 16459 pw.println(" uptime):"); 16460 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) { 16461 pw.println(" (nothing)"); 16462 } 16463 } 16464 16465 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16466 int opti, boolean fullCheckin, String dumpPackage) { 16467 if (mCurBroadcastStats == null) { 16468 return; 16469 } 16470 16471 if (mLastBroadcastStats != null) { 16472 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage); 16473 if (fullCheckin) { 16474 mLastBroadcastStats = null; 16475 return; 16476 } 16477 } 16478 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage); 16479 if (fullCheckin) { 16480 mCurBroadcastStats = null; 16481 } 16482 } 16483 16484 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16485 int opti, boolean dumpAll, String dumpPackage) { 16486 boolean needSep; 16487 boolean printedAnything = false; 16488 16489 ItemMatcher matcher = new ItemMatcher(); 16490 matcher.build(args, opti); 16491 16492 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 16493 16494 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 16495 printedAnything |= needSep; 16496 16497 if (mLaunchingProviders.size() > 0) { 16498 boolean printed = false; 16499 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 16500 ContentProviderRecord r = mLaunchingProviders.get(i); 16501 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 16502 continue; 16503 } 16504 if (!printed) { 16505 if (needSep) pw.println(); 16506 needSep = true; 16507 pw.println(" Launching content providers:"); 16508 printed = true; 16509 printedAnything = true; 16510 } 16511 pw.print(" Launching #"); pw.print(i); pw.print(": "); 16512 pw.println(r); 16513 } 16514 } 16515 16516 if (!printedAnything) { 16517 pw.println(" (nothing)"); 16518 } 16519 } 16520 16521 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16522 int opti, boolean dumpAll, String dumpPackage) { 16523 boolean needSep = false; 16524 boolean printedAnything = false; 16525 16526 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)"); 16527 16528 if (mGrantedUriPermissions.size() > 0) { 16529 boolean printed = false; 16530 int dumpUid = -2; 16531 if (dumpPackage != null) { 16532 try { 16533 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage, 16534 MATCH_ANY_USER, 0); 16535 } catch (NameNotFoundException e) { 16536 dumpUid = -1; 16537 } 16538 } 16539 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 16540 int uid = mGrantedUriPermissions.keyAt(i); 16541 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 16542 continue; 16543 } 16544 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 16545 if (!printed) { 16546 if (needSep) pw.println(); 16547 needSep = true; 16548 pw.println(" Granted Uri Permissions:"); 16549 printed = true; 16550 printedAnything = true; 16551 } 16552 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 16553 for (UriPermission perm : perms.values()) { 16554 pw.print(" "); pw.println(perm); 16555 if (dumpAll) { 16556 perm.dump(pw, " "); 16557 } 16558 } 16559 } 16560 } 16561 16562 if (!printedAnything) { 16563 pw.println(" (nothing)"); 16564 } 16565 } 16566 16567 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 16568 int opti, boolean dumpAll, String dumpPackage) { 16569 boolean printed = false; 16570 16571 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 16572 16573 if (mIntentSenderRecords.size() > 0) { 16574 // Organize these by package name, so they are easier to read. 16575 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>(); 16576 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>(); 16577 final Iterator<WeakReference<PendingIntentRecord>> it 16578 = mIntentSenderRecords.values().iterator(); 16579 while (it.hasNext()) { 16580 WeakReference<PendingIntentRecord> ref = it.next(); 16581 PendingIntentRecord rec = ref != null ? ref.get() : null; 16582 if (rec == null) { 16583 weakRefs.add(ref); 16584 continue; 16585 } 16586 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) { 16587 continue; 16588 } 16589 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName); 16590 if (list == null) { 16591 list = new ArrayList<>(); 16592 byPackage.put(rec.key.packageName, list); 16593 } 16594 list.add(rec); 16595 } 16596 for (int i = 0; i < byPackage.size(); i++) { 16597 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i); 16598 printed = true; 16599 pw.print(" * "); pw.print(byPackage.keyAt(i)); 16600 pw.print(": "); pw.print(intents.size()); pw.println(" items"); 16601 for (int j = 0; j < intents.size(); j++) { 16602 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j)); 16603 if (dumpAll) { 16604 intents.get(j).dump(pw, " "); 16605 } 16606 } 16607 } 16608 if (weakRefs.size() > 0) { 16609 printed = true; 16610 pw.println(" * WEAK REFS:"); 16611 for (int i = 0; i < weakRefs.size(); i++) { 16612 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i)); 16613 } 16614 } 16615 } 16616 16617 if (!printed) { 16618 pw.println(" (nothing)"); 16619 } 16620 } 16621 16622 private static final int dumpProcessList(PrintWriter pw, 16623 ActivityManagerService service, List list, 16624 String prefix, String normalLabel, String persistentLabel, 16625 String dumpPackage) { 16626 int numPers = 0; 16627 final int N = list.size()-1; 16628 for (int i=N; i>=0; i--) { 16629 ProcessRecord r = (ProcessRecord)list.get(i); 16630 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 16631 continue; 16632 } 16633 pw.println(String.format("%s%s #%2d: %s", 16634 prefix, (r.persistent ? persistentLabel : normalLabel), 16635 i, r.toString())); 16636 if (r.persistent) { 16637 numPers++; 16638 } 16639 } 16640 return numPers; 16641 } 16642 16643 private static final boolean dumpProcessOomList(PrintWriter pw, 16644 ActivityManagerService service, List<ProcessRecord> origList, 16645 String prefix, String normalLabel, String persistentLabel, 16646 boolean inclDetails, String dumpPackage) { 16647 16648 ArrayList<Pair<ProcessRecord, Integer>> list 16649 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 16650 for (int i=0; i<origList.size(); i++) { 16651 ProcessRecord r = origList.get(i); 16652 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 16653 continue; 16654 } 16655 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 16656 } 16657 16658 if (list.size() <= 0) { 16659 return false; 16660 } 16661 16662 Comparator<Pair<ProcessRecord, Integer>> comparator 16663 = new Comparator<Pair<ProcessRecord, Integer>>() { 16664 @Override 16665 public int compare(Pair<ProcessRecord, Integer> object1, 16666 Pair<ProcessRecord, Integer> object2) { 16667 if (object1.first.setAdj != object2.first.setAdj) { 16668 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 16669 } 16670 if (object1.first.setProcState != object2.first.setProcState) { 16671 return object1.first.setProcState > object2.first.setProcState ? -1 : 1; 16672 } 16673 if (object1.second.intValue() != object2.second.intValue()) { 16674 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 16675 } 16676 return 0; 16677 } 16678 }; 16679 16680 Collections.sort(list, comparator); 16681 16682 final long curUptime = SystemClock.uptimeMillis(); 16683 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 16684 16685 for (int i=list.size()-1; i>=0; i--) { 16686 ProcessRecord r = list.get(i).first; 16687 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 16688 char schedGroup; 16689 switch (r.setSchedGroup) { 16690 case ProcessList.SCHED_GROUP_BACKGROUND: 16691 schedGroup = 'B'; 16692 break; 16693 case ProcessList.SCHED_GROUP_DEFAULT: 16694 schedGroup = 'F'; 16695 break; 16696 case ProcessList.SCHED_GROUP_TOP_APP: 16697 schedGroup = 'T'; 16698 break; 16699 default: 16700 schedGroup = '?'; 16701 break; 16702 } 16703 char foreground; 16704 if (r.foregroundActivities) { 16705 foreground = 'A'; 16706 } else if (r.foregroundServices) { 16707 foreground = 'S'; 16708 } else { 16709 foreground = ' '; 16710 } 16711 String procState = ProcessList.makeProcStateString(r.curProcState); 16712 pw.print(prefix); 16713 pw.print(r.persistent ? persistentLabel : normalLabel); 16714 pw.print(" #"); 16715 int num = (origList.size()-1)-list.get(i).second; 16716 if (num < 10) pw.print(' '); 16717 pw.print(num); 16718 pw.print(": "); 16719 pw.print(oomAdj); 16720 pw.print(' '); 16721 pw.print(schedGroup); 16722 pw.print('/'); 16723 pw.print(foreground); 16724 pw.print('/'); 16725 pw.print(procState); 16726 pw.print(" trm:"); 16727 if (r.trimMemoryLevel < 10) pw.print(' '); 16728 pw.print(r.trimMemoryLevel); 16729 pw.print(' '); 16730 pw.print(r.toShortString()); 16731 pw.print(" ("); 16732 pw.print(r.adjType); 16733 pw.println(')'); 16734 if (r.adjSource != null || r.adjTarget != null) { 16735 pw.print(prefix); 16736 pw.print(" "); 16737 if (r.adjTarget instanceof ComponentName) { 16738 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 16739 } else if (r.adjTarget != null) { 16740 pw.print(r.adjTarget.toString()); 16741 } else { 16742 pw.print("{null}"); 16743 } 16744 pw.print("<="); 16745 if (r.adjSource instanceof ProcessRecord) { 16746 pw.print("Proc{"); 16747 pw.print(((ProcessRecord)r.adjSource).toShortString()); 16748 pw.println("}"); 16749 } else if (r.adjSource != null) { 16750 pw.println(r.adjSource.toString()); 16751 } else { 16752 pw.println("{null}"); 16753 } 16754 } 16755 if (inclDetails) { 16756 pw.print(prefix); 16757 pw.print(" "); 16758 pw.print("oom: max="); pw.print(r.maxAdj); 16759 pw.print(" curRaw="); pw.print(r.curRawAdj); 16760 pw.print(" setRaw="); pw.print(r.setRawAdj); 16761 pw.print(" cur="); pw.print(r.curAdj); 16762 pw.print(" set="); pw.println(r.setAdj); 16763 pw.print(prefix); 16764 pw.print(" "); 16765 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 16766 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 16767 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024); 16768 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024); 16769 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024); 16770 pw.println(); 16771 pw.print(prefix); 16772 pw.print(" "); 16773 pw.print("cached="); pw.print(r.cached); 16774 pw.print(" empty="); pw.print(r.empty); 16775 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 16776 16777 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 16778 if (r.lastCpuTime != 0) { 16779 long timeUsed = r.curCpuTime - r.lastCpuTime; 16780 pw.print(prefix); 16781 pw.print(" "); 16782 pw.print("run cpu over "); 16783 TimeUtils.formatDuration(uptimeSince, pw); 16784 pw.print(" used "); 16785 TimeUtils.formatDuration(timeUsed, pw); 16786 pw.print(" ("); 16787 pw.print((timeUsed*100)/uptimeSince); 16788 pw.println("%)"); 16789 } 16790 } 16791 } 16792 } 16793 return true; 16794 } 16795 16796 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 16797 String[] args) { 16798 ArrayList<ProcessRecord> procs; 16799 synchronized (this) { 16800 if (args != null && args.length > start 16801 && args[start].charAt(0) != '-') { 16802 procs = new ArrayList<ProcessRecord>(); 16803 int pid = -1; 16804 try { 16805 pid = Integer.parseInt(args[start]); 16806 } catch (NumberFormatException e) { 16807 } 16808 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16809 ProcessRecord proc = mLruProcesses.get(i); 16810 if (proc.pid == pid) { 16811 procs.add(proc); 16812 } else if (allPkgs && proc.pkgList != null 16813 && proc.pkgList.containsKey(args[start])) { 16814 procs.add(proc); 16815 } else if (proc.processName.equals(args[start])) { 16816 procs.add(proc); 16817 } 16818 } 16819 if (procs.size() <= 0) { 16820 return null; 16821 } 16822 } else { 16823 procs = new ArrayList<ProcessRecord>(mLruProcesses); 16824 } 16825 } 16826 return procs; 16827 } 16828 16829 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 16830 PrintWriter pw, String[] args) { 16831 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 16832 if (procs == null) { 16833 pw.println("No process found for: " + args[0]); 16834 return; 16835 } 16836 16837 long uptime = SystemClock.uptimeMillis(); 16838 long realtime = SystemClock.elapsedRealtime(); 16839 pw.println("Applications Graphics Acceleration Info:"); 16840 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 16841 16842 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 16843 ProcessRecord r = procs.get(i); 16844 if (r.thread != null) { 16845 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 16846 pw.flush(); 16847 try { 16848 TransferPipe tp = new TransferPipe(); 16849 try { 16850 r.thread.dumpGfxInfo(tp.getWriteFd(), args); 16851 tp.go(fd); 16852 } finally { 16853 tp.kill(); 16854 } 16855 } catch (IOException e) { 16856 pw.println("Failure while dumping the app: " + r); 16857 pw.flush(); 16858 } catch (RemoteException e) { 16859 pw.println("Got a RemoteException while dumping the app " + r); 16860 pw.flush(); 16861 } 16862 } 16863 } 16864 } 16865 16866 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 16867 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 16868 if (procs == null) { 16869 pw.println("No process found for: " + args[0]); 16870 return; 16871 } 16872 16873 pw.println("Applications Database Info:"); 16874 16875 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 16876 ProcessRecord r = procs.get(i); 16877 if (r.thread != null) { 16878 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 16879 pw.flush(); 16880 try { 16881 TransferPipe tp = new TransferPipe(); 16882 try { 16883 r.thread.dumpDbInfo(tp.getWriteFd(), args); 16884 tp.go(fd); 16885 } finally { 16886 tp.kill(); 16887 } 16888 } catch (IOException e) { 16889 pw.println("Failure while dumping the app: " + r); 16890 pw.flush(); 16891 } catch (RemoteException e) { 16892 pw.println("Got a RemoteException while dumping the app " + r); 16893 pw.flush(); 16894 } 16895 } 16896 } 16897 } 16898 16899 final static class MemItem { 16900 final boolean isProc; 16901 final String label; 16902 final String shortLabel; 16903 final long pss; 16904 final long swapPss; 16905 final int id; 16906 final boolean hasActivities; 16907 ArrayList<MemItem> subitems; 16908 16909 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id, 16910 boolean _hasActivities) { 16911 isProc = true; 16912 label = _label; 16913 shortLabel = _shortLabel; 16914 pss = _pss; 16915 swapPss = _swapPss; 16916 id = _id; 16917 hasActivities = _hasActivities; 16918 } 16919 16920 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) { 16921 isProc = false; 16922 label = _label; 16923 shortLabel = _shortLabel; 16924 pss = _pss; 16925 swapPss = _swapPss; 16926 id = _id; 16927 hasActivities = false; 16928 } 16929 } 16930 16931 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 16932 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) { 16933 if (sort && !isCompact) { 16934 Collections.sort(items, new Comparator<MemItem>() { 16935 @Override 16936 public int compare(MemItem lhs, MemItem rhs) { 16937 if (lhs.pss < rhs.pss) { 16938 return 1; 16939 } else if (lhs.pss > rhs.pss) { 16940 return -1; 16941 } 16942 return 0; 16943 } 16944 }); 16945 } 16946 16947 for (int i=0; i<items.size(); i++) { 16948 MemItem mi = items.get(i); 16949 if (!isCompact) { 16950 if (dumpSwapPss) { 16951 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss), 16952 mi.label, stringifyKBSize(mi.swapPss)); 16953 } else { 16954 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label); 16955 } 16956 } else if (mi.isProc) { 16957 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 16958 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(","); 16959 pw.print(dumpSwapPss ? mi.swapPss : "N/A"); 16960 pw.println(mi.hasActivities ? ",a" : ",e"); 16961 } else { 16962 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 16963 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A"); 16964 } 16965 if (mi.subitems != null) { 16966 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 16967 true, isCompact, dumpSwapPss); 16968 } 16969 } 16970 } 16971 16972 // These are in KB. 16973 static final long[] DUMP_MEM_BUCKETS = new long[] { 16974 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 16975 120*1024, 160*1024, 200*1024, 16976 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 16977 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 16978 }; 16979 16980 static final void appendMemBucket(StringBuilder out, long memKB, String label, 16981 boolean stackLike) { 16982 int start = label.lastIndexOf('.'); 16983 if (start >= 0) start++; 16984 else start = 0; 16985 int end = label.length(); 16986 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 16987 if (DUMP_MEM_BUCKETS[i] >= memKB) { 16988 long bucket = DUMP_MEM_BUCKETS[i]/1024; 16989 out.append(bucket); 16990 out.append(stackLike ? "MB." : "MB "); 16991 out.append(label, start, end); 16992 return; 16993 } 16994 } 16995 out.append(memKB/1024); 16996 out.append(stackLike ? "MB." : "MB "); 16997 out.append(label, start, end); 16998 } 16999 17000 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 17001 ProcessList.NATIVE_ADJ, 17002 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 17003 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 17004 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 17005 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 17006 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 17007 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ 17008 }; 17009 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 17010 "Native", 17011 "System", "Persistent", "Persistent Service", "Foreground", 17012 "Visible", "Perceptible", 17013 "Heavy Weight", "Backup", 17014 "A Services", "Home", 17015 "Previous", "B Services", "Cached" 17016 }; 17017 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 17018 "native", 17019 "sys", "pers", "persvc", "fore", 17020 "vis", "percept", 17021 "heavy", "backup", 17022 "servicea", "home", 17023 "prev", "serviceb", "cached" 17024 }; 17025 17026 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 17027 long realtime, boolean isCheckinRequest, boolean isCompact) { 17028 if (isCompact) { 17029 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION); 17030 } 17031 if (isCheckinRequest || isCompact) { 17032 // short checkin version 17033 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 17034 } else { 17035 pw.println("Applications Memory Usage (in Kilobytes):"); 17036 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 17037 } 17038 } 17039 17040 private static final int KSM_SHARED = 0; 17041 private static final int KSM_SHARING = 1; 17042 private static final int KSM_UNSHARED = 2; 17043 private static final int KSM_VOLATILE = 3; 17044 17045 private final long[] getKsmInfo() { 17046 long[] longOut = new long[4]; 17047 final int[] SINGLE_LONG_FORMAT = new int[] { 17048 PROC_SPACE_TERM| PROC_OUT_LONG 17049 }; 17050 long[] longTmp = new long[1]; 17051 readProcFile("/sys/kernel/mm/ksm/pages_shared", 17052 SINGLE_LONG_FORMAT, null, longTmp, null); 17053 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 17054 longTmp[0] = 0; 17055 readProcFile("/sys/kernel/mm/ksm/pages_sharing", 17056 SINGLE_LONG_FORMAT, null, longTmp, null); 17057 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 17058 longTmp[0] = 0; 17059 readProcFile("/sys/kernel/mm/ksm/pages_unshared", 17060 SINGLE_LONG_FORMAT, null, longTmp, null); 17061 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 17062 longTmp[0] = 0; 17063 readProcFile("/sys/kernel/mm/ksm/pages_volatile", 17064 SINGLE_LONG_FORMAT, null, longTmp, null); 17065 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 17066 return longOut; 17067 } 17068 17069 private static String stringifySize(long size, int order) { 17070 Locale locale = Locale.US; 17071 switch (order) { 17072 case 1: 17073 return String.format(locale, "%,13d", size); 17074 case 1024: 17075 return String.format(locale, "%,9dK", size / 1024); 17076 case 1024 * 1024: 17077 return String.format(locale, "%,5dM", size / 1024 / 1024); 17078 case 1024 * 1024 * 1024: 17079 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024); 17080 default: 17081 throw new IllegalArgumentException("Invalid size order"); 17082 } 17083 } 17084 17085 private static String stringifyKBSize(long size) { 17086 return stringifySize(size * 1024, 1024); 17087 } 17088 17089 // Update this version number in case you change the 'compact' format 17090 private static final int MEMINFO_COMPACT_VERSION = 1; 17091 17092 final void dumpApplicationMemoryUsage(FileDescriptor fd, 17093 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 17094 boolean dumpDetails = false; 17095 boolean dumpFullDetails = false; 17096 boolean dumpDalvik = false; 17097 boolean dumpSummaryOnly = false; 17098 boolean dumpUnreachable = false; 17099 boolean oomOnly = false; 17100 boolean isCompact = false; 17101 boolean localOnly = false; 17102 boolean packages = false; 17103 boolean isCheckinRequest = false; 17104 boolean dumpSwapPss = false; 17105 17106 int opti = 0; 17107 while (opti < args.length) { 17108 String opt = args[opti]; 17109 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 17110 break; 17111 } 17112 opti++; 17113 if ("-a".equals(opt)) { 17114 dumpDetails = true; 17115 dumpFullDetails = true; 17116 dumpDalvik = true; 17117 dumpSwapPss = true; 17118 } else if ("-d".equals(opt)) { 17119 dumpDalvik = true; 17120 } else if ("-c".equals(opt)) { 17121 isCompact = true; 17122 } else if ("-s".equals(opt)) { 17123 dumpDetails = true; 17124 dumpSummaryOnly = true; 17125 } else if ("-S".equals(opt)) { 17126 dumpSwapPss = true; 17127 } else if ("--unreachable".equals(opt)) { 17128 dumpUnreachable = true; 17129 } else if ("--oom".equals(opt)) { 17130 oomOnly = true; 17131 } else if ("--local".equals(opt)) { 17132 localOnly = true; 17133 } else if ("--package".equals(opt)) { 17134 packages = true; 17135 } else if ("--checkin".equals(opt)) { 17136 isCheckinRequest = true; 17137 17138 } else if ("-h".equals(opt)) { 17139 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]"); 17140 pw.println(" -a: include all available information for each process."); 17141 pw.println(" -d: include dalvik details."); 17142 pw.println(" -c: dump in a compact machine-parseable representation."); 17143 pw.println(" -s: dump only summary of application memory usage."); 17144 pw.println(" -S: dump also SwapPss."); 17145 pw.println(" --oom: only show processes organized by oom adj."); 17146 pw.println(" --local: only collect details locally, don't call process."); 17147 pw.println(" --package: interpret process arg as package, dumping all"); 17148 pw.println(" processes that have loaded that package."); 17149 pw.println(" --checkin: dump data for a checkin"); 17150 pw.println("If [process] is specified it can be the name or "); 17151 pw.println("pid of a specific process to dump."); 17152 return; 17153 } else { 17154 pw.println("Unknown argument: " + opt + "; use -h for help"); 17155 } 17156 } 17157 17158 long uptime = SystemClock.uptimeMillis(); 17159 long realtime = SystemClock.elapsedRealtime(); 17160 final long[] tmpLong = new long[1]; 17161 17162 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 17163 if (procs == null) { 17164 // No Java processes. Maybe they want to print a native process. 17165 if (args != null && args.length > opti 17166 && args[opti].charAt(0) != '-') { 17167 ArrayList<ProcessCpuTracker.Stats> nativeProcs 17168 = new ArrayList<ProcessCpuTracker.Stats>(); 17169 updateCpuStatsNow(); 17170 int findPid = -1; 17171 try { 17172 findPid = Integer.parseInt(args[opti]); 17173 } catch (NumberFormatException e) { 17174 } 17175 synchronized (mProcessCpuTracker) { 17176 final int N = mProcessCpuTracker.countStats(); 17177 for (int i=0; i<N; i++) { 17178 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 17179 if (st.pid == findPid || (st.baseName != null 17180 && st.baseName.equals(args[opti]))) { 17181 nativeProcs.add(st); 17182 } 17183 } 17184 } 17185 if (nativeProcs.size() > 0) { 17186 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 17187 isCompact); 17188 Debug.MemoryInfo mi = null; 17189 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 17190 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 17191 final int pid = r.pid; 17192 if (!isCheckinRequest && dumpDetails) { 17193 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 17194 } 17195 if (mi == null) { 17196 mi = new Debug.MemoryInfo(); 17197 } 17198 if (dumpDetails || (!brief && !oomOnly)) { 17199 Debug.getMemoryInfo(pid, mi); 17200 } else { 17201 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 17202 mi.dalvikPrivateDirty = (int)tmpLong[0]; 17203 } 17204 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 17205 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0); 17206 if (isCheckinRequest) { 17207 pw.println(); 17208 } 17209 } 17210 return; 17211 } 17212 } 17213 pw.println("No process found for: " + args[opti]); 17214 return; 17215 } 17216 17217 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 17218 dumpDetails = true; 17219 } 17220 17221 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 17222 17223 String[] innerArgs = new String[args.length-opti]; 17224 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 17225 17226 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 17227 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 17228 long nativePss = 0; 17229 long nativeSwapPss = 0; 17230 long dalvikPss = 0; 17231 long dalvikSwapPss = 0; 17232 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] : 17233 EmptyArray.LONG; 17234 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] : 17235 EmptyArray.LONG; 17236 long otherPss = 0; 17237 long otherSwapPss = 0; 17238 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 17239 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 17240 17241 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 17242 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 17243 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 17244 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 17245 17246 long totalPss = 0; 17247 long totalSwapPss = 0; 17248 long cachedPss = 0; 17249 long cachedSwapPss = 0; 17250 boolean hasSwapPss = false; 17251 17252 Debug.MemoryInfo mi = null; 17253 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 17254 final ProcessRecord r = procs.get(i); 17255 final IApplicationThread thread; 17256 final int pid; 17257 final int oomAdj; 17258 final boolean hasActivities; 17259 synchronized (this) { 17260 thread = r.thread; 17261 pid = r.pid; 17262 oomAdj = r.getSetAdjWithServices(); 17263 hasActivities = r.activities.size() > 0; 17264 } 17265 if (thread != null) { 17266 if (!isCheckinRequest && dumpDetails) { 17267 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 17268 } 17269 if (mi == null) { 17270 mi = new Debug.MemoryInfo(); 17271 } 17272 if (dumpDetails || (!brief && !oomOnly)) { 17273 Debug.getMemoryInfo(pid, mi); 17274 hasSwapPss = mi.hasSwappedOutPss; 17275 } else { 17276 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 17277 mi.dalvikPrivateDirty = (int)tmpLong[0]; 17278 } 17279 if (dumpDetails) { 17280 if (localOnly) { 17281 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 17282 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0); 17283 if (isCheckinRequest) { 17284 pw.println(); 17285 } 17286 } else { 17287 pw.flush(); 17288 try { 17289 TransferPipe tp = new TransferPipe(); 17290 try { 17291 thread.dumpMemInfo(tp.getWriteFd(), 17292 mi, isCheckinRequest, dumpFullDetails, 17293 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs); 17294 tp.go(fd); 17295 } finally { 17296 tp.kill(); 17297 } 17298 } catch (IOException e) { 17299 if (!isCheckinRequest) { 17300 pw.println("Got IoException! " + e); 17301 pw.flush(); 17302 } 17303 } catch (RemoteException e) { 17304 if (!isCheckinRequest) { 17305 pw.println("Got RemoteException! " + e); 17306 pw.flush(); 17307 } 17308 } 17309 } 17310 } 17311 17312 final long myTotalPss = mi.getTotalPss(); 17313 final long myTotalUss = mi.getTotalUss(); 17314 final long myTotalSwapPss = mi.getTotalSwappedOutPss(); 17315 17316 synchronized (this) { 17317 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 17318 // Record this for posterity if the process has been stable. 17319 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 17320 } 17321 } 17322 17323 if (!isCheckinRequest && mi != null) { 17324 totalPss += myTotalPss; 17325 totalSwapPss += myTotalSwapPss; 17326 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 17327 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss, 17328 myTotalSwapPss, pid, hasActivities); 17329 procMems.add(pssItem); 17330 procMemsMap.put(pid, pssItem); 17331 17332 nativePss += mi.nativePss; 17333 nativeSwapPss += mi.nativeSwappedOutPss; 17334 dalvikPss += mi.dalvikPss; 17335 dalvikSwapPss += mi.dalvikSwappedOutPss; 17336 for (int j=0; j<dalvikSubitemPss.length; j++) { 17337 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 17338 dalvikSubitemSwapPss[j] += 17339 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 17340 } 17341 otherPss += mi.otherPss; 17342 otherSwapPss += mi.otherSwappedOutPss; 17343 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 17344 long mem = mi.getOtherPss(j); 17345 miscPss[j] += mem; 17346 otherPss -= mem; 17347 mem = mi.getOtherSwappedOutPss(j); 17348 miscSwapPss[j] += mem; 17349 otherSwapPss -= mem; 17350 } 17351 17352 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 17353 cachedPss += myTotalPss; 17354 cachedSwapPss += myTotalSwapPss; 17355 } 17356 17357 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 17358 if (oomIndex == (oomPss.length - 1) 17359 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex] 17360 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) { 17361 oomPss[oomIndex] += myTotalPss; 17362 oomSwapPss[oomIndex] += myTotalSwapPss; 17363 if (oomProcs[oomIndex] == null) { 17364 oomProcs[oomIndex] = new ArrayList<MemItem>(); 17365 } 17366 oomProcs[oomIndex].add(pssItem); 17367 break; 17368 } 17369 } 17370 } 17371 } 17372 } 17373 17374 long nativeProcTotalPss = 0; 17375 17376 if (!isCheckinRequest && procs.size() > 1 && !packages) { 17377 // If we are showing aggregations, also look for native processes to 17378 // include so that our aggregations are more accurate. 17379 updateCpuStatsNow(); 17380 mi = null; 17381 synchronized (mProcessCpuTracker) { 17382 final int N = mProcessCpuTracker.countStats(); 17383 for (int i=0; i<N; i++) { 17384 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 17385 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 17386 if (mi == null) { 17387 mi = new Debug.MemoryInfo(); 17388 } 17389 if (!brief && !oomOnly) { 17390 Debug.getMemoryInfo(st.pid, mi); 17391 } else { 17392 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 17393 mi.nativePrivateDirty = (int)tmpLong[0]; 17394 } 17395 17396 final long myTotalPss = mi.getTotalPss(); 17397 final long myTotalSwapPss = mi.getTotalSwappedOutPss(); 17398 totalPss += myTotalPss; 17399 nativeProcTotalPss += myTotalPss; 17400 17401 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 17402 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false); 17403 procMems.add(pssItem); 17404 17405 nativePss += mi.nativePss; 17406 nativeSwapPss += mi.nativeSwappedOutPss; 17407 dalvikPss += mi.dalvikPss; 17408 dalvikSwapPss += mi.dalvikSwappedOutPss; 17409 for (int j=0; j<dalvikSubitemPss.length; j++) { 17410 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 17411 dalvikSubitemSwapPss[j] += 17412 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 17413 } 17414 otherPss += mi.otherPss; 17415 otherSwapPss += mi.otherSwappedOutPss; 17416 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 17417 long mem = mi.getOtherPss(j); 17418 miscPss[j] += mem; 17419 otherPss -= mem; 17420 mem = mi.getOtherSwappedOutPss(j); 17421 miscSwapPss[j] += mem; 17422 otherSwapPss -= mem; 17423 } 17424 oomPss[0] += myTotalPss; 17425 oomSwapPss[0] += myTotalSwapPss; 17426 if (oomProcs[0] == null) { 17427 oomProcs[0] = new ArrayList<MemItem>(); 17428 } 17429 oomProcs[0].add(pssItem); 17430 } 17431 } 17432 } 17433 17434 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 17435 17436 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1)); 17437 final int dalvikId = -2; 17438 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId)); 17439 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3)); 17440 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 17441 String label = Debug.MemoryInfo.getOtherLabel(j); 17442 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j)); 17443 } 17444 if (dalvikSubitemPss.length > 0) { 17445 // Add dalvik subitems. 17446 for (MemItem memItem : catMems) { 17447 int memItemStart = 0, memItemEnd = 0; 17448 if (memItem.id == dalvikId) { 17449 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START; 17450 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END; 17451 } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) { 17452 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START; 17453 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END; 17454 } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) { 17455 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START; 17456 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END; 17457 } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) { 17458 memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START; 17459 memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END; 17460 } else { 17461 continue; // No subitems, continue. 17462 } 17463 memItem.subitems = new ArrayList<MemItem>(); 17464 for (int j=memItemStart; j<=memItemEnd; j++) { 17465 final String name = Debug.MemoryInfo.getOtherLabel( 17466 Debug.MemoryInfo.NUM_OTHER_STATS + j); 17467 memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], 17468 dalvikSubitemSwapPss[j], j)); 17469 } 17470 } 17471 } 17472 17473 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 17474 for (int j=0; j<oomPss.length; j++) { 17475 if (oomPss[j] != 0) { 17476 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 17477 : DUMP_MEM_OOM_LABEL[j]; 17478 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j], 17479 DUMP_MEM_OOM_ADJ[j]); 17480 item.subitems = oomProcs[j]; 17481 oomMems.add(item); 17482 } 17483 } 17484 17485 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0; 17486 if (!brief && !oomOnly && !isCompact) { 17487 pw.println(); 17488 pw.println("Total PSS by process:"); 17489 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss); 17490 pw.println(); 17491 } 17492 if (!isCompact) { 17493 pw.println("Total PSS by OOM adjustment:"); 17494 } 17495 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss); 17496 if (!brief && !oomOnly) { 17497 PrintWriter out = categoryPw != null ? categoryPw : pw; 17498 if (!isCompact) { 17499 out.println(); 17500 out.println("Total PSS by category:"); 17501 } 17502 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss); 17503 } 17504 if (!isCompact) { 17505 pw.println(); 17506 } 17507 MemInfoReader memInfo = new MemInfoReader(); 17508 memInfo.readMemInfo(); 17509 if (nativeProcTotalPss > 0) { 17510 synchronized (this) { 17511 final long cachedKb = memInfo.getCachedSizeKb(); 17512 final long freeKb = memInfo.getFreeSizeKb(); 17513 final long zramKb = memInfo.getZramTotalSizeKb(); 17514 final long kernelKb = memInfo.getKernelUsedSizeKb(); 17515 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024, 17516 kernelKb*1024, nativeProcTotalPss*1024); 17517 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb, 17518 nativeProcTotalPss); 17519 } 17520 } 17521 if (!brief) { 17522 if (!isCompact) { 17523 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb())); 17524 pw.print(" (status "); 17525 switch (mLastMemoryLevel) { 17526 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 17527 pw.println("normal)"); 17528 break; 17529 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 17530 pw.println("moderate)"); 17531 break; 17532 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17533 pw.println("low)"); 17534 break; 17535 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17536 pw.println("critical)"); 17537 break; 17538 default: 17539 pw.print(mLastMemoryLevel); 17540 pw.println(")"); 17541 break; 17542 } 17543 pw.print(" Free RAM: "); 17544 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb() 17545 + memInfo.getFreeSizeKb())); 17546 pw.print(" ("); 17547 pw.print(stringifyKBSize(cachedPss)); 17548 pw.print(" cached pss + "); 17549 pw.print(stringifyKBSize(memInfo.getCachedSizeKb())); 17550 pw.print(" cached kernel + "); 17551 pw.print(stringifyKBSize(memInfo.getFreeSizeKb())); 17552 pw.println(" free)"); 17553 } else { 17554 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 17555 pw.print(cachedPss + memInfo.getCachedSizeKb() 17556 + memInfo.getFreeSizeKb()); pw.print(","); 17557 pw.println(totalPss - cachedPss); 17558 } 17559 } 17560 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss) 17561 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 17562 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb(); 17563 if (!isCompact) { 17564 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss 17565 + memInfo.getKernelUsedSizeKb())); pw.print(" ("); 17566 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + "); 17567 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n"); 17568 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM)); 17569 } else { 17570 pw.print("lostram,"); pw.println(lostRAM); 17571 } 17572 if (!brief) { 17573 if (memInfo.getZramTotalSizeKb() != 0) { 17574 if (!isCompact) { 17575 pw.print(" ZRAM: "); 17576 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb())); 17577 pw.print(" physical used for "); 17578 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb() 17579 - memInfo.getSwapFreeSizeKb())); 17580 pw.print(" in swap ("); 17581 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb())); 17582 pw.println(" total swap)"); 17583 } else { 17584 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 17585 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 17586 pw.println(memInfo.getSwapFreeSizeKb()); 17587 } 17588 } 17589 final long[] ksm = getKsmInfo(); 17590 if (!isCompact) { 17591 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 17592 || ksm[KSM_VOLATILE] != 0) { 17593 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING])); 17594 pw.print(" saved from shared "); 17595 pw.print(stringifyKBSize(ksm[KSM_SHARED])); 17596 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED])); 17597 pw.print(" unshared; "); 17598 pw.print(stringifyKBSize( 17599 ksm[KSM_VOLATILE])); pw.println(" volatile"); 17600 } 17601 pw.print(" Tuning: "); 17602 pw.print(ActivityManager.staticGetMemoryClass()); 17603 pw.print(" (large "); 17604 pw.print(ActivityManager.staticGetLargeMemoryClass()); 17605 pw.print("), oom "); 17606 pw.print(stringifySize( 17607 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024)); 17608 pw.print(", restore limit "); 17609 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb())); 17610 if (ActivityManager.isLowRamDeviceStatic()) { 17611 pw.print(" (low-ram)"); 17612 } 17613 if (ActivityManager.isHighEndGfx()) { 17614 pw.print(" (high-end-gfx)"); 17615 } 17616 pw.println(); 17617 } else { 17618 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 17619 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 17620 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 17621 pw.print("tuning,"); 17622 pw.print(ActivityManager.staticGetMemoryClass()); 17623 pw.print(','); 17624 pw.print(ActivityManager.staticGetLargeMemoryClass()); 17625 pw.print(','); 17626 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 17627 if (ActivityManager.isLowRamDeviceStatic()) { 17628 pw.print(",low-ram"); 17629 } 17630 if (ActivityManager.isHighEndGfx()) { 17631 pw.print(",high-end-gfx"); 17632 } 17633 pw.println(); 17634 } 17635 } 17636 } 17637 } 17638 17639 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 17640 long memtrack, String name) { 17641 sb.append(" "); 17642 sb.append(ProcessList.makeOomAdjString(oomAdj)); 17643 sb.append(' '); 17644 sb.append(ProcessList.makeProcStateString(procState)); 17645 sb.append(' '); 17646 ProcessList.appendRamKb(sb, pss); 17647 sb.append(": "); 17648 sb.append(name); 17649 if (memtrack > 0) { 17650 sb.append(" ("); 17651 sb.append(stringifyKBSize(memtrack)); 17652 sb.append(" memtrack)"); 17653 } 17654 } 17655 17656 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 17657 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 17658 sb.append(" (pid "); 17659 sb.append(mi.pid); 17660 sb.append(") "); 17661 sb.append(mi.adjType); 17662 sb.append('\n'); 17663 if (mi.adjReason != null) { 17664 sb.append(" "); 17665 sb.append(mi.adjReason); 17666 sb.append('\n'); 17667 } 17668 } 17669 17670 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 17671 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 17672 for (int i=0, N=memInfos.size(); i<N; i++) { 17673 ProcessMemInfo mi = memInfos.get(i); 17674 infoMap.put(mi.pid, mi); 17675 } 17676 updateCpuStatsNow(); 17677 long[] memtrackTmp = new long[1]; 17678 final List<ProcessCpuTracker.Stats> stats; 17679 // Get a list of Stats that have vsize > 0 17680 synchronized (mProcessCpuTracker) { 17681 stats = mProcessCpuTracker.getStats((st) -> { 17682 return st.vsize > 0; 17683 }); 17684 } 17685 final int statsCount = stats.size(); 17686 for (int i = 0; i < statsCount; i++) { 17687 ProcessCpuTracker.Stats st = stats.get(i); 17688 long pss = Debug.getPss(st.pid, null, memtrackTmp); 17689 if (pss > 0) { 17690 if (infoMap.indexOfKey(st.pid) < 0) { 17691 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 17692 ProcessList.NATIVE_ADJ, -1, "native", null); 17693 mi.pss = pss; 17694 mi.memtrack = memtrackTmp[0]; 17695 memInfos.add(mi); 17696 } 17697 } 17698 } 17699 17700 long totalPss = 0; 17701 long totalMemtrack = 0; 17702 for (int i=0, N=memInfos.size(); i<N; i++) { 17703 ProcessMemInfo mi = memInfos.get(i); 17704 if (mi.pss == 0) { 17705 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 17706 mi.memtrack = memtrackTmp[0]; 17707 } 17708 totalPss += mi.pss; 17709 totalMemtrack += mi.memtrack; 17710 } 17711 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 17712 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 17713 if (lhs.oomAdj != rhs.oomAdj) { 17714 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 17715 } 17716 if (lhs.pss != rhs.pss) { 17717 return lhs.pss < rhs.pss ? 1 : -1; 17718 } 17719 return 0; 17720 } 17721 }); 17722 17723 StringBuilder tag = new StringBuilder(128); 17724 StringBuilder stack = new StringBuilder(128); 17725 tag.append("Low on memory -- "); 17726 appendMemBucket(tag, totalPss, "total", false); 17727 appendMemBucket(stack, totalPss, "total", true); 17728 17729 StringBuilder fullNativeBuilder = new StringBuilder(1024); 17730 StringBuilder shortNativeBuilder = new StringBuilder(1024); 17731 StringBuilder fullJavaBuilder = new StringBuilder(1024); 17732 17733 boolean firstLine = true; 17734 int lastOomAdj = Integer.MIN_VALUE; 17735 long extraNativeRam = 0; 17736 long extraNativeMemtrack = 0; 17737 long cachedPss = 0; 17738 for (int i=0, N=memInfos.size(); i<N; i++) { 17739 ProcessMemInfo mi = memInfos.get(i); 17740 17741 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 17742 cachedPss += mi.pss; 17743 } 17744 17745 if (mi.oomAdj != ProcessList.NATIVE_ADJ 17746 && (mi.oomAdj < ProcessList.SERVICE_ADJ 17747 || mi.oomAdj == ProcessList.HOME_APP_ADJ 17748 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 17749 if (lastOomAdj != mi.oomAdj) { 17750 lastOomAdj = mi.oomAdj; 17751 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 17752 tag.append(" / "); 17753 } 17754 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 17755 if (firstLine) { 17756 stack.append(":"); 17757 firstLine = false; 17758 } 17759 stack.append("\n\t at "); 17760 } else { 17761 stack.append("$"); 17762 } 17763 } else { 17764 tag.append(" "); 17765 stack.append("$"); 17766 } 17767 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 17768 appendMemBucket(tag, mi.pss, mi.name, false); 17769 } 17770 appendMemBucket(stack, mi.pss, mi.name, true); 17771 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 17772 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 17773 stack.append("("); 17774 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 17775 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 17776 stack.append(DUMP_MEM_OOM_LABEL[k]); 17777 stack.append(":"); 17778 stack.append(DUMP_MEM_OOM_ADJ[k]); 17779 } 17780 } 17781 stack.append(")"); 17782 } 17783 } 17784 17785 appendMemInfo(fullNativeBuilder, mi); 17786 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 17787 // The short form only has native processes that are >= 512K. 17788 if (mi.pss >= 512) { 17789 appendMemInfo(shortNativeBuilder, mi); 17790 } else { 17791 extraNativeRam += mi.pss; 17792 extraNativeMemtrack += mi.memtrack; 17793 } 17794 } else { 17795 // Short form has all other details, but if we have collected RAM 17796 // from smaller native processes let's dump a summary of that. 17797 if (extraNativeRam > 0) { 17798 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 17799 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 17800 shortNativeBuilder.append('\n'); 17801 extraNativeRam = 0; 17802 } 17803 appendMemInfo(fullJavaBuilder, mi); 17804 } 17805 } 17806 17807 fullJavaBuilder.append(" "); 17808 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 17809 fullJavaBuilder.append(": TOTAL"); 17810 if (totalMemtrack > 0) { 17811 fullJavaBuilder.append(" ("); 17812 fullJavaBuilder.append(stringifyKBSize(totalMemtrack)); 17813 fullJavaBuilder.append(" memtrack)"); 17814 } else { 17815 } 17816 fullJavaBuilder.append("\n"); 17817 17818 MemInfoReader memInfo = new MemInfoReader(); 17819 memInfo.readMemInfo(); 17820 final long[] infos = memInfo.getRawInfo(); 17821 17822 StringBuilder memInfoBuilder = new StringBuilder(1024); 17823 Debug.getMemInfo(infos); 17824 memInfoBuilder.append(" MemInfo: "); 17825 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, "); 17826 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, "); 17827 memInfoBuilder.append(stringifyKBSize( 17828 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, "); 17829 memInfoBuilder.append(stringifyKBSize( 17830 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables "); 17831 memInfoBuilder.append(stringifyKBSize( 17832 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n"); 17833 memInfoBuilder.append(" "); 17834 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, "); 17835 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, "); 17836 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, "); 17837 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n"); 17838 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 17839 memInfoBuilder.append(" ZRAM: "); 17840 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL])); 17841 memInfoBuilder.append(" RAM, "); 17842 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL])); 17843 memInfoBuilder.append(" swap total, "); 17844 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE])); 17845 memInfoBuilder.append(" swap free\n"); 17846 } 17847 final long[] ksm = getKsmInfo(); 17848 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 17849 || ksm[KSM_VOLATILE] != 0) { 17850 memInfoBuilder.append(" KSM: "); 17851 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING])); 17852 memInfoBuilder.append(" saved from shared "); 17853 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED])); 17854 memInfoBuilder.append("\n "); 17855 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED])); 17856 memInfoBuilder.append(" unshared; "); 17857 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE])); 17858 memInfoBuilder.append(" volatile\n"); 17859 } 17860 memInfoBuilder.append(" Free RAM: "); 17861 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb() 17862 + memInfo.getFreeSizeKb())); 17863 memInfoBuilder.append("\n"); 17864 memInfoBuilder.append(" Used RAM: "); 17865 memInfoBuilder.append(stringifyKBSize( 17866 totalPss - cachedPss + memInfo.getKernelUsedSizeKb())); 17867 memInfoBuilder.append("\n"); 17868 memInfoBuilder.append(" Lost RAM: "); 17869 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb() 17870 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 17871 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb())); 17872 memInfoBuilder.append("\n"); 17873 Slog.i(TAG, "Low on memory:"); 17874 Slog.i(TAG, shortNativeBuilder.toString()); 17875 Slog.i(TAG, fullJavaBuilder.toString()); 17876 Slog.i(TAG, memInfoBuilder.toString()); 17877 17878 StringBuilder dropBuilder = new StringBuilder(1024); 17879 /* 17880 StringWriter oomSw = new StringWriter(); 17881 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 17882 StringWriter catSw = new StringWriter(); 17883 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 17884 String[] emptyArgs = new String[] { }; 17885 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 17886 oomPw.flush(); 17887 String oomString = oomSw.toString(); 17888 */ 17889 dropBuilder.append("Low on memory:"); 17890 dropBuilder.append(stack); 17891 dropBuilder.append('\n'); 17892 dropBuilder.append(fullNativeBuilder); 17893 dropBuilder.append(fullJavaBuilder); 17894 dropBuilder.append('\n'); 17895 dropBuilder.append(memInfoBuilder); 17896 dropBuilder.append('\n'); 17897 /* 17898 dropBuilder.append(oomString); 17899 dropBuilder.append('\n'); 17900 */ 17901 StringWriter catSw = new StringWriter(); 17902 synchronized (ActivityManagerService.this) { 17903 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 17904 String[] emptyArgs = new String[] { }; 17905 catPw.println(); 17906 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 17907 catPw.println(); 17908 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0, 17909 false, null).dumpLocked(); 17910 catPw.println(); 17911 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 17912 catPw.flush(); 17913 } 17914 dropBuilder.append(catSw.toString()); 17915 addErrorToDropBox("lowmem", null, "system_server", null, 17916 null, tag.toString(), dropBuilder.toString(), null, null); 17917 //Slog.i(TAG, "Sent to dropbox:"); 17918 //Slog.i(TAG, dropBuilder.toString()); 17919 synchronized (ActivityManagerService.this) { 17920 long now = SystemClock.uptimeMillis(); 17921 if (mLastMemUsageReportTime < now) { 17922 mLastMemUsageReportTime = now; 17923 } 17924 } 17925 } 17926 17927 /** 17928 * Searches array of arguments for the specified string 17929 * @param args array of argument strings 17930 * @param value value to search for 17931 * @return true if the value is contained in the array 17932 */ 17933 private static boolean scanArgs(String[] args, String value) { 17934 if (args != null) { 17935 for (String arg : args) { 17936 if (value.equals(arg)) { 17937 return true; 17938 } 17939 } 17940 } 17941 return false; 17942 } 17943 17944 private final boolean removeDyingProviderLocked(ProcessRecord proc, 17945 ContentProviderRecord cpr, boolean always) { 17946 final boolean inLaunching = mLaunchingProviders.contains(cpr); 17947 17948 if (!inLaunching || always) { 17949 synchronized (cpr) { 17950 cpr.launchingApp = null; 17951 cpr.notifyAll(); 17952 } 17953 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 17954 String names[] = cpr.info.authority.split(";"); 17955 for (int j = 0; j < names.length; j++) { 17956 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 17957 } 17958 } 17959 17960 for (int i = cpr.connections.size() - 1; i >= 0; i--) { 17961 ContentProviderConnection conn = cpr.connections.get(i); 17962 if (conn.waiting) { 17963 // If this connection is waiting for the provider, then we don't 17964 // need to mess with its process unless we are always removing 17965 // or for some reason the provider is not currently launching. 17966 if (inLaunching && !always) { 17967 continue; 17968 } 17969 } 17970 ProcessRecord capp = conn.client; 17971 conn.dead = true; 17972 if (conn.stableCount > 0) { 17973 if (!capp.persistent && capp.thread != null 17974 && capp.pid != 0 17975 && capp.pid != MY_PID) { 17976 capp.kill("depends on provider " 17977 + cpr.name.flattenToShortString() 17978 + " in dying proc " + (proc != null ? proc.processName : "??") 17979 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true); 17980 } 17981 } else if (capp.thread != null && conn.provider.provider != null) { 17982 try { 17983 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 17984 } catch (RemoteException e) { 17985 } 17986 // In the protocol here, we don't expect the client to correctly 17987 // clean up this connection, we'll just remove it. 17988 cpr.connections.remove(i); 17989 if (conn.client.conProviders.remove(conn)) { 17990 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name); 17991 } 17992 } 17993 } 17994 17995 if (inLaunching && always) { 17996 mLaunchingProviders.remove(cpr); 17997 } 17998 return inLaunching; 17999 } 18000 18001 /** 18002 * Main code for cleaning up a process when it has gone away. This is 18003 * called both as a result of the process dying, or directly when stopping 18004 * a process when running in single process mode. 18005 * 18006 * @return Returns true if the given process has been restarted, so the 18007 * app that was passed in must remain on the process lists. 18008 */ 18009 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 18010 boolean restarting, boolean allowRestart, int index, boolean replacingPid) { 18011 if (index >= 0) { 18012 removeLruProcessLocked(app); 18013 ProcessList.remove(app.pid); 18014 } 18015 18016 mProcessesToGc.remove(app); 18017 mPendingPssProcesses.remove(app); 18018 18019 // Dismiss any open dialogs. 18020 if (app.crashDialog != null && !app.forceCrashReport) { 18021 app.crashDialog.dismiss(); 18022 app.crashDialog = null; 18023 } 18024 if (app.anrDialog != null) { 18025 app.anrDialog.dismiss(); 18026 app.anrDialog = null; 18027 } 18028 if (app.waitDialog != null) { 18029 app.waitDialog.dismiss(); 18030 app.waitDialog = null; 18031 } 18032 18033 app.crashing = false; 18034 app.notResponding = false; 18035 18036 app.resetPackageList(mProcessStats); 18037 app.unlinkDeathRecipient(); 18038 app.makeInactive(mProcessStats); 18039 app.waitingToKill = null; 18040 app.forcingToImportant = null; 18041 updateProcessForegroundLocked(app, false, false); 18042 app.foregroundActivities = false; 18043 app.hasShownUi = false; 18044 app.treatLikeActivity = false; 18045 app.hasAboveClient = false; 18046 app.hasClientActivities = false; 18047 18048 mServices.killServicesLocked(app, allowRestart); 18049 18050 boolean restart = false; 18051 18052 // Remove published content providers. 18053 for (int i = app.pubProviders.size() - 1; i >= 0; i--) { 18054 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 18055 final boolean always = app.bad || !allowRestart; 18056 boolean inLaunching = removeDyingProviderLocked(app, cpr, always); 18057 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) { 18058 // We left the provider in the launching list, need to 18059 // restart it. 18060 restart = true; 18061 } 18062 18063 cpr.provider = null; 18064 cpr.proc = null; 18065 } 18066 app.pubProviders.clear(); 18067 18068 // Take care of any launching providers waiting for this process. 18069 if (cleanupAppInLaunchingProvidersLocked(app, false)) { 18070 restart = true; 18071 } 18072 18073 // Unregister from connected content providers. 18074 if (!app.conProviders.isEmpty()) { 18075 for (int i = app.conProviders.size() - 1; i >= 0; i--) { 18076 ContentProviderConnection conn = app.conProviders.get(i); 18077 conn.provider.connections.remove(conn); 18078 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 18079 conn.provider.name); 18080 } 18081 app.conProviders.clear(); 18082 } 18083 18084 // At this point there may be remaining entries in mLaunchingProviders 18085 // where we were the only one waiting, so they are no longer of use. 18086 // Look for these and clean up if found. 18087 // XXX Commented out for now. Trying to figure out a way to reproduce 18088 // the actual situation to identify what is actually going on. 18089 if (false) { 18090 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { 18091 ContentProviderRecord cpr = mLaunchingProviders.get(i); 18092 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 18093 synchronized (cpr) { 18094 cpr.launchingApp = null; 18095 cpr.notifyAll(); 18096 } 18097 } 18098 } 18099 } 18100 18101 skipCurrentReceiverLocked(app); 18102 18103 // Unregister any receivers. 18104 for (int i = app.receivers.size() - 1; i >= 0; i--) { 18105 removeReceiverLocked(app.receivers.valueAt(i)); 18106 } 18107 app.receivers.clear(); 18108 18109 // If the app is undergoing backup, tell the backup manager about it 18110 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 18111 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App " 18112 + mBackupTarget.appInfo + " died during backup"); 18113 mHandler.post(new Runnable() { 18114 @Override 18115 public void run(){ 18116 try { 18117 IBackupManager bm = IBackupManager.Stub.asInterface( 18118 ServiceManager.getService(Context.BACKUP_SERVICE)); 18119 bm.agentDisconnected(app.info.packageName); 18120 } catch (RemoteException e) { 18121 // can't happen; backup manager is local 18122 } 18123 } 18124 }); 18125 } 18126 18127 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) { 18128 ProcessChangeItem item = mPendingProcessChanges.get(i); 18129 if (item.pid == app.pid) { 18130 mPendingProcessChanges.remove(i); 18131 mAvailProcessChanges.add(item); 18132 } 18133 } 18134 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid, 18135 null).sendToTarget(); 18136 18137 // If the caller is restarting this app, then leave it in its 18138 // current lists and let the caller take care of it. 18139 if (restarting) { 18140 return false; 18141 } 18142 18143 if (!app.persistent || app.isolated) { 18144 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, 18145 "Removing non-persistent process during cleanup: " + app); 18146 if (!replacingPid) { 18147 removeProcessNameLocked(app.processName, app.uid, app); 18148 } 18149 if (mHeavyWeightProcess == app) { 18150 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 18151 mHeavyWeightProcess.userId, 0)); 18152 mHeavyWeightProcess = null; 18153 } 18154 } else if (!app.removed) { 18155 // This app is persistent, so we need to keep its record around. 18156 // If it is not already on the pending app list, add it there 18157 // and start a new process for it. 18158 if (mPersistentStartingProcesses.indexOf(app) < 0) { 18159 mPersistentStartingProcesses.add(app); 18160 restart = true; 18161 } 18162 } 18163 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v( 18164 TAG_CLEANUP, "Clean-up removing on hold: " + app); 18165 mProcessesOnHold.remove(app); 18166 18167 if (app == mHomeProcess) { 18168 mHomeProcess = null; 18169 } 18170 if (app == mPreviousProcess) { 18171 mPreviousProcess = null; 18172 } 18173 18174 if (restart && !app.isolated) { 18175 // We have components that still need to be running in the 18176 // process, so re-launch it. 18177 if (index < 0) { 18178 ProcessList.remove(app.pid); 18179 } 18180 addProcessNameLocked(app); 18181 startProcessLocked(app, "restart", app.processName); 18182 return true; 18183 } else if (app.pid > 0 && app.pid != MY_PID) { 18184 // Goodbye! 18185 boolean removed; 18186 synchronized (mPidsSelfLocked) { 18187 mPidsSelfLocked.remove(app.pid); 18188 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 18189 } 18190 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 18191 if (app.isolated) { 18192 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 18193 } 18194 app.setPid(0); 18195 } 18196 return false; 18197 } 18198 18199 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) { 18200 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { 18201 ContentProviderRecord cpr = mLaunchingProviders.get(i); 18202 if (cpr.launchingApp == app) { 18203 return true; 18204 } 18205 } 18206 return false; 18207 } 18208 18209 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 18210 // Look through the content providers we are waiting to have launched, 18211 // and if any run in this process then either schedule a restart of 18212 // the process or kill the client waiting for it if this process has 18213 // gone bad. 18214 boolean restart = false; 18215 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { 18216 ContentProviderRecord cpr = mLaunchingProviders.get(i); 18217 if (cpr.launchingApp == app) { 18218 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) { 18219 restart = true; 18220 } else { 18221 removeDyingProviderLocked(app, cpr, true); 18222 } 18223 } 18224 } 18225 return restart; 18226 } 18227 18228 // ========================================================= 18229 // SERVICES 18230 // ========================================================= 18231 18232 @Override 18233 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 18234 int flags) { 18235 enforceNotIsolatedCaller("getServices"); 18236 18237 final int callingUid = Binder.getCallingUid(); 18238 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission( 18239 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED); 18240 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(), 18241 callingUid); 18242 synchronized (this) { 18243 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid, 18244 allowed, canInteractAcrossUsers); 18245 } 18246 } 18247 18248 @Override 18249 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 18250 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 18251 synchronized (this) { 18252 return mServices.getRunningServiceControlPanelLocked(name); 18253 } 18254 } 18255 18256 @Override 18257 public ComponentName startService(IApplicationThread caller, Intent service, 18258 String resolvedType, boolean requireForeground, String callingPackage, int userId) 18259 throws TransactionTooLargeException { 18260 enforceNotIsolatedCaller("startService"); 18261 // Refuse possible leaked file descriptors 18262 if (service != null && service.hasFileDescriptors() == true) { 18263 throw new IllegalArgumentException("File descriptors passed in Intent"); 18264 } 18265 18266 if (callingPackage == null) { 18267 throw new IllegalArgumentException("callingPackage cannot be null"); 18268 } 18269 18270 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, 18271 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground); 18272 synchronized(this) { 18273 final int callingPid = Binder.getCallingPid(); 18274 final int callingUid = Binder.getCallingUid(); 18275 final long origId = Binder.clearCallingIdentity(); 18276 ComponentName res; 18277 try { 18278 res = mServices.startServiceLocked(caller, service, 18279 resolvedType, callingPid, callingUid, 18280 requireForeground, callingPackage, userId); 18281 } finally { 18282 Binder.restoreCallingIdentity(origId); 18283 } 18284 return res; 18285 } 18286 } 18287 18288 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, 18289 boolean fgRequired, String callingPackage, int userId) 18290 throws TransactionTooLargeException { 18291 synchronized(this) { 18292 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, 18293 "startServiceInPackage: " + service + " type=" + resolvedType); 18294 final long origId = Binder.clearCallingIdentity(); 18295 ComponentName res; 18296 try { 18297 res = mServices.startServiceLocked(null, service, 18298 resolvedType, -1, uid, fgRequired, callingPackage, userId); 18299 } finally { 18300 Binder.restoreCallingIdentity(origId); 18301 } 18302 return res; 18303 } 18304 } 18305 18306 @Override 18307 public int stopService(IApplicationThread caller, Intent service, 18308 String resolvedType, int userId) { 18309 enforceNotIsolatedCaller("stopService"); 18310 // Refuse possible leaked file descriptors 18311 if (service != null && service.hasFileDescriptors() == true) { 18312 throw new IllegalArgumentException("File descriptors passed in Intent"); 18313 } 18314 18315 synchronized(this) { 18316 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 18317 } 18318 } 18319 18320 @Override 18321 public IBinder peekService(Intent service, String resolvedType, String callingPackage) { 18322 enforceNotIsolatedCaller("peekService"); 18323 // Refuse possible leaked file descriptors 18324 if (service != null && service.hasFileDescriptors() == true) { 18325 throw new IllegalArgumentException("File descriptors passed in Intent"); 18326 } 18327 18328 if (callingPackage == null) { 18329 throw new IllegalArgumentException("callingPackage cannot be null"); 18330 } 18331 18332 synchronized(this) { 18333 return mServices.peekServiceLocked(service, resolvedType, callingPackage); 18334 } 18335 } 18336 18337 @Override 18338 public boolean stopServiceToken(ComponentName className, IBinder token, 18339 int startId) { 18340 synchronized(this) { 18341 return mServices.stopServiceTokenLocked(className, token, startId); 18342 } 18343 } 18344 18345 @Override 18346 public void setServiceForeground(ComponentName className, IBinder token, 18347 int id, Notification notification, int flags) { 18348 synchronized(this) { 18349 mServices.setServiceForegroundLocked(className, token, id, notification, flags); 18350 } 18351 } 18352 18353 @Override 18354 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 18355 boolean requireFull, String name, String callerPackage) { 18356 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll, 18357 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 18358 } 18359 18360 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 18361 String className, int flags) { 18362 boolean result = false; 18363 // For apps that don't have pre-defined UIDs, check for permission 18364 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) { 18365 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 18366 if (ActivityManager.checkUidPermission( 18367 INTERACT_ACROSS_USERS, 18368 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 18369 ComponentName comp = new ComponentName(aInfo.packageName, className); 18370 String msg = "Permission Denial: Component " + comp.flattenToShortString() 18371 + " requests FLAG_SINGLE_USER, but app does not hold " 18372 + INTERACT_ACROSS_USERS; 18373 Slog.w(TAG, msg); 18374 throw new SecurityException(msg); 18375 } 18376 // Permission passed 18377 result = true; 18378 } 18379 } else if ("system".equals(componentProcessName)) { 18380 result = true; 18381 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 18382 // Phone app and persistent apps are allowed to export singleuser providers. 18383 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID) 18384 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 18385 } 18386 if (DEBUG_MU) Slog.v(TAG_MU, 18387 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x" 18388 + Integer.toHexString(flags) + ") = " + result); 18389 return result; 18390 } 18391 18392 /** 18393 * Checks to see if the caller is in the same app as the singleton 18394 * component, or the component is in a special app. It allows special apps 18395 * to export singleton components but prevents exporting singleton 18396 * components for regular apps. 18397 */ 18398 boolean isValidSingletonCall(int callingUid, int componentUid) { 18399 int componentAppId = UserHandle.getAppId(componentUid); 18400 return UserHandle.isSameApp(callingUid, componentUid) 18401 || componentAppId == SYSTEM_UID 18402 || componentAppId == PHONE_UID 18403 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 18404 == PackageManager.PERMISSION_GRANTED; 18405 } 18406 18407 public int bindService(IApplicationThread caller, IBinder token, Intent service, 18408 String resolvedType, IServiceConnection connection, int flags, String callingPackage, 18409 int userId) throws TransactionTooLargeException { 18410 enforceNotIsolatedCaller("bindService"); 18411 18412 // Refuse possible leaked file descriptors 18413 if (service != null && service.hasFileDescriptors() == true) { 18414 throw new IllegalArgumentException("File descriptors passed in Intent"); 18415 } 18416 18417 if (callingPackage == null) { 18418 throw new IllegalArgumentException("callingPackage cannot be null"); 18419 } 18420 18421 synchronized(this) { 18422 return mServices.bindServiceLocked(caller, token, service, 18423 resolvedType, connection, flags, callingPackage, userId); 18424 } 18425 } 18426 18427 public boolean unbindService(IServiceConnection connection) { 18428 synchronized (this) { 18429 return mServices.unbindServiceLocked(connection); 18430 } 18431 } 18432 18433 public void publishService(IBinder token, Intent intent, IBinder service) { 18434 // Refuse possible leaked file descriptors 18435 if (intent != null && intent.hasFileDescriptors() == true) { 18436 throw new IllegalArgumentException("File descriptors passed in Intent"); 18437 } 18438 18439 synchronized(this) { 18440 if (!(token instanceof ServiceRecord)) { 18441 throw new IllegalArgumentException("Invalid service token"); 18442 } 18443 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 18444 } 18445 } 18446 18447 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 18448 // Refuse possible leaked file descriptors 18449 if (intent != null && intent.hasFileDescriptors() == true) { 18450 throw new IllegalArgumentException("File descriptors passed in Intent"); 18451 } 18452 18453 synchronized(this) { 18454 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 18455 } 18456 } 18457 18458 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 18459 synchronized(this) { 18460 if (!(token instanceof ServiceRecord)) { 18461 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token); 18462 throw new IllegalArgumentException("Invalid service token"); 18463 } 18464 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 18465 } 18466 } 18467 18468 // ========================================================= 18469 // BACKUP AND RESTORE 18470 // ========================================================= 18471 18472 // Cause the target app to be launched if necessary and its backup agent 18473 // instantiated. The backup agent will invoke backupAgentCreated() on the 18474 // activity manager to announce its creation. 18475 public boolean bindBackupAgent(String packageName, int backupMode, int userId) { 18476 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode); 18477 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 18478 18479 IPackageManager pm = AppGlobals.getPackageManager(); 18480 ApplicationInfo app = null; 18481 try { 18482 app = pm.getApplicationInfo(packageName, 0, userId); 18483 } catch (RemoteException e) { 18484 // can't happen; package manager is process-local 18485 } 18486 if (app == null) { 18487 Slog.w(TAG, "Unable to bind backup agent for " + packageName); 18488 return false; 18489 } 18490 18491 int oldBackupUid; 18492 int newBackupUid; 18493 18494 synchronized(this) { 18495 // !!! TODO: currently no check here that we're already bound 18496 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 18497 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 18498 synchronized (stats) { 18499 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 18500 } 18501 18502 // Backup agent is now in use, its package can't be stopped. 18503 try { 18504 AppGlobals.getPackageManager().setPackageStoppedState( 18505 app.packageName, false, UserHandle.getUserId(app.uid)); 18506 } catch (RemoteException e) { 18507 } catch (IllegalArgumentException e) { 18508 Slog.w(TAG, "Failed trying to unstop package " 18509 + app.packageName + ": " + e); 18510 } 18511 18512 BackupRecord r = new BackupRecord(ss, app, backupMode); 18513 ComponentName hostingName = 18514 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL) 18515 ? new ComponentName(app.packageName, app.backupAgentName) 18516 : new ComponentName("android", "FullBackupAgent"); 18517 // startProcessLocked() returns existing proc's record if it's already running 18518 ProcessRecord proc = startProcessLocked(app.processName, app, 18519 false, 0, "backup", hostingName, false, false, false); 18520 if (proc == null) { 18521 Slog.e(TAG, "Unable to start backup agent process " + r); 18522 return false; 18523 } 18524 18525 // If the app is a regular app (uid >= 10000) and not the system server or phone 18526 // process, etc, then mark it as being in full backup so that certain calls to the 18527 // process can be blocked. This is not reset to false anywhere because we kill the 18528 // process after the full backup is done and the ProcessRecord will vaporize anyway. 18529 if (UserHandle.isApp(app.uid) && 18530 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) { 18531 proc.inFullBackup = true; 18532 } 18533 r.app = proc; 18534 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1; 18535 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1; 18536 mBackupTarget = r; 18537 mBackupAppName = app.packageName; 18538 18539 // Try not to kill the process during backup 18540 updateOomAdjLocked(proc, true); 18541 18542 // If the process is already attached, schedule the creation of the backup agent now. 18543 // If it is not yet live, this will be done when it attaches to the framework. 18544 if (proc.thread != null) { 18545 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc); 18546 try { 18547 proc.thread.scheduleCreateBackupAgent(app, 18548 compatibilityInfoForPackageLocked(app), backupMode); 18549 } catch (RemoteException e) { 18550 // Will time out on the backup manager side 18551 } 18552 } else { 18553 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach"); 18554 } 18555 // Invariants: at this point, the target app process exists and the application 18556 // is either already running or in the process of coming up. mBackupTarget and 18557 // mBackupAppName describe the app, so that when it binds back to the AM we 18558 // know that it's scheduled for a backup-agent operation. 18559 } 18560 18561 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class); 18562 if (oldBackupUid != -1) { 18563 js.removeBackingUpUid(oldBackupUid); 18564 } 18565 if (newBackupUid != -1) { 18566 js.addBackingUpUid(newBackupUid); 18567 } 18568 18569 return true; 18570 } 18571 18572 @Override 18573 public void clearPendingBackup() { 18574 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup"); 18575 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 18576 18577 synchronized (this) { 18578 mBackupTarget = null; 18579 mBackupAppName = null; 18580 } 18581 18582 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class); 18583 js.clearAllBackingUpUids(); 18584 } 18585 18586 // A backup agent has just come up 18587 public void backupAgentCreated(String agentPackageName, IBinder agent) { 18588 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName 18589 + " = " + agent); 18590 18591 synchronized(this) { 18592 if (!agentPackageName.equals(mBackupAppName)) { 18593 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 18594 return; 18595 } 18596 } 18597 18598 long oldIdent = Binder.clearCallingIdentity(); 18599 try { 18600 IBackupManager bm = IBackupManager.Stub.asInterface( 18601 ServiceManager.getService(Context.BACKUP_SERVICE)); 18602 bm.agentConnected(agentPackageName, agent); 18603 } catch (RemoteException e) { 18604 // can't happen; the backup manager service is local 18605 } catch (Exception e) { 18606 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 18607 e.printStackTrace(); 18608 } finally { 18609 Binder.restoreCallingIdentity(oldIdent); 18610 } 18611 } 18612 18613 // done with this agent 18614 public void unbindBackupAgent(ApplicationInfo appInfo) { 18615 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo); 18616 if (appInfo == null) { 18617 Slog.w(TAG, "unbind backup agent for null app"); 18618 return; 18619 } 18620 18621 int oldBackupUid; 18622 18623 synchronized(this) { 18624 try { 18625 if (mBackupAppName == null) { 18626 Slog.w(TAG, "Unbinding backup agent with no active backup"); 18627 return; 18628 } 18629 18630 if (!mBackupAppName.equals(appInfo.packageName)) { 18631 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 18632 return; 18633 } 18634 18635 // Not backing this app up any more; reset its OOM adjustment 18636 final ProcessRecord proc = mBackupTarget.app; 18637 updateOomAdjLocked(proc, true); 18638 proc.inFullBackup = false; 18639 18640 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1; 18641 18642 // If the app crashed during backup, 'thread' will be null here 18643 if (proc.thread != null) { 18644 try { 18645 proc.thread.scheduleDestroyBackupAgent(appInfo, 18646 compatibilityInfoForPackageLocked(appInfo)); 18647 } catch (Exception e) { 18648 Slog.e(TAG, "Exception when unbinding backup agent:"); 18649 e.printStackTrace(); 18650 } 18651 } 18652 } finally { 18653 mBackupTarget = null; 18654 mBackupAppName = null; 18655 } 18656 } 18657 18658 if (oldBackupUid != -1) { 18659 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class); 18660 js.removeBackingUpUid(oldBackupUid); 18661 } 18662 } 18663 18664 // ========================================================= 18665 // BROADCASTS 18666 // ========================================================= 18667 18668 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) { 18669 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) { 18670 return false; 18671 } 18672 // Easy case -- we have the app's ProcessRecord. 18673 if (record != null) { 18674 return record.info.isInstantApp(); 18675 } 18676 // Otherwise check with PackageManager. 18677 if (callerPackage == null) { 18678 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name"); 18679 throw new IllegalArgumentException("Calling application did not provide package name"); 18680 } 18681 mAppOpsService.checkPackage(uid, callerPackage); 18682 try { 18683 IPackageManager pm = AppGlobals.getPackageManager(); 18684 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid)); 18685 } catch (RemoteException e) { 18686 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e); 18687 return true; 18688 } 18689 } 18690 18691 boolean isPendingBroadcastProcessLocked(int pid) { 18692 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 18693 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 18694 } 18695 18696 void skipPendingBroadcastLocked(int pid) { 18697 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 18698 for (BroadcastQueue queue : mBroadcastQueues) { 18699 queue.skipPendingBroadcastLocked(pid); 18700 } 18701 } 18702 18703 // The app just attached; send any pending broadcasts that it should receive 18704 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 18705 boolean didSomething = false; 18706 for (BroadcastQueue queue : mBroadcastQueues) { 18707 didSomething |= queue.sendPendingBroadcastsLocked(app); 18708 } 18709 return didSomething; 18710 } 18711 18712 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 18713 IIntentReceiver receiver, IntentFilter filter, String permission, int userId, 18714 int flags) { 18715 enforceNotIsolatedCaller("registerReceiver"); 18716 ArrayList<Intent> stickyIntents = null; 18717 ProcessRecord callerApp = null; 18718 final boolean visibleToInstantApps 18719 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0; 18720 int callingUid; 18721 int callingPid; 18722 boolean instantApp; 18723 synchronized(this) { 18724 if (caller != null) { 18725 callerApp = getRecordForAppLocked(caller); 18726 if (callerApp == null) { 18727 throw new SecurityException( 18728 "Unable to find app for caller " + caller 18729 + " (pid=" + Binder.getCallingPid() 18730 + ") when registering receiver " + receiver); 18731 } 18732 if (callerApp.info.uid != SYSTEM_UID && 18733 !callerApp.pkgList.containsKey(callerPackage) && 18734 !"android".equals(callerPackage)) { 18735 throw new SecurityException("Given caller package " + callerPackage 18736 + " is not running in process " + callerApp); 18737 } 18738 callingUid = callerApp.info.uid; 18739 callingPid = callerApp.pid; 18740 } else { 18741 callerPackage = null; 18742 callingUid = Binder.getCallingUid(); 18743 callingPid = Binder.getCallingPid(); 18744 } 18745 18746 instantApp = isInstantApp(callerApp, callerPackage, callingUid); 18747 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true, 18748 ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 18749 18750 Iterator<String> actions = filter.actionsIterator(); 18751 if (actions == null) { 18752 ArrayList<String> noAction = new ArrayList<String>(1); 18753 noAction.add(null); 18754 actions = noAction.iterator(); 18755 } 18756 18757 // Collect stickies of users 18758 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) }; 18759 while (actions.hasNext()) { 18760 String action = actions.next(); 18761 for (int id : userIds) { 18762 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id); 18763 if (stickies != null) { 18764 ArrayList<Intent> intents = stickies.get(action); 18765 if (intents != null) { 18766 if (stickyIntents == null) { 18767 stickyIntents = new ArrayList<Intent>(); 18768 } 18769 stickyIntents.addAll(intents); 18770 } 18771 } 18772 } 18773 } 18774 } 18775 18776 ArrayList<Intent> allSticky = null; 18777 if (stickyIntents != null) { 18778 final ContentResolver resolver = mContext.getContentResolver(); 18779 // Look for any matching sticky broadcasts... 18780 for (int i = 0, N = stickyIntents.size(); i < N; i++) { 18781 Intent intent = stickyIntents.get(i); 18782 // Don't provided intents that aren't available to instant apps. 18783 if (instantApp && 18784 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) { 18785 continue; 18786 } 18787 // If intent has scheme "content", it will need to acccess 18788 // provider that needs to lock mProviderMap in ActivityThread 18789 // and also it may need to wait application response, so we 18790 // cannot lock ActivityManagerService here. 18791 if (filter.match(resolver, intent, true, TAG) >= 0) { 18792 if (allSticky == null) { 18793 allSticky = new ArrayList<Intent>(); 18794 } 18795 allSticky.add(intent); 18796 } 18797 } 18798 } 18799 18800 // The first sticky in the list is returned directly back to the client. 18801 Intent sticky = allSticky != null ? allSticky.get(0) : null; 18802 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky); 18803 if (receiver == null) { 18804 return sticky; 18805 } 18806 18807 synchronized (this) { 18808 if (callerApp != null && (callerApp.thread == null 18809 || callerApp.thread.asBinder() != caller.asBinder())) { 18810 // Original caller already died 18811 return null; 18812 } 18813 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 18814 if (rl == null) { 18815 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 18816 userId, receiver); 18817 if (rl.app != null) { 18818 rl.app.receivers.add(rl); 18819 } else { 18820 try { 18821 receiver.asBinder().linkToDeath(rl, 0); 18822 } catch (RemoteException e) { 18823 return sticky; 18824 } 18825 rl.linkedToDeath = true; 18826 } 18827 mRegisteredReceivers.put(receiver.asBinder(), rl); 18828 } else if (rl.uid != callingUid) { 18829 throw new IllegalArgumentException( 18830 "Receiver requested to register for uid " + callingUid 18831 + " was previously registered for uid " + rl.uid 18832 + " callerPackage is " + callerPackage); 18833 } else if (rl.pid != callingPid) { 18834 throw new IllegalArgumentException( 18835 "Receiver requested to register for pid " + callingPid 18836 + " was previously registered for pid " + rl.pid 18837 + " callerPackage is " + callerPackage); 18838 } else if (rl.userId != userId) { 18839 throw new IllegalArgumentException( 18840 "Receiver requested to register for user " + userId 18841 + " was previously registered for user " + rl.userId 18842 + " callerPackage is " + callerPackage); 18843 } 18844 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 18845 permission, callingUid, userId, instantApp, visibleToInstantApps); 18846 rl.add(bf); 18847 if (!bf.debugCheck()) { 18848 Slog.w(TAG, "==> For Dynamic broadcast"); 18849 } 18850 mReceiverResolver.addFilter(bf); 18851 18852 // Enqueue broadcasts for all existing stickies that match 18853 // this filter. 18854 if (allSticky != null) { 18855 ArrayList receivers = new ArrayList(); 18856 receivers.add(bf); 18857 18858 final int stickyCount = allSticky.size(); 18859 for (int i = 0; i < stickyCount; i++) { 18860 Intent intent = allSticky.get(i); 18861 BroadcastQueue queue = broadcastQueueForIntent(intent); 18862 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 18863 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers, 18864 null, 0, null, null, false, true, true, -1); 18865 queue.enqueueParallelBroadcastLocked(r); 18866 queue.scheduleBroadcastsLocked(); 18867 } 18868 } 18869 18870 return sticky; 18871 } 18872 } 18873 18874 public void unregisterReceiver(IIntentReceiver receiver) { 18875 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver); 18876 18877 final long origId = Binder.clearCallingIdentity(); 18878 try { 18879 boolean doTrim = false; 18880 18881 synchronized(this) { 18882 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 18883 if (rl != null) { 18884 final BroadcastRecord r = rl.curBroadcast; 18885 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) { 18886 final boolean doNext = r.queue.finishReceiverLocked( 18887 r, r.resultCode, r.resultData, r.resultExtras, 18888 r.resultAbort, false); 18889 if (doNext) { 18890 doTrim = true; 18891 r.queue.processNextBroadcast(false); 18892 } 18893 } 18894 18895 if (rl.app != null) { 18896 rl.app.receivers.remove(rl); 18897 } 18898 removeReceiverLocked(rl); 18899 if (rl.linkedToDeath) { 18900 rl.linkedToDeath = false; 18901 rl.receiver.asBinder().unlinkToDeath(rl, 0); 18902 } 18903 } 18904 } 18905 18906 // If we actually concluded any broadcasts, we might now be able 18907 // to trim the recipients' apps from our working set 18908 if (doTrim) { 18909 trimApplications(); 18910 return; 18911 } 18912 18913 } finally { 18914 Binder.restoreCallingIdentity(origId); 18915 } 18916 } 18917 18918 void removeReceiverLocked(ReceiverList rl) { 18919 mRegisteredReceivers.remove(rl.receiver.asBinder()); 18920 for (int i = rl.size() - 1; i >= 0; i--) { 18921 mReceiverResolver.removeFilter(rl.get(i)); 18922 } 18923 } 18924 18925 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 18926 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18927 ProcessRecord r = mLruProcesses.get(i); 18928 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 18929 try { 18930 r.thread.dispatchPackageBroadcast(cmd, packages); 18931 } catch (RemoteException ex) { 18932 } 18933 } 18934 } 18935 } 18936 18937 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 18938 int callingUid, int[] users) { 18939 // TODO: come back and remove this assumption to triage all broadcasts 18940 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING; 18941 18942 List<ResolveInfo> receivers = null; 18943 try { 18944 HashSet<ComponentName> singleUserReceivers = null; 18945 boolean scannedFirstReceivers = false; 18946 for (int user : users) { 18947 // Skip users that have Shell restrictions, with exception of always permitted 18948 // Shell broadcasts 18949 if (callingUid == SHELL_UID 18950 && mUserController.hasUserRestriction( 18951 UserManager.DISALLOW_DEBUGGING_FEATURES, user) 18952 && !isPermittedShellBroadcast(intent)) { 18953 continue; 18954 } 18955 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 18956 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList(); 18957 if (user != UserHandle.USER_SYSTEM && newReceivers != null) { 18958 // If this is not the system user, we need to check for 18959 // any receivers that should be filtered out. 18960 for (int i=0; i<newReceivers.size(); i++) { 18961 ResolveInfo ri = newReceivers.get(i); 18962 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 18963 newReceivers.remove(i); 18964 i--; 18965 } 18966 } 18967 } 18968 if (newReceivers != null && newReceivers.size() == 0) { 18969 newReceivers = null; 18970 } 18971 if (receivers == null) { 18972 receivers = newReceivers; 18973 } else if (newReceivers != null) { 18974 // We need to concatenate the additional receivers 18975 // found with what we have do far. This would be easy, 18976 // but we also need to de-dup any receivers that are 18977 // singleUser. 18978 if (!scannedFirstReceivers) { 18979 // Collect any single user receivers we had already retrieved. 18980 scannedFirstReceivers = true; 18981 for (int i=0; i<receivers.size(); i++) { 18982 ResolveInfo ri = receivers.get(i); 18983 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 18984 ComponentName cn = new ComponentName( 18985 ri.activityInfo.packageName, ri.activityInfo.name); 18986 if (singleUserReceivers == null) { 18987 singleUserReceivers = new HashSet<ComponentName>(); 18988 } 18989 singleUserReceivers.add(cn); 18990 } 18991 } 18992 } 18993 // Add the new results to the existing results, tracking 18994 // and de-dupping single user receivers. 18995 for (int i=0; i<newReceivers.size(); i++) { 18996 ResolveInfo ri = newReceivers.get(i); 18997 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 18998 ComponentName cn = new ComponentName( 18999 ri.activityInfo.packageName, ri.activityInfo.name); 19000 if (singleUserReceivers == null) { 19001 singleUserReceivers = new HashSet<ComponentName>(); 19002 } 19003 if (!singleUserReceivers.contains(cn)) { 19004 singleUserReceivers.add(cn); 19005 receivers.add(ri); 19006 } 19007 } else { 19008 receivers.add(ri); 19009 } 19010 } 19011 } 19012 } 19013 } catch (RemoteException ex) { 19014 // pm is in same process, this will never happen. 19015 } 19016 return receivers; 19017 } 19018 19019 private boolean isPermittedShellBroadcast(Intent intent) { 19020 // remote bugreport should always be allowed to be taken 19021 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction()); 19022 } 19023 19024 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp, 19025 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) { 19026 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) { 19027 // Don't yell about broadcasts sent via shell 19028 return; 19029 } 19030 19031 final String action = intent.getAction(); 19032 if (isProtectedBroadcast 19033 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) 19034 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action) 19035 || Intent.ACTION_MEDIA_BUTTON.equals(action) 19036 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action) 19037 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action) 19038 || Intent.ACTION_MASTER_CLEAR.equals(action) 19039 || Intent.ACTION_FACTORY_RESET.equals(action) 19040 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action) 19041 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action) 19042 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action) 19043 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action) 19044 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action) 19045 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action) 19046 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) { 19047 // Broadcast is either protected, or it's a public action that 19048 // we've relaxed, so it's fine for system internals to send. 19049 return; 19050 } 19051 19052 // This broadcast may be a problem... but there are often system components that 19053 // want to send an internal broadcast to themselves, which is annoying to have to 19054 // explicitly list each action as a protected broadcast, so we will check for that 19055 // one safe case and allow it: an explicit broadcast, only being received by something 19056 // that has protected itself. 19057 if (receivers != null && receivers.size() > 0 19058 && (intent.getPackage() != null || intent.getComponent() != null)) { 19059 boolean allProtected = true; 19060 for (int i = receivers.size()-1; i >= 0; i--) { 19061 Object target = receivers.get(i); 19062 if (target instanceof ResolveInfo) { 19063 ResolveInfo ri = (ResolveInfo)target; 19064 if (ri.activityInfo.exported && ri.activityInfo.permission == null) { 19065 allProtected = false; 19066 break; 19067 } 19068 } else { 19069 BroadcastFilter bf = (BroadcastFilter)target; 19070 if (bf.requiredPermission == null) { 19071 allProtected = false; 19072 break; 19073 } 19074 } 19075 } 19076 if (allProtected) { 19077 // All safe! 19078 return; 19079 } 19080 } 19081 19082 // The vast majority of broadcasts sent from system internals 19083 // should be protected to avoid security holes, so yell loudly 19084 // to ensure we examine these cases. 19085 if (callerApp != null) { 19086 Log.wtf(TAG, "Sending non-protected broadcast " + action 19087 + " from system " + callerApp.toShortString() + " pkg " + callerPackage, 19088 new Throwable()); 19089 } else { 19090 Log.wtf(TAG, "Sending non-protected broadcast " + action 19091 + " from system uid " + UserHandle.formatUid(callingUid) 19092 + " pkg " + callerPackage, 19093 new Throwable()); 19094 } 19095 } 19096 19097 final int broadcastIntentLocked(ProcessRecord callerApp, 19098 String callerPackage, Intent intent, String resolvedType, 19099 IIntentReceiver resultTo, int resultCode, String resultData, 19100 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, 19101 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) { 19102 intent = new Intent(intent); 19103 19104 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid); 19105 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS 19106 if (callerInstantApp) { 19107 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 19108 } 19109 19110 // By default broadcasts do not go to stopped apps. 19111 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 19112 19113 // If we have not finished booting, don't allow this to launch new processes. 19114 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 19115 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19116 } 19117 19118 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, 19119 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 19120 + " ordered=" + ordered + " userid=" + userId); 19121 if ((resultTo != null) && !ordered) { 19122 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 19123 } 19124 19125 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true, 19126 ALLOW_NON_FULL, "broadcast", callerPackage); 19127 19128 // Make sure that the user who is receiving this broadcast is running. 19129 // If not, we will just skip it. Make an exception for shutdown broadcasts 19130 // and upgrade steps. 19131 19132 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) { 19133 if ((callingUid != SYSTEM_UID 19134 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 19135 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 19136 Slog.w(TAG, "Skipping broadcast of " + intent 19137 + ": user " + userId + " is stopped"); 19138 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 19139 } 19140 } 19141 19142 BroadcastOptions brOptions = null; 19143 if (bOptions != null) { 19144 brOptions = new BroadcastOptions(bOptions); 19145 if (brOptions.getTemporaryAppWhitelistDuration() > 0) { 19146 // See if the caller is allowed to do this. Note we are checking against 19147 // the actual real caller (not whoever provided the operation as say a 19148 // PendingIntent), because that who is actually supplied the arguments. 19149 if (checkComponentPermission( 19150 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, 19151 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 19152 != PackageManager.PERMISSION_GRANTED) { 19153 String msg = "Permission Denial: " + intent.getAction() 19154 + " broadcast from " + callerPackage + " (pid=" + callingPid 19155 + ", uid=" + callingUid + ")" 19156 + " requires " 19157 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST; 19158 Slog.w(TAG, msg); 19159 throw new SecurityException(msg); 19160 } 19161 } 19162 } 19163 19164 // Verify that protected broadcasts are only being sent by system code, 19165 // and that system code is only sending protected broadcasts. 19166 final String action = intent.getAction(); 19167 final boolean isProtectedBroadcast; 19168 try { 19169 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action); 19170 } catch (RemoteException e) { 19171 Slog.w(TAG, "Remote exception", e); 19172 return ActivityManager.BROADCAST_SUCCESS; 19173 } 19174 19175 final boolean isCallerSystem; 19176 switch (UserHandle.getAppId(callingUid)) { 19177 case ROOT_UID: 19178 case SYSTEM_UID: 19179 case PHONE_UID: 19180 case BLUETOOTH_UID: 19181 case NFC_UID: 19182 isCallerSystem = true; 19183 break; 19184 default: 19185 isCallerSystem = (callerApp != null) && callerApp.persistent; 19186 break; 19187 } 19188 19189 // First line security check before anything else: stop non-system apps from 19190 // sending protected broadcasts. 19191 if (!isCallerSystem) { 19192 if (isProtectedBroadcast) { 19193 String msg = "Permission Denial: not allowed to send broadcast " 19194 + action + " from pid=" 19195 + callingPid + ", uid=" + callingUid; 19196 Slog.w(TAG, msg); 19197 throw new SecurityException(msg); 19198 19199 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action) 19200 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) { 19201 // Special case for compatibility: we don't want apps to send this, 19202 // but historically it has not been protected and apps may be using it 19203 // to poke their own app widget. So, instead of making it protected, 19204 // just limit it to the caller. 19205 if (callerPackage == null) { 19206 String msg = "Permission Denial: not allowed to send broadcast " 19207 + action + " from unknown caller."; 19208 Slog.w(TAG, msg); 19209 throw new SecurityException(msg); 19210 } else if (intent.getComponent() != null) { 19211 // They are good enough to send to an explicit component... verify 19212 // it is being sent to the calling app. 19213 if (!intent.getComponent().getPackageName().equals( 19214 callerPackage)) { 19215 String msg = "Permission Denial: not allowed to send broadcast " 19216 + action + " to " 19217 + intent.getComponent().getPackageName() + " from " 19218 + callerPackage; 19219 Slog.w(TAG, msg); 19220 throw new SecurityException(msg); 19221 } 19222 } else { 19223 // Limit broadcast to their own package. 19224 intent.setPackage(callerPackage); 19225 } 19226 } 19227 } 19228 19229 if (action != null) { 19230 if (getBackgroundLaunchBroadcasts().contains(action)) { 19231 if (DEBUG_BACKGROUND_CHECK) { 19232 Slog.i(TAG, "Broadcast action " + action + " forcing include-background"); 19233 } 19234 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 19235 } 19236 19237 switch (action) { 19238 case Intent.ACTION_UID_REMOVED: 19239 case Intent.ACTION_PACKAGE_REMOVED: 19240 case Intent.ACTION_PACKAGE_CHANGED: 19241 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 19242 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 19243 case Intent.ACTION_PACKAGES_SUSPENDED: 19244 case Intent.ACTION_PACKAGES_UNSUSPENDED: 19245 // Handle special intents: if this broadcast is from the package 19246 // manager about a package being removed, we need to remove all of 19247 // its activities from the history stack. 19248 if (checkComponentPermission( 19249 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 19250 callingPid, callingUid, -1, true) 19251 != PackageManager.PERMISSION_GRANTED) { 19252 String msg = "Permission Denial: " + intent.getAction() 19253 + " broadcast from " + callerPackage + " (pid=" + callingPid 19254 + ", uid=" + callingUid + ")" 19255 + " requires " 19256 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 19257 Slog.w(TAG, msg); 19258 throw new SecurityException(msg); 19259 } 19260 switch (action) { 19261 case Intent.ACTION_UID_REMOVED: 19262 final int uid = getUidFromIntent(intent); 19263 if (uid >= 0) { 19264 mBatteryStatsService.removeUid(uid); 19265 mAppOpsService.uidRemoved(uid); 19266 } 19267 break; 19268 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 19269 // If resources are unavailable just force stop all those packages 19270 // and flush the attribute cache as well. 19271 String list[] = 19272 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 19273 if (list != null && list.length > 0) { 19274 for (int i = 0; i < list.length; i++) { 19275 forceStopPackageLocked(list[i], -1, false, true, true, 19276 false, false, userId, "storage unmount"); 19277 } 19278 mRecentTasks.cleanupLocked(UserHandle.USER_ALL); 19279 sendPackageBroadcastLocked( 19280 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE, 19281 list, userId); 19282 } 19283 break; 19284 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 19285 mRecentTasks.cleanupLocked(UserHandle.USER_ALL); 19286 break; 19287 case Intent.ACTION_PACKAGE_REMOVED: 19288 case Intent.ACTION_PACKAGE_CHANGED: 19289 Uri data = intent.getData(); 19290 String ssp; 19291 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 19292 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 19293 final boolean replacing = 19294 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 19295 final boolean killProcess = 19296 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false); 19297 final boolean fullUninstall = removed && !replacing; 19298 if (removed) { 19299 if (killProcess) { 19300 forceStopPackageLocked(ssp, UserHandle.getAppId( 19301 intent.getIntExtra(Intent.EXTRA_UID, -1)), 19302 false, true, true, false, fullUninstall, userId, 19303 removed ? "pkg removed" : "pkg changed"); 19304 } 19305 final int cmd = killProcess 19306 ? ApplicationThreadConstants.PACKAGE_REMOVED 19307 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL; 19308 sendPackageBroadcastLocked(cmd, 19309 new String[] {ssp}, userId); 19310 if (fullUninstall) { 19311 mAppOpsService.packageRemoved( 19312 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 19313 19314 // Remove all permissions granted from/to this package 19315 removeUriPermissionsForPackageLocked(ssp, userId, true); 19316 19317 removeTasksByPackageNameLocked(ssp, userId); 19318 19319 mServices.forceStopPackageLocked(ssp, userId); 19320 19321 // Hide the "unsupported display" dialog if necessary. 19322 if (mUnsupportedDisplaySizeDialog != null && ssp.equals( 19323 mUnsupportedDisplaySizeDialog.getPackageName())) { 19324 mUnsupportedDisplaySizeDialog.dismiss(); 19325 mUnsupportedDisplaySizeDialog = null; 19326 } 19327 mCompatModePackages.handlePackageUninstalledLocked(ssp); 19328 mBatteryStatsService.notePackageUninstalled(ssp); 19329 } 19330 } else { 19331 if (killProcess) { 19332 killPackageProcessesLocked(ssp, UserHandle.getAppId( 19333 intent.getIntExtra(Intent.EXTRA_UID, -1)), 19334 userId, ProcessList.INVALID_ADJ, 19335 false, true, true, false, "change " + ssp); 19336 } 19337 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess, 19338 intent.getStringArrayExtra( 19339 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST)); 19340 } 19341 } 19342 break; 19343 case Intent.ACTION_PACKAGES_SUSPENDED: 19344 case Intent.ACTION_PACKAGES_UNSUSPENDED: 19345 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals( 19346 intent.getAction()); 19347 final String[] packageNames = intent.getStringArrayExtra( 19348 Intent.EXTRA_CHANGED_PACKAGE_LIST); 19349 final int userHandle = intent.getIntExtra( 19350 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 19351 19352 synchronized(ActivityManagerService.this) { 19353 mRecentTasks.onPackagesSuspendedChanged( 19354 packageNames, suspended, userHandle); 19355 } 19356 break; 19357 } 19358 break; 19359 case Intent.ACTION_PACKAGE_REPLACED: 19360 { 19361 final Uri data = intent.getData(); 19362 final String ssp; 19363 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 19364 ApplicationInfo aInfo = null; 19365 try { 19366 aInfo = AppGlobals.getPackageManager() 19367 .getApplicationInfo(ssp, 0 /*flags*/, userId); 19368 } catch (RemoteException ignore) {} 19369 if (aInfo == null) { 19370 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:" 19371 + " ssp=" + ssp + " data=" + data); 19372 return ActivityManager.BROADCAST_SUCCESS; 19373 } 19374 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo); 19375 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED, 19376 new String[] {ssp}, userId); 19377 } 19378 break; 19379 } 19380 case Intent.ACTION_PACKAGE_ADDED: 19381 { 19382 // Special case for adding a package: by default turn on compatibility mode. 19383 Uri data = intent.getData(); 19384 String ssp; 19385 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 19386 final boolean replacing = 19387 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 19388 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 19389 19390 try { 19391 ApplicationInfo ai = AppGlobals.getPackageManager(). 19392 getApplicationInfo(ssp, 0, 0); 19393 mBatteryStatsService.notePackageInstalled(ssp, 19394 ai != null ? ai.versionCode : 0); 19395 } catch (RemoteException e) { 19396 } 19397 } 19398 break; 19399 } 19400 case Intent.ACTION_PACKAGE_DATA_CLEARED: 19401 { 19402 Uri data = intent.getData(); 19403 String ssp; 19404 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 19405 // Hide the "unsupported display" dialog if necessary. 19406 if (mUnsupportedDisplaySizeDialog != null && ssp.equals( 19407 mUnsupportedDisplaySizeDialog.getPackageName())) { 19408 mUnsupportedDisplaySizeDialog.dismiss(); 19409 mUnsupportedDisplaySizeDialog = null; 19410 } 19411 mCompatModePackages.handlePackageDataClearedLocked(ssp); 19412 } 19413 break; 19414 } 19415 case Intent.ACTION_TIMEZONE_CHANGED: 19416 // If this is the time zone changed action, queue up a message that will reset 19417 // the timezone of all currently running processes. This message will get 19418 // queued up before the broadcast happens. 19419 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 19420 break; 19421 case Intent.ACTION_TIME_CHANGED: 19422 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between 19423 // the tri-state value it may contain and "unknown". 19424 // For convenience we re-use the Intent extra values. 19425 final int NO_EXTRA_VALUE_FOUND = -1; 19426 final int timeFormatPreferenceMsgValue = intent.getIntExtra( 19427 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, 19428 NO_EXTRA_VALUE_FOUND /* defaultValue */); 19429 // Only send a message if the time preference is available. 19430 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) { 19431 Message updateTimePreferenceMsg = 19432 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG, 19433 timeFormatPreferenceMsgValue, 0); 19434 mHandler.sendMessage(updateTimePreferenceMsg); 19435 } 19436 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 19437 synchronized (stats) { 19438 stats.noteCurrentTimeChangedLocked(); 19439 } 19440 break; 19441 case Intent.ACTION_CLEAR_DNS_CACHE: 19442 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 19443 break; 19444 case Proxy.PROXY_CHANGE_ACTION: 19445 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 19446 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 19447 break; 19448 case android.hardware.Camera.ACTION_NEW_PICTURE: 19449 case android.hardware.Camera.ACTION_NEW_VIDEO: 19450 // In N we just turned these off; in O we are turing them back on partly, 19451 // only for registered receivers. This will still address the main problem 19452 // (a spam of apps waking up when a picture is taken putting significant 19453 // memory pressure on the system at a bad point), while still allowing apps 19454 // that are already actively running to know about this happening. 19455 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19456 break; 19457 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED: 19458 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG); 19459 break; 19460 case "com.android.launcher.action.INSTALL_SHORTCUT": 19461 // As of O, we no longer support this broadcasts, even for pre-O apps. 19462 // Apps should now be using ShortcutManager.pinRequestShortcut(). 19463 Log.w(TAG, "Broadcast " + action 19464 + " no longer supported. It will not be delivered."); 19465 return ActivityManager.BROADCAST_SUCCESS; 19466 } 19467 19468 if (Intent.ACTION_PACKAGE_ADDED.equals(action) || 19469 Intent.ACTION_PACKAGE_REMOVED.equals(action) || 19470 Intent.ACTION_PACKAGE_REPLACED.equals(action)) { 19471 final int uid = getUidFromIntent(intent); 19472 if (uid != -1) { 19473 final UidRecord uidRec = mActiveUids.get(uid); 19474 if (uidRec != null) { 19475 uidRec.updateHasInternetPermission(); 19476 } 19477 } 19478 } 19479 } 19480 19481 // Add to the sticky list if requested. 19482 if (sticky) { 19483 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 19484 callingPid, callingUid) 19485 != PackageManager.PERMISSION_GRANTED) { 19486 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 19487 + callingPid + ", uid=" + callingUid 19488 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 19489 Slog.w(TAG, msg); 19490 throw new SecurityException(msg); 19491 } 19492 if (requiredPermissions != null && requiredPermissions.length > 0) { 19493 Slog.w(TAG, "Can't broadcast sticky intent " + intent 19494 + " and enforce permissions " + Arrays.toString(requiredPermissions)); 19495 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 19496 } 19497 if (intent.getComponent() != null) { 19498 throw new SecurityException( 19499 "Sticky broadcasts can't target a specific component"); 19500 } 19501 // We use userId directly here, since the "all" target is maintained 19502 // as a separate set of sticky broadcasts. 19503 if (userId != UserHandle.USER_ALL) { 19504 // But first, if this is not a broadcast to all users, then 19505 // make sure it doesn't conflict with an existing broadcast to 19506 // all users. 19507 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 19508 UserHandle.USER_ALL); 19509 if (stickies != null) { 19510 ArrayList<Intent> list = stickies.get(intent.getAction()); 19511 if (list != null) { 19512 int N = list.size(); 19513 int i; 19514 for (i=0; i<N; i++) { 19515 if (intent.filterEquals(list.get(i))) { 19516 throw new IllegalArgumentException( 19517 "Sticky broadcast " + intent + " for user " 19518 + userId + " conflicts with existing global broadcast"); 19519 } 19520 } 19521 } 19522 } 19523 } 19524 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 19525 if (stickies == null) { 19526 stickies = new ArrayMap<>(); 19527 mStickyBroadcasts.put(userId, stickies); 19528 } 19529 ArrayList<Intent> list = stickies.get(intent.getAction()); 19530 if (list == null) { 19531 list = new ArrayList<>(); 19532 stickies.put(intent.getAction(), list); 19533 } 19534 final int stickiesCount = list.size(); 19535 int i; 19536 for (i = 0; i < stickiesCount; i++) { 19537 if (intent.filterEquals(list.get(i))) { 19538 // This sticky already exists, replace it. 19539 list.set(i, new Intent(intent)); 19540 break; 19541 } 19542 } 19543 if (i >= stickiesCount) { 19544 list.add(new Intent(intent)); 19545 } 19546 } 19547 19548 int[] users; 19549 if (userId == UserHandle.USER_ALL) { 19550 // Caller wants broadcast to go to all started users. 19551 users = mUserController.getStartedUserArrayLocked(); 19552 } else { 19553 // Caller wants broadcast to go to one specific user. 19554 users = new int[] {userId}; 19555 } 19556 19557 // Figure out who all will receive this broadcast. 19558 List receivers = null; 19559 List<BroadcastFilter> registeredReceivers = null; 19560 // Need to resolve the intent to interested receivers... 19561 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 19562 == 0) { 19563 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 19564 } 19565 if (intent.getComponent() == null) { 19566 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) { 19567 // Query one target user at a time, excluding shell-restricted users 19568 for (int i = 0; i < users.length; i++) { 19569 if (mUserController.hasUserRestriction( 19570 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 19571 continue; 19572 } 19573 List<BroadcastFilter> registeredReceiversForUser = 19574 mReceiverResolver.queryIntent(intent, 19575 resolvedType, false /*defaultOnly*/, users[i]); 19576 if (registeredReceivers == null) { 19577 registeredReceivers = registeredReceiversForUser; 19578 } else if (registeredReceiversForUser != null) { 19579 registeredReceivers.addAll(registeredReceiversForUser); 19580 } 19581 } 19582 } else { 19583 registeredReceivers = mReceiverResolver.queryIntent(intent, 19584 resolvedType, false /*defaultOnly*/, userId); 19585 } 19586 } 19587 19588 final boolean replacePending = 19589 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 19590 19591 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction() 19592 + " replacePending=" + replacePending); 19593 19594 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 19595 if (!ordered && NR > 0) { 19596 // If we are not serializing this broadcast, then send the 19597 // registered receivers separately so they don't wait for the 19598 // components to be launched. 19599 if (isCallerSystem) { 19600 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, 19601 isProtectedBroadcast, registeredReceivers); 19602 } 19603 final BroadcastQueue queue = broadcastQueueForIntent(intent); 19604 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 19605 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType, 19606 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo, 19607 resultCode, resultData, resultExtras, ordered, sticky, false, userId); 19608 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r); 19609 final boolean replaced = replacePending 19610 && (queue.replaceParallelBroadcastLocked(r) != null); 19611 // Note: We assume resultTo is null for non-ordered broadcasts. 19612 if (!replaced) { 19613 queue.enqueueParallelBroadcastLocked(r); 19614 queue.scheduleBroadcastsLocked(); 19615 } 19616 registeredReceivers = null; 19617 NR = 0; 19618 } 19619 19620 // Merge into one list. 19621 int ir = 0; 19622 if (receivers != null) { 19623 // A special case for PACKAGE_ADDED: do not allow the package 19624 // being added to see this broadcast. This prevents them from 19625 // using this as a back door to get run as soon as they are 19626 // installed. Maybe in the future we want to have a special install 19627 // broadcast or such for apps, but we'd like to deliberately make 19628 // this decision. 19629 String skipPackages[] = null; 19630 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 19631 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 19632 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 19633 Uri data = intent.getData(); 19634 if (data != null) { 19635 String pkgName = data.getSchemeSpecificPart(); 19636 if (pkgName != null) { 19637 skipPackages = new String[] { pkgName }; 19638 } 19639 } 19640 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 19641 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 19642 } 19643 if (skipPackages != null && (skipPackages.length > 0)) { 19644 for (String skipPackage : skipPackages) { 19645 if (skipPackage != null) { 19646 int NT = receivers.size(); 19647 for (int it=0; it<NT; it++) { 19648 ResolveInfo curt = (ResolveInfo)receivers.get(it); 19649 if (curt.activityInfo.packageName.equals(skipPackage)) { 19650 receivers.remove(it); 19651 it--; 19652 NT--; 19653 } 19654 } 19655 } 19656 } 19657 } 19658 19659 int NT = receivers != null ? receivers.size() : 0; 19660 int it = 0; 19661 ResolveInfo curt = null; 19662 BroadcastFilter curr = null; 19663 while (it < NT && ir < NR) { 19664 if (curt == null) { 19665 curt = (ResolveInfo)receivers.get(it); 19666 } 19667 if (curr == null) { 19668 curr = registeredReceivers.get(ir); 19669 } 19670 if (curr.getPriority() >= curt.priority) { 19671 // Insert this broadcast record into the final list. 19672 receivers.add(it, curr); 19673 ir++; 19674 curr = null; 19675 it++; 19676 NT++; 19677 } else { 19678 // Skip to the next ResolveInfo in the final list. 19679 it++; 19680 curt = null; 19681 } 19682 } 19683 } 19684 while (ir < NR) { 19685 if (receivers == null) { 19686 receivers = new ArrayList(); 19687 } 19688 receivers.add(registeredReceivers.get(ir)); 19689 ir++; 19690 } 19691 19692 if (isCallerSystem) { 19693 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, 19694 isProtectedBroadcast, receivers); 19695 } 19696 19697 if ((receivers != null && receivers.size() > 0) 19698 || resultTo != null) { 19699 BroadcastQueue queue = broadcastQueueForIntent(intent); 19700 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 19701 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType, 19702 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode, 19703 resultData, resultExtras, ordered, sticky, false, userId); 19704 19705 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r 19706 + ": prev had " + queue.mOrderedBroadcasts.size()); 19707 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST, 19708 "Enqueueing broadcast " + r.intent.getAction()); 19709 19710 final BroadcastRecord oldRecord = 19711 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null; 19712 if (oldRecord != null) { 19713 // Replaced, fire the result-to receiver. 19714 if (oldRecord.resultTo != null) { 19715 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent); 19716 try { 19717 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo, 19718 oldRecord.intent, 19719 Activity.RESULT_CANCELED, null, null, 19720 false, false, oldRecord.userId); 19721 } catch (RemoteException e) { 19722 Slog.w(TAG, "Failure [" 19723 + queue.mQueueName + "] sending broadcast result of " 19724 + intent, e); 19725 19726 } 19727 } 19728 } else { 19729 queue.enqueueOrderedBroadcastLocked(r); 19730 queue.scheduleBroadcastsLocked(); 19731 } 19732 } else { 19733 // There was nobody interested in the broadcast, but we still want to record 19734 // that it happened. 19735 if (intent.getComponent() == null && intent.getPackage() == null 19736 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 19737 // This was an implicit broadcast... let's record it for posterity. 19738 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0); 19739 } 19740 } 19741 19742 return ActivityManager.BROADCAST_SUCCESS; 19743 } 19744 19745 /** 19746 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1 19747 */ 19748 private int getUidFromIntent(Intent intent) { 19749 if (intent == null) { 19750 return -1; 19751 } 19752 final Bundle intentExtras = intent.getExtras(); 19753 return intent.hasExtra(Intent.EXTRA_UID) 19754 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 19755 } 19756 19757 final void rotateBroadcastStatsIfNeededLocked() { 19758 final long now = SystemClock.elapsedRealtime(); 19759 if (mCurBroadcastStats == null || 19760 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) { 19761 mLastBroadcastStats = mCurBroadcastStats; 19762 if (mLastBroadcastStats != null) { 19763 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime(); 19764 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis(); 19765 } 19766 mCurBroadcastStats = new BroadcastStats(); 19767 } 19768 } 19769 19770 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount, 19771 int skipCount, long dispatchTime) { 19772 rotateBroadcastStatsIfNeededLocked(); 19773 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime); 19774 } 19775 19776 final void addBackgroundCheckViolationLocked(String action, String targetPackage) { 19777 rotateBroadcastStatsIfNeededLocked(); 19778 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage); 19779 } 19780 19781 final Intent verifyBroadcastLocked(Intent intent) { 19782 // Refuse possible leaked file descriptors 19783 if (intent != null && intent.hasFileDescriptors() == true) { 19784 throw new IllegalArgumentException("File descriptors passed in Intent"); 19785 } 19786 19787 int flags = intent.getFlags(); 19788 19789 if (!mProcessesReady) { 19790 // if the caller really truly claims to know what they're doing, go 19791 // ahead and allow the broadcast without launching any receivers 19792 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 19793 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed. 19794 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 19795 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 19796 + " before boot completion"); 19797 throw new IllegalStateException("Cannot broadcast before boot completed"); 19798 } 19799 } 19800 19801 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 19802 throw new IllegalArgumentException( 19803 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 19804 } 19805 19806 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) { 19807 switch (Binder.getCallingUid()) { 19808 case ROOT_UID: 19809 case SHELL_UID: 19810 break; 19811 default: 19812 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID " 19813 + Binder.getCallingUid()); 19814 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL); 19815 break; 19816 } 19817 } 19818 19819 return intent; 19820 } 19821 19822 public final int broadcastIntent(IApplicationThread caller, 19823 Intent intent, String resolvedType, IIntentReceiver resultTo, 19824 int resultCode, String resultData, Bundle resultExtras, 19825 String[] requiredPermissions, int appOp, Bundle bOptions, 19826 boolean serialized, boolean sticky, int userId) { 19827 enforceNotIsolatedCaller("broadcastIntent"); 19828 synchronized(this) { 19829 intent = verifyBroadcastLocked(intent); 19830 19831 final ProcessRecord callerApp = getRecordForAppLocked(caller); 19832 final int callingPid = Binder.getCallingPid(); 19833 final int callingUid = Binder.getCallingUid(); 19834 final long origId = Binder.clearCallingIdentity(); 19835 int res = broadcastIntentLocked(callerApp, 19836 callerApp != null ? callerApp.info.packageName : null, 19837 intent, resolvedType, resultTo, resultCode, resultData, resultExtras, 19838 requiredPermissions, appOp, bOptions, serialized, sticky, 19839 callingPid, callingUid, userId); 19840 Binder.restoreCallingIdentity(origId); 19841 return res; 19842 } 19843 } 19844 19845 19846 int broadcastIntentInPackage(String packageName, int uid, 19847 Intent intent, String resolvedType, IIntentReceiver resultTo, 19848 int resultCode, String resultData, Bundle resultExtras, 19849 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky, 19850 int userId) { 19851 synchronized(this) { 19852 intent = verifyBroadcastLocked(intent); 19853 19854 final long origId = Binder.clearCallingIdentity(); 19855 String[] requiredPermissions = requiredPermission == null ? null 19856 : new String[] {requiredPermission}; 19857 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 19858 resultTo, resultCode, resultData, resultExtras, 19859 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized, 19860 sticky, -1, uid, userId); 19861 Binder.restoreCallingIdentity(origId); 19862 return res; 19863 } 19864 } 19865 19866 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 19867 // Refuse possible leaked file descriptors 19868 if (intent != null && intent.hasFileDescriptors() == true) { 19869 throw new IllegalArgumentException("File descriptors passed in Intent"); 19870 } 19871 19872 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 19873 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 19874 19875 synchronized(this) { 19876 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 19877 != PackageManager.PERMISSION_GRANTED) { 19878 String msg = "Permission Denial: unbroadcastIntent() from pid=" 19879 + Binder.getCallingPid() 19880 + ", uid=" + Binder.getCallingUid() 19881 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 19882 Slog.w(TAG, msg); 19883 throw new SecurityException(msg); 19884 } 19885 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 19886 if (stickies != null) { 19887 ArrayList<Intent> list = stickies.get(intent.getAction()); 19888 if (list != null) { 19889 int N = list.size(); 19890 int i; 19891 for (i=0; i<N; i++) { 19892 if (intent.filterEquals(list.get(i))) { 19893 list.remove(i); 19894 break; 19895 } 19896 } 19897 if (list.size() <= 0) { 19898 stickies.remove(intent.getAction()); 19899 } 19900 } 19901 if (stickies.size() <= 0) { 19902 mStickyBroadcasts.remove(userId); 19903 } 19904 } 19905 } 19906 } 19907 19908 void backgroundServicesFinishedLocked(int userId) { 19909 for (BroadcastQueue queue : mBroadcastQueues) { 19910 queue.backgroundServicesFinishedLocked(userId); 19911 } 19912 } 19913 19914 public void finishReceiver(IBinder who, int resultCode, String resultData, 19915 Bundle resultExtras, boolean resultAbort, int flags) { 19916 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who); 19917 19918 // Refuse possible leaked file descriptors 19919 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 19920 throw new IllegalArgumentException("File descriptors passed in Bundle"); 19921 } 19922 19923 final long origId = Binder.clearCallingIdentity(); 19924 try { 19925 boolean doNext = false; 19926 BroadcastRecord r; 19927 19928 synchronized(this) { 19929 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0 19930 ? mFgBroadcastQueue : mBgBroadcastQueue; 19931 r = queue.getMatchingOrderedReceiver(who); 19932 if (r != null) { 19933 doNext = r.queue.finishReceiverLocked(r, resultCode, 19934 resultData, resultExtras, resultAbort, true); 19935 } 19936 } 19937 19938 if (doNext) { 19939 r.queue.processNextBroadcast(false); 19940 } 19941 trimApplications(); 19942 } finally { 19943 Binder.restoreCallingIdentity(origId); 19944 } 19945 } 19946 19947 // ========================================================= 19948 // INSTRUMENTATION 19949 // ========================================================= 19950 19951 public boolean startInstrumentation(ComponentName className, 19952 String profileFile, int flags, Bundle arguments, 19953 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 19954 int userId, String abiOverride) { 19955 enforceNotIsolatedCaller("startInstrumentation"); 19956 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 19957 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 19958 // Refuse possible leaked file descriptors 19959 if (arguments != null && arguments.hasFileDescriptors()) { 19960 throw new IllegalArgumentException("File descriptors passed in Bundle"); 19961 } 19962 19963 synchronized(this) { 19964 InstrumentationInfo ii = null; 19965 ApplicationInfo ai = null; 19966 try { 19967 ii = mContext.getPackageManager().getInstrumentationInfo( 19968 className, STOCK_PM_FLAGS); 19969 ai = AppGlobals.getPackageManager().getApplicationInfo( 19970 ii.targetPackage, STOCK_PM_FLAGS, userId); 19971 } catch (PackageManager.NameNotFoundException e) { 19972 } catch (RemoteException e) { 19973 } 19974 if (ii == null) { 19975 reportStartInstrumentationFailureLocked(watcher, className, 19976 "Unable to find instrumentation info for: " + className); 19977 return false; 19978 } 19979 if (ai == null) { 19980 reportStartInstrumentationFailureLocked(watcher, className, 19981 "Unable to find instrumentation target package: " + ii.targetPackage); 19982 return false; 19983 } 19984 if (!ai.hasCode()) { 19985 reportStartInstrumentationFailureLocked(watcher, className, 19986 "Instrumentation target has no code: " + ii.targetPackage); 19987 return false; 19988 } 19989 19990 int match = mContext.getPackageManager().checkSignatures( 19991 ii.targetPackage, ii.packageName); 19992 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 19993 String msg = "Permission Denial: starting instrumentation " 19994 + className + " from pid=" 19995 + Binder.getCallingPid() 19996 + ", uid=" + Binder.getCallingPid() 19997 + " not allowed because package " + ii.packageName 19998 + " does not have a signature matching the target " 19999 + ii.targetPackage; 20000 reportStartInstrumentationFailureLocked(watcher, className, msg); 20001 throw new SecurityException(msg); 20002 } 20003 20004 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this); 20005 activeInstr.mClass = className; 20006 String defProcess = ai.processName;; 20007 if (ii.targetProcesses == null) { 20008 activeInstr.mTargetProcesses = new String[]{ai.processName}; 20009 } else if (ii.targetProcesses.equals("*")) { 20010 activeInstr.mTargetProcesses = new String[0]; 20011 } else { 20012 activeInstr.mTargetProcesses = ii.targetProcesses.split(","); 20013 defProcess = activeInstr.mTargetProcesses[0]; 20014 } 20015 activeInstr.mTargetInfo = ai; 20016 activeInstr.mProfileFile = profileFile; 20017 activeInstr.mArguments = arguments; 20018 activeInstr.mWatcher = watcher; 20019 activeInstr.mUiAutomationConnection = uiAutomationConnection; 20020 activeInstr.mResultClass = className; 20021 20022 final long origId = Binder.clearCallingIdentity(); 20023 // Instrumentation can kill and relaunch even persistent processes 20024 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 20025 "start instr"); 20026 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride); 20027 app.instr = activeInstr; 20028 activeInstr.mFinished = false; 20029 activeInstr.mRunningProcesses.add(app); 20030 if (!mActiveInstrumentation.contains(activeInstr)) { 20031 mActiveInstrumentation.add(activeInstr); 20032 } 20033 Binder.restoreCallingIdentity(origId); 20034 } 20035 20036 return true; 20037 } 20038 20039 /** 20040 * Report errors that occur while attempting to start Instrumentation. Always writes the 20041 * error to the logs, but if somebody is watching, send the report there too. This enables 20042 * the "am" command to report errors with more information. 20043 * 20044 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 20045 * @param cn The component name of the instrumentation. 20046 * @param report The error report. 20047 */ 20048 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher, 20049 ComponentName cn, String report) { 20050 Slog.w(TAG, report); 20051 if (watcher != null) { 20052 Bundle results = new Bundle(); 20053 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 20054 results.putString("Error", report); 20055 mInstrumentationReporter.reportStatus(watcher, cn, -1, results); 20056 } 20057 } 20058 20059 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) { 20060 if (app.instr == null) { 20061 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app); 20062 return; 20063 } 20064 20065 if (!app.instr.mFinished && results != null) { 20066 if (app.instr.mCurResults == null) { 20067 app.instr.mCurResults = new Bundle(results); 20068 } else { 20069 app.instr.mCurResults.putAll(results); 20070 } 20071 } 20072 } 20073 20074 public void addInstrumentationResults(IApplicationThread target, Bundle results) { 20075 int userId = UserHandle.getCallingUserId(); 20076 // Refuse possible leaked file descriptors 20077 if (results != null && results.hasFileDescriptors()) { 20078 throw new IllegalArgumentException("File descriptors passed in Intent"); 20079 } 20080 20081 synchronized(this) { 20082 ProcessRecord app = getRecordForAppLocked(target); 20083 if (app == null) { 20084 Slog.w(TAG, "addInstrumentationResults: no app for " + target); 20085 return; 20086 } 20087 final long origId = Binder.clearCallingIdentity(); 20088 addInstrumentationResultsLocked(app, results); 20089 Binder.restoreCallingIdentity(origId); 20090 } 20091 } 20092 20093 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 20094 if (app.instr == null) { 20095 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app); 20096 return; 20097 } 20098 20099 if (!app.instr.mFinished) { 20100 if (app.instr.mWatcher != null) { 20101 Bundle finalResults = app.instr.mCurResults; 20102 if (finalResults != null) { 20103 if (app.instr.mCurResults != null && results != null) { 20104 finalResults.putAll(results); 20105 } 20106 } else { 20107 finalResults = results; 20108 } 20109 mInstrumentationReporter.reportFinished(app.instr.mWatcher, 20110 app.instr.mClass, resultCode, finalResults); 20111 } 20112 20113 // Can't call out of the system process with a lock held, so post a message. 20114 if (app.instr.mUiAutomationConnection != null) { 20115 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG, 20116 app.instr.mUiAutomationConnection).sendToTarget(); 20117 } 20118 app.instr.mFinished = true; 20119 } 20120 20121 app.instr.removeProcess(app); 20122 app.instr = null; 20123 20124 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 20125 "finished inst"); 20126 } 20127 20128 public void finishInstrumentation(IApplicationThread target, 20129 int resultCode, Bundle results) { 20130 int userId = UserHandle.getCallingUserId(); 20131 // Refuse possible leaked file descriptors 20132 if (results != null && results.hasFileDescriptors()) { 20133 throw new IllegalArgumentException("File descriptors passed in Intent"); 20134 } 20135 20136 synchronized(this) { 20137 ProcessRecord app = getRecordForAppLocked(target); 20138 if (app == null) { 20139 Slog.w(TAG, "finishInstrumentation: no app for " + target); 20140 return; 20141 } 20142 final long origId = Binder.clearCallingIdentity(); 20143 finishInstrumentationLocked(app, resultCode, results); 20144 Binder.restoreCallingIdentity(origId); 20145 } 20146 } 20147 20148 // ========================================================= 20149 // CONFIGURATION 20150 // ========================================================= 20151 20152 public ConfigurationInfo getDeviceConfigurationInfo() { 20153 ConfigurationInfo config = new ConfigurationInfo(); 20154 synchronized (this) { 20155 final Configuration globalConfig = getGlobalConfiguration(); 20156 config.reqTouchScreen = globalConfig.touchscreen; 20157 config.reqKeyboardType = globalConfig.keyboard; 20158 config.reqNavigation = globalConfig.navigation; 20159 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD 20160 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) { 20161 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 20162 } 20163 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED 20164 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) { 20165 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 20166 } 20167 config.reqGlEsVersion = GL_ES_VERSION; 20168 } 20169 return config; 20170 } 20171 20172 ActivityStack getFocusedStack() { 20173 return mStackSupervisor.getFocusedStack(); 20174 } 20175 20176 @Override 20177 public int getFocusedStackId() throws RemoteException { 20178 ActivityStack focusedStack = getFocusedStack(); 20179 if (focusedStack != null) { 20180 return focusedStack.getStackId(); 20181 } 20182 return -1; 20183 } 20184 20185 public Configuration getConfiguration() { 20186 Configuration ci; 20187 synchronized(this) { 20188 ci = new Configuration(getGlobalConfiguration()); 20189 ci.userSetLocale = false; 20190 } 20191 return ci; 20192 } 20193 20194 @Override 20195 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException { 20196 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()"); 20197 synchronized (this) { 20198 mSuppressResizeConfigChanges = suppress; 20199 } 20200 } 20201 20202 /** 20203 * NOTE: For the pinned stack, this method is usually called after the bounds animation has 20204 * animated the stack to the fullscreen, but can also be called if we are relaunching an 20205 * activity and clearing the task at the same time. 20206 */ 20207 @Override 20208 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) { 20209 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()"); 20210 if (StackId.isHomeOrRecentsStack(fromStackId)) { 20211 throw new IllegalArgumentException("You can't move tasks from the home/recents stack."); 20212 } 20213 synchronized (this) { 20214 final long origId = Binder.clearCallingIdentity(); 20215 try { 20216 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop); 20217 } finally { 20218 Binder.restoreCallingIdentity(origId); 20219 } 20220 } 20221 } 20222 20223 @Override 20224 public void updatePersistentConfiguration(Configuration values) { 20225 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()"); 20226 enforceWriteSettingsPermission("updatePersistentConfiguration()"); 20227 if (values == null) { 20228 throw new NullPointerException("Configuration must not be null"); 20229 } 20230 20231 int userId = UserHandle.getCallingUserId(); 20232 20233 synchronized(this) { 20234 updatePersistentConfigurationLocked(values, userId); 20235 } 20236 } 20237 20238 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) { 20239 final long origId = Binder.clearCallingIdentity(); 20240 try { 20241 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */); 20242 } finally { 20243 Binder.restoreCallingIdentity(origId); 20244 } 20245 } 20246 20247 private void updateFontScaleIfNeeded(@UserIdInt int userId) { 20248 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(), 20249 FONT_SCALE, 1.0f, userId); 20250 20251 synchronized (this) { 20252 if (getGlobalConfiguration().fontScale == scaleFactor) { 20253 return; 20254 } 20255 20256 final Configuration configuration 20257 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY); 20258 configuration.fontScale = scaleFactor; 20259 updatePersistentConfigurationLocked(configuration, userId); 20260 } 20261 } 20262 20263 private void enforceWriteSettingsPermission(String func) { 20264 int uid = Binder.getCallingUid(); 20265 if (uid == ROOT_UID) { 20266 return; 20267 } 20268 20269 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid, 20270 Settings.getPackageNameForUid(mContext, uid), false)) { 20271 return; 20272 } 20273 20274 String msg = "Permission Denial: " + func + " from pid=" 20275 + Binder.getCallingPid() 20276 + ", uid=" + uid 20277 + " requires " + android.Manifest.permission.WRITE_SETTINGS; 20278 Slog.w(TAG, msg); 20279 throw new SecurityException(msg); 20280 } 20281 20282 @Override 20283 public boolean updateConfiguration(Configuration values) { 20284 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()"); 20285 20286 synchronized(this) { 20287 if (values == null && mWindowManager != null) { 20288 // sentinel: fetch the current configuration from the window manager 20289 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY); 20290 } 20291 20292 if (mWindowManager != null) { 20293 // Update OOM levels based on display size. 20294 mProcessList.applyDisplaySize(mWindowManager); 20295 } 20296 20297 final long origId = Binder.clearCallingIdentity(); 20298 try { 20299 if (values != null) { 20300 Settings.System.clearConfiguration(values); 20301 } 20302 updateConfigurationLocked(values, null, false, false /* persistent */, 20303 UserHandle.USER_NULL, false /* deferResume */, 20304 mTmpUpdateConfigurationResult); 20305 return mTmpUpdateConfigurationResult.changes != 0; 20306 } finally { 20307 Binder.restoreCallingIdentity(origId); 20308 } 20309 } 20310 } 20311 20312 void updateUserConfigurationLocked() { 20313 final Configuration configuration = new Configuration(getGlobalConfiguration()); 20314 final int currentUserId = mUserController.getCurrentUserIdLocked(); 20315 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration, 20316 currentUserId, Settings.System.canWrite(mContext)); 20317 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */, 20318 false /* persistent */, currentUserId, false /* deferResume */); 20319 } 20320 20321 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 20322 boolean initLocale) { 20323 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */); 20324 } 20325 20326 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 20327 boolean initLocale, boolean deferResume) { 20328 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user 20329 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */, 20330 UserHandle.USER_NULL, deferResume); 20331 } 20332 20333 // To cache the list of supported system locales 20334 private String[] mSupportedSystemLocales = null; 20335 20336 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 20337 boolean initLocale, boolean persistent, int userId, boolean deferResume) { 20338 return updateConfigurationLocked(values, starting, initLocale, persistent, userId, 20339 deferResume, null /* result */); 20340 } 20341 20342 /** 20343 * Do either or both things: (1) change the current configuration, and (2) 20344 * make sure the given activity is running with the (now) current 20345 * configuration. Returns true if the activity has been left running, or 20346 * false if <var>starting</var> is being destroyed to match the new 20347 * configuration. 20348 * 20349 * @param userId is only used when persistent parameter is set to true to persist configuration 20350 * for that particular user 20351 */ 20352 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 20353 boolean initLocale, boolean persistent, int userId, boolean deferResume, 20354 UpdateConfigurationResult result) { 20355 int changes = 0; 20356 boolean kept = true; 20357 20358 if (mWindowManager != null) { 20359 mWindowManager.deferSurfaceLayout(); 20360 } 20361 try { 20362 if (values != null) { 20363 changes = updateGlobalConfiguration(values, initLocale, persistent, userId, 20364 deferResume); 20365 } 20366 20367 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes); 20368 } finally { 20369 if (mWindowManager != null) { 20370 mWindowManager.continueSurfaceLayout(); 20371 } 20372 } 20373 20374 if (result != null) { 20375 result.changes = changes; 20376 result.activityRelaunched = !kept; 20377 } 20378 return kept; 20379 } 20380 20381 /** Update default (global) configuration and notify listeners about changes. */ 20382 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale, 20383 boolean persistent, int userId, boolean deferResume) { 20384 mTempConfig.setTo(getGlobalConfiguration()); 20385 final int changes = mTempConfig.updateFrom(values); 20386 if (changes == 0) { 20387 // Since calling to Activity.setRequestedOrientation leads to freezing the window with 20388 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call 20389 // performDisplayOverrideConfigUpdate in order to send the new display configuration 20390 // (even if there are no actual changes) to unfreeze the window. 20391 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY); 20392 return 0; 20393 } 20394 20395 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION, 20396 "Updating global configuration to: " + values); 20397 20398 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 20399 20400 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) { 20401 final LocaleList locales = values.getLocales(); 20402 int bestLocaleIndex = 0; 20403 if (locales.size() > 1) { 20404 if (mSupportedSystemLocales == null) { 20405 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales(); 20406 } 20407 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales)); 20408 } 20409 SystemProperties.set("persist.sys.locale", 20410 locales.get(bestLocaleIndex).toLanguageTag()); 20411 LocaleList.setDefault(locales, bestLocaleIndex); 20412 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, 20413 locales.get(bestLocaleIndex))); 20414 } 20415 20416 mConfigurationSeq = Math.max(++mConfigurationSeq, 1); 20417 mTempConfig.seq = mConfigurationSeq; 20418 20419 // Update stored global config and notify everyone about the change. 20420 mStackSupervisor.onConfigurationChanged(mTempConfig); 20421 20422 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig); 20423 // TODO(multi-display): Update UsageEvents#Event to include displayId. 20424 mUsageStatsService.reportConfigurationChange(mTempConfig, 20425 mUserController.getCurrentUserIdLocked()); 20426 20427 // TODO: If our config changes, should we auto dismiss any currently showing dialogs? 20428 mShowDialogs = shouldShowDialogs(mTempConfig); 20429 20430 AttributeCache ac = AttributeCache.instance(); 20431 if (ac != null) { 20432 ac.updateConfiguration(mTempConfig); 20433 } 20434 20435 // Make sure all resources in our process are updated right now, so that anyone who is going 20436 // to retrieve resource values after we return will be sure to get the new ones. This is 20437 // especially important during boot, where the first config change needs to guarantee all 20438 // resources have that config before following boot code is executed. 20439 mSystemThread.applyConfigurationToResources(mTempConfig); 20440 20441 // We need another copy of global config because we're scheduling some calls instead of 20442 // running them in place. We need to be sure that object we send will be handled unchanged. 20443 final Configuration configCopy = new Configuration(mTempConfig); 20444 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 20445 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 20446 msg.obj = configCopy; 20447 msg.arg1 = userId; 20448 mHandler.sendMessage(msg); 20449 } 20450 20451 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 20452 ProcessRecord app = mLruProcesses.get(i); 20453 try { 20454 if (app.thread != null) { 20455 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc " 20456 + app.processName + " new config " + configCopy); 20457 app.thread.scheduleConfigurationChanged(configCopy); 20458 } 20459 } catch (Exception e) { 20460 } 20461 } 20462 20463 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 20464 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING 20465 | Intent.FLAG_RECEIVER_FOREGROUND 20466 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 20467 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 20468 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, 20469 UserHandle.USER_ALL); 20470 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) { 20471 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 20472 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND 20473 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND 20474 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 20475 if (initLocale || !mProcessesReady) { 20476 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 20477 } 20478 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 20479 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, 20480 UserHandle.USER_ALL); 20481 } 20482 20483 // Override configuration of the default display duplicates global config, so we need to 20484 // update it also. This will also notify WindowManager about changes. 20485 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume, 20486 DEFAULT_DISPLAY); 20487 20488 return changes; 20489 } 20490 20491 @Override 20492 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) { 20493 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()"); 20494 20495 synchronized (this) { 20496 // Check if display is initialized in AM. 20497 if (!mStackSupervisor.isDisplayAdded(displayId)) { 20498 // Call might come when display is not yet added or has already been removed. 20499 if (DEBUG_CONFIGURATION) { 20500 Slog.w(TAG, "Trying to update display configuration for non-existing displayId=" 20501 + displayId); 20502 } 20503 return false; 20504 } 20505 20506 if (values == null && mWindowManager != null) { 20507 // sentinel: fetch the current configuration from the window manager 20508 values = mWindowManager.computeNewConfiguration(displayId); 20509 } 20510 20511 if (mWindowManager != null) { 20512 // Update OOM levels based on display size. 20513 mProcessList.applyDisplaySize(mWindowManager); 20514 } 20515 20516 final long origId = Binder.clearCallingIdentity(); 20517 try { 20518 if (values != null) { 20519 Settings.System.clearConfiguration(values); 20520 } 20521 updateDisplayOverrideConfigurationLocked(values, null /* starting */, 20522 false /* deferResume */, displayId, mTmpUpdateConfigurationResult); 20523 return mTmpUpdateConfigurationResult.changes != 0; 20524 } finally { 20525 Binder.restoreCallingIdentity(origId); 20526 } 20527 } 20528 } 20529 20530 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting, 20531 boolean deferResume, int displayId) { 20532 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */, 20533 displayId, null /* result */); 20534 } 20535 20536 /** 20537 * Updates override configuration specific for the selected display. If no config is provided, 20538 * new one will be computed in WM based on current display info. 20539 */ 20540 private boolean updateDisplayOverrideConfigurationLocked(Configuration values, 20541 ActivityRecord starting, boolean deferResume, int displayId, 20542 UpdateConfigurationResult result) { 20543 int changes = 0; 20544 boolean kept = true; 20545 20546 if (mWindowManager != null) { 20547 mWindowManager.deferSurfaceLayout(); 20548 } 20549 try { 20550 if (values != null) { 20551 if (displayId == DEFAULT_DISPLAY) { 20552 // Override configuration of the default display duplicates global config, so 20553 // we're calling global config update instead for default display. It will also 20554 // apply the correct override config. 20555 changes = updateGlobalConfiguration(values, false /* initLocale */, 20556 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume); 20557 } else { 20558 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId); 20559 } 20560 } 20561 20562 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes); 20563 } finally { 20564 if (mWindowManager != null) { 20565 mWindowManager.continueSurfaceLayout(); 20566 } 20567 } 20568 20569 if (result != null) { 20570 result.changes = changes; 20571 result.activityRelaunched = !kept; 20572 } 20573 return kept; 20574 } 20575 20576 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume, 20577 int displayId) { 20578 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId)); 20579 final int changes = mTempConfig.updateFrom(values); 20580 if (changes != 0) { 20581 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " 20582 + mTempConfig + " for displayId=" + displayId); 20583 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId); 20584 20585 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0; 20586 if (isDensityChange && displayId == DEFAULT_DISPLAY) { 20587 // Reset the unsupported display size dialog. 20588 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG); 20589 20590 killAllBackgroundProcessesExcept(N, 20591 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); 20592 } 20593 } 20594 20595 // Update the configuration with WM first and check if any of the stacks need to be resized 20596 // due to the configuration change. If so, resize the stacks now and do any relaunches if 20597 // necessary. This way we don't need to relaunch again afterwards in 20598 // ensureActivityConfigurationLocked(). 20599 if (mWindowManager != null) { 20600 final int[] resizedStacks = 20601 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId); 20602 if (resizedStacks != null) { 20603 for (int stackId : resizedStacks) { 20604 resizeStackWithBoundsFromWindowManager(stackId, deferResume); 20605 } 20606 } 20607 } 20608 20609 return changes; 20610 } 20611 20612 /** Applies latest configuration and/or visibility updates if needed. */ 20613 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) { 20614 boolean kept = true; 20615 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 20616 // mainStack is null during startup. 20617 if (mainStack != null) { 20618 if (changes != 0 && starting == null) { 20619 // If the configuration changed, and the caller is not already 20620 // in the process of starting an activity, then find the top 20621 // activity to check if its configuration needs to change. 20622 starting = mainStack.topRunningActivityLocked(); 20623 } 20624 20625 if (starting != null) { 20626 kept = starting.ensureActivityConfigurationLocked(changes, 20627 false /* preserveWindow */); 20628 // And we need to make sure at this point that all other activities 20629 // are made visible with the correct configuration. 20630 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes, 20631 !PRESERVE_WINDOWS); 20632 } 20633 } 20634 20635 return kept; 20636 } 20637 20638 /** Helper method that requests bounds from WM and applies them to stack. */ 20639 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) { 20640 final Rect newStackBounds = new Rect(); 20641 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds); 20642 mStackSupervisor.resizeStackLocked( 20643 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */, 20644 null /* tempTaskBounds */, null /* tempTaskInsetBounds */, 20645 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume); 20646 } 20647 20648 /** 20649 * Decide based on the configuration whether we should show the ANR, 20650 * crash, etc dialogs. The idea is that if there is no affordance to 20651 * press the on-screen buttons, or the user experience would be more 20652 * greatly impacted than the crash itself, we shouldn't show the dialog. 20653 * 20654 * A thought: SystemUI might also want to get told about this, the Power 20655 * dialog / global actions also might want different behaviors. 20656 */ 20657 private static boolean shouldShowDialogs(Configuration config) { 20658 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS 20659 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH 20660 && config.navigation == Configuration.NAVIGATION_NONAV); 20661 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK; 20662 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR 20663 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER) 20664 && modeType != Configuration.UI_MODE_TYPE_TELEVISION 20665 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET); 20666 return inputMethodExists && uiModeSupportsDialogs; 20667 } 20668 20669 @Override 20670 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 20671 synchronized (this) { 20672 ActivityRecord srec = ActivityRecord.forTokenLocked(token); 20673 if (srec != null) { 20674 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity); 20675 } 20676 } 20677 return false; 20678 } 20679 20680 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 20681 Intent resultData) { 20682 20683 synchronized (this) { 20684 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 20685 if (r != null) { 20686 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData); 20687 } 20688 return false; 20689 } 20690 } 20691 20692 public int getLaunchedFromUid(IBinder activityToken) { 20693 ActivityRecord srec; 20694 synchronized (this) { 20695 srec = ActivityRecord.forTokenLocked(activityToken); 20696 } 20697 if (srec == null) { 20698 return -1; 20699 } 20700 return srec.launchedFromUid; 20701 } 20702 20703 public String getLaunchedFromPackage(IBinder activityToken) { 20704 ActivityRecord srec; 20705 synchronized (this) { 20706 srec = ActivityRecord.forTokenLocked(activityToken); 20707 } 20708 if (srec == null) { 20709 return null; 20710 } 20711 return srec.launchedFromPackage; 20712 } 20713 20714 // ========================================================= 20715 // LIFETIME MANAGEMENT 20716 // ========================================================= 20717 20718 // Returns whether the app is receiving broadcast. 20719 // If receiving, fetch all broadcast queues which the app is 20720 // the current [or imminent] receiver on. 20721 private boolean isReceivingBroadcastLocked(ProcessRecord app, 20722 ArraySet<BroadcastQueue> receivingQueues) { 20723 if (!app.curReceivers.isEmpty()) { 20724 for (BroadcastRecord r : app.curReceivers) { 20725 receivingQueues.add(r.queue); 20726 } 20727 return true; 20728 } 20729 20730 // It's not the current receiver, but it might be starting up to become one 20731 for (BroadcastQueue queue : mBroadcastQueues) { 20732 final BroadcastRecord r = queue.mPendingBroadcast; 20733 if (r != null && r.curApp == app) { 20734 // found it; report which queue it's in 20735 receivingQueues.add(queue); 20736 } 20737 } 20738 20739 return !receivingQueues.isEmpty(); 20740 } 20741 20742 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState, 20743 int targetUid, ComponentName targetComponent, String targetProcess) { 20744 if (!mTrackingAssociations) { 20745 return null; 20746 } 20747 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 20748 = mAssociations.get(targetUid); 20749 if (components == null) { 20750 components = new ArrayMap<>(); 20751 mAssociations.put(targetUid, components); 20752 } 20753 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 20754 if (sourceUids == null) { 20755 sourceUids = new SparseArray<>(); 20756 components.put(targetComponent, sourceUids); 20757 } 20758 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 20759 if (sourceProcesses == null) { 20760 sourceProcesses = new ArrayMap<>(); 20761 sourceUids.put(sourceUid, sourceProcesses); 20762 } 20763 Association ass = sourceProcesses.get(sourceProcess); 20764 if (ass == null) { 20765 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, 20766 targetProcess); 20767 sourceProcesses.put(sourceProcess, ass); 20768 } 20769 ass.mCount++; 20770 ass.mNesting++; 20771 if (ass.mNesting == 1) { 20772 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis(); 20773 ass.mLastState = sourceState; 20774 } 20775 return ass; 20776 } 20777 20778 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 20779 ComponentName targetComponent) { 20780 if (!mTrackingAssociations) { 20781 return; 20782 } 20783 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 20784 = mAssociations.get(targetUid); 20785 if (components == null) { 20786 return; 20787 } 20788 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 20789 if (sourceUids == null) { 20790 return; 20791 } 20792 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 20793 if (sourceProcesses == null) { 20794 return; 20795 } 20796 Association ass = sourceProcesses.get(sourceProcess); 20797 if (ass == null || ass.mNesting <= 0) { 20798 return; 20799 } 20800 ass.mNesting--; 20801 if (ass.mNesting == 0) { 20802 long uptime = SystemClock.uptimeMillis(); 20803 ass.mTime += uptime - ass.mStartTime; 20804 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE] 20805 += uptime - ass.mLastStateUptime; 20806 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2; 20807 } 20808 } 20809 20810 private void noteUidProcessState(final int uid, final int state) { 20811 mBatteryStatsService.noteUidProcessState(uid, state); 20812 if (mTrackingAssociations) { 20813 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 20814 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 20815 = mAssociations.valueAt(i1); 20816 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 20817 SparseArray<ArrayMap<String, Association>> sourceUids 20818 = targetComponents.valueAt(i2); 20819 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid); 20820 if (sourceProcesses != null) { 20821 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 20822 Association ass = sourceProcesses.valueAt(i4); 20823 if (ass.mNesting >= 1) { 20824 // currently associated 20825 long uptime = SystemClock.uptimeMillis(); 20826 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE] 20827 += uptime - ass.mLastStateUptime; 20828 ass.mLastState = state; 20829 ass.mLastStateUptime = uptime; 20830 } 20831 } 20832 } 20833 } 20834 } 20835 } 20836 } 20837 20838 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 20839 boolean doingAll, long now) { 20840 if (mAdjSeq == app.adjSeq) { 20841 // This adjustment has already been computed. 20842 return app.curRawAdj; 20843 } 20844 20845 if (app.thread == null) { 20846 app.adjSeq = mAdjSeq; 20847 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 20848 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 20849 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 20850 } 20851 20852 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 20853 app.adjSource = null; 20854 app.adjTarget = null; 20855 app.empty = false; 20856 app.cached = false; 20857 20858 final int activitiesSize = app.activities.size(); 20859 20860 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 20861 // The max adjustment doesn't allow this app to be anything 20862 // below foreground, so it is not worth doing work for it. 20863 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app); 20864 app.adjType = "fixed"; 20865 app.adjSeq = mAdjSeq; 20866 app.curRawAdj = app.maxAdj; 20867 app.foregroundActivities = false; 20868 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20869 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 20870 // System processes can do UI, and when they do we want to have 20871 // them trim their memory after the user leaves the UI. To 20872 // facilitate this, here we need to determine whether or not it 20873 // is currently showing UI. 20874 app.systemNoUi = true; 20875 if (app == TOP_APP) { 20876 app.systemNoUi = false; 20877 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP; 20878 app.adjType = "pers-top-activity"; 20879 } else if (app.hasTopUi) { 20880 app.systemNoUi = false; 20881 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP; 20882 app.adjType = "pers-top-ui"; 20883 } else if (activitiesSize > 0) { 20884 for (int j = 0; j < activitiesSize; j++) { 20885 final ActivityRecord r = app.activities.get(j); 20886 if (r.visible) { 20887 app.systemNoUi = false; 20888 } 20889 } 20890 } 20891 if (!app.systemNoUi) { 20892 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 20893 } 20894 return (app.curAdj=app.maxAdj); 20895 } 20896 20897 app.systemNoUi = false; 20898 20899 final int PROCESS_STATE_CUR_TOP = mTopProcessState; 20900 20901 // Determine the importance of the process, starting with most 20902 // important to least, and assign an appropriate OOM adjustment. 20903 int adj; 20904 int schedGroup; 20905 int procState; 20906 boolean foregroundActivities = false; 20907 mTmpBroadcastQueue.clear(); 20908 if (app == TOP_APP) { 20909 // The last app on the list is the foreground app. 20910 adj = ProcessList.FOREGROUND_APP_ADJ; 20911 schedGroup = ProcessList.SCHED_GROUP_TOP_APP; 20912 app.adjType = "top-activity"; 20913 foregroundActivities = true; 20914 procState = PROCESS_STATE_CUR_TOP; 20915 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app); 20916 } else if (app.instr != null) { 20917 // Don't want to kill running instrumentation. 20918 adj = ProcessList.FOREGROUND_APP_ADJ; 20919 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20920 app.adjType = "instrumentation"; 20921 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 20922 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app); 20923 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) { 20924 // An app that is currently receiving a broadcast also 20925 // counts as being in the foreground for OOM killer purposes. 20926 // It's placed in a sched group based on the nature of the 20927 // broadcast as reflected by which queue it's active in. 20928 adj = ProcessList.FOREGROUND_APP_ADJ; 20929 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue)) 20930 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; 20931 app.adjType = "broadcast"; 20932 procState = ActivityManager.PROCESS_STATE_RECEIVER; 20933 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app); 20934 } else if (app.executingServices.size() > 0) { 20935 // An app that is currently executing a service callback also 20936 // counts as being in the foreground. 20937 adj = ProcessList.FOREGROUND_APP_ADJ; 20938 schedGroup = app.execServicesFg ? 20939 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; 20940 app.adjType = "exec-service"; 20941 procState = ActivityManager.PROCESS_STATE_SERVICE; 20942 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app); 20943 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 20944 } else { 20945 // As far as we know the process is empty. We may change our mind later. 20946 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 20947 // At this point we don't actually know the adjustment. Use the cached adj 20948 // value that the caller wants us to. 20949 adj = cachedAdj; 20950 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 20951 app.cached = true; 20952 app.empty = true; 20953 app.adjType = "cch-empty"; 20954 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app); 20955 } 20956 20957 // Examine all activities if not already foreground. 20958 if (!foregroundActivities && activitiesSize > 0) { 20959 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX; 20960 for (int j = 0; j < activitiesSize; j++) { 20961 final ActivityRecord r = app.activities.get(j); 20962 if (r.app != app) { 20963 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app 20964 + " instead of expected " + app); 20965 if (r.app == null || (r.app.uid == app.uid)) { 20966 // Only fix things up when they look sane 20967 r.app = app; 20968 } else { 20969 continue; 20970 } 20971 } 20972 if (r.visible) { 20973 // App has a visible activity; only upgrade adjustment. 20974 if (adj > ProcessList.VISIBLE_APP_ADJ) { 20975 adj = ProcessList.VISIBLE_APP_ADJ; 20976 app.adjType = "vis-activity"; 20977 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app); 20978 } 20979 if (procState > PROCESS_STATE_CUR_TOP) { 20980 procState = PROCESS_STATE_CUR_TOP; 20981 app.adjType = "vis-activity"; 20982 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app); 20983 } 20984 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20985 app.cached = false; 20986 app.empty = false; 20987 foregroundActivities = true; 20988 final TaskRecord task = r.getTask(); 20989 if (task != null && minLayer > 0) { 20990 final int layer = task.mLayerRank; 20991 if (layer >= 0 && minLayer > layer) { 20992 minLayer = layer; 20993 } 20994 } 20995 break; 20996 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 20997 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 20998 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 20999 app.adjType = "pause-activity"; 21000 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app); 21001 } 21002 if (procState > PROCESS_STATE_CUR_TOP) { 21003 procState = PROCESS_STATE_CUR_TOP; 21004 app.adjType = "pause-activity"; 21005 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app); 21006 } 21007 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21008 app.cached = false; 21009 app.empty = false; 21010 foregroundActivities = true; 21011 } else if (r.state == ActivityState.STOPPING) { 21012 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 21013 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 21014 app.adjType = "stop-activity"; 21015 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app); 21016 } 21017 // For the process state, we will at this point consider the 21018 // process to be cached. It will be cached either as an activity 21019 // or empty depending on whether the activity is finishing. We do 21020 // this so that we can treat the process as cached for purposes of 21021 // memory trimming (determing current memory level, trim command to 21022 // send to process) since there can be an arbitrary number of stopping 21023 // processes and they should soon all go into the cached state. 21024 if (!r.finishing) { 21025 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 21026 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 21027 app.adjType = "stop-activity"; 21028 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app); 21029 } 21030 } 21031 app.cached = false; 21032 app.empty = false; 21033 foregroundActivities = true; 21034 } else { 21035 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 21036 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 21037 app.adjType = "cch-act"; 21038 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app); 21039 } 21040 } 21041 } 21042 if (adj == ProcessList.VISIBLE_APP_ADJ) { 21043 adj += minLayer; 21044 } 21045 } 21046 21047 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ 21048 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { 21049 if (app.foregroundServices) { 21050 // The user is aware of this app, so make it visible. 21051 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 21052 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 21053 app.cached = false; 21054 app.adjType = "fg-service"; 21055 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21056 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app); 21057 } else if (app.hasOverlayUi) { 21058 // The process is display an overlay UI. 21059 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 21060 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 21061 app.cached = false; 21062 app.adjType = "has-overlay-ui"; 21063 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21064 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app); 21065 } 21066 } 21067 21068 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ 21069 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { 21070 if (app.forcingToImportant != null) { 21071 // This is currently used for toasts... they are not interactive, and 21072 // we don't want them to cause the app to become fully foreground (and 21073 // thus out of background check), so we yes the best background level we can. 21074 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 21075 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; 21076 app.cached = false; 21077 app.adjType = "force-imp"; 21078 app.adjSource = app.forcingToImportant; 21079 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21080 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app); 21081 } 21082 } 21083 21084 if (app == mHeavyWeightProcess) { 21085 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 21086 // We don't want to kill the current heavy-weight process. 21087 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 21088 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 21089 app.cached = false; 21090 app.adjType = "heavy"; 21091 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app); 21092 } 21093 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 21094 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 21095 app.adjType = "heavy"; 21096 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app); 21097 } 21098 } 21099 21100 if (app == mHomeProcess) { 21101 if (adj > ProcessList.HOME_APP_ADJ) { 21102 // This process is hosting what we currently consider to be the 21103 // home app, so we don't want to let it go into the background. 21104 adj = ProcessList.HOME_APP_ADJ; 21105 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 21106 app.cached = false; 21107 app.adjType = "home"; 21108 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app); 21109 } 21110 if (procState > ActivityManager.PROCESS_STATE_HOME) { 21111 procState = ActivityManager.PROCESS_STATE_HOME; 21112 app.adjType = "home"; 21113 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app); 21114 } 21115 } 21116 21117 if (app == mPreviousProcess && app.activities.size() > 0) { 21118 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 21119 // This was the previous process that showed UI to the user. 21120 // We want to try to keep it around more aggressively, to give 21121 // a good experience around switching between two apps. 21122 adj = ProcessList.PREVIOUS_APP_ADJ; 21123 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 21124 app.cached = false; 21125 app.adjType = "previous"; 21126 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app); 21127 } 21128 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 21129 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 21130 app.adjType = "previous"; 21131 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app); 21132 } 21133 } 21134 21135 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 21136 + " reason=" + app.adjType); 21137 21138 // By default, we use the computed adjustment. It may be changed if 21139 // there are applications dependent on our services or providers, but 21140 // this gives us a baseline and makes sure we don't get into an 21141 // infinite recursion. 21142 app.adjSeq = mAdjSeq; 21143 app.curRawAdj = adj; 21144 app.hasStartedServices = false; 21145 21146 if (mBackupTarget != null && app == mBackupTarget.app) { 21147 // If possible we want to avoid killing apps while they're being backed up 21148 if (adj > ProcessList.BACKUP_APP_ADJ) { 21149 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app); 21150 adj = ProcessList.BACKUP_APP_ADJ; 21151 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { 21152 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; 21153 } 21154 app.adjType = "backup"; 21155 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app); 21156 app.cached = false; 21157 } 21158 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 21159 procState = ActivityManager.PROCESS_STATE_BACKUP; 21160 app.adjType = "backup"; 21161 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app); 21162 } 21163 } 21164 21165 boolean mayBeTop = false; 21166 String mayBeTopType = null; 21167 Object mayBeTopSource = null; 21168 Object mayBeTopTarget = null; 21169 21170 for (int is = app.services.size()-1; 21171 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 21172 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 21173 || procState > ActivityManager.PROCESS_STATE_TOP); 21174 is--) { 21175 ServiceRecord s = app.services.valueAt(is); 21176 if (s.startRequested) { 21177 app.hasStartedServices = true; 21178 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 21179 procState = ActivityManager.PROCESS_STATE_SERVICE; 21180 app.adjType = "started-services"; 21181 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app); 21182 } 21183 if (app.hasShownUi && app != mHomeProcess) { 21184 // If this process has shown some UI, let it immediately 21185 // go to the LRU list because it may be pretty heavy with 21186 // UI stuff. We'll tag it with a label just to help 21187 // debug and understand what is going on. 21188 if (adj > ProcessList.SERVICE_ADJ) { 21189 app.adjType = "cch-started-ui-services"; 21190 } 21191 } else { 21192 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) { 21193 // This service has seen some activity within 21194 // recent memory, so we will keep its process ahead 21195 // of the background processes. 21196 if (adj > ProcessList.SERVICE_ADJ) { 21197 adj = ProcessList.SERVICE_ADJ; 21198 app.adjType = "started-services"; 21199 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app); 21200 app.cached = false; 21201 } 21202 } 21203 // If we have let the service slide into the background 21204 // state, still have some text describing what it is doing 21205 // even though the service no longer has an impact. 21206 if (adj > ProcessList.SERVICE_ADJ) { 21207 app.adjType = "cch-started-services"; 21208 } 21209 } 21210 } 21211 21212 for (int conni = s.connections.size()-1; 21213 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 21214 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 21215 || procState > ActivityManager.PROCESS_STATE_TOP); 21216 conni--) { 21217 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 21218 for (int i = 0; 21219 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 21220 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 21221 || procState > ActivityManager.PROCESS_STATE_TOP); 21222 i++) { 21223 // XXX should compute this based on the max of 21224 // all connected clients. 21225 ConnectionRecord cr = clist.get(i); 21226 if (cr.binding.client == app) { 21227 // Binding to ourself is not interesting. 21228 continue; 21229 } 21230 21231 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 21232 ProcessRecord client = cr.binding.client; 21233 int clientAdj = computeOomAdjLocked(client, cachedAdj, 21234 TOP_APP, doingAll, now); 21235 int clientProcState = client.curProcState; 21236 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 21237 // If the other app is cached for any reason, for purposes here 21238 // we are going to consider it empty. The specific cached state 21239 // doesn't propagate except under certain conditions. 21240 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 21241 } 21242 String adjType = null; 21243 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 21244 // Not doing bind OOM management, so treat 21245 // this guy more like a started service. 21246 if (app.hasShownUi && app != mHomeProcess) { 21247 // If this process has shown some UI, let it immediately 21248 // go to the LRU list because it may be pretty heavy with 21249 // UI stuff. We'll tag it with a label just to help 21250 // debug and understand what is going on. 21251 if (adj > clientAdj) { 21252 adjType = "cch-bound-ui-services"; 21253 } 21254 app.cached = false; 21255 clientAdj = adj; 21256 clientProcState = procState; 21257 } else { 21258 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) { 21259 // This service has not seen activity within 21260 // recent memory, so allow it to drop to the 21261 // LRU list if there is no other reason to keep 21262 // it around. We'll also tag it with a label just 21263 // to help debug and undertand what is going on. 21264 if (adj > clientAdj) { 21265 adjType = "cch-bound-services"; 21266 } 21267 clientAdj = adj; 21268 } 21269 } 21270 } 21271 if (adj > clientAdj) { 21272 // If this process has recently shown UI, and 21273 // the process that is binding to it is less 21274 // important than being visible, then we don't 21275 // care about the binding as much as we care 21276 // about letting this process get into the LRU 21277 // list to be killed and restarted if needed for 21278 // memory. 21279 if (app.hasShownUi && app != mHomeProcess 21280 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 21281 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 21282 adjType = "cch-bound-ui-services"; 21283 } 21284 } else { 21285 int newAdj; 21286 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 21287 |Context.BIND_IMPORTANT)) != 0) { 21288 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 21289 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 21290 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 21291 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 21292 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 21293 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ; 21294 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 21295 newAdj = clientAdj; 21296 } else { 21297 if (adj > ProcessList.VISIBLE_APP_ADJ) { 21298 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ); 21299 } else { 21300 newAdj = adj; 21301 } 21302 } 21303 if (!client.cached) { 21304 app.cached = false; 21305 } 21306 if (adj > newAdj) { 21307 adj = newAdj; 21308 adjType = "service"; 21309 } 21310 } 21311 } 21312 if ((cr.flags & (Context.BIND_NOT_FOREGROUND 21313 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) { 21314 // This will treat important bound services identically to 21315 // the top app, which may behave differently than generic 21316 // foreground work. 21317 if (client.curSchedGroup > schedGroup) { 21318 if ((cr.flags&Context.BIND_IMPORTANT) != 0) { 21319 schedGroup = client.curSchedGroup; 21320 } else { 21321 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21322 } 21323 } 21324 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 21325 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 21326 // Special handling of clients who are in the top state. 21327 // We *may* want to consider this process to be in the 21328 // top state as well, but only if there is not another 21329 // reason for it to be running. Being on the top is a 21330 // special state, meaning you are specifically running 21331 // for the current top app. If the process is already 21332 // running in the background for some other reason, it 21333 // is more important to continue considering it to be 21334 // in the background state. 21335 mayBeTop = true; 21336 mayBeTopType = "service"; 21337 mayBeTopSource = cr.binding.client; 21338 mayBeTopTarget = s.name; 21339 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 21340 } else { 21341 // Special handling for above-top states (persistent 21342 // processes). These should not bring the current process 21343 // into the top state, since they are not on top. Instead 21344 // give them the best state after that. 21345 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) { 21346 clientProcState = 21347 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 21348 } else if (mWakefulness 21349 == PowerManagerInternal.WAKEFULNESS_AWAKE && 21350 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) 21351 != 0) { 21352 clientProcState = 21353 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 21354 } else { 21355 clientProcState = 21356 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 21357 } 21358 } 21359 } 21360 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) { 21361 if (clientProcState < 21362 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { 21363 clientProcState = 21364 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; 21365 } 21366 } else { 21367 if (clientProcState < 21368 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 21369 clientProcState = 21370 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 21371 } 21372 } 21373 if (procState > clientProcState) { 21374 procState = clientProcState; 21375 if (adjType == null) { 21376 adjType = "service"; 21377 } 21378 } 21379 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 21380 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 21381 app.pendingUiClean = true; 21382 } 21383 if (adjType != null) { 21384 app.adjType = adjType; 21385 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 21386 .REASON_SERVICE_IN_USE; 21387 app.adjSource = cr.binding.client; 21388 app.adjSourceProcState = clientProcState; 21389 app.adjTarget = s.name; 21390 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType 21391 + ": " + app + ", due to " + cr.binding.client 21392 + " adj=" + adj + " procState=" + procState); 21393 } 21394 } 21395 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 21396 app.treatLikeActivity = true; 21397 } 21398 final ActivityRecord a = cr.activity; 21399 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 21400 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 21401 (a.visible || a.state == ActivityState.RESUMED || 21402 a.state == ActivityState.PAUSING)) { 21403 adj = ProcessList.FOREGROUND_APP_ADJ; 21404 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 21405 if ((cr.flags&Context.BIND_IMPORTANT) != 0) { 21406 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND; 21407 } else { 21408 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21409 } 21410 } 21411 app.cached = false; 21412 app.adjType = "service"; 21413 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 21414 .REASON_SERVICE_IN_USE; 21415 app.adjSource = a; 21416 app.adjSourceProcState = procState; 21417 app.adjTarget = s.name; 21418 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: " 21419 + app); 21420 } 21421 } 21422 } 21423 } 21424 } 21425 21426 for (int provi = app.pubProviders.size()-1; 21427 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 21428 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 21429 || procState > ActivityManager.PROCESS_STATE_TOP); 21430 provi--) { 21431 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 21432 for (int i = cpr.connections.size()-1; 21433 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 21434 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 21435 || procState > ActivityManager.PROCESS_STATE_TOP); 21436 i--) { 21437 ContentProviderConnection conn = cpr.connections.get(i); 21438 ProcessRecord client = conn.client; 21439 if (client == app) { 21440 // Being our own client is not interesting. 21441 continue; 21442 } 21443 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 21444 int clientProcState = client.curProcState; 21445 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 21446 // If the other app is cached for any reason, for purposes here 21447 // we are going to consider it empty. 21448 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 21449 } 21450 String adjType = null; 21451 if (adj > clientAdj) { 21452 if (app.hasShownUi && app != mHomeProcess 21453 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 21454 adjType = "cch-ui-provider"; 21455 } else { 21456 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 21457 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 21458 adjType = "provider"; 21459 } 21460 app.cached &= client.cached; 21461 } 21462 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 21463 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 21464 // Special handling of clients who are in the top state. 21465 // We *may* want to consider this process to be in the 21466 // top state as well, but only if there is not another 21467 // reason for it to be running. Being on the top is a 21468 // special state, meaning you are specifically running 21469 // for the current top app. If the process is already 21470 // running in the background for some other reason, it 21471 // is more important to continue considering it to be 21472 // in the background state. 21473 mayBeTop = true; 21474 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 21475 mayBeTopType = adjType = "provider-top"; 21476 mayBeTopSource = client; 21477 mayBeTopTarget = cpr.name; 21478 } else { 21479 // Special handling for above-top states (persistent 21480 // processes). These should not bring the current process 21481 // into the top state, since they are not on top. Instead 21482 // give them the best state after that. 21483 clientProcState = 21484 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 21485 if (adjType == null) { 21486 adjType = "provider"; 21487 } 21488 } 21489 } 21490 if (procState > clientProcState) { 21491 procState = clientProcState; 21492 } 21493 if (client.curSchedGroup > schedGroup) { 21494 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21495 } 21496 if (adjType != null) { 21497 app.adjType = adjType; 21498 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 21499 .REASON_PROVIDER_IN_USE; 21500 app.adjSource = client; 21501 app.adjSourceProcState = clientProcState; 21502 app.adjTarget = cpr.name; 21503 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType 21504 + ": " + app + ", due to " + client 21505 + " adj=" + adj + " procState=" + procState); 21506 } 21507 } 21508 // If the provider has external (non-framework) process 21509 // dependencies, ensure that its adjustment is at least 21510 // FOREGROUND_APP_ADJ. 21511 if (cpr.hasExternalProcessHandles()) { 21512 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 21513 adj = ProcessList.FOREGROUND_APP_ADJ; 21514 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21515 app.cached = false; 21516 app.adjType = "ext-provider"; 21517 app.adjTarget = cpr.name; 21518 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app); 21519 } 21520 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 21521 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 21522 } 21523 } 21524 } 21525 21526 if (app.lastProviderTime > 0 && 21527 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) { 21528 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 21529 adj = ProcessList.PREVIOUS_APP_ADJ; 21530 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 21531 app.cached = false; 21532 app.adjType = "recent-provider"; 21533 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app); 21534 } 21535 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 21536 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 21537 app.adjType = "recent-provider"; 21538 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app); 21539 } 21540 } 21541 21542 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 21543 // A client of one of our services or providers is in the top state. We 21544 // *may* want to be in the top state, but not if we are already running in 21545 // the background for some other reason. For the decision here, we are going 21546 // to pick out a few specific states that we want to remain in when a client 21547 // is top (states that tend to be longer-term) and otherwise allow it to go 21548 // to the top state. 21549 switch (procState) { 21550 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE: 21551 // Something else is keeping it at this level, just leave it. 21552 break; 21553 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 21554 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 21555 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND: 21556 case ActivityManager.PROCESS_STATE_SERVICE: 21557 // These all are longer-term states, so pull them up to the top 21558 // of the background states, but not all the way to the top state. 21559 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 21560 app.adjType = mayBeTopType; 21561 app.adjSource = mayBeTopSource; 21562 app.adjTarget = mayBeTopTarget; 21563 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType 21564 + ": " + app + ", due to " + mayBeTopSource 21565 + " adj=" + adj + " procState=" + procState); 21566 break; 21567 default: 21568 // Otherwise, top is a better choice, so take it. 21569 procState = ActivityManager.PROCESS_STATE_TOP; 21570 app.adjType = mayBeTopType; 21571 app.adjSource = mayBeTopSource; 21572 app.adjTarget = mayBeTopTarget; 21573 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType 21574 + ": " + app + ", due to " + mayBeTopSource 21575 + " adj=" + adj + " procState=" + procState); 21576 break; 21577 } 21578 } 21579 21580 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 21581 if (app.hasClientActivities) { 21582 // This is a cached process, but with client activities. Mark it so. 21583 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 21584 app.adjType = "cch-client-act"; 21585 } else if (app.treatLikeActivity) { 21586 // This is a cached process, but somebody wants us to treat it like it has 21587 // an activity, okay! 21588 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 21589 app.adjType = "cch-as-act"; 21590 } 21591 } 21592 21593 if (adj == ProcessList.SERVICE_ADJ) { 21594 if (doingAll) { 21595 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 21596 mNewNumServiceProcs++; 21597 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 21598 if (!app.serviceb) { 21599 // This service isn't far enough down on the LRU list to 21600 // normally be a B service, but if we are low on RAM and it 21601 // is large we want to force it down since we would prefer to 21602 // keep launcher over it. 21603 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 21604 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 21605 app.serviceHighRam = true; 21606 app.serviceb = true; 21607 //Slog.i(TAG, "ADJ " + app + " high ram!"); 21608 } else { 21609 mNewNumAServiceProcs++; 21610 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 21611 } 21612 } else { 21613 app.serviceHighRam = false; 21614 } 21615 } 21616 if (app.serviceb) { 21617 adj = ProcessList.SERVICE_B_ADJ; 21618 } 21619 } 21620 21621 app.curRawAdj = adj; 21622 21623 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 21624 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 21625 if (adj > app.maxAdj) { 21626 adj = app.maxAdj; 21627 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 21628 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 21629 } 21630 } 21631 21632 // Do final modification to adj. Everything we do between here and applying 21633 // the final setAdj must be done in this function, because we will also use 21634 // it when computing the final cached adj later. Note that we don't need to 21635 // worry about this for max adj above, since max adj will always be used to 21636 // keep it out of the cached vaues. 21637 app.curAdj = app.modifyRawOomAdj(adj); 21638 app.curSchedGroup = schedGroup; 21639 app.curProcState = procState; 21640 app.foregroundActivities = foregroundActivities; 21641 21642 return app.curRawAdj; 21643 } 21644 21645 /** 21646 * Record new PSS sample for a process. 21647 */ 21648 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss, 21649 long now) { 21650 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024, 21651 swapPss * 1024); 21652 proc.lastPssTime = now; 21653 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 21654 if (DEBUG_PSS) Slog.d(TAG_PSS, 21655 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss 21656 + " state=" + ProcessList.makeProcStateString(procState)); 21657 if (proc.initialIdlePss == 0) { 21658 proc.initialIdlePss = pss; 21659 } 21660 proc.lastPss = pss; 21661 proc.lastSwapPss = swapPss; 21662 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 21663 proc.lastCachedPss = pss; 21664 proc.lastCachedSwapPss = swapPss; 21665 } 21666 21667 final SparseArray<Pair<Long, String>> watchUids 21668 = mMemWatchProcesses.getMap().get(proc.processName); 21669 Long check = null; 21670 if (watchUids != null) { 21671 Pair<Long, String> val = watchUids.get(proc.uid); 21672 if (val == null) { 21673 val = watchUids.get(0); 21674 } 21675 if (val != null) { 21676 check = val.first; 21677 } 21678 } 21679 if (check != null) { 21680 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) { 21681 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 21682 if (!isDebuggable) { 21683 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 21684 isDebuggable = true; 21685 } 21686 } 21687 if (isDebuggable) { 21688 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting"); 21689 final ProcessRecord myProc = proc; 21690 final File heapdumpFile = DumpHeapProvider.getJavaFile(); 21691 mMemWatchDumpProcName = proc.processName; 21692 mMemWatchDumpFile = heapdumpFile.toString(); 21693 mMemWatchDumpPid = proc.pid; 21694 mMemWatchDumpUid = proc.uid; 21695 BackgroundThread.getHandler().post(new Runnable() { 21696 @Override 21697 public void run() { 21698 revokeUriPermission(ActivityThread.currentActivityThread() 21699 .getApplicationThread(), 21700 null, DumpHeapActivity.JAVA_URI, 21701 Intent.FLAG_GRANT_READ_URI_PERMISSION 21702 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 21703 UserHandle.myUserId()); 21704 ParcelFileDescriptor fd = null; 21705 try { 21706 heapdumpFile.delete(); 21707 fd = ParcelFileDescriptor.open(heapdumpFile, 21708 ParcelFileDescriptor.MODE_CREATE | 21709 ParcelFileDescriptor.MODE_TRUNCATE | 21710 ParcelFileDescriptor.MODE_WRITE_ONLY | 21711 ParcelFileDescriptor.MODE_APPEND); 21712 IApplicationThread thread = myProc.thread; 21713 if (thread != null) { 21714 try { 21715 if (DEBUG_PSS) Slog.d(TAG_PSS, 21716 "Requesting dump heap from " 21717 + myProc + " to " + heapdumpFile); 21718 thread.dumpHeap(/* managed= */ true, 21719 /* mallocInfo= */ false, /* runGc= */ false, 21720 heapdumpFile.toString(), fd); 21721 } catch (RemoteException e) { 21722 } 21723 } 21724 } catch (FileNotFoundException e) { 21725 e.printStackTrace(); 21726 } finally { 21727 if (fd != null) { 21728 try { 21729 fd.close(); 21730 } catch (IOException e) { 21731 } 21732 } 21733 } 21734 } 21735 }); 21736 } else { 21737 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check 21738 + ", but debugging not enabled"); 21739 } 21740 } 21741 } 21742 } 21743 21744 /** 21745 * Schedule PSS collection of a process. 21746 */ 21747 void requestPssLocked(ProcessRecord proc, int procState) { 21748 if (mPendingPssProcesses.contains(proc)) { 21749 return; 21750 } 21751 if (mPendingPssProcesses.size() == 0) { 21752 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 21753 } 21754 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc); 21755 proc.pssProcState = procState; 21756 mPendingPssProcesses.add(proc); 21757 } 21758 21759 /** 21760 * Schedule PSS collection of all processes. 21761 */ 21762 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 21763 if (!always) { 21764 if (now < (mLastFullPssTime + 21765 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL 21766 : mConstants.FULL_PSS_MIN_INTERVAL))) { 21767 return; 21768 } 21769 } 21770 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered); 21771 mLastFullPssTime = now; 21772 mFullPssPending = true; 21773 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 21774 mPendingPssProcesses.clear(); 21775 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 21776 ProcessRecord app = mLruProcesses.get(i); 21777 if (app.thread == null 21778 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) { 21779 continue; 21780 } 21781 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 21782 app.pssProcState = app.setProcState; 21783 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 21784 mTestPssMode, isSleepingLocked(), now); 21785 mPendingPssProcesses.add(app); 21786 } 21787 } 21788 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 21789 } 21790 21791 public void setTestPssMode(boolean enabled) { 21792 synchronized (this) { 21793 mTestPssMode = enabled; 21794 if (enabled) { 21795 // Whenever we enable the mode, we want to take a snapshot all of current 21796 // process mem use. 21797 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 21798 } 21799 } 21800 } 21801 21802 /** 21803 * Ask a given process to GC right now. 21804 */ 21805 final void performAppGcLocked(ProcessRecord app) { 21806 try { 21807 app.lastRequestedGc = SystemClock.uptimeMillis(); 21808 if (app.thread != null) { 21809 if (app.reportLowMemory) { 21810 app.reportLowMemory = false; 21811 app.thread.scheduleLowMemory(); 21812 } else { 21813 app.thread.processInBackground(); 21814 } 21815 } 21816 } catch (Exception e) { 21817 // whatever. 21818 } 21819 } 21820 21821 /** 21822 * Returns true if things are idle enough to perform GCs. 21823 */ 21824 private final boolean canGcNowLocked() { 21825 boolean processingBroadcasts = false; 21826 for (BroadcastQueue q : mBroadcastQueues) { 21827 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 21828 processingBroadcasts = true; 21829 } 21830 } 21831 return !processingBroadcasts 21832 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle()); 21833 } 21834 21835 /** 21836 * Perform GCs on all processes that are waiting for it, but only 21837 * if things are idle. 21838 */ 21839 final void performAppGcsLocked() { 21840 final int N = mProcessesToGc.size(); 21841 if (N <= 0) { 21842 return; 21843 } 21844 if (canGcNowLocked()) { 21845 while (mProcessesToGc.size() > 0) { 21846 ProcessRecord proc = mProcessesToGc.remove(0); 21847 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 21848 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL) 21849 <= SystemClock.uptimeMillis()) { 21850 // To avoid spamming the system, we will GC processes one 21851 // at a time, waiting a few seconds between each. 21852 performAppGcLocked(proc); 21853 scheduleAppGcsLocked(); 21854 return; 21855 } else { 21856 // It hasn't been long enough since we last GCed this 21857 // process... put it in the list to wait for its time. 21858 addProcessToGcListLocked(proc); 21859 break; 21860 } 21861 } 21862 } 21863 21864 scheduleAppGcsLocked(); 21865 } 21866 } 21867 21868 /** 21869 * If all looks good, perform GCs on all processes waiting for them. 21870 */ 21871 final void performAppGcsIfAppropriateLocked() { 21872 if (canGcNowLocked()) { 21873 performAppGcsLocked(); 21874 return; 21875 } 21876 // Still not idle, wait some more. 21877 scheduleAppGcsLocked(); 21878 } 21879 21880 /** 21881 * Schedule the execution of all pending app GCs. 21882 */ 21883 final void scheduleAppGcsLocked() { 21884 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 21885 21886 if (mProcessesToGc.size() > 0) { 21887 // Schedule a GC for the time to the next process. 21888 ProcessRecord proc = mProcessesToGc.get(0); 21889 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 21890 21891 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL; 21892 long now = SystemClock.uptimeMillis(); 21893 if (when < (now+mConstants.GC_TIMEOUT)) { 21894 when = now + mConstants.GC_TIMEOUT; 21895 } 21896 mHandler.sendMessageAtTime(msg, when); 21897 } 21898 } 21899 21900 /** 21901 * Add a process to the array of processes waiting to be GCed. Keeps the 21902 * list in sorted order by the last GC time. The process can't already be 21903 * on the list. 21904 */ 21905 final void addProcessToGcListLocked(ProcessRecord proc) { 21906 boolean added = false; 21907 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 21908 if (mProcessesToGc.get(i).lastRequestedGc < 21909 proc.lastRequestedGc) { 21910 added = true; 21911 mProcessesToGc.add(i+1, proc); 21912 break; 21913 } 21914 } 21915 if (!added) { 21916 mProcessesToGc.add(0, proc); 21917 } 21918 } 21919 21920 /** 21921 * Set up to ask a process to GC itself. This will either do it 21922 * immediately, or put it on the list of processes to gc the next 21923 * time things are idle. 21924 */ 21925 final void scheduleAppGcLocked(ProcessRecord app) { 21926 long now = SystemClock.uptimeMillis(); 21927 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) { 21928 return; 21929 } 21930 if (!mProcessesToGc.contains(app)) { 21931 addProcessToGcListLocked(app); 21932 scheduleAppGcsLocked(); 21933 } 21934 } 21935 21936 final void checkExcessivePowerUsageLocked() { 21937 updateCpuStatsNow(); 21938 21939 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 21940 boolean doCpuKills = true; 21941 if (mLastPowerCheckUptime == 0) { 21942 doCpuKills = false; 21943 } 21944 final long curUptime = SystemClock.uptimeMillis(); 21945 final long uptimeSince = curUptime - mLastPowerCheckUptime; 21946 mLastPowerCheckUptime = curUptime; 21947 int i = mLruProcesses.size(); 21948 while (i > 0) { 21949 i--; 21950 ProcessRecord app = mLruProcesses.get(i); 21951 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 21952 if (app.lastCpuTime <= 0) { 21953 continue; 21954 } 21955 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 21956 if (DEBUG_POWER) { 21957 StringBuilder sb = new StringBuilder(128); 21958 sb.append("CPU for "); 21959 app.toShortString(sb); 21960 sb.append(": over "); 21961 TimeUtils.formatDuration(uptimeSince, sb); 21962 sb.append(" used "); 21963 TimeUtils.formatDuration(cputimeUsed, sb); 21964 sb.append(" ("); 21965 sb.append((cputimeUsed*100)/uptimeSince); 21966 sb.append("%)"); 21967 Slog.i(TAG_POWER, sb.toString()); 21968 } 21969 // If the process has used too much CPU over the last duration, the 21970 // user probably doesn't want this, so kill! 21971 if (doCpuKills && uptimeSince > 0) { 21972 // What is the limit for this process? 21973 int cpuLimit; 21974 long checkDur = curUptime - app.whenUnimportant; 21975 if (checkDur <= mConstants.POWER_CHECK_INTERVAL) { 21976 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1; 21977 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2) 21978 || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) { 21979 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2; 21980 } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) { 21981 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3; 21982 } else { 21983 cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4; 21984 } 21985 if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) { 21986 synchronized (stats) { 21987 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 21988 uptimeSince, cputimeUsed); 21989 } 21990 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince 21991 + " dur=" + checkDur + " limit=" + cpuLimit, true); 21992 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 21993 } 21994 } 21995 app.lastCpuTime = app.curCpuTime; 21996 } 21997 } 21998 } 21999 22000 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now, 22001 long nowElapsed) { 22002 boolean success = true; 22003 22004 if (app.curRawAdj != app.setRawAdj) { 22005 app.setRawAdj = app.curRawAdj; 22006 } 22007 22008 int changes = 0; 22009 22010 if (app.curAdj != app.setAdj) { 22011 ProcessList.setOomAdj(app.pid, app.uid, app.curAdj); 22012 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) { 22013 String msg = "Set " + app.pid + " " + app.processName + " adj " 22014 + app.curAdj + ": " + app.adjType; 22015 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); 22016 } 22017 app.setAdj = app.curAdj; 22018 app.verifiedAdj = ProcessList.INVALID_ADJ; 22019 } 22020 22021 if (app.setSchedGroup != app.curSchedGroup) { 22022 int oldSchedGroup = app.setSchedGroup; 22023 app.setSchedGroup = app.curSchedGroup; 22024 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) { 22025 String msg = "Setting sched group of " + app.processName 22026 + " to " + app.curSchedGroup; 22027 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); 22028 } 22029 if (app.waitingToKill != null && app.curReceivers.isEmpty() 22030 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) { 22031 app.kill(app.waitingToKill, true); 22032 success = false; 22033 } else { 22034 int processGroup; 22035 switch (app.curSchedGroup) { 22036 case ProcessList.SCHED_GROUP_BACKGROUND: 22037 processGroup = THREAD_GROUP_BG_NONINTERACTIVE; 22038 break; 22039 case ProcessList.SCHED_GROUP_TOP_APP: 22040 case ProcessList.SCHED_GROUP_TOP_APP_BOUND: 22041 processGroup = THREAD_GROUP_TOP_APP; 22042 break; 22043 default: 22044 processGroup = THREAD_GROUP_DEFAULT; 22045 break; 22046 } 22047 long oldId = Binder.clearCallingIdentity(); 22048 try { 22049 setProcessGroup(app.pid, processGroup); 22050 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { 22051 // do nothing if we already switched to RT 22052 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) { 22053 mVrController.onTopProcChangedLocked(app); 22054 if (mUseFifoUiScheduling) { 22055 // Switch UI pipeline for app to SCHED_FIFO 22056 app.savedPriority = Process.getThreadPriority(app.pid); 22057 scheduleAsFifoPriority(app.pid, /* suppressLogs */true); 22058 if (app.renderThreadTid != 0) { 22059 scheduleAsFifoPriority(app.renderThreadTid, 22060 /* suppressLogs */true); 22061 if (DEBUG_OOM_ADJ) { 22062 Slog.d("UI_FIFO", "Set RenderThread (TID " + 22063 app.renderThreadTid + ") to FIFO"); 22064 } 22065 } else { 22066 if (DEBUG_OOM_ADJ) { 22067 Slog.d("UI_FIFO", "Not setting RenderThread TID"); 22068 } 22069 } 22070 } else { 22071 // Boost priority for top app UI and render threads 22072 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST); 22073 if (app.renderThreadTid != 0) { 22074 try { 22075 setThreadPriority(app.renderThreadTid, 22076 TOP_APP_PRIORITY_BOOST); 22077 } catch (IllegalArgumentException e) { 22078 // thread died, ignore 22079 } 22080 } 22081 } 22082 } 22083 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && 22084 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) { 22085 mVrController.onTopProcChangedLocked(app); 22086 if (mUseFifoUiScheduling) { 22087 try { 22088 // Reset UI pipeline to SCHED_OTHER 22089 setThreadScheduler(app.pid, SCHED_OTHER, 0); 22090 setThreadPriority(app.pid, app.savedPriority); 22091 if (app.renderThreadTid != 0) { 22092 setThreadScheduler(app.renderThreadTid, 22093 SCHED_OTHER, 0); 22094 setThreadPriority(app.renderThreadTid, -4); 22095 } 22096 } catch (IllegalArgumentException e) { 22097 Slog.w(TAG, 22098 "Failed to set scheduling policy, thread does not exist:\n" 22099 + e); 22100 } catch (SecurityException e) { 22101 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e); 22102 } 22103 } else { 22104 // Reset priority for top app UI and render threads 22105 setThreadPriority(app.pid, 0); 22106 if (app.renderThreadTid != 0) { 22107 setThreadPriority(app.renderThreadTid, 0); 22108 } 22109 } 22110 } 22111 } catch (Exception e) { 22112 if (false) { 22113 Slog.w(TAG, "Failed setting process group of " + app.pid 22114 + " to " + app.curSchedGroup); 22115 Slog.w(TAG, "at location", e); 22116 } 22117 } finally { 22118 Binder.restoreCallingIdentity(oldId); 22119 } 22120 } 22121 } 22122 if (app.repForegroundActivities != app.foregroundActivities) { 22123 app.repForegroundActivities = app.foregroundActivities; 22124 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 22125 } 22126 if (app.repProcState != app.curProcState) { 22127 app.repProcState = app.curProcState; 22128 if (app.thread != null) { 22129 try { 22130 if (false) { 22131 //RuntimeException h = new RuntimeException("here"); 22132 Slog.i(TAG, "Sending new process state " + app.repProcState 22133 + " to " + app /*, h*/); 22134 } 22135 app.thread.setProcessState(app.repProcState); 22136 } catch (RemoteException e) { 22137 } 22138 } 22139 } 22140 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT 22141 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) { 22142 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 22143 // Experimental code to more aggressively collect pss while 22144 // running test... the problem is that this tends to collect 22145 // the data right when a process is transitioning between process 22146 // states, which well tend to give noisy data. 22147 long start = SystemClock.uptimeMillis(); 22148 long pss = Debug.getPss(app.pid, mTmpLong, null); 22149 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now); 22150 mPendingPssProcesses.remove(app); 22151 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 22152 + " to " + app.curProcState + ": " 22153 + (SystemClock.uptimeMillis()-start) + "ms"); 22154 } 22155 app.lastStateTime = now; 22156 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 22157 mTestPssMode, isSleepingLocked(), now); 22158 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from " 22159 + ProcessList.makeProcStateString(app.setProcState) + " to " 22160 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 22161 + (app.nextPssTime-now) + ": " + app); 22162 } else { 22163 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 22164 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 22165 mTestPssMode)))) { 22166 requestPssLocked(app, app.setProcState); 22167 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 22168 mTestPssMode, isSleepingLocked(), now); 22169 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS, 22170 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 22171 } 22172 if (app.setProcState != app.curProcState) { 22173 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) { 22174 String msg = "Proc state change of " + app.processName 22175 + " to " + app.curProcState; 22176 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); 22177 } 22178 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 22179 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 22180 if (setImportant && !curImportant) { 22181 // This app is no longer something we consider important enough to allow to 22182 // use arbitrary amounts of battery power. Note 22183 // its current CPU time to later know to kill it if 22184 // it is not behaving well. 22185 app.whenUnimportant = now; 22186 app.lastCpuTime = 0; 22187 } 22188 // Inform UsageStats of important process state change 22189 // Must be called before updating setProcState 22190 maybeUpdateUsageStatsLocked(app, nowElapsed); 22191 22192 app.setProcState = app.curProcState; 22193 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 22194 app.notCachedSinceIdle = false; 22195 } 22196 if (!doingAll) { 22197 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 22198 } else { 22199 app.procStateChanged = true; 22200 } 22201 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime) 22202 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) { 22203 // For apps that sit around for a long time in the interactive state, we need 22204 // to report this at least once a day so they don't go idle. 22205 maybeUpdateUsageStatsLocked(app, nowElapsed); 22206 } 22207 22208 if (changes != 0) { 22209 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 22210 "Changes in " + app + ": " + changes); 22211 int i = mPendingProcessChanges.size()-1; 22212 ProcessChangeItem item = null; 22213 while (i >= 0) { 22214 item = mPendingProcessChanges.get(i); 22215 if (item.pid == app.pid) { 22216 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 22217 "Re-using existing item: " + item); 22218 break; 22219 } 22220 i--; 22221 } 22222 if (i < 0) { 22223 // No existing item in pending changes; need a new one. 22224 final int NA = mAvailProcessChanges.size(); 22225 if (NA > 0) { 22226 item = mAvailProcessChanges.remove(NA-1); 22227 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 22228 "Retrieving available item: " + item); 22229 } else { 22230 item = new ProcessChangeItem(); 22231 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 22232 "Allocating new item: " + item); 22233 } 22234 item.changes = 0; 22235 item.pid = app.pid; 22236 item.uid = app.info.uid; 22237 if (mPendingProcessChanges.size() == 0) { 22238 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 22239 "*** Enqueueing dispatch processes changed!"); 22240 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget(); 22241 } 22242 mPendingProcessChanges.add(item); 22243 } 22244 item.changes |= changes; 22245 item.foregroundActivities = app.repForegroundActivities; 22246 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 22247 "Item " + Integer.toHexString(System.identityHashCode(item)) 22248 + " " + app.toShortString() + ": changes=" + item.changes 22249 + " foreground=" + item.foregroundActivities 22250 + " type=" + app.adjType + " source=" + app.adjSource 22251 + " target=" + app.adjTarget); 22252 } 22253 22254 return success; 22255 } 22256 22257 private boolean isEphemeralLocked(int uid) { 22258 String packages[] = mContext.getPackageManager().getPackagesForUid(uid); 22259 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid 22260 return false; 22261 } 22262 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid), 22263 packages[0]); 22264 } 22265 22266 @VisibleForTesting 22267 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) { 22268 final UidRecord.ChangeItem pendingChange; 22269 if (uidRec == null || uidRec.pendingChange == null) { 22270 if (mPendingUidChanges.size() == 0) { 22271 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 22272 "*** Enqueueing dispatch uid changed!"); 22273 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget(); 22274 } 22275 final int NA = mAvailUidChanges.size(); 22276 if (NA > 0) { 22277 pendingChange = mAvailUidChanges.remove(NA-1); 22278 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 22279 "Retrieving available item: " + pendingChange); 22280 } else { 22281 pendingChange = new UidRecord.ChangeItem(); 22282 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 22283 "Allocating new item: " + pendingChange); 22284 } 22285 if (uidRec != null) { 22286 uidRec.pendingChange = pendingChange; 22287 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) { 22288 // If this uid is going away, and we haven't yet reported it is gone, 22289 // then do so now. 22290 change |= UidRecord.CHANGE_IDLE; 22291 } 22292 } else if (uid < 0) { 22293 throw new IllegalArgumentException("No UidRecord or uid"); 22294 } 22295 pendingChange.uidRecord = uidRec; 22296 pendingChange.uid = uidRec != null ? uidRec.uid : uid; 22297 mPendingUidChanges.add(pendingChange); 22298 } else { 22299 pendingChange = uidRec.pendingChange; 22300 // If there is no change in idle or active state, then keep whatever was pending. 22301 if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) { 22302 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE 22303 | UidRecord.CHANGE_ACTIVE)); 22304 } 22305 // If there is no change in cached or uncached state, then keep whatever was pending. 22306 if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) { 22307 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED 22308 | UidRecord.CHANGE_UNCACHED)); 22309 } 22310 // If this is a report of the UID being gone, then we shouldn't keep any previous 22311 // report of it being active or cached. (That is, a gone uid is never active, 22312 // and never cached.) 22313 if ((change & UidRecord.CHANGE_GONE) != 0) { 22314 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED); 22315 if (!uidRec.idle) { 22316 // If this uid is going away, and we haven't yet reported it is gone, 22317 // then do so now. 22318 change |= UidRecord.CHANGE_IDLE; 22319 } 22320 } 22321 } 22322 pendingChange.change = change; 22323 pendingChange.processState = uidRec != null 22324 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT; 22325 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid); 22326 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0; 22327 if (uidRec != null) { 22328 uidRec.lastReportedChange = change; 22329 uidRec.updateLastDispatchedProcStateSeq(change); 22330 } 22331 22332 // Directly update the power manager, since we sit on top of it and it is critical 22333 // it be kept in sync (so wake locks will be held as soon as appropriate). 22334 if (mLocalPowerManager != null) { 22335 // TO DO: dispatch cached/uncached changes here, so we don't need to report 22336 // all proc state changes. 22337 if ((change & UidRecord.CHANGE_ACTIVE) != 0) { 22338 mLocalPowerManager.uidActive(pendingChange.uid); 22339 } 22340 if ((change & UidRecord.CHANGE_IDLE) != 0) { 22341 mLocalPowerManager.uidIdle(pendingChange.uid); 22342 } 22343 if ((change & UidRecord.CHANGE_GONE) != 0) { 22344 mLocalPowerManager.uidGone(pendingChange.uid); 22345 } else { 22346 mLocalPowerManager.updateUidProcState(pendingChange.uid, 22347 pendingChange.processState); 22348 } 22349 } 22350 } 22351 22352 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName, 22353 String authority) { 22354 if (app == null) return; 22355 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 22356 UserState userState = mUserController.getStartedUserStateLocked(app.userId); 22357 if (userState == null) return; 22358 final long now = SystemClock.elapsedRealtime(); 22359 Long lastReported = userState.mProviderLastReportedFg.get(authority); 22360 if (lastReported == null || lastReported < now - 60 * 1000L) { 22361 if (mSystemReady) { 22362 // Cannot touch the user stats if not system ready 22363 mUsageStatsService.reportContentProviderUsage( 22364 authority, providerPkgName, app.userId); 22365 } 22366 userState.mProviderLastReportedFg.put(authority, now); 22367 } 22368 } 22369 } 22370 22371 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) { 22372 if (DEBUG_USAGE_STATS) { 22373 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList()) 22374 + "] state changes: old = " + app.setProcState + ", new = " 22375 + app.curProcState); 22376 } 22377 if (mUsageStatsService == null) { 22378 return; 22379 } 22380 boolean isInteraction; 22381 // To avoid some abuse patterns, we are going to be careful about what we consider 22382 // to be an app interaction. Being the top activity doesn't count while the display 22383 // is sleeping, nor do short foreground services. 22384 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { 22385 isInteraction = true; 22386 app.fgInteractionTime = 0; 22387 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) { 22388 if (app.fgInteractionTime == 0) { 22389 app.fgInteractionTime = nowElapsed; 22390 isInteraction = false; 22391 } else { 22392 isInteraction = nowElapsed > app.fgInteractionTime 22393 + mConstants.SERVICE_USAGE_INTERACTION_TIME; 22394 } 22395 } else { 22396 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 22397 app.fgInteractionTime = 0; 22398 } 22399 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime) 22400 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) { 22401 app.interactionEventTime = nowElapsed; 22402 String[] packages = app.getPackageList(); 22403 if (packages != null) { 22404 for (int i = 0; i < packages.length; i++) { 22405 mUsageStatsService.reportEvent(packages[i], app.userId, 22406 UsageEvents.Event.SYSTEM_INTERACTION); 22407 } 22408 } 22409 } 22410 app.reportedInteraction = isInteraction; 22411 if (!isInteraction) { 22412 app.interactionEventTime = 0; 22413 } 22414 } 22415 22416 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 22417 if (proc.thread != null) { 22418 if (proc.baseProcessTracker != null) { 22419 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 22420 } 22421 } 22422 } 22423 22424 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 22425 ProcessRecord TOP_APP, boolean doingAll, long now) { 22426 if (app.thread == null) { 22427 return false; 22428 } 22429 22430 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 22431 22432 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime()); 22433 } 22434 22435 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 22436 boolean oomAdj) { 22437 if (isForeground != proc.foregroundServices) { 22438 proc.foregroundServices = isForeground; 22439 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 22440 proc.info.uid); 22441 if (isForeground) { 22442 if (curProcs == null) { 22443 curProcs = new ArrayList<ProcessRecord>(); 22444 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 22445 } 22446 if (!curProcs.contains(proc)) { 22447 curProcs.add(proc); 22448 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 22449 proc.info.packageName, proc.info.uid); 22450 } 22451 } else { 22452 if (curProcs != null) { 22453 if (curProcs.remove(proc)) { 22454 mBatteryStatsService.noteEvent( 22455 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 22456 proc.info.packageName, proc.info.uid); 22457 if (curProcs.size() <= 0) { 22458 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 22459 } 22460 } 22461 } 22462 } 22463 if (oomAdj) { 22464 updateOomAdjLocked(); 22465 } 22466 } 22467 } 22468 22469 private final ActivityRecord resumedAppLocked() { 22470 ActivityRecord act = mStackSupervisor.getResumedActivityLocked(); 22471 String pkg; 22472 int uid; 22473 if (act != null) { 22474 pkg = act.packageName; 22475 uid = act.info.applicationInfo.uid; 22476 } else { 22477 pkg = null; 22478 uid = -1; 22479 } 22480 // Has the UID or resumed package name changed? 22481 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 22482 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 22483 if (mCurResumedPackage != null) { 22484 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 22485 mCurResumedPackage, mCurResumedUid); 22486 } 22487 mCurResumedPackage = pkg; 22488 mCurResumedUid = uid; 22489 if (mCurResumedPackage != null) { 22490 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 22491 mCurResumedPackage, mCurResumedUid); 22492 } 22493 } 22494 return act; 22495 } 22496 22497 /** 22498 * Update OomAdj for a specific process. 22499 * @param app The process to update 22500 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps 22501 * if necessary, or skip. 22502 * @return whether updateOomAdjLocked(app) was successful. 22503 */ 22504 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) { 22505 final ActivityRecord TOP_ACT = resumedAppLocked(); 22506 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 22507 final boolean wasCached = app.cached; 22508 22509 mAdjSeq++; 22510 22511 // This is the desired cached adjusment we want to tell it to use. 22512 // If our app is currently cached, we know it, and that is it. Otherwise, 22513 // we don't know it yet, and it needs to now be cached we will then 22514 // need to do a complete oom adj. 22515 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 22516 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 22517 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 22518 SystemClock.uptimeMillis()); 22519 if (oomAdjAll 22520 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) { 22521 // Changed to/from cached state, so apps after it in the LRU 22522 // list may also be changed. 22523 updateOomAdjLocked(); 22524 } 22525 return success; 22526 } 22527 22528 final void updateOomAdjLocked() { 22529 final ActivityRecord TOP_ACT = resumedAppLocked(); 22530 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 22531 final long now = SystemClock.uptimeMillis(); 22532 final long nowElapsed = SystemClock.elapsedRealtime(); 22533 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 22534 final int N = mLruProcesses.size(); 22535 22536 if (false) { 22537 RuntimeException e = new RuntimeException(); 22538 e.fillInStackTrace(); 22539 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 22540 } 22541 22542 // Reset state in all uid records. 22543 for (int i=mActiveUids.size()-1; i>=0; i--) { 22544 final UidRecord uidRec = mActiveUids.valueAt(i); 22545 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 22546 "Starting update of " + uidRec); 22547 uidRec.reset(); 22548 } 22549 22550 mStackSupervisor.rankTaskLayersIfNeeded(); 22551 22552 mAdjSeq++; 22553 mNewNumServiceProcs = 0; 22554 mNewNumAServiceProcs = 0; 22555 22556 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES; 22557 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit; 22558 22559 // Let's determine how many processes we have running vs. 22560 // how many slots we have for background processes; we may want 22561 // to put multiple processes in a slot of there are enough of 22562 // them. 22563 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 22564 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 22565 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 22566 if (numEmptyProcs > cachedProcessLimit) { 22567 // If there are more empty processes than our limit on cached 22568 // processes, then use the cached process limit for the factor. 22569 // This ensures that the really old empty processes get pushed 22570 // down to the bottom, so if we are running low on memory we will 22571 // have a better chance at keeping around more cached processes 22572 // instead of a gazillion empty processes. 22573 numEmptyProcs = cachedProcessLimit; 22574 } 22575 int emptyFactor = numEmptyProcs/numSlots; 22576 if (emptyFactor < 1) emptyFactor = 1; 22577 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 22578 if (cachedFactor < 1) cachedFactor = 1; 22579 int stepCached = 0; 22580 int stepEmpty = 0; 22581 int numCached = 0; 22582 int numEmpty = 0; 22583 int numTrimming = 0; 22584 22585 mNumNonCachedProcs = 0; 22586 mNumCachedHiddenProcs = 0; 22587 22588 // First update the OOM adjustment for each of the 22589 // application processes based on their current state. 22590 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 22591 int nextCachedAdj = curCachedAdj+1; 22592 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 22593 int nextEmptyAdj = curEmptyAdj+2; 22594 for (int i=N-1; i>=0; i--) { 22595 ProcessRecord app = mLruProcesses.get(i); 22596 if (!app.killedByAm && app.thread != null) { 22597 app.procStateChanged = false; 22598 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 22599 22600 // If we haven't yet assigned the final cached adj 22601 // to the process, do that now. 22602 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 22603 switch (app.curProcState) { 22604 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 22605 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 22606 // This process is a cached process holding activities... 22607 // assign it the next cached value for that type, and then 22608 // step that cached level. 22609 app.curRawAdj = curCachedAdj; 22610 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 22611 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i 22612 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 22613 + ")"); 22614 if (curCachedAdj != nextCachedAdj) { 22615 stepCached++; 22616 if (stepCached >= cachedFactor) { 22617 stepCached = 0; 22618 curCachedAdj = nextCachedAdj; 22619 nextCachedAdj += 2; 22620 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 22621 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 22622 } 22623 } 22624 } 22625 break; 22626 default: 22627 // For everything else, assign next empty cached process 22628 // level and bump that up. Note that this means that 22629 // long-running services that have dropped down to the 22630 // cached level will be treated as empty (since their process 22631 // state is still as a service), which is what we want. 22632 app.curRawAdj = curEmptyAdj; 22633 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 22634 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i 22635 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 22636 + ")"); 22637 if (curEmptyAdj != nextEmptyAdj) { 22638 stepEmpty++; 22639 if (stepEmpty >= emptyFactor) { 22640 stepEmpty = 0; 22641 curEmptyAdj = nextEmptyAdj; 22642 nextEmptyAdj += 2; 22643 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 22644 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 22645 } 22646 } 22647 } 22648 break; 22649 } 22650 } 22651 22652 applyOomAdjLocked(app, true, now, nowElapsed); 22653 22654 // Count the number of process types. 22655 switch (app.curProcState) { 22656 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 22657 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 22658 mNumCachedHiddenProcs++; 22659 numCached++; 22660 if (numCached > cachedProcessLimit) { 22661 app.kill("cached #" + numCached, true); 22662 } 22663 break; 22664 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 22665 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES 22666 && app.lastActivityTime < oldTime) { 22667 app.kill("empty for " 22668 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 22669 / 1000) + "s", true); 22670 } else { 22671 numEmpty++; 22672 if (numEmpty > emptyProcessLimit) { 22673 app.kill("empty #" + numEmpty, true); 22674 } 22675 } 22676 break; 22677 default: 22678 mNumNonCachedProcs++; 22679 break; 22680 } 22681 22682 if (app.isolated && app.services.size() <= 0) { 22683 // If this is an isolated process, and there are no 22684 // services running in it, then the process is no longer 22685 // needed. We agressively kill these because we can by 22686 // definition not re-use the same process again, and it is 22687 // good to avoid having whatever code was running in them 22688 // left sitting around after no longer needed. 22689 app.kill("isolated not needed", true); 22690 } else { 22691 // Keeping this process, update its uid. 22692 final UidRecord uidRec = app.uidRecord; 22693 if (uidRec != null) { 22694 uidRec.ephemeral = app.info.isInstantApp(); 22695 if (uidRec.curProcState > app.curProcState) { 22696 uidRec.curProcState = app.curProcState; 22697 } 22698 if (app.foregroundServices) { 22699 uidRec.foregroundServices = true; 22700 } 22701 } 22702 } 22703 22704 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 22705 && !app.killedByAm) { 22706 numTrimming++; 22707 } 22708 } 22709 } 22710 22711 incrementProcStateSeqAndNotifyAppsLocked(); 22712 22713 mNumServiceProcs = mNewNumServiceProcs; 22714 22715 // Now determine the memory trimming level of background processes. 22716 // Unfortunately we need to start at the back of the list to do this 22717 // properly. We only do this if the number of background apps we 22718 // are managing to keep around is less than half the maximum we desire; 22719 // if we are keeping a good number around, we'll let them use whatever 22720 // memory they want. 22721 final int numCachedAndEmpty = numCached + numEmpty; 22722 int memFactor; 22723 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES 22724 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) { 22725 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 22726 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 22727 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 22728 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 22729 } else { 22730 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 22731 } 22732 } else { 22733 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 22734 } 22735 // We always allow the memory level to go up (better). We only allow it to go 22736 // down if we are in a state where that is allowed, *and* the total number of processes 22737 // has gone down since last time. 22738 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor 22739 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel 22740 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses); 22741 if (memFactor > mLastMemoryLevel) { 22742 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 22743 memFactor = mLastMemoryLevel; 22744 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!"); 22745 } 22746 } 22747 if (memFactor != mLastMemoryLevel) { 22748 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel); 22749 } 22750 mLastMemoryLevel = memFactor; 22751 mLastNumProcesses = mLruProcesses.size(); 22752 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now); 22753 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 22754 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 22755 if (mLowRamStartTime == 0) { 22756 mLowRamStartTime = now; 22757 } 22758 int step = 0; 22759 int fgTrimLevel; 22760 switch (memFactor) { 22761 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 22762 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 22763 break; 22764 case ProcessStats.ADJ_MEM_FACTOR_LOW: 22765 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 22766 break; 22767 default: 22768 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 22769 break; 22770 } 22771 int factor = numTrimming/3; 22772 int minFactor = 2; 22773 if (mHomeProcess != null) minFactor++; 22774 if (mPreviousProcess != null) minFactor++; 22775 if (factor < minFactor) factor = minFactor; 22776 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 22777 for (int i=N-1; i>=0; i--) { 22778 ProcessRecord app = mLruProcesses.get(i); 22779 if (allChanged || app.procStateChanged) { 22780 setProcessTrackerStateLocked(app, trackerMemFactor, now); 22781 app.procStateChanged = false; 22782 } 22783 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 22784 && !app.killedByAm) { 22785 if (app.trimMemoryLevel < curLevel && app.thread != null) { 22786 try { 22787 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 22788 "Trimming memory of " + app.processName + " to " + curLevel); 22789 app.thread.scheduleTrimMemory(curLevel); 22790 } catch (RemoteException e) { 22791 } 22792 if (false) { 22793 // For now we won't do this; our memory trimming seems 22794 // to be good enough at this point that destroying 22795 // activities causes more harm than good. 22796 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 22797 && app != mHomeProcess && app != mPreviousProcess) { 22798 // Need to do this on its own message because the stack may not 22799 // be in a consistent state at this point. 22800 // For these apps we will also finish their activities 22801 // to help them free memory. 22802 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 22803 } 22804 } 22805 } 22806 app.trimMemoryLevel = curLevel; 22807 step++; 22808 if (step >= factor) { 22809 step = 0; 22810 switch (curLevel) { 22811 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 22812 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 22813 break; 22814 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 22815 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 22816 break; 22817 } 22818 } 22819 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 22820 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 22821 && app.thread != null) { 22822 try { 22823 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 22824 "Trimming memory of heavy-weight " + app.processName 22825 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 22826 app.thread.scheduleTrimMemory( 22827 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 22828 } catch (RemoteException e) { 22829 } 22830 } 22831 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 22832 } else { 22833 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 22834 || app.systemNoUi) && app.pendingUiClean) { 22835 // If this application is now in the background and it 22836 // had done UI, then give it the special trim level to 22837 // have it free UI resources. 22838 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 22839 if (app.trimMemoryLevel < level && app.thread != null) { 22840 try { 22841 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 22842 "Trimming memory of bg-ui " + app.processName 22843 + " to " + level); 22844 app.thread.scheduleTrimMemory(level); 22845 } catch (RemoteException e) { 22846 } 22847 } 22848 app.pendingUiClean = false; 22849 } 22850 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 22851 try { 22852 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 22853 "Trimming memory of fg " + app.processName 22854 + " to " + fgTrimLevel); 22855 app.thread.scheduleTrimMemory(fgTrimLevel); 22856 } catch (RemoteException e) { 22857 } 22858 } 22859 app.trimMemoryLevel = fgTrimLevel; 22860 } 22861 } 22862 } else { 22863 if (mLowRamStartTime != 0) { 22864 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 22865 mLowRamStartTime = 0; 22866 } 22867 for (int i=N-1; i>=0; i--) { 22868 ProcessRecord app = mLruProcesses.get(i); 22869 if (allChanged || app.procStateChanged) { 22870 setProcessTrackerStateLocked(app, trackerMemFactor, now); 22871 app.procStateChanged = false; 22872 } 22873 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 22874 || app.systemNoUi) && app.pendingUiClean) { 22875 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 22876 && app.thread != null) { 22877 try { 22878 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 22879 "Trimming memory of ui hidden " + app.processName 22880 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 22881 app.thread.scheduleTrimMemory( 22882 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 22883 } catch (RemoteException e) { 22884 } 22885 } 22886 app.pendingUiClean = false; 22887 } 22888 app.trimMemoryLevel = 0; 22889 } 22890 } 22891 22892 if (mAlwaysFinishActivities) { 22893 // Need to do this on its own message because the stack may not 22894 // be in a consistent state at this point. 22895 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 22896 } 22897 22898 if (allChanged) { 22899 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 22900 } 22901 22902 ArrayList<UidRecord> becameIdle = null; 22903 22904 // Update from any uid changes. 22905 if (mLocalPowerManager != null) { 22906 mLocalPowerManager.startUidChanges(); 22907 } 22908 for (int i=mActiveUids.size()-1; i>=0; i--) { 22909 final UidRecord uidRec = mActiveUids.valueAt(i); 22910 int uidChange = UidRecord.CHANGE_PROCSTATE; 22911 if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT 22912 && (uidRec.setProcState != uidRec.curProcState 22913 || uidRec.setWhitelist != uidRec.curWhitelist)) { 22914 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 22915 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState 22916 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist 22917 + " to " + uidRec.curWhitelist); 22918 if (ActivityManager.isProcStateBackground(uidRec.curProcState) 22919 && !uidRec.curWhitelist) { 22920 // UID is now in the background (and not on the temp whitelist). Was it 22921 // previously in the foreground (or on the temp whitelist)? 22922 if (!ActivityManager.isProcStateBackground(uidRec.setProcState) 22923 || uidRec.setWhitelist) { 22924 uidRec.lastBackgroundTime = nowElapsed; 22925 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) { 22926 // Note: the background settle time is in elapsed realtime, while 22927 // the handler time base is uptime. All this means is that we may 22928 // stop background uids later than we had intended, but that only 22929 // happens because the device was sleeping so we are okay anyway. 22930 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, 22931 mConstants.BACKGROUND_SETTLE_TIME); 22932 } 22933 } 22934 if (uidRec.idle && !uidRec.setIdle) { 22935 uidChange = UidRecord.CHANGE_IDLE; 22936 if (becameIdle == null) { 22937 becameIdle = new ArrayList<>(); 22938 } 22939 becameIdle.add(uidRec); 22940 } 22941 } else { 22942 if (uidRec.idle) { 22943 uidChange = UidRecord.CHANGE_ACTIVE; 22944 EventLogTags.writeAmUidActive(uidRec.uid); 22945 uidRec.idle = false; 22946 } 22947 uidRec.lastBackgroundTime = 0; 22948 } 22949 final boolean wasCached = uidRec.setProcState 22950 > ActivityManager.PROCESS_STATE_RECEIVER; 22951 final boolean isCached = uidRec.curProcState 22952 > ActivityManager.PROCESS_STATE_RECEIVER; 22953 if (wasCached != isCached || 22954 uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) { 22955 uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED; 22956 } 22957 uidRec.setProcState = uidRec.curProcState; 22958 uidRec.setWhitelist = uidRec.curWhitelist; 22959 uidRec.setIdle = uidRec.idle; 22960 enqueueUidChangeLocked(uidRec, -1, uidChange); 22961 noteUidProcessState(uidRec.uid, uidRec.curProcState); 22962 if (uidRec.foregroundServices) { 22963 mServices.foregroundServiceProcStateChangedLocked(uidRec); 22964 } 22965 } 22966 } 22967 if (mLocalPowerManager != null) { 22968 mLocalPowerManager.finishUidChanges(); 22969 } 22970 22971 if (becameIdle != null) { 22972 // If we have any new uids that became idle this time, we need to make sure 22973 // they aren't left with running services. 22974 for (int i = becameIdle.size() - 1; i >= 0; i--) { 22975 mServices.stopInBackgroundLocked(becameIdle.get(i).uid); 22976 } 22977 } 22978 22979 if (mProcessStats.shouldWriteNowLocked(now)) { 22980 mHandler.post(new Runnable() { 22981 @Override public void run() { 22982 synchronized (ActivityManagerService.this) { 22983 mProcessStats.writeStateAsyncLocked(); 22984 } 22985 } 22986 }); 22987 } 22988 22989 if (DEBUG_OOM_ADJ) { 22990 final long duration = SystemClock.uptimeMillis() - now; 22991 if (false) { 22992 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms", 22993 new RuntimeException("here").fillInStackTrace()); 22994 } else { 22995 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms"); 22996 } 22997 } 22998 } 22999 23000 @Override 23001 public void makePackageIdle(String packageName, int userId) { 23002 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 23003 != PackageManager.PERMISSION_GRANTED) { 23004 String msg = "Permission Denial: makePackageIdle() from pid=" 23005 + Binder.getCallingPid() 23006 + ", uid=" + Binder.getCallingUid() 23007 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 23008 Slog.w(TAG, msg); 23009 throw new SecurityException(msg); 23010 } 23011 final int callingPid = Binder.getCallingPid(); 23012 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(), 23013 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null); 23014 long callingId = Binder.clearCallingIdentity(); 23015 synchronized(this) { 23016 try { 23017 IPackageManager pm = AppGlobals.getPackageManager(); 23018 int pkgUid = -1; 23019 try { 23020 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES 23021 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM); 23022 } catch (RemoteException e) { 23023 } 23024 if (pkgUid == -1) { 23025 throw new IllegalArgumentException("Unknown package name " + packageName); 23026 } 23027 23028 if (mLocalPowerManager != null) { 23029 mLocalPowerManager.startUidChanges(); 23030 } 23031 final int appId = UserHandle.getAppId(pkgUid); 23032 final int N = mActiveUids.size(); 23033 for (int i=N-1; i>=0; i--) { 23034 final UidRecord uidRec = mActiveUids.valueAt(i); 23035 final long bgTime = uidRec.lastBackgroundTime; 23036 if (bgTime > 0 && !uidRec.idle) { 23037 if (UserHandle.getAppId(uidRec.uid) == appId) { 23038 if (userId == UserHandle.USER_ALL || 23039 userId == UserHandle.getUserId(uidRec.uid)) { 23040 EventLogTags.writeAmUidIdle(uidRec.uid); 23041 uidRec.idle = true; 23042 uidRec.setIdle = true; 23043 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid) 23044 + " from package " + packageName + " user " + userId); 23045 doStopUidLocked(uidRec.uid, uidRec); 23046 } 23047 } 23048 } 23049 } 23050 } finally { 23051 if (mLocalPowerManager != null) { 23052 mLocalPowerManager.finishUidChanges(); 23053 } 23054 Binder.restoreCallingIdentity(callingId); 23055 } 23056 } 23057 } 23058 23059 final void idleUids() { 23060 synchronized (this) { 23061 final int N = mActiveUids.size(); 23062 if (N <= 0) { 23063 return; 23064 } 23065 final long nowElapsed = SystemClock.elapsedRealtime(); 23066 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME; 23067 long nextTime = 0; 23068 if (mLocalPowerManager != null) { 23069 mLocalPowerManager.startUidChanges(); 23070 } 23071 for (int i=N-1; i>=0; i--) { 23072 final UidRecord uidRec = mActiveUids.valueAt(i); 23073 final long bgTime = uidRec.lastBackgroundTime; 23074 if (bgTime > 0 && !uidRec.idle) { 23075 if (bgTime <= maxBgTime) { 23076 EventLogTags.writeAmUidIdle(uidRec.uid); 23077 uidRec.idle = true; 23078 uidRec.setIdle = true; 23079 doStopUidLocked(uidRec.uid, uidRec); 23080 } else { 23081 if (nextTime == 0 || nextTime > bgTime) { 23082 nextTime = bgTime; 23083 } 23084 } 23085 } 23086 } 23087 if (mLocalPowerManager != null) { 23088 mLocalPowerManager.finishUidChanges(); 23089 } 23090 if (nextTime > 0) { 23091 mHandler.removeMessages(IDLE_UIDS_MSG); 23092 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, 23093 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed); 23094 } 23095 } 23096 } 23097 23098 /** 23099 * Checks if any uid is coming from background to foreground or vice versa and if so, increments 23100 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter 23101 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block. 23102 */ 23103 @VisibleForTesting 23104 @GuardedBy("this") 23105 void incrementProcStateSeqAndNotifyAppsLocked() { 23106 if (mWaitForNetworkTimeoutMs <= 0) { 23107 return; 23108 } 23109 // Used for identifying which uids need to block for network. 23110 ArrayList<Integer> blockingUids = null; 23111 for (int i = mActiveUids.size() - 1; i >= 0; --i) { 23112 final UidRecord uidRec = mActiveUids.valueAt(i); 23113 // If the network is not restricted for uid, then nothing to do here. 23114 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) { 23115 continue; 23116 } 23117 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) { 23118 continue; 23119 } 23120 // If process state is not changed, then there's nothing to do. 23121 if (uidRec.setProcState == uidRec.curProcState) { 23122 continue; 23123 } 23124 final int blockState = getBlockStateForUid(uidRec); 23125 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as 23126 // there's nothing the app needs to do in this scenario. 23127 if (blockState == NETWORK_STATE_NO_CHANGE) { 23128 continue; 23129 } 23130 synchronized (uidRec.networkStateLock) { 23131 uidRec.curProcStateSeq = ++mProcStateSeqCounter; 23132 if (blockState == NETWORK_STATE_BLOCK) { 23133 if (blockingUids == null) { 23134 blockingUids = new ArrayList<>(); 23135 } 23136 blockingUids.add(uidRec.uid); 23137 } else { 23138 if (DEBUG_NETWORK) { 23139 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking" 23140 + " threads for uid: " + uidRec); 23141 } 23142 if (uidRec.waitingForNetwork) { 23143 uidRec.networkStateLock.notifyAll(); 23144 } 23145 } 23146 } 23147 } 23148 23149 // There are no uids that need to block, so nothing more to do. 23150 if (blockingUids == null) { 23151 return; 23152 } 23153 23154 for (int i = mLruProcesses.size() - 1; i >= 0; --i) { 23155 final ProcessRecord app = mLruProcesses.get(i); 23156 if (!blockingUids.contains(app.uid)) { 23157 continue; 23158 } 23159 if (!app.killedByAm && app.thread != null) { 23160 final UidRecord uidRec = mActiveUids.get(app.uid); 23161 try { 23162 if (DEBUG_NETWORK) { 23163 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: " 23164 + uidRec); 23165 } 23166 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq); 23167 } catch (RemoteException ignored) { 23168 } 23169 } 23170 } 23171 } 23172 23173 /** 23174 * Checks if the uid is coming from background to foreground or vice versa and returns 23175 * appropriate block state based on this. 23176 * 23177 * @return blockState based on whether the uid is coming from background to foreground or 23178 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or 23179 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise 23180 * {@link #NETWORK_STATE_NO_CHANGE}. 23181 */ 23182 @VisibleForTesting 23183 int getBlockStateForUid(UidRecord uidRec) { 23184 // Denotes whether uid's process state is currently allowed network access. 23185 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState) 23186 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState); 23187 // Denotes whether uid's process state was previously allowed network access. 23188 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState) 23189 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState); 23190 23191 // When the uid is coming to foreground, AMS should inform the app thread that it should 23192 // block for the network rules to get updated before launching an activity. 23193 if (!wasAllowed && isAllowed) { 23194 return NETWORK_STATE_BLOCK; 23195 } 23196 // When the uid is going to background, AMS should inform the app thread that if an 23197 // activity launch is blocked for the network rules to get updated, it should be unblocked. 23198 if (wasAllowed && !isAllowed) { 23199 return NETWORK_STATE_UNBLOCK; 23200 } 23201 return NETWORK_STATE_NO_CHANGE; 23202 } 23203 23204 final void runInBackgroundDisabled(int uid) { 23205 synchronized (this) { 23206 UidRecord uidRec = mActiveUids.get(uid); 23207 if (uidRec != null) { 23208 // This uid is actually running... should it be considered background now? 23209 if (uidRec.idle) { 23210 doStopUidLocked(uidRec.uid, uidRec); 23211 } 23212 } else { 23213 // This uid isn't actually running... still send a report about it being "stopped". 23214 doStopUidLocked(uid, null); 23215 } 23216 } 23217 } 23218 23219 final void doStopUidLocked(int uid, final UidRecord uidRec) { 23220 mServices.stopInBackgroundLocked(uid); 23221 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE); 23222 } 23223 23224 /** 23225 * Whitelists {@code targetUid} to temporarily bypass Power Save mode. 23226 */ 23227 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid, 23228 long duration, String tag) { 23229 if (DEBUG_WHITELISTS) { 23230 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", " 23231 + targetUid + ", " + duration + ")"); 23232 } 23233 23234 synchronized (mPidsSelfLocked) { 23235 final ProcessRecord pr = mPidsSelfLocked.get(callerPid); 23236 if (pr == null) { 23237 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid " 23238 + callerPid); 23239 return; 23240 } 23241 if (!pr.whitelistManager) { 23242 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid) 23243 != PackageManager.PERMISSION_GRANTED) { 23244 if (DEBUG_WHITELISTS) { 23245 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid 23246 + ": pid " + callerPid + " is not allowed"); 23247 } 23248 return; 23249 } 23250 } 23251 } 23252 23253 tempWhitelistUidLocked(targetUid, duration, tag); 23254 } 23255 23256 /** 23257 * Whitelists {@code targetUid} to temporarily bypass Power Save mode. 23258 */ 23259 void tempWhitelistUidLocked(int targetUid, long duration, String tag) { 23260 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag)); 23261 setUidTempWhitelistStateLocked(targetUid, true); 23262 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget(); 23263 } 23264 23265 void pushTempWhitelist() { 23266 final int N; 23267 final PendingTempWhitelist[] list; 23268 23269 // First copy out the pending changes... we need to leave them in the map for now, 23270 // in case someone needs to check what is coming up while we don't have the lock held. 23271 synchronized(this) { 23272 N = mPendingTempWhitelist.size(); 23273 list = new PendingTempWhitelist[N]; 23274 for (int i = 0; i < N; i++) { 23275 list[i] = mPendingTempWhitelist.valueAt(i); 23276 } 23277 } 23278 23279 // Now safely dispatch changes to device idle controller. 23280 for (int i = 0; i < N; i++) { 23281 PendingTempWhitelist ptw = list[i]; 23282 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid, 23283 ptw.duration, true, ptw.tag); 23284 } 23285 23286 // And now we can safely remove them from the map. 23287 synchronized(this) { 23288 for (int i = 0; i < N; i++) { 23289 PendingTempWhitelist ptw = list[i]; 23290 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid); 23291 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) { 23292 mPendingTempWhitelist.removeAt(index); 23293 } 23294 } 23295 } 23296 } 23297 23298 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) { 23299 boolean changed = false; 23300 for (int i=mActiveUids.size()-1; i>=0; i--) { 23301 final UidRecord uidRec = mActiveUids.valueAt(i); 23302 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) { 23303 uidRec.curWhitelist = onWhitelist; 23304 changed = true; 23305 } 23306 } 23307 if (changed) { 23308 updateOomAdjLocked(); 23309 } 23310 } 23311 23312 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) { 23313 boolean changed = false; 23314 final UidRecord uidRec = mActiveUids.get(uid); 23315 if (uidRec != null && uidRec.curWhitelist != onWhitelist) { 23316 uidRec.curWhitelist = onWhitelist; 23317 updateOomAdjLocked(); 23318 } 23319 } 23320 23321 final void trimApplications() { 23322 synchronized (this) { 23323 int i; 23324 23325 // First remove any unused application processes whose package 23326 // has been removed. 23327 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 23328 final ProcessRecord app = mRemovedProcesses.get(i); 23329 if (app.activities.size() == 0 23330 && app.curReceivers.isEmpty() && app.services.size() == 0) { 23331 Slog.i( 23332 TAG, "Exiting empty application process " 23333 + app.toShortString() + " (" 23334 + (app.thread != null ? app.thread.asBinder() : null) 23335 + ")\n"); 23336 if (app.pid > 0 && app.pid != MY_PID) { 23337 app.kill("empty", false); 23338 } else { 23339 try { 23340 app.thread.scheduleExit(); 23341 } catch (Exception e) { 23342 // Ignore exceptions. 23343 } 23344 } 23345 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/); 23346 mRemovedProcesses.remove(i); 23347 23348 if (app.persistent) { 23349 addAppLocked(app.info, null, false, null /* ABI override */); 23350 } 23351 } 23352 } 23353 23354 // Now update the oom adj for all processes. 23355 updateOomAdjLocked(); 23356 } 23357 } 23358 23359 /** This method sends the specified signal to each of the persistent apps */ 23360 public void signalPersistentProcesses(int sig) throws RemoteException { 23361 if (sig != SIGNAL_USR1) { 23362 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 23363 } 23364 23365 synchronized (this) { 23366 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 23367 != PackageManager.PERMISSION_GRANTED) { 23368 throw new SecurityException("Requires permission " 23369 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 23370 } 23371 23372 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 23373 ProcessRecord r = mLruProcesses.get(i); 23374 if (r.thread != null && r.persistent) { 23375 sendSignal(r.pid, sig); 23376 } 23377 } 23378 } 23379 } 23380 23381 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 23382 if (proc == null || proc == mProfileProc) { 23383 proc = mProfileProc; 23384 profileType = mProfileType; 23385 clearProfilerLocked(); 23386 } 23387 if (proc == null) { 23388 return; 23389 } 23390 try { 23391 proc.thread.profilerControl(false, null, profileType); 23392 } catch (RemoteException e) { 23393 throw new IllegalStateException("Process disappeared"); 23394 } 23395 } 23396 23397 private void clearProfilerLocked() { 23398 if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) { 23399 try { 23400 mProfilerInfo.profileFd.close(); 23401 } catch (IOException e) { 23402 } 23403 } 23404 mProfileApp = null; 23405 mProfileProc = null; 23406 mProfilerInfo = null; 23407 } 23408 23409 public boolean profileControl(String process, int userId, boolean start, 23410 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 23411 23412 try { 23413 synchronized (this) { 23414 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 23415 // its own permission. 23416 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 23417 != PackageManager.PERMISSION_GRANTED) { 23418 throw new SecurityException("Requires permission " 23419 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 23420 } 23421 23422 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 23423 throw new IllegalArgumentException("null profile info or fd"); 23424 } 23425 23426 ProcessRecord proc = null; 23427 if (process != null) { 23428 proc = findProcessLocked(process, userId, "profileControl"); 23429 } 23430 23431 if (start && (proc == null || proc.thread == null)) { 23432 throw new IllegalArgumentException("Unknown process: " + process); 23433 } 23434 23435 if (start) { 23436 stopProfilerLocked(null, 0); 23437 setProfileApp(proc.info, proc.processName, profilerInfo); 23438 mProfileProc = proc; 23439 mProfileType = profileType; 23440 ParcelFileDescriptor fd = profilerInfo.profileFd; 23441 try { 23442 fd = fd.dup(); 23443 } catch (IOException e) { 23444 fd = null; 23445 } 23446 profilerInfo.profileFd = fd; 23447 proc.thread.profilerControl(start, profilerInfo, profileType); 23448 fd = null; 23449 try { 23450 mProfilerInfo.profileFd.close(); 23451 } catch (IOException e) { 23452 } 23453 mProfilerInfo.profileFd = null; 23454 } else { 23455 stopProfilerLocked(proc, profileType); 23456 if (profilerInfo != null && profilerInfo.profileFd != null) { 23457 try { 23458 profilerInfo.profileFd.close(); 23459 } catch (IOException e) { 23460 } 23461 } 23462 } 23463 23464 return true; 23465 } 23466 } catch (RemoteException e) { 23467 throw new IllegalStateException("Process disappeared"); 23468 } finally { 23469 if (profilerInfo != null && profilerInfo.profileFd != null) { 23470 try { 23471 profilerInfo.profileFd.close(); 23472 } catch (IOException e) { 23473 } 23474 } 23475 } 23476 } 23477 23478 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 23479 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 23480 userId, true, ALLOW_FULL_ONLY, callName, null); 23481 ProcessRecord proc = null; 23482 try { 23483 int pid = Integer.parseInt(process); 23484 synchronized (mPidsSelfLocked) { 23485 proc = mPidsSelfLocked.get(pid); 23486 } 23487 } catch (NumberFormatException e) { 23488 } 23489 23490 if (proc == null) { 23491 ArrayMap<String, SparseArray<ProcessRecord>> all 23492 = mProcessNames.getMap(); 23493 SparseArray<ProcessRecord> procs = all.get(process); 23494 if (procs != null && procs.size() > 0) { 23495 proc = procs.valueAt(0); 23496 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 23497 for (int i=1; i<procs.size(); i++) { 23498 ProcessRecord thisProc = procs.valueAt(i); 23499 if (thisProc.userId == userId) { 23500 proc = thisProc; 23501 break; 23502 } 23503 } 23504 } 23505 } 23506 } 23507 23508 return proc; 23509 } 23510 23511 public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo, 23512 boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException { 23513 23514 try { 23515 synchronized (this) { 23516 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 23517 // its own permission (same as profileControl). 23518 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 23519 != PackageManager.PERMISSION_GRANTED) { 23520 throw new SecurityException("Requires permission " 23521 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 23522 } 23523 23524 if (fd == null) { 23525 throw new IllegalArgumentException("null fd"); 23526 } 23527 23528 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 23529 if (proc == null || proc.thread == null) { 23530 throw new IllegalArgumentException("Unknown process: " + process); 23531 } 23532 23533 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 23534 if (!isDebuggable) { 23535 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 23536 throw new SecurityException("Process not debuggable: " + proc); 23537 } 23538 } 23539 23540 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd); 23541 fd = null; 23542 return true; 23543 } 23544 } catch (RemoteException e) { 23545 throw new IllegalStateException("Process disappeared"); 23546 } finally { 23547 if (fd != null) { 23548 try { 23549 fd.close(); 23550 } catch (IOException e) { 23551 } 23552 } 23553 } 23554 } 23555 23556 @Override 23557 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize, 23558 String reportPackage) { 23559 if (processName != null) { 23560 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 23561 "setDumpHeapDebugLimit()"); 23562 } else { 23563 synchronized (mPidsSelfLocked) { 23564 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid()); 23565 if (proc == null) { 23566 throw new SecurityException("No process found for calling pid " 23567 + Binder.getCallingPid()); 23568 } 23569 if (!Build.IS_DEBUGGABLE 23570 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 23571 throw new SecurityException("Not running a debuggable build"); 23572 } 23573 processName = proc.processName; 23574 uid = proc.uid; 23575 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) { 23576 throw new SecurityException("Package " + reportPackage + " is not running in " 23577 + proc); 23578 } 23579 } 23580 } 23581 synchronized (this) { 23582 if (maxMemSize > 0) { 23583 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage)); 23584 } else { 23585 if (uid != 0) { 23586 mMemWatchProcesses.remove(processName, uid); 23587 } else { 23588 mMemWatchProcesses.getMap().remove(processName); 23589 } 23590 } 23591 } 23592 } 23593 23594 @Override 23595 public void dumpHeapFinished(String path) { 23596 synchronized (this) { 23597 if (Binder.getCallingPid() != mMemWatchDumpPid) { 23598 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid() 23599 + " does not match last pid " + mMemWatchDumpPid); 23600 return; 23601 } 23602 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) { 23603 Slog.w(TAG, "dumpHeapFinished: Calling path " + path 23604 + " does not match last path " + mMemWatchDumpFile); 23605 return; 23606 } 23607 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path); 23608 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG); 23609 23610 // Forced gc to clean up the remnant hprof fd. 23611 Runtime.getRuntime().gc(); 23612 } 23613 } 23614 23615 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 23616 public void monitor() { 23617 synchronized (this) { } 23618 } 23619 23620 void onCoreSettingsChange(Bundle settings) { 23621 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 23622 ProcessRecord processRecord = mLruProcesses.get(i); 23623 try { 23624 if (processRecord.thread != null) { 23625 processRecord.thread.setCoreSettings(settings); 23626 } 23627 } catch (RemoteException re) { 23628 /* ignore */ 23629 } 23630 } 23631 } 23632 23633 // Multi-user methods 23634 23635 /** 23636 * Start user, if its not already running, but don't bring it to foreground. 23637 */ 23638 @Override 23639 public boolean startUserInBackground(final int userId) { 23640 return mUserController.startUser(userId, /* foreground */ false); 23641 } 23642 23643 @Override 23644 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) { 23645 return mUserController.unlockUser(userId, token, secret, listener); 23646 } 23647 23648 @Override 23649 public boolean switchUser(final int targetUserId) { 23650 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId); 23651 int currentUserId; 23652 UserInfo targetUserInfo; 23653 synchronized (this) { 23654 currentUserId = mUserController.getCurrentUserIdLocked(); 23655 targetUserInfo = mUserController.getUserInfo(targetUserId); 23656 if (targetUserId == currentUserId) { 23657 Slog.i(TAG, "user #" + targetUserId + " is already the current user"); 23658 return true; 23659 } 23660 if (targetUserInfo == null) { 23661 Slog.w(TAG, "No user info for user #" + targetUserId); 23662 return false; 23663 } 23664 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) { 23665 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId 23666 + " when device is in demo mode"); 23667 return false; 23668 } 23669 if (!targetUserInfo.supportsSwitchTo()) { 23670 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported"); 23671 return false; 23672 } 23673 if (targetUserInfo.isManagedProfile()) { 23674 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user"); 23675 return false; 23676 } 23677 mUserController.setTargetUserIdLocked(targetUserId); 23678 } 23679 if (mUserController.mUserSwitchUiEnabled) { 23680 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId); 23681 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo); 23682 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG); 23683 mUiHandler.sendMessage(mHandler.obtainMessage( 23684 START_USER_SWITCH_UI_MSG, userNames)); 23685 } else { 23686 mHandler.removeMessages(START_USER_SWITCH_FG_MSG); 23687 mHandler.sendMessage(mHandler.obtainMessage( 23688 START_USER_SWITCH_FG_MSG, targetUserId, 0)); 23689 } 23690 return true; 23691 } 23692 23693 void scheduleStartProfilesLocked() { 23694 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 23695 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 23696 DateUtils.SECOND_IN_MILLIS); 23697 } 23698 } 23699 23700 @Override 23701 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) { 23702 return mUserController.stopUser(userId, force, callback); 23703 } 23704 23705 @Override 23706 public UserInfo getCurrentUser() { 23707 return mUserController.getCurrentUser(); 23708 } 23709 23710 String getStartedUserState(int userId) { 23711 synchronized (this) { 23712 final UserState userState = mUserController.getStartedUserStateLocked(userId); 23713 return UserState.stateToString(userState.state); 23714 } 23715 } 23716 23717 @Override 23718 public boolean isUserRunning(int userId, int flags) { 23719 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId()) 23720 && checkCallingPermission(INTERACT_ACROSS_USERS) 23721 != PackageManager.PERMISSION_GRANTED) { 23722 String msg = "Permission Denial: isUserRunning() from pid=" 23723 + Binder.getCallingPid() 23724 + ", uid=" + Binder.getCallingUid() 23725 + " requires " + INTERACT_ACROSS_USERS; 23726 Slog.w(TAG, msg); 23727 throw new SecurityException(msg); 23728 } 23729 synchronized (this) { 23730 return mUserController.isUserRunningLocked(userId, flags); 23731 } 23732 } 23733 23734 @Override 23735 public int[] getRunningUserIds() { 23736 if (checkCallingPermission(INTERACT_ACROSS_USERS) 23737 != PackageManager.PERMISSION_GRANTED) { 23738 String msg = "Permission Denial: isUserRunning() from pid=" 23739 + Binder.getCallingPid() 23740 + ", uid=" + Binder.getCallingUid() 23741 + " requires " + INTERACT_ACROSS_USERS; 23742 Slog.w(TAG, msg); 23743 throw new SecurityException(msg); 23744 } 23745 synchronized (this) { 23746 return mUserController.getStartedUserArrayLocked(); 23747 } 23748 } 23749 23750 @Override 23751 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) { 23752 mUserController.registerUserSwitchObserver(observer, name); 23753 } 23754 23755 @Override 23756 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 23757 mUserController.unregisterUserSwitchObserver(observer); 23758 } 23759 23760 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 23761 if (info == null) return null; 23762 ApplicationInfo newInfo = new ApplicationInfo(info); 23763 newInfo.initForUser(userId); 23764 return newInfo; 23765 } 23766 23767 public boolean isUserStopped(int userId) { 23768 synchronized (this) { 23769 return mUserController.getStartedUserStateLocked(userId) == null; 23770 } 23771 } 23772 23773 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 23774 if (aInfo == null 23775 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 23776 return aInfo; 23777 } 23778 23779 ActivityInfo info = new ActivityInfo(aInfo); 23780 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 23781 return info; 23782 } 23783 23784 private boolean processSanityChecksLocked(ProcessRecord process) { 23785 if (process == null || process.thread == null) { 23786 return false; 23787 } 23788 23789 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 23790 if (!isDebuggable) { 23791 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 23792 return false; 23793 } 23794 } 23795 23796 return true; 23797 } 23798 23799 public boolean startBinderTracking() throws RemoteException { 23800 synchronized (this) { 23801 mBinderTransactionTrackingEnabled = true; 23802 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own 23803 // permission (same as profileControl). 23804 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 23805 != PackageManager.PERMISSION_GRANTED) { 23806 throw new SecurityException("Requires permission " 23807 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 23808 } 23809 23810 for (int i = 0; i < mLruProcesses.size(); i++) { 23811 ProcessRecord process = mLruProcesses.get(i); 23812 if (!processSanityChecksLocked(process)) { 23813 continue; 23814 } 23815 try { 23816 process.thread.startBinderTracking(); 23817 } catch (RemoteException e) { 23818 Log.v(TAG, "Process disappared"); 23819 } 23820 } 23821 return true; 23822 } 23823 } 23824 23825 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException { 23826 try { 23827 synchronized (this) { 23828 mBinderTransactionTrackingEnabled = false; 23829 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own 23830 // permission (same as profileControl). 23831 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 23832 != PackageManager.PERMISSION_GRANTED) { 23833 throw new SecurityException("Requires permission " 23834 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 23835 } 23836 23837 if (fd == null) { 23838 throw new IllegalArgumentException("null fd"); 23839 } 23840 23841 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor())); 23842 pw.println("Binder transaction traces for all processes.\n"); 23843 for (ProcessRecord process : mLruProcesses) { 23844 if (!processSanityChecksLocked(process)) { 23845 continue; 23846 } 23847 23848 pw.println("Traces for process: " + process.processName); 23849 pw.flush(); 23850 try { 23851 TransferPipe tp = new TransferPipe(); 23852 try { 23853 process.thread.stopBinderTrackingAndDump(tp.getWriteFd()); 23854 tp.go(fd.getFileDescriptor()); 23855 } finally { 23856 tp.kill(); 23857 } 23858 } catch (IOException e) { 23859 pw.println("Failure while dumping IPC traces from " + process + 23860 ". Exception: " + e); 23861 pw.flush(); 23862 } catch (RemoteException e) { 23863 pw.println("Got a RemoteException while dumping IPC traces from " + 23864 process + ". Exception: " + e); 23865 pw.flush(); 23866 } 23867 } 23868 fd = null; 23869 return true; 23870 } 23871 } finally { 23872 if (fd != null) { 23873 try { 23874 fd.close(); 23875 } catch (IOException e) { 23876 } 23877 } 23878 } 23879 } 23880 23881 @VisibleForTesting 23882 final class LocalService extends ActivityManagerInternal { 23883 @Override 23884 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent, 23885 int targetUserId) { 23886 synchronized (ActivityManagerService.this) { 23887 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid, 23888 targetPkg, intent, null, targetUserId); 23889 } 23890 } 23891 23892 @Override 23893 public String checkContentProviderAccess(String authority, int userId) { 23894 return ActivityManagerService.this.checkContentProviderAccess(authority, userId); 23895 } 23896 23897 @Override 23898 public void onWakefulnessChanged(int wakefulness) { 23899 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 23900 } 23901 23902 @Override 23903 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 23904 String processName, String abiOverride, int uid, Runnable crashHandler) { 23905 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 23906 processName, abiOverride, uid, crashHandler); 23907 } 23908 23909 @Override 23910 public SleepToken acquireSleepToken(String tag, int displayId) { 23911 Preconditions.checkNotNull(tag); 23912 return ActivityManagerService.this.acquireSleepToken(tag, displayId); 23913 } 23914 23915 @Override 23916 public ComponentName getHomeActivityForUser(int userId) { 23917 synchronized (ActivityManagerService.this) { 23918 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId); 23919 return homeActivity == null ? null : homeActivity.realActivity; 23920 } 23921 } 23922 23923 @Override 23924 public void onUserRemoved(int userId) { 23925 synchronized (ActivityManagerService.this) { 23926 ActivityManagerService.this.onUserStoppedLocked(userId); 23927 } 23928 mBatteryStatsService.onUserRemoved(userId); 23929 } 23930 23931 @Override 23932 public void onLocalVoiceInteractionStarted(IBinder activity, 23933 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) { 23934 synchronized (ActivityManagerService.this) { 23935 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity, 23936 voiceSession, voiceInteractor); 23937 } 23938 } 23939 23940 @Override 23941 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) { 23942 synchronized (ActivityManagerService.this) { 23943 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting( 23944 reasons, timestamp); 23945 } 23946 } 23947 23948 @Override 23949 public void notifyAppTransitionFinished() { 23950 synchronized (ActivityManagerService.this) { 23951 mStackSupervisor.notifyAppTransitionDone(); 23952 } 23953 } 23954 23955 @Override 23956 public void notifyAppTransitionCancelled() { 23957 synchronized (ActivityManagerService.this) { 23958 mStackSupervisor.notifyAppTransitionDone(); 23959 } 23960 } 23961 23962 @Override 23963 public List<IBinder> getTopVisibleActivities() { 23964 synchronized (ActivityManagerService.this) { 23965 return mStackSupervisor.getTopVisibleActivities(); 23966 } 23967 } 23968 23969 @Override 23970 public void notifyDockedStackMinimizedChanged(boolean minimized) { 23971 synchronized (ActivityManagerService.this) { 23972 mStackSupervisor.setDockedStackMinimized(minimized); 23973 } 23974 } 23975 23976 @Override 23977 public void killForegroundAppsForUser(int userHandle) { 23978 synchronized (ActivityManagerService.this) { 23979 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 23980 final int NP = mProcessNames.getMap().size(); 23981 for (int ip = 0; ip < NP; ip++) { 23982 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 23983 final int NA = apps.size(); 23984 for (int ia = 0; ia < NA; ia++) { 23985 final ProcessRecord app = apps.valueAt(ia); 23986 if (app.persistent) { 23987 // We don't kill persistent processes. 23988 continue; 23989 } 23990 if (app.removed) { 23991 procs.add(app); 23992 } else if (app.userId == userHandle && app.foregroundActivities) { 23993 app.removed = true; 23994 procs.add(app); 23995 } 23996 } 23997 } 23998 23999 final int N = procs.size(); 24000 for (int i = 0; i < N; i++) { 24001 removeProcessLocked(procs.get(i), false, true, "kill all fg"); 24002 } 24003 } 24004 } 24005 24006 @Override 24007 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken, 24008 long duration) { 24009 if (!(target instanceof PendingIntentRecord)) { 24010 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target); 24011 return; 24012 } 24013 synchronized (ActivityManagerService.this) { 24014 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration); 24015 } 24016 } 24017 24018 @Override 24019 public void setDeviceIdleWhitelist(int[] appids) { 24020 synchronized (ActivityManagerService.this) { 24021 mDeviceIdleWhitelist = appids; 24022 } 24023 } 24024 24025 @Override 24026 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) { 24027 synchronized (ActivityManagerService.this) { 24028 mDeviceIdleTempWhitelist = appids; 24029 setAppIdTempWhitelistStateLocked(changingAppId, adding); 24030 } 24031 } 24032 24033 @Override 24034 public void updatePersistentConfigurationForUser(@NonNull Configuration values, 24035 int userId) { 24036 Preconditions.checkNotNull(values, "Configuration must not be null"); 24037 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported"); 24038 synchronized (ActivityManagerService.this) { 24039 updateConfigurationLocked(values, null, false, true, userId, 24040 false /* deferResume */); 24041 } 24042 } 24043 24044 @Override 24045 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents, 24046 Bundle bOptions) { 24047 Preconditions.checkNotNull(intents, "intents"); 24048 final String[] resolvedTypes = new String[intents.length]; 24049 for (int i = 0; i < intents.length; i++) { 24050 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver()); 24051 } 24052 24053 // UID of the package on user userId. 24054 // "= 0" is needed because otherwise catch(RemoteException) would make it look like 24055 // packageUid may not be initialized. 24056 int packageUid = 0; 24057 try { 24058 packageUid = AppGlobals.getPackageManager().getPackageUid( 24059 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId); 24060 } catch (RemoteException e) { 24061 // Shouldn't happen. 24062 } 24063 24064 synchronized (ActivityManagerService.this) { 24065 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes, 24066 /*resultTo*/ null, bOptions, userId); 24067 } 24068 } 24069 24070 @Override 24071 public int getUidProcessState(int uid) { 24072 return getUidState(uid); 24073 } 24074 24075 @Override 24076 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) { 24077 synchronized (ActivityManagerService.this) { 24078 24079 // We might change the visibilities here, so prepare an empty app transition which 24080 // might be overridden later if we actually change visibilities. 24081 final boolean wasTransitionSet = 24082 mWindowManager.getPendingAppTransition() != TRANSIT_NONE; 24083 if (!wasTransitionSet) { 24084 mWindowManager.prepareAppTransition(TRANSIT_NONE, 24085 false /* alwaysKeepCurrent */); 24086 } 24087 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 24088 24089 // If there was a transition set already we don't want to interfere with it as we 24090 // might be starting it too early. 24091 if (!wasTransitionSet) { 24092 mWindowManager.executeAppTransition(); 24093 } 24094 } 24095 if (callback != null) { 24096 callback.run(); 24097 } 24098 } 24099 24100 @Override 24101 public boolean isSystemReady() { 24102 // no need to synchronize(this) just to read & return the value 24103 return mSystemReady; 24104 } 24105 24106 @Override 24107 public void notifyKeyguardTrustedChanged() { 24108 synchronized (ActivityManagerService.this) { 24109 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) { 24110 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 24111 } 24112 } 24113 } 24114 24115 /** 24116 * Sets if the given pid has an overlay UI or not. 24117 * 24118 * @param pid The pid we are setting overlay UI for. 24119 * @param hasOverlayUi True if the process has overlay UI. 24120 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY 24121 */ 24122 @Override 24123 public void setHasOverlayUi(int pid, boolean hasOverlayUi) { 24124 synchronized (ActivityManagerService.this) { 24125 final ProcessRecord pr; 24126 synchronized (mPidsSelfLocked) { 24127 pr = mPidsSelfLocked.get(pid); 24128 if (pr == null) { 24129 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid); 24130 return; 24131 } 24132 } 24133 if (pr.hasOverlayUi == hasOverlayUi) { 24134 return; 24135 } 24136 pr.hasOverlayUi = hasOverlayUi; 24137 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid); 24138 updateOomAdjLocked(pr, true); 24139 } 24140 } 24141 24142 /** 24143 * Called after the network policy rules are updated by 24144 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid} 24145 * and {@param procStateSeq}. 24146 */ 24147 @Override 24148 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) { 24149 if (DEBUG_NETWORK) { 24150 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: " 24151 + uid + " seq: " + procStateSeq); 24152 } 24153 UidRecord record; 24154 synchronized (ActivityManagerService.this) { 24155 record = mActiveUids.get(uid); 24156 if (record == null) { 24157 if (DEBUG_NETWORK) { 24158 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid 24159 + " procStateSeq: " + procStateSeq); 24160 } 24161 return; 24162 } 24163 } 24164 synchronized (record.networkStateLock) { 24165 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) { 24166 if (DEBUG_NETWORK) { 24167 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already" 24168 + " been handled for uid: " + uid); 24169 } 24170 return; 24171 } 24172 record.lastNetworkUpdatedProcStateSeq = procStateSeq; 24173 if (record.curProcStateSeq > procStateSeq) { 24174 if (DEBUG_NETWORK) { 24175 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid 24176 + ", curProcstateSeq: " + record.curProcStateSeq 24177 + ", procStateSeq: " + procStateSeq); 24178 } 24179 return; 24180 } 24181 if (record.waitingForNetwork) { 24182 if (DEBUG_NETWORK) { 24183 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid 24184 + ", procStateSeq: " + procStateSeq); 24185 } 24186 record.networkStateLock.notifyAll(); 24187 } 24188 } 24189 } 24190 24191 /** 24192 * Called after virtual display Id is updated by 24193 * {@link com.android.server.vr.Vr2dDisplay} with a specific 24194 * {@param vrVr2dDisplayId}. 24195 */ 24196 @Override 24197 public void setVr2dDisplayId(int vr2dDisplayId) { 24198 if (DEBUG_STACK) { 24199 Slog.d(TAG, "setVr2dDisplayId called for: " + 24200 vr2dDisplayId); 24201 } 24202 synchronized (ActivityManagerService.this) { 24203 mVr2dDisplayId = vr2dDisplayId; 24204 } 24205 } 24206 24207 @Override 24208 public void saveANRState(String reason) { 24209 synchronized (ActivityManagerService.this) { 24210 final StringWriter sw = new StringWriter(); 24211 final PrintWriter pw = new FastPrintWriter(sw, false, 1024); 24212 pw.println(" ANR time: " + DateFormat.getDateTimeInstance().format(new Date())); 24213 if (reason != null) { 24214 pw.println(" Reason: " + reason); 24215 } 24216 pw.println(); 24217 mActivityStarter.dump(pw, " ", null); 24218 pw.println(); 24219 pw.println("-------------------------------------------------------------------------------"); 24220 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */, 24221 true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */, 24222 "" /* header */); 24223 pw.println(); 24224 pw.close(); 24225 24226 mLastANRState = sw.toString(); 24227 } 24228 } 24229 24230 @Override 24231 public void clearSavedANRState() { 24232 synchronized (ActivityManagerService.this) { 24233 mLastANRState = null; 24234 } 24235 } 24236 24237 @Override 24238 public void setFocusedActivity(IBinder token) { 24239 synchronized (ActivityManagerService.this) { 24240 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 24241 if (r == null) { 24242 throw new IllegalArgumentException( 24243 "setFocusedActivity: No activity record matching token=" + token); 24244 } 24245 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked( 24246 r, "setFocusedActivity")) { 24247 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 24248 } 24249 } 24250 } 24251 } 24252 24253 /** 24254 * Called by app main thread to wait for the network policy rules to get updated. 24255 * 24256 * @param procStateSeq The sequence number indicating the process state change that the main 24257 * thread is interested in. 24258 */ 24259 @Override 24260 public void waitForNetworkStateUpdate(long procStateSeq) { 24261 final int callingUid = Binder.getCallingUid(); 24262 if (DEBUG_NETWORK) { 24263 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq); 24264 } 24265 UidRecord record; 24266 synchronized (this) { 24267 record = mActiveUids.get(callingUid); 24268 if (record == null) { 24269 return; 24270 } 24271 } 24272 synchronized (record.networkStateLock) { 24273 if (record.lastDispatchedProcStateSeq < procStateSeq) { 24274 if (DEBUG_NETWORK) { 24275 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not " 24276 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid 24277 + " lastProcStateSeqDispatchedToObservers: " 24278 + record.lastDispatchedProcStateSeq); 24279 } 24280 return; 24281 } 24282 if (record.curProcStateSeq > procStateSeq) { 24283 if (DEBUG_NETWORK) { 24284 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: " 24285 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq 24286 + ", procStateSeq: " + procStateSeq); 24287 } 24288 return; 24289 } 24290 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) { 24291 if (DEBUG_NETWORK) { 24292 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. " 24293 + procStateSeq + ", so no need to wait. Uid: " 24294 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: " 24295 + record.lastNetworkUpdatedProcStateSeq); 24296 } 24297 return; 24298 } 24299 try { 24300 if (DEBUG_NETWORK) { 24301 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update." 24302 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq); 24303 } 24304 final long startTime = SystemClock.uptimeMillis(); 24305 record.waitingForNetwork = true; 24306 record.networkStateLock.wait(mWaitForNetworkTimeoutMs); 24307 record.waitingForNetwork = false; 24308 final long totalTime = SystemClock.uptimeMillis() - startTime; 24309 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) { 24310 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: " 24311 + totalTime + ". Uid: " + callingUid + " procStateSeq: " 24312 + procStateSeq + " UidRec: " + record 24313 + " validateUidRec: " + mValidateUids.get(callingUid)); 24314 } 24315 } catch (InterruptedException e) { 24316 Thread.currentThread().interrupt(); 24317 } 24318 } 24319 } 24320 24321 public void waitForBroadcastIdle(PrintWriter pw) { 24322 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()"); 24323 while (true) { 24324 boolean idle = true; 24325 synchronized (this) { 24326 for (BroadcastQueue queue : mBroadcastQueues) { 24327 if (!queue.isIdle()) { 24328 final String msg = "Waiting for queue " + queue + " to become idle..."; 24329 pw.println(msg); 24330 pw.flush(); 24331 Slog.v(TAG, msg); 24332 idle = false; 24333 } 24334 } 24335 } 24336 24337 if (idle) { 24338 final String msg = "All broadcast queues are idle!"; 24339 pw.println(msg); 24340 pw.flush(); 24341 Slog.v(TAG, msg); 24342 return; 24343 } else { 24344 SystemClock.sleep(1000); 24345 } 24346 } 24347 } 24348 24349 /** 24350 * Return the user id of the last resumed activity. 24351 */ 24352 @Override 24353 public @UserIdInt int getLastResumedActivityUserId() { 24354 enforceCallingPermission( 24355 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()"); 24356 synchronized (this) { 24357 if (mLastResumedActivity == null) { 24358 return mUserController.getCurrentUserIdLocked(); 24359 } 24360 return mLastResumedActivity.userId; 24361 } 24362 } 24363 24364 /** 24365 * An implementation of IAppTask, that allows an app to manage its own tasks via 24366 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 24367 * only the process that calls getAppTasks() can call the AppTask methods. 24368 */ 24369 class AppTaskImpl extends IAppTask.Stub { 24370 private int mTaskId; 24371 private int mCallingUid; 24372 24373 public AppTaskImpl(int taskId, int callingUid) { 24374 mTaskId = taskId; 24375 mCallingUid = callingUid; 24376 } 24377 24378 private void checkCaller() { 24379 if (mCallingUid != Binder.getCallingUid()) { 24380 throw new SecurityException("Caller " + mCallingUid 24381 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 24382 } 24383 } 24384 24385 @Override 24386 public void finishAndRemoveTask() { 24387 checkCaller(); 24388 24389 synchronized (ActivityManagerService.this) { 24390 long origId = Binder.clearCallingIdentity(); 24391 try { 24392 // We remove the task from recents to preserve backwards 24393 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false, 24394 REMOVE_FROM_RECENTS)) { 24395 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 24396 } 24397 } finally { 24398 Binder.restoreCallingIdentity(origId); 24399 } 24400 } 24401 } 24402 24403 @Override 24404 public ActivityManager.RecentTaskInfo getTaskInfo() { 24405 checkCaller(); 24406 24407 synchronized (ActivityManagerService.this) { 24408 long origId = Binder.clearCallingIdentity(); 24409 try { 24410 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId); 24411 if (tr == null) { 24412 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 24413 } 24414 return createRecentTaskInfoFromTaskRecord(tr); 24415 } finally { 24416 Binder.restoreCallingIdentity(origId); 24417 } 24418 } 24419 } 24420 24421 @Override 24422 public void moveToFront() { 24423 checkCaller(); 24424 // Will bring task to front if it already has a root activity. 24425 final long origId = Binder.clearCallingIdentity(); 24426 try { 24427 synchronized (this) { 24428 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null); 24429 } 24430 } finally { 24431 Binder.restoreCallingIdentity(origId); 24432 } 24433 } 24434 24435 @Override 24436 public int startActivity(IBinder whoThread, String callingPackage, 24437 Intent intent, String resolvedType, Bundle bOptions) { 24438 checkCaller(); 24439 24440 int callingUser = UserHandle.getCallingUserId(); 24441 TaskRecord tr; 24442 IApplicationThread appThread; 24443 synchronized (ActivityManagerService.this) { 24444 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId); 24445 if (tr == null) { 24446 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 24447 } 24448 appThread = IApplicationThread.Stub.asInterface(whoThread); 24449 if (appThread == null) { 24450 throw new IllegalArgumentException("Bad app thread " + appThread); 24451 } 24452 } 24453 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent, 24454 resolvedType, null, null, null, null, 0, 0, null, null, 24455 null, bOptions, false, callingUser, tr, "AppTaskImpl"); 24456 } 24457 24458 @Override 24459 public void setExcludeFromRecents(boolean exclude) { 24460 checkCaller(); 24461 24462 synchronized (ActivityManagerService.this) { 24463 long origId = Binder.clearCallingIdentity(); 24464 try { 24465 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId); 24466 if (tr == null) { 24467 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 24468 } 24469 Intent intent = tr.getBaseIntent(); 24470 if (exclude) { 24471 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 24472 } else { 24473 intent.setFlags(intent.getFlags() 24474 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 24475 } 24476 } finally { 24477 Binder.restoreCallingIdentity(origId); 24478 } 24479 } 24480 } 24481 } 24482 24483 /** 24484 * Kill processes for the user with id userId and that depend on the package named packageName 24485 */ 24486 @Override 24487 public void killPackageDependents(String packageName, int userId) { 24488 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()"); 24489 if (packageName == null) { 24490 throw new NullPointerException( 24491 "Cannot kill the dependents of a package without its name."); 24492 } 24493 24494 long callingId = Binder.clearCallingIdentity(); 24495 IPackageManager pm = AppGlobals.getPackageManager(); 24496 int pkgUid = -1; 24497 try { 24498 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 24499 } catch (RemoteException e) { 24500 } 24501 if (userId != UserHandle.USER_ALL && pkgUid == -1) { 24502 throw new IllegalArgumentException( 24503 "Cannot kill dependents of non-existing package " + packageName); 24504 } 24505 try { 24506 synchronized(this) { 24507 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId, 24508 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false, 24509 "dep: " + packageName); 24510 } 24511 } finally { 24512 Binder.restoreCallingIdentity(callingId); 24513 } 24514 } 24515 24516 @Override 24517 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback) 24518 throws RemoteException { 24519 final long callingId = Binder.clearCallingIdentity(); 24520 try { 24521 mKeyguardController.dismissKeyguard(token, callback); 24522 } finally { 24523 Binder.restoreCallingIdentity(callingId); 24524 } 24525 } 24526 24527 @Override 24528 public int restartUserInBackground(final int userId) { 24529 return mUserController.restartUser(userId, /* foreground */ false); 24530 } 24531 24532 @Override 24533 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) { 24534 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 24535 "scheduleApplicationInfoChanged()"); 24536 24537 synchronized (this) { 24538 final long origId = Binder.clearCallingIdentity(); 24539 try { 24540 updateApplicationInfoLocked(packageNames, userId); 24541 } finally { 24542 Binder.restoreCallingIdentity(origId); 24543 } 24544 } 24545 } 24546 24547 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) { 24548 final boolean updateFrameworkRes = packagesToUpdate.contains("android"); 24549 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 24550 final ProcessRecord app = mLruProcesses.get(i); 24551 if (app.thread == null) { 24552 continue; 24553 } 24554 24555 if (userId != UserHandle.USER_ALL && app.userId != userId) { 24556 continue; 24557 } 24558 24559 final int packageCount = app.pkgList.size(); 24560 for (int j = 0; j < packageCount; j++) { 24561 final String packageName = app.pkgList.keyAt(j); 24562 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) { 24563 try { 24564 final ApplicationInfo ai = AppGlobals.getPackageManager() 24565 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId); 24566 if (ai != null) { 24567 app.thread.scheduleApplicationInfoChanged(ai); 24568 } 24569 } catch (RemoteException e) { 24570 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s", 24571 packageName, app)); 24572 } 24573 } 24574 } 24575 } 24576 } 24577 24578 /** 24579 * Attach an agent to the specified process (proces name or PID) 24580 */ 24581 public void attachAgent(String process, String path) { 24582 try { 24583 synchronized (this) { 24584 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent"); 24585 if (proc == null || proc.thread == null) { 24586 throw new IllegalArgumentException("Unknown process: " + process); 24587 } 24588 24589 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 24590 if (!isDebuggable) { 24591 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 24592 throw new SecurityException("Process not debuggable: " + proc); 24593 } 24594 } 24595 24596 proc.thread.attachAgent(path); 24597 } 24598 } catch (RemoteException e) { 24599 throw new IllegalStateException("Process disappeared"); 24600 } 24601 } 24602 24603 @VisibleForTesting 24604 public static class Injector { 24605 private NetworkManagementInternal mNmi; 24606 24607 public Context getContext() { 24608 return null; 24609 } 24610 24611 public AppOpsService getAppOpsService(File file, Handler handler) { 24612 return new AppOpsService(file, handler); 24613 } 24614 24615 public Handler getUiHandler(ActivityManagerService service) { 24616 return service.new UiHandler(); 24617 } 24618 24619 public boolean isNetworkRestrictedForUid(int uid) { 24620 if (ensureHasNetworkManagementInternal()) { 24621 return mNmi.isNetworkRestrictedForUid(uid); 24622 } 24623 return false; 24624 } 24625 24626 private boolean ensureHasNetworkManagementInternal() { 24627 if (mNmi == null) { 24628 mNmi = LocalServices.getService(NetworkManagementInternal.class); 24629 } 24630 return mNmi != null; 24631 } 24632 } 24633 24634 @Override 24635 public void setShowWhenLocked(IBinder token, boolean showWhenLocked) 24636 throws RemoteException { 24637 synchronized (this) { 24638 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 24639 if (r == null) { 24640 return; 24641 } 24642 final long origId = Binder.clearCallingIdentity(); 24643 try { 24644 r.setShowWhenLocked(showWhenLocked); 24645 } finally { 24646 Binder.restoreCallingIdentity(origId); 24647 } 24648 } 24649 } 24650 24651 @Override 24652 public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException { 24653 synchronized (this) { 24654 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 24655 if (r == null) { 24656 return; 24657 } 24658 final long origId = Binder.clearCallingIdentity(); 24659 try { 24660 r.setTurnScreenOn(turnScreenOn); 24661 } finally { 24662 Binder.restoreCallingIdentity(origId); 24663 } 24664 } 24665 } 24666 } 24667