Merge "Add explicit private audio recording request"

gugelfrei
Eric Laurent 5 years ago committed by Android (Google) Code Review
commit 630f74baaf

@ -107,8 +107,11 @@ int main(int argc, char* argv[])
if (useMic) {
// talk into the appropriate microphone for the duration
audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
attr.source = AUDIO_SOURCE_MIC;
source = new AudioSource(
AUDIO_SOURCE_MIC,
&attr,
String16(),
sampleRate,
channels);

@ -38,12 +38,15 @@ static void (*s_setInputPreset)(AAudioStreamBuilder* builder,
aaudio_input_preset_t inputPreset) = nullptr;
static void (*s_setAllowedCapturePolicy)(AAudioStreamBuilder* builder,
aaudio_allowed_capture_policy_t usage) = nullptr;
static void (*s_setPrivacySensitive)(AAudioStreamBuilder* builder,
bool privacySensitive) = nullptr;
static bool s_loadAttempted = false;
static aaudio_usage_t (*s_getUsage)(AAudioStream *stream) = nullptr;
static aaudio_content_type_t (*s_getContentType)(AAudioStream *stream) = nullptr;
static aaudio_input_preset_t (*s_getInputPreset)(AAudioStream *stream) = nullptr;
static aaudio_allowed_capture_policy_t (*s_getAllowedCapturePolicy)(AAudioStream *stream) = nullptr;
static bool (*s_isPrivacySensitive)(AAudioStream *stream) = nullptr;
// Link to test functions in shared library.
static void loadFutureFunctions() {
@ -68,6 +71,10 @@ static void loadFutureFunctions() {
dlsym(handle, "AAudioStreamBuilder_setAllowedCapturePolicy");
if (s_setAllowedCapturePolicy == nullptr) goto error;
s_setPrivacySensitive = (void (*)(AAudioStreamBuilder *, bool))
dlsym(handle, "AAudioStreamBuilder_setPrivacySensitive");
if (s_setPrivacySensitive == nullptr) goto error;
s_getUsage = (aaudio_usage_t (*)(AAudioStream *))
dlsym(handle, "AAudioStream_getUsage");
if (s_getUsage == nullptr) goto error;
@ -83,6 +90,10 @@ static void loadFutureFunctions() {
s_getAllowedCapturePolicy = (aaudio_input_preset_t (*)(AAudioStream *))
dlsym(handle, "AAudioStream_getAllowedCapturePolicy");
if (s_getAllowedCapturePolicy == nullptr) goto error;
s_isPrivacySensitive = (bool (*)(AAudioStream *))
dlsym(handle, "AAudioStream_isPrivacySensitive");
if (s_isPrivacySensitive == nullptr) goto error;
}
return;
@ -91,9 +102,11 @@ error:
s_setUsage = nullptr;
s_setContentType = nullptr;
s_setInputPreset = nullptr;
s_setPrivacySensitive = nullptr;
s_getUsage = nullptr;
s_getContentType = nullptr;
s_getInputPreset = nullptr;
s_isPrivacySensitive = nullptr;
dlclose(handle);
return;
}
@ -211,6 +224,14 @@ public:
mFramesPerCallback = size;
}
int32_t isPrivacySensitive() const {
return mPrivacySensitive;
}
void setPrivacySensitive(int32_t privacySensitive) {
mPrivacySensitive = privacySensitive;
}
/**
* Apply these parameters to a stream builder.
* @param builder
@ -234,12 +255,12 @@ public:
}
if (s_setContentType != nullptr) {
s_setContentType(builder, mContentType);
} else if (mUsage != AAUDIO_UNSPECIFIED){
} else if (mContentType != AAUDIO_UNSPECIFIED){
printf("WARNING: setContentType not supported");
}
if (s_setInputPreset != nullptr) {
s_setInputPreset(builder, mInputPreset);
} else if (mUsage != AAUDIO_UNSPECIFIED){
} else if (mInputPreset != AAUDIO_UNSPECIFIED){
printf("WARNING: setInputPreset not supported");
}
@ -249,6 +270,15 @@ public:
} else if (mAllowedCapturePolicy != AAUDIO_UNSPECIFIED){
printf("WARNING: setAllowedCapturePolicy not supported");
}
if (mPrivacySensitive != PRIVACY_SENSITIVE_DEFAULT) {
if (s_setPrivacySensitive != nullptr) {
s_setPrivacySensitive(builder,
mPrivacySensitive == PRIVACY_SENSITIVE_ENABLED);
} else {
printf("WARNING: setPrivacySensitive not supported");
}
}
}
static constexpr int32_t kDefaultNumberOfBursts = 2;
@ -270,6 +300,13 @@ private:
int32_t mNumberOfBursts = kDefaultNumberOfBursts;
int32_t mFramesPerCallback = AAUDIO_UNSPECIFIED;
enum {
PRIVACY_SENSITIVE_DEFAULT = -1,
PRIVACY_SENSITIVE_DISABLED = 0,
PRIVACY_SENSITIVE_ENABLED = 1,
};
int32_t mPrivacySensitive = PRIVACY_SENSITIVE_DEFAULT;
};
class AAudioArgsParser : public AAudioParameters {
@ -341,6 +378,9 @@ public:
case 'z':
setFramesPerCallback(atoi(&arg[2]));
break;
case 'S':
setPrivacySensitive(atoi(&arg[2]));
break;
default:
unrecognized = true;
break;
@ -399,6 +439,9 @@ public:
printf(" -x to use EXCLUSIVE mode\n");
printf(" -y{contentType} eg. 1 for AAUDIO_CONTENT_TYPE_SPEECH\n");
printf(" -z{callbackSize} or block size, in frames, default = 0\n");
printf(" -S{0|1} set privacy Sensitive enabled or disabled\n");
printf(" 0 = disabled\n");
printf(" 1 = enabled\n");
}
static aaudio_performance_mode_t parseAllowedCapturePolicy(char c) {
@ -506,10 +549,15 @@ public:
getContentType(), s_getContentType(stream));
}
if (AAudioStream_getDirection(stream) == AAUDIO_DIRECTION_INPUT
&& s_getInputPreset != nullptr) {
if (AAudioStream_getDirection(stream) == AAUDIO_DIRECTION_INPUT) {
if (s_getInputPreset != nullptr) {
printf(" InputPreset: requested = %d, actual = %d\n",
getInputPreset(), s_getInputPreset(stream));
}
if (s_isPrivacySensitive != nullptr) {
printf(" Privacy Sensitive: requested = %d, actual = %d\n",
isPrivacySensitive(), s_isPrivacySensitive(stream));
}
}
printf(" Is MMAP used? %s\n", AAudioStream_isMMapUsed(stream)

@ -759,6 +759,28 @@ AAUDIO_API void AAudioStreamBuilder_setAllowedCapturePolicy(AAudioStreamBuilder*
AAUDIO_API void AAudioStreamBuilder_setSessionId(AAudioStreamBuilder* builder,
aaudio_session_id_t sessionId) __INTRODUCED_IN(28);
/** Indicates whether this input stream must be marked as privacy sensitive or not.
*
* When true, this input stream is privacy sensitive and any concurrent capture
* is not permitted.
*
* This is off (false) by default except when the input preset is {@link #AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION}
* or {@link #AAUDIO_INPUT_PRESET_CAMCORDER}.
*
* Always takes precedence over default from input preset when set explicitly.
*
* Only relevant if the stream direction is {@link #AAUDIO_DIRECTION_INPUT}.
*
* Added in API level 30.
*
* @param builder reference provided by AAudio_createStreamBuilder()
* @param privacySensitive true if capture from this stream must be marked as privacy sensitive,
* false otherwise.
*/
AAUDIO_API void AAudioStreamBuilder_setPrivacySensitive(AAudioStreamBuilder* builder,
bool privacySensitive) __INTRODUCED_IN(30);
/**
* Return one of these values from the data callback function.
*/
@ -1444,6 +1466,20 @@ AAUDIO_API aaudio_input_preset_t AAudioStream_getInputPreset(AAudioStream* strea
AAUDIO_API aaudio_allowed_capture_policy_t AAudioStream_getAllowedCapturePolicy(
AAudioStream* stream) __INTRODUCED_IN(29);
/**
* Return whether this input stream is marked as privacy sensitive or not.
*
* See {@link #AAudioStreamBuilder_setPrivacySensitive()}.
*
* Added in API level 30.
*
* @param stream reference provided by AAudioStreamBuilder_openStream()
* @return true if privacy sensitive, false otherwise
*/
AAUDIO_API bool AAudioStream_isPrivacySensitive(AAudioStream* stream)
__INTRODUCED_IN(30);
#ifdef __cplusplus
}
#endif

@ -66,6 +66,8 @@ status_t AAudioStreamConfiguration::writeToParcel(Parcel* parcel) const {
if (status != NO_ERROR) goto error;
status = parcel->writeInt32(getSessionId());
if (status != NO_ERROR) goto error;
status = parcel->writeInt32(isPrivacySensitive() ? 1 : 0);
if (status != NO_ERROR) goto error;
return NO_ERROR;
error:
ALOGE("%s(): write failed = %d", __func__, status);
@ -111,7 +113,9 @@ status_t AAudioStreamConfiguration::readFromParcel(const Parcel* parcel) {
status = parcel->readInt32(&value);
if (status != NO_ERROR) goto error;
setSessionId(value);
status = parcel->readInt32(&value);
if (status != NO_ERROR) goto error;
setPrivacySensitive(value == 1);
return NO_ERROR;
error:
ALOGE("%s(): read failed = %d", __func__, status);

@ -116,6 +116,7 @@ aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) {
request.getConfiguration().setUsage(getUsage());
request.getConfiguration().setContentType(getContentType());
request.getConfiguration().setInputPreset(getInputPreset());
request.getConfiguration().setPrivacySensitive(isPrivacySensitive());
request.getConfiguration().setBufferCapacity(builder.getBufferCapacity());

@ -149,6 +149,12 @@ AAUDIO_API void AAudioStreamBuilder_setInputPreset(AAudioStreamBuilder* builder,
streamBuilder->setInputPreset(inputPreset);
}
AAUDIO_API void AAudioStreamBuilder_setPrivacySensitive(AAudioStreamBuilder* builder,
bool privacySensitive) {
AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
streamBuilder->setPrivacySensitiveRequest(privacySensitive);
}
AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder* builder,
int32_t frames)
{
@ -507,3 +513,9 @@ AAUDIO_API bool AAudioStream_isMMapUsed(AAudioStream* stream)
AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
return audioStream->isMMap();
}
AAUDIO_API bool AAudioStream_isPrivacySensitive(AAudioStream* stream)
{
AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
return audioStream->isPrivacySensitive();
}

@ -47,6 +47,7 @@ void AAudioStreamParameters::copyFrom(const AAudioStreamParameters &other) {
mContentType = other.mContentType;
mInputPreset = other.mInputPreset;
mAllowedCapturePolicy = other.mAllowedCapturePolicy;
mIsPrivacySensitive = other.mIsPrivacySensitive;
}
static aaudio_result_t isFormatValid(audio_format_t format) {
@ -195,4 +196,5 @@ void AAudioStreamParameters::dump() const {
ALOGD("mContentType = %6d", mContentType);
ALOGD("mInputPreset = %6d", mInputPreset);
ALOGD("mAllowedCapturePolicy = %6d", mAllowedCapturePolicy);
ALOGD("mIsPrivacySensitive = %s", mIsPrivacySensitive ? "true" : "false");
}

@ -128,6 +128,14 @@ public:
mSessionId = sessionId;
}
bool isPrivacySensitive() const {
return mIsPrivacySensitive;
}
void setPrivacySensitive(bool privacySensitive) {
mIsPrivacySensitive = privacySensitive;
}
/**
* @return bytes per frame of getFormat()
*/
@ -158,6 +166,7 @@ private:
int32_t mBufferCapacity = AAUDIO_UNSPECIFIED;
aaudio_allowed_capture_policy_t mAllowedCapturePolicy = AAUDIO_UNSPECIFIED;
aaudio_session_id_t mSessionId = AAUDIO_SESSION_ID_NONE;
bool mIsPrivacySensitive = false;
};
} /* namespace aaudio */

@ -91,6 +91,7 @@ aaudio_result_t AudioStream::open(const AudioStreamBuilder& builder)
if (mAllowedCapturePolicy == AAUDIO_UNSPECIFIED) {
mAllowedCapturePolicy = AAUDIO_ALLOW_CAPTURE_BY_ALL;
}
mIsPrivacySensitive = builder.isPrivacySensitive();
// callbacks
mFramesPerDataCallback = builder.getFramesPerDataCallback();

@ -234,6 +234,10 @@ public:
return mSessionId;
}
bool isPrivacySensitive() const {
return mIsPrivacySensitive;
}
/**
* This is only valid after setSamplesPerFrame() and setFormat() have been called.
*/
@ -543,6 +547,13 @@ protected:
mAllowedCapturePolicy = policy;
}
/**
* This should not be called after the open() call.
*/
void setPrivacySensitive(bool privacySensitive) {
mIsPrivacySensitive = privacySensitive;
}
private:
aaudio_result_t safeStop();
@ -565,6 +576,7 @@ private:
aaudio_content_type_t mContentType = AAUDIO_UNSPECIFIED;
aaudio_input_preset_t mInputPreset = AAUDIO_UNSPECIFIED;
aaudio_allowed_capture_policy_t mAllowedCapturePolicy = AAUDIO_ALLOW_CAPTURE_BY_ALL;
bool mIsPrivacySensitive = false;
int32_t mSessionId = AAUDIO_UNSPECIFIED;

@ -158,6 +158,19 @@ aaudio_result_t AudioStreamBuilder::build(AudioStream** streamPtr) {
return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
}
setPrivacySensitive(false);
if (mPrivacySensitiveReq == PRIVACY_SENSITIVE_DEFAULT) {
// When not explicitly requested, set privacy sensitive mode according to input preset:
// communication and camcorder captures are considered privacy sensitive by default.
aaudio_input_preset_t preset = getInputPreset();
if (preset == AAUDIO_INPUT_PRESET_CAMCORDER
|| preset == AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION) {
setPrivacySensitive(true);
}
} else if (mPrivacySensitiveReq == PRIVACY_SENSITIVE_ENABLED) {
setPrivacySensitive(true);
}
result = builder_createStream(getDirection(), sharingMode, allowMMap, &audioStream);
if (result == AAUDIO_OK) {
// Open the stream using the parameters from the builder.
@ -257,4 +270,5 @@ void AudioStreamBuilder::logParameters() const {
mFramesPerDataCallback);
ALOGI("usage = %6d, contentType = %d, inputPreset = %d, allowedCapturePolicy = %d",
getUsage(), getContentType(), getInputPreset(), getAllowedCapturePolicy());
ALOGI("privacy sensitive = %s", isPrivacySensitive() ? "true" : "false");
}

@ -98,6 +98,12 @@ public:
return this;
}
AudioStreamBuilder* setPrivacySensitiveRequest(bool privacySensitive) {
mPrivacySensitiveReq =
privacySensitive ? PRIVACY_SENSITIVE_ENABLED : PRIVACY_SENSITIVE_DISABLED;
return this;
}
aaudio_result_t build(AudioStream **streamPtr);
virtual aaudio_result_t validate() const override;
@ -114,6 +120,14 @@ private:
AAudioStream_errorCallback mErrorCallbackProc = nullptr;
void *mErrorCallbackUserData = nullptr;
enum {
PRIVACY_SENSITIVE_DEFAULT = -1,
PRIVACY_SENSITIVE_DISABLED = 0,
PRIVACY_SENSITIVE_ENABLED = 1,
};
typedef int32_t privacy_sensitive_t;
privacy_sensitive_t mPrivacySensitiveReq = PRIVACY_SENSITIVE_DEFAULT;
};
} /* namespace aaudio */

@ -142,11 +142,13 @@ aaudio_result_t AudioStreamRecord::open(const AudioStreamBuilder& builder)
const audio_source_t source =
AAudioConvert_inputPresetToAudioSource(builder.getInputPreset());
const audio_flags_mask_t attrFlags =
AAudioConvert_privacySensitiveToAudioFlagsMask(builder.isPrivacySensitive());
const audio_attributes_t attributes = {
.content_type = contentType,
.usage = AUDIO_USAGE_UNKNOWN, // only used for output
.source = source,
.flags = AUDIO_FLAG_NONE, // Different than the AUDIO_INPUT_FLAGS
.flags = attrFlags, // Different than the AUDIO_INPUT_FLAGS
.tags = ""
};

@ -234,6 +234,11 @@ audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
}
}
audio_flags_mask_t AAudioConvert_privacySensitiveToAudioFlagsMask(
bool privacySensitive) {
return privacySensitive ? AUDIO_FLAG_CAPTURE_PRIVATE : AUDIO_FLAG_NONE;
}
int32_t AAudioConvert_framesToBytes(int32_t numFrames,
int32_t bytesPerFrame,
int32_t *sizeInBytes) {

@ -92,6 +92,9 @@ audio_source_t AAudioConvert_inputPresetToAudioSource(aaudio_input_preset_t pres
audio_flags_mask_t AAudioConvert_allowCapturePolicyToAudioFlagsMask(
aaudio_allowed_capture_policy_t policy);
audio_flags_mask_t AAudioConvert_privacySensitiveToAudioFlagsMask(
bool privacySensitive);
// Note that this code may be replaced by Settings or by some other system configuration tool.
/**

@ -262,8 +262,12 @@ status_t AudioRecord::set(
}
if (pAttributes == NULL) {
memset(&mAttributes, 0, sizeof(audio_attributes_t));
mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
mAttributes.source = inputSource;
if (inputSource == AUDIO_SOURCE_VOICE_COMMUNICATION
|| inputSource == AUDIO_SOURCE_CAMCORDER) {
mAttributes.flags |= AUDIO_FLAG_CAPTURE_PRIVATE;
}
} else {
// stream type shouldn't be looked at, this track has audio attributes
memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));

@ -67,7 +67,9 @@ enum {
GET_ACTIVE_MICROPHONES,
GET_PORT_ID,
SET_PREFERRED_MICROPHONE_DIRECTION,
SET_PREFERRED_MICROPHONE_FIELD_DIMENSION
SET_PREFERRED_MICROPHONE_FIELD_DIMENSION,
SET_PRIVACY_SENSITIVE,
GET_PRIVACY_SENSITIVE
};
class BpMediaRecorder: public BpInterface<IMediaRecorder>
@ -151,6 +153,36 @@ public:
return reply.readInt32();
}
status_t setPrivacySensitive(bool privacySensitive)
{
ALOGV("%s(%s)", __func__, privacySensitive ? "true" : "false");
Parcel data, reply;
data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
data.writeInt32(privacySensitive ? 1 : 0);
status_t status = remote()->transact(SET_PRIVACY_SENSITIVE, data, &reply);
if (status != NO_ERROR) {
return status;
}
return reply.readInt32();
}
status_t isPrivacySensitive(bool *privacySensitive) const
{
Parcel data, reply;
data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
*privacySensitive = false;
status_t status = remote()->transact(GET_PRIVACY_SENSITIVE, data, &reply);
if (status != NO_ERROR) {
return status;
}
status = reply.readInt32();
if (status == NO_ERROR) {
*privacySensitive = reply.readInt32() == 1;
}
ALOGV("%s status %d enabled: %s", __func__, status, *privacySensitive ? "true" : "false");
return status;
}
status_t setOutputFormat(int of)
{
ALOGV("setOutputFormat(%d)", of);
@ -537,6 +569,24 @@ status_t BnMediaRecorder::onTransact(
reply->writeInt32(setAudioSource(as));
return NO_ERROR;
} break;
case SET_PRIVACY_SENSITIVE: {
ALOGV("SET_PRIVACY_SENSITIVE");
CHECK_INTERFACE(IMediaRecorder, data, reply);
bool privacySensitive = data.readInt32() == 1;
reply->writeInt32(setPrivacySensitive(privacySensitive));
return NO_ERROR;
} break;
case GET_PRIVACY_SENSITIVE: {
ALOGV("GET_PRIVACY_SENSITIVE");
CHECK_INTERFACE(IMediaRecorder, data, reply);
bool privacySensitive = false;
status_t status = isPrivacySensitive(&privacySensitive);
reply->writeInt32(status);
if (status == NO_ERROR) {
reply->writeInt32(privacySensitive ? 1 : 0);
}
return NO_ERROR;
} break;
case SET_OUTPUT_FORMAT: {
ALOGV("SET_OUTPUT_FORMAT");
CHECK_INTERFACE(IMediaRecorder, data, reply);

@ -44,6 +44,8 @@ public:
virtual status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface) = 0;
virtual status_t setVideoSource(int vs) = 0;
virtual status_t setAudioSource(int as) = 0;
virtual status_t setPrivacySensitive(bool privacySensitive) = 0;
virtual status_t isPrivacySensitive(bool *privacySensitive) const = 0;
virtual status_t setOutputFormat(int of) = 0;
virtual status_t setVideoEncoder(int ve) = 0;
virtual status_t setAudioEncoder(int ae) = 0;

@ -39,6 +39,8 @@ struct MediaRecorderBase {
virtual status_t init() = 0;
virtual status_t setAudioSource(audio_source_t as) = 0;
virtual status_t setPrivacySensitive(bool privacySensitive) = 0 ;
virtual status_t isPrivacySensitive(bool *privacySensitive) const = 0;
virtual status_t setVideoSource(video_source vs) = 0;
virtual status_t setOutputFormat(output_format of) = 0;
virtual status_t setAudioEncoder(audio_encoder ae) = 0;
@ -79,6 +81,7 @@ struct MediaRecorderBase {
protected:
String16 mOpPackageName;
private:

@ -236,6 +236,8 @@ public:
status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface);
status_t setVideoSource(int vs);
status_t setAudioSource(int as);
status_t setPrivacySensitive(bool privacySensitive);
status_t isPrivacySensitive(bool *privacySensitive) const;
status_t setOutputFormat(int of);
status_t setVideoEncoder(int ve);
status_t setAudioEncoder(int ae);

@ -178,6 +178,47 @@ status_t MediaRecorder::setAudioSource(int as)
return ret;
}
status_t MediaRecorder::setPrivacySensitive(bool privacySensitive)
{
ALOGV("%s(%s)", __func__, privacySensitive ? "true" : "false");
if (mMediaRecorder == NULL) {
ALOGE("%s: media recorder is not initialized yet", __func__);
return INVALID_OPERATION;
}
if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED) || !mIsAudioSourceSet) {
ALOGE("%s called in an invalid state(%d) or audio source not (%d)",
__func__, mCurrentState, mIsAudioSourceSet);
return INVALID_OPERATION;
}
status_t ret = mMediaRecorder->setPrivacySensitive(privacySensitive);
if (OK != ret) {
ALOGV("%s failed: %d", __func__, ret);
mCurrentState = MEDIA_RECORDER_ERROR;
return ret;
}
return ret;
}
status_t MediaRecorder::isPrivacySensitive(bool *privacySensitive) const
{
if (mMediaRecorder == NULL) {
ALOGE("%s: media recorder is not initialized yet", __func__);
return INVALID_OPERATION;
}
if (!(mCurrentState & MEDIA_RECORDER_INITIALIZED) || !mIsAudioSourceSet) {
ALOGE("%s called in an invalid state(%d) or audio source not (%d)",
__func__, mCurrentState, mIsAudioSourceSet);
return INVALID_OPERATION;
}
status_t ret = mMediaRecorder->isPrivacySensitive(privacySensitive);
ALOGV("%s status: %d eanbled %s", __func__, ret, *privacySensitive ? "enabled" : "disabled");
return ret;
}
status_t MediaRecorder::setOutputFormat(int of)
{
ALOGV("setOutputFormat(%d)", of);

@ -395,6 +395,7 @@ const AudioFlagConverter::Table AudioFlagConverter::mTable[] = {
MAKE_STRING_FROM_ENUM(AUDIO_FLAG_DEEP_BUFFER),
MAKE_STRING_FROM_ENUM(AUDIO_FLAG_NO_MEDIA_PROJECTION),
MAKE_STRING_FROM_ENUM(AUDIO_FLAG_NO_SYSTEM_CAPTURE),
MAKE_STRING_FROM_ENUM(AUDIO_FLAG_CAPTURE_PRIVATE),
TERMINATOR
};

@ -138,6 +138,29 @@ status_t MediaRecorderClient::setAudioSource(int as)
return mRecorder->setAudioSource((audio_source_t)as);
}
status_t MediaRecorderClient::setPrivacySensitive(bool privacySensitive)
{
ALOGV("%s(%s)", __func__, privacySensitive ? "true" : "false");
Mutex::Autolock lock(mLock);
if (mRecorder == NULL) {
ALOGE("%s: recorder is not initialized", __func__);
return NO_INIT;
}
return mRecorder->setPrivacySensitive(privacySensitive);
}
status_t MediaRecorderClient::isPrivacySensitive(bool *privacySensitive) const
{
Mutex::Autolock lock(mLock);
if (mRecorder == NULL) {
ALOGE("%s: recorder is not initialized", __func__);
return NO_INIT;
}
status_t status = mRecorder->isPrivacySensitive(privacySensitive);
ALOGV("%s: status: %d enabled: %s", __func__, status, *privacySensitive ? "true" : "false");
return status;
}
status_t MediaRecorderClient::setOutputFormat(int of)
{
ALOGV("setOutputFormat(%d)", of);

@ -51,6 +51,8 @@ public:
virtual status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface);
virtual status_t setVideoSource(int vs);
virtual status_t setAudioSource(int as);
status_t setPrivacySensitive(bool privacySensitive) override;
status_t isPrivacySensitive(bool *privacySensitive) const override;
virtual status_t setOutputFormat(int of);
virtual status_t setVideoEncoder(int ve);
virtual status_t setAudioEncoder(int ae);
@ -98,7 +100,7 @@ private:
sp<AudioDeviceUpdatedNotifier> mAudioDeviceUpdatedNotifier;
pid_t mPid;
Mutex mLock;
mutable Mutex mLock;
MediaRecorderBase *mRecorder;
sp<MediaPlayerService> mMediaPlayerService;
};

@ -115,6 +115,7 @@ StagefrightRecorder::StagefrightRecorder(const String16 &opPackageName)
mWriter(NULL),
mOutputFd(-1),
mAudioSource((audio_source_t)AUDIO_SOURCE_CNT), // initialize with invalid value
mPrivacySensitive(PRIVACY_SENSITIVE_DEFAULT),
mVideoSource(VIDEO_SOURCE_LIST_END),
mStarted(false),
mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
@ -238,7 +239,31 @@ status_t StagefrightRecorder::setAudioSource(audio_source_t as) {
} else {
mAudioSource = as;
}
// Reset privacy sensitive in case this is the second time audio source is set
mPrivacySensitive = PRIVACY_SENSITIVE_DEFAULT;
return OK;
}
status_t StagefrightRecorder::setPrivacySensitive(bool privacySensitive) {
// privacy sensitive cannot be set before audio source is set
if (mAudioSource == AUDIO_SOURCE_CNT) {
return INVALID_OPERATION;
}
mPrivacySensitive = privacySensitive ? PRIVACY_SENSITIVE_ENABLED : PRIVACY_SENSITIVE_DISABLED;
return OK;
}
status_t StagefrightRecorder::isPrivacySensitive(bool *privacySensitive) const {
*privacySensitive = false;
if (mAudioSource == AUDIO_SOURCE_CNT) {
return INVALID_OPERATION;
}
if (mPrivacySensitive == PRIVACY_SENSITIVE_DEFAULT) {
*privacySensitive = mAudioSource == AUDIO_SOURCE_VOICE_COMMUNICATION
|| mAudioSource == AUDIO_SOURCE_CAMCORDER;
} else {
*privacySensitive = mPrivacySensitive == PRIVACY_SENSITIVE_ENABLED;
}
return OK;
}
@ -1082,9 +1107,35 @@ sp<MediaCodecSource> StagefrightRecorder::createAudioSource() {
}
}
audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
attr.source = mAudioSource;
// attr.flags AUDIO_FLAG_CAPTURE_PRIVATE is cleared by default
if (mPrivacySensitive == PRIVACY_SENSITIVE_DEFAULT) {
if (attr.source == AUDIO_SOURCE_VOICE_COMMUNICATION
|| attr.source == AUDIO_SOURCE_CAMCORDER) {
attr.flags |= AUDIO_FLAG_CAPTURE_PRIVATE;
mPrivacySensitive = PRIVACY_SENSITIVE_ENABLED;
} else {
mPrivacySensitive = PRIVACY_SENSITIVE_DISABLED;
}
} else {
if (mAudioSource == AUDIO_SOURCE_REMOTE_SUBMIX
|| mAudioSource == AUDIO_SOURCE_FM_TUNER
|| mAudioSource == AUDIO_SOURCE_VOICE_DOWNLINK
|| mAudioSource == AUDIO_SOURCE_VOICE_UPLINK
|| mAudioSource == AUDIO_SOURCE_VOICE_CALL
|| mAudioSource == AUDIO_SOURCE_ECHO_REFERENCE) {
ALOGE("Cannot request private capture with source: %d", mAudioSource);
return NULL;
}
if (mPrivacySensitive == PRIVACY_SENSITIVE_ENABLED) {
attr.flags |= AUDIO_FLAG_CAPTURE_PRIVATE;
}
}
sp<AudioSource> audioSource =
new AudioSource(
mAudioSource,
&attr,
mOpPackageName,
sourceSampleRate,
mAudioChannels,

@ -46,6 +46,8 @@ struct StagefrightRecorder : public MediaRecorderBase {
virtual ~StagefrightRecorder();
virtual status_t init();
virtual status_t setAudioSource(audio_source_t as);
status_t setPrivacySensitive(bool privacySensitive) override;
status_t isPrivacySensitive(bool *privacySensitive) const override;
virtual status_t setVideoSource(video_source vs);
virtual status_t setOutputFormat(output_format of);
virtual status_t setAudioEncoder(audio_encoder ae);
@ -82,6 +84,13 @@ struct StagefrightRecorder : public MediaRecorderBase {
status_t getPortId(audio_port_handle_t *portId) const override;
private:
enum privacy_sensitive_t {
PRIVACY_SENSITIVE_DEFAULT = -1,
PRIVACY_SENSITIVE_DISABLED = 0,
PRIVACY_SENSITIVE_ENABLED = 1,
};
mutable Mutex mLock;
sp<hardware::ICamera> mCamera;
sp<ICameraRecordingProxy> mCameraProxy;
@ -101,6 +110,7 @@ private:
void updateMetrics();
audio_source_t mAudioSource;
privacy_sensitive_t mPrivacySensitive;
video_source mVideoSource;
output_format mOutputFormat;
audio_encoder mAudioEncoder;

@ -50,7 +50,7 @@ static void AudioRecordCallbackFunction(int event, void *user, void *info) {
}
AudioSource::AudioSource(
audio_source_t inputSource, const String16 &opPackageName,
const audio_attributes_t *attr, const String16 &opPackageName,
uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
uid_t uid, pid_t pid, audio_port_handle_t selectedDeviceId,
audio_microphone_direction_t selectedMicDirection,
@ -92,7 +92,7 @@ AudioSource::AudioSource(
}
mRecord = new AudioRecord(
inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
AUDIO_SOURCE_DEFAULT, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
audio_channel_in_mask_from_count(channelCount),
opPackageName,
(size_t) (bufCount * frameCount),
@ -104,7 +104,7 @@ AudioSource::AudioSource(
AUDIO_INPUT_FLAG_NONE,
uid,
pid,
NULL /*pAttributes*/,
attr,
selectedDeviceId,
selectedMicDirection,
selectedMicFieldDimension);

@ -37,7 +37,7 @@ struct AudioSource : public MediaSource, public MediaBufferObserver {
// Note that the "channels" parameter _is_ the number of channels,
// _not_ a bitmask of audio_channels_t constants.
AudioSource(
audio_source_t inputSource,
const audio_attributes_t *attr,
const String16 &opPackageName,
uint32_t sampleRate,
uint32_t channels,

@ -489,7 +489,7 @@ void AudioPolicyService::updateUidStates_l()
latestActive = current;
latestStartNs = current->startTimeNs;
}
if (isPrivacySensitiveSource(current->attributes.source)) {
if ((current->attributes.flags & AUDIO_FLAG_CAPTURE_PRIVATE) != 0) {
if (current->startTimeNs > latestSensitiveStartNs) {
latestSensitiveActive = current;
latestSensitiveStartNs = current->startTimeNs;
@ -601,19 +601,6 @@ app_state_t AudioPolicyService::apmStatFromAmState(int amState) {
return APP_STATE_FOREGROUND;
}
/* static */
bool AudioPolicyService::isPrivacySensitiveSource(audio_source_t source)
{
switch (source) {
case AUDIO_SOURCE_CAMCORDER:
case AUDIO_SOURCE_VOICE_COMMUNICATION:
return true;
default:
break;
}
return false;
}
/* static */
bool AudioPolicyService::isVirtualSource(audio_source_t source)
{

@ -338,7 +338,6 @@ private:
void silenceAllRecordings_l();
static bool isPrivacySensitiveSource(audio_source_t source);
static bool isVirtualSource(audio_source_t source);
// If recording we need to make sure the UID is allowed to do that. If the UID is idle

@ -62,6 +62,7 @@ std::string AAudioServiceEndpoint::dump() const {
result << " InputPreset: " << getInputPreset() << "\n";
result << " Reference Count: " << mOpenCount << "\n";
result << " Session Id: " << getSessionId() << "\n";
result << " Privacy Sensitive: " << isPrivacySensitive() << "\n";
result << " Connected: " << mConnected.load() << "\n";
result << " Registered Streams:" << "\n";
result << AAudioServiceStreamShared::dumpHeader() << "\n";

@ -90,9 +90,14 @@ aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamReques
const audio_source_t source = (direction == AAUDIO_DIRECTION_INPUT)
? AAudioConvert_inputPresetToAudioSource(getInputPreset())
: AUDIO_SOURCE_DEFAULT;
const audio_flags_mask_t flags = AUDIO_FLAG_LOW_LATENCY |
AAudioConvert_allowCapturePolicyToAudioFlagsMask(getAllowedCapturePolicy());
audio_flags_mask_t flags;
if (direction == AAUDIO_DIRECTION_OUTPUT) {
flags = AUDIO_FLAG_LOW_LATENCY
| AAudioConvert_allowCapturePolicyToAudioFlagsMask(getAllowedCapturePolicy());
} else {
flags = AUDIO_FLAG_LOW_LATENCY
| AAudioConvert_privacySensitiveToAudioFlagsMask(isPrivacySensitive());
}
const audio_attributes_t attributes = {
.content_type = contentType,
.usage = usage,

Loading…
Cancel
Save