2eebf92965
Attribution source is the abstraction to capture the data flows for private data across apps. Checking permissions for an attribution source does this for all apps in the chain that would receive the data as well as the relevant app ops are checked/noted/started as needed. Teach speech recognition service about attribution chains. If an implementation does nothing the OS would enforce permisisons and do blame as always. This apporach leads to double blaming and doesn't support attribition chains where app calls into the default recognizer which calls into the on device recognizer (this nests recursively). If the implementer takes advantage of the attribution chain mechanims the permissions for the entire chain are checked at mic access time and all apps are blamed only once. Fixed a few bugs around finishing ops for attribution chains. Also ensured that any app death in a started attribution chain would lead to finishing the op for this app bug: 158792096 Test: (added tests for speech reco) atest CtsMediaTestCases atest CtsPermissionTestCases atest CtsPermission2TestCases atest CtsPermission3TestCases atest CtsPermission4TestCases atest CtsPermission5TestCases atest CtsAppOpsTestCases atest CtsAppOps2TestCases Merged-In: Ic92c7adc14bd2d135ac13b96f17a1b393dd562e4 Change-Id: Ic92c7adc14bd2d135ac13b96f17a1b393dd562e4
190 lines
7.8 KiB
C++
190 lines
7.8 KiB
C++
/*
|
|
* Copyright (C) 2010 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef ANDROID_MEDIA_VISUALIZER_H
|
|
#define ANDROID_MEDIA_VISUALIZER_H
|
|
|
|
#include <media/AudioEffect.h>
|
|
#include <system/audio_effects/effect_visualizer.h>
|
|
#include <utils/Thread.h>
|
|
#include "android/content/AttributionSourceState.h"
|
|
|
|
/**
|
|
* The Visualizer class enables application to retrieve part of the currently playing audio for
|
|
* visualization purpose. It is not an audio recording interface and only returns partial and low
|
|
* quality audio content. However, to protect privacy of certain audio data (e.g voice mail) the use
|
|
* of the visualizer requires the permission android.permission.RECORD_AUDIO.
|
|
* The audio session ID passed to the constructor indicates which audio content should be
|
|
* visualized:
|
|
* - If the session is 0, the audio output mix is visualized
|
|
* - If the session is not 0, the audio from a particular MediaPlayer or AudioTrack
|
|
* using this audio session is visualized
|
|
* Two types of representation of audio content can be captured:
|
|
* - Waveform data: consecutive 8-bit (unsigned) mono samples by using the getWaveForm() method
|
|
* - Frequency data: 8-bit magnitude FFT by using the getFft() method
|
|
*
|
|
* The length of the capture can be retrieved or specified by calling respectively
|
|
* getCaptureSize() and setCaptureSize() methods. Note that the size of the FFT
|
|
* is half of the specified capture size but both sides of the spectrum are returned yielding in a
|
|
* number of bytes equal to the capture size. The capture size must be a power of 2 in the range
|
|
* returned by getMinCaptureSize() and getMaxCaptureSize().
|
|
* In addition to the polling capture mode, a callback mode is also available by installing a
|
|
* callback function by use of the setCaptureCallBack() method. The rate at which the callback
|
|
* is called as well as the type of data returned is specified.
|
|
* Before capturing data, the Visualizer must be enabled by calling the setEnabled() method.
|
|
* When data capture is not needed any more, the Visualizer should be disabled.
|
|
*/
|
|
|
|
|
|
namespace android {
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class Visualizer: public AudioEffect {
|
|
public:
|
|
|
|
enum callback_flags {
|
|
CAPTURE_WAVEFORM = 0x00000001, // capture callback returns a PCM wave form
|
|
CAPTURE_FFT = 0x00000002, // apture callback returns a frequency representation
|
|
CAPTURE_CALL_JAVA = 0x00000004 // the callback thread can call java
|
|
};
|
|
|
|
|
|
/* Constructor.
|
|
* See AudioEffect constructor for details on parameters.
|
|
*/
|
|
explicit Visualizer(const android::content::AttributionSourceState& attributionSource);
|
|
|
|
~Visualizer();
|
|
|
|
/**
|
|
* Initialize an uninitialized Visualizer.
|
|
* See AudioEffect 'set' function for details on parameters.
|
|
*/
|
|
status_t set(int32_t priority = 0,
|
|
effect_callback_t cbf = NULL,
|
|
void* user = NULL,
|
|
audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX,
|
|
audio_io_handle_t io = AUDIO_IO_HANDLE_NONE,
|
|
const AudioDeviceTypeAddr& device = {},
|
|
bool probe = false);
|
|
|
|
// Declared 'final' because we call this in ~Visualizer().
|
|
status_t setEnabled(bool enabled) final;
|
|
|
|
// maximum capture size in samples
|
|
static uint32_t getMaxCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MAX; }
|
|
// minimum capture size in samples
|
|
static uint32_t getMinCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MIN; }
|
|
// maximum capture rate in millihertz
|
|
static uint32_t getMaxCaptureRate() { return CAPTURE_RATE_MAX; }
|
|
|
|
// callback used to return periodic PCM or FFT captures to the application. Either one or both
|
|
// types of data are returned (PCM and FFT) according to flags indicated when installing the
|
|
// callback. When a type of data is not present, the corresponding size (waveformSize or
|
|
// fftSize) is 0.
|
|
typedef void (*capture_cbk_t)(void* user,
|
|
uint32_t waveformSize,
|
|
uint8_t *waveform,
|
|
uint32_t fftSize,
|
|
uint8_t *fft,
|
|
uint32_t samplingrate);
|
|
|
|
// install a callback to receive periodic captures. The capture rate is specified in milliHertz
|
|
// and the capture format is according to flags (see callback_flags).
|
|
status_t setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate);
|
|
|
|
// set the capture size capture size must be a power of two in the range
|
|
// [VISUALIZER_CAPTURE_SIZE_MAX. VISUALIZER_CAPTURE_SIZE_MIN]
|
|
// must be called when the visualizer is not enabled
|
|
status_t setCaptureSize(uint32_t size);
|
|
uint32_t getCaptureSize() { return mCaptureSize; }
|
|
|
|
// returns the capture rate indicated when installing the callback
|
|
uint32_t getCaptureRate() { return mCaptureRate; }
|
|
|
|
// returns the sampling rate of the audio being captured
|
|
uint32_t getSamplingRate() { return mSampleRate; }
|
|
|
|
// set the way volume affects the captured data
|
|
// mode must one of VISUALIZER_SCALING_MODE_NORMALIZED,
|
|
// VISUALIZER_SCALING_MODE_AS_PLAYED
|
|
status_t setScalingMode(uint32_t mode);
|
|
uint32_t getScalingMode() { return mScalingMode; }
|
|
|
|
// set which measurements are done on the audio buffers processed by the effect.
|
|
// valid measurements (mask): MEASUREMENT_MODE_PEAK_RMS
|
|
status_t setMeasurementMode(uint32_t mode);
|
|
uint32_t getMeasurementMode() { return mMeasurementMode; }
|
|
|
|
// return a set of int32_t measurements
|
|
status_t getIntMeasurements(uint32_t type, uint32_t number, int32_t *measurements);
|
|
|
|
// return a capture in PCM 8 bit unsigned format. The size of the capture is equal to
|
|
// getCaptureSize()
|
|
status_t getWaveForm(uint8_t *waveform);
|
|
|
|
// return a capture in FFT 8 bit signed format. The size of the capture is equal to
|
|
// getCaptureSize() but the length of the FFT is half of the size (both parts of the spectrum
|
|
// are returned
|
|
status_t getFft(uint8_t *fft);
|
|
void release();
|
|
|
|
protected:
|
|
// from IEffectClient
|
|
virtual void controlStatusChanged(bool controlGranted);
|
|
|
|
private:
|
|
|
|
static const uint32_t CAPTURE_RATE_MAX = 20000;
|
|
static const uint32_t CAPTURE_RATE_DEF = 10000;
|
|
static const uint32_t CAPTURE_SIZE_DEF = VISUALIZER_CAPTURE_SIZE_MAX;
|
|
|
|
/* internal class to handle the callback */
|
|
class CaptureThread : public Thread
|
|
{
|
|
public:
|
|
CaptureThread(Visualizer* visualizer, uint32_t captureRate, bool bCanCallJava = false);
|
|
|
|
private:
|
|
friend class Visualizer;
|
|
virtual bool threadLoop();
|
|
wp<Visualizer> mReceiver;
|
|
Mutex mLock;
|
|
uint32_t mSleepTimeUs;
|
|
};
|
|
|
|
status_t doFft(uint8_t *fft, uint8_t *waveform);
|
|
void periodicCapture();
|
|
uint32_t initCaptureSize();
|
|
|
|
Mutex mCaptureLock;
|
|
uint32_t mCaptureRate = CAPTURE_RATE_DEF;
|
|
uint32_t mCaptureSize = CAPTURE_SIZE_DEF;
|
|
uint32_t mSampleRate = 44100000;
|
|
uint32_t mScalingMode = VISUALIZER_SCALING_MODE_NORMALIZED;
|
|
uint32_t mMeasurementMode = MEASUREMENT_MODE_NONE;
|
|
capture_cbk_t mCaptureCallBack = nullptr;
|
|
void *mCaptureCbkUser = nullptr;
|
|
sp<CaptureThread> mCaptureThread;
|
|
uint32_t mCaptureFlags = 0;
|
|
};
|
|
|
|
|
|
}; // namespace android
|
|
|
|
#endif // ANDROID_MEDIA_VISUALIZER_H
|