Merge tag 'android-security-15.0.0_r10' into staging/lineage-22.2_merge-android-security-15.0.0_r10
Android Security 15.0.0 Release 10 (13793697)
# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCaLciswAKCRDorT+BmrEO
# eIteAJ96gVr8EH2JegpLjuR6Q9TFzzcukgCgiLGp/vd6l1MLGg7gV1ipJ4WIooM=
# =sCKm
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue Sep 2 20:00:35 2025 EEST
# gpg: using DSA key 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Good signature from "The Android Open Source Project <initial-contribution@android.com>" [ultimate]
* tag 'android-security-15.0.0_r10':
[RESTRICT AUTOMERGE] Fix audio AppOps refcount mismatch
[RESTRICT AUTOMERGE] Validate full attr chain for recording
Conflicts:
media/utils/ServiceUtilities.cpp
services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
services/audiopolicy/service/AudioRecordClient.cpp
Change-Id: I34851e8fb1a0faea0ba3446f5a4656d3cad29535
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 7fd5be5..81662f1 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -172,9 +172,28 @@
permission::PermissionChecker permissionChecker;
int permitted;
if (start) {
- permitted = permissionChecker.checkPermissionForStartDataDeliveryFromDatasource(
+ // Do a double-check, where we first check without actually starting in order to handle
+ // the behavior of AppOps where ops are sometimes started but paused for SOFT_DENIED.
+ // Since there is no way to maintain reference consensus due to this behavior, avoid
+ // starting an op when a restriction is in place by first checking. In the case where we
+ // startOp would fail, call a noteOp (which will also fail) instead. This preserves
+ // behavior that is reliant on listening to op rejected events (such as the hint
+ // dialogue to unmute the microphone). Technically racy, but very unlikely.
+ //
+ // TODO(b/294609684) To be removed when the pause state for an OP is removed.
+ permitted = permissionChecker.checkPermissionForPreflightFromDatasource(
sAndroidPermissionRecordAudio, resolvedAttributionSource.value(), msg,
attributedOpCode);
+ if (permitted == PERMISSION_GRANTED) {
+ permitted = permissionChecker.checkPermissionForStartDataDeliveryFromDatasource(
+ sAndroidPermissionRecordAudio, resolvedAttributionSource.value(), msg,
+ attributedOpCode);
+ } else {
+ // intentionally don't set permitted
+ permissionChecker.checkPermissionForDataDeliveryFromDatasource(
+ sAndroidPermissionRecordAudio, resolvedAttributionSource.value(), msg,
+ attributedOpCode);
+ }
} else {
permitted = permissionChecker.checkPermissionForPreflightFromDatasource(
sAndroidPermissionRecordAudio, resolvedAttributionSource.value(), msg,
diff --git a/services/audiopolicy/service/AudioRecordClient.cpp b/services/audiopolicy/service/AudioRecordClient.cpp
index 79a7458..aec43ca 100644
--- a/services/audiopolicy/service/AudioRecordClient.cpp
+++ b/services/audiopolicy/service/AudioRecordClient.cpp
@@ -50,7 +50,7 @@
if (pm != nullptr) {
const auto status = pm->getTargetSdkVersionForPackage(
String16{packageName.data(), packageName.size()}, &targetSdk);
- return status.isOk() ? targetSdk : -1;
+ return status.isOk() ? targetSdk : __ANDROID_API_FUTURE__;
}
}
return targetSdk;