Merge "Creates a flag for the Braille Display HID APIs." into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index c477a75..9e30843 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -180,6 +180,12 @@
],
}
+cc_aconfig_library {
+ name: "android_location_flags_c_lib",
+ vendor_available: true,
+ aconfig_declarations: "android.location.flags-aconfig",
+}
+
java_aconfig_library {
name: "android.location.flags-aconfig-java",
aconfig_declarations: "android.location.flags-aconfig",
@@ -256,7 +262,6 @@
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
-
// OS
aconfig_declarations {
name: "android.os.flags-aconfig",
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 183b9b0..7c52238 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -6971,16 +6971,21 @@
public static final int FLAG_DEBUG_LOG_RESOLUTION = 0x00000008;
/**
* If set, this intent will not match any components in packages that
- * are currently stopped. If this is not set, then the default behavior
- * is to include such applications in the result.
+ * are currently
+ * {@linkplain android.content.pm.ApplicationInfo#FLAG_STOPPED stopped}.
+ * If this is not set, then the default behavior is to include such
+ * applications in the result.
*/
public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 0x00000010;
/**
* If set, this intent will always match any components in packages that
- * are currently stopped. This is the default behavior when
+ * are currently
+ * {@linkplain android.content.pm.ApplicationInfo#FLAG_STOPPED stopped}.
+ * This is the default behavior when
* {@link #FLAG_EXCLUDE_STOPPED_PACKAGES} is not set. If both of these
* flags are set, this one wins (it allows overriding of exclude for
- * places where the framework may automatically set the exclude flag).
+ * places where the framework may automatically set the exclude flag,
+ * such as broadcasts).
*/
public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 0x00000020;
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 3713380..869c621 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -375,6 +375,19 @@
/**
* Value for {@link #flags}: true if this application's package is in
* the stopped state.
+ *
+ * <p>Stopped is the initial state after an app is installed, before it is launched
+ * or otherwise directly interacted with by the user. The system tries not to
+ * start it unless initiated by a user interaction (typically launching its icon
+ * from the launcher, could also include user actions like adding it as an app widget,
+ * selecting it as a live wallpaper, selecting it as a keyboard, etc). Stopped
+ * applications will not receive broadcasts unless the sender specifies
+ * {@link android.content.Intent#FLAG_INCLUDE_STOPPED_PACKAGES}.
+ *
+ * <p>Applications should avoid launching activies, binding to or starting services, or
+ * otherwise causing a stopped application to run unless initiated by the user.
+ *
+ * <p>An app can also return to the stopped state by a "force stop".
*/
public static final int FLAG_STOPPED = 1<<21;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 8151a91..0fb0993 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -11024,7 +11024,7 @@
}
/**
- * Returns the property defined in the given package's <appliction> tag.
+ * Returns the property defined in the given package's <application> tag.
*
* @throws NameNotFoundException if either the given package is not installed or if the
* given property is not defined within the <application> tag.
diff --git a/location/java/android/location/flags/gnss.aconfig b/location/java/android/location/flags/gnss.aconfig
index 794a555..5f1279e 100644
--- a/location/java/android/location/flags/gnss.aconfig
+++ b/location/java/android/location/flags/gnss.aconfig
@@ -41,3 +41,10 @@
description: "Flag for GNSS configuration from resource"
bug: "317734846"
}
+
+flag {
+ name: "replace_future_elapsed_realtime_jni"
+ namespace: "location"
+ description: "Flag for replacing future elapsedRealtime in JNI"
+ bug: "314328533"
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
index ddaa488..449ee6f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
@@ -42,6 +42,7 @@
import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
+import java.util.Optional
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOf
@@ -63,6 +64,8 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
+ @Mock private lateinit var appWidgetManagerOptional: Optional<AppWidgetManager>
+
@Mock private lateinit var appWidgetManager: AppWidgetManager
@Mock private lateinit var appWidgetHost: AppWidgetHost
@@ -113,6 +116,8 @@
whenever(stopwatchProviderInfo.loadLabel(any())).thenReturn("Stopwatch")
whenever(userTracker.userHandle).thenReturn(userHandle)
whenever(communalWidgetDao.getWidgets()).thenReturn(flowOf(emptyMap()))
+ whenever(appWidgetManagerOptional.isPresent).thenReturn(true)
+ whenever(appWidgetManagerOptional.get()).thenReturn(appWidgetManager)
}
@Test
@@ -296,7 +301,7 @@
private fun initCommunalWidgetRepository(): CommunalWidgetRepositoryImpl {
return CommunalWidgetRepositoryImpl(
- appWidgetManager,
+ appWidgetManagerOptional,
appWidgetHost,
testScope.backgroundScope,
testDispatcher,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index 90e4a38..7b8cb82 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -77,6 +77,13 @@
applicationScope: CoroutineScope,
vibratorHelper: VibratorHelper,
): Spaghetti {
+ /**
+ * View is only set visible in BiometricViewSizeBinder once PromptSize is determined that
+ * accounts for iconView size, to prevent prompt resizing being visible to the user.
+ *
+ * TODO(b/288175072): May be able to remove this once constraint layout is implemented
+ */
+ view.visibility = View.INVISIBLE
val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!!
val textColorError =
@@ -102,7 +109,7 @@
iconView,
iconOverlayView,
view.getUpdatedFingerprintAffordanceSize(),
- viewModel.iconViewModel
+ viewModel
)
val indicatorMessageView = view.requireViewById<TextView>(R.id.indicator)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
index 7e16d1e..1a7b6c9 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
@@ -30,7 +30,6 @@
import androidx.core.view.doOnLayout
import androidx.core.view.isGone
import androidx.lifecycle.lifecycleScope
-import com.android.systemui.res.R
import com.android.systemui.biometrics.AuthPanelController
import com.android.systemui.biometrics.Utils
import com.android.systemui.biometrics.ui.BiometricPromptLayout
@@ -41,6 +40,8 @@
import com.android.systemui.biometrics.ui.viewmodel.isNullOrNotSmall
import com.android.systemui.biometrics.ui.viewmodel.isSmall
import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.res.R
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
/** Helper for [BiometricViewBinder] to handle resize transitions. */
@@ -93,7 +94,20 @@
view.repeatWhenAttached {
var currentSize: PromptSize? = null
lifecycleScope.launch {
- viewModel.size.collect { size ->
+ /**
+ * View is only set visible in BiometricViewSizeBinder once PromptSize is
+ * determined that accounts for iconView size, to prevent prompt resizing being
+ * visible to the user.
+ *
+ * TODO(b/288175072): May be able to remove isIconViewLoaded once constraint
+ * layout is implemented
+ */
+ combine(viewModel.isIconViewLoaded, viewModel.size, ::Pair).collect {
+ (isIconViewLoaded, size) ->
+ if (!isIconViewLoaded) {
+ return@collect
+ }
+
// prepare for animated size transitions
for (v in viewsToHideWhenSmall) {
v.showTextOrHide(forceHide = size.isSmall)
@@ -198,6 +212,8 @@
}
currentSize = size
+ view.visibility = View.VISIBLE
+ viewModel.setIsIconViewLoaded(false)
notifyAccessibilityChanged()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
index 475ef18..6e3bcf5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
@@ -26,6 +26,7 @@
import com.android.settingslib.widget.LottieColorUtils
import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel
import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel.AuthType
+import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.util.kotlin.Utils.Companion.toQuad
import com.android.systemui.util.kotlin.Utils.Companion.toQuint
@@ -45,8 +46,9 @@
iconView: LottieAnimationView,
iconOverlayView: LottieAnimationView,
iconViewLayoutParamSizeOverride: Pair<Int, Int>?,
- viewModel: PromptIconViewModel
+ promptViewModel: PromptViewModel
) {
+ val viewModel = promptViewModel.iconViewModel
iconView.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.onConfigurationChanged(iconView.context.resources.configuration)
@@ -71,25 +73,45 @@
}
launch {
+ var width: Int
+ var height: Int
viewModel.activeAuthType.collect { activeAuthType ->
- if (iconViewLayoutParamSizeOverride == null) {
- val width: Int
- val height: Int
- when (activeAuthType) {
- AuthType.Fingerprint,
- AuthType.Coex -> {
- width = viewModel.fingerprintIconWidth
- height = viewModel.fingerprintIconHeight
- }
- AuthType.Face -> {
- width = viewModel.faceIconWidth
- height = viewModel.faceIconHeight
+ when (activeAuthType) {
+ AuthType.Fingerprint,
+ AuthType.Coex -> {
+ width = viewModel.fingerprintIconWidth
+ height = viewModel.fingerprintIconHeight
+
+ /**
+ * View is only set visible in BiometricViewSizeBinder once
+ * PromptSize is determined that accounts for iconView size, to
+ * prevent prompt resizing being visible to the user.
+ *
+ * TODO(b/288175072): May be able to remove this once constraint
+ * layout is implemented
+ */
+ iconView.removeAllLottieOnCompositionLoadedListener()
+ iconView.addLottieOnCompositionLoadedListener {
+ promptViewModel.setIsIconViewLoaded(true)
}
}
+ AuthType.Face -> {
+ width = viewModel.faceIconWidth
+ height = viewModel.faceIconHeight
+ /**
+ * Set to true by default since face icon is a drawable, which
+ * doesn't have a LottieOnCompositionLoadedListener equivalent.
+ *
+ * TODO(b/318569643): To be updated once face assets are updated
+ * from drawables
+ */
+ promptViewModel.setIsIconViewLoaded(true)
+ }
+ }
+ if (iconViewLayoutParamSizeOverride == null) {
iconView.layoutParams.width = width
iconView.layoutParams.height = height
-
iconOverlayView.layoutParams.width = width
iconOverlayView.layoutParams.height = height
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index 6d0a58e..d899827e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -192,6 +192,28 @@
val iconViewModel: PromptIconViewModel =
PromptIconViewModel(this, displayStateInteractor, promptSelectorInteractor)
+ private val _isIconViewLoaded = MutableStateFlow(false)
+
+ /**
+ * For prompts with an iconView, false until the prompt's iconView animation has been loaded in
+ * the view, otherwise true by default. Used for BiometricViewSizeBinder to wait for the icon
+ * asset to be loaded before determining the prompt size.
+ */
+ val isIconViewLoaded: Flow<Boolean> =
+ combine(credentialKind, _isIconViewLoaded.asStateFlow()) { credentialKind, isIconViewLoaded
+ ->
+ if (credentialKind is PromptKind.Biometric) {
+ isIconViewLoaded
+ } else {
+ true
+ }
+ }
+
+ // Sets whether the prompt's iconView animation has been loaded in the view yet.
+ fun setIsIconViewLoaded(iconViewLoaded: Boolean) {
+ _isIconViewLoaded.value = iconViewLoaded
+ }
+
/** Padding for prompt UI elements */
val promptPadding: Flow<Rect> =
combine(size, displayStateInteractor.currentRotation) { size, rotation ->
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt
index d1bbe57..cab8adf 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepository.kt
@@ -38,6 +38,7 @@
import com.android.systemui.log.core.Logger
import com.android.systemui.log.dagger.CommunalLog
import com.android.systemui.settings.UserTracker
+import java.util.Optional
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
@@ -75,7 +76,7 @@
class CommunalWidgetRepositoryImpl
@Inject
constructor(
- private val appWidgetManager: AppWidgetManager,
+ private val appWidgetManager: Optional<AppWidgetManager>,
private val appWidgetHost: AppWidgetHost,
@Application private val applicationScope: CoroutineScope,
@Background private val bgDispatcher: CoroutineDispatcher,
@@ -144,7 +145,7 @@
override val communalWidgets: Flow<List<CommunalWidgetContentModel>> =
isHostActive.flatMapLatest { isHostActive ->
- if (!isHostActive) {
+ if (!isHostActive || !appWidgetManager.isPresent) {
return@flatMapLatest flowOf(emptyList())
}
communalWidgetDao.getWidgets().map { it.map(::mapToContentModel) }
@@ -187,7 +188,7 @@
val (_, widgetId) = entry.value
return CommunalWidgetContentModel(
appWidgetId = widgetId,
- providerInfo = appWidgetManager.getAppWidgetInfo(widgetId),
+ providerInfo = appWidgetManager.get().getAppWidgetInfo(widgetId),
priority = entry.key.rank,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryModule.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryModule.kt
index 5793f10..d0d9e3f 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryModule.kt
@@ -31,6 +31,7 @@
import dagger.Binds
import dagger.Module
import dagger.Provides
+import java.util.Optional
import javax.inject.Named
@Module
@@ -41,8 +42,8 @@
@SysUISingleton
@Provides
- fun provideAppWidgetManager(@Application context: Context): AppWidgetManager {
- return AppWidgetManager.getInstance(context)
+ fun provideAppWidgetManager(@Application context: Context): Optional<AppWidgetManager> {
+ return Optional.ofNullable(AppWidgetManager.getInstance(context))
}
@SysUISingleton
@@ -54,7 +55,7 @@
@SysUISingleton
@Provides
fun provideCommunalWidgetHost(
- appWidgetManager: AppWidgetManager,
+ appWidgetManager: Optional<AppWidgetManager>,
appWidgetHost: AppWidgetHost,
@CommunalLog logBuffer: LogBuffer,
): CommunalWidgetHost {
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/CommunalWidgetHost.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/CommunalWidgetHost.kt
index 086d729..155de32 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/CommunalWidgetHost.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/CommunalWidgetHost.kt
@@ -22,6 +22,7 @@
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.Logger
import com.android.systemui.log.dagger.CommunalLog
+import java.util.Optional
import javax.inject.Inject
/**
@@ -31,7 +32,7 @@
class CommunalWidgetHost
@Inject
constructor(
- private val appWidgetManager: AppWidgetManager,
+ private val appWidgetManager: Optional<AppWidgetManager>,
private val appWidgetHost: AppWidgetHost,
@CommunalLog logBuffer: LogBuffer,
) {
@@ -56,6 +57,10 @@
return null
}
- private fun bindWidget(widgetId: Int, provider: ComponentName): Boolean =
- appWidgetManager.bindAppWidgetIdIfAllowed(widgetId, provider)
+ private fun bindWidget(widgetId: Int, provider: ComponentName): Boolean {
+ if (appWidgetManager.isPresent) {
+ return appWidgetManager.get().bindAppWidgetIdIfAllowed(widgetId, provider)
+ }
+ return false
+ }
}
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index b7feca5..e7e721b 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -162,7 +162,6 @@
"pdf_viewer",
"pixel_audio_android",
"pixel_bluetooth",
- "pixel_system_sw_touch",
"pixel_system_sw_video",
"pixel_watch",
"platform_security",
@@ -175,6 +174,7 @@
"safety_center",
"sensors",
"system_performance",
+ "system_sw_touch",
"system_sw_usb",
"test_suites",
"text",
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 203ac2c..df8d9e1 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -2906,7 +2906,13 @@
// TODO(b/302609140): Remove extra logging after this issue is diagnosed.
if (code == OP_BLUETOOTH_CONNECT) {
Slog.e(TAG, "noting OP_BLUETOOTH_CONNECT returned MODE_ERRORED as"
- + " #getOpsLocked returned null");
+ + " #getOpsLocked returned null for"
+ + " uid: " + uid
+ + " packageName: " + packageName
+ + " attributionTag: " + attributionTag
+ + " pvr.isAttributionTagValid: " + pvr.isAttributionTagValid
+ + " pvr.bypass: " + pvr.bypass);
+ Slog.e(TAG, "mUidStates.get(" + uid + "): " + mUidStates.get(uid));
}
return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag,
packageName);
diff --git a/services/core/java/com/android/server/pm/BroadcastHelper.java b/services/core/java/com/android/server/pm/BroadcastHelper.java
index e830d28..e984e9c 100644
--- a/services/core/java/com/android/server/pm/BroadcastHelper.java
+++ b/services/core/java/com/android/server/pm/BroadcastHelper.java
@@ -262,6 +262,7 @@
// Deliver LOCKED_BOOT_COMPLETED first
Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
.setPackage(packageName);
+ lockedBcIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
if (includeStopped) {
lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
}
@@ -275,6 +276,7 @@
// Deliver BOOT_COMPLETED only if user is unlocked
if (mUmInternal.isUserUnlockingOrUnlocked(userId)) {
Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
+ bcIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
if (includeStopped) {
bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
}
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index c920ca8..588c629 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -487,7 +487,7 @@
// Do not uninstall the APK if an app should be cached
boolean keepUninstalledPackage =
mPm.shouldKeepUninstalledPackageLPr(packageName);
- if (ps.isInstalledOrHasDataOnAnyOtherUser(
+ if (ps.isInstalledOnAnyOtherUser(
mUserManagerInternal.getUserIds(), userId) || keepUninstalledPackage) {
// Other users still have this package installed, so all
// we need to do is clear this user's data and save that
@@ -533,7 +533,7 @@
// artifacts are not stored in the same directory as the APKs
deleteArtDexoptArtifacts(packageName);
}
- deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
+ deleteInstalledPackageLIF(ps, userId, deleteCodeAndResources, flags, allUserHandles,
outInfo, writeSettings);
}
@@ -554,7 +554,7 @@
}
@GuardedBy("mPm.mInstallLock")
- private void deleteInstalledPackageLIF(PackageSetting ps,
+ private void deleteInstalledPackageLIF(PackageSetting ps, int userId,
boolean deleteCodeAndResources, int flags, @NonNull int[] allUserHandles,
@NonNull PackageRemovedInfo outInfo, boolean writeSettings) {
synchronized (mPm.mLock) {
@@ -567,7 +567,7 @@
// Delete package data from internal structures and also remove data if flag is set
mRemovePackageHelper.removePackageDataLIF(
- ps, allUserHandles, outInfo, flags, writeSettings);
+ ps, userId, allUserHandles, outInfo, flags, writeSettings);
// Delete application code and resources only for parent packages
if (deleteCodeAndResources) {
@@ -677,8 +677,8 @@
flags |= PackageManager.DELETE_KEEP_DATA;
}
synchronized (mPm.mInstallLock) {
- deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, outInfo,
- writeSettings);
+ deleteInstalledPackageLIF(deletedPs, UserHandle.USER_ALL, true, flags, allUserHandles,
+ outInfo, writeSettings);
}
}
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 1b5e789..992d8eb 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -4590,7 +4590,9 @@
private void assertPackageWithSharedUserIdIsPrivileged(AndroidPackage pkg)
throws PackageManagerException {
- if (!AndroidPackageLegacyUtils.isPrivileged(pkg) && (pkg.getSharedUserId() != null)) {
+ if (!AndroidPackageLegacyUtils.isPrivileged(pkg)
+ && (pkg.getSharedUserId() != null)
+ && !pkg.isLeavingSharedUser()) {
SharedUserSetting sharedUserSetting = null;
try {
synchronized (mPm.mLock) {
@@ -4630,7 +4632,8 @@
if (((scanFlags & SCAN_AS_PRIVILEGED) == 0)
&& !AndroidPackageLegacyUtils.isPrivileged(pkg)
&& (pkg.getSharedUserId() != null)
- && !skipVendorPrivilegeScan) {
+ && !skipVendorPrivilegeScan
+ && !pkg.isLeavingSharedUser()) {
SharedUserSetting sharedUserSetting = null;
synchronized (mPm.mLock) {
try {
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 02ce159..45fc49a 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -825,7 +825,7 @@
return changed;
}
- boolean isInstalledOrHasDataOnAnyOtherUser(int[] allUsers, int currentUser) {
+ boolean isInstalledOnAnyOtherUser(int[] allUsers, int currentUser) {
for (int user: allUsers) {
if (user == currentUser) {
continue;
@@ -834,6 +834,16 @@
if (userState.isInstalled()) {
return true;
}
+ }
+ return false;
+ }
+
+ boolean hasDataOnAnyOtherUser(int[] allUsers, int currentUser) {
+ for (int user: allUsers) {
+ if (user == currentUser) {
+ continue;
+ }
+ final PackageUserStateInternal userState = readUserState(user);
if (userState.dataExists()) {
return true;
}
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index 2854453..02e28dd 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -355,16 +355,22 @@
// Called to clean up disabled system packages
public void removePackageData(final PackageSetting deletedPs, @NonNull int[] allUserHandles) {
synchronized (mPm.mInstallLock) {
- removePackageDataLIF(deletedPs, allUserHandles, new PackageRemovedInfo(),
- /* flags= */ 0, /* writeSettings= */ false);
+ removePackageDataLIF(deletedPs, UserHandle.USER_ALL, allUserHandles,
+ new PackageRemovedInfo(), /* flags= */ 0, /* writeSettings= */ false);
}
}
- /*
+ /**
* This method deletes the package from internal data structures such as mPackages / mSettings.
+ *
+ * @param targetUserId indicates the target user of the deletion. It equals to
+ * {@link UserHandle.USER_ALL} if the deletion was initiated for all users,
+ * otherwise it equals to the specific user id that the deletion was meant
+ * for.
*/
@GuardedBy("mPm.mInstallLock")
- public void removePackageDataLIF(final PackageSetting deletedPs, @NonNull int[] allUserHandles,
+ public void removePackageDataLIF(final PackageSetting deletedPs, int targetUserId,
+ @NonNull int[] allUserHandles,
@NonNull PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
String packageName = deletedPs.getPackageName();
if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + deletedPs);
@@ -372,7 +378,7 @@
final AndroidPackage deletedPkg = deletedPs.getPkg();
// Delete all the data and states related to this package.
- clearPackageStateForUserLIF(deletedPs, UserHandle.USER_ALL, flags);
+ clearPackageStateForUserLIF(deletedPs, targetUserId, flags);
// Delete from mPackages
removePackageLI(packageName, (flags & PackageManager.DELETE_CHATTY) != 0);
@@ -384,7 +390,7 @@
deletedPs.setPkg(null);
}
- if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
+ if (shouldDeletePackageSetting(deletedPs, targetUserId, allUserHandles, flags)) {
// Delete from mSettings
final SparseBooleanArray changedUsers = new SparseBooleanArray();
synchronized (mPm.mLock) {
@@ -457,6 +463,25 @@
}
}
+ private static boolean shouldDeletePackageSetting(PackageSetting deletedPs, int userId,
+ int[] allUserHandles, int flags) {
+ if ((flags & PackageManager.DELETE_KEEP_DATA) != 0) {
+ return false;
+ }
+ if (userId == UserHandle.USER_ALL) {
+ // Deleting for ALL. Let's wipe the PackageSetting.
+ return true;
+ }
+ if (deletedPs.hasDataOnAnyOtherUser(allUserHandles, userId)) {
+ // We arrived here because we are uninstalling the package for a specified user, and the
+ // package isn't installed on any other user. Before we proceed to completely delete the
+ // PackageSetting from mSettings, let's first check if data exists on any other user.
+ // If so, do not wipe the PackageSetting.
+ return false;
+ }
+ return true;
+ }
+
void cleanUpResources(@Nullable String packageName, @Nullable File codeFile,
@Nullable String[] instructionSets) {
synchronized (mPm.mInstallLock) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index d683855..5d710d2 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1405,7 +1405,9 @@
case AppOpsManager.MODE_ERRORED: {
if (permission.equals(Manifest.permission.BLUETOOTH_CONNECT)) {
Slog.e(LOG_TAG, "BLUETOOTH_CONNECT permission hard denied as op"
- + " mode is MODE_ERRORED for " + attributionSource);
+ + " mode is MODE_ERRORED. Permission check was requested for: "
+ + attributionSource + " and op transaction was invoked for "
+ + current);
}
return PermissionChecker.PERMISSION_HARD_DENIED;
}
diff --git a/services/core/jni/gnss/Android.bp b/services/core/jni/gnss/Android.bp
index f3ba484f62..e72259f 100644
--- a/services/core/jni/gnss/Android.bp
+++ b/services/core/jni/gnss/Android.bp
@@ -68,5 +68,6 @@
"android.hardware.gnss@2.1",
"android.hardware.gnss.measurement_corrections@1.0",
"android.hardware.gnss.visibility_control@1.0",
+ "android_location_flags_c_lib",
],
}
diff --git a/services/core/jni/gnss/Utils.cpp b/services/core/jni/gnss/Utils.cpp
index 571534f..274e3b7 100644
--- a/services/core/jni/gnss/Utils.cpp
+++ b/services/core/jni/gnss/Utils.cpp
@@ -20,6 +20,7 @@
#include <android/hardware/gnss/1.0/IGnss.h>
#include <android/hardware/gnss/2.0/IGnss.h>
+#include <android_location_flags.h>
#include <utils/SystemClock.h>
/*
* Save a pointer to JavaVm to attach/detach threads executing
@@ -27,6 +28,8 @@
*/
JavaVM* android::ScopedJniThreadAttach::sJvm;
+namespace location_flags = android::location::flags;
+
namespace android {
namespace {
@@ -194,7 +197,12 @@
flags = static_cast<uint32_t>(location.elapsedRealtime.flags);
if (flags & android::hardware::gnss::ElapsedRealtime::HAS_TIMESTAMP_NS) {
- SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
+ if (location_flags::replace_future_elapsed_realtime_jni() &&
+ location.elapsedRealtime.timestampNs > android::elapsedRealtimeNano()) {
+ SET(ElapsedRealtimeNanos, android::elapsedRealtimeNano());
+ } else {
+ SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
+ }
} else {
SET(ElapsedRealtimeNanos, android::elapsedRealtimeNano());
}