Camera: implement camera audio restriction API
Test: new CTS test
Bug: 135676184
Change-Id: I5f26e343a4ee92b66fabfaa6bda94224ae311c40
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 9a91ea0..9ba6553 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -135,7 +135,8 @@
CameraService::CameraService() :
mEventLog(DEFAULT_EVENT_LOG_LENGTH),
mNumberOfCameras(0),
- mSoundRef(0), mInitialized(false) {
+ mSoundRef(0), mInitialized(false),
+ mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE) {
ALOGI("CameraService started (pid=%d)", getpid());
mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
}
@@ -164,6 +165,7 @@
mUidPolicy->registerSelf();
mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
mSensorPrivacyPolicy->registerSelf();
+ mAppOps.setCameraAudioRestriction(mAudioRestriction);
sp<HidlCameraService> hcs = HidlCameraService::getInstance(this);
if (hcs->registerAsService() != android::OK) {
ALOGE("%s: Failed to register default android.frameworks.cameraservice.service@1.0",
@@ -2027,6 +2029,7 @@
mActiveClientManager.remove(i);
}
}
+ updateAudioRestrictionLocked();
}
bool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
@@ -2400,6 +2403,7 @@
mClientPackageName(clientPackageName), mClientPid(clientPid), mClientUid(clientUid),
mServicePid(servicePid),
mDisconnected(false),
+ mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE),
mRemoteBinder(remoteCallback)
{
if (sCameraService == nullptr) {
@@ -2503,6 +2507,30 @@
return level == API_2;
}
+int32_t CameraService::BasicClient::setAudioRestriction(int32_t mode) {
+ {
+ Mutex::Autolock l(mAudioRestrictionLock);
+ mAudioRestriction = mode;
+ }
+ return sCameraService->updateAudioRestriction();
+}
+
+int32_t CameraService::BasicClient::getAudioRestriction() const {
+ Mutex::Autolock l(mAudioRestrictionLock);
+ return mAudioRestriction;
+}
+
+bool CameraService::BasicClient::isValidAudioRestriction(int32_t mode) {
+ switch (mode) {
+ case hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE:
+ case hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_VIBRATION:
+ case hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_VIBRATION_SOUND:
+ return true;
+ default:
+ return false;
+ }
+}
+
status_t CameraService::BasicClient::startCameraOps() {
ATRACE_CALL();
@@ -3532,4 +3560,25 @@
" help print this message\n");
}
+int32_t CameraService::updateAudioRestriction() {
+ Mutex::Autolock lock(mServiceLock);
+ return updateAudioRestrictionLocked();
+}
+
+int32_t CameraService::updateAudioRestrictionLocked() {
+ int32_t mode = 0;
+ // iterate through all active client
+ for (const auto& i : mActiveClientManager.getAll()) {
+ const auto clientSp = i->getValue();
+ mode |= clientSp->getAudioRestriction();
+ }
+
+ bool modeChanged = (mAudioRestriction != mode);
+ mAudioRestriction = mode;
+ if (modeChanged) {
+ mAppOps.setCameraAudioRestriction(mode);
+ }
+ return mode;
+}
+
}; // namespace android
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 67829dd..df8c17c 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -258,6 +258,14 @@
// Block the client form using the camera
virtual void block();
+
+ // set audio restriction from client
+ // Will call into camera service and hold mServiceLock
+ virtual int32_t setAudioRestriction(int32_t mode);
+
+ virtual int32_t getAudioRestriction() const;
+
+ static bool isValidAudioRestriction(int32_t mode);
protected:
BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
@@ -286,6 +294,9 @@
const pid_t mServicePid;
bool mDisconnected;
+ mutable Mutex mAudioRestrictionLock;
+ int32_t mAudioRestriction;
+
// - The app-side Binder interface to receive callbacks from us
sp<IBinder> mRemoteBinder; // immutable after constructor
@@ -439,6 +450,9 @@
}; // class CameraClientManager
+ int32_t updateAudioRestriction();
+ int32_t updateAudioRestrictionLocked();
+
private:
typedef hardware::camera::common::V1_0::CameraDeviceStatus CameraDeviceStatus;
@@ -966,6 +980,13 @@
void broadcastTorchModeStatus(const String8& cameraId,
hardware::camera::common::V1_0::TorchModeStatus status);
+
+ // TODO: right now each BasicClient holds one AppOpsManager instance.
+ // We can refactor the code so all of clients share this instance
+ AppOpsManager mAppOps;
+
+ // Aggreated audio restriction mode for all camera clients
+ int32_t mAudioRestriction;
};
} // namespace android
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 162b50f..eb599e0 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -2253,6 +2253,12 @@
return OK;
}
+int32_t Camera2Client::setAudioRestriction(int /*mode*/) {
+ // Empty implementation. setAudioRestriction is hidden interface and not
+ // supported by android.hardware.Camera API
+ return INVALID_OPERATION;
+}
+
const char* Camera2Client::kAutofocusLabel = "autofocus";
const char* Camera2Client::kTakepictureLabel = "take_picture";
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index a9ea271..8df8d2b 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -83,6 +83,7 @@
virtual void notifyError(int32_t errorCode,
const CaptureResultExtras& resultExtras);
virtual status_t setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer);
+ virtual int32_t setAudioRestriction(int mode);
/**
* Interface used by CameraService
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index d65ac7b..089f6cf 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -1171,4 +1171,18 @@
return INVALID_OPERATION;
}
+int32_t CameraClient::setAudioRestriction(int mode) {
+ if (!isValidAudioRestriction(mode)) {
+ ALOGE("%s: invalid audio restriction mode %d", __FUNCTION__, mode);
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mLock);
+ if (checkPidAndHardware() != NO_ERROR) {
+ return INVALID_OPERATION;
+ }
+ return BasicClient::setAudioRestriction(mode);
+}
+
+
}; // namespace android
diff --git a/services/camera/libcameraservice/api1/CameraClient.h b/services/camera/libcameraservice/api1/CameraClient.h
index 9530b6c..fefa8c9 100644
--- a/services/camera/libcameraservice/api1/CameraClient.h
+++ b/services/camera/libcameraservice/api1/CameraClient.h
@@ -59,6 +59,7 @@
virtual String8 getParameters() const;
virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
virtual status_t setVideoTarget(const sp<IGraphicBufferProducer>& bufferProducer);
+ virtual int32_t setAudioRestriction(int mode);
// Interface used by CameraService
CameraClient(const sp<CameraService>& cameraService,
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index c7a4f2b..be188bc 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1870,6 +1870,26 @@
return res;
}
+binder::Status CameraDeviceClient::setCameraAudioRestriction(int32_t mode,
+ /*out*/ int32_t* outMode) {
+ ATRACE_CALL();
+ binder::Status res;
+ if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
+
+ if (!isValidAudioRestriction(mode)) {
+ String8 msg = String8::format("Camera %s: invalid audio restriction mode %d",
+ mCameraIdStr.string(), mode);
+ ALOGW("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
+
+ Mutex::Autolock icl(mBinderSerializationLock);
+ if (outMode != nullptr) {
+ *outMode = BasicClient::setAudioRestriction(mode);
+ }
+ return binder::Status::ok();
+}
+
status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
return BasicClient::dump(fd, args);
}
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 1c5abb0..a9aa190 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -152,6 +152,10 @@
virtual binder::Status finalizeOutputConfigurations(int32_t streamId,
const hardware::camera2::params::OutputConfiguration &outputConfiguration) override;
+ virtual binder::Status setCameraAudioRestriction(int32_t mode,
+ /*out*/
+ int32_t* outMode = NULL) override;
+
/**
* Interface used by CameraService
*/