Merge "MediaController: Use Context#getPackageName() for RemoteUserInfo"
diff --git a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
index 579412e..f9bb3ac 100644
--- a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
+++ b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
@@ -55,38 +55,27 @@
class CameraHelper {
public:
- CameraHelper(native_handle_t* imgReaderAnw) : mImgReaderAnw(imgReaderAnw) {}
+ CameraHelper(const char* id, ACameraManager *manager) :
+ mImgReaderAnw(nullptr), mCameraId(id), mCameraManager(manager) {}
~CameraHelper() { closeCamera(); }
- int initCamera() {
- if (mImgReaderAnw == nullptr) {
+ struct PhysicalImgReaderInfo {
+ const char* physicalCameraId;
+ native_handle_t* anw;
+ };
+ int initCamera(native_handle_t* imgReaderAnw,
+ const std::vector<PhysicalImgReaderInfo>& physicalImgReaders) {
+ if (imgReaderAnw == nullptr) {
ALOGE("Cannot initialize camera before image reader get initialized.");
return -1;
}
+ if (mIsCameraReady) {
+ ALOGE("initCamera should only be called once.");
+ return -1;
+ }
+
int ret;
-
- mCameraManager = ACameraManager_create();
- if (mCameraManager == nullptr) {
- ALOGE("Failed to create ACameraManager.");
- return -1;
- }
-
- ret = ACameraManager_getCameraIdList(mCameraManager, &mCameraIdList);
- if (ret != AMEDIA_OK) {
- ALOGE("Failed to get cameraIdList: ret=%d", ret);
- return ret;
- }
- if (mCameraIdList->numCameras < 1) {
- ALOGW("Device has no camera on board.");
- return 0;
- }
-
- // We always use the first camera.
- mCameraId = mCameraIdList->cameraIds[0];
- if (mCameraId == nullptr) {
- ALOGE("Failed to get cameraId.");
- return -1;
- }
+ mImgReaderAnw = imgReaderAnw;
ret = ACameraManager_openCamera(mCameraManager, mCameraId, &mDeviceCb, &mDevice);
if (ret != AMEDIA_OK || mDevice == nullptr) {
@@ -94,18 +83,6 @@
return -1;
}
- ret = ACameraManager_getCameraCharacteristics(mCameraManager, mCameraId, &mCameraMetadata);
- if (ret != ACAMERA_OK || mCameraMetadata == nullptr) {
- ALOGE("Get camera %s characteristics failure. ret %d, metadata %p", mCameraId, ret,
- mCameraMetadata);
- return -1;
- }
-
- if (!isCapabilitySupported(ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE)) {
- ALOGW("Camera does not support BACKWARD_COMPATIBLE.");
- return 0;
- }
-
// Create capture session
ret = ACaptureSessionOutputContainer_create(&mOutputs);
if (ret != AMEDIA_OK) {
@@ -122,6 +99,25 @@
ALOGE("ACaptureSessionOutputContainer_add failed, ret=%d", ret);
return ret;
}
+
+ for (auto& physicalStream : physicalImgReaders) {
+ ACaptureSessionOutput* sessionOutput = nullptr;
+ ret = ACaptureSessionPhysicalOutput_create(physicalStream.anw,
+ physicalStream.physicalCameraId, &sessionOutput);
+ if (ret != ACAMERA_OK) {
+ ALOGE("ACaptureSessionPhysicalOutput_create failed, ret=%d", ret);
+ return ret;
+ }
+ ret = ACaptureSessionOutputContainer_add(mOutputs, sessionOutput);
+ if (ret != AMEDIA_OK) {
+ ALOGE("ACaptureSessionOutputContainer_add failed, ret=%d", ret);
+ return ret;
+ }
+ mExtraOutputs.push_back(sessionOutput);
+ // Assume that at most one physical stream per physical camera.
+ mPhysicalCameraIds.push_back(physicalStream.physicalCameraId);
+ }
+
ret = ACameraDevice_createCaptureSession(mDevice, mOutputs, &mSessionCb, &mSession);
if (ret != AMEDIA_OK) {
ALOGE("ACameraDevice_createCaptureSession failed, ret=%d", ret);
@@ -145,21 +141,25 @@
return ret;
}
+ for (auto& physicalStream : physicalImgReaders) {
+ ACameraOutputTarget* outputTarget = nullptr;
+ ret = ACameraOutputTarget_create(physicalStream.anw, &outputTarget);
+ if (ret != AMEDIA_OK) {
+ ALOGE("ACameraOutputTarget_create failed, ret=%d", ret);
+ return ret;
+ }
+ ret = ACaptureRequest_addTarget(mStillRequest, outputTarget);
+ if (ret != AMEDIA_OK) {
+ ALOGE("ACaptureRequest_addTarget failed, ret=%d", ret);
+ return ret;
+ }
+ mReqExtraOutputs.push_back(outputTarget);
+ }
+
mIsCameraReady = true;
return 0;
}
- bool isCapabilitySupported(acamera_metadata_enum_android_request_available_capabilities_t cap) {
- ACameraMetadata_const_entry entry;
- ACameraMetadata_getConstEntry(
- mCameraMetadata, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
- for (uint32_t i = 0; i < entry.count; i++) {
- if (entry.data.u8[i] == cap) {
- return true;
- }
- }
- return false;
- }
bool isCameraReady() { return mIsCameraReady; }
@@ -169,6 +169,10 @@
ACameraOutputTarget_free(mReqImgReaderOutput);
mReqImgReaderOutput = nullptr;
}
+ for (auto& outputTarget : mReqExtraOutputs) {
+ ACameraOutputTarget_free(outputTarget);
+ }
+ mReqExtraOutputs.clear();
if (mStillRequest) {
ACaptureRequest_free(mStillRequest);
mStillRequest = nullptr;
@@ -182,6 +186,10 @@
ACaptureSessionOutput_free(mImgReaderOutput);
mImgReaderOutput = nullptr;
}
+ for (auto& extraOutput : mExtraOutputs) {
+ ACaptureSessionOutput_free(extraOutput);
+ }
+ mExtraOutputs.clear();
if (mOutputs) {
ACaptureSessionOutputContainer_free(mOutputs);
mOutputs = nullptr;
@@ -191,19 +199,6 @@
ACameraDevice_close(mDevice);
mDevice = nullptr;
}
- if (mCameraMetadata) {
- ACameraMetadata_free(mCameraMetadata);
- mCameraMetadata = nullptr;
- }
- // Destroy camera manager
- if (mCameraIdList) {
- ACameraManager_deleteCameraIdList(mCameraIdList);
- mCameraIdList = nullptr;
- }
- if (mCameraManager) {
- ACameraManager_delete(mCameraManager);
- mCameraManager = nullptr;
- }
mIsCameraReady = false;
}
@@ -213,6 +208,12 @@
&seqId);
}
+ int takeLogicalCameraPicture() {
+ int seqId;
+ return ACameraCaptureSession_logicalCamera_capture(mSession, &mLogicalCaptureCallbacks,
+ 1, &mStillRequest, &seqId);
+ }
+
bool checkCallbacks(int pictureCount) {
std::lock_guard<std::mutex> lock(mMutex);
if (mCompletedCaptureCallbackCount != pictureCount) {
@@ -241,22 +242,22 @@
native_handle_t* mImgReaderAnw = nullptr; // not owned by us.
- // Camera manager
- ACameraManager* mCameraManager = nullptr;
- ACameraIdList* mCameraIdList = nullptr;
// Camera device
- ACameraMetadata* mCameraMetadata = nullptr;
ACameraDevice* mDevice = nullptr;
// Capture session
ACaptureSessionOutputContainer* mOutputs = nullptr;
ACaptureSessionOutput* mImgReaderOutput = nullptr;
+ std::vector<ACaptureSessionOutput*> mExtraOutputs;
+
ACameraCaptureSession* mSession = nullptr;
// Capture request
ACaptureRequest* mStillRequest = nullptr;
ACameraOutputTarget* mReqImgReaderOutput = nullptr;
+ std::vector<ACameraOutputTarget*> mReqExtraOutputs;
bool mIsCameraReady = false;
const char* mCameraId;
+ ACameraManager* mCameraManager;
int mCompletedCaptureCallbackCount = 0;
std::mutex mMutex;
ACameraCaptureSession_captureCallbacks mCaptureCallbacks = {
@@ -264,7 +265,6 @@
this, // context
nullptr, // onCaptureStarted
nullptr, // onCaptureProgressed
- // onCaptureCompleted, called serially, so no lock needed.
[](void* ctx , ACameraCaptureSession *, ACaptureRequest *,
const ACameraMetadata *) {
CameraHelper *ch = static_cast<CameraHelper *>(ctx);
@@ -275,8 +275,44 @@
nullptr, // onCaptureSequenceCompleted
nullptr, // onCaptureSequenceAborted
nullptr, // onCaptureBufferLost
- };
+ };
+ std::vector<std::string> mPhysicalCameraIds;
+ ACameraCaptureSession_logicalCamera_captureCallbacks mLogicalCaptureCallbacks = {
+ // TODO: Add tests for other callbacks
+ this, // context
+ nullptr, // onCaptureStarted
+ nullptr, // onCaptureProgressed
+ [](void* ctx , ACameraCaptureSession *, ACaptureRequest *,
+ const ACameraMetadata *, size_t physicalResultCount,
+ const char** physicalCameraIds, const ACameraMetadata** physicalResults) {
+ CameraHelper *ch = static_cast<CameraHelper *>(ctx);
+ std::lock_guard<std::mutex> lock(ch->mMutex);
+ ASSERT_EQ(physicalResultCount, ch->mPhysicalCameraIds.size());
+ for (size_t i = 0; i < physicalResultCount; i++) {
+ ASSERT_TRUE(physicalCameraIds[i] != nullptr);
+ ASSERT_TRUE(physicalResults[i] != nullptr);
+ ASSERT_NE(std::find(ch->mPhysicalCameraIds.begin(),
+ ch->mPhysicalCameraIds.end(), physicalCameraIds[i]),
+ ch->mPhysicalCameraIds.end());
+
+ // Verify frameNumber and sensorTimestamp exist in physical
+ // result metadata
+ ACameraMetadata_const_entry entry;
+ ACameraMetadata_getConstEntry(
+ physicalResults[i], ACAMERA_SYNC_FRAME_NUMBER, &entry);
+ ASSERT_EQ(entry.count, 1);
+ ACameraMetadata_getConstEntry(
+ physicalResults[i], ACAMERA_SENSOR_TIMESTAMP, &entry);
+ ASSERT_EQ(entry.count, 1);
+ }
+ ch->mCompletedCaptureCallbackCount++;
+ },
+ nullptr, // onCaptureFailed
+ nullptr, // onCaptureSequenceCompleted
+ nullptr, // onCaptureSequenceAborted
+ nullptr, // onCaptureBufferLost
+ };
};
class ImageReaderTestCase {
@@ -476,84 +512,276 @@
AImageReader_BufferRemovedListener mReaderDetachedCb{this, onBufferRemoved};
};
-bool takePictures(uint64_t readerUsage, int readerMaxImages, bool readerAsync, int pictureCount) {
- int ret = 0;
- ImageReaderTestCase testCase(
- kTestImageWidth, kTestImageHeight, kTestImageFormat, readerUsage, readerMaxImages,
- readerAsync);
- ret = testCase.initImageReader();
- if (ret < 0) {
- ALOGE("Unable to initialize ImageReader");
+
+class AImageReaderVendorTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ mCameraManager = ACameraManager_create();
+ if (mCameraManager == nullptr) {
+ ALOGE("Failed to create ACameraManager.");
+ return;
+ }
+
+ camera_status_t ret = ACameraManager_getCameraIdList(mCameraManager, &mCameraIdList);
+ if (ret != ACAMERA_OK) {
+ ALOGE("Failed to get cameraIdList: ret=%d", ret);
+ return;
+ }
+ if (mCameraIdList->numCameras < 1) {
+ ALOGW("Device has no camera on board.");
+ return;
+ }
+ }
+ void TearDown() override {
+ // Destroy camera manager
+ if (mCameraIdList) {
+ ACameraManager_deleteCameraIdList(mCameraIdList);
+ mCameraIdList = nullptr;
+ }
+ if (mCameraManager) {
+ ACameraManager_delete(mCameraManager);
+ mCameraManager = nullptr;
+ }
+ }
+
+ bool takePictures(const char* id, uint64_t readerUsage, int readerMaxImages,
+ bool readerAsync, int pictureCount) {
+ int ret = 0;
+
+ ImageReaderTestCase testCase(
+ kTestImageWidth, kTestImageHeight, kTestImageFormat, readerUsage, readerMaxImages,
+ readerAsync);
+ ret = testCase.initImageReader();
+ if (ret < 0) {
+ ALOGE("Unable to initialize ImageReader");
+ return false;
+ }
+
+ CameraHelper cameraHelper(id, mCameraManager);
+ ret = cameraHelper.initCamera(testCase.getNativeWindow(), {});
+ if (ret < 0) {
+ ALOGE("Unable to initialize camera helper");
+ return false;
+ }
+
+ if (!cameraHelper.isCameraReady()) {
+ ALOGW("Camera is not ready after successful initialization. It's either due to camera "
+ "on board lacks BACKWARDS_COMPATIBLE capability or the device does not have "
+ "camera on board.");
+ return true;
+ }
+
+ for (int i = 0; i < pictureCount; i++) {
+ ret = cameraHelper.takePicture();
+ if (ret < 0) {
+ ALOGE("Unable to take picture");
+ return false;
+ }
+ }
+
+ // Sleep until all capture finished
+ for (int i = 0; i < kCaptureWaitRetry * pictureCount; i++) {
+ usleep(kCaptureWaitUs);
+ if (testCase.getAcquiredImageCount() == pictureCount) {
+ ALOGI("Session take ~%d ms to capture %d images", i * kCaptureWaitUs / 1000,
+ pictureCount);
+ break;
+ }
+ }
+ return testCase.getAcquiredImageCount() == pictureCount &&
+ cameraHelper.checkCallbacks(pictureCount);
+ }
+
+ bool testTakePicturesNative(const char* id) {
+ for (auto& readerUsage :
+ {AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN}) {
+ for (auto& readerMaxImages : {1, 4, 8}) {
+ for (auto& readerAsync : {true, false}) {
+ for (auto& pictureCount : {1, 4, 8}) {
+ if (!takePictures(id, readerUsage, readerMaxImages,
+ readerAsync, pictureCount)) {
+ ALOGE("Test takePictures failed for test case usage=%" PRIu64
+ ", maxImages=%d, async=%d, pictureCount=%d",
+ readerUsage, readerMaxImages, readerAsync, pictureCount);
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ // Camera manager
+ ACameraManager* mCameraManager = nullptr;
+ ACameraIdList* mCameraIdList = nullptr;
+
+ bool isCapabilitySupported(ACameraMetadata* staticInfo,
+ acamera_metadata_enum_android_request_available_capabilities_t cap) {
+ ACameraMetadata_const_entry entry;
+ ACameraMetadata_getConstEntry(
+ staticInfo, ACAMERA_REQUEST_AVAILABLE_CAPABILITIES, &entry);
+ for (uint32_t i = 0; i < entry.count; i++) {
+ if (entry.data.u8[i] == cap) {
+ return true;
+ }
+ }
return false;
}
- CameraHelper cameraHelper(testCase.getNativeWindow());
- ret = cameraHelper.initCamera();
- if (ret < 0) {
- ALOGE("Unable to initialize camera helper");
+ bool isSizeSupportedForFormat(ACameraMetadata* staticInfo,
+ int32_t format, int32_t width, int32_t height) {
+ ACameraMetadata_const_entry entry;
+ ACameraMetadata_getConstEntry(staticInfo,
+ ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry);
+ for (uint32_t i = 0; i < entry.count; i += 4) {
+ if (entry.data.i32[i] == format &&
+ entry.data.i32[i+3] == ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
+ entry.data.i32[i+1] == width &&
+ entry.data.i32[i+2] == height) {
+ return true;
+ }
+ }
return false;
}
+ void findCandidateLogicalCamera(const char **cameraId,
+ ACameraMetadata** staticMetadata,
+ std::vector<const char*>* candidatePhysicalIds) {
+ // Find first available logical camera
+ for (int i = 0; i < mCameraIdList->numCameras; i++) {
+ camera_status_t ret;
+ ret = ACameraManager_getCameraCharacteristics(
+ mCameraManager, mCameraIdList->cameraIds[i], staticMetadata);
+ ASSERT_EQ(ret, ACAMERA_OK);
+ ASSERT_NE(*staticMetadata, nullptr);
+
+ if (!isCapabilitySupported(*staticMetadata,
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA)) {
+ ACameraMetadata_free(*staticMetadata);
+ *staticMetadata = nullptr;
+ continue;
+ }
+
+ // Check returned physical camera Ids are valid
+ size_t physicalCameraIdCnt = 0;
+ const char*const* physicalCameraIds = nullptr;
+ bool isLogicalCamera = ACameraMetadata_isLogicalMultiCamera(*staticMetadata,
+ &physicalCameraIdCnt, &physicalCameraIds);
+ ASSERT_TRUE(isLogicalCamera);
+ ASSERT_GE(physicalCameraIdCnt, 2);
+ ACameraMetadata* physicalCameraMetadata = nullptr;
+ candidatePhysicalIds->clear();
+ for (size_t j = 0; j < physicalCameraIdCnt && candidatePhysicalIds->size() < 2; j++) {
+ ASSERT_GT(strlen(physicalCameraIds[j]), 0);
+ ret = ACameraManager_getCameraCharacteristics(
+ mCameraManager, physicalCameraIds[j], &physicalCameraMetadata);
+ ASSERT_EQ(ret, ACAMERA_OK);
+ ASSERT_NE(physicalCameraMetadata, nullptr);
+
+ if (isSizeSupportedForFormat(physicalCameraMetadata, kTestImageFormat,
+ kTestImageWidth, kTestImageHeight)) {
+ candidatePhysicalIds->push_back(physicalCameraIds[j]);
+ }
+ ACameraMetadata_free(physicalCameraMetadata);
+ }
+ if (candidatePhysicalIds->size() == 2) {
+ *cameraId = mCameraIdList->cameraIds[i];
+ return;
+ } else {
+ ACameraMetadata_free(*staticMetadata);
+ *staticMetadata = nullptr;
+ }
+ }
+ *cameraId = nullptr;
+ return;
+ }
+};
+
+TEST_F(AImageReaderVendorTest, CreateWindowNativeHandle) {
+ // We always use the first camera.
+ const char* cameraId = mCameraIdList->cameraIds[0];
+ ASSERT_TRUE(cameraId != nullptr);
+
+ ACameraMetadata* staticMetadata = nullptr;
+ camera_status_t ret = ACameraManager_getCameraCharacteristics(
+ mCameraManager, cameraId, &staticMetadata);
+ ASSERT_EQ(ret, ACAMERA_OK);
+ ASSERT_NE(staticMetadata, nullptr);
+
+ bool isBC = isCapabilitySupported(staticMetadata,
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
+
+ ACameraMetadata_free(staticMetadata);
+
+ if (!isBC) {
+ ALOGW("Camera does not support BACKWARD_COMPATIBLE.");
+ return;
+ }
+
+ EXPECT_TRUE(testTakePicturesNative(cameraId));
+}
+
+TEST_F(AImageReaderVendorTest, LogicalCameraPhysicalStream) {
+ const char* cameraId = nullptr;
+ ACameraMetadata* staticMetadata = nullptr;
+ std::vector<const char*> physicalCameraIds;
+
+ findCandidateLogicalCamera(&cameraId, &staticMetadata, &physicalCameraIds);
+ if (cameraId == nullptr) {
+ // Couldn't find logical camera to test
+ return;
+ }
+
+ // Test streaming the logical multi-camera
+ uint64_t readerUsage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN;
+ int32_t readerMaxImages = 8;
+ bool readerAsync = false;
+ const int pictureCount = 6;
+ std::vector<ImageReaderTestCase*> testCases;
+ for (size_t i = 0; i < 3; i++) {
+ ImageReaderTestCase* testCase = new ImageReaderTestCase(
+ kTestImageWidth, kTestImageHeight, kTestImageFormat, readerUsage, readerMaxImages,
+ readerAsync);
+ ASSERT_EQ(testCase->initImageReader(), 0);
+ testCases.push_back(testCase);
+ }
+
+ CameraHelper cameraHelper(cameraId, mCameraManager);
+ std::vector<CameraHelper::PhysicalImgReaderInfo> physicalImgReaderInfo;
+ physicalImgReaderInfo.push_back({physicalCameraIds[0], testCases[1]->getNativeWindow()});
+ physicalImgReaderInfo.push_back({physicalCameraIds[1], testCases[2]->getNativeWindow()});
+
+ int ret = cameraHelper.initCamera(testCases[0]->getNativeWindow(), physicalImgReaderInfo);
+ ASSERT_EQ(ret, 0);
+
if (!cameraHelper.isCameraReady()) {
ALOGW("Camera is not ready after successful initialization. It's either due to camera on "
"board lacks BACKWARDS_COMPATIBLE capability or the device does not have camera on "
"board.");
- return true;
+ return;
}
for (int i = 0; i < pictureCount; i++) {
- ret = cameraHelper.takePicture();
- if (ret < 0) {
- ALOGE("Unable to take picture");
- return false;
- }
+ ret = cameraHelper.takeLogicalCameraPicture();
+ ASSERT_EQ(ret, 0);
}
// Sleep until all capture finished
for (int i = 0; i < kCaptureWaitRetry * pictureCount; i++) {
usleep(kCaptureWaitUs);
- if (testCase.getAcquiredImageCount() == pictureCount) {
+ if (testCases[0]->getAcquiredImageCount() == pictureCount) {
ALOGI("Session take ~%d ms to capture %d images", i * kCaptureWaitUs / 1000,
pictureCount);
break;
}
}
- return testCase.getAcquiredImageCount() == pictureCount &&
- cameraHelper.checkCallbacks(pictureCount);
-}
+ ASSERT_EQ(testCases[0]->getAcquiredImageCount(), pictureCount);
+ ASSERT_EQ(testCases[1]->getAcquiredImageCount(), pictureCount);
+ ASSERT_EQ(testCases[2]->getAcquiredImageCount(), pictureCount);
+ ASSERT_TRUE(cameraHelper.checkCallbacks(pictureCount));
-class AImageReaderWindowHandleTest : public ::testing::Test {
- public:
- void SetUp() override {
- }
- void TearDown() override {
-
- }
-
-};
-
-bool testTakePicturesNative() {
- for (auto& readerUsage :
- {AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN}) {
- for (auto& readerMaxImages : {1, 4, 8}) {
- for (auto& readerAsync : {true, false}) {
- for (auto& pictureCount : {1, 4, 8}) {
- if (!takePictures(readerUsage, readerMaxImages, readerAsync, pictureCount)) {
- ALOGE("Test takePictures failed for test case usage=%" PRIu64 ", maxImages=%d, "
- "async=%d, pictureCount=%d",
- readerUsage, readerMaxImages, readerAsync, pictureCount);
- return false;
- }
- }
- }
- }
- }
- return true;
-}
-
-
-TEST_F(AImageReaderWindowHandleTest, CreateWindowNativeHandle) {
- EXPECT_TRUE(testTakePicturesNative());
+ ACameraMetadata_free(staticMetadata);
}
} // namespace
diff --git a/media/libaudioclient/AudioPolicy.cpp b/media/libaudioclient/AudioPolicy.cpp
index d1f7525..9601d6d 100644
--- a/media/libaudioclient/AudioPolicy.cpp
+++ b/media/libaudioclient/AudioPolicy.cpp
@@ -22,6 +22,22 @@
namespace android {
//
+// AudioDeviceTypeAddr implementation
+//
+status_t AudioDeviceTypeAddr::readFromParcel(Parcel *parcel) {
+ mType = (audio_devices_t) parcel->readInt32();
+ mAddress = parcel->readString8();
+ return NO_ERROR;
+}
+
+status_t AudioDeviceTypeAddr::writeToParcel(Parcel *parcel) const {
+ parcel->writeInt32((int32_t) mType);
+ parcel->writeString8(mAddress);
+ return NO_ERROR;
+}
+
+
+//
// AudioMixMatchCriterion implementation
//
AudioMixMatchCriterion::AudioMixMatchCriterion(audio_usage_t usage,
@@ -40,11 +56,22 @@
status_t AudioMixMatchCriterion::readFromParcel(Parcel *parcel)
{
mRule = parcel->readInt32();
- if (mRule == RULE_MATCH_ATTRIBUTE_USAGE ||
- mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) {
- mValue.mUsage = (audio_usage_t)parcel->readInt32();
- } else {
- mValue.mSource = (audio_source_t)parcel->readInt32();
+ switch (mRule) {
+ case RULE_MATCH_ATTRIBUTE_USAGE:
+ case RULE_EXCLUDE_ATTRIBUTE_USAGE:
+ mValue.mUsage = (audio_usage_t) parcel->readInt32();
+ break;
+ case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+ case RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET:
+ mValue.mSource = (audio_source_t) parcel->readInt32();
+ break;
+ case RULE_MATCH_UID:
+ case RULE_EXCLUDE_UID:
+ mValue.mUid = (uid_t) parcel->readInt32();
+ break;
+ default:
+ ALOGE("Trying to build AudioMixMatchCriterion from unknown rule %d", mRule);
+ return BAD_VALUE;
}
return NO_ERROR;
}
@@ -116,4 +143,11 @@
return NO_ERROR;
}
+void AudioMix::excludeUid(uid_t uid) const {
+ AudioMixMatchCriterion crit;
+ crit.mRule = RULE_EXCLUDE_UID;
+ crit.mValue.mUid = uid;
+ mCriteria.add(crit);
+}
+
} // namespace android
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index dc7531c..baeae8b 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1236,6 +1236,19 @@
return aps->registerPolicyMixes(mixes, registration);
}
+status_t AudioSystem::setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PERMISSION_DENIED;
+ return aps->setUidDeviceAffinities(uid, devices);
+}
+
+status_t AudioSystem::removeUidDeviceAffinities(uid_t uid) {
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PERMISSION_DENIED;
+ return aps->removeUidDeviceAffinities(uid);
+}
+
status_t AudioSystem::startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_port_handle_t *portId)
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 0ce8b16..272415c 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -90,6 +90,8 @@
SET_ASSISTANT_UID,
SET_A11Y_SERVICES_UIDS,
IS_HAPTIC_PLAYBACK_SUPPORTED,
+ SET_UID_DEVICE_AFFINITY,
+ REMOVE_UID_DEVICE_AFFINITY,
};
#define MAX_ITEMS_PER_LIST 1024
@@ -990,6 +992,50 @@
return reply.readBool();
}
+ virtual status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+
+ data.writeInt32((int32_t) uid);
+ size_t size = devices.size();
+ size_t sizePosition = data.dataPosition();
+ data.writeInt32((int32_t) size);
+ size_t finalSize = size;
+ for (size_t i = 0; i < size; i++) {
+ size_t position = data.dataPosition();
+ if (devices[i].writeToParcel(&data) != NO_ERROR) {
+ data.setDataPosition(position);
+ finalSize--;
+ }
+ }
+ if (size != finalSize) {
+ size_t position = data.dataPosition();
+ data.setDataPosition(sizePosition);
+ data.writeInt32(finalSize);
+ data.setDataPosition(position);
+ }
+
+ status_t status = remote()->transact(SET_UID_DEVICE_AFFINITY, data, &reply);
+ if (status == NO_ERROR) {
+ status = (status_t)reply.readInt32();
+ }
+ return status;
+ }
+
+ virtual status_t removeUidDeviceAffinities(uid_t uid)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+
+ data.writeInt32((int32_t) uid);
+
+ status_t status = remote()->transact(REMOVE_UID_DEVICE_AFFINITY, data, &reply);
+ if (status == NO_ERROR) {
+ status = (status_t)reply.readInt32();
+ }
+ return status;
+ }
};
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -1048,7 +1094,9 @@
case GET_SURROUND_FORMATS:
case SET_SURROUND_FORMAT_ENABLED:
case SET_ASSISTANT_UID:
- case SET_A11Y_SERVICES_UIDS: {
+ case SET_A11Y_SERVICES_UIDS:
+ case SET_UID_DEVICE_AFFINITY:
+ case REMOVE_UID_DEVICE_AFFINITY: {
if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
__func__, code, IPCThreadState::self()->getCallingPid(),
@@ -1811,6 +1859,30 @@
CHECK_INTERFACE(IAudioPolicyService, data, reply);
bool isSupported = isHapticPlaybackSupported();
reply->writeBool(isSupported);
+ return NO_ERROR;
+ }
+
+ case SET_UID_DEVICE_AFFINITY: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ const uid_t uid = (uid_t) data.readInt32();
+ Vector<AudioDeviceTypeAddr> devices;
+ size_t size = (size_t)data.readInt32();
+ for (size_t i = 0; i < size; i++) {
+ AudioDeviceTypeAddr device;
+ if (device.readFromParcel((Parcel*)&data) == NO_ERROR) {
+ devices.add(device);
+ }
+ }
+ status_t status = setUidDeviceAffinities(uid, devices);
+ reply->writeInt32(status);
+ return NO_ERROR;
+ }
+
+ case REMOVE_UID_DEVICE_AFFINITY: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ const uid_t uid = (uid_t) data.readInt32();
+ status_t status = removeUidDeviceAffinities(uid);
+ reply->writeInt32(status);
return NO_ERROR;
}
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 8da0069..96e1235 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -56,6 +56,19 @@
#define MAX_MIXES_PER_POLICY 10
#define MAX_CRITERIA_PER_MIX 20
+class AudioDeviceTypeAddr {
+public:
+ AudioDeviceTypeAddr() {}
+ AudioDeviceTypeAddr(audio_devices_t type, String8 address) :
+ mType(type), mAddress(address) {}
+
+ status_t readFromParcel(Parcel *parcel);
+ status_t writeToParcel(Parcel *parcel) const;
+
+ audio_devices_t mType;
+ String8 mAddress;
+};
+
class AudioMixMatchCriterion {
public:
AudioMixMatchCriterion() {}
@@ -87,7 +100,9 @@
status_t readFromParcel(Parcel *parcel);
status_t writeToParcel(Parcel *parcel) const;
- Vector<AudioMixMatchCriterion> mCriteria;
+ void excludeUid(uid_t uid) const;
+
+ mutable Vector<AudioMixMatchCriterion> mCriteria;
uint32_t mMixType;
audio_config_t mFormat;
uint32_t mRouteFlags;
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index b0da5b8..781e9df 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -325,6 +325,10 @@
static status_t registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration);
+ static status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices);
+
+ static status_t removeUidDeviceAffinities(uid_t uid);
+
static status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_port_handle_t *portId);
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index 61f3b27..fb4fe93 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -167,6 +167,11 @@
virtual status_t registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration) = 0;
+ virtual status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices)
+ = 0;
+
+ virtual status_t removeUidDeviceAffinities(uid_t uid) = 0;
+
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_port_handle_t *portId) = 0;
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/rate_control.cpp b/media/libstagefright/codecs/m4v_h263/enc/src/rate_control.cpp
index 53149c1..ecc3217 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/rate_control.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/rate_control.cpp
@@ -377,15 +377,15 @@
/* In/out : Nr, B, Rr */
/* Return : Void */
/* Modified : */
+/* Input argument "video" is guaranteed non-null by caller */
/* ======================================================================== */
-
PV_STATUS RC_UpdateBuffer(VideoEncData *video, Int currLayer, Int num_skip)
{
rateControl *rc = video->rc[currLayer];
MultiPass *pMP = video->pMP[currLayer];
- if (video == NULL || rc == NULL || pMP == NULL)
+ if (rc == NULL || pMP == NULL)
return PV_FAIL;
rc->VBV_fullness -= (Int)(rc->bitrate / rc->framerate * num_skip); //rc[currLayer]->Rp;
@@ -524,6 +524,7 @@
/* In/out : rc->T */
/* Return : Void */
/* Modified : */
+/* Input argument "input" is guaranteed non-null by caller */
/* ================================================================================ */
void targetBitCalculation(void *input)
@@ -537,7 +538,7 @@
Int diff_counter_BTsrc, diff_counter_BTdst, prev_counter_diff, curr_counter_diff, bound;
/* BT = Bit Transfer, for pMP->counter_BTsrc, pMP->counter_BTdst */
- if (video == NULL || currVol == NULL || pMP == NULL || rc == NULL)
+ if (currVol == NULL || pMP == NULL || rc == NULL)
return;
/* some stuff about frame dropping remained here to be done because pMP cannot be inserted into updateRateControl()*/
@@ -693,6 +694,7 @@
/* In/out : rc->T and rc->Qc */
/* Return : Void */
/* Modified : */
+/* Input argument "input" is guaranteed non-null by caller */
/* ================================================================================ */
/* Mad based variable bit allocation + QP calculation with a new quadratic method */
@@ -708,7 +710,7 @@
float curr_mad, prev_mad, curr_RD, prev_RD, average_mad, aver_QP;
- if (video == NULL || currVol == NULL || pMP == NULL || rc == NULL)
+ if (currVol == NULL || pMP == NULL || rc == NULL)
return;
/* Mad based variable bit allocation */
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index bfa1b5e..d71aa15 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -51,6 +51,7 @@
libcutils \
libutils \
liblog \
+ libaudioclient \
libsoundtrigger
ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index ad12a90..1c2b9d7 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -210,6 +210,10 @@
virtual status_t registerPolicyMixes(const Vector<AudioMix>& mixes) = 0;
virtual status_t unregisterPolicyMixes(Vector<AudioMix> mixes) = 0;
+ virtual status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices)
+ = 0;
+ virtual status_t removeUidDeviceAffinities(uid_t uid) = 0;
+
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_port_handle_t *portId,
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
index 96c00ea..955e87b 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h
@@ -80,6 +80,10 @@
status_t getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix);
+ status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices);
+ status_t removeUidDeviceAffinities(uid_t uid);
+ status_t getDevicesForUid(uid_t uid, Vector<AudioDeviceTypeAddr>& devices) const;
+
void dump(String8 *dst) const;
};
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index 3cf8014..776d98f 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -340,6 +340,87 @@
return NO_ERROR;
}
+status_t AudioPolicyMixCollection::setUidDeviceAffinities(uid_t uid,
+ const Vector<AudioDeviceTypeAddr>& devices) {
+ // remove existing rules for this uid
+ removeUidDeviceAffinities(uid);
+
+ // for each player mix: add a rule to match or exclude the uid based on the device
+ for (size_t i = 0; i < size(); i++) {
+ const AudioMix *mix = valueAt(i)->getMix();
+ if (mix->mMixType != MIX_TYPE_PLAYERS) {
+ continue;
+ }
+ // check if this mix goes to a device in the list of devices
+ bool deviceMatch = false;
+ for (size_t j = 0; j < devices.size(); j++) {
+ if (devices[j].mType == mix->mDeviceType
+ && devices[j].mAddress == mix->mDeviceAddress) {
+ deviceMatch = true;
+ break;
+ }
+ }
+ if (!deviceMatch) {
+ // this mix doesn't go to one of the listed devices for the given uid,
+ // modify its rules to exclude the uid
+ mix->excludeUid(uid);
+ }
+ }
+
+ return NO_ERROR;
+}
+
+status_t AudioPolicyMixCollection::removeUidDeviceAffinities(uid_t uid) {
+ // for each player mix: remove existing rules that match or exclude this uid
+ for (size_t i = 0; i < size(); i++) {
+ bool foundUidRule = false;
+ AudioMix *mix = valueAt(i)->getMix();
+ if (mix->mMixType != MIX_TYPE_PLAYERS) {
+ continue;
+ }
+ std::vector<size_t> criteriaToRemove;
+ for (size_t j = 0; j < mix->mCriteria.size(); j++) {
+ const uint32_t rule = mix->mCriteria[j].mRule;
+ // is this rule affecting the uid?
+ if (rule == RULE_EXCLUDE_UID
+ && uid == mix->mCriteria[j].mValue.mUid) {
+ foundUidRule = true;
+ criteriaToRemove.push_back(j);
+ }
+ }
+ if (foundUidRule) {
+ for (size_t j = criteriaToRemove.size() - 1; j >= 0; j--) {
+ mix->mCriteria.removeAt(criteriaToRemove[j]);
+ }
+ }
+ }
+ return NO_ERROR;
+}
+
+status_t AudioPolicyMixCollection::getDevicesForUid(uid_t uid,
+ Vector<AudioDeviceTypeAddr>& devices) const {
+ // for each player mix: find rules that don't exclude this uid, and add the device to the list
+ for (size_t i = 0; i < size(); i++) {
+ bool ruleAllowsUid = true;
+ AudioMix *mix = valueAt(i)->getMix();
+ if (mix->mMixType != MIX_TYPE_PLAYERS) {
+ continue;
+ }
+ for (size_t j = 0; j < mix->mCriteria.size(); j++) {
+ const uint32_t rule = mix->mCriteria[j].mRule;
+ if (rule == RULE_EXCLUDE_UID
+ && uid == mix->mCriteria[j].mValue.mUid) {
+ ruleAllowsUid = false;
+ break;
+ }
+ }
+ if (ruleAllowsUid) {
+ devices.add(AudioDeviceTypeAddr(mix->mDeviceType, mix->mDeviceAddress));
+ }
+ }
+ return NO_ERROR;
+}
+
void AudioPolicyMixCollection::dump(String8 *dst) const
{
dst->append("\nAudio Policy Mix:\n");
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index aa205f0..baa5eb3 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2674,6 +2674,59 @@
}
}
+status_t AudioPolicyManager::setUidDeviceAffinities(uid_t uid,
+ const Vector<AudioDeviceTypeAddr>& devices) {
+ ALOGV("%s() uid=%d num devices %zu", __FUNCTION__, uid, devices.size());
+ // uid/device affinity is only for output devices
+ for (size_t i = 0; i < devices.size(); i++) {
+ if (!audio_is_output_device(devices[i].mType)) {
+ ALOGE("setUidDeviceAffinities() device=%08x is NOT an output device",
+ devices[i].mType);
+ return BAD_VALUE;
+ }
+ }
+ status_t res = mPolicyMixes.setUidDeviceAffinities(uid, devices);
+ if (res == NO_ERROR) {
+ // reevaluate outputs for all given devices
+ for (size_t i = 0; i < devices.size(); i++) {
+ sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(
+ devices[i].mType, devices[i].mAddress, String8());
+ SortedVector<audio_io_handle_t> outputs;
+ if (checkOutputsForDevice(devDesc, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+ outputs,
+ devDesc->address()) != NO_ERROR) {
+ ALOGE("setUidDeviceAffinities() error in checkOutputsForDevice for device=%08x"
+ " addr=%s", devices[i].mType, devices[i].mAddress.string());
+ return INVALID_OPERATION;
+ }
+ }
+ }
+ return res;
+}
+
+status_t AudioPolicyManager::removeUidDeviceAffinities(uid_t uid) {
+ ALOGV("%s() uid=%d", __FUNCTION__, uid);
+ Vector<AudioDeviceTypeAddr> devices;
+ status_t res = mPolicyMixes.getDevicesForUid(uid, devices);
+ if (res == NO_ERROR) {
+ // reevaluate outputs for all found devices
+ for (size_t i = 0; i < devices.size(); i++) {
+ sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(
+ devices[i].mType, devices[i].mAddress, String8());
+ SortedVector<audio_io_handle_t> outputs;
+ if (checkOutputsForDevice(devDesc, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ outputs,
+ devDesc->address()) != NO_ERROR) {
+ ALOGE("%s() error in checkOutputsForDevice for device=%08x addr=%s",
+ __FUNCTION__, devices[i].mType, devices[i].mAddress.string());
+ return INVALID_OPERATION;
+ }
+ }
+ }
+
+ return res;
+}
+
void AudioPolicyManager::dump(String8 *dst) const
{
dst->appendFormat("\nAudioPolicyManager Dump: %p\n", this);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 35dd87c..9eb1dcf 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -218,6 +218,9 @@
virtual status_t registerPolicyMixes(const Vector<AudioMix>& mixes);
virtual status_t unregisterPolicyMixes(Vector<AudioMix> mixes);
+ virtual status_t setUidDeviceAffinities(uid_t uid,
+ const Vector<AudioDeviceTypeAddr>& devices);
+ virtual status_t removeUidDeviceAffinities(uid_t uid);
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 439764b..80503fd 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1037,6 +1037,31 @@
}
}
+status_t AudioPolicyService::setUidDeviceAffinities(uid_t uid,
+ const Vector<AudioDeviceTypeAddr>& devices) {
+ Mutex::Autolock _l(mLock);
+ if(!modifyAudioRoutingAllowed()) {
+ return PERMISSION_DENIED;
+ }
+ if (mAudioPolicyManager == NULL) {
+ return NO_INIT;
+ }
+ AutoCallerClear acc;
+ return mAudioPolicyManager->setUidDeviceAffinities(uid, devices);
+}
+
+status_t AudioPolicyService::removeUidDeviceAffinities(uid_t uid) {
+ Mutex::Autolock _l(mLock);
+ if(!modifyAudioRoutingAllowed()) {
+ return PERMISSION_DENIED;
+ }
+ if (mAudioPolicyManager == NULL) {
+ return NO_INIT;
+ }
+ AutoCallerClear acc;
+ return mAudioPolicyManager->removeUidDeviceAffinities(uid);
+}
+
status_t AudioPolicyService::startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_port_handle_t *portId)
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index c44d816..959e757 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -199,6 +199,10 @@
virtual status_t registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration);
+ virtual status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices);
+
+ virtual status_t removeUidDeviceAffinities(uid_t uid);
+
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_port_handle_t *portId);
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
index 6d9ed6f..35ac458 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy
@@ -21,6 +21,7 @@
getuid: 1
setpriority: 1
sigaltstack: 1
+fstat: 1
fstatfs: 1
newfstatat: 1
restart_syscall: 1