Merge "AudioSystem callback for dynamic policy mix activity" 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/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 3f62ed7..b90da1b 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -34,6 +34,7 @@
#include "IDrmManagerService.h"
#define INVALID_BUFFER_LENGTH -1
+#define MAX_BINDER_TRANSACTION_SIZE ((1*1024*1024)-(4096*2))
using namespace android;
@@ -933,7 +934,12 @@
//Filling DRM info
const int infoType = data.readInt32();
- const int bufferSize = data.readInt32();
+ const uint32_t bufferSize = data.readInt32();
+
+ if (bufferSize > data.dataAvail()) {
+ return BAD_VALUE;
+ }
+
char* buffer = NULL;
if (0 < bufferSize) {
buffer = (char *)data.readInplace(bufferSize);
@@ -986,6 +992,9 @@
const int size = data.readInt32();
for (int index = 0; index < size; ++index) {
+ if (!data.dataAvail()) {
+ break;
+ }
const String8 key(data.readString8());
if (key == String8("FileDescriptorKey")) {
char buffer[16];
@@ -1035,7 +1044,12 @@
const int uniqueId = data.readInt32();
//Filling DRM Rights
- const int bufferSize = data.readInt32();
+ const uint32_t bufferSize = data.readInt32();
+ if (bufferSize > data.dataAvail()) {
+ reply->writeInt32(BAD_VALUE);
+ return DRM_NO_ERROR;
+ }
+
const DrmBuffer drmBuffer((char *)data.readInplace(bufferSize), bufferSize);
const String8 mimeType(data.readString8());
@@ -1206,10 +1220,13 @@
const int convertId = data.readInt32();
//Filling input data
- const int bufferSize = data.readInt32();
+ const uint32_t bufferSize = data.readInt32();
+ if (bufferSize > data.dataAvail()) {
+ return BAD_VALUE;
+ }
DrmBuffer* inputData = new DrmBuffer((char *)data.readInplace(bufferSize), bufferSize);
- DrmConvertedStatus* drmConvertedStatus = convertData(uniqueId, convertId, inputData);
+ DrmConvertedStatus* drmConvertedStatus = convertData(uniqueId, convertId, inputData);
if (NULL != drmConvertedStatus) {
//Filling Drm Converted Ststus
@@ -1393,7 +1410,12 @@
const int decryptUnitId = data.readInt32();
//Filling Header info
- const int bufferSize = data.readInt32();
+ const uint32_t bufferSize = data.readInt32();
+ if (bufferSize > data.dataAvail()) {
+ reply->writeInt32(BAD_VALUE);
+ clearDecryptHandle(&handle);
+ return DRM_NO_ERROR;
+ }
DrmBuffer* headerInfo = NULL;
headerInfo = new DrmBuffer((char *)data.readInplace(bufferSize), bufferSize);
@@ -1417,9 +1439,17 @@
readDecryptHandleFromParcelData(&handle, data);
const int decryptUnitId = data.readInt32();
- const int decBufferSize = data.readInt32();
+ const uint32_t decBufferSize = data.readInt32();
+ const uint32_t encBufferSize = data.readInt32();
- const int encBufferSize = data.readInt32();
+ if (encBufferSize > data.dataAvail() ||
+ decBufferSize > MAX_BINDER_TRANSACTION_SIZE) {
+ reply->writeInt32(BAD_VALUE);
+ reply->writeInt32(0);
+ clearDecryptHandle(&handle);
+ return DRM_NO_ERROR;
+ }
+
DrmBuffer* encBuffer
= new DrmBuffer((char *)data.readInplace(encBufferSize), encBufferSize);
@@ -1429,8 +1459,10 @@
DrmBuffer* IV = NULL;
if (0 != data.dataAvail()) {
- const int ivBufferlength = data.readInt32();
- IV = new DrmBuffer((char *)data.readInplace(ivBufferlength), ivBufferlength);
+ const uint32_t ivBufferlength = data.readInt32();
+ if (ivBufferlength <= data.dataAvail()) {
+ IV = new DrmBuffer((char *)data.readInplace(ivBufferlength), ivBufferlength);
+ }
}
const status_t status
@@ -1477,7 +1509,11 @@
DecryptHandle handle;
readDecryptHandleFromParcelData(&handle, data);
- const int numBytes = data.readInt32();
+ const uint32_t numBytes = data.readInt32();
+ if (numBytes > MAX_BINDER_TRANSACTION_SIZE) {
+ reply->writeInt32(BAD_VALUE);
+ return DRM_NO_ERROR;
+ }
char* buffer = new char[numBytes];
const off64_t offset = data.readInt64();
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 a3af1b2..debfd35 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -250,7 +250,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/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/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/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 97fb841..928856d 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -707,11 +707,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 79944ee..f3a8902 100644
--- a/media/libmedia/IHDCP.cpp
+++ b/media/libmedia/IHDCP.cpp
@@ -284,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);
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/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/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index c7df5a0..4fcee90 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -806,6 +806,11 @@
return err;
mNumUndequeuedBuffers = minUndequeuedBuffers;
+ if (!mStoreMetaDataInOutputBuffers) {
+ static_cast<Surface*>(mNativeWindow.get())
+ ->getIGraphicBufferProducer()->allowAllocation(true);
+ }
+
ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
"output port",
mComponentName.c_str(), bufferCount, bufferSize);
@@ -864,6 +869,11 @@
}
}
+ if (!mStoreMetaDataInOutputBuffers) {
+ static_cast<Surface*>(mNativeWindow.get())
+ ->getIGraphicBufferProducer()->allowAllocation(false);
+ }
+
return err;
}
@@ -4909,7 +4919,10 @@
CHECK(mCodec->mNode == 0);
OMXClient client;
- CHECK_EQ(client.connect(), (status_t)OK);
+ if (client.connect() != OK) {
+ mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
+ return false;
+ }
sp<IOMX> omx = client.interface();
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/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 55e3c19..2e54e8c 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -282,6 +282,41 @@
mFirstFramePos = pos;
mFixedHeader = header;
+ mMeta = new MetaData;
+ sp<XINGSeeker> seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos);
+
+ if (seeker == NULL) {
+ mSeeker = VBRISeeker::CreateFromSource(mDataSource, post_id3_pos);
+ } else {
+ mSeeker = seeker;
+ int encd = seeker->getEncoderDelay();
+ int encp = seeker->getEncoderPadding();
+ if (encd != 0 || encp != 0) {
+ mMeta->setInt32(kKeyEncoderDelay, encd);
+ mMeta->setInt32(kKeyEncoderPadding, encp);
+ }
+ }
+
+ if (mSeeker != NULL) {
+ // While it is safe to send the XING/VBRI frame to the decoder, this will
+ // result in an extra 1152 samples being output. In addition, the bitrate
+ // of the Xing header might not match the rest of the file, which could
+ // lead to problems when seeking. The real first frame to decode is after
+ // the XING/VBRI frame, so skip there.
+ size_t frame_size;
+ int sample_rate;
+ int num_channels;
+ int bitrate;
+ GetMPEGAudioFrameSize(
+ header, &frame_size, &sample_rate, &num_channels, &bitrate);
+ pos += frame_size;
+ if (!Resync(mDataSource, 0, &pos, &post_id3_pos, &header)) {
+ // mInitCheck will remain NO_INIT
+ return;
+ }
+ mFirstFramePos = pos;
+ mFixedHeader = header;
+ }
size_t frame_size;
int sample_rate;
@@ -292,8 +327,6 @@
unsigned layer = 4 - ((header >> 17) & 3);
- mMeta = new MetaData;
-
switch (layer) {
case 1:
mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I);
@@ -312,27 +345,6 @@
mMeta->setInt32(kKeyBitRate, bitrate * 1000);
mMeta->setInt32(kKeyChannelCount, num_channels);
- sp<XINGSeeker> seeker = XINGSeeker::CreateFromSource(mDataSource, mFirstFramePos);
-
- if (seeker == NULL) {
- mSeeker = VBRISeeker::CreateFromSource(mDataSource, post_id3_pos);
- } else {
- mSeeker = seeker;
- int encd = seeker->getEncoderDelay();
- int encp = seeker->getEncoderPadding();
- if (encd != 0 || encp != 0) {
- mMeta->setInt32(kKeyEncoderDelay, encd);
- mMeta->setInt32(kKeyEncoderPadding, encp);
- }
- }
-
- if (mSeeker != NULL) {
- // While it is safe to send the XING/VBRI frame to the decoder, this will
- // result in an extra 1152 samples being output. The real first frame to
- // decode is after the XING/VBRI frame, so skip there.
- mFirstFramePos += frame_size;
- }
-
int64_t durationUs;
if (mSeeker == NULL || !mSeeker->getDuration(&durationUs)) {
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index aa0d2e6..8a2dc35 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -392,6 +392,10 @@
tmp.erase(tmp.size() - 7, 7);
}
const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
+ if (mcl == NULL) {
+ mCodec = NULL; // remove the codec.
+ return NO_INIT; // if called from Java should raise IOException
+ }
ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
if (codecIdx >= 0) {
const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 26798ae..f12a913 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -80,6 +80,10 @@
infos.push_back(gCodecList->getCodecInfo(i));
}
}
+ } else {
+ // failure to initialize may be temporary. retry on next call.
+ delete gCodecList;
+ gCodecList = NULL;
}
}
}
@@ -168,7 +172,7 @@
OMXClient client;
mInitCheck = client.connect();
if (mInitCheck != OK) {
- return;
+ return; // this may fail if IMediaPlayerService is not available.
}
mOMX = client.interface();
parseXMLFile(codecs_xml);
@@ -882,14 +886,16 @@
return -EINVAL;
}
- // size, blocks, bitrate, frame-rate, blocks-per-second, aspect-ratio: range
+ // size, blocks, bitrate, frame-rate, blocks-per-second, aspect-ratio,
+ // measured-frame-rate, measured-blocks-per-second: range
// quality: range + default + [scale]
// complexity: range + default
bool found;
if (name == "aspect-ratio" || name == "bitrate" || name == "block-count"
|| name == "blocks-per-second" || name == "complexity"
- || name == "frame-rate" || name == "quality" || name == "size") {
+ || name == "frame-rate" || name == "quality" || name == "size"
+ || name == "measured-blocks-per-second" || name == "measured-frame-rate") {
AString min, max;
if (msg->findString("min", &min) && msg->findString("max", &max)) {
min.append("-");
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index 230c1f7..06a598f 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -400,10 +400,16 @@
sp<IBinder> binder = sm->getService(String16("media.player"));
sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
- CHECK(service.get() != NULL);
+ if (service.get() == NULL) {
+ ALOGE("Cannot obtain IMediaPlayerService");
+ return NO_INIT;
+ }
mOMX = service->getOMX();
- CHECK(mOMX.get() != NULL);
+ if (mOMX.get() == NULL) {
+ ALOGE("Cannot obtain IOMX");
+ return NO_INIT;
+ }
if (!mOMX->livesLocally(0 /* node */, getpid())) {
ALOGI("Using client-side OMX mux.");
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 0d8e64a..7b089b0 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -181,6 +181,11 @@
msg->setInt32("rotation-degrees", rotationDegrees);
}
+ int32_t fps;
+ if (meta->findInt32(kKeyFrameRate, &fps)) {
+ msg->setInt32("frame-rate", fps);
+ }
+
uint32_t type;
const void *data;
size_t size;
@@ -588,6 +593,11 @@
meta->setInt32(kKeyMaxHeight, maxHeight);
}
+ int32_t fps;
+ if (msg->findInt32("frame-rate", &fps)) {
+ meta->setInt32(kKeyFrameRate, fps);
+ }
+
// reassemble the csd data into its original form
sp<ABuffer> csd0;
if (msg->findBuffer("csd-0", &csd0)) {
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/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 5411821..0d071b2 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -302,9 +302,13 @@
// The two checks below shouldn't happen,
// we already checked above the stream count matches
ssize_t index = newType2PIDs.indexOfKey(temp[i]->type());
- CHECK(index >= 0);
+ if (index < 0) {
+ return false;
+ }
Vector<int32_t> &newPIDs = newType2PIDs.editValueAt(index);
- CHECK(newPIDs.size() > 0);
+ if (newPIDs.isEmpty()) {
+ return false;
+ }
// get the next PID for temp[i]->type() in the new PID map
Vector<int32_t>::iterator it = newPIDs.begin();
@@ -335,13 +339,11 @@
return ERROR_MALFORMED;
}
- CHECK_EQ(br->getBits(1), 0u);
+ br->skipBits(1); // '0'
MY_LOGV(" reserved = %u", br->getBits(2));
unsigned section_length = br->getBits(12);
ALOGV(" section_length = %u", section_length);
- CHECK_EQ(section_length & 0xc00, 0u);
- CHECK_LE(section_length, 1021u);
MY_LOGV(" program_number = %u", br->getBits(16));
MY_LOGV(" reserved = %u", br->getBits(2));
@@ -358,7 +360,6 @@
unsigned program_info_length = br->getBits(12);
ALOGV(" program_info_length = %u", program_info_length);
- CHECK_EQ(program_info_length & 0xc00, 0u);
br->skipBits(program_info_length * 8); // skip descriptors
@@ -369,8 +370,7 @@
// final CRC.
size_t infoBytesRemaining = section_length - 9 - program_info_length - 4;
- while (infoBytesRemaining > 0) {
- CHECK_GE(infoBytesRemaining, 5u);
+ while (infoBytesRemaining >= 5) {
unsigned streamType = br->getBits(8);
ALOGV(" stream_type = 0x%02x", streamType);
@@ -384,9 +384,6 @@
unsigned ES_info_length = br->getBits(12);
ALOGV(" ES_info_length = %u", ES_info_length);
- CHECK_EQ(ES_info_length & 0xc00, 0u);
-
- CHECK_GE(infoBytesRemaining - 5, ES_info_length);
#if 0
br->skipBits(ES_info_length * 8); // skip descriptors
@@ -398,13 +395,13 @@
unsigned descLength = br->getBits(8);
ALOGV(" len = %u", descLength);
- CHECK_GE(info_bytes_remaining, 2 + descLength);
-
+ if (info_bytes_remaining < descLength) {
+ return ERROR_MALFORMED;
+ }
br->skipBits(descLength * 8);
info_bytes_remaining -= descLength + 2;
}
- CHECK_EQ(info_bytes_remaining, 0u);
#endif
StreamInfo info;
@@ -415,7 +412,9 @@
infoBytesRemaining -= 5 + ES_info_length;
}
- CHECK_EQ(infoBytesRemaining, 0u);
+ if (infoBytesRemaining != 0) {
+ ALOGW("Section data remains unconsumed");
+ }
MY_LOGV(" CRC = 0x%08x", br->getBits(32));
bool PIDsChanged = false;
@@ -680,7 +679,10 @@
}
size_t payloadSizeBits = br->numBitsLeft();
- CHECK_EQ(payloadSizeBits % 8, 0u);
+ if (payloadSizeBits % 8 != 0u) {
+ ALOGE("Wrong value");
+ return BAD_VALUE;
+ }
size_t neededSize = mBuffer->size() + payloadSizeBits / 8;
if (mBuffer->capacity() < neededSize) {
@@ -797,8 +799,6 @@
return ERROR_MALFORMED;
}
- CHECK_EQ(packet_startcode_prefix, 0x000001u);
-
unsigned stream_id = br->getBits(8);
ALOGV("stream_id = 0x%02x", stream_id);
@@ -813,7 +813,9 @@
&& stream_id != 0xff // program_stream_directory
&& stream_id != 0xf2 // DSMCC
&& stream_id != 0xf8) { // H.222.1 type E
- CHECK_EQ(br->getBits(2), 2u);
+ if (br->getBits(2) != 2u) {
+ return ERROR_MALFORMED;
+ }
MY_LOGV("PES_scrambling_control = %u", br->getBits(2));
MY_LOGV("PES_priority = %u", br->getBits(1));
@@ -847,34 +849,51 @@
uint64_t PTS = 0, DTS = 0;
if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
- CHECK_GE(optional_bytes_remaining, 5u);
+ if (optional_bytes_remaining < 5u) {
+ return ERROR_MALFORMED;
+ }
if (br->getBits(4) != PTS_DTS_flags) {
- ALOGE("PES data Error!");
return ERROR_MALFORMED;
}
PTS = ((uint64_t)br->getBits(3)) << 30;
- CHECK_EQ(br->getBits(1), 1u);
+ if (br->getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
PTS |= ((uint64_t)br->getBits(15)) << 15;
- CHECK_EQ(br->getBits(1), 1u);
+ if (br->getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
PTS |= br->getBits(15);
- CHECK_EQ(br->getBits(1), 1u);
+ if (br->getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
ALOGV("PTS = 0x%016" PRIx64 " (%.2f)", PTS, PTS / 90000.0);
optional_bytes_remaining -= 5;
if (PTS_DTS_flags == 3) {
- CHECK_GE(optional_bytes_remaining, 5u);
+ if (optional_bytes_remaining < 5u) {
+ return ERROR_MALFORMED;
+ }
- CHECK_EQ(br->getBits(4), 1u);
+ if (br->getBits(4) != 1u) {
+ return ERROR_MALFORMED;
+ }
DTS = ((uint64_t)br->getBits(3)) << 30;
- CHECK_EQ(br->getBits(1), 1u);
+ if (br->getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
DTS |= ((uint64_t)br->getBits(15)) << 15;
- CHECK_EQ(br->getBits(1), 1u);
+ if (br->getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
DTS |= br->getBits(15);
- CHECK_EQ(br->getBits(1), 1u);
+ if (br->getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
ALOGV("DTS = %" PRIu64, DTS);
@@ -883,31 +902,47 @@
}
if (ESCR_flag) {
- CHECK_GE(optional_bytes_remaining, 6u);
+ if (optional_bytes_remaining < 6u) {
+ return ERROR_MALFORMED;
+ }
br->getBits(2);
uint64_t ESCR = ((uint64_t)br->getBits(3)) << 30;
- CHECK_EQ(br->getBits(1), 1u);
+ if (br->getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
ESCR |= ((uint64_t)br->getBits(15)) << 15;
- CHECK_EQ(br->getBits(1), 1u);
+ if (br->getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
ESCR |= br->getBits(15);
- CHECK_EQ(br->getBits(1), 1u);
+ if (br->getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
ALOGV("ESCR = %" PRIu64, ESCR);
MY_LOGV("ESCR_extension = %u", br->getBits(9));
- CHECK_EQ(br->getBits(1), 1u);
+ if (br->getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
optional_bytes_remaining -= 6;
}
if (ES_rate_flag) {
- CHECK_GE(optional_bytes_remaining, 3u);
+ if (optional_bytes_remaining < 3u) {
+ return ERROR_MALFORMED;
+ }
- CHECK_EQ(br->getBits(1), 1u);
+ if (br->getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
MY_LOGV("ES_rate = %u", br->getBits(22));
- CHECK_EQ(br->getBits(1), 1u);
+ if (br->getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
optional_bytes_remaining -= 3;
}
@@ -917,7 +952,9 @@
// ES data follows.
if (PES_packet_length != 0) {
- CHECK_GE(PES_packet_length, PES_header_data_length + 3);
+ if (PES_packet_length < PES_header_data_length + 3) {
+ return ERROR_MALFORMED;
+ }
unsigned dataLength =
PES_packet_length - 3 - PES_header_data_length;
@@ -930,7 +967,9 @@
return ERROR_MALFORMED;
}
- CHECK_GE(br->numBitsLeft(), dataLength * 8);
+ if (br->numBitsLeft() < dataLength * 8) {
+ return ERROR_MALFORMED;
+ }
onPayloadData(
PTS_DTS_flags, PTS, DTS, br->data(), dataLength);
@@ -942,15 +981,21 @@
br->data(), br->numBitsLeft() / 8);
size_t payloadSizeBits = br->numBitsLeft();
- CHECK_EQ(payloadSizeBits % 8, 0u);
+ if (payloadSizeBits % 8 != 0u) {
+ return ERROR_MALFORMED;
+ }
ALOGV("There's %zu bytes of payload.", payloadSizeBits / 8);
}
} else if (stream_id == 0xbe) { // padding_stream
- CHECK_NE(PES_packet_length, 0u);
+ if (PES_packet_length == 0u) {
+ return ERROR_MALFORMED;
+ }
br->skipBits(PES_packet_length * 8);
} else {
- CHECK_NE(PES_packet_length, 0u);
+ if (PES_packet_length == 0u) {
+ return ERROR_MALFORMED;
+ }
br->skipBits(PES_packet_length * 8);
}
@@ -1082,7 +1127,10 @@
}
status_t ATSParser::feedTSPacket(const void *data, size_t size) {
- CHECK_EQ(size, kTSPacketSize);
+ if (size != kTSPacketSize) {
+ ALOGE("Wrong TS packet size");
+ return BAD_VALUE;
+ }
ABitReader br((const uint8_t *)data, kTSPacketSize);
return parseTS(&br);
@@ -1108,14 +1156,23 @@
}
} else if (type == DISCONTINUITY_ABSOLUTE_TIME) {
int64_t timeUs;
- CHECK(extra->findInt64("timeUs", &timeUs));
+ if (!extra->findInt64("timeUs", &timeUs)) {
+ ALOGE("timeUs not found");
+ return;
+ }
- CHECK(mPrograms.empty());
+ if (!mPrograms.empty()) {
+ ALOGE("mPrograms is not empty");
+ return;
+ }
mAbsoluteTimeAnchorUs = timeUs;
return;
} else if (type == DISCONTINUITY_TIME_OFFSET) {
int64_t offset;
- CHECK(extra->findInt64("offset", &offset));
+ if (!extra->findInt64("offset", &offset)) {
+ ALOGE("offset not found");
+ return;
+ }
mTimeOffsetValid = true;
mTimeOffsetUs = offset;
@@ -1128,7 +1185,10 @@
}
void ATSParser::signalEOS(status_t finalResult) {
- CHECK_NE(finalResult, (status_t)OK);
+ if (finalResult == (status_t) OK) {
+ ALOGE("finalResult not OK");
+ return;
+ }
for (size_t i = 0; i < mPrograms.size(); ++i) {
mPrograms.editItemAt(i)->signalEOS(finalResult);
@@ -1144,14 +1204,12 @@
}
unsigned section_syntax_indictor = br->getBits(1);
ALOGV(" section_syntax_indictor = %u", section_syntax_indictor);
- CHECK_EQ(section_syntax_indictor, 1u);
- CHECK_EQ(br->getBits(1), 0u);
+ br->skipBits(1); // '0'
MY_LOGV(" reserved = %u", br->getBits(2));
unsigned section_length = br->getBits(12);
ALOGV(" section_length = %u", section_length);
- CHECK_EQ(section_length & 0xc00, 0u);
MY_LOGV(" transport_stream_id = %u", br->getBits(16));
MY_LOGV(" reserved = %u", br->getBits(2));
@@ -1161,7 +1219,6 @@
MY_LOGV(" last_section_number = %u", br->getBits(8));
size_t numProgramBytes = (section_length - 5 /* header */ - 4 /* crc */);
- CHECK_EQ((numProgramBytes % 4), 0u);
for (size_t i = 0; i < numProgramBytes / 4; ++i) {
unsigned program_number = br->getBits(16);
@@ -1221,7 +1278,9 @@
br->skipBits(skip * 8);
}
- CHECK((br->numBitsLeft() % 8) == 0);
+ if (br->numBitsLeft() % 8 != 0) {
+ return ERROR_MALFORMED;
+ }
status_t err = section->append(br->data(), br->numBitsLeft() / 8);
if (err != OK) {
@@ -1291,7 +1350,7 @@
return OK;
}
-void ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) {
+status_t ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) {
unsigned adaptation_field_length = br->getBits(8);
if (adaptation_field_length > 0) {
@@ -1307,6 +1366,9 @@
size_t numBitsRead = 4;
if (PCR_flag) {
+ if (adaptation_field_length * 8 < 52) {
+ return ERROR_MALFORMED;
+ }
br->skipBits(4);
uint64_t PCR_base = br->getBits(32);
PCR_base = (PCR_base << 1) | br->getBits(1);
@@ -1337,10 +1399,9 @@
numBitsRead += 52;
}
- CHECK_GE(adaptation_field_length * 8, numBitsRead);
-
br->skipBits(adaptation_field_length * 8 - numBitsRead);
}
+ return OK;
}
status_t ATSParser::parseTS(ABitReader *br) {
@@ -1375,15 +1436,16 @@
// ALOGI("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);
- if (adaptation_field_control == 2 || adaptation_field_control == 3) {
- parseAdaptationField(br, PID);
- }
-
status_t err = OK;
- if (adaptation_field_control == 1 || adaptation_field_control == 3) {
- err = parsePID(
- br, PID, continuity_counter, payload_unit_start_indicator);
+ if (adaptation_field_control == 2 || adaptation_field_control == 3) {
+ err = parseAdaptationField(br, PID);
+ }
+ if (err == OK) {
+ if (adaptation_field_control == 1 || adaptation_field_control == 3) {
+ err = parsePID(
+ br, PID, continuity_counter, payload_unit_start_indicator);
+ }
}
++mNumTSPacketsParsed;
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 87ab1a0..4def333 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -133,7 +133,7 @@
unsigned continuity_counter,
unsigned payload_unit_start_indicator);
- void parseAdaptationField(ABitReader *br, unsigned PID);
+ status_t parseAdaptationField(ABitReader *br, unsigned PID);
status_t parseTS(ABitReader *br);
void updatePCR(unsigned PID, uint64_t PCR, size_t byteOffsetFromStart);
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index f28a1fd..7b5b46a 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -421,8 +421,8 @@
}
default:
- TRESPASS();
- break;
+ ALOGE("Unknown mode: %d", mMode);
+ return ERROR_MALFORMED;
}
}
@@ -503,7 +503,10 @@
case METADATA:
return dequeueAccessUnitMetadata();
default:
- CHECK_EQ((unsigned)mMode, (unsigned)MPEG_AUDIO);
+ if (mMode != MPEG_AUDIO) {
+ ALOGE("Unknown mode");
+ return NULL;
+ }
return dequeueAccessUnitMPEGAudio();
}
}
@@ -540,7 +543,10 @@
memcpy(accessUnit->data(), mBuffer->data(), syncStartPos + payloadSize);
int64_t timeUs = fetchTimestamp(syncStartPos + payloadSize);
- CHECK_GE(timeUs, 0ll);
+ if (timeUs < 0ll) {
+ ALOGE("negative timeUs");
+ return NULL;
+ }
accessUnit->meta()->setInt64("timeUs", timeUs);
accessUnit->meta()->setInt32("isSync", 1);
@@ -560,15 +566,24 @@
}
ABitReader bits(mBuffer->data(), 4);
- CHECK_EQ(bits.getBits(8), 0xa0);
+ if (bits.getBits(8) != 0xa0) {
+ ALOGE("Unexpected bit values");
+ return NULL;
+ }
unsigned numAUs = bits.getBits(8);
bits.skipBits(8);
unsigned quantization_word_length __unused = bits.getBits(2);
unsigned audio_sampling_frequency = bits.getBits(3);
unsigned num_channels = bits.getBits(3);
- CHECK_EQ(audio_sampling_frequency, 2); // 48kHz
- CHECK_EQ(num_channels, 1u); // stereo!
+ if (audio_sampling_frequency != 2) {
+ ALOGE("Wrong sampling freq");
+ return NULL;
+ }
+ if (num_channels != 1u) {
+ ALOGE("Wrong channel #");
+ return NULL;
+ }
if (mFormat == NULL) {
mFormat = new MetaData;
@@ -590,7 +605,10 @@
memcpy(accessUnit->data(), mBuffer->data() + 4, payloadSize);
int64_t timeUs = fetchTimestamp(payloadSize + 4);
- CHECK_GE(timeUs, 0ll);
+ if (timeUs < 0ll) {
+ ALOGE("Negative timeUs");
+ return NULL;
+ }
accessUnit->meta()->setInt64("timeUs", timeUs);
accessUnit->meta()->setInt32("isSync", 1);
@@ -614,14 +632,19 @@
return NULL;
}
- CHECK(!mRangeInfos.empty());
+ if (mRangeInfos.empty()) {
+ return NULL;
+ }
const RangeInfo &info = *mRangeInfos.begin();
if (mBuffer->size() < info.mLength) {
return NULL;
}
- CHECK_GE(info.mTimestampUs, 0ll);
+ if (info.mTimestampUs < 0ll) {
+ ALOGE("Negative info.mTimestampUs");
+ return NULL;
+ }
// The idea here is consume all AAC frames starting at offsets before
// info.mLength so we can assign a meaningful timestamp without
@@ -638,17 +661,26 @@
// adts_fixed_header
- CHECK_EQ(bits.getBits(12), 0xfffu);
+ if (bits.getBits(12) != 0xfffu) {
+ ALOGE("Wrong atds_fixed_header");
+ return NULL;
+ }
bits.skipBits(3); // ID, layer
bool protection_absent __unused = bits.getBits(1) != 0;
if (mFormat == NULL) {
unsigned profile = bits.getBits(2);
- CHECK_NE(profile, 3u);
+ if (profile == 3u) {
+ ALOGE("profile should not be 3");
+ return NULL;
+ }
unsigned sampling_freq_index = bits.getBits(4);
bits.getBits(1); // private_bit
unsigned channel_configuration = bits.getBits(3);
- CHECK_NE(channel_configuration, 0u);
+ if (channel_configuration == 0u) {
+ ALOGE("channel_config should not be 0");
+ return NULL;
+ }
bits.skipBits(2); // original_copy, home
mFormat = MakeAACCodecSpecificData(
@@ -658,8 +690,14 @@
int32_t sampleRate;
int32_t numChannels;
- CHECK(mFormat->findInt32(kKeySampleRate, &sampleRate));
- CHECK(mFormat->findInt32(kKeyChannelCount, &numChannels));
+ if (!mFormat->findInt32(kKeySampleRate, &sampleRate)) {
+ ALOGE("SampleRate not found");
+ return NULL;
+ }
+ if (!mFormat->findInt32(kKeyChannelCount, &numChannels)) {
+ ALOGE("ChannelCount not found");
+ return NULL;
+ }
ALOGI("found AAC codec config (%d Hz, %d channels)",
sampleRate, numChannels);
@@ -682,7 +720,8 @@
if (number_of_raw_data_blocks_in_frame != 0) {
// To be implemented.
- TRESPASS();
+ ALOGE("Should not reach here.");
+ return NULL;
}
if (offset + aac_frame_length > mBuffer->size()) {
@@ -714,7 +753,9 @@
bool first = true;
while (size > 0) {
- CHECK(!mRangeInfos.empty());
+ if (mRangeInfos.empty()) {
+ return timeUs;
+ }
RangeInfo *info = &*mRangeInfos.begin();
@@ -813,7 +854,10 @@
unsigned nalType = mBuffer->data()[pos.nalOffset] & 0x1f;
if (nalType == 6 && pos.nalSize > 0) {
- CHECK_LT(seiIndex, sei->size() / sizeof(NALPosition));
+ if (seiIndex >= sei->size() / sizeof(NALPosition)) {
+ ALOGE("Wrong seiIndex");
+ return NULL;
+ }
NALPosition &seiPos = ((NALPosition *)sei->data())[seiIndex++];
seiPos.nalOffset = dstOffset + 4;
seiPos.nalSize = pos.nalSize;
@@ -851,7 +895,10 @@
mBuffer->setRange(0, mBuffer->size() - nextScan);
int64_t timeUs = fetchTimestamp(nextScan);
- CHECK_GE(timeUs, 0ll);
+ if (timeUs < 0ll) {
+ ALOGE("Negative timeUs");
+ return NULL;
+ }
accessUnit->meta()->setInt64("timeUs", timeUs);
if (foundIDR) {
@@ -873,7 +920,10 @@
totalSize += nalSize;
}
- CHECK_EQ(err, (status_t)-EAGAIN);
+ if (err != (status_t)-EAGAIN) {
+ ALOGE("Unexpeted err");
+ return NULL;
+ }
return NULL;
}
@@ -890,9 +940,12 @@
size_t frameSize;
int samplingRate, numChannels, bitrate, numSamples;
- CHECK(GetMPEGAudioFrameSize(
+ if (!GetMPEGAudioFrameSize(
header, &frameSize, &samplingRate, &numChannels,
- &bitrate, &numSamples));
+ &bitrate, &numSamples)) {
+ ALOGE("Failed to get audio frame size");
+ return NULL;
+ }
if (size < frameSize) {
return NULL;
@@ -910,7 +963,10 @@
mBuffer->setRange(0, mBuffer->size() - frameSize);
int64_t timeUs = fetchTimestamp(frameSize);
- CHECK_GE(timeUs, 0ll);
+ if (timeUs < 0ll) {
+ ALOGE("Negative timeUs");
+ return NULL;
+ }
accessUnit->meta()->setInt64("timeUs", timeUs);
accessUnit->meta()->setInt32("isSync", 1);
@@ -932,7 +988,7 @@
kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
break;
default:
- TRESPASS();
+ return NULL;
}
mFormat->setInt32(kKeySampleRate, samplingRate);
@@ -943,7 +999,10 @@
}
static void EncodeSize14(uint8_t **_ptr, size_t size) {
- CHECK_LE(size, 0x3fff);
+ if (size > 0x3fff) {
+ ALOGE("Wrong size");
+ return;
+ }
uint8_t *ptr = *_ptr;
@@ -1018,7 +1077,10 @@
// seqHeader without/with extension
if (mFormat == NULL) {
- CHECK_GE(size, 7u);
+ if (size < 7u) {
+ ALOGE("Size too small");
+ return NULL;
+ }
unsigned width =
(data[4] << 4) | data[5] >> 4;
@@ -1078,7 +1140,10 @@
mBuffer->setRange(0, mBuffer->size() - offset);
int64_t timeUs = fetchTimestamp(offset);
- CHECK_GE(timeUs, 0ll);
+ if (timeUs < 0ll) {
+ ALOGE("Negative timeUs");
+ return NULL;
+ }
offset = 0;
@@ -1111,7 +1176,7 @@
}
if (memcmp(kStartCode, data, 3)) {
- TRESPASS();
+ return -EAGAIN;
}
size_t offset = 3;
@@ -1171,25 +1236,37 @@
case EXPECT_VISUAL_OBJECT_START:
{
- CHECK_EQ(chunkType, 0xb5);
+ if (chunkType != 0xb5) {
+ ALOGE("Unexpected chunkType");
+ return NULL;
+ }
state = EXPECT_VO_START;
break;
}
case EXPECT_VO_START:
{
- CHECK_LE(chunkType, 0x1f);
+ if (chunkType > 0x1f) {
+ ALOGE("Unexpected chunkType");
+ return NULL;
+ }
state = EXPECT_VOL_START;
break;
}
case EXPECT_VOL_START:
{
- CHECK((chunkType & 0xf0) == 0x20);
+ if ((chunkType & 0xf0) != 0x20) {
+ ALOGE("Wrong chunkType");
+ return NULL;
+ }
- CHECK(ExtractDimensionsFromVOLHeader(
+ if (!ExtractDimensionsFromVOLHeader(
&data[offset], chunkSize,
- &width, &height));
+ &width, &height)) {
+ ALOGE("Failed to get dimension");
+ return NULL;
+ }
state = WAIT_FOR_VOP_START;
break;
@@ -1242,7 +1319,10 @@
mBuffer->setRange(0, size);
int64_t timeUs = fetchTimestamp(offset);
- CHECK_GE(timeUs, 0ll);
+ if (timeUs < 0ll) {
+ ALOGE("Negative timeus");
+ return NULL;
+ }
offset = 0;
@@ -1266,7 +1346,8 @@
}
default:
- TRESPASS();
+ ALOGE("Unknown state: %d", state);
+ return NULL;
}
if (discard) {
diff --git a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
index 85859f7..67ffad3 100644
--- a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
@@ -265,7 +265,10 @@
}
unsigned PES_packet_length = U16_AT(mBuffer->data() + 4);
- CHECK_NE(PES_packet_length, 0u);
+ if (PES_packet_length == 0u) {
+ ALOGE("PES_packet_length is 0");
+ return -EAGAIN;
+ }
size_t n = PES_packet_length + 6;
@@ -286,7 +289,10 @@
return ERROR_MALFORMED;
}
- CHECK_EQ(packet_startcode_prefix, 0x000001u);
+ if (packet_startcode_prefix != 0x000001u) {
+ ALOGE("Wrong PES prefix");
+ return ERROR_MALFORMED;
+ }
unsigned stream_id = br.getBits(8);
ALOGV("stream_id = 0x%02x", stream_id);
@@ -366,8 +372,7 @@
&& stream_id != 0xff // program_stream_directory
&& stream_id != 0xf2 // DSMCC
&& stream_id != 0xf8) { // H.222.1 type E
- CHECK_EQ(br.getBits(2), 2u);
-
+ /* unsigned PES_marker_bits = */br.getBits(2); // should be 0x2(hex)
/* unsigned PES_scrambling_control = */br.getBits(2);
/* unsigned PES_priority = */br.getBits(1);
/* unsigned data_alignment_indicator = */br.getBits(1);
@@ -400,16 +405,26 @@
uint64_t PTS = 0, DTS = 0;
if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
- CHECK_GE(optional_bytes_remaining, 5u);
+ if (optional_bytes_remaining < 5u) {
+ return ERROR_MALFORMED;
+ }
- CHECK_EQ(br.getBits(4), PTS_DTS_flags);
+ if (br.getBits(4) != PTS_DTS_flags) {
+ return ERROR_MALFORMED;
+ }
PTS = ((uint64_t)br.getBits(3)) << 30;
- CHECK_EQ(br.getBits(1), 1u);
+ if (br.getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
PTS |= ((uint64_t)br.getBits(15)) << 15;
- CHECK_EQ(br.getBits(1), 1u);
+ if (br.getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
PTS |= br.getBits(15);
- CHECK_EQ(br.getBits(1), 1u);
+ if (br.getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
ALOGV("PTS = %" PRIu64, PTS);
// ALOGI("PTS = %.2f secs", PTS / 90000.0f);
@@ -417,16 +432,26 @@
optional_bytes_remaining -= 5;
if (PTS_DTS_flags == 3) {
- CHECK_GE(optional_bytes_remaining, 5u);
+ if (optional_bytes_remaining < 5u) {
+ return ERROR_MALFORMED;
+ }
- CHECK_EQ(br.getBits(4), 1u);
+ if (br.getBits(4) != 1u) {
+ return ERROR_MALFORMED;
+ }
DTS = ((uint64_t)br.getBits(3)) << 30;
- CHECK_EQ(br.getBits(1), 1u);
+ if (br.getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
DTS |= ((uint64_t)br.getBits(15)) << 15;
- CHECK_EQ(br.getBits(1), 1u);
+ if (br.getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
DTS |= br.getBits(15);
- CHECK_EQ(br.getBits(1), 1u);
+ if (br.getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
ALOGV("DTS = %" PRIu64, DTS);
@@ -435,31 +460,47 @@
}
if (ESCR_flag) {
- CHECK_GE(optional_bytes_remaining, 6u);
+ if (optional_bytes_remaining < 6u) {
+ return ERROR_MALFORMED;
+ }
br.getBits(2);
uint64_t ESCR = ((uint64_t)br.getBits(3)) << 30;
- CHECK_EQ(br.getBits(1), 1u);
+ if (br.getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
ESCR |= ((uint64_t)br.getBits(15)) << 15;
- CHECK_EQ(br.getBits(1), 1u);
+ if (br.getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
ESCR |= br.getBits(15);
- CHECK_EQ(br.getBits(1), 1u);
+ if (br.getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
ALOGV("ESCR = %" PRIu64, ESCR);
/* unsigned ESCR_extension = */br.getBits(9);
- CHECK_EQ(br.getBits(1), 1u);
+ if (br.getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
optional_bytes_remaining -= 6;
}
if (ES_rate_flag) {
- CHECK_GE(optional_bytes_remaining, 3u);
+ if (optional_bytes_remaining < 3u) {
+ return ERROR_MALFORMED;
+ }
- CHECK_EQ(br.getBits(1), 1u);
+ if (br.getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
/* unsigned ES_rate = */br.getBits(22);
- CHECK_EQ(br.getBits(1), 1u);
+ if (br.getBits(1) != 1u) {
+ return ERROR_MALFORMED;
+ }
optional_bytes_remaining -= 3;
}
@@ -468,7 +509,9 @@
// ES data follows.
- CHECK_GE(PES_packet_length, PES_header_data_length + 3);
+ if (PES_packet_length < PES_header_data_length + 3) {
+ return ERROR_MALFORMED;
+ }
unsigned dataLength =
PES_packet_length - 3 - PES_header_data_length;
@@ -481,7 +524,9 @@
return ERROR_MALFORMED;
}
- CHECK_GE(br.numBitsLeft(), dataLength * 8);
+ if (br.numBitsLeft() < dataLength * 8) {
+ return ERROR_MALFORMED;
+ }
ssize_t index = mTracks.indexOfKey(stream_id);
if (index < 0 && mScanning) {
@@ -521,10 +566,14 @@
return err;
}
} else if (stream_id == 0xbe) { // padding_stream
- CHECK_NE(PES_packet_length, 0u);
+ if (PES_packet_length == 0u) {
+ return ERROR_MALFORMED;
+ }
br.skipBits(PES_packet_length * 8);
} else {
- CHECK_NE(PES_packet_length, 0u);
+ if (PES_packet_length == 0u) {
+ return ERROR_MALFORMED;
+ }
br.skipBits(PES_packet_length * 8);
}
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index 74cb5d8..f5c33cf 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -131,7 +131,10 @@
bool seekable = true;
if (mSourceImpls.size() > 1) {
- CHECK_EQ(mSourceImpls.size(), 2u);
+ if (mSourceImpls.size() != 2u) {
+ ALOGE("Wrong size");
+ return NULL;
+ }
sp<MetaData> meta = mSourceImpls.editItemAt(index)->getFormat();
const char *mime;
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/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index 80c1c2f..cd0c462 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -154,6 +154,10 @@
} else {
mData->mCodec = android::MediaCodec::CreateByComponentName(mData->mLooper, name);
}
+ if (mData->mCodec == NULL) { // failed to create codec
+ AMediaCodec_delete(mData);
+ return NULL;
+ }
mData->mHandler = new CodecHandler(mData);
mData->mLooper->registerHandler(mData->mHandler);
mData->mGeneration = 1;
@@ -180,17 +184,21 @@
EXPORT
media_status_t AMediaCodec_delete(AMediaCodec *mData) {
- if (mData->mCodec != NULL) {
- mData->mCodec->release();
- mData->mCodec.clear();
- }
+ if (mData != NULL) {
+ if (mData->mCodec != NULL) {
+ mData->mCodec->release();
+ mData->mCodec.clear();
+ }
- if (mData->mLooper != NULL) {
- mData->mLooper->unregisterHandler(mData->mHandler->id());
- mData->mLooper->stop();
- mData->mLooper.clear();
+ if (mData->mLooper != NULL) {
+ if (mData->mHandler != NULL) {
+ mData->mLooper->unregisterHandler(mData->mHandler->id());
+ }
+ mData->mLooper->stop();
+ mData->mLooper.clear();
+ }
+ delete mData;
}
- delete mData;
return AMEDIA_OK;
}
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 2e905fd..238edfa 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->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 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