Merge "stagefright: convert kKeyFrameRate between msg and meta" into mnc-dev
diff --git a/cmds/stagefright/audioloop.cpp b/cmds/stagefright/audioloop.cpp
index 7b0de24..6e9e6ec 100644
--- a/cmds/stagefright/audioloop.cpp
+++ b/cmds/stagefright/audioloop.cpp
@@ -18,6 +18,8 @@
#include <sys/stat.h>
#include <fcntl.h>
+#include <utils/String16.h>
+
#include <binder/ProcessState.h>
#include <media/mediarecorder.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -34,7 +36,7 @@
static void usage(const char* name)
{
- fprintf(stderr, "Usage: %s [-d duration] [-m] [-w] [<output-file>]\n", name);
+ fprintf(stderr, "Usage: %s [-d du.ration] [-m] [-w] [<output-file>]\n", name);
fprintf(stderr, "Encodes either a sine wave or microphone input to AMR format\n");
fprintf(stderr, " -d duration in seconds, default 5 seconds\n");
fprintf(stderr, " -m use microphone for input, default sine source\n");
@@ -85,6 +87,7 @@
// talk into the appropriate microphone for the duration
source = new AudioSource(
AUDIO_SOURCE_MIC,
+ String16(),
kSampleRate,
channels);
} else {
diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h
index 583695d..61da4f2 100644
--- a/include/media/AudioEffect.h
+++ b/include/media/AudioEffect.h
@@ -201,8 +201,12 @@
*/
/* Simple Constructor.
+ *
+ * Parameters:
+ *
+ * opPackageName: The package name used for app op checks.
*/
- AudioEffect();
+ AudioEffect(const String16& opPackageName);
/* Constructor.
@@ -211,6 +215,7 @@
*
* type: type of effect created: can be null if uuid is specified. This corresponds to
* the OpenSL ES interface implemented by this effect.
+ * opPackageName: The package name used for app op checks.
* uuid: Uuid of effect created: can be null if type is specified. This uuid corresponds to
* a particular implementation of an effect type.
* priority: requested priority for effect control: the priority level corresponds to the
@@ -227,6 +232,7 @@
*/
AudioEffect(const effect_uuid_t *type,
+ const String16& opPackageName,
const effect_uuid_t *uuid = NULL,
int32_t priority = 0,
effect_callback_t cbf = NULL,
@@ -239,6 +245,7 @@
* Same as above but with type and uuid specified by character strings
*/
AudioEffect(const char *typeStr,
+ const String16& opPackageName,
const char *uuidStr = NULL,
int32_t priority = 0,
effect_callback_t cbf = NULL,
@@ -406,7 +413,9 @@
void* mUserData; // client context for callback function
effect_descriptor_t mDescriptor; // effect descriptor
int32_t mId; // system wide unique effect engine instance ID
- Mutex mLock; // Mutex for mEnabled access
+ Mutex mLock; // Mutex for mEnabled access
+
+ String16 mOpPackageName; // The package name used for app op checks.
// IEffectClient
virtual void controlStatusChanged(bool controlGranted);
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index dbe2788..b743c11 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -129,8 +129,12 @@
/* Constructs an uninitialized AudioRecord. No connection with
* AudioFlinger takes place. Use set() after this.
+ *
+ * Parameters:
+ *
+ * opPackageName: The package name used for app ops.
*/
- AudioRecord();
+ AudioRecord(const String16& opPackageName);
/* Creates an AudioRecord object and registers it with AudioFlinger.
* Once created, the track needs to be started before it can be used.
@@ -143,6 +147,7 @@
* format: Audio format (e.g AUDIO_FORMAT_PCM_16_BIT for signed
* 16 bits per sample).
* channelMask: Channel mask, such that audio_is_input_channel(channelMask) is true.
+ * opPackageName: The package name used for app ops.
* frameCount: Minimum size of track PCM buffer in frames. This defines the
* application's contribution to the
* latency of the track. The actual size selected by the AudioRecord could
@@ -165,6 +170,7 @@
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
+ const String16& opPackageName,
size_t frameCount = 0,
callback_t cbf = NULL,
void* user = NULL,
@@ -374,6 +380,16 @@
status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount,
size_t *nonContig = NULL);
+ // Explicit Routing
+ /**
+ * TODO Document this method.
+ */
+ status_t setInputDevice(audio_port_handle_t deviceId);
+
+ /**
+ * TODO Document this method.
+ */
+ audio_port_handle_t getInputDevice();
private:
/* If nonContig is non-NULL, it is an output parameter that will be set to the number of
* additional non-contiguous frames that are predicted to be available immediately,
@@ -473,7 +489,7 @@
// caller must hold lock on mLock for all _l methods
- status_t openRecord_l(size_t epoch);
+ status_t openRecord_l(size_t epoch, const String16& opPackageName);
// FIXME enum is faster than strcmp() for parameter 'from'
status_t restoreRecord_l(const char *from);
@@ -510,6 +526,8 @@
status_t mStatus;
+ String16 mOpPackageName; // The package name used for app ops.
+
size_t mFrameCount; // corresponds to current IAudioRecord, value is
// reported back by AudioFlinger to the client
size_t mReqFrameCount; // frame count to request the first or next time
@@ -560,6 +578,10 @@
sp<DeathNotifier> mDeathNotifier;
uint32_t mSequence; // incremented for each new IAudioRecord attempt
audio_attributes_t mAttributes;
+
+ // For Device Selection API
+ // a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
+ audio_port_handle_t mSelectedDeviceId;
};
}; // namespace android
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 182133c..a454481 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -248,7 +248,8 @@
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_input_flags_t flags);
+ audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
static status_t startInput(audio_io_handle_t input,
audio_session_t session);
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 2d34c02..e7ee0ce 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -859,7 +859,7 @@
// For Device Selection API
// a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
- int mSelectedDeviceId;
+ audio_port_handle_t mSelectedDeviceId;
private:
class DeathNotifier : public IBinder::DeathRecipient {
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index f927a80..046345c 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -85,6 +85,7 @@
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
+ const String16& callingPackage,
size_t *pFrameCount,
track_flags_t *flags,
pid_t tid, // -1 means unused, otherwise must be valid non-0
@@ -198,6 +199,7 @@
// AudioFlinger doesn't take over handle reference from client
audio_io_handle_t output,
int sessionId,
+ const String16& callingPackage,
status_t *status,
int *id,
int *enabled) = 0;
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 413267b..56a1dc6 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -78,12 +78,13 @@
audio_stream_type_t stream,
audio_session_t session) = 0;
virtual status_t getInputForAttr(const audio_attributes_t *attr,
- audio_io_handle_t *input,
- audio_session_t session,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- audio_input_flags_t flags) = 0;
+ audio_io_handle_t *input,
+ audio_session_t session,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE) = 0;
virtual status_t startInput(audio_io_handle_t input,
audio_session_t session) = 0;
virtual status_t stopInput(audio_io_handle_t input,
diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
index 49a3d61..a316ce2 100644
--- a/include/media/IMediaPlayerService.h
+++ b/include/media/IMediaPlayerService.h
@@ -47,7 +47,7 @@
public:
DECLARE_META_INTERFACE(MediaPlayerService);
- virtual sp<IMediaRecorder> createMediaRecorder() = 0;
+ virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName) = 0;
virtual sp<IMediaMetadataRetriever> createMetadataRetriever() = 0;
virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client, int audioSessionId = 0)
= 0;
@@ -65,8 +65,8 @@
// display client when display connection, disconnection or errors occur.
// The assumption is that at most one remote display will be connected to the
// provided interface at a time.
- virtual sp<IRemoteDisplay> listenForRemoteDisplay(const sp<IRemoteDisplayClient>& client,
- const String8& iface) = 0;
+ virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName,
+ const sp<IRemoteDisplayClient>& client, const String8& iface) = 0;
// codecs and audio devices usage tracking for the battery app
enum BatteryDataBits {
diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h
index f55063e..f9feede 100644
--- a/include/media/MediaRecorderBase.h
+++ b/include/media/MediaRecorderBase.h
@@ -29,7 +29,8 @@
class IGraphicBufferProducer;
struct MediaRecorderBase {
- MediaRecorderBase() {}
+ MediaRecorderBase(const String16 &opPackageName)
+ : mOpPackageName(opPackageName) {}
virtual ~MediaRecorderBase() {}
virtual status_t init() = 0;
@@ -57,6 +58,10 @@
virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() const = 0;
+
+protected:
+ String16 mOpPackageName;
+
private:
MediaRecorderBase(const MediaRecorderBase &);
MediaRecorderBase &operator=(const MediaRecorderBase &);
diff --git a/include/media/MediaResource.h b/include/media/MediaResource.h
index 0b57c84..20f2cad 100644
--- a/include/media/MediaResource.h
+++ b/include/media/MediaResource.h
@@ -25,6 +25,8 @@
extern const char kResourceSecureCodec[];
extern const char kResourceNonSecureCodec[];
+extern const char kResourceAudioCodec[];
+extern const char kResourceVideoCodec[];
extern const char kResourceGraphicMemory[];
class MediaResource {
diff --git a/include/media/Visualizer.h b/include/media/Visualizer.h
index 6167dd6..b92f816 100644
--- a/include/media/Visualizer.h
+++ b/include/media/Visualizer.h
@@ -65,7 +65,8 @@
/* Constructor.
* See AudioEffect constructor for details on parameters.
*/
- Visualizer(int32_t priority = 0,
+ Visualizer(const String16& opPackageName,
+ int32_t priority = 0,
effect_callback_t cbf = NULL,
void* user = NULL,
int sessionId = 0);
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 74a6469..8e40c5d 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -209,7 +209,7 @@
public virtual IMediaDeathNotifier
{
public:
- MediaRecorder();
+ MediaRecorder(const String16& opPackageName);
~MediaRecorder();
void died();
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index a8d0fcb..c14e6c0 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -192,6 +192,7 @@
List<sp<AMessage> > mDeferredQueue;
bool mSentFormat;
+ bool mIsVideo;
bool mIsEncoder;
bool mUseMetadataOnEncoderOutput;
bool mShutdownInProgress;
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index 4c9aaad..50cf371 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -35,6 +35,7 @@
// _not_ a bitmask of audio_channels_t constants.
AudioSource(
audio_source_t inputSource,
+ const String16 &opPackageName,
uint32_t sampleRate,
uint32_t channels = 1);
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index f2b21c9..d89e4c7 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -351,7 +351,7 @@
bool isExecuting() const;
uint64_t getGraphicBufferSize();
- void addResource(const char *type, uint64_t value);
+ void addResource(const String8 &type, const String8 &subtype, uint64_t value);
/* called to get the last codec error when the sticky flag is set.
* if no such codec error is found, returns UNKNOWN_ERROR.
diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp
index 7d8222f..bbeb854 100644
--- a/media/libmedia/AudioEffect.cpp
+++ b/media/libmedia/AudioEffect.cpp
@@ -35,13 +35,14 @@
// ---------------------------------------------------------------------------
-AudioEffect::AudioEffect()
- : mStatus(NO_INIT)
+AudioEffect::AudioEffect(const String16& opPackageName)
+ : mStatus(NO_INIT), mOpPackageName(opPackageName)
{
}
AudioEffect::AudioEffect(const effect_uuid_t *type,
+ const String16& opPackageName,
const effect_uuid_t *uuid,
int32_t priority,
effect_callback_t cbf,
@@ -49,12 +50,13 @@
int sessionId,
audio_io_handle_t io
)
- : mStatus(NO_INIT)
+ : mStatus(NO_INIT), mOpPackageName(opPackageName)
{
mStatus = set(type, uuid, priority, cbf, user, sessionId, io);
}
AudioEffect::AudioEffect(const char *typeStr,
+ const String16& opPackageName,
const char *uuidStr,
int32_t priority,
effect_callback_t cbf,
@@ -62,7 +64,7 @@
int sessionId,
audio_io_handle_t io
)
- : mStatus(NO_INIT)
+ : mStatus(NO_INIT), mOpPackageName(opPackageName)
{
effect_uuid_t type;
effect_uuid_t *pType = NULL;
@@ -128,7 +130,7 @@
mIEffectClient = new EffectClient(this);
iEffect = audioFlinger->createEffect((effect_descriptor_t *)&mDescriptor,
- mIEffectClient, priority, io, mSessionId, &mStatus, &mId, &enabled);
+ mIEffectClient, priority, io, mSessionId, mOpPackageName, &mStatus, &mId, &enabled);
if (iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) {
ALOGE("set(): AudioFlinger could not create effect, status: %d", mStatus);
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 5bbe786..9a61977 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -65,9 +65,10 @@
// ---------------------------------------------------------------------------
-AudioRecord::AudioRecord()
- : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE),
- mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
+AudioRecord::AudioRecord(const String16 &opPackageName)
+ : mStatus(NO_INIT), mOpPackageName(opPackageName), mSessionId(AUDIO_SESSION_ALLOCATE),
+ mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT),
+ mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
{
}
@@ -76,6 +77,7 @@
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
+ const String16& opPackageName,
size_t frameCount,
callback_t cbf,
void* user,
@@ -84,10 +86,13 @@
transfer_type transferType,
audio_input_flags_t flags,
const audio_attributes_t* pAttributes)
- : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE),
+ : mStatus(NO_INIT),
+ mOpPackageName(opPackageName),
+ mSessionId(AUDIO_SESSION_ALLOCATE),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
mPreviousSchedulingGroup(SP_DEFAULT),
- mProxy(NULL)
+ mProxy(NULL),
+ mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
{
mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
@@ -134,9 +139,9 @@
const audio_attributes_t* pAttributes)
{
ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
- "notificationFrames %u, sessionId %d, transferType %d, flags %#x",
+ "notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s",
inputSource, sampleRate, format, channelMask, frameCount, notificationFrames,
- sessionId, transferType, flags);
+ sessionId, transferType, flags, String8(mOpPackageName).string());
switch (transferType) {
case TRANSFER_DEFAULT:
@@ -233,7 +238,7 @@
}
// create the IAudioRecord
- status_t status = openRecord_l(0 /*epoch*/);
+ status_t status = openRecord_l(0 /*epoch*/, mOpPackageName);
if (status != NO_ERROR) {
if (mAudioRecordThread != 0) {
@@ -415,10 +420,25 @@
return AudioSystem::getInputFramesLost(getInputPrivate());
}
+// ---- Explicit Routing ---------------------------------------------------
+status_t AudioRecord::setInputDevice(audio_port_handle_t deviceId) {
+ AutoMutex lock(mLock);
+ if (mSelectedDeviceId != deviceId) {
+ mSelectedDeviceId = deviceId;
+ android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
+ }
+ return NO_ERROR;
+}
+
+audio_port_handle_t AudioRecord::getInputDevice() {
+ AutoMutex lock(mLock);
+ return mSelectedDeviceId;
+}
+
// -------------------------------------------------------------------------
// must be called with mLock held
-status_t AudioRecord::openRecord_l(size_t epoch)
+status_t AudioRecord::openRecord_l(size_t epoch, const String16& opPackageName)
{
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
if (audioFlinger == 0) {
@@ -461,7 +481,8 @@
audio_io_handle_t input;
status_t status = AudioSystem::getInputForAttr(&mAttributes, &input,
(audio_session_t)mSessionId,
- mSampleRate, mFormat, mChannelMask, mFlags);
+ mSampleRate, mFormat, mChannelMask,
+ mFlags, mSelectedDeviceId);
if (status != NO_ERROR) {
ALOGE("Could not get audio input for record source %d, sample rate %u, format %#x, "
@@ -484,8 +505,10 @@
sp<IMemory> iMem; // for cblk
sp<IMemory> bufferMem;
sp<IAudioRecord> record = audioFlinger->openRecord(input,
- mSampleRate, mFormat,
+ mSampleRate,
+ mFormat,
mChannelMask,
+ opPackageName,
&temp,
&trackFlags,
tid,
@@ -1014,7 +1037,7 @@
// It will also delete the strong references on previous IAudioRecord and IMemory
size_t position = mProxy->getPosition();
mNewPosition = position + mUpdatePeriod;
- status_t result = openRecord_l(position);
+ status_t result = openRecord_l(position, mOpPackageName);
if (result == NO_ERROR) {
if (mActive) {
// callback thread or sync event hasn't changed
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 2ed50e8..3478441 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -700,11 +700,13 @@
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_input_flags_t flags)
+ audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return NO_INIT;
- return aps->getInputForAttr(attr, input, session, samplingRate, format, channelMask, flags);
+ return aps->getInputForAttr(
+ attr, input, session, samplingRate, format, channelMask, flags, selectedDeviceId);
}
status_t AudioSystem::startInput(audio_io_handle_t input,
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 38055f9..d48532e 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -174,6 +174,7 @@
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
+ const String16& opPackageName,
size_t *pFrameCount,
track_flags_t *flags,
pid_t tid,
@@ -190,6 +191,7 @@
data.writeInt32(sampleRate);
data.writeInt32(format);
data.writeInt32(channelMask);
+ data.writeString16(opPackageName);
size_t frameCount = pFrameCount != NULL ? *pFrameCount : 0;
data.writeInt64(frameCount);
track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
@@ -702,6 +704,7 @@
int32_t priority,
audio_io_handle_t output,
int sessionId,
+ const String16& opPackageName,
status_t *status,
int *id,
int *enabled)
@@ -722,6 +725,7 @@
data.writeInt32(priority);
data.writeInt32((int32_t) output);
data.writeInt32(sessionId);
+ data.writeString16(opPackageName);
status_t lStatus = remote()->transact(CREATE_EFFECT, data, &reply);
if (lStatus != NO_ERROR) {
@@ -950,6 +954,7 @@
uint32_t sampleRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
audio_channel_mask_t channelMask = data.readInt32();
+ const String16& opPackageName = data.readString16();
size_t frameCount = data.readInt64();
track_flags_t flags = (track_flags_t) data.readInt32();
pid_t tid = (pid_t) data.readInt32();
@@ -959,9 +964,8 @@
sp<IMemory> buffers;
status_t status;
sp<IAudioRecord> record = openRecord(input,
- sampleRate, format, channelMask, &frameCount, &flags, tid, &sessionId,
- ¬ificationFrames,
- cblk, buffers, &status);
+ sampleRate, format, channelMask, opPackageName, &frameCount, &flags, tid,
+ &sessionId, ¬ificationFrames, cblk, buffers, &status);
LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR));
reply->writeInt64(frameCount);
reply->writeInt32(flags);
@@ -1247,12 +1251,13 @@
int32_t priority = data.readInt32();
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
int sessionId = data.readInt32();
+ const String16 opPackageName = data.readString16();
status_t status;
int id;
int enabled;
sp<IEffect> effect = createEffect(&desc, client, priority, output, sessionId,
- &status, &id, &enabled);
+ opPackageName, &status, &id, &enabled);
reply->writeInt32(status);
reply->writeInt32(id);
reply->writeInt32(enabled);
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index afae7f5..fc36a7f 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -278,7 +278,8 @@
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_input_flags_t flags)
+ audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -296,6 +297,7 @@
data.writeInt32(static_cast <uint32_t>(format));
data.writeInt32(channelMask);
data.writeInt32(flags);
+ data.writeInt32(selectedDeviceId);
status_t status = remote()->transact(GET_INPUT_FOR_ATTR, data, &reply);
if (status != NO_ERROR) {
return status;
@@ -914,10 +916,11 @@
audio_format_t format = (audio_format_t) data.readInt32();
audio_channel_mask_t channelMask = data.readInt32();
audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
+ audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32();
audio_io_handle_t input;
status_t status = getInputForAttr(&attr, &input, session,
samplingRate, format, channelMask,
- flags);
+ flags, selectedDeviceId);
reply->writeInt32(status);
if (status == NO_ERROR) {
reply->writeInt32(input);
diff --git a/media/libmedia/IHDCP.cpp b/media/libmedia/IHDCP.cpp
index 9122f75..f3a8902 100644
--- a/media/libmedia/IHDCP.cpp
+++ b/media/libmedia/IHDCP.cpp
@@ -241,8 +241,19 @@
case HDCP_ENCRYPT:
{
size_t size = data.readInt32();
+ size_t bufSize = 2 * size;
- void *inData = malloc(2 * size);
+ // watch out for overflow
+ void *inData = NULL;
+ if (bufSize > size) {
+ inData = malloc(bufSize);
+ }
+
+ if (inData == NULL) {
+ reply->writeInt32(ERROR_OUT_OF_RANGE);
+ return OK;
+ }
+
void *outData = (uint8_t *)inData + size;
data.read(inData, size);
@@ -273,11 +284,17 @@
size_t offset = data.readInt32();
size_t size = data.readInt32();
uint32_t streamCTR = data.readInt32();
- void *outData = malloc(size);
+ void *outData = NULL;
uint64_t inputCTR;
- status_t err = encryptNative(graphicBuffer, offset, size,
- streamCTR, &inputCTR, outData);
+ status_t err = ERROR_OUT_OF_RANGE;
+
+ outData = malloc(size);
+
+ if (outData != NULL) {
+ err = encryptNative(graphicBuffer, offset, size,
+ streamCTR, &inputCTR, outData);
+ }
reply->writeInt32(err);
@@ -295,8 +312,19 @@
case HDCP_DECRYPT:
{
size_t size = data.readInt32();
+ size_t bufSize = 2 * size;
- void *inData = malloc(2 * size);
+ // watch out for overflow
+ void *inData = NULL;
+ if (bufSize > size) {
+ inData = malloc(bufSize);
+ }
+
+ if (inData == NULL) {
+ reply->writeInt32(ERROR_OUT_OF_RANGE);
+ return OK;
+ }
+
void *outData = (uint8_t *)inData + size;
data.read(inData, size);
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index aa7b2e1..05f8670 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -78,10 +78,11 @@
return interface_cast<IMediaPlayer>(reply.readStrongBinder());
}
- virtual sp<IMediaRecorder> createMediaRecorder()
+ virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName)
{
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
+ data.writeString16(opPackageName);
remote()->transact(CREATE_MEDIA_RECORDER, data, &reply);
return interface_cast<IMediaRecorder>(reply.readStrongBinder());
}
@@ -128,11 +129,12 @@
return remote()->transact(PULL_BATTERY_DATA, data, reply);
}
- virtual sp<IRemoteDisplay> listenForRemoteDisplay(const sp<IRemoteDisplayClient>& client,
- const String8& iface)
+ virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName,
+ const sp<IRemoteDisplayClient>& client, const String8& iface)
{
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
+ data.writeString16(opPackageName);
data.writeStrongBinder(IInterface::asBinder(client));
data.writeString8(iface);
remote()->transact(LISTEN_FOR_REMOTE_DISPLAY, data, &reply);
@@ -166,7 +168,8 @@
} break;
case CREATE_MEDIA_RECORDER: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
- sp<IMediaRecorder> recorder = createMediaRecorder();
+ const String16 opPackageName = data.readString16();
+ sp<IMediaRecorder> recorder = createMediaRecorder(opPackageName);
reply->writeStrongBinder(IInterface::asBinder(recorder));
return NO_ERROR;
} break;
@@ -214,10 +217,11 @@
} break;
case LISTEN_FOR_REMOTE_DISPLAY: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
+ const String16 opPackageName = data.readString16();
sp<IRemoteDisplayClient> client(
interface_cast<IRemoteDisplayClient>(data.readStrongBinder()));
String8 iface(data.readString8());
- sp<IRemoteDisplay> display(listenForRemoteDisplay(client, iface));
+ sp<IRemoteDisplay> display(listenForRemoteDisplay(opPackageName, client, iface));
reply->writeStrongBinder(IInterface::asBinder(display));
return NO_ERROR;
} break;
diff --git a/media/libmedia/MediaResource.cpp b/media/libmedia/MediaResource.cpp
index eea2c43..40ec0cb 100644
--- a/media/libmedia/MediaResource.cpp
+++ b/media/libmedia/MediaResource.cpp
@@ -23,6 +23,8 @@
const char kResourceSecureCodec[] = "secure-codec";
const char kResourceNonSecureCodec[] = "non-secure-codec";
+const char kResourceAudioCodec[] = "audio-codec";
+const char kResourceVideoCodec[] = "video-codec";
const char kResourceGraphicMemory[] = "graphic-memory";
MediaResource::MediaResource() : mValue(0) {}
diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp
index 9d69b6a..dc46038 100644
--- a/media/libmedia/Visualizer.cpp
+++ b/media/libmedia/Visualizer.cpp
@@ -34,11 +34,12 @@
// ---------------------------------------------------------------------------
-Visualizer::Visualizer (int32_t priority,
+Visualizer::Visualizer (const String16& opPackageName,
+ int32_t priority,
effect_callback_t cbf,
void* user,
int sessionId)
- : AudioEffect(SL_IID_VISUALIZATION, NULL, priority, cbf, user, sessionId),
+ : AudioEffect(SL_IID_VISUALIZATION, opPackageName, NULL, priority, cbf, user, sessionId),
mCaptureRate(CAPTURE_RATE_DEF),
mCaptureSize(CAPTURE_SIZE_DEF),
mSampleRate(44100000),
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index a2d6e53..9470936 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -594,13 +594,13 @@
return INVALID_OPERATION;
}
-MediaRecorder::MediaRecorder() : mSurfaceMediaSource(NULL)
+MediaRecorder::MediaRecorder(const String16& opPackageName) : mSurfaceMediaSource(NULL)
{
ALOGV("constructor");
const sp<IMediaPlayerService>& service(getMediaPlayerService());
if (service != NULL) {
- mMediaRecorder = service->createMediaRecorder();
+ mMediaRecorder = service->createMediaRecorder(opPackageName);
}
if (mMediaRecorder != NULL) {
mCurrentState = MEDIA_RECORDER_IDLE;
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 3bc763f..9567eff 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -307,10 +307,10 @@
ALOGV("MediaPlayerService destroyed");
}
-sp<IMediaRecorder> MediaPlayerService::createMediaRecorder()
+sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(const String16 &opPackageName)
{
pid_t pid = IPCThreadState::self()->getCallingPid();
- sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid);
+ sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid, opPackageName);
wp<MediaRecorderClient> w = recorder;
Mutex::Autolock lock(mLock);
mMediaRecorderClients.add(w);
@@ -381,12 +381,13 @@
}
sp<IRemoteDisplay> MediaPlayerService::listenForRemoteDisplay(
+ const String16 &opPackageName,
const sp<IRemoteDisplayClient>& client, const String8& iface) {
if (!checkPermission("android.permission.CONTROL_WIFI_DISPLAY")) {
return NULL;
}
- return new RemoteDisplay(client, iface.string());
+ return new RemoteDisplay(opPackageName, client, iface.string());
}
status_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& args) const
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 6ddfe14..1a3ce92 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -188,7 +188,7 @@
static void instantiate();
// IMediaPlayerService interface
- virtual sp<IMediaRecorder> createMediaRecorder();
+ virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName);
void removeMediaRecorderClient(wp<MediaRecorderClient> client);
virtual sp<IMediaMetadataRetriever> createMetadataRetriever();
@@ -200,8 +200,8 @@
virtual sp<IDrm> makeDrm();
virtual sp<IHDCP> makeHDCP(bool createEncryptionModule);
- virtual sp<IRemoteDisplay> listenForRemoteDisplay(const sp<IRemoteDisplayClient>& client,
- const String8& iface);
+ virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName,
+ const sp<IRemoteDisplayClient>& client, const String8& iface);
virtual status_t dump(int fd, const Vector<String16>& args);
void removeClient(wp<Client> client);
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 319ebb0..40e9d1c 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -290,11 +290,12 @@
return NO_ERROR;
}
-MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid)
+MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid,
+ const String16& opPackageName)
{
ALOGV("Client constructor");
mPid = pid;
- mRecorder = new StagefrightRecorder;
+ mRecorder = new StagefrightRecorder(opPackageName);
mMediaPlayerService = service;
}
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index b45344b..e03ec3f 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -62,7 +62,8 @@
MediaRecorderClient(
const sp<MediaPlayerService>& service,
- pid_t pid);
+ pid_t pid,
+ const String16& opPackageName);
virtual ~MediaRecorderClient();
pid_t mPid;
diff --git a/media/libmediaplayerservice/RemoteDisplay.cpp b/media/libmediaplayerservice/RemoteDisplay.cpp
index eb959b4..0eb4b5d 100644
--- a/media/libmediaplayerservice/RemoteDisplay.cpp
+++ b/media/libmediaplayerservice/RemoteDisplay.cpp
@@ -26,13 +26,14 @@
namespace android {
RemoteDisplay::RemoteDisplay(
+ const String16 &opPackageName,
const sp<IRemoteDisplayClient> &client,
const char *iface)
: mLooper(new ALooper),
mNetSession(new ANetworkSession) {
mLooper->setName("wfd_looper");
- mSource = new WifiDisplaySource(mNetSession, client);
+ mSource = new WifiDisplaySource(opPackageName, mNetSession, client);
mLooper->registerHandler(mSource);
mNetSession->start();
diff --git a/media/libmediaplayerservice/RemoteDisplay.h b/media/libmediaplayerservice/RemoteDisplay.h
index 1a48981..d4573e9 100644
--- a/media/libmediaplayerservice/RemoteDisplay.h
+++ b/media/libmediaplayerservice/RemoteDisplay.h
@@ -33,6 +33,7 @@
struct RemoteDisplay : public BnRemoteDisplay {
RemoteDisplay(
+ const String16 &opPackageName,
const sp<IRemoteDisplayClient> &client,
const char *iface);
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 8a0b060d..aa19a25 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -69,8 +69,9 @@
}
-StagefrightRecorder::StagefrightRecorder()
- : mWriter(NULL),
+StagefrightRecorder::StagefrightRecorder(const String16 &opPackageName)
+ : MediaRecorderBase(opPackageName),
+ mWriter(NULL),
mOutputFd(-1),
mAudioSource(AUDIO_SOURCE_CNT),
mVideoSource(VIDEO_SOURCE_LIST_END),
@@ -905,6 +906,7 @@
sp<AudioSource> audioSource =
new AudioSource(
mAudioSource,
+ mOpPackageName,
mSampleRate,
mAudioChannels);
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 8fa5bfa..1425f59 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -40,7 +40,7 @@
struct ALooper;
struct StagefrightRecorder : public MediaRecorderBase {
- StagefrightRecorder();
+ StagefrightRecorder(const String16 &opPackageName);
virtual ~StagefrightRecorder();
virtual status_t init();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index a028b01..b670d68 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -634,6 +634,17 @@
if (mRenderer != NULL) {
mRenderer->setPlaybackRate(mPlaybackRate);
}
+
+ if (mVideoDecoder != NULL) {
+ sp<MetaData> meta = getFileMeta();
+ int32_t rate;
+ if (meta != NULL && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) {
+ sp<AMessage> params = new AMessage();
+ params->setFloat("operating-rate", rate * mPlaybackRate);
+ mVideoDecoder->setParameters(params);
+ }
+ }
+
break;
}
@@ -1249,6 +1260,8 @@
return -EWOULDBLOCK;
}
+ format->setInt32("priority", 0 /* realtime */);
+
if (!audio) {
AString mime;
CHECK(format->findString("mime", &mime));
@@ -1265,6 +1278,12 @@
if (mSourceFlags & Source::FLAG_PROTECTED) {
format->setInt32("protected", true);
}
+
+ sp<MetaData> meta = getFileMeta();
+ int32_t rate;
+ if (meta != NULL && meta->findInt32(kKeyFrameRate, &rate) && rate > 0) {
+ format->setFloat("operating-rate", rate * mPlaybackRate);
+ }
}
if (audio) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index acc9ef5..3c4d695 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -252,6 +252,14 @@
mResumePending = false;
}
+void NuPlayer::Decoder::onSetParameters(const sp<AMessage> ¶ms) {
+ if (mCodec == NULL) {
+ ALOGW("onSetParameters called before codec is created.");
+ return;
+ }
+ mCodec->setParameters(params);
+}
+
void NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
bool hadNoRenderer = (mRenderer == NULL);
mRenderer = renderer;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index 9f0ef1b5..dd84620 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -40,6 +40,7 @@
virtual void onMessageReceived(const sp<AMessage> &msg);
virtual void onConfigure(const sp<AMessage> &format);
+ virtual void onSetParameters(const sp<AMessage> ¶ms);
virtual void onSetRenderer(const sp<Renderer> &renderer);
virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers);
virtual void onResume(bool notifyComplete);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
index 36b41ec..9d509bf 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
@@ -70,6 +70,12 @@
mDecoderLooper->registerHandler(this);
}
+void NuPlayer::DecoderBase::setParameters(const sp<AMessage> ¶ms) {
+ sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
+ msg->setMessage("params", params);
+ msg->post();
+}
+
void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
sp<AMessage> msg = new AMessage(kWhatSetRenderer, this);
msg->setObject("renderer", renderer);
@@ -123,6 +129,14 @@
break;
}
+ case kWhatSetParameters:
+ {
+ sp<AMessage> params;
+ CHECK(msg->findMessage("params", ¶ms));
+ onSetParameters(params);
+ break;
+ }
+
case kWhatSetRenderer:
{
sp<RefBase> obj;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
index 262f5d5..b52e7f7 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
@@ -33,6 +33,7 @@
void configure(const sp<AMessage> &format);
void init();
+ void setParameters(const sp<AMessage> ¶ms);
void setRenderer(const sp<Renderer> &renderer);
@@ -62,6 +63,7 @@
virtual void onMessageReceived(const sp<AMessage> &msg);
virtual void onConfigure(const sp<AMessage> &format) = 0;
+ virtual void onSetParameters(const sp<AMessage> ¶ms) = 0;
virtual void onSetRenderer(const sp<Renderer> &renderer) = 0;
virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers) = 0;
virtual void onResume(bool notifyComplete) = 0;
@@ -78,6 +80,7 @@
private:
enum {
kWhatConfigure = 'conf',
+ kWhatSetParameters = 'setP',
kWhatSetRenderer = 'setR',
kWhatGetInputBuffers = 'gInB',
kWhatRequestInputBuffers = 'reqB',
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
index fdb9039..d7b070e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
@@ -88,6 +88,10 @@
}
}
+void NuPlayer::DecoderPassThrough::onSetParameters(const sp<AMessage> &/*params*/) {
+ ALOGW("onSetParameters() called unexpectedly");
+}
+
void NuPlayer::DecoderPassThrough::onSetRenderer(
const sp<Renderer> &renderer) {
// renderer can't be changed during offloading
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
index b7dcb8d..2f6df2c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
@@ -40,6 +40,7 @@
virtual void onMessageReceived(const sp<AMessage> &msg);
virtual void onConfigure(const sp<AMessage> &format);
+ virtual void onSetParameters(const sp<AMessage> ¶ms);
virtual void onSetRenderer(const sp<Renderer> &renderer);
virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers);
virtual void onResume(bool notifyComplete);
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index da22f11..c7df5a0 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -405,6 +405,7 @@
: mQuirks(0),
mNode(0),
mSentFormat(false),
+ mIsVideo(false),
mIsEncoder(false),
mUseMetadataOnEncoderOutput(false),
mShutdownInProgress(false),
@@ -1186,6 +1187,7 @@
mIsEncoder = encoder;
+
status_t err = setComponentRole(encoder /* isEncoder */, mime);
if (err != OK) {
@@ -1244,6 +1246,7 @@
// sps/pps to idr frames, since in metadata mode the bitstream is in an
// opaque handle, to which we don't have access.
int32_t video = !strncasecmp(mime, "video/", 6);
+ mIsVideo = video;
if (encoder && video) {
OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
&& msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
@@ -5684,6 +5687,15 @@
}
}
+ float rate;
+ if (params->findFloat("operating-rate", &rate) && rate > 0) {
+ status_t err = setOperatingRate(rate, mIsVideo);
+ if (err != OK) {
+ ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
+ return err;
+ }
+ }
+
return OK;
}
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 804f131..e5a6a9b 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -50,7 +50,8 @@
}
AudioSource::AudioSource(
- audio_source_t inputSource, uint32_t sampleRate, uint32_t channelCount)
+ audio_source_t inputSource, const String16 &opPackageName, uint32_t sampleRate,
+ uint32_t channelCount)
: mStarted(false),
mSampleRate(sampleRate),
mPrevSampleTimeUs(0),
@@ -78,6 +79,7 @@
mRecord = new AudioRecord(
inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
audio_channel_in_mask_from_count(channelCount),
+ opPackageName,
(size_t) (bufCount * frameCount),
AudioRecordCallbackFunction,
this,
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 7065a6e..aa0d2e6 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -434,7 +434,8 @@
status_t err;
Vector<MediaResource> resources;
const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec;
- resources.push_back(MediaResource(String8(type), 1));
+ const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
+ resources.push_back(MediaResource(String8(type), String8(subtype), 1));
for (int i = 0; i <= kMaxRetry; ++i) {
if (i > 0) {
// Don't try to reclaim resource for the first time.
@@ -492,7 +493,8 @@
Vector<MediaResource> resources;
const char *type = (mFlags & kFlagIsSecure) ?
kResourceSecureCodec : kResourceNonSecureCodec;
- resources.push_back(MediaResource(String8(type), 1));
+ const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
+ resources.push_back(MediaResource(String8(type), String8(subtype), 1));
// Don't know the buffer size at this point, but it's fine to use 1 because
// the reclaimResource call doesn't consider the requester's buffer size for now.
resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
@@ -557,9 +559,9 @@
return size;
}
-void MediaCodec::addResource(const char *type, uint64_t value) {
+void MediaCodec::addResource(const String8 &type, const String8 &subtype, uint64_t value) {
Vector<MediaResource> resources;
- resources.push_back(MediaResource(String8(type), value));
+ resources.push_back(MediaResource(type, subtype, value));
mResourceManagerService->addResource(
getCallingPid(), getId(mResourceManagerClient), mResourceManagerClient, resources);
}
@@ -571,7 +573,8 @@
Vector<MediaResource> resources;
const char *type = (mFlags & kFlagIsSecure) ?
kResourceSecureCodec : kResourceNonSecureCodec;
- resources.push_back(MediaResource(String8(type), 1));
+ const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
+ resources.push_back(MediaResource(String8(type), String8(subtype), 1));
// Don't know the buffer size at this point, but it's fine to use 1 because
// the reclaimResource call doesn't consider the requester's buffer size for now.
resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
@@ -1183,7 +1186,9 @@
mFlags &= ~kFlagIsSecure;
resourceType = String8(kResourceNonSecureCodec);
}
- addResource(resourceType, 1);
+
+ const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
+ addResource(resourceType, String8(subtype), 1);
(new AMessage)->postReply(mReplyID);
break;
@@ -1297,7 +1302,11 @@
// allocating input buffers, so this is a good
// indication that now all buffers are allocated.
if (mIsVideo) {
- addResource(kResourceGraphicMemory, getGraphicBufferSize());
+ String8 subtype;
+ addResource(
+ String8(kResourceGraphicMemory),
+ subtype,
+ getGraphicBufferSize());
}
setState(STARTED);
(new AMessage)->postReply(mReplyID);
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index ddca437..70d2c69 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -925,6 +925,11 @@
ALOGV("codec id = %s", codecID);
ALOGV("codec name = %s", track->GetCodecNameAsUTF8());
+ if (codecID == NULL) {
+ ALOGW("unknown codecID is not supported.");
+ continue;
+ }
+
size_t codecPrivateSize;
const unsigned char *codecPrivate =
track->GetCodecPrivate(codecPrivateSize);
@@ -941,10 +946,7 @@
const mkvparser::VideoTrack *vtrack =
static_cast<const mkvparser::VideoTrack *>(track);
- if (codecID == NULL) {
- ALOGW("unknown codecID is not supported.");
- continue;
- } else if (!strcmp("V_MPEG4/ISO/AVC", codecID)) {
+ if (!strcmp("V_MPEG4/ISO/AVC", codecID)) {
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
meta->setData(kKeyAVCC, 0, codecPrivate, codecPrivateSize);
} else if (!strcmp("V_MPEG4/ISO/ASP", codecID)) {
diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
index fd889f9..3860e9b 100644
--- a/media/libstagefright/tests/SurfaceMediaSource_test.cpp
+++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
@@ -19,6 +19,7 @@
#include <gtest/gtest.h>
#include <utils/String8.h>
+#include <utils/String16.h>
#include <utils/Errors.h>
#include <fcntl.h>
#include <unistd.h>
@@ -466,7 +467,7 @@
// Set up the MediaRecorder which runs in the same process as mediaserver
sp<MediaRecorder> SurfaceMediaSourceGLTest::setUpMediaRecorder(int fd, int videoSource,
int outputFormat, int videoEncoder, int width, int height, int fps) {
- sp<MediaRecorder> mr = new MediaRecorder();
+ sp<MediaRecorder> mr = new MediaRecorder(String16());
mr->setVideoSource(videoSource);
mr->setOutputFormat(outputFormat);
mr->setVideoEncoder(videoEncoder);
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index 5e2f0bf..ed5a404 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -345,12 +345,14 @@
////////////////////////////////////////////////////////////////////////////////
WifiDisplaySource::PlaybackSession::PlaybackSession(
+ const String16 &opPackageName,
const sp<ANetworkSession> &netSession,
const sp<AMessage> ¬ify,
const in_addr &interfaceAddr,
const sp<IHDCP> &hdcp,
const char *path)
- : mNetSession(netSession),
+ : mOpPackageName(opPackageName),
+ mNetSession(netSession),
mNotify(notify),
mInterfaceAddr(interfaceAddr),
mHDCP(hdcp),
@@ -1069,6 +1071,7 @@
status_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) {
sp<AudioSource> audioSource = new AudioSource(
AUDIO_SOURCE_REMOTE_SUBMIX,
+ mOpPackageName,
48000 /* sampleRate */,
2 /* channelCount */);
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h
index 4cd1a75..f6673df 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.h
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.h
@@ -22,6 +22,8 @@
#include "VideoFormats.h"
#include "WifiDisplaySource.h"
+#include <utils/String16.h>
+
namespace android {
struct ABuffer;
@@ -36,6 +38,7 @@
// display.
struct WifiDisplaySource::PlaybackSession : public AHandler {
PlaybackSession(
+ const String16 &opPackageName,
const sp<ANetworkSession> &netSession,
const sp<AMessage> ¬ify,
const struct in_addr &interfaceAddr,
@@ -96,6 +99,8 @@
kWhatPullExtractorSample,
};
+ String16 mOpPackageName;
+
sp<ANetworkSession> mNetSession;
sp<AMessage> mNotify;
in_addr mInterfaceAddr;
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index 332fe16..e26165e 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -50,10 +50,12 @@
const AString WifiDisplaySource::sUserAgent = MakeUserAgent();
WifiDisplaySource::WifiDisplaySource(
+ const String16 &opPackageName,
const sp<ANetworkSession> &netSession,
const sp<IRemoteDisplayClient> &client,
const char *path)
- : mState(INITIALIZED),
+ : mOpPackageName(opPackageName),
+ mState(INITIALIZED),
mNetSession(netSession),
mClient(client),
mSessionID(0),
@@ -1245,7 +1247,7 @@
sp<PlaybackSession> playbackSession =
new PlaybackSession(
- mNetSession, notify, mInterfaceAddr, mHDCP, mMediaPath.c_str());
+ mOpPackageName, mNetSession, notify, mInterfaceAddr, mHDCP, mMediaPath.c_str());
looper()->registerHandler(playbackSession);
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
index c417cf5..c25a675 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
@@ -25,6 +25,8 @@
#include <netinet/in.h>
+#include <utils/String16.h>
+
namespace android {
struct AReplyToken;
@@ -38,6 +40,7 @@
static const unsigned kWifiDisplayDefaultPort = 7236;
WifiDisplaySource(
+ const String16 &opPackageName,
const sp<ANetworkSession> &netSession,
const sp<IRemoteDisplayClient> &client,
const char *path = NULL);
@@ -114,6 +117,8 @@
static const AString sUserAgent;
+ String16 mOpPackageName;
+
State mState;
VideoFormats mSupportedSourceVideoFormats;
sp<ANetworkSession> mNetSession;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 5002099..48f7514 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1416,6 +1416,7 @@
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
+ const String16& opPackageName,
size_t *frameCount,
IAudioFlinger::track_flags_t *flags,
pid_t tid,
@@ -1435,7 +1436,7 @@
buffers.clear();
// check calling permissions
- if (!recordingAllowed()) {
+ if (!recordingAllowed(opPackageName)) {
ALOGE("openRecord() permission denied: recording not allowed");
lStatus = PERMISSION_DENIED;
goto Exit;
@@ -2447,6 +2448,7 @@
int32_t priority,
audio_io_handle_t io,
int sessionId,
+ const String16& opPackageName,
status_t *status,
int *id,
int *enabled)
@@ -2543,7 +2545,7 @@
// check recording permission for visualizer
if ((memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) &&
- !recordingAllowed()) {
+ !recordingAllowed(opPackageName)) {
lStatus = PERMISSION_DENIED;
goto Exit;
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index e1ddcbc..3c4517f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -120,6 +120,7 @@
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
+ const String16& opPackageName,
size_t *pFrameCount,
IAudioFlinger::track_flags_t *flags,
pid_t tid,
@@ -216,6 +217,7 @@
int32_t priority,
audio_io_handle_t io,
int sessionId,
+ const String16& opPackageName,
status_t *status /*non-NULL*/,
int *id,
int *enabled);
diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp
index 8246fef..0a718fb 100644
--- a/services/audioflinger/ServiceUtilities.cpp
+++ b/services/audioflinger/ServiceUtilities.cpp
@@ -14,38 +14,97 @@
* limitations under the License.
*/
+#include <binder/AppOpsManager.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/PermissionCache.h>
#include "ServiceUtilities.h"
+/* When performing permission checks we do not use permission cache for
+ * runtime permissions (protection level dangerous) as they may change at
+ * runtime. All other permissions (protection level normal and dangerous)
+ * can be cached as they never change. Of course all permission checked
+ * here are platform defined.
+ */
+
namespace android {
// Not valid until initialized by AudioFlinger constructor. It would have to be
// re-initialized if the process containing AudioFlinger service forks (which it doesn't).
pid_t getpid_cached;
-bool recordingAllowed() {
+bool recordingAllowed(const String16& opPackageName) {
+ // Note: We are getting the UID from the calling IPC thread state because all
+ // clients that perform recording create AudioRecord in their own processes
+ // and the system does not create AudioRecord objects on behalf of apps. This
+ // differs from playback where in some situations the system recreates AudioTrack
+ // instances associated with a client's MediaPlayer on behalf of this client.
+ // In the latter case we have to store the client UID and pass in along for
+ // security checks.
+
if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;
static const String16 sRecordAudio("android.permission.RECORD_AUDIO");
- // don't use PermissionCache; this is not a system permission
- bool ok = checkCallingPermission(sRecordAudio);
- if (!ok) ALOGE("Request requires android.permission.RECORD_AUDIO");
- return ok;
+
+ // IMPORTANT: Don't use PermissionCache - a runtime permission and may change.
+ const bool ok = checkCallingPermission(sRecordAudio);
+ if (!ok) {
+ ALOGE("Request requires android.permission.RECORD_AUDIO");
+ return false;
+ }
+
+ const uid_t uid = IPCThreadState::self()->getCallingUid();
+ String16 checkedOpPackageName = opPackageName;
+
+ // In some cases the calling code has no access to the package it runs under.
+ // For example, code using the wilhelm framework's OpenSL-ES APIs. In this
+ // case we will get the packages for the calling UID and pick the first one
+ // for attributing the app op. This will work correctly for runtime permissions
+ // as for legacy apps we will toggle the app op for all packages in the UID.
+ // The caveat is that the operation may be attributed to the wrong package and
+ // stats based on app ops may be slightly off.
+ if (checkedOpPackageName.size() <= 0) {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("permission"));
+ if (binder == 0) {
+ ALOGE("Cannot get permission service");
+ return false;
+ }
+
+ sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder);
+ Vector<String16> packages;
+
+ permCtrl->getPackagesForUid(uid, packages);
+
+ if (packages.isEmpty()) {
+ ALOGE("No packages for calling UID");
+ return false;
+ }
+ checkedOpPackageName = packages[0];
+ }
+
+ AppOpsManager appOps;
+ if (appOps.noteOp(AppOpsManager::OP_RECORD_AUDIO, uid, opPackageName)
+ != AppOpsManager::MODE_ALLOWED) {
+ ALOGE("Request denied by app op OP_RECORD_AUDIO");
+ return false;
+ }
+
+ return true;
}
bool captureAudioOutputAllowed() {
if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;
static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
- // don't use PermissionCache; this is not a system permission
- bool ok = checkCallingPermission(sCaptureAudioOutput);
+ // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
+ bool ok = PermissionCache::checkCallingPermission(sCaptureAudioOutput);
if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
return ok;
}
bool captureHotwordAllowed() {
static const String16 sCaptureHotwordAllowed("android.permission.CAPTURE_AUDIO_HOTWORD");
- bool ok = checkCallingPermission(sCaptureHotwordAllowed);
+ // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
+ bool ok = PermissionCache::checkCallingPermission(sCaptureHotwordAllowed);
if (!ok) ALOGE("android.permission.CAPTURE_AUDIO_HOTWORD");
return ok;
}
@@ -53,15 +112,16 @@
bool settingsAllowed() {
if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;
static const String16 sAudioSettings("android.permission.MODIFY_AUDIO_SETTINGS");
- // don't use PermissionCache; this is not a system permission
- bool ok = checkCallingPermission(sAudioSettings);
+ // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
+ bool ok = PermissionCache::checkCallingPermission(sAudioSettings);
if (!ok) ALOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
return ok;
}
bool modifyAudioRoutingAllowed() {
static const String16 sModifyAudioRoutingAllowed("android.permission.MODIFY_AUDIO_ROUTING");
- bool ok = checkCallingPermission(sModifyAudioRoutingAllowed);
+ // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
+ bool ok = PermissionCache::checkCallingPermission(sModifyAudioRoutingAllowed);
if (!ok) ALOGE("android.permission.MODIFY_AUDIO_ROUTING");
return ok;
}
@@ -69,7 +129,7 @@
bool dumpAllowed() {
// don't optimize for same pid, since mediaserver never dumps itself
static const String16 sDump("android.permission.DUMP");
- // OK to use PermissionCache; this is a system permission
+ // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
bool ok = PermissionCache::checkCallingPermission(sDump);
// convention is for caller to dump an error message to fd instead of logging here
//if (!ok) ALOGE("Request requires android.permission.DUMP");
diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h
index df6f6f4..fba6dce 100644
--- a/services/audioflinger/ServiceUtilities.h
+++ b/services/audioflinger/ServiceUtilities.h
@@ -20,11 +20,10 @@
extern pid_t getpid_cached;
-bool recordingAllowed();
+bool recordingAllowed(const String16& opPackageName);
bool captureAudioOutputAllowed();
bool captureHotwordAllowed();
bool settingsAllowed();
bool modifyAudioRoutingAllowed();
bool dumpAllowed();
-
}
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 58c65fa..9230750 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -133,6 +133,7 @@
audio_format_t format,
audio_channel_mask_t channelMask,
audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
input_type_t *inputType) = 0;
// indicates to the audio policy manager that the input starts being used.
virtual status_t startInput(audio_io_handle_t input,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index ba3fcaf..7de72de 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -689,7 +689,7 @@
break;
}
}
- mOutputRoutes.addRoute(session, *stream, deviceDesc);
+ mOutputRoutes.addRoute(session, *stream, SessionRoute::SOURCE_TYPE_NA, deviceDesc);
return NO_ERROR;
}
@@ -1226,6 +1226,7 @@
audio_format_t format,
audio_channel_mask_t channelMask,
audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
input_type_t *inputType)
{
ALOGV("getInputForAttr() source %d, samplingRate %d, format %d, channelMask %x,"
@@ -1247,6 +1248,16 @@
}
halInputSource = inputSource;
+ // Explicit routing?
+ sp<DeviceDescriptor> deviceDesc;
+ for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
+ if (mAvailableInputDevices[i]->getId() == selectedDeviceId) {
+ deviceDesc = mAvailableInputDevices[i];
+ break;
+ }
+ }
+ mInputRoutes.addRoute(session, SessionRoute::STREAM_TYPE_NA, inputSource, deviceDesc);
+
if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
status_t ret = mPolicyMixes.getInputMixForAttr(*attr, &policyMix);
@@ -1378,6 +1389,7 @@
addInput(*input, inputDesc);
mpClientInterface->onAudioPortListUpdate();
+
return NO_ERROR;
}
@@ -1419,7 +1431,7 @@
}
}
- if (inputDesc->mRefCount == 0) {
+ if (inputDesc->mRefCount == 0 || mInputRoutes.hasRouteChanged(session)) {
// if input maps to a dynamic policy with an activity listener, notify of state change
if ((inputDesc->mPolicyMix != NULL)
&& ((inputDesc->mPolicyMix->mFlags & MIX_FLAG_NOTIFY_ACTIVITY) != 0)) {
@@ -1427,6 +1439,9 @@
MIX_STATE_MIXING);
}
+ // Routing?
+ mInputRoutes.incRouteActivity(session);
+
if (mInputs.activeInputsCount() == 0) {
SoundTrigger::setCaptureState(true);
}
@@ -1479,6 +1494,10 @@
}
inputDesc->mRefCount--;
+
+ // Routing?
+ mInputRoutes.decRouteActivity(session);
+
if (inputDesc->mRefCount == 0) {
// if input maps to a dynamic policy with an activity listener, notify of state change
if ((inputDesc->mPolicyMix != NULL)
@@ -1521,6 +1540,10 @@
ALOGW("releaseInput() releasing unknown input %d", input);
return;
}
+
+ // Routing
+ mInputRoutes.removeRoute(session);
+
sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
ALOG_ASSERT(inputDesc != 0);
@@ -3771,7 +3794,6 @@
audio_devices_t device = getDeviceAndMixForInputSource(inputDesc->mInputSource);
- ALOGV("getNewInputDevice() selected device %x", device);
return device;
}
@@ -4291,7 +4313,15 @@
audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
{
- return mEngine->getDeviceForInputSource(inputSource);
+ for (size_t routeIndex = 0; routeIndex < mInputRoutes.size(); routeIndex++) {
+ sp<SessionRoute> route = mInputRoutes.valueAt(routeIndex);
+ if (inputSource == route->mSource && route->mDeviceDescriptor != 0
+ /*&& route->mActivityCount != 0*/) {
+ return route->mDeviceDescriptor->type();
+ }
+ }
+
+ return mEngine->getDeviceForInputSource(inputSource);
}
float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
@@ -4514,8 +4544,8 @@
// --- SessionRoute class implementation
void AudioPolicyManager::SessionRoute::log(const char* prefix) {
- ALOGI("%s[SessionRoute strm:0x%X, sess:0x%X, dev:0x%X refs:%d act:%d",
- prefix, mStreamType, mSession,
+ ALOGI("%s[SessionRoute strm:0x%X, src:%d, sess:0x%X, dev:0x%X refs:%d act:%d",
+ prefix, mStreamType, mSource, mSession,
mDeviceDescriptor != 0 ? mDeviceDescriptor->type() : AUDIO_DEVICE_NONE,
mRefCount, mActivityCount);
}
@@ -4537,28 +4567,6 @@
return false;
}
-void AudioPolicyManager::SessionRouteMap::addRoute(audio_session_t session,
- audio_stream_type_t streamType,
- sp<DeviceDescriptor> deviceDescriptor)
-{
- sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
- if (route != NULL) {
- if ((route->mDeviceDescriptor == 0 && deviceDescriptor != 0) ||
- (!route->mDeviceDescriptor->equals(deviceDescriptor))) {
- route->mChanged = true;
- }
- route->mRefCount++;
- route->mDeviceDescriptor = deviceDescriptor;
- } else {
- route = new AudioPolicyManager::SessionRoute(session, streamType, deviceDescriptor);
- route->mRefCount++;
- add(session, route);
- if (deviceDescriptor != 0) {
- route->mChanged = true;
- }
- }
-}
-
void AudioPolicyManager::SessionRouteMap::removeRoute(audio_session_t session)
{
sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
@@ -4594,6 +4602,38 @@
}
}
+void AudioPolicyManager::SessionRouteMap::addRoute(audio_session_t session,
+ audio_stream_type_t streamType,
+ audio_source_t source,
+ sp<DeviceDescriptor> descriptor)
+{
+ if (mMapType == MAPTYPE_INPUT && streamType != SessionRoute::STREAM_TYPE_NA) {
+ ALOGE("Adding Output Route to InputRouteMap");
+ return;
+ } else if (mMapType == MAPTYPE_OUTPUT && source != SessionRoute::SOURCE_TYPE_NA) {
+ ALOGE("Adding Input Route to OutputRouteMap");
+ return;
+ }
+
+ sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
+
+ if (route != 0) {
+ if ((route->mDeviceDescriptor == 0 && descriptor != 0) ||
+ (!route->mDeviceDescriptor->equals(descriptor))) {
+ route->mChanged = true;
+ }
+ route->mRefCount++;
+ route->mDeviceDescriptor = descriptor;
+ } else {
+ route = new AudioPolicyManager::SessionRoute(session, streamType, source, descriptor);
+ route->mRefCount++;
+ add(session, route);
+ if (descriptor != 0) {
+ route->mChanged = true;
+ }
+ }
+}
+
void AudioPolicyManager::defaultAudioPolicyConfig(void)
{
sp<HwModule> module;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 521f6c4..b965411 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -131,6 +131,7 @@
audio_format_t format,
audio_channel_mask_t channelMask,
audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
input_type_t *inputType);
// indicates to the audio policy manager that the input starts being used.
@@ -233,45 +234,84 @@
routing_strategy getStrategy(audio_stream_type_t stream) const;
protected:
- class SessionRoute : public RefBase
- {
+ class SessionRoute : public RefBase {
public:
- friend class SessionRouteMap;
+ // For Input (Source) routes, use STREAM_TYPE_NA ("NA" = "not applicable)for the
+ // streamType argument
+ static const audio_stream_type_t STREAM_TYPE_NA = AUDIO_STREAM_DEFAULT;
+
+ // For Output (Sink) routes, use SOURCE_TYPE_NA ("NA" = "not applicable") for the
+ // source argument
+
+ static const audio_source_t SOURCE_TYPE_NA = AUDIO_SOURCE_DEFAULT;
+
SessionRoute(audio_session_t session,
audio_stream_type_t streamType,
+ audio_source_t source,
sp<DeviceDescriptor> deviceDescriptor)
- : mSession(session),
- mStreamType(streamType),
- mDeviceDescriptor(deviceDescriptor),
- mRefCount(0),
- mActivityCount(0),
- mChanged(false) {}
-
- void log(const char* prefix);
+ : mSession(session),
+ mDeviceDescriptor(deviceDescriptor),
+ mRefCount(0),
+ mActivityCount(0),
+ mChanged(false),
+ mStreamType(streamType),
+ mSource(source) {}
audio_session_t mSession;
- audio_stream_type_t mStreamType;
sp<DeviceDescriptor> mDeviceDescriptor;
+ void log(const char* prefix);
+
// "reference" counting
int mRefCount; // +/- on references
int mActivityCount; // +/- on start/stop
bool mChanged;
+
+ // for outputs
+ const audio_stream_type_t mStreamType;
+
+ // for inputs
+ const audio_source_t mSource;
};
- class SessionRouteMap: public KeyedVector<audio_session_t, sp<SessionRoute>>
- {
- public:
+ class SessionRouteMap: public KeyedVector<audio_session_t, sp<SessionRoute>> {
+ public:
+ // These constants identify the SessionRoutMap as holding EITHER input routes,
+ // or output routes. An error will occur if an attempt is made to add a SessionRoute
+ // object with mStreamType == STREAM_TYPE_NA (i.e. an input SessionRoute) to a
+ // SessionRoutMap that is marked for output (i.e. mMapType == SESSION_ROUTE_MAP_OUTPUT)
+ // and similarly for output SessionRoutes and Input SessionRouteMaps.
+ typedef enum {
+ MAPTYPE_INPUT = 0,
+ MAPTYPE_OUTPUT = 1
+ } session_route_map_type_t;
+
+ SessionRouteMap(session_route_map_type_t mapType) :
+ mMapType(mapType) {
+ }
+
bool hasRoute(audio_session_t session);
- void addRoute(audio_session_t session, audio_stream_type_t streamType,
- sp<DeviceDescriptor> deviceDescriptor);
void removeRoute(audio_session_t session);
int incRouteActivity(audio_session_t session);
int decRouteActivity(audio_session_t session);
bool hasRouteChanged(audio_session_t session); // also clears the changed flag
void log(const char* caption);
+
+ // Specify an Output(Sink) route by passing SessionRoute::SOURCE_TYPE_NA in the
+ // source argument.
+ // Specify an Input(Source) rout by passing SessionRoute::AUDIO_STREAM_DEFAULT
+ // in the streamType argument.
+ void addRoute(audio_session_t session,
+ audio_stream_type_t streamType,
+ audio_source_t source,
+ sp<DeviceDescriptor> deviceDescriptor);
+
+ private:
+ // Used to mark a SessionRoute as for either inputs (mMapType == kSessionRouteMap_Input)
+ // or outputs (mMapType == kSessionRouteMap_Output)
+ const session_route_map_type_t mMapType;
};
// From AudioPolicyManagerObserver
@@ -535,8 +575,8 @@
DeviceVector mAvailableOutputDevices; // all available output devices
DeviceVector mAvailableInputDevices; // all available input devices
- SessionRouteMap mOutputRoutes;
- SessionRouteMap mInputRoutes;
+ SessionRouteMap mOutputRoutes = SessionRouteMap(SessionRouteMap::MAPTYPE_OUTPUT);
+ SessionRouteMap mInputRoutes = SessionRouteMap(SessionRouteMap::MAPTYPE_INPUT);
StreamDescriptorCollection mStreams; // stream descriptors for volume control
bool mLimitRingtoneVolume; // limit ringtone volume to music volume if headset connected
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index e6ace20..282ddeb 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -109,8 +109,8 @@
Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
for (size_t i = 0; i < effects.size(); i++) {
EffectDesc *effect = effects[i];
- sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0,
- audioSession, input);
+ sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, -1, 0,
+ 0, audioSession, input);
status_t status = fx->initCheck();
if (status != NO_ERROR && status != ALREADY_EXISTS) {
ALOGW("addInputEffects(): failed to create Fx %s on source %d",
@@ -254,7 +254,7 @@
Vector <EffectDesc *> effects = mOutputStreams.valueAt(index)->mEffects;
for (size_t i = 0; i < effects.size(); i++) {
EffectDesc *effect = effects[i];
- sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, 0, 0, 0,
+ sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, 0, 0, 0,
audioSession, output);
status_t status = fx->initCheck();
if (status != NO_ERROR && status != ALREADY_EXISTS) {
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index e764eda..5ceb1cf 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -150,7 +150,7 @@
audio_format_t format,
audio_channel_mask_t channelMask,
audio_output_flags_t flags,
- int mSelectedDeviceId,
+ audio_port_handle_t selectedDeviceId,
const audio_offload_info_t *offloadInfo)
{
if (mAudioPolicyManager == NULL) {
@@ -159,7 +159,7 @@
ALOGV("getOutput()");
Mutex::Autolock _l(mLock);
return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, samplingRate,
- format, channelMask, flags, mSelectedDeviceId, offloadInfo);
+ format, channelMask, flags, selectedDeviceId, offloadInfo);
}
status_t AudioPolicyService::startOutput(audio_io_handle_t output,
@@ -251,7 +251,8 @@
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_input_flags_t flags)
+ audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
@@ -273,7 +274,7 @@
// the audio_in_acoustics_t parameter is ignored by get_input()
status = mAudioPolicyManager->getInputForAttr(attr, input, session,
samplingRate, format, channelMask,
- flags, &inputType);
+ flags, selectedDeviceId, &inputType);
audioPolicyEffects = mAudioPolicyEffects;
if (status == NO_ERROR) {
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
index f783437..433e712 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
@@ -237,7 +237,8 @@
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_input_flags_t flags __unused)
+ audio_input_flags_t flags __unused,
+ audio_port_handle_t selectedDeviceId __unused)
{
if (mpAudioPolicy == NULL) {
return NO_INIT;
@@ -568,7 +569,7 @@
audio_format_t format,
audio_channel_mask_t channelMask,
audio_output_flags_t flags,
- int selectedDeviceId __unused,
+ audio_port_handle_t selectedDeviceId __unused,
const audio_offload_info_t *offloadInfo)
{
if (attr != NULL) {
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 4e25d33..07ea96b 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -84,7 +84,7 @@
audio_format_t format = AUDIO_FORMAT_DEFAULT,
audio_channel_mask_t channelMask = 0,
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
- int selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
const audio_offload_info_t *offloadInfo = NULL);
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
@@ -101,7 +101,8 @@
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_input_flags_t flags);
+ audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
virtual status_t startInput(audio_io_handle_t input,
audio_session_t session);
virtual status_t stopInput(audio_io_handle_t input,
diff --git a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp
index 5c8f750..88c5811 100644
--- a/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/CallbackProcessor.cpp
@@ -395,7 +395,7 @@
heapIdx = mCallbackHeapHead;
- mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount;
+ mCallbackHeapHead = (mCallbackHeapHead + 1) % kCallbackHeapCount;
mCallbackHeapFree--;
// TODO: Get rid of this copy by passing the gralloc queue all the way