Camera: implement camera audio restriction API

Test: new CTS test
Bug: 135676184
Change-Id: I5f26e343a4ee92b66fabfaa6bda94224ae311c40
gugelfrei
Yin-Chia Yeh 5 years ago
parent b59478c8fb
commit dba03231c2

@ -347,6 +347,13 @@ status_t Camera::setPreviewCallbackTarget(
return c->setPreviewCallbackTarget(callbackProducer);
}
int32_t Camera::setAudioRestriction(int32_t mode)
{
sp <::android::hardware::ICamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->setAudioRestriction(mode);
}
// callback from camera service
void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
{

@ -56,6 +56,7 @@ enum {
SET_VIDEO_BUFFER_TARGET,
RELEASE_RECORDING_FRAME_HANDLE,
RELEASE_RECORDING_FRAME_HANDLE_BATCH,
SET_AUDIO_RESTRICTION,
};
class BpCamera: public BpInterface<ICamera>
@ -191,6 +192,14 @@ public:
}
}
int32_t setAudioRestriction(int32_t mode) {
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
data.writeInt32(mode);
remote()->transact(SET_AUDIO_RESTRICTION, data, &reply);
return reply.readInt32();
}
status_t setVideoBufferMode(int32_t videoBufferMode)
{
ALOGV("setVideoBufferMode: %d", videoBufferMode);
@ -494,6 +503,12 @@ status_t BnCamera::onTransact(
reply->writeInt32(setVideoTarget(st));
return NO_ERROR;
} break;
case SET_AUDIO_RESTRICTION: {
CHECK_INTERFACE(ICamera, data, reply);
int32_t mode = data.readInt32();
reply->writeInt32(setAudioRestriction(mode));
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}

@ -155,4 +155,20 @@ interface ICameraDeviceUser
void updateOutputConfiguration(int streamId, in OutputConfiguration outputConfiguration);
void finalizeOutputConfigurations(int streamId, in OutputConfiguration outputConfiguration);
// Keep in sync with public API in
// frameworks/base/core/java/android/hardware/camera2/CameraDevice.java
const int AUDIO_RESTRICTION_NONE = 0;
const int AUDIO_RESTRICTION_VIBRATION = 1;
const int AUDIO_RESTRICTION_VIBRATION_SOUND = 3;
/**
* Set audio restriction mode for this camera device.
*
* @param mode the audio restriction mode ID as above
*
* @return the resulting system-wide audio restriction mode
*/
int setCameraAudioRestriction(int mode);
}

@ -167,6 +167,8 @@ public:
sp<ICameraRecordingProxy> getRecordingProxy();
int32_t setAudioRestriction(int32_t mode);
// ICameraClient interface
virtual void notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
virtual void dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,

@ -140,6 +140,9 @@ public:
// Set the video buffer producer for camera to use in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode.
virtual status_t setVideoTarget(
const sp<IGraphicBufferProducer>& bufferProducer) = 0;
// Set the audio restriction mode
virtual int32_t setAudioRestriction(int32_t mode) = 0;
};
// ----------------------------------------------------------------------------

@ -135,7 +135,8 @@ sp<hardware::ICameraServiceProxy> CameraService::sCameraServiceProxy;
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 @@ void CameraService::onFirstRef()
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 @@ void CameraService::removeByClient(const BasicClient* client) {
mActiveClientManager.remove(i);
}
}
updateAudioRestrictionLocked();
}
bool CameraService::evictClientIdByRemote(const wp<IBinder>& remote) {
@ -2400,6 +2403,7 @@ CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
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 @@ bool CameraService::BasicClient::canCastToApiClient(apiLevel level) const {
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 @@ status_t CameraService::printHelp(int out) {
" 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

@ -258,6 +258,14 @@ public:
// 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 @@ public:
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 @@ public:
}; // class CameraClientManager
int32_t updateAudioRestriction();
int32_t updateAudioRestrictionLocked();
private:
typedef hardware::camera::common::V1_0::CameraDeviceStatus CameraDeviceStatus;
@ -966,6 +980,13 @@ private:
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

@ -2253,6 +2253,12 @@ status_t Camera2Client::setVideoTarget(const sp<IGraphicBufferProducer>& bufferP
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";

@ -83,6 +83,7 @@ public:
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

@ -1171,4 +1171,18 @@ status_t CameraClient::setVideoTarget(const sp<IGraphicBufferProducer>& bufferPr
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

@ -59,6 +59,7 @@ public:
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,

@ -1870,6 +1870,26 @@ binder::Status CameraDeviceClient::finalizeOutputConfigurations(int32_t streamId
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);
}

@ -152,6 +152,10 @@ public:
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
*/

Loading…
Cancel
Save