Merge cherrypicks of [4691111, 4689862, 4690575, 4690576, 4690577, 4690578, 4689866, 4689868, 4689869, 4689870, 4691132, 4689456, 4689963, 4691133, 4691134, 4691156, 4691157, 4691159, 4691161, 4690581, 4689964, 4689460, 4691112, 4690582, 4690583, 4691165, 4691166, 4691167, 4691168, 4691169, 4691170, 4691211, 4691212, 4691213, 4691214, 4691215, 4691216, 4691217, 4691218, 4691219, 4691232, 4691233, 4691234, 4691235, 4691236, 4691237, 4691238, 4691239, 4691240, 4691241, 4691243, 4691245, 4691247, 4691249, 4691250, 4691291, 4691292, 4691293, 4691294, 4691295, 4691296, 4691255, 4689476, 4689477, 4689478, 4691223, 4691224, 4691136, 4689479, 4689480, 4691137, 4691225, 4691226, 4691227, 4691371, 4691228, 4691328, 4689967, 4691138, 4691139, 4691140, 4691433, 4689968, 4689969, 4691395, 4691230, 4691297, 4691298, 4691299, 4691300, 4691396, 4691397, 4691398, 4691399, 4691400, 4691401, 4691402, 4691403, 4691404, 4691405, 4691406, 4691407, 4691408, 4691409, 4691410, 4691471, 4691472, 4691473, 4691474, 4691475, 4691476, 4691477, 4691478, 4691479, 4691480, 4691481, 4691482, 4691483, 4691484, 4691485, 4691486, 4691487, 4691488, 4691143, 4691144, 4691511, 4691113, 4689482, 4691533, 4691145, 4691146, 4691147, 4691148, 4691536] into sparse-4732991-L01200000196794104
Change-Id: I066b69b810f0a1acd43176472ac2a3f87c429873
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 1fdc6e1..5dd2563 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -240,11 +240,12 @@
Mutex::Autolock autoLock(mLock);
int32_t seqNum = mHeapSeqNum++;
+
int fd = heap->getHeapID();
nativeHandle->data[0] = fd;
auto hidlHandle = hidl_handle(nativeHandle);
auto hidlMemory = hidl_memory("ashmem", hidlHandle, heap->getSize());
- mHeapBases.add(seqNum, mNextBufferId);
+ mHeapBases.add(seqNum, HeapBase(mNextBufferId, heap->getSize()));
Return<void> hResult = mPlugin->setSharedBufferBase(hidlMemory, mNextBufferId++);
ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
return seqNum;
@@ -269,10 +270,26 @@
return UNEXPECTED_NULL;
}
- // memory must be in the declared heap
- CHECK(mHeapBases.indexOfKey(seqNum) >= 0);
+ // memory must be in one of the heaps that have been set
+ if (mHeapBases.indexOfKey(seqNum) < 0) {
+ return UNKNOWN_ERROR;
+ }
- buffer->bufferId = mHeapBases.valueFor(seqNum);
+ // heap must be the same size as the one that was set in setHeapBase
+ if (mHeapBases.valueFor(seqNum).getSize() != heap->getSize()) {
+ android_errorWriteLog(0x534e4554, "76221123");
+ return UNKNOWN_ERROR;
+ }
+
+ // memory must be within the address space of the heap
+ if (memory->pointer() != static_cast<uint8_t *>(heap->getBase()) + memory->offset() ||
+ heap->getSize() < memory->offset() + memory->size() ||
+ SIZE_MAX - memory->offset() < memory->size()) {
+ android_errorWriteLog(0x534e4554, "76221123");
+ return UNKNOWN_ERROR;
+ }
+
+ buffer->bufferId = mHeapBases.valueFor(seqNum).getBufferId();
buffer->offset = offset >= 0 ? offset : 0;
buffer->size = size;
return OK;
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index d838975..f071a02 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -940,7 +940,7 @@
audio_output_flags_t flags =
static_cast <audio_output_flags_t>(data.readInt32());
bool hasOffloadInfo = data.readInt32() != 0;
- audio_offload_info_t offloadInfo;
+ audio_offload_info_t offloadInfo = {};
if (hasOffloadInfo) {
data.read(&offloadInfo, sizeof(audio_offload_info_t));
}
@@ -956,7 +956,7 @@
case GET_OUTPUT_FOR_ATTR: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_attributes_t attr;
+ audio_attributes_t attr = {};
bool hasAttributes = data.readInt32() != 0;
if (hasAttributes) {
data.read(&attr, sizeof(audio_attributes_t));
@@ -1024,7 +1024,7 @@
case GET_INPUT_FOR_ATTR: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_attributes_t attr;
+ audio_attributes_t attr = {};
data.read(&attr, sizeof(audio_attributes_t));
sanetizeAudioAttributes(&attr);
audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
@@ -1125,8 +1125,11 @@
case GET_OUTPUT_FOR_EFFECT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- effect_descriptor_t desc;
- data.read(&desc, sizeof(effect_descriptor_t));
+ effect_descriptor_t desc = {};
+ if (data.read(&desc, sizeof(desc)) != NO_ERROR) {
+ android_errorWriteLog(0x534e4554, "73126106");
+ }
+ (void)sanitizeEffectDescriptor(&desc);
audio_io_handle_t output = getOutputForEffect(&desc);
reply->writeInt32(static_cast <int>(output));
return NO_ERROR;
@@ -1134,8 +1137,11 @@
case REGISTER_EFFECT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- effect_descriptor_t desc;
- data.read(&desc, sizeof(effect_descriptor_t));
+ effect_descriptor_t desc = {};
+ if (data.read(&desc, sizeof(desc)) != NO_ERROR) {
+ android_errorWriteLog(0x534e4554, "73126106");
+ }
+ (void)sanitizeEffectDescriptor(&desc);
audio_io_handle_t io = data.readInt32();
uint32_t strategy = data.readInt32();
audio_session_t session = (audio_session_t) data.readInt32();
@@ -1194,7 +1200,7 @@
count = AudioEffect::kMaxPreProcessing;
}
uint32_t retCount = count;
- effect_descriptor_t *descriptors = new effect_descriptor_t[count];
+ effect_descriptor_t *descriptors = new effect_descriptor_t[count]{};
status_t status = queryDefaultPreProcessing(audioSession, descriptors, &retCount);
reply->writeInt32(status);
if (status != NO_ERROR && status != NO_MEMORY) {
@@ -1213,7 +1219,7 @@
case IS_OFFLOAD_SUPPORTED: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_offload_info_t info;
+ audio_offload_info_t info = {};
data.read(&info, sizeof(audio_offload_info_t));
bool isSupported = isOffloadSupported(info);
reply->writeInt32(isSupported);
@@ -1268,7 +1274,7 @@
case CREATE_AUDIO_PATCH: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- struct audio_patch patch;
+ struct audio_patch patch = {};
data.read(&patch, sizeof(struct audio_patch));
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
if (data.read(&handle, sizeof(audio_patch_handle_t)) != NO_ERROR) {
@@ -1284,7 +1290,7 @@
case RELEASE_AUDIO_PATCH: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_patch_handle_t handle;
+ audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
data.read(&handle, sizeof(audio_patch_handle_t));
status_t status = releaseAudioPatch(handle);
reply->writeInt32(status);
@@ -1323,8 +1329,9 @@
case SET_AUDIO_PORT_CONFIG: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- struct audio_port_config config;
+ struct audio_port_config config = {};
data.read(&config, sizeof(struct audio_port_config));
+ (void)sanitizeAudioPortConfig(&config);
status_t status = setAudioPortConfig(&config);
reply->writeInt32(status);
return NO_ERROR;
@@ -1398,9 +1405,10 @@
case START_AUDIO_SOURCE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- struct audio_port_config source;
+ struct audio_port_config source = {};
data.read(&source, sizeof(struct audio_port_config));
- audio_attributes_t attributes;
+ (void)sanitizeAudioPortConfig(&source);
+ audio_attributes_t attributes = {};
data.read(&attributes, sizeof(audio_attributes_t));
sanetizeAudioAttributes(&attributes);
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
@@ -1453,6 +1461,14 @@
}
}
+/** returns true if string overflow was prevented by zero termination */
+template <size_t size>
+static bool preventStringOverflow(char (&s)[size]) {
+ if (strnlen(s, size) < size) return false;
+ s[size - 1] = '\0';
+ return true;
+}
+
void BnAudioPolicyService::sanetizeAudioAttributes(audio_attributes_t* attr)
{
const size_t tagsMaxSize = AUDIO_ATTRIBUTES_TAGS_MAX_SIZE;
@@ -1462,6 +1478,27 @@
attr->tags[tagsMaxSize - 1] = '\0';
}
+/** returns BAD_VALUE if sanitization was required. */
+status_t BnAudioPolicyService::sanitizeEffectDescriptor(effect_descriptor_t* desc)
+{
+ if (preventStringOverflow(desc->name)
+ | /* always */ preventStringOverflow(desc->implementor)) {
+ android_errorWriteLog(0x534e4554, "73126106"); // SafetyNet logging
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+/** returns BAD_VALUE if sanitization was required. */
+status_t BnAudioPolicyService::sanitizeAudioPortConfig(struct audio_port_config* config)
+{
+ if (config->type == AUDIO_PORT_TYPE_DEVICE &&
+ preventStringOverflow(config->ext.device.address)) {
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
// ----------------------------------------------------------------------------
} // namespace android
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index 60ba4ba..eec3e88 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -185,6 +185,8 @@
uint32_t flags = 0);
private:
void sanetizeAudioAttributes(audio_attributes_t* attr);
+ status_t sanitizeEffectDescriptor(effect_descriptor_t* desc);
+ status_t sanitizeAudioPortConfig(struct audio_port_config* config);
};
// ----------------------------------------------------------------------------
diff --git a/media/libmedia/include/media/CryptoHal.h b/media/libmedia/include/media/CryptoHal.h
index a5d8b43..80e181e 100644
--- a/media/libmedia/include/media/CryptoHal.h
+++ b/media/libmedia/include/media/CryptoHal.h
@@ -79,7 +79,20 @@
*/
status_t mInitCheck;
- KeyedVector<int32_t, uint32_t> mHeapBases;
+ struct HeapBase {
+ HeapBase() : mBufferId(0), mSize(0) {}
+ HeapBase(uint32_t bufferId, size_t size) :
+ mBufferId(bufferId), mSize(size) {}
+
+ uint32_t getBufferId() const {return mBufferId;}
+ size_t getSize() const {return mSize;}
+
+ private:
+ uint32_t mBufferId;
+ size_t mSize;
+ };
+
+ KeyedVector<int32_t, HeapBase> mHeapBases;
uint32_t mNextBufferId;
int32_t mHeapSeqNum;
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp
index cd0a003..686c059 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.cpp
+++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp
@@ -126,8 +126,7 @@
sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(
player_type playerType,
- const wp<IMediaPlayer> &client,
- notify_callback_f notifyFunc,
+ const sp<MediaPlayerBase::Listener> &listener,
pid_t pid) {
sp<MediaPlayerBase> p;
IFactory* factory;
@@ -152,7 +151,7 @@
init_result = p->initCheck();
if (init_result == NO_ERROR) {
- p->setNotifyCallback(client, notifyFunc);
+ p->setNotifyCallback(listener);
} else {
ALOGE("Failed to create player object of type %d, initCheck failed"
" (res = %d)", playerType, init_result);
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.h b/media/libmediaplayerservice/MediaPlayerFactory.h
index 6aedeb2..e88700c 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.h
+++ b/media/libmediaplayerservice/MediaPlayerFactory.h
@@ -65,8 +65,7 @@
const sp<DataSource> &source);
static sp<MediaPlayerBase> createPlayer(player_type playerType,
- const wp<IMediaPlayer> &client,
- notify_callback_f notifyFunc,
+ const sp<MediaPlayerBase::Listener> &listener,
pid_t pid);
static void registerBuiltinFactories();
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 6e17b8d..3445469 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -590,10 +590,11 @@
mUid = uid;
mRetransmitEndpointValid = false;
mAudioAttributes = NULL;
+ mListener = new Listener(this);
#if CALLBACK_ANTAGONIZER
ALOGD("create Antagonizer");
- mAntagonizer = new Antagonizer(notify, this);
+ mAntagonizer = new Antagonizer(mListener);
#endif
}
@@ -627,7 +628,7 @@
// and reset the player. We assume the player will serialize
// access to itself if necessary.
if (p != 0) {
- p->setNotifyCallback(0, 0);
+ p->setNotifyCallback(0);
#if CALLBACK_ANTAGONIZER
ALOGD("kill Antagonizer");
mAntagonizer->kill();
@@ -652,7 +653,7 @@
p.clear();
}
if (p == NULL) {
- p = MediaPlayerFactory::createPlayer(playerType, this, notify, mPid);
+ p = MediaPlayerFactory::createPlayer(playerType, mListener, mPid);
}
if (p != NULL) {
@@ -1430,25 +1431,19 @@
}
void MediaPlayerService::Client::notify(
- const wp<IMediaPlayer> &listener, int msg, int ext1, int ext2, const Parcel *obj)
+ int msg, int ext1, int ext2, const Parcel *obj)
{
- sp<IMediaPlayer> spListener = listener.promote();
- if (spListener == NULL) {
- return;
- }
- Client* client = static_cast<Client*>(spListener.get());
-
sp<IMediaPlayerClient> c;
sp<Client> nextClient;
status_t errStartNext = NO_ERROR;
{
- Mutex::Autolock l(client->mLock);
- c = client->mClient;
- if (msg == MEDIA_PLAYBACK_COMPLETE && client->mNextClient != NULL) {
- nextClient = client->mNextClient;
+ Mutex::Autolock l(mLock);
+ c = mClient;
+ if (msg == MEDIA_PLAYBACK_COMPLETE && mNextClient != NULL) {
+ nextClient = mNextClient;
- if (client->mAudioOutput != NULL)
- client->mAudioOutput->switchToNextOutput();
+ if (mAudioOutput != NULL)
+ mAudioOutput->switchToNextOutput();
errStartNext = nextClient->start();
}
@@ -1474,17 +1469,17 @@
MEDIA_INFO_METADATA_UPDATE == ext1) {
const media::Metadata::Type metadata_type = ext2;
- if(client->shouldDropMetadata(metadata_type)) {
+ if(shouldDropMetadata(metadata_type)) {
return;
}
// Update the list of metadata that have changed. getMetadata
// also access mMetadataUpdated and clears it.
- client->addNewMetadataUpdate(metadata_type);
+ addNewMetadataUpdate(metadata_type);
}
if (c != NULL) {
- ALOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, spListener.get(), msg, ext1, ext2);
+ ALOGV("[%d] notify (%d, %d, %d)", mConnId, msg, ext1, ext2);
c->notify(msg, ext1, ext2, obj);
}
}
@@ -1542,8 +1537,8 @@
#if CALLBACK_ANTAGONIZER
const int Antagonizer::interval = 10000; // 10 msecs
-Antagonizer::Antagonizer(notify_callback_f cb, const wp<IMediaPlayer> &client) :
- mExit(false), mActive(false), mClient(client), mCb(cb)
+Antagonizer::Antagonizer(const sp<MediaPlayerBase::Listener> &listener) :
+ mExit(false), mActive(false), mListener(listener)
{
createThread(callbackThread, this);
}
@@ -1563,7 +1558,7 @@
while (!p->mExit) {
if (p->mActive) {
ALOGV("send event");
- p->mCb(p->mClient, 0, 0, 0);
+ p->mListener->notify(0, 0, 0, 0);
}
usleep(interval);
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index f043f32..34e5e2a 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -51,7 +51,7 @@
#if CALLBACK_ANTAGONIZER
class Antagonizer {
public:
- Antagonizer(notify_callback_f cb, const wp<IMediaPlayer> &client);
+ Antagonizer(const sp<MediaPlayerBase::Listener> &listener);
void start() { mActive = true; }
void stop() { mActive = false; }
void kill();
@@ -59,12 +59,11 @@
static const int interval;
Antagonizer();
static int callbackThread(void* cookie);
- Mutex mLock;
- Condition mCondition;
- bool mExit;
- bool mActive;
- wp<IMediaPlayer> mClient;
- notify_callback_f mCb;
+ Mutex mLock;
+ Condition mCondition;
+ bool mExit;
+ bool mActive;
+ sp<MediaPlayerBase::Listener> mListener;
};
#endif
@@ -215,7 +214,6 @@
}; // AudioOutput
-
public:
static void instantiate();
@@ -365,8 +363,7 @@
status_t setDataSource_post(const sp<MediaPlayerBase>& p,
status_t status);
- static void notify(const wp<IMediaPlayer> &cookie, int msg,
- int ext1, int ext2, const Parcel *obj);
+ void notify(int msg, int ext1, int ext2, const Parcel *obj);
pid_t pid() const { return mPid; }
virtual status_t dump(int fd, const Vector<String16>& args);
@@ -437,23 +434,38 @@
status_t setAudioAttributes_l(const Parcel &request);
- mutable Mutex mLock;
- sp<MediaPlayerBase> mPlayer;
- sp<MediaPlayerService> mService;
- sp<IMediaPlayerClient> mClient;
- sp<AudioOutput> mAudioOutput;
- pid_t mPid;
- status_t mStatus;
- bool mLoop;
- int32_t mConnId;
- audio_session_t mAudioSessionId;
- audio_attributes_t * mAudioAttributes;
- uid_t mUid;
- sp<ANativeWindow> mConnectedWindow;
- sp<IBinder> mConnectedWindowBinder;
- struct sockaddr_in mRetransmitEndpoint;
- bool mRetransmitEndpointValid;
- sp<Client> mNextClient;
+ class Listener : public MediaPlayerBase::Listener {
+ public:
+ Listener(const wp<Client> &client) : mClient(client) {}
+ virtual ~Listener() {}
+ virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) {
+ sp<Client> client = mClient.promote();
+ if (client != NULL) {
+ client->notify(msg, ext1, ext2, obj);
+ }
+ }
+ private:
+ wp<Client> mClient;
+ };
+
+ mutable Mutex mLock;
+ sp<MediaPlayerBase> mPlayer;
+ sp<MediaPlayerService> mService;
+ sp<IMediaPlayerClient> mClient;
+ sp<AudioOutput> mAudioOutput;
+ pid_t mPid;
+ status_t mStatus;
+ bool mLoop;
+ int32_t mConnId;
+ audio_session_t mAudioSessionId;
+ audio_attributes_t * mAudioAttributes;
+ uid_t mUid;
+ sp<ANativeWindow> mConnectedWindow;
+ sp<IBinder> mConnectedWindowBinder;
+ struct sockaddr_in mRetransmitEndpoint;
+ bool mRetransmitEndpointValid;
+ sp<Client> mNextClient;
+ sp<MediaPlayerBase::Listener> mListener;
// Metadata filters.
media::Metadata::Filter mMetadataAllow; // protected by mLock
@@ -468,7 +480,7 @@
sp<ServiceDeathNotifier> mExtractorDeathListener;
sp<ServiceDeathNotifier> mCodecDeathListener;
#if CALLBACK_ANTAGONIZER
- Antagonizer* mAntagonizer;
+ Antagonizer* mAntagonizer;
#endif
}; // Client
diff --git a/media/libmediaplayerservice/include/MediaPlayerInterface.h b/media/libmediaplayerservice/include/MediaPlayerInterface.h
index 34f1fe4..6d02cce 100644
--- a/media/libmediaplayerservice/include/MediaPlayerInterface.h
+++ b/media/libmediaplayerservice/include/MediaPlayerInterface.h
@@ -66,14 +66,17 @@
// duration below which we do not allow deep audio buffering
#define AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US 5000000
-// callback mechanism for passing messages to MediaPlayer object
-typedef void (*notify_callback_f)(const wp<IMediaPlayer> &listener,
- int msg, int ext1, int ext2, const Parcel *obj);
-
// abstract base class - use MediaPlayerInterface
class MediaPlayerBase : public RefBase
{
public:
+ // callback mechanism for passing messages to MediaPlayer object
+ class Listener : public RefBase {
+ public:
+ virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) = 0;
+ virtual ~Listener() {}
+ };
+
// AudioSink: abstraction layer for audio output
class AudioSink : public RefBase {
public:
@@ -152,7 +155,7 @@
virtual sp<VolumeShaper::State> getVolumeShaperState(int id);
};
- MediaPlayerBase() : mClient(0), mNotify(0) {}
+ MediaPlayerBase() {}
virtual ~MediaPlayerBase() {}
virtual status_t initCheck() = 0;
virtual bool hardwareOutput() = 0;
@@ -263,22 +266,22 @@
};
void setNotifyCallback(
- const wp<IMediaPlayer> &client, notify_callback_f notifyFunc) {
+ const sp<Listener> &listener) {
Mutex::Autolock autoLock(mNotifyLock);
- mClient = client; mNotify = notifyFunc;
+ mListener = listener;
}
void sendEvent(int msg, int ext1=0, int ext2=0,
const Parcel *obj=NULL) {
- notify_callback_f notifyCB;
- wp<IMediaPlayer> client;
+ sp<Listener> listener;
{
Mutex::Autolock autoLock(mNotifyLock);
- notifyCB = mNotify;
- client = mClient;
+ listener = mListener;
}
- if (notifyCB) notifyCB(client, msg, ext1, ext2, obj);
+ if (listener != NULL) {
+ listener->notify(msg, ext1, ext2, obj);
+ }
}
virtual status_t dump(int /* fd */, const Vector<String16>& /* args */) const {
@@ -297,8 +300,7 @@
friend class MediaPlayerService;
Mutex mNotifyLock;
- wp<IMediaPlayer> mClient;
- notify_callback_f mNotify;
+ sp<Listener> mListener;
};
// Implement this class for media players that use the AudioFlinger software mixer
diff --git a/media/libstagefright/ItemTable.cpp b/media/libstagefright/ItemTable.cpp
index f9ee1c4..f589f4f 100644
--- a/media/libstagefright/ItemTable.cpp
+++ b/media/libstagefright/ItemTable.cpp
@@ -1335,7 +1335,8 @@
ALOGV("adding %s: itemId %d", image.isGrid() ? "grid" : "image", info.itemId);
if (image.isGrid()) {
- if (size > 12) {
+ // ImageGrid struct is at least 8-byte, at most 12-byte (if flags&1)
+ if (size < 8 || size > 12) {
return ERROR_MALFORMED;
}
uint8_t buf[12];
diff --git a/media/libstagefright/MidiExtractor.cpp b/media/libstagefright/MidiExtractor.cpp
index 7930bbb..2145134 100644
--- a/media/libstagefright/MidiExtractor.cpp
+++ b/media/libstagefright/MidiExtractor.cpp
@@ -246,8 +246,9 @@
EAS_I32 numRendered;
EAS_RESULT result = EAS_Render(mEasData, p, mEasConfig->mixBufferSize, &numRendered);
if (result != EAS_SUCCESS) {
- ALOGE("EAS_Render returned %ld", result);
- break;
+ ALOGE("EAS_Render() returned %ld, numBytesOutput = %d", result, numBytesOutput);
+ buffer->release();
+ return NULL; // Stop processing to prevent infinite loops.
}
p += numRendered * mEasConfig->numChannels;
numBytesOutput += numRendered * mEasConfig->numChannels * sizeof(EAS_PCM);
diff --git a/media/libstagefright/VideoFrameScheduler.cpp b/media/libstagefright/VideoFrameScheduler.cpp
index 03226c7..6819bba 100644
--- a/media/libstagefright/VideoFrameScheduler.cpp
+++ b/media/libstagefright/VideoFrameScheduler.cpp
@@ -129,6 +129,11 @@
numSamplesToUse = mNumSamples;
}
+ if ((period >> kPrecision) == 0 ) {
+ ALOGW("Period is 0, or after including precision is 0 - would cause div0, returning");
+ return false;
+ }
+
int64_t sumX = 0;
int64_t sumXX = 0;
int64_t sumXY = 0;
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index 214feab..6115513 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -56,7 +56,7 @@
const char *language,
uint32_t flags);
- bool getActiveURI(AString *uri) const;
+ bool getActiveURI(AString *uri, const char *baseURL) const;
void pickRandomMediaItems();
status_t selectTrack(size_t index, bool select);
@@ -75,6 +75,7 @@
AString mURI;
AString mLanguage;
uint32_t mFlags;
+ AString makeURL(const char *baseURL) const;
};
Type mType;
@@ -227,12 +228,16 @@
return format;
}
-bool M3UParser::MediaGroup::getActiveURI(AString *uri) const {
+bool M3UParser::MediaGroup::getActiveURI(AString *uri, const char *baseURL) const {
for (size_t i = 0; i < mMediaItems.size(); ++i) {
if (mSelectedIndex >= 0 && i == (size_t)mSelectedIndex) {
const Media &item = mMediaItems.itemAt(i);
- *uri = item.mURI;
+ if (item.mURI.empty()) {
+ *uri = "";
+ } else {
+ *uri = item.makeURL(baseURL);
+ }
return true;
}
}
@@ -321,7 +326,7 @@
}
if (uri) {
- *uri = mItems.itemAt(index).mURI;
+ *uri = mItems.itemAt(index).makeURL(mBaseURI.c_str());
}
if (meta) {
@@ -427,7 +432,7 @@
AString groupID;
if (!meta->findString(key, &groupID)) {
if (uri != NULL) {
- *uri = mItems.itemAt(index).mURI;
+ *uri = mItems.itemAt(index).makeURL(mBaseURI.c_str());
}
AString codecs;
@@ -458,12 +463,12 @@
// don't care about the active URI (or if there is an active one)
if (uri != NULL) {
sp<MediaGroup> group = mMediaGroups.valueFor(groupID);
- if (!group->getActiveURI(uri)) {
+ if (!group->getActiveURI(uri, mBaseURI.c_str())) {
return false;
}
if ((*uri).empty()) {
- *uri = mItems.itemAt(index).mURI;
+ *uri = mItems.itemAt(index).makeURL(mBaseURI.c_str());
}
}
@@ -544,6 +549,18 @@
return true;
}
+AString M3UParser::Item::makeURL(const char *baseURL) const {
+ AString out;
+ CHECK(MakeURL(baseURL, mURI.c_str(), &out));
+ return out;
+}
+
+AString M3UParser::MediaGroup::Media::makeURL(const char *baseURL) const {
+ AString out;
+ CHECK(MakeURL(baseURL, mURI.c_str(), &out));
+ return out;
+}
+
status_t M3UParser::parse(const void *_data, size_t size) {
int32_t lineNo = 0;
@@ -674,7 +691,7 @@
mItems.push();
Item *item = &mItems.editItemAt(mItems.size() - 1);
- CHECK(MakeURL(mBaseURI.c_str(), line.c_str(), &item->mURI));
+ item->mURI = line;
item->mMeta = itemMeta;
@@ -1186,9 +1203,7 @@
AString tmp(val, 1, val.size() - 2);
- if (!MakeURL(mBaseURI.c_str(), tmp.c_str(), &groupURI)) {
- ALOGI("Failed to make absolute URI from '%s'.", tmp.c_str());
- }
+ groupURI = tmp;
haveGroupURI = true;
}
diff --git a/media/libstagefright/httplive/M3UParser.h b/media/libstagefright/httplive/M3UParser.h
index fa648ed..c85335a 100644
--- a/media/libstagefright/httplive/M3UParser.h
+++ b/media/libstagefright/httplive/M3UParser.h
@@ -64,6 +64,7 @@
struct Item {
AString mURI;
sp<AMessage> mMeta;
+ AString makeURL(const char *baseURL) const;
};
status_t mInitCheck;
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 58d8b13..a0bfd06 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -328,12 +328,25 @@
}
void ID3::removeUnsynchronization() {
- for (size_t i = 0; i + 1 < mSize; ++i) {
- if (mData[i] == 0xff && mData[i + 1] == 0x00) {
- memmove(&mData[i + 1], &mData[i + 2], mSize - i - 2);
- --mSize;
+
+ // This file has "unsynchronization", so we have to replace occurrences
+ // of 0xff 0x00 with just 0xff in order to get the real data.
+
+ size_t writeOffset = 1;
+ for (size_t readOffset = 1; readOffset < mSize; ++readOffset) {
+ if (mData[readOffset - 1] == 0xff && mData[readOffset] == 0x00) {
+ continue;
}
+ // Only move data if there's actually something to move.
+ // This handles the special case of the data being only [0xff, 0x00]
+ // which should be converted to just 0xff if unsynchronization is on.
+ mData[writeOffset++] = mData[readOffset];
}
+
+ if (writeOffset < mSize) {
+ mSize = writeOffset;
+ }
+
}
static void WriteSyncsafeInteger(uint8_t *dst, size_t x) {
@@ -593,6 +606,9 @@
// UCS-2
// API wants number of characters, not number of bytes...
int len = n / 2;
+ if (len == 0) {
+ return;
+ }
const char16_t *framedata = (const char16_t *) (frameData + 1);
char16_t *framedatacopy = NULL;
if (*framedata == 0xfffe) {
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 015a148..0c2203a 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -686,6 +686,7 @@
CLOG_CONFIG(setPortMode, "%s(%d), port %d", asString(mode), mode, portIndex);
+ status_t err = OK;
switch (mode) {
case IOMX::kPortModeDynamicANWBuffer:
{
@@ -694,17 +695,19 @@
CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
"not setting port mode to %s(%d) on output",
asString(mode), mode);
- return StatusFromOMXError(OMX_ErrorUnsupportedIndex);
+ err = StatusFromOMXError(OMX_ErrorUnsupportedIndex);
+ break;
}
- status_t err = enableNativeBuffers_l(
+ err = enableNativeBuffers_l(
portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
if (err != OK) {
- return err;
+ break;
}
}
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
- return storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL);
+ err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL);
+ break;
}
case IOMX::kPortModeDynamicNativeHandle:
@@ -712,13 +715,15 @@
if (portIndex != kPortIndexInput) {
CLOG_ERROR(setPortMode, BAD_VALUE,
"%s(%d) mode is only supported on input port", asString(mode), mode);
- return BAD_VALUE;
+ err = BAD_VALUE;
+ break;
}
(void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
MetadataBufferType metaType = kMetadataBufferTypeNativeHandleSource;
- return storeMetaDataInBuffers_l(portIndex, OMX_TRUE, &metaType);
+ err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, &metaType);
+ break;
}
case IOMX::kPortModePresetSecureBuffer:
@@ -726,7 +731,8 @@
// Allow on both input and output.
(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
(void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
- return enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_TRUE);
+ err = enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_TRUE);
+ break;
}
case IOMX::kPortModePresetANWBuffer:
@@ -734,7 +740,8 @@
if (portIndex != kPortIndexOutput) {
CLOG_ERROR(setPortMode, BAD_VALUE,
"%s(%d) mode is only supported on output port", asString(mode), mode);
- return BAD_VALUE;
+ err = BAD_VALUE;
+ break;
}
// Check if we're simulating legacy mode with metadata mode,
@@ -743,7 +750,7 @@
if (storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL) == OK) {
CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
"metdata mode enabled successfully");
- return OK;
+ break;
}
CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
@@ -754,15 +761,15 @@
// Disable secure buffer and enable graphic buffer
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
- status_t err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
+ err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
if (err != OK) {
- return err;
+ break;
}
// Not running experiment, or metadata is not supported.
// Disable metadata mode and use legacy mode.
(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
- return OK;
+ break;
}
case IOMX::kPortModePresetByteBuffer:
@@ -771,15 +778,19 @@
(void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
(void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
(void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
- return OK;
- }
-
- default:
break;
}
- CLOG_ERROR(setPortMode, BAD_VALUE, "invalid port mode %d", mode);
- return BAD_VALUE;
+ default:
+ CLOG_ERROR(setPortMode, BAD_VALUE, "invalid port mode %d", mode);
+ err = BAD_VALUE;
+ break;
+ }
+
+ if (err == OK) {
+ mPortMode[portIndex] = mode;
+ }
+ return err;
}
status_t OMXNodeInstance::enableNativeBuffers_l(
@@ -1057,28 +1068,52 @@
}
switch (omxBuffer.mBufferType) {
- case OMXBuffer::kBufferTypePreset:
+ case OMXBuffer::kBufferTypePreset: {
+ if (mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer
+ && mPortMode[portIndex] != IOMX::kPortModeDynamicNativeHandle) {
+ break;
+ }
return useBuffer_l(portIndex, NULL, NULL, buffer);
+ }
- case OMXBuffer::kBufferTypeSharedMem:
+ case OMXBuffer::kBufferTypeSharedMem: {
+ if (mPortMode[portIndex] != IOMX::kPortModePresetByteBuffer
+ && mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer) {
+ break;
+ }
return useBuffer_l(portIndex, omxBuffer.mMem, NULL, buffer);
+ }
- case OMXBuffer::kBufferTypeANWBuffer:
+ case OMXBuffer::kBufferTypeANWBuffer: {
+ if (mPortMode[portIndex] != IOMX::kPortModePresetANWBuffer
+ && mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer) {
+ break;
+ }
return useGraphicBuffer_l(portIndex, omxBuffer.mGraphicBuffer, buffer);
+ }
case OMXBuffer::kBufferTypeHidlMemory: {
+ if (mPortMode[portIndex] != IOMX::kPortModePresetByteBuffer
+ && mPortMode[portIndex] != IOMX::kPortModeDynamicANWBuffer
+ && mPortMode[portIndex] != IOMX::kPortModeDynamicNativeHandle) {
+ break;
+ }
sp<IHidlMemory> hidlMemory = mapMemory(omxBuffer.mHidlMemory);
if (hidlMemory == nullptr) {
ALOGE("OMXNodeInstance useBuffer() failed to map memory");
return NO_MEMORY;
}
return useBuffer_l(portIndex, NULL, hidlMemory, buffer);
- }
+ }
default:
+ return BAD_VALUE;
break;
}
- return BAD_VALUE;
+ ALOGE("b/77486542 : bufferType = %d vs. portMode = %d",
+ omxBuffer.mBufferType, mPortMode[portIndex]);
+ android_errorWriteLog(0x534e4554, "77486542");
+ return INVALID_OPERATION;
}
status_t OMXNodeInstance::useBuffer_l(
@@ -1514,6 +1549,11 @@
android_errorWriteLog(0x534e4554, "35467458");
return BAD_VALUE;
}
+ if (mPortMode[portIndex] != IOMX::kPortModePresetSecureBuffer) {
+ ALOGE("b/77486542");
+ android_errorWriteLog(0x534e4554, "77486542");
+ return INVALID_OPERATION;
+ }
BufferMeta *buffer_meta = new BufferMeta(portIndex);
OMX_BUFFERHEADERTYPE *header;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index fcf9070..cdaffe7 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -385,6 +385,7 @@
mSamplingRate = 0;
mChannelMask = AUDIO_CHANNEL_NONE;
mFormat = AUDIO_FORMAT_INVALID;
+ memset(&mGain, 0, sizeof(struct audio_gain_config));
mGain.index = -1;
}
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index 2ef6234..c19cc35 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -49,9 +49,9 @@
virtual aaudio_result_t close() = 0;
- virtual aaudio_result_t registerStream(android::sp<AAudioServiceStreamBase> stream);
+ aaudio_result_t registerStream(android::sp<AAudioServiceStreamBase> stream);
- virtual aaudio_result_t unregisterStream(android::sp<AAudioServiceStreamBase> stream);
+ aaudio_result_t unregisterStream(android::sp<AAudioServiceStreamBase> stream);
virtual aaudio_result_t startStream(android::sp<AAudioServiceStreamBase> stream,
audio_port_handle_t *clientHandle) = 0;
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index ff0b037..d9b8766 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -104,6 +104,9 @@
goto error;
}
+ // This is not protected by a lock because the stream cannot be
+ // referenced until the service returns a handle to the client.
+ // So only one thread can open a stream.
mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService,
request,
sharingMode);
@@ -112,6 +115,9 @@
result = AAUDIO_ERROR_UNAVAILABLE;
goto error;
}
+ // Save a weak pointer that we will use to access the endpoint.
+ mServiceEndpointWeak = mServiceEndpoint;
+
mFramesPerBurst = mServiceEndpoint->getFramesPerBurst();
copyFrom(*mServiceEndpoint);
}
@@ -130,15 +136,19 @@
stop();
- if (mServiceEndpoint == nullptr) {
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
result = AAUDIO_ERROR_INVALID_STATE;
} else {
- mServiceEndpoint->unregisterStream(this);
- AAudioEndpointManager &mEndpointManager = AAudioEndpointManager::getInstance();
- mEndpointManager.closeEndpoint(mServiceEndpoint);
- mServiceEndpoint.clear();
+ endpoint->unregisterStream(this);
+ AAudioEndpointManager &endpointManager = AAudioEndpointManager::getInstance();
+ endpointManager.closeEndpoint(endpoint);
+
+ // AAudioService::closeStream() prevents two threads from closing at the same time.
+ mServiceEndpoint.clear(); // endpoint will hold the pointer until this method returns.
}
+
{
std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
stopTimestampThread();
@@ -152,7 +162,12 @@
aaudio_result_t AAudioServiceStreamBase::startDevice() {
mClientHandle = AUDIO_PORT_HANDLE_NONE;
- return mServiceEndpoint->startStream(this, &mClientHandle);
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ return endpoint->startStream(this, &mClientHandle);
}
/**
@@ -162,16 +177,11 @@
*/
aaudio_result_t AAudioServiceStreamBase::start() {
aaudio_result_t result = AAUDIO_OK;
+
if (isRunning()) {
return AAUDIO_OK;
}
- if (mServiceEndpoint == nullptr) {
- ALOGE("AAudioServiceStreamBase::start() missing endpoint");
- result = AAUDIO_ERROR_INVALID_STATE;
- goto error;
- }
-
// Start with fresh presentation timestamps.
mAtomicTimestamp.clear();
@@ -198,10 +208,6 @@
if (!isRunning()) {
return result;
}
- if (mServiceEndpoint == nullptr) {
- ALOGE("AAudioServiceStreamShared::pause() missing endpoint");
- return AAUDIO_ERROR_INVALID_STATE;
- }
// Send it now because the timestamp gets rounded up when stopStream() is called below.
// Also we don't need the timestamps while we are shutting down.
@@ -213,7 +219,12 @@
return result;
}
- result = mServiceEndpoint->stopStream(this, mClientHandle);
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ result = endpoint->stopStream(this, mClientHandle);
if (result != AAUDIO_OK) {
ALOGE("AAudioServiceStreamShared::pause() mServiceEndpoint returned %d", result);
disconnect(); // TODO should we return or pause Base first?
@@ -230,11 +241,6 @@
return result;
}
- if (mServiceEndpoint == nullptr) {
- ALOGE("AAudioServiceStreamShared::stop() missing endpoint");
- return AAUDIO_ERROR_INVALID_STATE;
- }
-
// Send it now because the timestamp gets rounded up when stopStream() is called below.
// Also we don't need the timestamps while we are shutting down.
sendCurrentTimestamp(); // warning - this calls a virtual function
@@ -244,8 +250,13 @@
return result;
}
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
// TODO wait for data to be played out
- result = mServiceEndpoint->stopStream(this, mClientHandle);
+ result = endpoint->stopStream(this, mClientHandle);
if (result != AAUDIO_OK) {
ALOGE("AAudioServiceStreamShared::stop() mServiceEndpoint returned %d", result);
disconnect();
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index af435b4..815b1cc 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -233,7 +233,12 @@
SimpleDoubleBuffer<Timestamp> mAtomicTimestamp;
android::AAudioService &mAudioService;
+
+ // The mServiceEndpoint variable can be accessed by multiple threads.
+ // So we access it by locally promoting a weak pointer to a smart pointer,
+ // which is thread-safe.
android::sp<AAudioServiceEndpoint> mServiceEndpoint;
+ android::wp<AAudioServiceEndpoint> mServiceEndpointWeak;
private:
aaudio_handle_t mHandle = -1;
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index 44ba1ca..2e7ff8b 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -70,14 +70,19 @@
return result;
}
- result = mServiceEndpoint->registerStream(keep);
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+
+ result = endpoint->registerStream(keep);
if (result != AAUDIO_OK) {
- goto error;
+ return result;
}
setState(AAUDIO_STREAM_STATE_OPEN);
-error:
return AAUDIO_OK;
}
@@ -122,21 +127,37 @@
aaudio_result_t AAudioServiceStreamMMAP::startClient(const android::AudioClient& client,
audio_port_handle_t *clientHandle) {
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
// Start the client on behalf of the application. Generate a new porthandle.
- aaudio_result_t result = mServiceEndpoint->startClient(client, clientHandle);
+ aaudio_result_t result = endpoint->startClient(client, clientHandle);
return result;
}
aaudio_result_t AAudioServiceStreamMMAP::stopClient(audio_port_handle_t clientHandle) {
- aaudio_result_t result = mServiceEndpoint->stopClient(clientHandle);
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ aaudio_result_t result = endpoint->stopClient(clientHandle);
return result;
}
// Get free-running DSP or DMA hardware position from the HAL.
aaudio_result_t AAudioServiceStreamMMAP::getFreeRunningPosition(int64_t *positionFrames,
int64_t *timeNanos) {
- sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP{
- static_cast<AAudioServiceEndpointMMAP *>(mServiceEndpoint.get())};
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP =
+ static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
+
aaudio_result_t result = serviceEndpointMMAP->getFreeRunningPosition(positionFrames, timeNanos);
if (result == AAUDIO_OK) {
Timestamp timestamp(*positionFrames, *timeNanos);
@@ -152,8 +173,15 @@
// Get timestamp that was written by getFreeRunningPosition()
aaudio_result_t AAudioServiceStreamMMAP::getHardwareTimestamp(int64_t *positionFrames,
int64_t *timeNanos) {
- sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP{
- static_cast<AAudioServiceEndpointMMAP *>(mServiceEndpoint.get())};
+
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP =
+ static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
+
// TODO Get presentation timestamp from the HAL
if (mAtomicTimestamp.isValid()) {
Timestamp timestamp = mAtomicTimestamp.read();
@@ -171,7 +199,12 @@
aaudio_result_t AAudioServiceStreamMMAP::getAudioDataDescription(
AudioEndpointParcelable &parcelable)
{
- sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP{
- static_cast<AAudioServiceEndpointMMAP *>(mServiceEndpoint.get())};
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ sp<AAudioServiceEndpointMMAP> serviceEndpointMMAP =
+ static_cast<AAudioServiceEndpointMMAP *>(endpoint.get());
return serviceEndpointMMAP->getDownDataDescription(parcelable);
}
diff --git a/services/oboeservice/AAudioServiceStreamShared.cpp b/services/oboeservice/AAudioServiceStreamShared.cpp
index 084f996..f55c40d 100644
--- a/services/oboeservice/AAudioServiceStreamShared.cpp
+++ b/services/oboeservice/AAudioServiceStreamShared.cpp
@@ -128,6 +128,11 @@
const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration();
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ result = AAUDIO_ERROR_INVALID_STATE;
+ goto error;
+ }
// Is the request compatible with the shared endpoint?
setFormat(configurationInput.getFormat());
@@ -141,20 +146,20 @@
setSampleRate(configurationInput.getSampleRate());
if (getSampleRate() == AAUDIO_UNSPECIFIED) {
- setSampleRate(mServiceEndpoint->getSampleRate());
- } else if (getSampleRate() != mServiceEndpoint->getSampleRate()) {
+ setSampleRate(endpoint->getSampleRate());
+ } else if (getSampleRate() != endpoint->getSampleRate()) {
ALOGE("AAudioServiceStreamShared::open() mSampleRate = %d, need %d",
- getSampleRate(), mServiceEndpoint->getSampleRate());
+ getSampleRate(), endpoint->getSampleRate());
result = AAUDIO_ERROR_INVALID_RATE;
goto error;
}
setSamplesPerFrame(configurationInput.getSamplesPerFrame());
if (getSamplesPerFrame() == AAUDIO_UNSPECIFIED) {
- setSamplesPerFrame(mServiceEndpoint->getSamplesPerFrame());
- } else if (getSamplesPerFrame() != mServiceEndpoint->getSamplesPerFrame()) {
+ setSamplesPerFrame(endpoint->getSamplesPerFrame());
+ } else if (getSamplesPerFrame() != endpoint->getSamplesPerFrame()) {
ALOGE("AAudioServiceStreamShared::open() mSamplesPerFrame = %d, need %d",
- getSamplesPerFrame(), mServiceEndpoint->getSamplesPerFrame());
+ getSamplesPerFrame(), endpoint->getSamplesPerFrame());
result = AAUDIO_ERROR_OUT_OF_RANGE;
goto error;
}
@@ -181,9 +186,9 @@
}
ALOGD("AAudioServiceStreamShared::open() actual rate = %d, channels = %d, deviceId = %d",
- getSampleRate(), getSamplesPerFrame(), mServiceEndpoint->getDeviceId());
+ getSampleRate(), getSamplesPerFrame(), endpoint->getDeviceId());
- result = mServiceEndpoint->registerStream(keep);
+ result = endpoint->registerStream(keep);
if (result != AAUDIO_OK) {
goto error;
}
@@ -250,7 +255,13 @@
int64_t *timeNanos) {
int64_t position = 0;
- aaudio_result_t result = mServiceEndpoint->getTimestamp(&position, timeNanos);
+ sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote();
+ if (endpoint == nullptr) {
+ ALOGE("%s() has no endpoint", __func__);
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+
+ aaudio_result_t result = endpoint->getTimestamp(&position, timeNanos);
if (result == AAUDIO_OK) {
int64_t offset = mTimestampPositionOffset.load();
// TODO, do not go below starting value