Merge "Camera: Correct the U/V plane selection for HEIC streams" into main am: ab7efbbba0 am: b308a7889d
Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/3151316
Change-Id: Ia1b3c5e09d01317f7937f27d1dae3ce7cdbdc4e8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/aidl/com/android/media/permission/PermissionEnum.aidl b/aidl/com/android/media/permission/PermissionEnum.aidl
index 834a275..b08db44 100644
--- a/aidl/com/android/media/permission/PermissionEnum.aidl
+++ b/aidl/com/android/media/permission/PermissionEnum.aidl
@@ -21,11 +21,21 @@
* {@hide}
*/
enum PermissionEnum {
- MODIFY_AUDIO_ROUTING = 0,
- MODIFY_PHONE_STATE = 1,
- CALL_AUDIO_INTERCEPTION = 2,
// This is a runtime + WIU permission, which means data delivery should be protected by AppOps
// We query the controller only for early fails/hard errors
- RECORD_AUDIO = 3,
- ENUM_SIZE = 4, // Not for actual usage
+ RECORD_AUDIO = 0,
+ MODIFY_AUDIO_ROUTING = 1,
+ MODIFY_AUDIO_SETTINGS = 2,
+ MODIFY_PHONE_STATE = 3,
+ MODIFY_DEFAULT_AUDIO_EFFECTS = 4,
+ WRITE_SECURE_SETTINGS = 5,
+ CALL_AUDIO_INTERCEPTION = 6,
+ ACCESS_ULTRASOUND = 7,
+ CAPTURE_AUDIO_OUTPUT = 8,
+ CAPTURE_MEDIA_OUTPUT = 9,
+ CAPTURE_AUDIO_HOTWORD = 10,
+ CAPTURE_TUNER_AUDIO_INPUT = 11,
+ CAPTURE_VOICE_COMMUNICATION_OUTPUT = 12,
+ BLUETOOTH_CONNECT = 13,
+ ENUM_SIZE = 14, // Not for actual usage, used by Java
}
diff --git a/camera/Android.bp b/camera/Android.bp
index 9e1efae..d91fcb2 100644
--- a/camera/Android.bp
+++ b/camera/Android.bp
@@ -75,6 +75,7 @@
local_include_dirs: ["aidl"],
include_dirs: [
"frameworks/native/aidl/gui",
+ "frameworks/native/libs/permission/aidl",
],
},
@@ -106,6 +107,7 @@
shared_libs: [
"camera_platform_flags_c_lib",
+ "framework-permission-aidl-cpp",
"lib-platform-compat-native-api",
"libbase",
"libbinder",
@@ -114,6 +116,7 @@
"libgui",
"liblog",
"libnativewindow",
+ "libpermission",
"libutils",
],
@@ -126,6 +129,7 @@
"include/camera",
],
export_shared_lib_headers: [
+ "framework-permission-aidl-cpp",
"libcamera_metadata",
"libgui",
"libnativewindow",
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index 8018390..a866dc8 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -70,12 +70,12 @@
}
sp<Camera> Camera::connect(int cameraId, const std::string& clientPackageName,
- int clientUid, int clientPid, int targetSdkVersion, int rotationOverride,
- bool forceSlowJpegMode, int32_t deviceId, int32_t devicePolicy)
+ int targetSdkVersion, int rotationOverride,
+ bool forceSlowJpegMode, const AttributionSourceState& clientAttribution,
+ int32_t devicePolicy)
{
- return CameraBaseT::connect(cameraId, clientPackageName, clientUid,
- clientPid, targetSdkVersion, rotationOverride, forceSlowJpegMode, deviceId,
- devicePolicy);
+ return CameraBaseT::connect(cameraId, clientPackageName, targetSdkVersion, rotationOverride,
+ forceSlowJpegMode, clientAttribution, devicePolicy);
}
status_t Camera::reconnect()
diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp
index d7415a3..b617c65 100644
--- a/camera/CameraBase.cpp
+++ b/camera/CameraBase.cpp
@@ -162,9 +162,10 @@
template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
const std::string& clientPackageName,
- int clientUid, int clientPid, int targetSdkVersion,
- int rotationOverride, bool forceSlowJpegMode,
- int32_t deviceId, int32_t devicePolicy)
+ int targetSdkVersion, int rotationOverride,
+ bool forceSlowJpegMode,
+ const AttributionSourceState& clientAttribution,
+ int32_t devicePolicy)
{
ALOGV("%s: connect", __FUNCTION__);
sp<TCam> c = new TCam(cameraId);
@@ -176,9 +177,9 @@
TCamConnectService fnConnectService = TCamTraits::fnConnectService;
ALOGI("Connect camera (legacy API) - rotationOverride %d, forceSlowJpegMode %d",
rotationOverride, forceSlowJpegMode);
- ret = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
- clientPid, targetSdkVersion, rotationOverride, forceSlowJpegMode, deviceId,
- devicePolicy, /*out*/ &c->mCamera);
+ ret = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, targetSdkVersion,
+ rotationOverride, forceSlowJpegMode, clientAttribution, devicePolicy,
+ /*out*/ &c->mCamera);
}
if (ret.isOk() && c->mCamera != nullptr) {
IInterface::asBinder(c->mCamera)->linkToDeath(c);
@@ -257,7 +258,8 @@
}
template <typename TCam, typename TCamTraits>
-int CameraBase<TCam, TCamTraits>::getNumberOfCameras(int32_t deviceId, int32_t devicePolicy) {
+int CameraBase<TCam, TCamTraits>::getNumberOfCameras(
+ const AttributionSourceState& clientAttribution, int32_t devicePolicy) {
const sp<::android::hardware::ICameraService> cs = getCameraService();
if (!cs.get()) {
@@ -266,7 +268,7 @@
}
int32_t count;
binder::Status res = cs->getNumberOfCameras(
- ::android::hardware::ICameraService::CAMERA_TYPE_BACKWARD_COMPATIBLE, deviceId,
+ ::android::hardware::ICameraService::CAMERA_TYPE_BACKWARD_COMPATIBLE, clientAttribution,
devicePolicy, &count);
if (!res.isOk()) {
ALOGE("Error reading number of cameras: %s",
@@ -279,12 +281,12 @@
// this can be in BaseCamera but it should be an instance method
template <typename TCam, typename TCamTraits>
status_t CameraBase<TCam, TCamTraits>::getCameraInfo(int cameraId,
- int rotationOverride, int32_t deviceId, int32_t devicePolicy,
+ int rotationOverride, const AttributionSourceState& clientAttribution, int32_t devicePolicy,
struct hardware::CameraInfo* cameraInfo) {
const sp<::android::hardware::ICameraService> cs = getCameraService();
if (cs == 0) return UNKNOWN_ERROR;
- binder::Status res = cs->getCameraInfo(cameraId, rotationOverride, deviceId, devicePolicy,
- cameraInfo);
+ binder::Status res = cs->getCameraInfo(cameraId, rotationOverride, clientAttribution,
+ devicePolicy, cameraInfo);
return res.isOk() ? OK : res.serviceSpecificErrorCode();
}
diff --git a/camera/aidl/android/hardware/ICameraService.aidl b/camera/aidl/android/hardware/ICameraService.aidl
index d9a0934..2df1495 100644
--- a/camera/aidl/android/hardware/ICameraService.aidl
+++ b/camera/aidl/android/hardware/ICameraService.aidl
@@ -16,6 +16,7 @@
package android.hardware;
+import android.content.AttributionSourceState;
import android.hardware.ICamera;
import android.hardware.ICameraClient;
import android.hardware.camera2.ICameraDeviceUser;
@@ -66,13 +67,13 @@
*
* @param type The type of the camera, can be either CAMERA_TYPE_BACKWARD_COMPATIBLE
* or CAMERA_TYPE_ALL.
- * @param deviceId The device id of the context associated with the caller.
+ * @param clientAttribution The AttributionSource of the client.
* @param devicePolicy The camera policy of the device of the associated context (default
* policy for default device context). Only virtual cameras would be exposed
* only for custom policy and only real cameras would be exposed for default
* policy.
*/
- int getNumberOfCameras(int type, int deviceId, int devicePolicy);
+ int getNumberOfCameras(int type, in AttributionSourceState clientAttribution, int devicePolicy);
/**
* If changed, reflect in
@@ -97,19 +98,20 @@
* will override the sensor orientation and rotate and crop, while {@link
* ICameraService#ROTATION_OVERRIDE_ROTATION_ONLY} will rotate and crop the camera feed
* without changing the sensor orientation.
- * @param deviceId The device id of the context associated with the caller.
+ * @param clientAttribution The AttributionSource of the client.
* @param devicePolicy The camera policy of the device of the associated context (default
* policy for default device context). Only virtual cameras would be exposed
* only for custom policy and only real cameras would be exposed for default
* policy.
* @return CameraInfo for the camera.
*/
- CameraInfo getCameraInfo(int cameraId, int rotationOverride, int deviceId,
- int devicePolicy);
+ CameraInfo getCameraInfo(int cameraId, int rotationOverride,
+ in AttributionSourceState clientAttribution, int devicePolicy);
/**
- * Default UID/PID values for non-privileged callers of
- * connect() and connectDevice()
+ * Default UID/PID values for non-privileged callers of connect() and connectDevice(). Can be
+ * used to set the pid/uid fields of AttributionSourceState to indicate the calling uid/pid
+ * should be used.
*/
const int USE_CALLING_UID = -1;
const int USE_CALLING_PID = -1;
@@ -119,8 +121,6 @@
*
* @param cameraId The ID of the camera to open.
* @param opPackageName The package name to report for the app-ops.
- * @param clientUid UID for the calling client.
- * @param clientPid PID for the calling client.
* @param targetSdkVersion the target sdk level of the application calling this function.
* @param rotationOverride Whether to override the sensor orientation information to
* correspond to portrait: {@link ICameraService#ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT}
@@ -128,7 +128,7 @@
* ICameraService#ROTATION_OVERRIDE_ROTATION_ONLY} will rotate and crop the camera feed
* without changing the sensor orientation.
* @param forceSlowJpegMode Whether to force slow jpeg mode.
- * @param deviceId The device id of the context associated with the caller.
+ * @param clientAttribution The AttributionSource of the client.
* @param devicePolicy The camera policy of the device of the associated context (default
* policy for default device context). Only virtual cameras would be exposed
* only for custom policy and only real cameras would be exposed for default
@@ -137,11 +137,10 @@
ICamera connect(ICameraClient client,
int cameraId,
@utf8InCpp String opPackageName,
- int clientUid, int clientPid,
int targetSdkVersion,
int rotationOverride,
boolean forceSlowJpegMode,
- int deviceId,
+ in AttributionSourceState clientAttribution,
int devicePolicy);
/**
@@ -150,14 +149,13 @@
*
* @param cameraId The ID of the camera to open.
* @param opPackageName The package name to report for the app-ops.
- * @param clientUid UID for the calling client.
* @param targetSdkVersion the target sdk level of the application calling this function.
* @param rotationOverride Whether to override the sensor orientation information to
* correspond to portrait: {@link ICameraService#ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT}
* will override the sensor orientation and rotate and crop, while {@link
* ICameraService#ROTATION_OVERRIDE_ROTATION_ONLY} will rotate and crop the camera feed
* without changing the sensor orientation.
- * @param deviceId The device id of the context associated with the caller.
+ * @param clientAttribution The AttributionSource of the client.
* @param devicePolicy The camera policy of the device of the associated context (default
* policy for default device context). Only virtual cameras would be exposed
* only for custom policy and only real cameras would be exposed for default
@@ -167,10 +165,10 @@
@utf8InCpp String cameraId,
@utf8InCpp String opPackageName,
@nullable @utf8InCpp String featureId,
- int clientUid, int oomScoreOffset,
+ int oomScoreOffset,
int targetSdkVersion,
int rotationOverride,
- int deviceId,
+ in AttributionSourceState clientAttribution,
int devicePolicy);
/**
@@ -194,7 +192,7 @@
*
* @param sessions the set of camera id and session configuration pairs to be queried.
* @param targetSdkVersion the target sdk level of the application calling this function.
- * @param deviceId The device id of the context associated with the caller.
+ * @param clientAttribution The AttributionSource of the client.
* @param devicePolicy The camera policy of the device of the associated context (default
* policy for default device context). Only virtual cameras would be exposed
* only for custom policy and only real cameras would be exposed for default
@@ -206,7 +204,7 @@
*/
boolean isConcurrentSessionConfigurationSupported(
in CameraIdAndSessionConfiguration[] sessions,
- int targetSdkVersion, int deviceId, int devicePolicy);
+ int targetSdkVersion, in AttributionSourceState clientAttribution, int devicePolicy);
/**
* Inject Session Params into an existing camera session.
@@ -236,7 +234,7 @@
* will override the sensor orientation and rotate and crop, while {@link
* ICameraService#ROTATION_OVERRIDE_ROTATION_ONLY} will rotate and crop the camera feed
* without changing the sensor orientation.
- * @param deviceId The device id of the context associated with the caller.
+ * @param clientAttribution The AttributionSource of the client.
* @param devicePolicy The camera policy of the device of the associated context (default
* policy for default device context). Only virtual cameras would be exposed
* only for custom policy and only real cameras would be exposed for default
@@ -244,7 +242,7 @@
* @return Characteristics for the given camera.
*/
CameraMetadataNative getCameraCharacteristics(@utf8InCpp String cameraId, int targetSdkVersion,
- int rotationOverride, int deviceId, int devicePolicy);
+ int rotationOverride, in AttributionSourceState clientAttribution, int devicePolicy);
/**
* Read in the vendor tag descriptors from the camera module HAL.
@@ -284,14 +282,14 @@
* Set the torch mode for a camera device.
*
* @param cameraId The ID of the camera to set torch mode for.
- * @param deviceId The device id of the context associated with the caller.
+ * @param clientAttribution The AttributionSource of the client.
* @param devicePolicy The camera policy of the device of the associated context (default
* policy for default device context). Only virtual cameras would be exposed
* only for custom policy and only real cameras would be exposed for default
* policy.
*/
void setTorchMode(@utf8InCpp String cameraId, boolean enabled, IBinder clientBinder,
- int deviceId, int devicePolicy);
+ in AttributionSourceState clientAttribution, int devicePolicy);
/**
* Change the brightness level of the flash unit associated with cameraId to strengthLevel.
@@ -299,27 +297,28 @@
*
* @param cameraId The ID of the camera.
* @param strengthLevel The torch strength level to set for the camera.
- * @param deviceId The device id of the context associated with the caller.
+ * @param clientAttribution The AttributionSource of the client.
* @param devicePolicy The camera policy of the device of the associated context (default
* policy for default device context). Only virtual cameras would be exposed
* only for custom policy and only real cameras would be exposed for default
* policy.
*/
void turnOnTorchWithStrengthLevel(@utf8InCpp String cameraId, int strengthLevel,
- IBinder clientBinder, int deviceId, int devicePolicy);
+ IBinder clientBinder, in AttributionSourceState clientAttribution, int devicePolicy);
/**
* Get the brightness level of the flash unit associated with cameraId.
*
* @param cameraId The ID of the camera.
- * @param deviceId The device id of the context associated with the caller.
+ * @param clientAttribution The AttributionSource of the client.
* @param devicePolicy The camera policy of the device of the associated context (default
* policy for default device context). Only virtual cameras would be exposed
* only for custom policy and only real cameras would be exposed for default
* policy.
* @return Torch strength level for the camera.
*/
- int getTorchStrengthLevel(@utf8InCpp String cameraId, int deviceId, int devicePolicy);
+ int getTorchStrengthLevel(@utf8InCpp String cameraId,
+ in AttributionSourceState clientAttribution, int devicePolicy);
/**
* Notify the camera service of a system event. Should only be called from system_server.
@@ -385,7 +384,7 @@
*
* @param cameraId The camera id to create the CaptureRequest for.
* @param templateId The template id create the CaptureRequest for.
- * @param deviceId the device id of the context associated with the caller.
+ * @param clientAttribution The AttributionSource of the client.
* @param devicePolicy The camera policy of the device of the associated context (default
* policy for default device context). Only virtual cameras would be exposed
* only for custom policy and only real cameras would be exposed for default
@@ -393,7 +392,7 @@
* @return Metadata representing the CaptureRequest.
*/
CameraMetadataNative createDefaultRequest(@utf8InCpp String cameraId, int templateId,
- int deviceId, int devicePolicy);
+ in AttributionSourceState clientAttribution, int devicePolicy);
/**
* Check whether a particular session configuration with optional session parameters
@@ -402,7 +401,7 @@
* @param cameraId The camera id to query session configuration for
* @param targetSdkVersion the target sdk level of the application calling this function.
* @param sessionConfiguration Specific session configuration to be verified.
- * @param deviceId The device id of the context associated with the caller.
+ * @param clientAttribution The AttributionSource of the client.
* @param devicePolicy The camera policy of the device of the associated context (default
* policy for default device context). Only virtual cameras would be exposed
* only for custom policy and only real cameras would be exposed for default
@@ -412,7 +411,7 @@
*/
boolean isSessionConfigurationWithParametersSupported(@utf8InCpp String cameraId,
int targetSdkVersion, in SessionConfiguration sessionConfiguration,
- int deviceId, int devicePolicy);
+ in AttributionSourceState clientAttribution, int devicePolicy);
/**
* Get the camera characteristics for a particular session configuration for
@@ -427,7 +426,7 @@
* without changing the sensor orientation.
* @param sessionConfiguration Session configuration for which the characteristics
* must be fetched.
- * @param deviceId The device id of the context associated with the caller.
+ * @param clientAttribution The AttributionSource of the client.
* @param devicePolicy The camera policy of the device of the associated context (default
* policy for default device context). Only virtual cameras would be exposed
* only for custom policy and only real cameras would be exposed for default
@@ -438,6 +437,6 @@
int targetSdkVersion,
int rotationOverride,
in SessionConfiguration sessionConfiguration,
- int deviceId,
+ in AttributionSourceState clientAttribution,
int devicePolicy);
}
diff --git a/camera/include/camera/Camera.h b/camera/include/camera/Camera.h
index 3ecd10d..f533dd8 100644
--- a/camera/include/camera/Camera.h
+++ b/camera/include/camera/Camera.h
@@ -59,7 +59,7 @@
typedef ::android::hardware::ICameraClient TCamCallbacks;
typedef ::android::binder::Status (::android::hardware::ICameraService::*TCamConnectService)
(const sp<::android::hardware::ICameraClient>&,
- int, const std::string&, int, int, int, int, bool, int32_t, int32_t,
+ int, const std::string&, int, int, bool, const AttributionSourceState&, int32_t,
/*out*/
sp<::android::hardware::ICamera>*);
static TCamConnectService fnConnectService;
@@ -82,9 +82,9 @@
static sp<Camera> create(const sp<::android::hardware::ICamera>& camera);
static sp<Camera> connect(int cameraId,
const std::string& clientPackageName,
- int clientUid, int clientPid, int targetSdkVersion,
- int rotationOverride, bool forceSlowJpegMode,
- int32_t deviceId = kDefaultDeviceId, int32_t devicePolicy = 0);
+ int targetSdkVersion, int rotationOverride, bool forceSlowJpegMode,
+ const AttributionSourceState& clientAttribution,
+ int32_t devicePolicy = 0);
virtual ~Camera();
diff --git a/camera/include/camera/CameraBase.h b/camera/include/camera/CameraBase.h
index 3370b3d..aa83362 100644
--- a/camera/include/camera/CameraBase.h
+++ b/camera/include/camera/CameraBase.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_HARDWARE_CAMERA_BASE_H
#define ANDROID_HARDWARE_CAMERA_BASE_H
+#include <android/content/AttributionSourceState.h>
#include <android/hardware/ICameraServiceListener.h>
#include <utils/Mutex.h>
@@ -107,6 +108,7 @@
} // namespace hardware
+using content::AttributionSourceState;
using hardware::CameraInfo;
template <typename TCam>
@@ -124,18 +126,19 @@
static sp<TCam> connect(int cameraId,
const std::string& clientPackageName,
- int clientUid, int clientPid, int targetSdkVersion,
- int rotationOverride, bool forceSlowJpegMode,
- int32_t deviceId, int32_t devicePolicy);
+ int targetSdkVersion, int rotationOverride, bool forceSlowJpegMode,
+ const AttributionSourceState &clientAttribution,
+ int32_t devicePolicy);
virtual void disconnect();
void setListener(const sp<TCamListener>& listener);
- static int getNumberOfCameras(int32_t deviceId, int32_t devicePolicy);
+ static int getNumberOfCameras(const AttributionSourceState& clientAttribution,
+ int32_t devicePolicy);
static status_t getCameraInfo(int cameraId,
int rotationOverride,
- int32_t deviceId,
+ const AttributionSourceState& clientAttribution,
int32_t devicePolicy,
/*out*/
struct hardware::CameraInfo* cameraInfo);
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index a603659..379c0b5 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -79,6 +79,7 @@
shared_libs: [
"android.companion.virtual.virtualdevice_aidl-cpp",
"android.companion.virtualdevice.flags-aconfig-cc",
+ "framework-permission-aidl-cpp",
"libandroid_runtime",
"libbinder",
"libcamera_client",
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index f36a743..6caaa94 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -810,9 +810,15 @@
CameraMetadata rawMetadata;
int targetSdkVersion = android_get_application_target_sdk_version();
+
+ AttributionSourceState clientAttribution;
+ clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
+ clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
+ clientAttribution.deviceId = mDeviceContext.deviceId;
+
binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr,
targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
- mDeviceContext.deviceId, static_cast<int32_t>(mDeviceContext.policy),
+ clientAttribution, static_cast<int32_t>(mDeviceContext.policy),
&rawMetadata);
if (!serviceRet.isOk()) {
switch(serviceRet.serviceSpecificErrorCode()) {
@@ -860,13 +866,18 @@
sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
int targetSdkVersion = android_get_application_target_sdk_version();
+
+ AttributionSourceState clientAttribution;
+ clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
+ clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
+ clientAttribution.deviceId = mDeviceContext.deviceId;
+
// No way to get package name from native.
// Send a zero length package name and let camera service figure it out from UID
binder::Status serviceRet = cs->connectDevice(
- callbacks, cameraId, "", {},
- hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0,
+ callbacks, cameraId, "", {}, /*oomScoreOffset*/0,
targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
- mDeviceContext.deviceId, static_cast<int32_t>(mDeviceContext.policy),
+ clientAttribution, static_cast<int32_t>(mDeviceContext.policy),
/*out*/&deviceRemote);
if (!serviceRet.isOk()) {
diff --git a/camera/tests/Android.bp b/camera/tests/Android.bp
index 9aaac6a..484335a 100644
--- a/camera/tests/Android.bp
+++ b/camera/tests/Android.bp
@@ -29,6 +29,7 @@
"CameraCharacteristicsPermission.cpp",
],
shared_libs: [
+ "framework-permission-aidl-cpp",
"liblog",
"libutils",
"libcutils",
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index e5f99be..e8c2006 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -33,6 +33,7 @@
#include <hardware/gralloc.h>
#include <camera/CameraMetadata.h>
+#include <android/content/AttributionSourceState.h>
#include <android/hardware/ICameraService.h>
#include <android/hardware/ICameraServiceListener.h>
#include <android/hardware/BnCameraServiceListener.h>
@@ -347,7 +348,10 @@
binder::Status res;
int32_t numCameras = 0;
- res = service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_ALL, kDefaultDeviceId,
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
+ clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
+ res = service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_ALL, clientAttribution,
/*devicePolicy*/0, &numCameras);
EXPECT_TRUE(res.isOk()) << res;
EXPECT_LE(0, numCameras);
@@ -360,7 +364,7 @@
EXPECT_EQ(numCameras, static_cast<const int>(statuses.size()));
for (const auto &it : statuses) {
- listener->onStatusChanged(it.status, it.cameraId, kDefaultDeviceId);
+ listener->onStatusChanged(it.status, it.cameraId, clientAttribution.deviceId);
}
for (int32_t i = 0; i < numCameras; i++) {
@@ -379,7 +383,7 @@
CameraMetadata metadata;
res = service->getCameraCharacteristics(cameraId,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false,
- kDefaultDeviceId, /*devicePolicy*/0, &metadata);
+ clientAttribution, /*devicePolicy*/0, &metadata);
EXPECT_TRUE(res.isOk()) << res;
EXPECT_FALSE(metadata.isEmpty());
@@ -394,9 +398,9 @@
sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
sp<hardware::camera2::ICameraDeviceUser> device;
res = service->connectDevice(callbacks, cameraId, "meeeeeeeee!",
- {}, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/ 0,
+ {}, /*oomScoreOffset*/ 0,
/*targetSdkVersion*/__ANDROID_API_FUTURE__,
- /*overrideToPortrait*/false, kDefaultDeviceId, /*devicePolicy*/0, /*out*/&device);
+ /*overrideToPortrait*/false, clientAttribution, /*devicePolicy*/0, /*out*/&device);
EXPECT_TRUE(res.isOk()) << res;
ASSERT_NE(nullptr, device.get());
device->disconnect();
@@ -406,12 +410,12 @@
if (torchStatus == hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF) {
// Check torch calls
res = service->setTorchMode(cameraId,
- /*enabled*/true, callbacks, kDefaultDeviceId, /*devicePolicy*/0);
+ /*enabled*/true, callbacks, clientAttribution, /*devicePolicy*/0);
EXPECT_TRUE(res.isOk()) << res;
EXPECT_TRUE(listener->waitForTorchState(
hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON, i));
res = service->setTorchMode(cameraId,
- /*enabled*/false, callbacks, kDefaultDeviceId, /*devicePolicy*/0);
+ /*enabled*/false, callbacks, clientAttribution, /*devicePolicy*/0);
EXPECT_TRUE(res.isOk()) << res;
EXPECT_TRUE(listener->waitForTorchState(
hardware::ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF, i));
@@ -437,10 +441,13 @@
sp<hardware::camera2::ICameraDeviceUser> device;
{
SCOPED_TRACE("openNewDevice");
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
+ clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
binder::Status res = service->connectDevice(callbacks, deviceId, "meeeeeeeee!",
- {}, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/ 0,
+ {}, /*oomScoreOffset*/ 0,
/*targetSdkVersion*/__ANDROID_API_FUTURE__,
- /*overrideToPortrait*/false, kDefaultDeviceId, /*devicePolicy*/0,
+ /*overrideToPortrait*/false, clientAttribution, /*devicePolicy*/0,
/*out*/&device);
EXPECT_TRUE(res.isOk()) << res;
}
@@ -473,11 +480,13 @@
serviceListener = new TestCameraServiceListener();
std::vector<hardware::CameraStatus> statuses;
service->addListener(serviceListener, &statuses);
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
for (const auto &it : statuses) {
- serviceListener->onStatusChanged(it.status, it.cameraId, kDefaultDeviceId);
+ serviceListener->onStatusChanged(it.status, it.cameraId, clientAttribution.deviceId);
}
service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_BACKWARD_COMPATIBLE,
- kDefaultDeviceId, /*devicePolicy*/0, &numCameras);
+ clientAttribution, /*devicePolicy*/0, &numCameras);
}
virtual void TearDown() {
diff --git a/camera/tests/CameraCharacteristicsPermission.cpp b/camera/tests/CameraCharacteristicsPermission.cpp
index 10f7f22..9204eb1 100644
--- a/camera/tests/CameraCharacteristicsPermission.cpp
+++ b/camera/tests/CameraCharacteristicsPermission.cpp
@@ -19,6 +19,7 @@
#include <gtest/gtest.h>
+#include <android/content/AttributionSourceState.h>
#include <binder/ProcessState.h>
#include <utils/Errors.h>
#include <utils/Log.h>
@@ -47,8 +48,10 @@
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.camera"));
mCameraService = interface_cast<ICameraService>(binder);
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
rc = mCameraService->getNumberOfCameras(
- hardware::ICameraService::CAMERA_TYPE_ALL, kDefaultDeviceId, /*devicePolicy*/0,
+ hardware::ICameraService::CAMERA_TYPE_ALL, clientAttribution, /*devicePolicy*/0,
&numCameras);
EXPECT_TRUE(rc.isOk());
}
@@ -73,9 +76,11 @@
CameraMetadata metadata;
std::vector<int32_t> tagsNeedingPermission;
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
rc = mCameraService->getCameraCharacteristics(cameraIdStr,
/*targetSdkVersion*/__ANDROID_API_FUTURE__,
- /*overrideToPortrait*/false, kDefaultDeviceId, /*devicePolicy*/0, &metadata);
+ /*overrideToPortrait*/false, clientAttribution, /*devicePolicy*/0, &metadata);
ASSERT_TRUE(rc.isOk());
EXPECT_FALSE(metadata.isEmpty());
EXPECT_EQ(metadata.removePermissionEntries(CAMERA_METADATA_INVALID_VENDOR_ID,
diff --git a/camera/tests/CameraZSLTests.cpp b/camera/tests/CameraZSLTests.cpp
index 56fcfa4..b80ad15 100644
--- a/camera/tests/CameraZSLTests.cpp
+++ b/camera/tests/CameraZSLTests.cpp
@@ -19,6 +19,7 @@
#include <gtest/gtest.h>
+#include <android/content/AttributionSourceState.h>
#include <binder/ProcessState.h>
#include <utils/Errors.h>
#include <utils/Log.h>
@@ -84,8 +85,10 @@
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.camera"));
mCameraService = interface_cast<ICameraService>(binder);
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
rc = mCameraService->getNumberOfCameras(
- hardware::ICameraService::CAMERA_TYPE_ALL, kDefaultDeviceId, /*devicePolicy*/0,
+ hardware::ICameraService::CAMERA_TYPE_ALL, clientAttribution, /*devicePolicy*/0,
&numCameras);
EXPECT_TRUE(rc.isOk());
@@ -183,9 +186,11 @@
}
CameraMetadata metadata;
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
rc = mCameraService->getCameraCharacteristics(cameraIdStr,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false,
- kDefaultDeviceId, /*devicePolicy*/0, &metadata);
+ clientAttribution, /*devicePolicy*/0, &metadata);
if (!rc.isOk()) {
// The test is relevant only for cameras with Hal 3.x
// support.
@@ -209,11 +214,11 @@
continue;
}
+ clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
+ clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
rc = mCameraService->connect(this, cameraId,
- "ZSLTest", hardware::ICameraService::USE_CALLING_UID,
- hardware::ICameraService::USE_CALLING_PID,
- /*targetSdkVersion*/__ANDROID_API_FUTURE__,
- /*overrideToPortrait*/false, /*forceSlowJpegMode*/false, kDefaultDeviceId,
+ "ZSLTest", /*targetSdkVersion*/__ANDROID_API_FUTURE__,
+ /*overrideToPortrait*/false, /*forceSlowJpegMode*/false, clientAttribution,
/*devicePolicy*/0, &cameraDevice);
EXPECT_TRUE(rc.isOk());
diff --git a/camera/tests/fuzzer/Android.bp b/camera/tests/fuzzer/Android.bp
index bd97c39..3b6413c 100644
--- a/camera/tests/fuzzer/Android.bp
+++ b/camera/tests/fuzzer/Android.bp
@@ -31,6 +31,7 @@
],
shared_libs: [
"camera_platform_flags_c_lib",
+ "framework-permission-aidl-cpp",
"libbase",
"libcutils",
"libutils",
diff --git a/camera/tests/fuzzer/camera_fuzzer.cpp b/camera/tests/fuzzer/camera_fuzzer.cpp
index b0f59f1..9b6fd49 100644
--- a/camera/tests/fuzzer/camera_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_fuzzer.cpp
@@ -17,6 +17,7 @@
#include <Camera.h>
#include <CameraParameters.h>
#include <CameraUtils.h>
+#include <android/content/AttributionSourceState.h>
#include <binder/MemoryDealer.h>
#include <fuzzer/FuzzedDataProvider.h>
#include <gui/Surface.h>
@@ -123,21 +124,23 @@
sp<ICameraService> cameraService = nullptr;
cameraService = interface_cast<ICameraService>(binder);
sp<ICamera> cameraDevice = nullptr;
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
if (mFDP->ConsumeBool()) {
+ clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
+ clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
cameraService->connect(this, mFDP->ConsumeIntegral<int32_t>() /* cameraId */, "CAMERAFUZZ",
- hardware::ICameraService::USE_CALLING_UID,
- hardware::ICameraService::USE_CALLING_PID,
/*targetSdkVersion*/ __ANDROID_API_FUTURE__,
/*overrideToPortrait*/ false, /*forceSlowJpegMode*/ false,
- kDefaultDeviceId, /*devicePolicy*/0, &cameraDevice);
+ clientAttribution, /*devicePolicy*/0, &cameraDevice);
} else {
+ clientAttribution.uid = mFDP->ConsumeIntegral<int8_t>();
+ clientAttribution.pid = mFDP->ConsumeIntegral<int8_t>();
cameraService->connect(this, mFDP->ConsumeIntegral<int32_t>() /* cameraId */,
mFDP->ConsumeRandomLengthString(kMaxBytes).c_str(),
- mFDP->ConsumeIntegral<int8_t>() /* clientUid */,
- mFDP->ConsumeIntegral<int8_t>() /* clientPid */,
/*targetSdkVersion*/ mFDP->ConsumeIntegral<int32_t>(),
/*overrideToPortrait*/ mFDP->ConsumeBool(),
- /*forceSlowJpegMode*/ mFDP->ConsumeBool(), kDefaultDeviceId,
+ /*forceSlowJpegMode*/ mFDP->ConsumeBool(), clientAttribution,
/*devicePolicy*/0, &cameraDevice);
}
@@ -165,13 +168,15 @@
}
int32_t cameraId = mFDP->ConsumeIntegral<int32_t>();
- Camera::getNumberOfCameras(kDefaultDeviceId, /*devicePolicy*/0);
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
+ Camera::getNumberOfCameras(clientAttribution, /*devicePolicy*/0);
CameraInfo cameraInfo;
cameraInfo.facing = mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidFacing)
: mFDP->ConsumeIntegral<int32_t>();
cameraInfo.orientation = mFDP->ConsumeBool() ? mFDP->PickValueInArray(kValidOrientation)
: mFDP->ConsumeIntegral<int32_t>();
- Camera::getCameraInfo(cameraId, /*overrideToPortrait*/false, kDefaultDeviceId,
+ Camera::getCameraInfo(cameraId, /*overrideToPortrait*/false, clientAttribution,
/*devicePolicy*/0, &cameraInfo);
mCamera->reconnect();
diff --git a/media/audio/aconfig/audioserver.aconfig b/media/audio/aconfig/audioserver.aconfig
index 6f76408..39fa187 100644
--- a/media/audio/aconfig/audioserver.aconfig
+++ b/media/audio/aconfig/audioserver.aconfig
@@ -29,6 +29,14 @@
}
flag {
+ name: "fix_call_audio_patch"
+ namespace: "media_audio"
+ description:
+ "optimize creation and release of audio patches for call routing"
+ bug: "292492229"
+}
+
+flag {
name: "fix_concurrent_playback_behavior_with_bit_perfect_client"
namespace: "media_audio"
description:
diff --git a/media/codec2/hal/common/MultiAccessUnitHelper.cpp b/media/codec2/hal/common/MultiAccessUnitHelper.cpp
index b1fa82f..55bf7a9 100644
--- a/media/codec2/hal/common/MultiAccessUnitHelper.cpp
+++ b/media/codec2/hal/common/MultiAccessUnitHelper.cpp
@@ -497,9 +497,10 @@
// This is to take care of the last bytes and to decide to send with
// FLAG_INCOMPLETE or not.
if ((frame->mWview
- && (frame->mWview->offset() > frame->mLargeFrameTuning.thresholdSize))
+ && (frame->mWview->offset() >= frame->mLargeFrameTuning.thresholdSize))
|| frame->mComponentFrameIds.empty()) {
if (frame->mLargeWork) {
+ frame->mLargeWork->result = C2_OK;
finalizeWork(*frame);
addOutWork(frame->mLargeWork);
frame->reset();
@@ -558,12 +559,15 @@
c2_status_t ret = C2_OK;
if (frame.mLargeWork == nullptr) {
frame.mLargeWork.reset(new C2Work);
+ frame.mLargeWork->result = C2_OK;
+ frame.mLargeWork->input.flags = (C2FrameData::flags_t)0;
frame.mLargeWork->input.ordinal = frame.inOrdinal;
frame.mLargeWork->input.ordinal.frameIndex = frame.inOrdinal.frameIndex;
}
if (allocateWorket) {
if (frame.mLargeWork->worklets.size() == 0) {
frame.mLargeWork->worklets.emplace_back(new C2Worklet);
+ frame.mLargeWork->worklets.back()->output.flags = (C2FrameData::flags_t)0;
}
}
if (allocateBuffer) {
@@ -611,6 +615,9 @@
if (c2ret != C2_OK) {
return c2ret;
}
+ uint32_t flags = work->input.flags;
+ flags |= frame.mLargeWork->input.flags;
+ frame.mLargeWork->input.flags = (C2FrameData::flags_t)flags;
C2FrameData& outputFramedata = frame.mLargeWork->worklets.front()->output;
if (!(*worklet)->output.configUpdate.empty()) {
for (auto& configUpdate : (*worklet)->output.configUpdate) {
@@ -678,6 +685,9 @@
}
}
allocateWork(frame, true, true);
+ uint32_t flags = work->input.flags;
+ flags |= frame.mLargeWork->input.flags;
+ frame.mLargeWork->input.flags = (C2FrameData::flags_t)flags;
C2ReadView rView = blocks.front().map().get();
if (rView.error()) {
LOG(ERROR) << "Buffer read view error";
@@ -744,7 +754,8 @@
}
LOG(DEBUG) << "Finalizing work with input Idx "
<< frame.mLargeWork->input.ordinal.frameIndex.peekull()
- << " timestamp " << timeStampUs;
+ << " timestamp " << timeStampUs
+ << " inFlags " << inFlags;
uint32_t finalFlags = 0;
if ((!forceComplete)
&& (frame.mLargeWork->result == C2_OK)
diff --git a/media/libaaudio/fuzzer/Android.bp b/media/libaaudio/fuzzer/Android.bp
index ba231c1..a1551f8 100644
--- a/media/libaaudio/fuzzer/Android.bp
+++ b/media/libaaudio/fuzzer/Android.bp
@@ -46,9 +46,9 @@
],
static_libs: [
"aaudio-aidl-cpp",
+ "audio-permission-aidl-cpp",
"audioclient-types-aidl-cpp",
"audioflinger-aidl-cpp",
- "audio-permission-aidl-cpp",
"audiopolicy-aidl-cpp",
"audiopolicy-types-aidl-cpp",
"av-types-aidl-cpp",
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
index 8595308..255bd0f 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
@@ -261,6 +261,11 @@
void AudioStreamLegacy::onAudioDeviceUpdate(audio_io_handle_t /* audioIo */,
audio_port_handle_t deviceId) {
+ // Check for an invalid deviceId. Why change to UNSPECIFIED?
+ if (deviceId == AAUDIO_UNSPECIFIED) {
+ ALOGE("%s(, deviceId = AAUDIO_UNSPECIFIED)! Why?", __func__);
+ return;
+ }
// Device routing is a common source of errors and DISCONNECTS.
// Please leave this log in place. If there is a bug then this might
// get called after the stream has been deleted so log before we
diff --git a/media/libmedia/include/media/RingBuffer.h b/media/libmedia/include/media/RingBuffer.h
index 4d92d87..a08f35e 100644
--- a/media/libmedia/include/media/RingBuffer.h
+++ b/media/libmedia/include/media/RingBuffer.h
@@ -44,8 +44,14 @@
/**
* Forward iterator to this class. Implements an std:forward_iterator.
*/
- class iterator : public std::iterator<std::forward_iterator_tag, T> {
+ class iterator {
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = T;
+ using difference_type = std::ptrdiff_t;
+ using pointer = T*;
+ using reference = T&;
+
iterator(T* ptr, size_t size, size_t pos, size_t ctr);
iterator& operator++();
@@ -357,5 +363,3 @@
}; // namespace android
#endif // ANDROID_SERVICE_UTILS_RING_BUFFER_H
-
-
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index e229844..02a5e6c 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -150,10 +150,14 @@
int32_t cameraId, const std::string& clientName, uid_t clientUid, pid_t clientPid) {
if (camera == 0) {
- mCamera = Camera::connect(cameraId, clientName, clientUid, clientPid,
- /*targetSdkVersion*/__ANDROID_API_FUTURE__,
+ AttributionSourceState clientAttribution;
+ clientAttribution.pid = clientPid;
+ clientAttribution.uid = clientUid;
+ clientAttribution.deviceId = kDefaultDeviceId;
+
+ mCamera = Camera::connect(cameraId, clientName, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
/*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
- /*forceSlowJpegMode*/false);
+ /*forceSlowJpegMode*/false, clientAttribution);
if (mCamera == 0) return -EBUSY;
mCameraFlags &= ~FLAGS_HOT_CAMERA;
} else {
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
index 4183023..4ab5d10 100644
--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
@@ -619,6 +619,13 @@
if (!isValidOMXParam(outParams)) {
return OMX_ErrorBadParameter;
}
+ if (offsetof(DescribeHDR10PlusInfoParams, nValue) + outParams->nParamSize >
+ outParams->nSize) {
+ ALOGE("b/329641908: too large param size; nParamSize=%u nSize=%u",
+ outParams->nParamSize, outParams->nSize);
+ android_errorWriteLog(0x534e4554, "329641908");
+ return OMX_ErrorBadParameter;
+ }
outParams->nParamSizeUsed = info->size();
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index b763f09..2abf682 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -213,6 +213,7 @@
],
static_libs: [
+ "audiopermissioncontroller",
"libcpustats",
"libpermission",
],
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 60be37d..e76ece2 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -39,13 +39,17 @@
#include <binder/IServiceManager.h>
#include <binder/Parcel.h>
#include <cutils/properties.h>
+#include <com_android_media_audio.h>
#include <com_android_media_audioserver.h>
#include <media/AidlConversion.h>
#include <media/AudioParameter.h>
#include <media/AudioValidator.h>
#include <media/IMediaLogService.h>
+#include <media/IPermissionProvider.h>
#include <media/MediaMetricsItem.h>
+#include <media/NativePermissionController.h>
#include <media/TypeConverter.h>
+#include <media/ValidatedAttributionSourceState.h>
#include <mediautils/BatteryNotifier.h>
#include <mediautils/MemoryLeakTrackUtil.h>
#include <mediautils/MethodStatistics.h>
@@ -81,12 +85,17 @@
namespace android {
using ::android::base::StringPrintf;
+using aidl_utils::statusTFromBinderStatus;
using media::IEffectClient;
using media::audio::common::AudioMMapPolicyInfo;
using media::audio::common::AudioMMapPolicyType;
using media::audio::common::AudioMode;
using android::content::AttributionSourceState;
using android::detail::AudioHalVersionInfo;
+using com::android::media::permission::INativePermissionController;
+using com::android::media::permission::IPermissionProvider;
+using com::android::media::permission::NativePermissionController;
+using com::android::media::permission::ValidatedAttributionSourceState;
static const AudioHalVersionInfo kMaxAAudioPropertyDeviceHalVersion =
AudioHalVersionInfo(AudioHalVersionInfo::Type::HIDL, 7, 1);
@@ -118,6 +127,52 @@
}
}
+static error::BinderResult<ValidatedAttributionSourceState>
+validateAttributionFromContextOrTrustedCaller(AttributionSourceState attr,
+ const IPermissionProvider& provider) {
+ const auto callingUid = IPCThreadState::self()->getCallingUid();
+ // We trust the following UIDs to appropriate validated identities above us
+ if (isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
+ // Legacy paths may not properly populate package name, so we attempt to handle.
+ if (!attr.packageName.has_value() || attr.packageName.value() == "") {
+ ALOGW("Trusted client %d provided attr with missing package name" , callingUid);
+ attr.packageName = VALUE_OR_RETURN(provider.getPackagesForUid(callingUid))[0];
+ }
+ // Behavior change: In the case of delegation, if pid is invalid,
+ // filling it in with the callingPid will cause a mismatch between the
+ // pid and the uid in the attribution, which is error-prone.
+ // Instead, assert that the pid from a trusted source is valid
+ if (attr.pid == -1) {
+ if (callingUid != static_cast<uid_t>(attr.uid)) {
+ return error::unexpectedExceptionCode(binder::Status::EX_ILLEGAL_ARGUMENT,
+ "validateAttribution: Invalid pid from delegating trusted source");
+ } else {
+ // Legacy handling for trusted clients which may not fill pid correctly
+ attr.pid = IPCThreadState::self()->getCallingPid();
+ }
+ }
+ return ValidatedAttributionSourceState::createFromTrustedSource(std::move(attr));
+ } else {
+ // Behavior change: Populate pid with callingPid unconditionally. Previously, we
+ // allowed caller provided pid, if uid matched calling context, but this is error-prone
+ // since it allows mismatching uid/pid
+ return ValidatedAttributionSourceState::createFromBinderContext(std::move(attr), provider);
+ }
+}
+
+#define VALUE_OR_RETURN_CONVERTED(exp) \
+ ({ \
+ auto _tmp = (exp); \
+ if (!_tmp.ok()) { \
+ ALOGE("Function: %s Line: %d Failed result (%s)", __FUNCTION__, __LINE__, \
+ errorToString(_tmp.error()).c_str()); \
+ return statusTFromBinderStatus(_tmp.error()); \
+ } \
+ std::move(_tmp.value()); \
+ })
+
+
+
// Creates association between Binder code to name for IAudioFlinger.
#define IAUDIOFLINGER_BINDER_METHOD_MACRO_LIST \
BINDER_METHOD_ENTRY(createTrack) \
@@ -519,30 +574,42 @@
audio_attributes_t localAttr = *attr;
// TODO b/182392553: refactor or make clearer
- pid_t clientPid =
- VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(client.attributionSource.pid));
- bool updatePid = (clientPid == (pid_t)-1);
- const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+ AttributionSourceState adjAttributionSource;
+ if (!com::android::media::audio::audioserver_permissions()) {
+ pid_t clientPid =
+ VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(client.attributionSource.pid));
+ bool updatePid = (clientPid == (pid_t)-1);
+ const uid_t callingUid = IPCThreadState::self()->getCallingUid();
- AttributionSourceState adjAttributionSource = client.attributionSource;
- if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
- uid_t clientUid =
- VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(client.attributionSource.uid));
- ALOGW_IF(clientUid != callingUid,
- "%s uid %d tried to pass itself off as %d",
- __FUNCTION__, callingUid, clientUid);
- adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
- updatePid = true;
- }
- if (updatePid) {
- const pid_t callingPid = IPCThreadState::self()->getCallingPid();
- ALOGW_IF(clientPid != (pid_t)-1 && clientPid != callingPid,
- "%s uid %d pid %d tried to pass itself off as pid %d",
- __func__, callingUid, callingPid, clientPid);
- adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
- }
- adjAttributionSource = afutils::checkAttributionSourcePackage(
+ adjAttributionSource = client.attributionSource;
+ if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
+ uid_t clientUid =
+ VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(client.attributionSource.uid));
+ ALOGW_IF(clientUid != callingUid,
+ "%s uid %d tried to pass itself off as %d",
+ __FUNCTION__, callingUid, clientUid);
+ adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_uid_t_int32_t(callingUid));
+ updatePid = true;
+ }
+ if (updatePid) {
+ const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+ ALOGW_IF(clientPid != (pid_t)-1 && clientPid != callingPid,
+ "%s uid %d pid %d tried to pass itself off as pid %d",
+ __func__, callingUid, callingPid, clientPid);
+ adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_pid_t_int32_t(callingPid));
+ }
+ adjAttributionSource = afutils::checkAttributionSourcePackage(
adjAttributionSource);
+ } else {
+ auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED(
+ validateAttributionFromContextOrTrustedCaller(client.attributionSource,
+ getPermissionProvider()
+ ));
+ // TODO pass wrapped object around
+ adjAttributionSource = std::move(validatedAttrSource).unwrapInto();
+ }
if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
audio_config_t fullConfig = AUDIO_CONFIG_INITIALIZER;
@@ -997,36 +1064,50 @@
bool isSpatialized = false;
bool isBitPerfect = false;
- // TODO b/182392553: refactor or make clearer
- pid_t clientPid =
- VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(input.clientInfo.attributionSource.pid));
- bool updatePid = (clientPid == (pid_t)-1);
- const uid_t callingUid = IPCThreadState::self()->getCallingUid();
- uid_t clientUid =
- VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(input.clientInfo.attributionSource.uid));
audio_io_handle_t effectThreadId = AUDIO_IO_HANDLE_NONE;
std::vector<int> effectIds;
audio_attributes_t localAttr = input.attr;
- AttributionSourceState adjAttributionSource = input.clientInfo.attributionSource;
- if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
- ALOGW_IF(clientUid != callingUid,
- "%s uid %d tried to pass itself off as %d",
- __FUNCTION__, callingUid, clientUid);
- adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
- clientUid = callingUid;
- updatePid = true;
+ AttributionSourceState adjAttributionSource;
+ pid_t callingPid = IPCThreadState::self()->getCallingPid();
+ if (!com::android::media::audio::audioserver_permissions()) {
+ adjAttributionSource = input.clientInfo.attributionSource;
+ const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+ uid_t clientUid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_uid_t(
+ input.clientInfo.attributionSource.uid));
+ pid_t clientPid =
+ VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(
+ input.clientInfo.attributionSource.pid));
+ bool updatePid = (clientPid == (pid_t)-1);
+
+ if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
+ ALOGW_IF(clientUid != callingUid,
+ "%s uid %d tried to pass itself off as %d",
+ __FUNCTION__, callingUid, clientUid);
+ adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_uid_t_int32_t(callingUid));
+ clientUid = callingUid;
+ updatePid = true;
+ }
+ if (updatePid) {
+ ALOGW_IF(clientPid != (pid_t)-1 && clientPid != callingPid,
+ "%s uid %d pid %d tried to pass itself off as pid %d",
+ __func__, callingUid, callingPid, clientPid);
+ clientPid = callingPid;
+ adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_pid_t_int32_t(callingPid));
+ }
+ adjAttributionSource = afutils::checkAttributionSourcePackage(
+ adjAttributionSource);
+
+ } else {
+ auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED(
+ validateAttributionFromContextOrTrustedCaller(input.clientInfo.attributionSource,
+ getPermissionProvider()
+ ));
+ // TODO pass wrapped object around
+ adjAttributionSource = std::move(validatedAttrSource).unwrapInto();
}
- const pid_t callingPid = IPCThreadState::self()->getCallingPid();
- if (updatePid) {
- ALOGW_IF(clientPid != (pid_t)-1 && clientPid != callingPid,
- "%s uid %d pid %d tried to pass itself off as pid %d",
- __func__, callingUid, callingPid, clientPid);
- clientPid = callingPid;
- adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
- }
- adjAttributionSource = afutils::checkAttributionSourcePackage(
- adjAttributionSource);
audio_session_t sessionId = input.sessionId;
if (sessionId == AUDIO_SESSION_ALLOCATE) {
@@ -1079,7 +1160,7 @@
goto Exit;
}
- client = registerPid(clientPid);
+ client = registerPid(adjAttributionSource.pid);
IAfPlaybackThread* effectThread = nullptr;
sp<IAfEffectChain> effectChain = nullptr;
@@ -2199,6 +2280,12 @@
}
}
+const IPermissionProvider& AudioFlinger::getPermissionProvider() {
+ // This is inited as part of service construction, prior to binder registration,
+ // so it should always be non-null.
+ return mAudioPolicyServiceLocal.load()->getPermissionProvider();
+}
+
// removeClient_l() must be called with AudioFlinger::clientMutex() held
void AudioFlinger::removeClient_l(pid_t pid)
{
@@ -2308,30 +2395,43 @@
output.buffers.clear();
output.inputId = AUDIO_IO_HANDLE_NONE;
- // TODO b/182392553: refactor or clean up
- AttributionSourceState adjAttributionSource = input.clientInfo.attributionSource;
- bool updatePid = (adjAttributionSource.pid == -1);
- const uid_t callingUid = IPCThreadState::self()->getCallingUid();
- const uid_t currentUid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(
- adjAttributionSource.uid));
- if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
- ALOGW_IF(currentUid != callingUid,
- "%s uid %d tried to pass itself off as %d",
- __FUNCTION__, callingUid, currentUid);
- adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
- updatePid = true;
+ AttributionSourceState adjAttributionSource;
+ pid_t callingPid = IPCThreadState::self()->getCallingPid();
+ if (!com::android::media::audio::audioserver_permissions()) {
+ adjAttributionSource = input.clientInfo.attributionSource;
+ bool updatePid = (adjAttributionSource.pid == -1);
+ const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+ const uid_t currentUid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(
+ adjAttributionSource.uid));
+ if (!isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
+ ALOGW_IF(currentUid != callingUid,
+ "%s uid %d tried to pass itself off as %d",
+ __FUNCTION__, callingUid, currentUid);
+ adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_uid_t_int32_t(callingUid));
+ updatePid = true;
+ }
+ const pid_t currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(
+ adjAttributionSource.pid));
+ if (updatePid) {
+ ALOGW_IF(currentPid != (pid_t)-1 && currentPid != callingPid,
+ "%s uid %d pid %d tried to pass itself off as pid %d",
+ __func__, callingUid, callingPid, currentPid);
+ adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_pid_t_int32_t(callingPid));
+ }
+ adjAttributionSource = afutils::checkAttributionSourcePackage(
+ adjAttributionSource);
+ } else {
+ auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED(
+ validateAttributionFromContextOrTrustedCaller(
+ input.clientInfo.attributionSource,
+ getPermissionProvider()
+ ));
+ // TODO pass wrapped object around
+ adjAttributionSource = std::move(validatedAttrSource).unwrapInto();
}
- const pid_t callingPid = IPCThreadState::self()->getCallingPid();
- const pid_t currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(
- adjAttributionSource.pid));
- if (updatePid) {
- ALOGW_IF(currentPid != (pid_t)-1 && currentPid != callingPid,
- "%s uid %d pid %d tried to pass itself off as pid %d",
- __func__, callingUid, callingPid, currentPid);
- adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
- }
- adjAttributionSource = afutils::checkAttributionSourcePackage(
- adjAttributionSource);
+
// further format checks are performed by createRecordTrack_l()
if (!audio_is_valid_format(input.config.format)) {
ALOGE("createRecord() invalid format %#x", input.config.format);
@@ -3812,7 +3912,11 @@
IAfPlaybackThread* AudioFlinger::primaryPlaybackThread_l() const
{
- audio_utils::lock_guard lock(hardwareMutex());
+ // The atomic ptr mPrimaryHardwareDev requires both the
+ // AudioFlinger and the Hardware mutex for modification.
+ // As we hold the AudioFlinger mutex, we access it
+ // safely without the Hardware mutex, to avoid mutex order
+ // inversion with Thread methods and the ThreadBase mutex.
if (mPrimaryHardwareDev == nullptr) {
return nullptr;
}
@@ -4117,20 +4221,31 @@
int idOut = -1;
status_t lStatus = NO_ERROR;
-
- // TODO b/182392553: refactor or make clearer
- const uid_t callingUid = IPCThreadState::self()->getCallingUid();
- adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
- pid_t currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(adjAttributionSource.pid));
- if (currentPid == -1 || !isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
- const pid_t callingPid = IPCThreadState::self()->getCallingPid();
- ALOGW_IF(currentPid != -1 && currentPid != callingPid,
- "%s uid %d pid %d tried to pass itself off as pid %d",
- __func__, callingUid, callingPid, currentPid);
- adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(callingPid));
- currentPid = callingPid;
+ uid_t callingUid = IPCThreadState::self()->getCallingUid();
+ pid_t currentPid;
+ if (!com::android::media::audio::audioserver_permissions()) {
+ adjAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
+ currentPid = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_pid_t(adjAttributionSource.pid));
+ if (currentPid == -1 || !isAudioServerOrMediaServerOrSystemServerOrRootUid(callingUid)) {
+ const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+ ALOGW_IF(currentPid != -1 && currentPid != callingPid,
+ "%s uid %d pid %d tried to pass itself off as pid %d",
+ __func__, callingUid, callingPid, currentPid);
+ adjAttributionSource.pid = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_pid_t_int32_t(callingPid));
+ currentPid = callingPid;
+ }
+ adjAttributionSource = afutils::checkAttributionSourcePackage(adjAttributionSource);
+ } else {
+ auto validatedAttrSource = VALUE_OR_RETURN_CONVERTED(
+ validateAttributionFromContextOrTrustedCaller(request.attributionSource,
+ getPermissionProvider()
+ ));
+ // TODO pass wrapped object around
+ adjAttributionSource = std::move(validatedAttrSource).unwrapInto();
+ currentPid = adjAttributionSource.pid;
}
- adjAttributionSource = afutils::checkAttributionSourcePackage(adjAttributionSource);
+
ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d, factory %p",
adjAttributionSource.pid, effectClient.get(), priority, sessionId, io,
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 501aed1..46f4068 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -407,6 +407,8 @@
void onHardError(std::set<audio_port_handle_t>& trackPortIds) final
EXCLUDES_AudioFlinger_ClientMutex;
+ const ::com::android::media::permission::IPermissionProvider& getPermissionProvider() final;
+
// ---- end of IAfThreadCallback interface
/* List available audio ports and their attributes */
diff --git a/services/audioflinger/DeviceEffectManager.h b/services/audioflinger/DeviceEffectManager.h
index 287d838..3af51d5 100644
--- a/services/audioflinger/DeviceEffectManager.h
+++ b/services/audioflinger/DeviceEffectManager.h
@@ -108,6 +108,7 @@
}
audio_io_handle_t io() const final { return AUDIO_IO_HANDLE_NONE; }
+ bool shouldDispatchAddRemoveToHal(bool isAdded __unused) const final { return true; }
bool isOutput() const final { return false; }
bool isOffload() const final { return false; }
bool isOffloadOrDirect() const final { return false; }
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 8356339..bceba4b 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1040,12 +1040,11 @@
{
if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
(mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
- if (mCurrentHalStream == getCallback()->io()) {
+ if (!getCallback()->shouldDispatchAddRemoveToHal(/* isAdded= */ true)) {
return;
}
(void)getCallback()->addEffectToHal(mEffectInterface);
- mCurrentHalStream = getCallback()->io();
}
}
@@ -1142,11 +1141,10 @@
{
if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
(mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
- if (mCurrentHalStream != getCallback()->io()) {
- return (mCurrentHalStream == AUDIO_IO_HANDLE_NONE) ? NO_ERROR : INVALID_OPERATION;
+ if (!getCallback()->shouldDispatchAddRemoveToHal(/* isAdded= */ false)) {
+ return (getCallback()->io() == AUDIO_IO_HANDLE_NONE) ? NO_ERROR : INVALID_OPERATION;
}
getCallback()->removeEffectFromHal(mEffectInterface);
- mCurrentHalStream = AUDIO_IO_HANDLE_NONE;
}
return NO_ERROR;
}
@@ -3122,12 +3120,16 @@
return result;
}
result = st->addEffect(effect);
+ if (result == OK) {
+ mCurrentHalStream = t->id();
+ }
ALOGE_IF(result != OK, "Error when adding effect: %d", result);
return result;
}
status_t EffectChain::EffectCallback::removeEffectFromHal(
const sp<EffectHalInterface>& effect) {
+ mCurrentHalStream = AUDIO_IO_HANDLE_NONE;
status_t result = NO_INIT;
const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
@@ -3142,6 +3144,11 @@
return result;
}
+bool EffectChain::EffectCallback::shouldDispatchAddRemoveToHal(bool isAdded) const {
+ const bool currentHalStreamMatchesThreadId = (io() == mCurrentHalStream);
+ return isAdded != currentHalStreamMatchesThreadId;
+}
+
audio_io_handle_t EffectChain::EffectCallback::io() const {
const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
@@ -3734,11 +3741,14 @@
if (proxy == nullptr) {
return NO_INIT;
}
- return proxy->addEffectToHal(effect);
+ status_t ret = proxy->addEffectToHal(effect);
+ mAddedToHal = (ret == OK);
+ return ret;
}
status_t DeviceEffectProxy::ProxyCallback::removeEffectFromHal(
const sp<EffectHalInterface>& effect) {
+ mAddedToHal = false;
sp<DeviceEffectProxy> proxy = mProxy.promote();
if (proxy == nullptr) {
return NO_INIT;
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index d107543..549cff2 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -279,8 +279,6 @@
// sending disable command.
uint32_t mDisableWaitCnt; // current process() calls count during disable period.
bool mOffloaded; // effect is currently offloaded to the audio DSP
- // effect has been added to this HAL input stream
- audio_io_handle_t mCurrentHalStream = AUDIO_IO_HANDLE_NONE;
bool mIsOutput; // direction of the AF thread
bool mSupportsFloat; // effect supports float processing
@@ -596,6 +594,7 @@
status_t allocateHalBuffer(size_t size, sp<EffectBufferHalInterface>* buffer) override;
bool updateOrphanEffectChains(const sp<IAfEffectBase>& effect) override;
+ bool shouldDispatchAddRemoveToHal(bool isAdded) const override;
audio_io_handle_t io() const override;
bool isOutput() const override;
bool isOffload() const override;
@@ -653,6 +652,8 @@
mediautils::atomic_wp<IAfThreadBase> mThread;
sp<IAfThreadCallback> mAfThreadCallback;
IAfThreadBase::type_t mThreadType = IAfThreadBase::MIXER;
+ // effect has been added to this HAL input stream
+ audio_io_handle_t mCurrentHalStream = AUDIO_IO_HANDLE_NONE;
};
DISALLOW_COPY_AND_ASSIGN(EffectChain);
@@ -784,6 +785,9 @@
}
audio_io_handle_t io() const override { return AUDIO_IO_HANDLE_NONE; }
+ bool shouldDispatchAddRemoveToHal(bool isAdded) const override {
+ return isAdded != mAddedToHal;
+ }
bool isOutput() const override;
bool isOffload() const override { return false; }
bool isOffloadOrDirect() const override { return false; }
@@ -824,6 +828,7 @@
private:
const wp<DeviceEffectProxy> mProxy;
const sp<DeviceEffectManagerCallback> mManagerCallback;
+ bool mAddedToHal = false;
};
status_t checkPort(const IAfPatchPanel::Patch& patch,
diff --git a/services/audioflinger/IAfEffect.h b/services/audioflinger/IAfEffect.h
index 2bf252a..98a0fcb 100644
--- a/services/audioflinger/IAfEffect.h
+++ b/services/audioflinger/IAfEffect.h
@@ -46,6 +46,7 @@
public:
// Trivial methods usually implemented with help from ThreadBase
virtual audio_io_handle_t io() const = 0;
+ virtual bool shouldDispatchAddRemoveToHal(bool isAdded) const = 0;
virtual bool isOutput() const = 0;
virtual bool isOffload() const = 0;
virtual bool isOffloadOrDirect() const = 0;
diff --git a/services/audioflinger/IAfThread.h b/services/audioflinger/IAfThread.h
index a7da658..4d26aa0 100644
--- a/services/audioflinger/IAfThread.h
+++ b/services/audioflinger/IAfThread.h
@@ -37,6 +37,10 @@
#include <optional>
+namespace com::android::media::permission {
+ class IPermissionProvider;
+}
+
namespace android {
class IAfDirectOutputThread;
@@ -122,6 +126,9 @@
EXCLUDES_AudioFlinger_ClientMutex = 0;
virtual void onHardError(std::set<audio_port_handle_t>& trackPortIds) = 0;
+
+ virtual const ::com::android::media::permission::IPermissionProvider&
+ getPermissionProvider() = 0;
};
class IAfThreadBase : public virtual RefBase {
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 5c0ca5e..2dcbbce 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -72,6 +72,7 @@
#include <media/nbaio/Pipe.h>
#include <media/nbaio/PipeReader.h>
#include <media/nbaio/SourceAudioBufferProvider.h>
+#include <media/ValidatedAttributionSourceState.h>
#include <mediautils/BatteryNotifier.h>
#include <mediautils/Process.h>
#include <mediautils/SchedulingPolicyService.h>
@@ -120,6 +121,8 @@
return a < b ? a : b;
}
+using com::android::media::permission::ValidatedAttributionSourceState;
+
namespace android {
using audioflinger::SyncEvent;
@@ -5093,7 +5096,6 @@
// mPipeSink below
// mNormalSink below
{
- setMasterBalance(afThreadCallback->getMasterBalance_l());
ALOGV("MixerThread() id=%d type=%d", id, type);
ALOGV("mSampleRate=%u, mChannelMask=%#x, mChannelCount=%u, mFormat=%#x, mFrameSize=%zu, "
"mFrameCount=%zu, mNormalFrameCount=%zu",
@@ -5105,6 +5107,8 @@
// The Duplicating thread uses the AudioMixer and delivers data to OutputTracks
// (downstream MixerThreads) in DuplicatingThread::threadLoop_write().
// Do not create or use mFastMixer, mOutputSink, mPipeSink, or mNormalSink.
+ // Balance is *not* set in the DuplicatingThread here (or from AudioFlinger),
+ // as the downstream MixerThreads implement it.
return;
}
// create an NBAIO sink for the HAL output stream, and negotiate
@@ -5264,6 +5268,9 @@
mNormalSink = initFastMixer ? mPipeSink : mOutputSink;
break;
}
+ // setMasterBalance needs to be called after the FastMixer
+ // (if any) is set up, in order to deliver the balance settings to it.
+ setMasterBalance(afThreadCallback->getMasterBalance_l());
}
MixerThread::~MixerThread()
@@ -10298,8 +10305,23 @@
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
audio_io_handle_t io = mId;
- const AttributionSourceState adjAttributionSource = afutils::checkAttributionSourcePackage(
- client.attributionSource);
+ AttributionSourceState adjAttributionSource;
+ if (!com::android::media::audio::audioserver_permissions()) {
+ adjAttributionSource = afutils::checkAttributionSourcePackage(
+ client.attributionSource);
+ } else {
+ // TODO(b/342475009) validate in oboeservice, and plumb downwards
+ auto validatedRes = ValidatedAttributionSourceState::createFromTrustedUidNoPackage(
+ client.attributionSource,
+ mAfThreadCallback->getPermissionProvider()
+ );
+ if (!validatedRes.has_value()) {
+ ALOGE("MMAP client package validation fail: %s",
+ validatedRes.error().toString8().c_str());
+ return aidl_utils::statusTFromBinderStatus(validatedRes.error());
+ }
+ adjAttributionSource = std::move(validatedRes.value()).unwrapInto();
+ }
const auto localSessionId = mSessionId;
auto localAttr = mAttr;
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index e91e2a3..deb7345 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -294,8 +294,7 @@
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_port_handle_t *portId,
- uid_t uid,
- bool internal = false) = 0;
+ uid_t uid) = 0;
virtual status_t stopAudioSource(audio_port_handle_t portId) = 0;
virtual status_t setMasterMono(bool mono) = 0;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
index 6167f95..e519766 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
@@ -47,13 +47,17 @@
if (active) {
// On MMAP IOs, the preferred device is selected by the first client (virtual client
- // created when the mmap stream is opened). This client is never active.
+ // created when the mmap stream is opened). This client is never active and we only
+ // consider the Filter criteria, not the active state.
// On non MMAP IOs, the preferred device is honored only if all active clients have
// a preferred device in which case the first client drives the selection.
if (desc->isMmap()) {
- // The client list is never empty on a MMAP IO
- return devices.getDeviceFromId(
- desc->clientsList(false /*activeOnly*/)[0]->preferredDeviceId());
+ auto matchingClients = desc->clientsList(
+ false /*activeOnly*/, filter, false /*preferredDevice*/);
+ if (matchingClients.empty()) {
+ return nullptr;
+ }
+ return devices.getDeviceFromId(matchingClients[0]->preferredDeviceId());
} else {
auto activeClientsWithRoute =
desc->clientsList(true /*activeOnly*/, filter, true /*preferredDevice*/);
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index c26ea10..0f2fe24 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -41,7 +41,8 @@
{
public:
AudioInputDescriptor(const sp<IOProfile>& profile,
- AudioPolicyClientInterface *clientInterface);
+ AudioPolicyClientInterface *clientInterface,
+ bool isPreemptor);
virtual ~AudioInputDescriptor() = default;
@@ -127,6 +128,8 @@
// active use case
void checkSuspendEffects();
+ bool isPreemptor() const { return mIsPreemptor; }
+
private:
void updateClientRecordingConfiguration(int event, const sp<RecordClientDescriptor>& client);
@@ -145,6 +148,7 @@
int32_t mGlobalActiveCount = 0; // non-client-specific activity ref count
EffectDescriptorCollection mEnabledEffects;
audio_input_flags_t& mFlags = AudioPortConfig::mFlags.input;
+ bool mIsPreemptor; // true if this input was opened after preemting another one
};
class AudioInputCollection :
diff --git a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
index a596c43..60da405 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
@@ -63,6 +63,8 @@
* HW Audio Source.
*/
virtual bool isInternal() const { return false; }
+ virtual bool isCallRx() const { return false; }
+ virtual bool isCallTx() const { return false; }
audio_port_handle_t portId() const { return mPortId; }
uid_t uid() const { return mUid; }
audio_session_t session() const { return mSessionId; };
@@ -236,7 +238,7 @@
const sp<DeviceDescriptor>& srcDevice,
audio_stream_type_t stream, product_strategy_t strategy,
VolumeSource volumeSource,
- bool isInternal);
+ bool isInternal, bool isCallRx, bool isCallTx);
~SourceClientDescriptor() override = default;
@@ -263,6 +265,8 @@
wp<HwAudioOutputDescriptor> hwOutput() const { return mHwOutput; }
void setHwOutput(const sp<HwAudioOutputDescriptor>& hwOutput);
bool isInternal() const override { return mIsInternal; }
+ bool isCallRx() const override { return mIsCallRx; }
+ bool isCallTx() const override { return mIsCallTx; }
using ClientDescriptor::dump;
void dump(String8 *dst, int spaces) const override;
@@ -294,6 +298,8 @@
* requester to prevent rerouting SwOutput involved in raw patches.
*/
bool mIsInternal = false;
+ bool mIsCallRx = false;
+ bool mIsCallTx = false;
};
class SourceClientCollection :
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 44f84b9..5a0fd97 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -30,9 +30,10 @@
namespace android {
AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile,
- AudioPolicyClientInterface *clientInterface)
+ AudioPolicyClientInterface *clientInterface,
+ bool isPreemptor)
: mProfile(profile)
- , mClientInterface(clientInterface)
+ , mClientInterface(clientInterface), mIsPreemptor(isPreemptor)
{
if (profile != NULL) {
profile->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
@@ -275,6 +276,9 @@
"%s invalid profile active count %u",
__func__, mProfile->curActiveCount);
mProfile->curActiveCount--;
+ // allow preemption again now that at least one client was able to
+ // capture on this input
+ mIsPreemptor = false;
}
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
index 667c189..ad6977b 100644
--- a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
@@ -96,12 +96,14 @@
SourceClientDescriptor::SourceClientDescriptor(audio_port_handle_t portId, uid_t uid,
audio_attributes_t attributes, const struct audio_port_config &config,
const sp<DeviceDescriptor>& srcDevice, audio_stream_type_t stream,
- product_strategy_t strategy, VolumeSource volumeSource, bool isInternal) :
+ product_strategy_t strategy, VolumeSource volumeSource,
+ bool isInternal, bool isCallRx, bool isCallTx) :
TrackClientDescriptor::TrackClientDescriptor(portId, uid, AUDIO_SESSION_NONE, attributes,
{config.sample_rate, config.channel_mask, config.format}, AUDIO_PORT_HANDLE_NONE,
stream, strategy, volumeSource, AUDIO_OUTPUT_FLAG_NONE, false,
{} /* Sources do not support secondary outputs*/, nullptr),
- mSrcDevice(srcDevice), mIsInternal(isInternal)
+ mSrcDevice(srcDevice), mIsInternal(isInternal),
+ mIsCallRx(isCallRx), mIsCallTx(isCallTx)
{
}
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 406bc4f..7666a2b 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -428,10 +428,12 @@
// LE audio broadcast device is only used if:
// - No call is active
- // - either MEDIA or SONIFICATION_RESPECTFUL is the highest priority active strategy
- // OR the LE audio unicast device is not active
+ // - either MEDIA, SONIFICATION_RESPECTFUL or SONIFICATION is the highest priority
+ // active strategy
+ // OR the LE audio unicast device is not active
if (devices2.isEmpty() && !isInCall()
- && (strategy == STRATEGY_MEDIA || strategy == STRATEGY_SONIFICATION_RESPECTFUL)) {
+ && (strategy == STRATEGY_MEDIA || strategy == STRATEGY_SONIFICATION_RESPECTFUL
+ || strategy == STRATEGY_SONIFICATION)) {
legacy_strategy topActiveStrategy = STRATEGY_NONE;
for (const auto &ps : getOrderedProductStrategies()) {
if (outputs.isStrategyActive(ps)) {
@@ -443,6 +445,7 @@
if (topActiveStrategy == STRATEGY_NONE || topActiveStrategy == STRATEGY_MEDIA
|| topActiveStrategy == STRATEGY_SONIFICATION_RESPECTFUL
+ || topActiveStrategy == STRATEGY_SONIFICATION
|| !outputs.isAnyDeviceTypeActive(getAudioDeviceOutLeAudioUnicastSet())) {
devices2 =
availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_BLE_BROADCAST);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index cca7f92..299ba86 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -66,6 +66,7 @@
using android::media::audio::common::AudioDeviceAddress;
using android::media::audio::common::AudioPortDeviceExt;
using android::media::audio::common::AudioPortExt;
+using com::android::media::audioserver::fix_call_audio_patch;
using content::AttributionSourceState;
//FIXME: workaround for truncated touch sounds
@@ -704,8 +705,10 @@
audio_attributes_t attr = { .source = AUDIO_SOURCE_VOICE_COMMUNICATION };
auto txSourceDevice = mEngine->getInputDeviceForAttributes(attr);
- disconnectTelephonyAudioSource(mCallRxSourceClient);
- disconnectTelephonyAudioSource(mCallTxSourceClient);
+ if (!fix_call_audio_patch()) {
+ disconnectTelephonyAudioSource(mCallRxSourceClient);
+ disconnectTelephonyAudioSource(mCallTxSourceClient);
+ }
if (rxDevices.isEmpty()) {
ALOGW("%s() no selected output device", __func__);
@@ -758,13 +761,16 @@
// Use legacy routing method for voice calls via setOutputDevice() on primary output.
// Otherwise, create two audio patches for TX and RX path.
if (!createRxPatch) {
+ if (fix_call_audio_patch()) {
+ disconnectTelephonyAudioSource(mCallRxSourceClient);
+ }
if (!hasPrimaryOutput()) {
ALOGW("%s() no primary output available", __func__);
return INVALID_OPERATION;
}
muteWaitMs = setOutputDevices(__func__, mPrimaryOutput, rxDevices, true, delayMs);
} else { // create RX path audio patch
- connectTelephonyRxAudioSource();
+ connectTelephonyRxAudioSource(delayMs);
// If the TX device is on the primary HW module but RX device is
// on other HW module, SinkMetaData of telephony input should handle it
// assuming the device uses audio HAL V5.0 and above
@@ -780,6 +786,8 @@
}
}
connectTelephonyTxAudioSource(txSourceDevice, txSinkDevice, delayMs);
+ } else if (fix_call_audio_patch()) {
+ disconnectTelephonyAudioSource(mCallTxSourceClient);
}
if (waitMs != nullptr) {
*waitMs = muteWaitMs;
@@ -799,19 +807,40 @@
return false;
}
-void AudioPolicyManager::connectTelephonyRxAudioSource()
+void AudioPolicyManager::connectTelephonyRxAudioSource(uint32_t delayMs)
{
- disconnectTelephonyAudioSource(mCallRxSourceClient);
+ const auto aa = mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL);
+
+ if (fix_call_audio_patch()) {
+ if (mCallRxSourceClient != nullptr) {
+ DeviceVector rxDevices =
+ mEngine->getOutputDevicesForAttributes(aa, nullptr, false /*fromCache*/);
+ ALOG_ASSERT(!rxDevices.isEmpty() || !mCallRxSourceClient->isConnected(),
+ "connectTelephonyRxAudioSource(): no device found for call RX source");
+ sp<DeviceDescriptor> rxDevice = rxDevices.itemAt(0);
+ if (mCallRxSourceClient->isConnected()
+ && mCallRxSourceClient->sinkDevice()->equals(rxDevice)) {
+ return;
+ }
+ disconnectTelephonyAudioSource(mCallRxSourceClient);
+ }
+ } else {
+ disconnectTelephonyAudioSource(mCallRxSourceClient);
+ }
+
const struct audio_port_config source = {
.role = AUDIO_PORT_ROLE_SOURCE, .type = AUDIO_PORT_TYPE_DEVICE,
.ext.device.type = AUDIO_DEVICE_IN_TELEPHONY_RX, .ext.device.address = ""
};
- const auto aa = mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL);
-
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
- status_t status = startAudioSource(&source, &aa, &portId, 0 /*uid*/, true /*internal*/);
+
+ status_t status = startAudioSourceInternal(&source, &aa, &portId, 0 /*uid*/,
+ true /*internal*/, true /*isCallRx*/, delayMs);
ALOGE_IF(status != OK, "%s: failed to start audio source (%d)", __func__, status);
mCallRxSourceClient = mAudioSources.valueFor(portId);
+ ALOGV("%s portdID %d between source %s and sink %s", __func__, portId,
+ mCallRxSourceClient->srcDevice()->toString().c_str(),
+ mCallRxSourceClient->sinkDevice()->toString().c_str());
ALOGE_IF(mCallRxSourceClient == nullptr,
"%s failed to start Telephony Rx AudioSource", __func__);
}
@@ -830,15 +859,26 @@
const sp<DeviceDescriptor> &srcDevice, const sp<DeviceDescriptor> &sinkDevice,
uint32_t delayMs)
{
- disconnectTelephonyAudioSource(mCallTxSourceClient);
if (srcDevice == nullptr || sinkDevice == nullptr) {
ALOGW("%s could not create patch, invalid sink and/or source device(s)", __func__);
return;
}
+
+ if (fix_call_audio_patch()) {
+ if (mCallTxSourceClient != nullptr) {
+ if (mCallTxSourceClient->isConnected()
+ && mCallTxSourceClient->srcDevice()->equals(srcDevice)) {
+ return;
+ }
+ disconnectTelephonyAudioSource(mCallTxSourceClient);
+ }
+ } else {
+ disconnectTelephonyAudioSource(mCallTxSourceClient);
+ }
+
PatchBuilder patchBuilder;
patchBuilder.addSource(srcDevice).addSink(sinkDevice);
- ALOGV("%s between source %s and sink %s", __func__,
- srcDevice->toString().c_str(), sinkDevice->toString().c_str());
+
auto callTxSourceClientPortId = PolicyAudioPort::getNextUniqueId();
const auto aa = mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL);
@@ -846,7 +886,8 @@
srcDevice->toAudioPortConfig(&source);
mCallTxSourceClient = new SourceClientDescriptor(
callTxSourceClientPortId, mUidCached, aa, source, srcDevice, AUDIO_STREAM_PATCH,
- mCommunnicationStrategy, toVolumeSource(aa), true);
+ mCommunnicationStrategy, toVolumeSource(aa), true,
+ false /*isCallRx*/, true /*isCallTx*/);
mCallTxSourceClient->setPreferredDeviceId(sinkDevice->getId());
audio_patch_handle_t patchHandle = AUDIO_PATCH_HANDLE_NONE;
@@ -854,6 +895,8 @@
mCallTxSourceClient, sinkDevice, patchBuilder.patch(), patchHandle, mUidCached,
delayMs);
ALOGE_IF(status != NO_ERROR, "%s() error %d creating TX audio patch", __func__, status);
+ ALOGV("%s portdID %d between source %s and sink %s", __func__, callTxSourceClientPortId,
+ srcDevice->toString().c_str(), sinkDevice->toString().c_str());
if (status == NO_ERROR) {
mAudioSources.add(callTxSourceClientPortId, mCallTxSourceClient);
}
@@ -3082,43 +3125,115 @@
}
}
+ bool isPreemptor = false;
if (!profile->canOpenNewIo()) {
- for (size_t i = 0; i < mInputs.size(); ) {
- sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
- if (desc->mProfile != profile) {
- i++;
- continue;
- }
- // if sound trigger, reuse input if used by other sound trigger on same session
- // else
- // reuse input if active client app is not in IDLE state
- //
- RecordClientVector clients = desc->clientsList();
- bool doClose = false;
- for (const auto& client : clients) {
- if (isSoundTrigger != client->isSoundTrigger()) {
+ if (com::android::media::audioserver::fix_input_sharing_logic()) {
+ // First pick best candidate for preemption (there may not be any):
+ // - Preempt and input if:
+ // - It has only strictly lower priority use cases than the new client
+ // - It has equal priority use cases than the new client, was not
+ // opened thanks to preemption or has been active since opened.
+ // - Order the preemption candidates by inactive first and priority second
+ sp<AudioInputDescriptor> closeCandidate;
+ int leastCloseRank = INT_MAX;
+ static const int sCloseActive = 0x100;
+
+ for (size_t i = 0; i < mInputs.size(); i++) {
+ sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
+ if (desc->mProfile != profile) {
continue;
}
- if (client->isSoundTrigger()) {
- if (session == client->session()) {
+ sp<RecordClientDescriptor> topPrioClient = desc->getHighestPriorityClient();
+ if (topPrioClient == nullptr) {
+ continue;
+ }
+ int topPrio = source_priority(topPrioClient->source());
+ if (topPrio < source_priority(attributes.source)
+ || (topPrio == source_priority(attributes.source)
+ && !desc->isPreemptor())) {
+ int closeRank = (desc->isActive() ? sCloseActive : 0) + topPrio;
+ if (closeRank < leastCloseRank) {
+ leastCloseRank = closeRank;
+ closeCandidate = desc;
+ }
+ }
+ }
+
+ if (closeCandidate != nullptr) {
+ closeInput(closeCandidate->mIoHandle);
+ // Mark the new input as being issued from a preemption
+ // so that is will not be preempted later
+ isPreemptor = true;
+ } else {
+ // Then pick the best reusable input (There is always one)
+ // The order of preference is:
+ // 1) active inputs with same use case as the new client
+ // 2) inactive inputs with same use case
+ // 3) active inputs with different use cases
+ // 4) inactive inputs with different use cases
+ sp<AudioInputDescriptor> reuseCandidate;
+ int leastReuseRank = INT_MAX;
+ static const int sReuseDifferentUseCase = 0x100;
+
+ for (size_t i = 0; i < mInputs.size(); i++) {
+ sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
+ if (desc->mProfile != profile) {
+ continue;
+ }
+ int reuseRank = sReuseDifferentUseCase;
+ for (const auto& client: desc->getClientIterable()) {
+ if (client->source() == attributes.source) {
+ reuseRank = 0;
+ break;
+ }
+ }
+ reuseRank += desc->isActive() ? 0 : 1;
+ if (reuseRank < leastReuseRank) {
+ leastReuseRank = reuseRank;
+ reuseCandidate = desc;
+ }
+ }
+ return reuseCandidate->mIoHandle;
+ }
+ } else { // fix_input_sharing_logic()
+ for (size_t i = 0; i < mInputs.size(); ) {
+ sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
+ if (desc->mProfile != profile) {
+ i++;
+ continue;
+ }
+ // if sound trigger, reuse input if used by other sound trigger on same session
+ // else
+ // reuse input if active client app is not in IDLE state
+ //
+ RecordClientVector clients = desc->clientsList();
+ bool doClose = false;
+ for (const auto& client : clients) {
+ if (isSoundTrigger != client->isSoundTrigger()) {
+ continue;
+ }
+ if (client->isSoundTrigger()) {
+ if (session == client->session()) {
+ return desc->mIoHandle;
+ }
+ continue;
+ }
+ if (client->active() && client->appState() != APP_STATE_IDLE) {
return desc->mIoHandle;
}
- continue;
+ doClose = true;
}
- if (client->active() && client->appState() != APP_STATE_IDLE) {
- return desc->mIoHandle;
+ if (doClose) {
+ closeInput(desc->mIoHandle);
+ } else {
+ i++;
}
- doClose = true;
- }
- if (doClose) {
- closeInput(desc->mIoHandle);
- } else {
- i++;
}
}
}
- sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile, mpClientInterface);
+ sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(
+ profile, mpClientInterface, isPreemptor);
audio_config_t lConfig = AUDIO_CONFIG_INITIALIZER;
lConfig.sample_rate = profileSamplingRate;
@@ -5097,7 +5212,7 @@
new SourceClientDescriptor(
portId, uid, attributes, *source, srcDevice, AUDIO_STREAM_PATCH,
mEngine->getProductStrategyForAttributes(attributes), toVolumeSource(attributes),
- true);
+ true, false /*isCallRx*/, false /*isCallTx*/);
sourceDesc->setPreferredDeviceId(sinkDevice->getId());
status_t status =
@@ -5429,7 +5544,7 @@
outputDesc->toAudioPortConfig(&srcMixPortConfig, nullptr);
// for volume control, we may need a valid stream
srcMixPortConfig.ext.mix.usecase.stream =
- (!sourceDesc->isInternal() || isCallTxAudioSource(sourceDesc)) ?
+ (!sourceDesc->isInternal() || sourceDesc->isCallTx()) ?
mEngine->getStreamTypeForAttributes(sourceDesc->attributes()) :
AUDIO_STREAM_PATCH;
patchBuilder.addSource(srcMixPortConfig);
@@ -5767,7 +5882,16 @@
status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_port_handle_t *portId,
- uid_t uid, bool internal)
+ uid_t uid) {
+ return startAudioSourceInternal(source, attributes, portId, uid,
+ false /*internal*/, false /*isCallRx*/, 0 /*delayMs*/);
+}
+
+status_t AudioPolicyManager::startAudioSourceInternal(const struct audio_port_config *source,
+ const audio_attributes_t *attributes,
+ audio_port_handle_t *portId,
+ uid_t uid, bool internal, bool isCallRx,
+ uint32_t delayMs)
{
ALOGV("%s", __FUNCTION__);
*portId = AUDIO_PORT_HANDLE_NONE;
@@ -5800,16 +5924,17 @@
new SourceClientDescriptor(*portId, uid, *attributes, *source, srcDevice,
mEngine->getStreamTypeForAttributes(*attributes),
mEngine->getProductStrategyForAttributes(*attributes),
- toVolumeSource(*attributes), internal);
+ toVolumeSource(*attributes), internal, isCallRx, false);
- status_t status = connectAudioSource(sourceDesc);
+ status_t status = connectAudioSource(sourceDesc, delayMs);
if (status == NO_ERROR) {
mAudioSources.add(*portId, sourceDesc);
}
return status;
}
-status_t AudioPolicyManager::connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc)
+status_t AudioPolicyManager::connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc,
+ uint32_t delayMs)
{
ALOGV("%s handle %d", __FUNCTION__, sourceDesc->portId());
@@ -5835,7 +5960,7 @@
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
return connectAudioSourceToSink(
- sourceDesc, sinkDevice, patchBuilder.patch(), handle, mUidCached, 0 /*delayMs*/);
+ sourceDesc, sinkDevice, patchBuilder.patch(), handle, mUidCached, delayMs);
}
status_t AudioPolicyManager::stopAudioSource(audio_port_handle_t portId)
@@ -5893,7 +6018,8 @@
float AudioPolicyManager::getStreamVolumeDB(
audio_stream_type_t stream, int index, audio_devices_t device)
{
- return computeVolume(getVolumeCurves(stream), toVolumeSource(stream), index, {device});
+ return computeVolume(getVolumeCurves(stream), toVolumeSource(stream), index,
+ {device}, /* adjustAttenuation= */false);
}
status_t AudioPolicyManager::getSurroundFormats(unsigned int *numSurroundFormats,
@@ -6623,8 +6749,8 @@
__func__, inProfile->getTagName().c_str());
continue;
}
- sp<AudioInputDescriptor> inputDesc =
- new AudioInputDescriptor(inProfile, mpClientInterface);
+ sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(
+ inProfile, mpClientInterface, false /*isPreemptor*/);
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
status_t status = inputDesc->open(nullptr,
@@ -6934,7 +7060,7 @@
continue;
}
- desc = new AudioInputDescriptor(profile, mpClientInterface);
+ desc = new AudioInputDescriptor(profile, mpClientInterface, false /*isPreemptor*/);
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
status = desc->open(nullptr, device, AUDIO_SOURCE_MIC, AUDIO_INPUT_FLAG_NONE, &input);
@@ -7180,8 +7306,8 @@
sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
if (sourceDesc != nullptr && followsSameRouting(attr, sourceDesc->attributes())
&& sourceDesc->getPatchHandle() == AUDIO_PATCH_HANDLE_NONE
- && !isCallRxAudioSource(sourceDesc) && !sourceDesc->isInternal()) {
- connectAudioSource(sourceDesc);
+ && !sourceDesc->isCallRx() && !sourceDesc->isInternal()) {
+ connectAudioSource(sourceDesc, 0 /*delayMs*/);
}
}
}
@@ -7287,8 +7413,8 @@
}
}
sp<SourceClientDescriptor> source = getSourceForAttributesOnOutput(srcOut, attr);
- if (source != nullptr && !isCallRxAudioSource(source) && !source->isInternal()) {
- connectAudioSource(source);
+ if (source != nullptr && !source->isCallRx() && !source->isInternal()) {
+ connectAudioSource(source, 0 /*delayMs*/);
}
}
@@ -8047,7 +8173,7 @@
VolumeSource vsToDriveAbs = toVolumeSource(groupToDriveAbs);
if (vsToDriveAbs == volumeSource) {
// attenuation is applied by the abs volume controller
- return volumeDbMax;
+ return (index != 0) ? volumeDbMax : volumeDb;
} else {
IVolumeCurves &curvesAbs = getVolumeCurves(vsToDriveAbs);
int indexAbs = curvesAbs.getVolumeIndex({volumeDevice});
@@ -8071,9 +8197,15 @@
VolumeSource volumeSource,
int index,
const DeviceTypeSet& deviceTypes,
+ bool adjustAttenuation,
bool computeInternalInteraction)
{
- float volumeDb = adjustDeviceAttenuationForAbsVolume(curves, volumeSource, index, deviceTypes);
+ float volumeDb;
+ if (adjustAttenuation) {
+ volumeDb = adjustDeviceAttenuationForAbsVolume(curves, volumeSource, index, deviceTypes);
+ } else {
+ volumeDb = curves.volIndexToDb(Volume::getDeviceCategory(deviceTypes), index);
+ }
ALOGV("%s volume source %d, index %d, devices %s, compute internal %b ", __func__,
volumeSource, index, dumpDeviceTypes(deviceTypes).c_str(), computeInternalInteraction);
@@ -8094,7 +8226,8 @@
mOutputs.isActive(ringVolumeSrc, 0)) {
auto &ringCurves = getVolumeCurves(AUDIO_STREAM_RING);
const float ringVolumeDb = computeVolume(ringCurves, ringVolumeSrc, index, deviceTypes,
- /* computeInternalInteraction= */ false);
+ adjustAttenuation,
+ /* computeInternalInteraction= */false);
return ringVolumeDb - 4 > volumeDb ? ringVolumeDb - 4 : volumeDb;
}
@@ -8112,7 +8245,7 @@
int voiceVolumeIndex = voiceCurves.getVolumeIndex(deviceTypes);
const float maxVoiceVolDb =
computeVolume(voiceCurves, callVolumeSrc, voiceVolumeIndex, deviceTypes,
- /* computeInternalInteraction= */ false)
+ adjustAttenuation, /* computeInternalInteraction= */false)
+ IN_CALL_EARPIECE_HEADROOM_DB;
// FIXME: Workaround for call screening applications until a proper audio mode is defined
// to support this scenario : Exempt the RING stream from the audio cap if the audio was
@@ -8165,7 +8298,8 @@
musicVolumeSrc,
musicCurves.getVolumeIndex(musicDevice),
musicDevice,
- /* computeInternalInteraction= */ false);
+ adjustAttenuation,
+ /* computeInternalInteraction= */ false);
float minVolDb = (musicVolDb > SONIFICATION_HEADSET_VOLUME_MIN_DB) ?
musicVolDb : SONIFICATION_HEADSET_VOLUME_MIN_DB;
if (volumeDb > minVolDb) {
@@ -8460,7 +8594,7 @@
sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
if (sourceDesc->isConnected() && (sourceDesc->srcDevice()->equals(deviceDesc) ||
sourceDesc->sinkDevice()->equals(deviceDesc))
- && !isCallRxAudioSource(sourceDesc)) {
+ && !sourceDesc->isCallRx()) {
disconnectAudioSource(sourceDesc);
}
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 011e867..98853ce 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -345,8 +345,7 @@
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_port_handle_t *portId,
- uid_t uid,
- bool internal = false);
+ uid_t uid);
virtual status_t stopAudioSource(audio_port_handle_t portId);
virtual status_t setMasterMono(bool mono);
@@ -591,6 +590,8 @@
* @param index index to match in the volume curves for the calculation
* @param deviceTypes devices that should be considered in the volume curves for the
* calculation
+ * @param adjustAttenuation boolean indicating whether we should adjust the value to
+ * avoid double attenuation when controlling an avrcp device
* @param computeInternalInteraction boolean indicating whether recursive volume computation
* should continue within the volume computation. Defaults to {@code true} so the
* volume interactions can be computed. Calls within the method should always set the
@@ -599,6 +600,7 @@
*/
virtual float computeVolume(IVolumeCurves &curves, VolumeSource volumeSource,
int index, const DeviceTypeSet& deviceTypes,
+ bool adjustAttenuation = true,
bool computeInternalInteraction = true);
// rescale volume index from srcStream within range of dstStream
@@ -705,15 +707,7 @@
void updateCallAndOutputRouting(bool forceVolumeReeval = true, uint32_t delayMs = 0,
bool skipDelays = false);
- bool isCallRxAudioSource(const sp<SourceClientDescriptor> &source) {
- return mCallRxSourceClient != nullptr && source == mCallRxSourceClient;
- }
-
- bool isCallTxAudioSource(const sp<SourceClientDescriptor> &source) {
- return mCallTxSourceClient != nullptr && source == mCallTxSourceClient;
- }
-
- void connectTelephonyRxAudioSource();
+ void connectTelephonyRxAudioSource(uint32_t delayMs);
void disconnectTelephonyAudioSource(sp<SourceClientDescriptor> &clientDesc);
@@ -938,7 +932,8 @@
status_t hasPrimaryOutput() const { return mPrimaryOutput != 0; }
- status_t connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
+ status_t connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc,
+ uint32_t delayMs);
status_t disconnectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
status_t connectAudioSourceToSink(const sp<SourceClientDescriptor>& sourceDesc,
@@ -976,6 +971,13 @@
void checkLeBroadcastRoutes(bool wasUnicastActive,
sp<SwAudioOutputDescriptor> ignoredOutput, uint32_t delayMs);
+ status_t startAudioSourceInternal(const struct audio_port_config *source,
+ const audio_attributes_t *attributes,
+ audio_port_handle_t *portId,
+ uid_t uid,
+ bool internal,
+ bool isCallRx,
+ uint32_t delayMs);
const uid_t mUidCached; // AID_AUDIOSERVER
sp<const AudioPolicyConfig> mConfig;
EngineInstance mEngine; // Audio Policy Engine instance
diff --git a/services/audiopolicy/permission/Android.bp b/services/audiopolicy/permission/Android.bp
index d5f59a0..cfbeaae 100644
--- a/services/audiopolicy/permission/Android.bp
+++ b/services/audiopolicy/permission/Android.bp
@@ -34,8 +34,8 @@
shared_libs: [
"libbase",
"libbinder",
- "libutils",
"liblog",
+ "libutils",
],
host_supported: true,
@@ -43,21 +43,21 @@
integer_overflow: true,
},
cflags: [
- "-Wall",
- "-Wdeprecated",
- "-Wextra",
- "-Werror=format",
- "-Wextra-semi",
- "-Wthread-safety",
- "-Wconditional-uninitialized",
- "-Wimplicit-fallthrough",
- "-Wreorder-init-list",
- "-Werror=reorder-init-list",
- "-Wshadow-all",
- "-Wunreachable-code-aggressive",
- "-Werror",
"-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION",
"-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
+ "-Wall",
+ "-Wconditional-uninitialized",
+ "-Wdeprecated",
+ "-Werror",
+ "-Werror=format",
+ "-Werror=reorder-init-list",
+ "-Wextra",
+ "-Wextra-semi",
+ "-Wimplicit-fallthrough",
+ "-Wreorder-init-list",
+ "-Wshadow-all",
+ "-Wthread-safety",
+ "-Wunreachable-code-aggressive",
],
tidy: true,
tidy_checks: [
diff --git a/services/audiopolicy/tests/Android.bp b/services/audiopolicy/tests/Android.bp
index dc61115..4006489 100644
--- a/services/audiopolicy/tests/Android.bp
+++ b/services/audiopolicy/tests/Android.bp
@@ -12,6 +12,7 @@
name: "audiopolicy_tests",
defaults: [
+ "aconfig_lib_cc_shared_link.defaults",
"latest_android_media_audio_common_types_cpp_static",
],
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index ba0a1eb..d1dd1e9 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -72,6 +72,7 @@
*input = mNextIoHandle++;
mOpenedInputs.insert(*input);
ALOGD("%s: opened input %d", __func__, *input);
+ mOpenInputCallsCount++;
return NO_ERROR;
}
@@ -86,6 +87,7 @@
return BAD_VALUE;
}
ALOGD("%s: closed input %d", __func__, input);
+ mCloseInputCallsCount++;
return NO_ERROR;
}
@@ -260,6 +262,18 @@
auto it = mTracksInternalMute.find(portId);
return it == mTracksInternalMute.end() ? false : it->second;
}
+ void resetInputApiCallsCounters() {
+ mOpenInputCallsCount = 0;
+ mCloseInputCallsCount = 0;
+ }
+
+ size_t getCloseInputCallsCount() const {
+ return mCloseInputCallsCount;
+ }
+
+ size_t getOpenInputCallsCount() const {
+ return mOpenInputCallsCount;
+ }
private:
audio_module_handle_t mNextModuleHandle = AUDIO_MODULE_HANDLE_NONE + 1;
@@ -275,6 +289,8 @@
std::set<audio_channel_mask_t> mSupportedChannelMasks;
std::map<audio_port_handle_t, bool> mTracksInternalMute;
std::set<audio_io_handle_t> mOpenedInputs;
+ size_t mOpenInputCallsCount = 0;
+ size_t mCloseInputCallsCount = 0;
};
} // namespace android
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 4c98687..07aad0c 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -3830,3 +3830,92 @@
testing::Values(AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE,
AUDIO_USAGE_ALARM)
);
+
+class AudioPolicyManagerInputPreemptionTest : public AudioPolicyManagerTestWithConfigurationFile {
+};
+
+TEST_F_WITH_FLAGS(
+ AudioPolicyManagerInputPreemptionTest,
+ SameSessionReusesInput,
+ REQUIRES_FLAGS_ENABLED(
+ ACONFIG_FLAG(com::android::media::audioserver, fix_input_sharing_logic))
+) {
+ mClient->resetInputApiCallsCounters();
+
+ audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
+ attr.source = AUDIO_SOURCE_MIC;
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ audio_io_handle_t input1 = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input1, TEST_SESSION_ID, 1, &selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
+ 48000));
+
+ EXPECT_EQ(1, mClient->getOpenInputCallsCount());
+
+ audio_io_handle_t input2 = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input2, TEST_SESSION_ID, 1, &selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
+ 48000));
+
+ EXPECT_EQ(1, mClient->getOpenInputCallsCount());
+ EXPECT_EQ(0, mClient->getCloseInputCallsCount());
+ EXPECT_EQ(input1, input2);
+}
+
+TEST_F_WITH_FLAGS(
+ AudioPolicyManagerInputPreemptionTest,
+ LesserPriorityReusesInput,
+ REQUIRES_FLAGS_ENABLED(
+ ACONFIG_FLAG(com::android::media::audioserver, fix_input_sharing_logic))
+) {
+ mClient->resetInputApiCallsCounters();
+
+ audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
+ attr.source = AUDIO_SOURCE_MIC;
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ audio_io_handle_t input1 = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input1, TEST_SESSION_ID, 1, &selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
+ 48000));
+
+ EXPECT_EQ(1, mClient->getOpenInputCallsCount());
+
+ audio_io_handle_t input2 = AUDIO_PORT_HANDLE_NONE;
+ attr.source = AUDIO_SOURCE_VOICE_RECOGNITION;
+ ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input2, OTHER_SESSION_ID, 1, &selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
+ 48000));
+
+ EXPECT_EQ(1, mClient->getOpenInputCallsCount());
+ EXPECT_EQ(0, mClient->getCloseInputCallsCount());
+ EXPECT_EQ(input1, input2);
+}
+
+TEST_F_WITH_FLAGS(
+ AudioPolicyManagerInputPreemptionTest,
+ HigherPriorityPreemptsInput,
+ REQUIRES_FLAGS_ENABLED(
+ ACONFIG_FLAG(com::android::media::audioserver, fix_input_sharing_logic))
+) {
+ mClient->resetInputApiCallsCounters();
+
+ audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
+ attr.source = AUDIO_SOURCE_MIC;
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ audio_io_handle_t input1 = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input1, TEST_SESSION_ID, 1, &selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
+ 48000));
+
+ EXPECT_EQ(1, mClient->getOpenInputCallsCount());
+
+ audio_io_handle_t input2 = AUDIO_PORT_HANDLE_NONE;
+ attr.source = AUDIO_SOURCE_CAMCORDER;
+ ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, &input2, OTHER_SESSION_ID, 1, &selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
+ 48000));
+
+ EXPECT_EQ(2, mClient->getOpenInputCallsCount());
+ EXPECT_EQ(1, mClient->getCloseInputCallsCount());
+ EXPECT_NE(input1, input2);
+}
diff --git a/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml b/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
index bbc19fa..67e99f2 100644
--- a/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
+++ b/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
@@ -30,7 +30,7 @@
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
- <mixPort name="primary input" role="sink">
+ <mixPort name="primary input" role="sink" maxActiveCount="1" maxOpenCount="1">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index acc3b32..13cffa7 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -513,7 +513,7 @@
void CameraService::onDeviceStatusChanged(const std::string& cameraId,
CameraDeviceStatus newHalStatus) {
ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
- cameraId.c_str(), newHalStatus);
+ cameraId.c_str(), eToI(newHalStatus));
StatusInternal newStatus = mapToInternal(newHalStatus);
@@ -537,7 +537,8 @@
StatusInternal oldStatus = state->getStatus();
if (oldStatus == newStatus) {
- ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus);
+ ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__,
+ eToI(newStatus));
return;
}
@@ -580,7 +581,7 @@
const std::string& physicalId,
CameraDeviceStatus newHalStatus) {
ALOGI("%s: Status changed for cameraId=%s, physicalCameraId=%s, newStatus=%d",
- __FUNCTION__, id.c_str(), physicalId.c_str(), newHalStatus);
+ __FUNCTION__, id.c_str(), physicalId.c_str(), eToI(newHalStatus));
StatusInternal newStatus = mapToInternal(newHalStatus);
@@ -596,7 +597,7 @@
if (logicalCameraStatus != StatusInternal::PRESENT &&
logicalCameraStatus != StatusInternal::NOT_AVAILABLE) {
ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
- __FUNCTION__, physicalId.c_str(), newHalStatus, logicalCameraStatus);
+ __FUNCTION__, physicalId.c_str(), eToI(newHalStatus), eToI(logicalCameraStatus));
return;
}
@@ -688,7 +689,7 @@
void CameraService::onTorchStatusChangedLocked(const std::string& cameraId,
TorchModeStatus newStatus, SystemCameraKind systemCameraKind) {
ALOGI("%s: Torch status changed for cameraId=%s, newStatus=%d",
- __FUNCTION__, cameraId.c_str(), newStatus);
+ __FUNCTION__, cameraId.c_str(), eToI(newStatus));
TorchModeStatus status;
status_t res = getTorchStatusLocked(cameraId, &status);
@@ -783,12 +784,13 @@
return true;
}
-Status CameraService::getNumberOfCameras(int32_t type, int32_t deviceId, int32_t devicePolicy,
+Status CameraService::getNumberOfCameras(int32_t type,
+ const AttributionSourceState& clientAttribution, int32_t devicePolicy,
int32_t* numCameras) {
ATRACE_CALL();
- if (vd_flags::camera_device_awareness() && (deviceId != kDefaultDeviceId)
+ if (vd_flags::camera_device_awareness() && (clientAttribution.deviceId != kDefaultDeviceId)
&& (devicePolicy != IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT)) {
- *numCameras = mVirtualDeviceCameraIdMapper.getNumberOfCameras(deviceId);
+ *numCameras = mVirtualDeviceCameraIdMapper.getNumberOfCameras(clientAttribution.deviceId);
return Status::ok();
}
@@ -821,7 +823,7 @@
}
Status CameraService::createDefaultRequest(const std::string& unresolvedCameraId, int templateId,
- int32_t deviceId, int32_t devicePolicy,
+ const AttributionSourceState& clientAttribution, int32_t devicePolicy,
/* out */
hardware::camera2::impl::CameraMetadataNative* request) {
ATRACE_CALL();
@@ -836,11 +838,11 @@
return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem is not available");
}
- std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy);
+ std::optional<std::string> cameraIdOptional =
+ resolveCameraId(unresolvedCameraId, clientAttribution.deviceId, devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
- unresolvedCameraId.c_str(), deviceId);
+ unresolvedCameraId.c_str(), clientAttribution.deviceId);
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
@@ -885,7 +887,7 @@
Status CameraService::isSessionConfigurationWithParametersSupported(
const std::string& unresolvedCameraId, int targetSdkVersion,
const SessionConfiguration& sessionConfiguration,
- int32_t deviceId, int32_t devicePolicy,
+ const AttributionSourceState& clientAttribution, int32_t devicePolicy,
/*out*/ bool* supported) {
ATRACE_CALL();
@@ -899,11 +901,11 @@
return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem is not available");
}
- std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy);
+ std::optional<std::string> cameraIdOptional =
+ resolveCameraId(unresolvedCameraId, clientAttribution.deviceId, devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
- unresolvedCameraId.c_str(), deviceId);
+ unresolvedCameraId.c_str(), clientAttribution.deviceId);
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
@@ -982,7 +984,8 @@
Status CameraService::getSessionCharacteristics(const std::string& unresolvedCameraId,
int targetSdkVersion, int rotationOverride,
- const SessionConfiguration& sessionConfiguration, int32_t deviceId, int32_t devicePolicy,
+ const SessionConfiguration& sessionConfiguration,
+ const AttributionSourceState& clientAttribution, int32_t devicePolicy,
/*out*/ CameraMetadata* outMetadata) {
ATRACE_CALL();
@@ -999,11 +1002,11 @@
return STATUS_ERROR(ERROR_DISCONNECTED, "Camera subsystem is not available");
}
- std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy);
+ std::optional<std::string> cameraIdOptional =
+ resolveCameraId(unresolvedCameraId, clientAttribution.deviceId, devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
- unresolvedCameraId.c_str(), deviceId);
+ unresolvedCameraId.c_str(), clientAttribution.deviceId);
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
@@ -1205,14 +1208,16 @@
return mVirtualDeviceCameraIdMapper.getActualCameraId(deviceId, inputCameraId);
}
-Status CameraService::getCameraInfo(int cameraId, int rotationOverride, int32_t deviceId,
- int32_t devicePolicy, CameraInfo* cameraInfo) {
+Status CameraService::getCameraInfo(int cameraId, int rotationOverride,
+ const AttributionSourceState& clientAttribution, int32_t devicePolicy,
+ CameraInfo* cameraInfo) {
ATRACE_CALL();
Mutex::Autolock l(mServiceLock);
- std::string cameraIdStr = cameraIdIntToStrLocked(cameraId, deviceId, devicePolicy);
+ std::string cameraIdStr =
+ cameraIdIntToStrLocked(cameraId, clientAttribution.deviceId, devicePolicy);
if (cameraIdStr.empty()) {
std::string msg = fmt::sprintf("Camera %d: Invalid camera id for device id %d",
- cameraId, deviceId);
+ cameraId, clientAttribution.deviceId);
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
@@ -1286,8 +1291,8 @@
}
Status CameraService::getCameraCharacteristics(const std::string& unresolvedCameraId,
- int targetSdkVersion, int rotationOverride, int32_t deviceId, int32_t devicePolicy,
- CameraMetadata* cameraInfo) {
+ int targetSdkVersion, int rotationOverride, const AttributionSourceState& clientAttribution,
+ int32_t devicePolicy, CameraMetadata* cameraInfo) {
ATRACE_CALL();
if (!cameraInfo) {
@@ -1302,11 +1307,11 @@
"Camera subsystem is not available");;
}
- std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy);
+ std::optional<std::string> cameraIdOptional =
+ resolveCameraId(unresolvedCameraId, clientAttribution.deviceId, devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
- unresolvedCameraId.c_str(), deviceId);
+ unresolvedCameraId.c_str(), clientAttribution.deviceId);
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
@@ -1339,16 +1344,17 @@
return filterSensitiveMetadataIfNeeded(cameraId, cameraInfo);
}
-Status CameraService::getTorchStrengthLevel(const std::string& unresolvedCameraId, int32_t deviceId,
+Status CameraService::getTorchStrengthLevel(const std::string& unresolvedCameraId,
+ const AttributionSourceState& clientAttribution,
int32_t devicePolicy, int32_t* torchStrength) {
ATRACE_CALL();
Mutex::Autolock l(mServiceLock);
- std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy);
+ std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId,
+ clientAttribution.deviceId, devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
- unresolvedCameraId.c_str(), deviceId);
+ unresolvedCameraId.c_str(), clientAttribution.deviceId);
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
@@ -1552,7 +1558,7 @@
serviceStatus = ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON;
break;
default:
- ALOGW("Unknown new flash status: %d", status);
+ ALOGW("Unknown new flash status: %d", eToI(status));
}
return serviceStatus;
}
@@ -1570,7 +1576,7 @@
serviceStatus = StatusInternal::ENUMERATING;
break;
default:
- ALOGW("Unknown new HAL device status: %d", status);
+ ALOGW("Unknown new HAL device status: %d", eToI(status));
}
return serviceStatus;
}
@@ -1594,7 +1600,7 @@
serviceStatus = ICameraServiceListener::STATUS_UNKNOWN;
break;
default:
- ALOGW("Unknown new internal device status: %d", status);
+ ALOGW("Unknown new internal device status: %d", eToI(status));
}
return serviceStatus;
}
@@ -2129,29 +2135,29 @@
const sp<ICameraClient>& cameraClient,
int api1CameraId,
const std::string& clientPackageName,
- int clientUid,
- int clientPid,
int targetSdkVersion,
int rotationOverride,
bool forceSlowJpegMode,
- int32_t deviceId,
+ const AttributionSourceState& clientAttribution,
int32_t devicePolicy,
/*out*/
sp<ICamera>* device) {
ATRACE_CALL();
Status ret = Status::ok();
- std::string cameraIdStr = cameraIdIntToStr(api1CameraId, deviceId, devicePolicy);
+ std::string cameraIdStr =
+ cameraIdIntToStr(api1CameraId, clientAttribution.deviceId, devicePolicy);
if (cameraIdStr.empty()) {
std::string msg = fmt::sprintf("Camera %d: Invalid camera id for device id %d",
- api1CameraId, deviceId);
+ api1CameraId, clientAttribution.deviceId);
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
sp<Client> client = nullptr;
ret = connectHelper<ICameraClient,Client>(cameraClient, cameraIdStr, api1CameraId,
- clientPackageName, /*systemNativeClient*/ false, {}, clientUid, clientPid, API_1,
+ clientPackageName, /*systemNativeClient*/ false, {}, clientAttribution.uid,
+ clientAttribution.pid, API_1,
/*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, targetSdkVersion,
rotationOverride, forceSlowJpegMode, cameraIdStr, /*out*/client);
@@ -2235,8 +2241,8 @@
const std::string& unresolvedCameraId,
const std::string& clientPackageName,
const std::optional<std::string>& clientFeatureId,
- int clientUid, int oomScoreOffset, int targetSdkVersion,
- int rotationOverride, int32_t deviceId, int32_t devicePolicy,
+ int oomScoreOffset, int targetSdkVersion,
+ int rotationOverride, const AttributionSourceState& clientAttribution, int32_t devicePolicy,
/*out*/
sp<hardware::camera2::ICameraDeviceUser>* device) {
ATRACE_CALL();
@@ -2253,11 +2259,11 @@
systemNativeClient = true;
}
- std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy);
+ std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId,
+ clientAttribution.deviceId, devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
- unresolvedCameraId.c_str(), deviceId);
+ unresolvedCameraId.c_str(), clientAttribution.deviceId);
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
@@ -2272,8 +2278,8 @@
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
- userid_t clientUserId = multiuser_get_user_id(clientUid);
- if (clientUid == USE_CALLING_UID) {
+ userid_t clientUserId = multiuser_get_user_id(clientAttribution.uid);
+ if (clientAttribution.uid == USE_CALLING_UID) {
clientUserId = multiuser_get_user_id(callingUid);
}
@@ -2300,9 +2306,9 @@
ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb,
cameraId, /*api1CameraId*/-1, clientPackageNameAdj, systemNativeClient, clientFeatureId,
- clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, oomScoreOffset,
- targetSdkVersion, rotationOverride, /*forceSlowJpegMode*/false, unresolvedCameraId,
- /*out*/client);
+ clientAttribution.uid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false,
+ oomScoreOffset, targetSdkVersion, rotationOverride, /*forceSlowJpegMode*/false,
+ unresolvedCameraId, /*out*/client);
if (!ret.isOk()) {
logRejected(cameraId, callingPid, clientPackageNameAdj, toStdString(ret.toString8()));
@@ -2825,8 +2831,8 @@
}
Status CameraService::turnOnTorchWithStrengthLevel(const std::string& unresolvedCameraId,
- int32_t torchStrength, const sp<IBinder>& clientBinder, int32_t deviceId,
- int32_t devicePolicy) {
+ int32_t torchStrength, const sp<IBinder>& clientBinder,
+ const AttributionSourceState& clientAttribution, int32_t devicePolicy) {
Mutex::Autolock lock(mServiceLock);
ATRACE_CALL();
@@ -2837,11 +2843,11 @@
}
int uid = getCallingUid();
- std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy);
+ std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId,
+ clientAttribution.deviceId, devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
- unresolvedCameraId.c_str(), deviceId);
+ unresolvedCameraId.c_str(), clientAttribution.deviceId);
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
@@ -2963,7 +2969,8 @@
}
Status CameraService::setTorchMode(const std::string& unresolvedCameraId, bool enabled,
- const sp<IBinder>& clientBinder, int32_t deviceId, int32_t devicePolicy) {
+ const sp<IBinder>& clientBinder, const AttributionSourceState& clientAttribution,
+ int32_t devicePolicy) {
Mutex::Autolock lock(mServiceLock);
ATRACE_CALL();
@@ -2974,11 +2981,11 @@
}
int uid = getCallingUid();
- std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId, deviceId,
- devicePolicy);
+ std::optional<std::string> cameraIdOptional = resolveCameraId(unresolvedCameraId,
+ clientAttribution.deviceId, devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
- unresolvedCameraId.c_str(), deviceId);
+ unresolvedCameraId.c_str(), clientAttribution.deviceId);
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
@@ -3309,7 +3316,7 @@
Status CameraService::isConcurrentSessionConfigurationSupported(
const std::vector<CameraIdAndSessionConfiguration>& cameraIdsAndSessionConfigurations,
- int targetSdkVersion, int32_t deviceId, int32_t devicePolicy,
+ int targetSdkVersion, const AttributionSourceState& clientAttribution, int32_t devicePolicy,
/*out*/bool* isSupported) {
if (!isSupported) {
ALOGE("%s: isSupported is NULL", __FUNCTION__);
@@ -3324,10 +3331,11 @@
for (auto cameraIdAndSessionConfiguration : cameraIdsAndSessionConfigurations) {
std::optional<std::string> cameraIdOptional =
- resolveCameraId(cameraIdAndSessionConfiguration.mCameraId, deviceId, devicePolicy);
+ resolveCameraId(cameraIdAndSessionConfiguration.mCameraId,
+ clientAttribution.deviceId, devicePolicy);
if (!cameraIdOptional.has_value()) {
std::string msg = fmt::sprintf("Camera %s: Invalid camera id for device id %d",
- cameraIdAndSessionConfiguration.mCameraId.c_str(), deviceId);
+ cameraIdAndSessionConfiguration.mCameraId.c_str(), clientAttribution.deviceId);
ALOGE("%s: %s", __FUNCTION__, msg.c_str());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
}
@@ -3340,7 +3348,7 @@
bool hasCameraPermission = ((callingPid == getpid()) ||
hasPermissionsForCamera(callingPid, callingUid,
devicePolicy == IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT
- ? kDefaultDeviceId : deviceId));
+ ? kDefaultDeviceId : clientAttribution.deviceId));
if (!hasCameraPermission) {
return STATUS_ERROR(ERROR_PERMISSION_DENIED,
"android.permission.CAMERA needed to call"
@@ -5777,7 +5785,7 @@
}
ALOGV("%s: Status has changed for camera ID %s from %#x to %#x", __FUNCTION__,
- cameraId.c_str(), oldStatus, status);
+ cameraId.c_str(), eToI(oldStatus), eToI(status));
if (oldStatus == StatusInternal::NOT_PRESENT &&
(status != StatusInternal::PRESENT &&
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 9998fb8..3866c12 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -154,13 +154,16 @@
// resolveCameraId(logicalCameraId, deviceId, devicePolicy) to arrive at the correct
// cameraId to perform the operation on (in case of contexts
// associated with virtual devices).
- virtual binder::Status getNumberOfCameras(int32_t type, int32_t deviceId,
+ virtual binder::Status getNumberOfCameras(int32_t type,
+ const AttributionSourceState& clientAttribution,
int32_t devicePolicy, int32_t* numCameras);
virtual binder::Status getCameraInfo(int cameraId, int rotationOverride,
- int32_t deviceId, int32_t devicePolicy, hardware::CameraInfo* cameraInfo) override;
+ const AttributionSourceState& clientAttribution,
+ int32_t devicePolicy, hardware::CameraInfo* cameraInfo) override;
virtual binder::Status getCameraCharacteristics(const std::string& cameraId,
- int targetSdkVersion, int rotationOverride, int32_t deviceId,
+ int targetSdkVersion, int rotationOverride,
+ const AttributionSourceState& clientAttribution,
int32_t devicePolicy, CameraMetadata* cameraInfo) override;
virtual binder::Status getCameraVendorTagDescriptor(
/*out*/
@@ -171,16 +174,16 @@
virtual binder::Status connect(const sp<hardware::ICameraClient>& cameraClient,
int32_t cameraId, const std::string& clientPackageName,
- int32_t clientUid, int clientPid, int targetSdkVersion,
- int rotationOverride, bool forceSlowJpegMode, int32_t deviceId,
+ int targetSdkVersion, int rotationOverride, bool forceSlowJpegMode,
+ const AttributionSourceState& clientAttribution,
int32_t devicePolicy, /*out*/ sp<hardware::ICamera>* device) override;
virtual binder::Status connectDevice(
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
const std::string& cameraId,
const std::string& clientPackageName, const std::optional<std::string>& clientFeatureId,
- int32_t clientUid, int scoreOffset, int targetSdkVersion, int rotationOverride,
- int32_t deviceId, int32_t devicePolicy,
+ int scoreOffset, int targetSdkVersion, int rotationOverride,
+ const AttributionSourceState& clientAttribution, int32_t devicePolicy,
/*out*/
sp<hardware::camera2::ICameraDeviceUser>* device);
@@ -196,7 +199,7 @@
virtual binder::Status isConcurrentSessionConfigurationSupported(
const std::vector<hardware::camera2::utils::CameraIdAndSessionConfiguration>& sessions,
- int targetSdkVersion, int32_t deviceId, int32_t devicePolicy,
+ int targetSdkVersion, const AttributionSourceState& clientAttribution, int32_t devicePolicy,
/*out*/bool* supported);
virtual binder::Status getLegacyParameters(
@@ -205,13 +208,16 @@
std::string* parameters);
virtual binder::Status setTorchMode(const std::string& cameraId, bool enabled,
- const sp<IBinder>& clientBinder, int32_t deviceId, int32_t devicePolicy);
-
- virtual binder::Status turnOnTorchWithStrengthLevel(const std::string& cameraId,
- int32_t torchStrength, const sp<IBinder>& clientBinder, int32_t deviceId,
+ const sp<IBinder>& clientBinder, const AttributionSourceState& clientAttribution,
int32_t devicePolicy);
- virtual binder::Status getTorchStrengthLevel(const std::string& cameraId, int32_t deviceId,
+ virtual binder::Status turnOnTorchWithStrengthLevel(const std::string& cameraId,
+ int32_t torchStrength, const sp<IBinder>& clientBinder,
+ const AttributionSourceState& clientAttribution,
+ int32_t devicePolicy);
+
+ virtual binder::Status getTorchStrengthLevel(const std::string& cameraId,
+ const AttributionSourceState& clientAttribution,
int32_t devicePolicy, int32_t* torchStrength);
virtual binder::Status notifySystemEvent(int32_t eventId,
@@ -247,19 +253,20 @@
const hardware::camera2::impl::CameraMetadataNative& sessionParams);
virtual binder::Status createDefaultRequest(const std::string& cameraId, int templateId,
- int32_t deviceId, int32_t devicePolicy,
+ const AttributionSourceState& clientAttribution, int32_t devicePolicy,
/*out*/
hardware::camera2::impl::CameraMetadataNative* request);
virtual binder::Status isSessionConfigurationWithParametersSupported(
const std::string& cameraId, int targetSdkVersion,
const SessionConfiguration& sessionConfiguration,
- int32_t deviceId, int32_t devicePolicy,
+ const AttributionSourceState& clientAttribution, int32_t devicePolicy,
/*out*/ bool* supported);
virtual binder::Status getSessionCharacteristics(
const std::string& cameraId, int targetSdkVersion, int rotationOverride,
- const SessionConfiguration& sessionConfiguration, int32_t deviceId,
+ const SessionConfiguration& sessionConfiguration,
+ const AttributionSourceState& clientAttribution,
int32_t devicePolicy, /*out*/ CameraMetadata* outMetadata);
// Extra permissions checks
diff --git a/services/camera/libcameraservice/aidl/AidlCameraService.cpp b/services/camera/libcameraservice/aidl/AidlCameraService.cpp
index 2886942..8923655 100644
--- a/services/camera/libcameraservice/aidl/AidlCameraService.cpp
+++ b/services/camera/libcameraservice/aidl/AidlCameraService.cpp
@@ -28,6 +28,7 @@
#include <binder/Status.h>
#include <camera/CameraUtils.h>
#include <hidl/HidlTransportSupport.h>
+#include <utils/AttributionAndPermissionUtils.h>
#include <utils/Utils.h>
namespace android::frameworks::cameraservice::service::implementation {
@@ -89,10 +90,15 @@
if (_aidl_return == nullptr) { return fromSStatus(SStatus::ILLEGAL_ARGUMENT); }
::android::CameraMetadata cameraMetadata;
+ AttributionSourceState clientAttribution =
+ AttributionAndPermissionUtils::buildAttributionSource(
+ hardware::ICameraService::USE_CALLING_PID,
+ hardware::ICameraService::USE_CALLING_UID,
+ kDefaultDeviceId);
UStatus ret = mCameraService->getCameraCharacteristics(in_cameraId,
mVndkVersion,
ROTATION_OVERRIDE_NONE,
- kDefaultDeviceId,
+ clientAttribution,
/* devicePolicy= */ 0,
&cameraMetadata);
if (!ret.isOk()) {
@@ -143,16 +149,20 @@
return fromSStatus(SStatus::UNKNOWN_ERROR);
}
sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
+ AttributionSourceState clientAttribution =
+ AttributionAndPermissionUtils::buildAttributionSource(
+ hardware::ICameraService::USE_CALLING_PID,
+ hardware::ICameraService::USE_CALLING_UID,
+ kDefaultDeviceId);
binder::Status serviceRet = mCameraService->connectDevice(
callbacks,
in_cameraId,
std::string(),
/* clientFeatureId= */{},
- hardware::ICameraService::USE_CALLING_UID,
/* scoreOffset= */ 0,
/* targetSdkVersion= */ __ANDROID_API_FUTURE__,
ROTATION_OVERRIDE_NONE,
- kDefaultDeviceId,
+ clientAttribution,
/* devicePolicy= */ 0,
&unstableDevice);
if (!serviceRet.isOk()) {
diff --git a/services/camera/libcameraservice/aidl/AidlUtils.cpp b/services/camera/libcameraservice/aidl/AidlUtils.cpp
index d23566c..1ec5072 100644
--- a/services/camera/libcameraservice/aidl/AidlUtils.cpp
+++ b/services/camera/libcameraservice/aidl/AidlUtils.cpp
@@ -26,6 +26,7 @@
#include <device3/Camera3StreamInterface.h>
#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
#include <mediautils/AImageReaderUtils.h>
+#include "utils/Utils.h"
namespace android::hardware::cameraservice::utils::conversion::aidl {
@@ -347,8 +348,8 @@
// Ensure the vendor ID are the same before attempting
// anything else. If vendor IDs differ we cannot safely copy the characteristics.
if (from.getVendorId() != to->getVendorId()) {
- ALOGE("%s: Incompatible CameraMetadata objects. Vendor IDs differ. From: %lu; To: %lu",
- __FUNCTION__, from.getVendorId(), to->getVendorId());
+ ALOGE("%s: Incompatible CameraMetadata objects. Vendor IDs differ. From: %" PRIu64
+ "; To: %" PRIu64, __FUNCTION__, from.getVendorId(), to->getVendorId());
return BAD_VALUE;
}
@@ -364,7 +365,7 @@
for (size_t i = 0; i < get_camera_metadata_entry_count(src); i++) {
int ret = get_camera_metadata_ro_entry(src, i, &entry);
if (ret != OK) {
- ALOGE("%s: Could not fetch entry at index %lu. Error: %d", __FUNCTION__, i, ret);
+ ALOGE("%s: Could not fetch entry at index %zu. Error: %d", __FUNCTION__, i, ret);
from.unlock(src);
return BAD_VALUE;
}
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index c995cbe..ea4f6fd 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -40,6 +40,7 @@
#include "common/CameraDeviceBase.h"
#include "utils/ExifUtils.h"
#include "utils/SessionConfigurationUtils.h"
+#include "utils/Utils.h"
#include "HeicEncoderInfoManager.h"
#include "HeicCompositeStream.h"
@@ -1464,7 +1465,7 @@
const uint8_t *header = appSegmentBuffer + (maxSize - sizeof(CameraBlob));
const CameraBlob *blob = (const CameraBlob*)(header);
if (blob->blobId != CameraBlobId::JPEG_APP_SEGMENTS) {
- ALOGE("%s: Invalid EXIF blobId %d", __FUNCTION__, blob->blobId);
+ ALOGE("%s: Invalid EXIF blobId %d", __FUNCTION__, eToI(blob->blobId));
return 0;
}
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 6416c11..2440c37 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -51,6 +51,7 @@
#include "api2/HeicCompositeStream.h"
#include "device3/ZoomRatioMapper.h"
+#include "utils/Utils.h"
namespace android {
@@ -92,7 +93,7 @@
case TorchModeStatus::AVAILABLE_ON:
return "AVAILABLE_ON";
}
- ALOGW("Unexpected HAL torch mode status code %d", s);
+ ALOGW("Unexpected HAL torch mode status code %d", eToI(s));
return "UNKNOWN_STATUS";
}
@@ -105,7 +106,7 @@
case CameraDeviceStatus::ENUMERATING:
return "ENUMERATING";
}
- ALOGW("Unexpected HAL device status code %d", s);
+ ALOGW("Unexpected HAL device status code %d", eToI(s));
return "UNKNOWN_STATUS";
}
@@ -2279,7 +2280,7 @@
return tryToInitializeAidlProviderLocked(removedAidlProviderName,
providerInfo);
default:
- ALOGE("%s Unsupported Transport %d", __FUNCTION__, providerTransport);
+ ALOGE("%s Unsupported Transport %d", __FUNCTION__, eToI(providerTransport));
}
}
}
@@ -2366,7 +2367,7 @@
}
break;
default:
- ALOGE("%s Invalid transport %d", __FUNCTION__, transport);
+ ALOGE("%s Invalid transport %d", __FUNCTION__, eToI(transport));
return BAD_VALUE;
}
@@ -2712,7 +2713,7 @@
}
if (!known) {
ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
- mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
+ mProviderName.c_str(), cameraDeviceName.c_str(), eToI(newStatus));
return;
}
// no lock needed since listener is set up only once during
diff --git a/services/camera/libcameraservice/common/HalConversionsTemplated.h b/services/camera/libcameraservice/common/HalConversionsTemplated.h
index 96a715c..c586062 100644
--- a/services/camera/libcameraservice/common/HalConversionsTemplated.h
+++ b/services/camera/libcameraservice/common/HalConversionsTemplated.h
@@ -19,6 +19,7 @@
#include "common/CameraProviderManager.h"
#include <device3/Camera3StreamInterface.h>
+#include <utils/Utils.h>
namespace android {
@@ -48,7 +49,7 @@
case HalCameraDeviceStatus::ENUMERATING:
return CameraDeviceStatus::ENUMERATING;
}
- ALOGW("Unexpectedcamera device status code %d", s);
+ ALOGW("Unexpectedcamera device status code %d", eToI(s));
return CameraDeviceStatus::NOT_PRESENT;
}
@@ -74,7 +75,7 @@
case HalTorchModeStatus::AVAILABLE_ON:
return TorchModeStatus::AVAILABLE_ON;
}
- ALOGW("Unexpectedcamera torch mode status code %d", s);
+ ALOGW("Unexpectedcamera torch mode status code %d", eToI(s));
return TorchModeStatus::NOT_AVAILABLE;
}
@@ -88,7 +89,7 @@
case HalCameraDeviceStatus::ENUMERATING:
return "ENUMERATING";
}
- ALOGW("Unexpected HAL device status code %d", s);
+ ALOGW("Unexpected HAL device status code %d", eToI(s));
return "UNKNOWN_STATUS";
}
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index 1e546fb..40800d9 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -26,6 +26,7 @@
#include "device3/ZoomRatioMapper.h"
#include <utils/SessionConfigurationUtilsHidl.h>
#include <utils/Trace.h>
+#include <utils/Utils.h>
#include <android/hardware/camera/device/3.7/ICameraDevice.h>
@@ -69,7 +70,7 @@
case Status::INTERNAL_ERROR:
return INVALID_OPERATION;
}
- ALOGW("Unexpected HAL status code %d", s);
+ ALOGW("Unexpected HAL status code %d", eToI(s));
return INVALID_OPERATION;
}
@@ -111,7 +112,7 @@
case Status::INTERNAL_ERROR:
return "INTERNAL_ERROR";
}
- ALOGW("Unexpected HAL status code %d", s);
+ ALOGW("Unexpected HAL status code %d", eToI(s));
return "UNKNOWN_ERROR";
}
@@ -591,7 +592,7 @@
}
if (status != Status::OK) {
ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
- __FUNCTION__, id.c_str(), statusToString(status), status);
+ __FUNCTION__, id.c_str(), statusToString(status), eToI(status));
return;
}
@@ -770,7 +771,7 @@
if (status != Status::OK) {
ALOGE("%s: Unable to get physical camera %s characteristics for device %s: %s (%d)",
__FUNCTION__, id.c_str(), mId.c_str(),
- statusToString(status), status);
+ statusToString(status), eToI(status));
return;
}
@@ -928,7 +929,7 @@
res = INVALID_OPERATION;
break;
default:
- ALOGE("%s: Session configuration query failed: %d", __FUNCTION__, callStatus);
+ ALOGE("%s: Session configuration query failed: %d", __FUNCTION__, eToI(callStatus));
res = UNKNOWN_ERROR;
}
} else {
@@ -1076,7 +1077,7 @@
break;
default:
ALOGE("%s: Session configuration query failed: %d", __FUNCTION__,
- callStatus);
+ eToI(callStatus));
res = UNKNOWN_ERROR;
}
} else {
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
index 9dacaf6..09299e6 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
@@ -56,6 +56,7 @@
#include "device3/hidl/HidlCamera3OfflineSession.h"
#include "utils/SessionConfigurationUtilsHidl.h"
#include "utils/TraceHFR.h"
+#include "utils/Utils.h"
#include "../../common/hidl/HidlProviderInfo.h"
#include "HidlCamera3Device.h"
@@ -881,7 +882,7 @@
ret = true;
break;
default:
- ALOGV("%s: Reconfiguration query failed: %d", __FUNCTION__, callStatus);
+ ALOGV("%s: Reconfiguration query failed: %d", __FUNCTION__, eToI(callStatus));
ret = true;
}
} else {
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index d3b2a51..463aefb 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -26,6 +26,7 @@
#include <hidl/HidlTransportSupport.h>
#include <camera/CameraUtils.h>
+#include <utils/AttributionAndPermissionUtils.h>
#include <utils/Utils.h>
namespace android {
@@ -68,10 +69,15 @@
getCameraCharacteristics_cb _hidl_cb) {
android::CameraMetadata cameraMetadata;
HStatus status = HStatus::NO_ERROR;
+ AttributionSourceState clientAttribution =
+ AttributionAndPermissionUtils::buildAttributionSource(
+ hardware::ICameraService::USE_CALLING_PID,
+ hardware::ICameraService::USE_CALLING_UID,
+ kDefaultDeviceId);
binder::Status serviceRet =
mAidlICameraService->getCameraCharacteristics(cameraId,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, ROTATION_OVERRIDE_NONE,
- kDefaultDeviceId, 0, &cameraMetadata);
+ clientAttribution, 0, &cameraMetadata);
HCameraMetadata hidlMetadata;
if (!serviceRet.isOk()) {
switch(serviceRet.serviceSpecificErrorCode()) {
@@ -119,11 +125,15 @@
return Void();
}
sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
+ AttributionSourceState clientAttribution =
+ AttributionAndPermissionUtils::buildAttributionSource(
+ hardware::ICameraService::USE_CALLING_PID,
+ hardware::ICameraService::USE_CALLING_UID,
+ kDefaultDeviceId);
binder::Status serviceRet = mAidlICameraService->connectDevice(
- callbacks, cameraId, std::string(), {},
- hardware::ICameraService::USE_CALLING_UID, 0/*oomScoreOffset*/,
+ callbacks, cameraId, std::string(), {}, 0/*oomScoreOffset*/,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, ROTATION_OVERRIDE_NONE,
- kDefaultDeviceId, /*devicePolicy*/0, /*out*/&deviceRemote);
+ clientAttribution, /*devicePolicy*/0, /*out*/&deviceRemote);
HStatus status = HStatus::NO_ERROR;
if (!serviceRet.isOk()) {
ALOGE("%s: Unable to connect to camera device", __FUNCTION__);
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
index c710671..53234f0 100644
--- a/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/Android.bp
@@ -35,6 +35,7 @@
"libmedia_headers",
],
shared_libs: [
+ "framework-permission-aidl-cpp",
"libbinder",
"libbase",
"libutils",
@@ -85,7 +86,7 @@
"camera_service_fuzzer.cpp",
],
defaults: [
- "camera_service_fuzzer_defaults"
+ "camera_service_fuzzer_defaults",
],
}
diff --git a/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
index bce0faf..515a2a7 100644
--- a/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
+++ b/services/camera/libcameraservice/libcameraservice_fuzzer/camera_service_fuzzer.cpp
@@ -23,6 +23,7 @@
#include <CameraService.h>
#include <device3/Camera3StreamInterface.h>
+#include <android/content/AttributionSourceState.h>
#include <android/hardware/BnCameraServiceListener.h>
#include <android/hardware/camera2/BnCameraDeviceCallbacks.h>
#include <android/hardware/ICameraServiceListener.h>
@@ -219,7 +220,9 @@
} else {
camType = kCamType[mFuzzedDataProvider->ConsumeBool()];
}
- mCameraService->getNumberOfCameras(camType, kDefaultDeviceId, /*devicePolicy*/0, &mNumCameras);
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
+ mCameraService->getNumberOfCameras(camType, clientAttribution, /*devicePolicy*/0, &mNumCameras);
}
void CameraFuzzer::getCameraInformation(int32_t cameraId) {
@@ -238,14 +241,17 @@
hardware::camera2::params::VendorTagDescriptorCache cache;
mCameraService->getCameraVendorTagCache(&cache);
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
+
CameraInfo cameraInfo;
- mCameraService->getCameraInfo(cameraId, ROTATION_OVERRIDE_NONE, kDefaultDeviceId,
+ mCameraService->getCameraInfo(cameraId, ROTATION_OVERRIDE_NONE, clientAttribution,
/*devicePolicy*/0, &cameraInfo);
CameraMetadata metadata;
mCameraService->getCameraCharacteristics(cameraIdStr,
/*targetSdkVersion*/__ANDROID_API_FUTURE__, ROTATION_OVERRIDE_NONE,
- kDefaultDeviceId, /*devicePolicy*/0, &metadata);
+ clientAttribution, /*devicePolicy*/0, &metadata);
}
void CameraFuzzer::invokeCameraSound() {
@@ -327,13 +333,15 @@
std::string cameraIdStr = std::to_string(cameraId);
sp<IBinder> binder = new BBinder;
- mCameraService->setTorchMode(cameraIdStr, true, binder, kDefaultDeviceId, /*devicePolicy*/0);
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
+ mCameraService->setTorchMode(cameraIdStr, true, binder, clientAttribution, /*devicePolicy*/0);
ALOGV("Turned torch on.");
int32_t torchStrength = rand() % 5 + 1;
ALOGV("Changing torch strength level to %d", torchStrength);
mCameraService->turnOnTorchWithStrengthLevel(cameraIdStr, torchStrength, binder,
- kDefaultDeviceId, /*devicePolicy*/0);
- mCameraService->setTorchMode(cameraIdStr, false, binder, kDefaultDeviceId, /*devicePolicy*/0);
+ clientAttribution, /*devicePolicy*/0);
+ mCameraService->setTorchMode(cameraIdStr, false, binder, clientAttribution, /*devicePolicy*/0);
ALOGV("Turned torch off.");
}
@@ -349,13 +357,15 @@
::android::binder::Status rc;
sp<ICamera> cameraDevice;
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
+ clientAttribution.uid = android::CameraService::USE_CALLING_UID;
+ clientAttribution.pid = android::CameraService::USE_CALLING_PID;
rc = mCameraService->connect(this, cameraId, std::string(),
- android::CameraService::USE_CALLING_UID,
- android::CameraService::USE_CALLING_PID,
/*targetSdkVersion*/ __ANDROID_API_FUTURE__,
ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT,
/*forceSlowJpegMode*/false,
- kDefaultDeviceId, /*devicePolicy*/0, &cameraDevice);
+ clientAttribution, /*devicePolicy*/0, &cameraDevice);
if (!rc.isOk()) {
// camera not connected
return;
@@ -590,11 +600,14 @@
for (auto s : statuses) {
sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
sp<hardware::camera2::ICameraDeviceUser> device;
+
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
+ clientAttribution.uid = android::CameraService::USE_CALLING_UID;
mCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
- android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
- /*targetSdkVersion*/__ANDROID_API_FUTURE__,
+ 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT,
- kDefaultDeviceId, /*devicePolicy*/0, &device);
+ clientAttribution, /*devicePolicy*/0, &device);
if (device == nullptr) {
continue;
}
diff --git a/services/camera/libcameraservice/tests/Android.bp b/services/camera/libcameraservice/tests/Android.bp
index 55e2c9d..8bb5ffa 100644
--- a/services/camera/libcameraservice/tests/Android.bp
+++ b/services/camera/libcameraservice/tests/Android.bp
@@ -30,7 +30,7 @@
"ExifUtilsTest.cpp",
"NV12Compressor.cpp",
"RotateAndCropMapperTest.cpp",
- "SessionStatsBuilderTest.cpp",
+ "SessionStatsBuilderTest.cpp",
"ZoomRatioTest.cpp",
],
@@ -76,7 +76,7 @@
defaults: [
"libcameraservice_deps",
- "cameraservice_test_hostsupported"
+ "cameraservice_test_hostsupported",
],
// Only include libs that can't be run host-side here
@@ -118,13 +118,13 @@
name: "cameraservice_test_host",
defaults: [
- "cameraservice_test_hostsupported"
+ "cameraservice_test_hostsupported",
],
include_dirs: [
"frameworks/av/camera/include",
"frameworks/av/camera/include/camera",
- "frameworks/native/libs/binder/include_activitymanager"
+ "frameworks/native/libs/binder/include_activitymanager",
],
// Only include libs that can't be run device-side here
diff --git a/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp b/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
index feb5540..cd07a69 100644
--- a/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraPermissionsTest.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <android/content/AttributionSourceState.h>
#include <android/hardware/BnCameraServiceListener.h>
#include <android/hardware/BnCameraServiceProxy.h>
#include <android/hardware/camera2/BnCameraDeviceCallbacks.h>
@@ -223,6 +224,10 @@
// Test that camera connections fail with ERROR_DISABLED when the camera is disabled via device
// policy, and succeed when it isn't.
TEST_F(CameraPermissionsTest, TestCameraDisabled) {
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
+ clientAttribution.uid = android::CameraService::USE_CALLING_UID;
+
std::vector<hardware::CameraStatus> statuses;
sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
sCameraService->addListenerTest(serviceListener, &statuses);
@@ -234,10 +239,9 @@
sp<hardware::camera2::ICameraDeviceUser> device;
binder::Status status =
sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
- android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
- /*targetSdkVersion*/__ANDROID_API_FUTURE__,
+ 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
hardware::ICameraService::ROTATION_OVERRIDE_NONE,
- kDefaultDeviceId, /*devicePolicy*/0, &device);
+ clientAttribution, /*devicePolicy*/0, &device);
AutoDisconnectDevice autoDisconnect(device);
ASSERT_TRUE(!status.isOk()) << "connectDevice returned OK status";
ASSERT_EQ(status.serviceSpecificErrorCode(), hardware::ICameraService::ERROR_DISABLED)
@@ -250,10 +254,9 @@
sp<hardware::camera2::ICameraDeviceUser> device;
binder::Status status =
sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
- android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
- /*targetSdkVersion*/__ANDROID_API_FUTURE__,
+ 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
hardware::ICameraService::ROTATION_OVERRIDE_NONE,
- kDefaultDeviceId, /*devicePolicy*/0, &device);
+ clientAttribution, /*devicePolicy*/0, &device);
AutoDisconnectDevice autoDisconnect(device);
ASSERT_TRUE(status.isOk());
}
@@ -261,6 +264,10 @@
// Test that consecutive camera connections succeed.
TEST_F(CameraPermissionsTest, TestConsecutiveConnections) {
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
+ clientAttribution.uid = android::CameraService::USE_CALLING_UID;
+
std::vector<hardware::CameraStatus> statuses;
sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
sCameraService->addListenerTest(serviceListener, &statuses);
@@ -271,19 +278,17 @@
sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
binder::Status status =
sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
- android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
- /*targetSdkVersion*/__ANDROID_API_FUTURE__,
+ 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
hardware::ICameraService::ROTATION_OVERRIDE_NONE,
- kDefaultDeviceId, /*devicePolicy*/0, &deviceA);
+ clientAttribution, /*devicePolicy*/0, &deviceA);
AutoDisconnectDevice autoDisconnectA(deviceA);
ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
" service specific error code " << status.serviceSpecificErrorCode();
status =
sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
- android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
- /*targetSdkVersion*/__ANDROID_API_FUTURE__,
+ 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
hardware::ICameraService::ROTATION_OVERRIDE_NONE,
- kDefaultDeviceId, /*devicePolicy*/0, &deviceB);
+ clientAttribution, /*devicePolicy*/0, &deviceB);
AutoDisconnectDevice autoDisconnectB(deviceB);
ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
" service specific error code " << status.serviceSpecificErrorCode();
@@ -293,6 +298,10 @@
// Test that consecutive camera connections succeed even when a nonzero oomScoreOffset is provided
// in the second call.
TEST_F(CameraPermissionsTest, TestConflictingOomScoreOffset) {
+ AttributionSourceState clientAttribution;
+ clientAttribution.deviceId = kDefaultDeviceId;
+ clientAttribution.uid = android::CameraService::USE_CALLING_UID;
+
std::vector<hardware::CameraStatus> statuses;
sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
sCameraService->addListenerTest(serviceListener, &statuses);
@@ -303,19 +312,17 @@
sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
binder::Status status =
sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
- android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
- /*targetSdkVersion*/__ANDROID_API_FUTURE__,
+ 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
hardware::ICameraService::ROTATION_OVERRIDE_NONE,
- kDefaultDeviceId, /*devicePolicy*/0, &deviceA);
+ clientAttribution, /*devicePolicy*/0, &deviceA);
AutoDisconnectDevice autoDisconnectA(deviceA);
ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
" service specific error code " << status.serviceSpecificErrorCode();
status =
sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
- android::CameraService::USE_CALLING_UID, 1/*oomScoreDiff*/,
- /*targetSdkVersion*/__ANDROID_API_FUTURE__,
+ 1/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
hardware::ICameraService::ROTATION_OVERRIDE_NONE,
- kDefaultDeviceId, /*devicePolicy*/0, &deviceB);
+ clientAttribution, /*devicePolicy*/0, &deviceB);
AutoDisconnectDevice autoDisconnectB(deviceB);
ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
" service specific error code " << status.serviceSpecificErrorCode();
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
index 4f238ab..4daab0f 100644
--- a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
@@ -41,6 +41,20 @@
mCameraService = cameraService;
}
+ static AttributionSourceState buildAttributionSource(int callingPid, int callingUid) {
+ AttributionSourceState attributionSource{};
+ attributionSource.pid = callingPid;
+ attributionSource.uid = callingUid;
+ return attributionSource;
+ }
+
+ static AttributionSourceState buildAttributionSource(int callingPid, int callingUid,
+ int32_t deviceId) {
+ AttributionSourceState attributionSource = buildAttributionSource(callingPid, callingUid);
+ attributionSource.deviceId = deviceId;
+ return attributionSource;
+ }
+
// Utilities handling Binder calling identities (previously in CameraThreadState)
virtual int getCallingUid();
virtual int getCallingPid();
@@ -123,17 +137,13 @@
: mAttributionAndPermissionUtils(attributionAndPermissionUtils) { }
static AttributionSourceState buildAttributionSource(int callingPid, int callingUid) {
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- return attributionSource;
+ return AttributionAndPermissionUtils::buildAttributionSource(callingPid, callingUid);
}
static AttributionSourceState buildAttributionSource(int callingPid, int callingUid,
int32_t deviceId) {
- AttributionSourceState attributionSource = buildAttributionSource(callingPid, callingUid);
- attributionSource.deviceId = deviceId;
- return attributionSource;
+ return AttributionAndPermissionUtils::buildAttributionSource(
+ callingPid, callingUid, deviceId);
}
static AttributionSourceState buildAttributionSource(int callingPid, int callingUid,
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
index cfa1815..9986a84 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
@@ -23,6 +23,7 @@
#include "device3/aidl/AidlCamera3Device.h"
#include "device3/hidl/HidlCamera3Device.h"
#include "device3/Camera3OutputStream.h"
+#include "utils/Utils.h"
using android::camera3::OutputStreamInfo;
using android::hardware::camera2::ICameraDeviceUser;
@@ -48,16 +49,16 @@
hidl.streams.resize(aidl.streams.size());
size_t i = 0;
for (const auto &stream : aidl.streams) {
- if (static_cast<int>(stream.dynamicRangeProfile) !=
+ if (eToI(stream.dynamicRangeProfile) !=
ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
ALOGE("%s Dynamic range profile %" PRId64 " not supported by HIDL", __FUNCTION__,
- stream.dynamicRangeProfile);
+ eToI(stream.dynamicRangeProfile));
return BAD_VALUE;
}
- if (static_cast<int>(stream.useCase) != ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
+ if (eToI(stream.useCase) != ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
ALOGE("%s Stream use case %" PRId64 "not supported by HIDL", __FUNCTION__,
- stream.useCase);
+ eToI(stream.useCase));
return BAD_VALUE;
}
diff --git a/services/camera/libcameraservice/utils/Utils.h b/services/camera/libcameraservice/utils/Utils.h
index 4e90871..0eb5e2c 100644
--- a/services/camera/libcameraservice/utils/Utils.h
+++ b/services/camera/libcameraservice/utils/Utils.h
@@ -19,10 +19,21 @@
#include <sched.h>
#include <unistd.h>
+#include <type_traits>
namespace android {
/**
+ * Magically convert an enum to its underlying integer type, mostly so they can be
+ * printed with printf-style formatters without warnings.
+ * Backport of C++23 std::to_underlying()
+ */
+template<typename Enum>
+constexpr std::underlying_type_t<Enum> eToI(Enum val) {
+ return static_cast<std::underlying_type_t<Enum>>(val);
+}
+
+/**
* As of Android V, ro.board.api_level returns the year and month of release (ex. 202404)
* instead of release SDK version. This function maps year/month format back to release
* SDK version.