Merge "Add audioserver to wakelock group." am: 9f877cf5c9 am: b1fc5bfcfb
am: 9f448e0fb1
Change-Id: I2109113b136e56e222aaf8d6a359190e26dc2600
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 61fc897..2c088e6 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -579,12 +579,12 @@
break;
}
+ CHECK(buffer != NULL);
+
if (buffer->range_length() > 0) {
break;
}
- CHECK(buffer != NULL);
-
buffer->release();
buffer = NULL;
}
diff --git a/media/OWNERS b/media/OWNERS
index 1f687a2..1e2d123 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -2,8 +2,10 @@
dwkang@google.com
elaurent@google.com
essick@google.com
+gkasten@google.com
hkuang@google.com
hunga@google.com
+jiabin@google.com
jmtrivi@google.com
krocard@google.com
lajos@google.com
diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc
index 1f2e82f..f1e815b 100644
--- a/media/audioserver/audioserver.rc
+++ b/media/audioserver/audioserver.rc
@@ -7,6 +7,7 @@
ioprio rt 4
writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
onrestart restart vendor.audio-hal-2-0
+ onrestart restart vendor.audio-hal-4-0-msd
# Keep the original service name for backward compatibility when upgrading
# O-MR1 devices with framework-only.
onrestart restart audio-hal-2-0
diff --git a/media/libaudioclient/include/media/AudioParameter.h b/media/libaudioclient/include/media/AudioParameter.h
index 967d895..24837e3 100644
--- a/media/libaudioclient/include/media/AudioParameter.h
+++ b/media/libaudioclient/include/media/AudioParameter.h
@@ -64,6 +64,9 @@
static const char * const keyPresentationId;
static const char * const keyProgramId;
+ // keyAudioLanguagePreferred: Preferred audio language
+ static const char * const keyAudioLanguagePreferred;
+
// keyStreamConnect / Disconnect: value is an int in audio_devices_t
static const char * const keyStreamConnect;
static const char * const keyStreamDisconnect;
diff --git a/media/libaudiohal/2.0/DevicesFactoryHalHidl.cpp b/media/libaudiohal/2.0/DevicesFactoryHalHidl.cpp
index 5b33592..31da263 100644
--- a/media/libaudiohal/2.0/DevicesFactoryHalHidl.cpp
+++ b/media/libaudiohal/2.0/DevicesFactoryHalHidl.cpp
@@ -43,9 +43,6 @@
ALOGE("Failed to obtain IDevicesFactory service, terminating process.");
exit(1);
}
- // The MSD factory is optional
- mDevicesFactoryMsd = IDevicesFactory::getService(AUDIO_HAL_SERVICE_NAME_MSD);
- // TODO: Register death handler, and add 'restart' directive to audioserver.rc
}
DevicesFactoryHalHidl::~DevicesFactoryHalHidl() {
diff --git a/media/libaudiohal/2.0/DevicesFactoryHalHidl.h b/media/libaudiohal/2.0/DevicesFactoryHalHidl.h
index 0748849..e2f1ad1 100644
--- a/media/libaudiohal/2.0/DevicesFactoryHalHidl.h
+++ b/media/libaudiohal/2.0/DevicesFactoryHalHidl.h
@@ -39,7 +39,6 @@
friend class DevicesFactoryHalHybrid;
sp<IDevicesFactory> mDevicesFactory;
- sp<IDevicesFactory> mDevicesFactoryMsd;
static status_t nameFromHal(const char *name, IDevicesFactory::Device *device);
diff --git a/media/libaudiohal/4.0/DevicesFactoryHalHidl.cpp b/media/libaudiohal/4.0/DevicesFactoryHalHidl.cpp
index c83194e..c566728 100644
--- a/media/libaudiohal/4.0/DevicesFactoryHalHidl.cpp
+++ b/media/libaudiohal/4.0/DevicesFactoryHalHidl.cpp
@@ -15,6 +15,7 @@
*/
#include <string.h>
+#include <vector>
#define LOG_TAG "DevicesFactoryHalHidl"
//#define LOG_NDEBUG 0
@@ -35,40 +36,48 @@
namespace V4_0 {
DevicesFactoryHalHidl::DevicesFactoryHalHidl() {
- mDevicesFactory = IDevicesFactory::getService();
- if (mDevicesFactory != 0) {
- // It is assumed that DevicesFactory is owned by AudioFlinger
- // and thus have the same lifespan.
- mDevicesFactory->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
- } else {
- ALOGE("Failed to obtain IDevicesFactory service, terminating process.");
+ sp<IDevicesFactory> defaultFactory{IDevicesFactory::getService()};
+ if (!defaultFactory) {
+ ALOGE("Failed to obtain IDevicesFactory/default service, terminating process.");
exit(1);
}
+ mDeviceFactories.push_back(defaultFactory);
// The MSD factory is optional
- mDevicesFactoryMsd = IDevicesFactory::getService(AUDIO_HAL_SERVICE_NAME_MSD);
- // TODO: Register death handler, and add 'restart' directive to audioserver.rc
-}
-
-DevicesFactoryHalHidl::~DevicesFactoryHalHidl() {
+ sp<IDevicesFactory> msdFactory{IDevicesFactory::getService(AUDIO_HAL_SERVICE_NAME_MSD)};
+ if (msdFactory) {
+ mDeviceFactories.push_back(msdFactory);
+ }
+ for (const auto& factory : mDeviceFactories) {
+ // It is assumed that the DevicesFactoryHalInterface instance is owned
+ // by AudioFlinger and thus have the same lifespan.
+ factory->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
+ }
}
status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
- if (mDevicesFactory == 0) return NO_INIT;
+ if (mDeviceFactories.empty()) return NO_INIT;
Result retval = Result::NOT_INITIALIZED;
- Return<void> ret = mDevicesFactory->openDevice(
- name,
- [&](Result r, const sp<IDevice>& result) {
- retval = r;
- if (retval == Result::OK) {
- *device = new DeviceHalHidl(result);
- }
- });
- if (ret.isOk()) {
- if (retval == Result::OK) return OK;
- else if (retval == Result::INVALID_ARGUMENTS) return BAD_VALUE;
- else return NO_INIT;
+ for (const auto& factory : mDeviceFactories) {
+ Return<void> ret = factory->openDevice(
+ name,
+ [&](Result r, const sp<IDevice>& result) {
+ retval = r;
+ if (retval == Result::OK) {
+ *device = new DeviceHalHidl(result);
+ }
+ });
+ if (!ret.isOk()) return FAILED_TRANSACTION;
+ switch (retval) {
+ // Device was found and was initialized successfully.
+ case Result::OK: return OK;
+ // Device was found but failed to initalize.
+ case Result::NOT_INITIALIZED: return NO_INIT;
+ // Otherwise continue iterating.
+ default: ;
+ }
}
- return FAILED_TRANSACTION;
+ ALOGW("The specified device name is not recognized: \"%s\"", name);
+ return BAD_VALUE;
}
} // namespace V4_0
diff --git a/media/libaudiohal/4.0/DevicesFactoryHalHidl.h b/media/libaudiohal/4.0/DevicesFactoryHalHidl.h
index 114889b..c97178f 100644
--- a/media/libaudiohal/4.0/DevicesFactoryHalHidl.h
+++ b/media/libaudiohal/4.0/DevicesFactoryHalHidl.h
@@ -39,13 +39,12 @@
private:
friend class DevicesFactoryHalHybrid;
- sp<IDevicesFactory> mDevicesFactory;
- sp<IDevicesFactory> mDevicesFactoryMsd;
+ std::vector<sp<IDevicesFactory>> mDeviceFactories;
// Can not be constructed directly by clients.
DevicesFactoryHalHidl();
- virtual ~DevicesFactoryHalHidl();
+ virtual ~DevicesFactoryHalHidl() = default;
};
} // namespace V4_0
diff --git a/media/libmedia/AudioParameter.cpp b/media/libmedia/AudioParameter.cpp
index 034f7c2..1c95e27 100644
--- a/media/libmedia/AudioParameter.cpp
+++ b/media/libmedia/AudioParameter.cpp
@@ -36,6 +36,8 @@
const char * const AudioParameter::keyHwAvSync = AUDIO_PARAMETER_HW_AV_SYNC;
const char * const AudioParameter::keyPresentationId = AUDIO_PARAMETER_STREAM_PRESENTATION_ID;
const char * const AudioParameter::keyProgramId = AUDIO_PARAMETER_STREAM_PROGRAM_ID;
+const char * const AudioParameter::keyAudioLanguagePreferred =
+ AUDIO_PARAMETER_KEY_AUDIO_LANGUAGE_PREFERRED;
const char * const AudioParameter::keyMonoOutput = AUDIO_PARAMETER_MONO_OUTPUT;
const char * const AudioParameter::keyStreamHwAvSync = AUDIO_PARAMETER_STREAM_HW_AV_SYNC;
const char * const AudioParameter::keyStreamConnect = AUDIO_PARAMETER_DEVICE_CONNECT;
diff --git a/media/libmedia/include/media/PatchBuilder.h b/media/libmedia/include/media/PatchBuilder.h
new file mode 100644
index 0000000..f2722a6
--- /dev/null
+++ b/media/libmedia/include/media/PatchBuilder.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_PATCH_BUILDER_H
+#define ANDROID_PATCH_BUILDER_H
+
+#include <functional>
+#include <utility>
+
+#include <system/audio.h>
+#include <utils/StrongPointer.h>
+
+// This is a header-only utility.
+
+namespace android {
+
+class PatchBuilder {
+ public:
+ using mix_usecase_t = decltype(audio_port_config_mix_ext::usecase);
+
+ PatchBuilder() = default;
+
+ // All existing methods operating on audio patches take a pointer to const.
+ // It's OK to construct a temporary PatchBuilder while preparing a parameter
+ // to such a function because the Builder will be kept alive until the code
+ // execution reaches the function call statement semicolon.
+ const struct audio_patch* patch() const { return &mPatch; }
+
+ template<typename T, typename... S>
+ PatchBuilder& addSink(T&& t, S&&... s) {
+ sinks().add(std::forward<T>(t), std::forward<S>(s)...);
+ return *this;
+ }
+ // Explicit type of the second parameter allows clients to provide the struct inline.
+ template<typename T>
+ PatchBuilder& addSink(T&& t, const mix_usecase_t& update) {
+ sinks().add(std::forward<T>(t), update);
+ return *this;
+ }
+ template<typename T, typename... S>
+ PatchBuilder& addSource(T&& t, S&&... s) {
+ sources().add(std::forward<T>(t), std::forward<S>(s)...);
+ return *this;
+ }
+ // Explicit type of the second parameter allows clients to provide the struct inline.
+ template<typename T>
+ PatchBuilder& addSource(T&& t, const mix_usecase_t& update) {
+ sources().add(std::forward<T>(t), update);
+ return *this;
+ }
+
+ private:
+ struct PortCfgs {
+ PortCfgs(unsigned int *countPtr, struct audio_port_config *portCfgs)
+ : mCountPtr(countPtr), mPortCfgs(portCfgs) {}
+ audio_port_config& add(const audio_port_config& portCfg) {
+ return *advance() = portCfg;
+ }
+ template<typename T>
+ audio_port_config& add(const sp<T>& entity) {
+ audio_port_config* added = advance();
+ entity->toAudioPortConfig(added);
+ return *added;
+ }
+ template<typename T>
+ void add(const sp<T>& entity, const mix_usecase_t& usecaseUpdate) {
+ add(entity).ext.mix.usecase = usecaseUpdate;
+ }
+ template<typename T>
+ void add(const sp<T>& entity,
+ std::function<mix_usecase_t(const mix_usecase_t&)> usecaseUpdater) {
+ mix_usecase_t* usecase = &add(entity).ext.mix.usecase;
+ *usecase = usecaseUpdater(*usecase);
+ }
+ struct audio_port_config* advance() {
+ return &mPortCfgs[(*mCountPtr)++];
+ }
+ unsigned int *mCountPtr;
+ struct audio_port_config *mPortCfgs;
+ };
+
+ PortCfgs sinks() { return PortCfgs(&mPatch.num_sinks, mPatch.sinks); }
+ PortCfgs sources() { return PortCfgs(&mPatch.num_sources, mPatch.sources); }
+
+ struct audio_patch mPatch = {};
+};
+
+} // namespace android
+
+#endif // ANDROID_PATCH_BUILDER_H
diff --git a/media/libmediaextractor/MediaBuffer.cpp b/media/libmediaextractor/MediaBuffer.cpp
index 39f8d6e..d197b3f 100644
--- a/media/libmediaextractor/MediaBuffer.cpp
+++ b/media/libmediaextractor/MediaBuffer.cpp
@@ -39,7 +39,7 @@
mRangeOffset(0),
mRangeLength(size),
mOwnsData(false),
- mMetaData(new MetaData),
+ mMetaData(new MetaDataBase),
mOriginal(NULL) {
}
@@ -51,7 +51,7 @@
mRangeOffset(0),
mRangeLength(size),
mOwnsData(true),
- mMetaData(new MetaData),
+ mMetaData(new MetaDataBase),
mOriginal(NULL) {
if (size < kSharedMemThreshold
|| std::atomic_load_explicit(&mUseSharedMemory, std::memory_order_seq_cst) == 0) {
@@ -84,7 +84,7 @@
mRangeLength(mSize),
mBuffer(buffer),
mOwnsData(false),
- mMetaData(new MetaData),
+ mMetaData(new MetaDataBase),
mOriginal(NULL) {
}
@@ -96,7 +96,7 @@
return;
}
- int prevCount = __sync_fetch_and_sub(&mRefCount, 1);
+ int prevCount = mRefCount.fetch_sub(1);
if (prevCount == 1) {
if (mObserver == NULL) {
delete this;
@@ -110,13 +110,13 @@
void MediaBuffer::claim() {
CHECK(mObserver != NULL);
- CHECK_EQ(mRefCount, 1);
+ CHECK_EQ(mRefCount.load(std::memory_order_relaxed), 1);
- mRefCount = 0;
+ mRefCount.store(0, std::memory_order_relaxed);
}
void MediaBuffer::add_ref() {
- (void) __sync_fetch_and_add(&mRefCount, 1);
+ (void) mRefCount.fetch_add(1);
}
void *MediaBuffer::data() const {
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h b/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
index f944d51..5a25965 100644
--- a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
+++ b/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
@@ -86,12 +86,14 @@
virtual MediaBufferBase *clone();
// sum of localRefcount() and remoteRefcount()
+ // Result should be treated as approximate unless the result precludes concurrent accesses.
virtual int refcount() const {
return localRefcount() + remoteRefcount();
}
+ // Result should be treated as approximate unless the result precludes concurrent accesses.
virtual int localRefcount() const {
- return mRefCount;
+ return mRefCount.load(std::memory_order_relaxed);
}
virtual int remoteRefcount() const {
@@ -146,7 +148,7 @@
void claim();
MediaBufferObserver *mObserver;
- int mRefCount;
+ std::atomic<int> mRefCount;
void *mData;
size_t mSize, mRangeOffset, mRangeLength;
diff --git a/media/libstagefright/codecs/xaacdec/Android.bp b/media/libstagefright/codecs/xaacdec/Android.bp
new file mode 100644
index 0000000..465951b
--- /dev/null
+++ b/media/libstagefright/codecs/xaacdec/Android.bp
@@ -0,0 +1,38 @@
+cc_library_shared {
+ name: "libstagefright_soft_xaacdec",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+
+ srcs: [
+ "SoftXAAC.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/av/media/libstagefright/include",
+ "frameworks/native/include/media/openmax",
+ ],
+
+ cflags: [
+ "-Werror",
+ ],
+
+ sanitize: {
+ // integer_overflow: true,
+ misc_undefined: [ "signed-integer-overflow", "unsigned-integer-overflow", ],
+ cfi: true,
+ },
+
+ static_libs: ["libxaacdec"],
+
+ shared_libs: [
+ "libstagefright_omx",
+ "libstagefright_foundation",
+ "libutils",
+ "libcutils",
+ "liblog",
+ ],
+
+ compile_multilib: "32",
+}
diff --git a/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp b/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
new file mode 100644
index 0000000..376755b
--- /dev/null
+++ b/media/libstagefright/codecs/xaacdec/SoftXAAC.cpp
@@ -0,0 +1,1329 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "SoftXAAC"
+#include <utils/Log.h>
+
+#include "SoftXAAC.h"
+
+#include <OMX_AudioExt.h>
+#include <OMX_IndexExt.h>
+#include <cutils/properties.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/misc.h>
+#include <math.h>
+
+#define DRC_DEFAULT_MOBILE_REF_LEVEL 64 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_CUT 127 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1 /* switch for heavy compression for mobile conf */
+#define DRC_DEFAULT_MOBILE_ENC_LEVEL (-1) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
+
+#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level"
+#define PROP_DRC_OVERRIDE_CUT "aac_drc_cut"
+#define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost"
+#define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy"
+#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
+#define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */
+
+namespace android {
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+static const OMX_U32 kSupportedProfiles[] = {
+ OMX_AUDIO_AACObjectLC,
+ OMX_AUDIO_AACObjectHE,
+ OMX_AUDIO_AACObjectHE_PS,
+ OMX_AUDIO_AACObjectLD,
+ OMX_AUDIO_AACObjectELD,
+};
+
+SoftXAAC::SoftXAAC(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ mIsADTS(false),
+ mInputBufferCount(0),
+ mOutputBufferCount(0),
+ mSignalledError(false),
+ mLastInHeader(NULL),
+ mPrevTimestamp(0),
+ mCurrentTimestamp(0),
+ mOutputPortSettingsChange(NONE),
+ mXheaacCodecHandle(NULL),
+ mInputBufferSize(0),
+ mOutputFrameLength(1024),
+ mInputBuffer(NULL),
+ mOutputBuffer(NULL),
+ mSampFreq(0),
+ mNumChannels(0),
+ mPcmWdSz(0),
+ mChannelMask(0),
+ mIsCodecInitialized(false),
+ mIsCodecConfigFlushRequired(false)
+{
+ initPorts();
+ CHECK_EQ(initDecoder(), (status_t)OK);
+}
+
+SoftXAAC::~SoftXAAC() {
+ int errCode = deInitXAACDecoder();
+ if (0 != errCode) {
+ ALOGE("deInitXAACDecoder() failed %d",errCode);
+ }
+
+ mIsCodecInitialized = false;
+ mIsCodecConfigFlushRequired = false;
+}
+
+void SoftXAAC::initPorts() {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = 0;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = kNumInputBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 8192;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/aac");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
+
+ addPort(def);
+
+ def.nPortIndex = 1;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = kNumOutputBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 4096 * MAX_CHANNEL_COUNT;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+
+ addPort(def);
+}
+
+status_t SoftXAAC::initDecoder() {
+ status_t status = UNKNOWN_ERROR;
+
+ unsigned int ui_drc_val;
+ IA_ERRORCODE err_code = IA_NO_ERROR;
+ initXAACDecoder();
+ if (NULL == mXheaacCodecHandle) {
+ ALOGE("AAC decoder is null. initXAACDecoder Failed");
+ } else {
+ status = OK;
+ }
+
+ mEndOfInput = false;
+ mEndOfOutput = false;
+
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL))
+ {
+ ui_drc_val = atoi(value);
+ ALOGV("AAC decoder using desired DRC target reference level of %d instead of %d",ui_drc_val,
+ DRC_DEFAULT_MOBILE_REF_LEVEL);
+ }
+ else
+ {
+ ui_drc_val= DRC_DEFAULT_MOBILE_REF_LEVEL;
+ }
+
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL,
+ &ui_drc_val);
+
+ ALOGV("Error code returned after DRC Target level set_config is %d", err_code);
+ ALOGV("Setting IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL with value %d", ui_drc_val);
+
+ if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL))
+ {
+ ui_drc_val = atoi(value);
+ ALOGV("AAC decoder using desired DRC attenuation factor of %d instead of %d", ui_drc_val,
+ DRC_DEFAULT_MOBILE_DRC_CUT);
+ }
+ else
+ {
+ ui_drc_val=DRC_DEFAULT_MOBILE_DRC_CUT;
+ }
+
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT,
+ &ui_drc_val);
+ ALOGV("Error code returned after DRC cut factor set_config is %d", err_code);
+ ALOGV("Setting IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT with value %d", ui_drc_val);
+
+ if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL))
+ {
+ ui_drc_val = atoi(value);
+ ALOGV("AAC decoder using desired DRC boost factor of %d instead of %d", ui_drc_val,
+ DRC_DEFAULT_MOBILE_DRC_BOOST);
+ }
+ else
+ {
+ ui_drc_val = DRC_DEFAULT_MOBILE_DRC_BOOST;
+ }
+
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST,
+ &ui_drc_val);
+ ALOGV("Error code returned after DRC boost factor set_config is %d", err_code);
+ ALOGV("Setting DRC_DEFAULT_MOBILE_DRC_BOOST with value %d", ui_drc_val);
+
+ if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL))
+ {
+ ui_drc_val = atoi(value);
+ ALOGV("AAC decoder using desired DRC boost factor of %d instead of %d", ui_drc_val,
+ DRC_DEFAULT_MOBILE_DRC_HEAVY);
+ }
+ else
+ {
+ ui_drc_val = DRC_DEFAULT_MOBILE_DRC_HEAVY;
+ }
+
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP,
+ &ui_drc_val);
+ ALOGV("Error code returned after DRC heavy set_config is %d", err_code);
+ ALOGV("Setting DRC_DEFAULT_MOBILE_DRC_HEAVY with value %d", ui_drc_val);
+
+ return status;
+}
+
+OMX_ERRORTYPE SoftXAAC::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+
+ switch ((OMX_U32) index) {
+
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ formatParams->eEncoding =
+ (formatParams->nPortIndex == 0)
+ ? OMX_AUDIO_CodingAAC : OMX_AUDIO_CodingPCM;
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioAac:
+ {
+ OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
+ (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
+
+ if (!isValidOMXParam(aacParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (aacParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ aacParams->nBitRate = 0;
+ aacParams->nAudioBandWidth = 0;
+ aacParams->nAACtools = 0;
+ aacParams->nAACERtools = 0;
+ aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
+
+ aacParams->eAACStreamFormat =
+ mIsADTS
+ ? OMX_AUDIO_AACStreamFormatMP4ADTS
+ : OMX_AUDIO_AACStreamFormatMP4FF;
+
+ aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
+
+ if (!isConfigured()) {
+ aacParams->nChannels = 1;
+ aacParams->nSampleRate = 44100;
+ aacParams->nFrameLength = 0;
+ } else {
+ aacParams->nChannels = mNumChannels;
+ aacParams->nSampleRate = mSampFreq;
+ aacParams->nFrameLength = mOutputFrameLength;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (!isValidOMXParam(pcmParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (pcmParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ pcmParams->eNumData = OMX_NumericalDataSigned;
+ pcmParams->eEndian = OMX_EndianBig;
+ pcmParams->bInterleaved = OMX_TRUE;
+ pcmParams->nBitPerSample = 16;
+ pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+ pcmParams->eChannelMapping[2] = OMX_AUDIO_ChannelCF;
+ pcmParams->eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
+ pcmParams->eChannelMapping[4] = OMX_AUDIO_ChannelLS;
+ pcmParams->eChannelMapping[5] = OMX_AUDIO_ChannelRS;
+
+ if (!isConfigured()) {
+ pcmParams->nChannels = 1;
+ pcmParams->nSamplingRate = 44100;
+ } else {
+ pcmParams->nChannels = mNumChannels;
+ pcmParams->nSamplingRate = mSampFreq;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioProfileQuerySupported:
+ {
+ OMX_AUDIO_PARAM_ANDROID_PROFILETYPE *profileParams =
+ (OMX_AUDIO_PARAM_ANDROID_PROFILETYPE *)params;
+
+ if (!isValidOMXParam(profileParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (profileParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (profileParams->nProfileIndex >= NELEM(kSupportedProfiles)) {
+ return OMX_ErrorNoMore;
+ }
+
+ profileParams->eProfile =
+ kSupportedProfiles[profileParams->nProfileIndex];
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftXAAC::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+
+ switch ((int)index) {
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (!isValidOMXParam(roleParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (strncmp((const char *)roleParams->cRole,
+ "audio_decoder.aac",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPortFormat:
+ {
+ const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if ((formatParams->nPortIndex == 0
+ && formatParams->eEncoding != OMX_AUDIO_CodingAAC)
+ || (formatParams->nPortIndex == 1
+ && formatParams->eEncoding != OMX_AUDIO_CodingPCM)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioAac:
+ {
+ const OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
+ (const OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
+
+ if (!isValidOMXParam(aacParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (aacParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) {
+ mIsADTS = false;
+ } else if (aacParams->eAACStreamFormat
+ == OMX_AUDIO_AACStreamFormatMP4ADTS) {
+ mIsADTS = true;
+ } else {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioAndroidAacPresentation:
+ {
+ const OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE *aacPresParams =
+ (const OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE *)params;
+
+ if (!isValidOMXParam(aacPresParams)) {
+ ALOGE("set OMX_ErrorBadParameter");
+ return OMX_ErrorBadParameter;
+ }
+
+ // for the following parameters of the OMX_AUDIO_PARAM_AACPROFILETYPE structure,
+ // a value of -1 implies the parameter is not set by the application:
+ // nMaxOutputChannels -1 by default
+ // nDrcCut uses default platform properties, see initDecoder()
+ // nDrcBoost idem
+ // nHeavyCompression idem
+ // nTargetReferenceLevel idem
+ // nEncodedTargetLevel idem
+ if (aacPresParams->nMaxOutputChannels >= 0) {
+ int max;
+ if (aacPresParams->nMaxOutputChannels >= 8) { max = 8; }
+ else if (aacPresParams->nMaxOutputChannels >= 6) { max = 6; }
+ else if (aacPresParams->nMaxOutputChannels >= 2) { max = 2; }
+ else {
+ // -1 or 0: disable downmix, 1: mono
+ max = aacPresParams->nMaxOutputChannels;
+ }
+ }
+ /* Apply DRC Changes */
+ setXAACDRCInfo(aacPresParams->nDrcCut,
+ aacPresParams->nDrcBoost,
+ aacPresParams->nTargetReferenceLevel,
+ aacPresParams->nHeavyCompression);
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (!isValidOMXParam(pcmParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (pcmParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+bool SoftXAAC::isConfigured() const {
+ return mInputBufferCount > 0;
+}
+
+void SoftXAAC::onQueueFilled(OMX_U32 /* portIndex */) {
+ if (mSignalledError || mOutputPortSettingsChange != NONE) {
+ ALOGE("onQueueFilled do not process %d %d",mSignalledError,mOutputPortSettingsChange);
+ return;
+ }
+
+ uint8_t* inBuffer = NULL;
+ uint32_t inBufferLength = 0;
+
+ List<BufferInfo *> &inQueue = getPortQueue(0);
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+
+ signed int numOutBytes = 0;
+
+ /* If decoder call fails in between, then mOutputFrameLength is used */
+ /* Decoded output for AAC is 1024/2048 samples / channel */
+ /* TODO: For USAC mOutputFrameLength can go up to 4096 */
+ /* Note: entire buffer logic to save and retrieve assumes 2 bytes per*/
+ /* sample currently */
+ if (mIsCodecInitialized) {
+ numOutBytes = mOutputFrameLength * (mPcmWdSz/8) * mNumChannels;
+ if ((mPcmWdSz/8) != 2) {
+ ALOGE("XAAC assumes 2 bytes per sample! mPcmWdSz %d",mPcmWdSz);
+ }
+ }
+
+ while ((!inQueue.empty() || mEndOfInput) && !outQueue.empty()) {
+ if (!inQueue.empty()) {
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ mEndOfInput = (inHeader->nFlags & OMX_BUFFERFLAG_EOS) != 0;
+
+ if (mInputBufferCount == 0 && !(inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
+ ALOGE("first buffer should have OMX_BUFFERFLAG_CODECCONFIG set");
+ inHeader->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
+ }
+ if ((inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != 0) {
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ inBuffer = inHeader->pBuffer + inHeader->nOffset;
+ inBufferLength = inHeader->nFilledLen;
+
+ /* GA header configuration sent to Decoder! */
+ int err_code = configXAACDecoder(inBuffer,inBufferLength);
+ if (0 != err_code) {
+ ALOGW("configXAACDecoder err_code = %d", err_code);
+ mSignalledError = true;
+ notify(OMX_EventError, OMX_ErrorUndefined, err_code, NULL);
+ return;
+ }
+ mInputBufferCount++;
+ mOutputBufferCount++; // fake increase of outputBufferCount to keep the counters aligned
+
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ mLastInHeader = NULL;
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+
+ // Only send out port settings changed event if both sample rate
+ // and mNumChannels are valid.
+ if (mSampFreq && mNumChannels && !mIsCodecConfigFlushRequired) {
+ ALOGV("Configuring decoder: %d Hz, %d channels", mSampFreq, mNumChannels);
+ notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+ mOutputPortSettingsChange = AWAITING_DISABLED;
+ }
+
+ return;
+ }
+
+ if (inHeader->nFilledLen == 0) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ mLastInHeader = NULL;
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ continue;
+ }
+
+ // Restore Offset and Length for Port reconfig case
+ size_t tempOffset = inHeader->nOffset;
+ size_t tempFilledLen = inHeader->nFilledLen;
+ if (mIsADTS) {
+ size_t adtsHeaderSize = 0;
+ // skip 30 bits, aac_frame_length follows.
+ // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
+
+ const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
+
+ bool signalError = false;
+ if (inHeader->nFilledLen < 7) {
+ ALOGE("Audio data too short to contain even the ADTS header. "
+ "Got %d bytes.", inHeader->nFilledLen);
+ hexdump(adtsHeader, inHeader->nFilledLen);
+ signalError = true;
+ } else {
+ bool protectionAbsent = (adtsHeader[1] & 1);
+
+ unsigned aac_frame_length =
+ ((adtsHeader[3] & 3) << 11)
+ | (adtsHeader[4] << 3)
+ | (adtsHeader[5] >> 5);
+
+ if (inHeader->nFilledLen < aac_frame_length) {
+ ALOGE("Not enough audio data for the complete frame. "
+ "Got %d bytes, frame size according to the ADTS "
+ "header is %u bytes.",
+ inHeader->nFilledLen, aac_frame_length);
+ hexdump(adtsHeader, inHeader->nFilledLen);
+ signalError = true;
+ } else {
+ adtsHeaderSize = (protectionAbsent ? 7 : 9);
+ if (aac_frame_length < adtsHeaderSize) {
+ signalError = true;
+ } else {
+ inBuffer = (uint8_t *)adtsHeader + adtsHeaderSize;
+ inBufferLength = aac_frame_length - adtsHeaderSize;
+
+ inHeader->nOffset += adtsHeaderSize;
+ inHeader->nFilledLen -= adtsHeaderSize;
+ }
+ }
+ }
+
+ if (signalError) {
+ mSignalledError = true;
+ notify(OMX_EventError, OMX_ErrorStreamCorrupt, ERROR_MALFORMED, NULL);
+ return;
+ }
+
+ // insert buffer size and time stamp
+ if (mLastInHeader != inHeader) {
+ mCurrentTimestamp = inHeader->nTimeStamp;
+ mLastInHeader = inHeader;
+ } else {
+ mCurrentTimestamp = mPrevTimestamp +
+ mOutputFrameLength * 1000000ll / mSampFreq;
+ }
+ } else {
+ inBuffer = inHeader->pBuffer + inHeader->nOffset;
+ inBufferLength = inHeader->nFilledLen;
+ mLastInHeader = inHeader;
+ mCurrentTimestamp = inHeader->nTimeStamp;
+ }
+
+ int numLoops = 0;
+ signed int prevSampleRate = mSampFreq;
+ signed int prevNumChannels = mNumChannels;
+
+ /* XAAC decoder expects first frame to be fed via configXAACDecoder API */
+ /* which should initialize the codec. Once this state is reached, call the */
+ /* decodeXAACStream API with same frame to decode! */
+ if (!mIsCodecInitialized) {
+ int err_code = configXAACDecoder(inBuffer,inBufferLength);
+ if (0 != err_code) {
+ ALOGW("configXAACDecoder Failed 2 err_code = %d", err_code);
+ mSignalledError = true;
+ notify(OMX_EventError, OMX_ErrorUndefined, err_code, NULL);
+ return;
+ }
+ mIsCodecConfigFlushRequired = true;
+ }
+
+ if (!mSampFreq || !mNumChannels) {
+ if ((mInputBufferCount > 2) && (mOutputBufferCount <= 1)) {
+ ALOGW("Invalid AAC stream");
+ ALOGW("mSampFreq %d mNumChannels %d ",mSampFreq,mNumChannels);
+ mSignalledError = true;
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ return;
+ }
+ } else if ((mSampFreq != prevSampleRate) ||
+ (mNumChannels != prevNumChannels)) {
+ ALOGV("Reconfiguring decoder: %d->%d Hz, %d->%d channels",
+ prevSampleRate, mSampFreq, prevNumChannels, mNumChannels);
+ inHeader->nOffset = tempOffset;
+ inHeader->nFilledLen = tempFilledLen;
+ notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+ mOutputPortSettingsChange = AWAITING_DISABLED;
+ return;
+ }
+
+ signed int bytesConsumed = 0;
+ int errorCode = 0;
+ if (mIsCodecInitialized) {
+ errorCode = decodeXAACStream(inBuffer,inBufferLength, &bytesConsumed, &numOutBytes);
+ } else {
+ ALOGW("Assumption that first frame after header initializes decoder failed!");
+ }
+ inHeader->nFilledLen -= bytesConsumed;
+ inHeader->nOffset += bytesConsumed;
+
+ if (inHeader->nFilledLen != 0) {
+ ALOGE("All data not consumed");
+ }
+
+ /* In case of error, decoder would have given out empty buffer */
+ if ((0 != errorCode) && (0 == numOutBytes) && mIsCodecInitialized) {
+ numOutBytes = mOutputFrameLength * (mPcmWdSz/8) * mNumChannels;
+ }
+ numLoops++;
+
+ if (0 == bytesConsumed) {
+ ALOGE("bytesConsumed = 0 should never happen");
+ mSignalledError = true;
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ return;
+ }
+
+ if (errorCode) {
+ /* Clear buffer for output buffer is done inside XAAC codec */
+ /* TODO - Check if below memset is on top of reset inside codec */
+ memset(mOutputBuffer, 0, numOutBytes); // TODO: check for overflow, ASAN
+
+ // Discard input buffer.
+ if (inHeader) {
+ inHeader->nFilledLen = 0;
+ }
+
+ // fall through
+ }
+
+ if (inHeader && inHeader->nFilledLen == 0) {
+ inInfo->mOwnedByUs = false;
+ mInputBufferCount++;
+ inQueue.erase(inQueue.begin());
+ mLastInHeader = NULL;
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ } else {
+ ALOGV("inHeader->nFilledLen = %d", inHeader ? inHeader->nFilledLen : 0);
+ }
+
+ if (!outQueue.empty() && numOutBytes) {
+ BufferInfo *outInfo = *outQueue.begin();
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+ if (outHeader->nOffset != 0) {
+ ALOGE("outHeader->nOffset != 0 is not handled");
+ mSignalledError = true;
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ return;
+ }
+
+ signed short *outBuffer =
+ reinterpret_cast<signed short *>(outHeader->pBuffer + outHeader->nOffset);
+ int samplesize = mNumChannels * sizeof(int16_t);
+ if (outHeader->nOffset
+ + mOutputFrameLength * samplesize
+ > outHeader->nAllocLen) {
+ ALOGE("buffer overflow");
+ mSignalledError = true;
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ return;
+ }
+ memcpy(outBuffer, mOutputBuffer, numOutBytes);
+ outHeader->nFilledLen = numOutBytes;
+
+ if (mEndOfInput && !outQueue.empty()) {
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ mEndOfOutput = true;
+ } else {
+ outHeader->nFlags = 0;
+ }
+ outHeader->nTimeStamp = mCurrentTimestamp;
+ mPrevTimestamp = mCurrentTimestamp;
+
+ mOutputBufferCount++;
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(outQueue.begin());
+ outInfo = NULL;
+ ALOGV("out timestamp %lld / %d", outHeader->nTimeStamp, outHeader->nFilledLen);
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+ }
+ }
+
+ if (mEndOfInput) {
+ if (!outQueue.empty()) {
+ if (!mEndOfOutput) {
+ ALOGV(" empty block signaling EOS");
+ // send partial or empty block signaling EOS
+ mEndOfOutput = true;
+ BufferInfo *outInfo = *outQueue.begin();
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+ outHeader->nFilledLen = 0;
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ outHeader->nTimeStamp = mPrevTimestamp ;
+
+ mOutputBufferCount++;
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(outQueue.begin());
+ outInfo = NULL;
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+ }
+ break; // if outQueue not empty but no more output
+ }
+ }
+ }
+}
+
+void SoftXAAC::onPortFlushCompleted(OMX_U32 portIndex) {
+ if (portIndex == 0) {
+ // Make sure that the next buffer output does not still
+ // depend on fragments from the last one decoded.
+ // drain all existing data
+ if (mIsCodecInitialized) {
+ configflushDecode();
+ }
+ drainDecoder();
+ mLastInHeader = NULL;
+ mEndOfInput = false;
+ } else {
+ mEndOfOutput = false;
+ }
+}
+
+void SoftXAAC::configflushDecode() {
+ IA_ERRORCODE err_code;
+ UWORD32 ui_init_done;
+ uint32_t inBufferLength=8203;
+
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_INIT,
+ IA_CMD_TYPE_FLUSH_MEM,
+ NULL);
+ ALOGV("Codec initialized:%d",mIsCodecInitialized);
+ ALOGV("Error code from first flush %d",err_code);
+
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_INPUT_BYTES,
+ 0,
+ &inBufferLength);
+
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_INIT,
+ IA_CMD_TYPE_FLUSH_MEM,
+ NULL);
+
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_INIT,
+ IA_CMD_TYPE_INIT_DONE_QUERY,
+ &ui_init_done);
+
+ ALOGV("Flush called");
+
+ if (ui_init_done) {
+ err_code = getXAACStreamInfo();
+ ALOGV("Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz %d\nchannelMask %d\noutputFrameLength %d",
+ mSampFreq,mNumChannels,mPcmWdSz,mChannelMask,mOutputFrameLength);
+ mIsCodecInitialized = true;
+ }
+
+}
+int SoftXAAC::drainDecoder() {
+ return 0;
+}
+
+void SoftXAAC::onReset() {
+ drainDecoder();
+
+ // reset the "configured" state
+ mInputBufferCount = 0;
+ mOutputBufferCount = 0;
+ mEndOfInput = false;
+ mEndOfOutput = false;
+ mLastInHeader = NULL;
+
+ mSignalledError = false;
+ mOutputPortSettingsChange = NONE;
+}
+
+void SoftXAAC::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
+ if (portIndex != 1) {
+ return;
+ }
+
+ switch (mOutputPortSettingsChange) {
+ case NONE:
+ break;
+
+ case AWAITING_DISABLED:
+ {
+ CHECK(!enabled);
+ mOutputPortSettingsChange = AWAITING_ENABLED;
+ break;
+ }
+
+ default:
+ {
+ CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
+ CHECK(enabled);
+ mOutputPortSettingsChange = NONE;
+ break;
+ }
+ }
+}
+
+int SoftXAAC::initXAACDecoder() {
+ LOOPIDX i;
+
+ /* Error code */
+ IA_ERRORCODE err_code = IA_NO_ERROR;
+
+ /* First part */
+ /* Error Handler Init */
+ /* Get Library Name, Library Version and API Version */
+ /* Initialize API structure + Default config set */
+ /* Set config params from user */
+ /* Initialize memory tables */
+ /* Get memory information and allocate memory */
+
+ /* Memory variables */
+ UWORD32 n_mems, ui_rem;
+ UWORD32 ui_proc_mem_tabs_size;
+ /* API size */
+ UWORD32 pui_ap_isize;
+
+ mInputBufferSize = 0;
+ mInputBuffer = 0;
+ mOutputBuffer = 0;
+ mMallocCount = 0;
+
+ /* Process struct initing end */
+ /* ******************************************************************/
+ /* Initialize API structure and set config params to default */
+ /* ******************************************************************/
+
+ /* Get the API size */
+ err_code = ixheaacd_dec_api(NULL,
+ IA_API_CMD_GET_API_SIZE,
+ 0,
+ &pui_ap_isize);
+ ALOGV("return code of IA_API_CMD_GET_API_SIZE: %d",err_code);
+ /* Allocate memory for API */
+ mMemoryArray[mMallocCount] = memalign(4, pui_ap_isize);
+ if (mMemoryArray[mMallocCount] == NULL) {
+ ALOGE("malloc for pui_ap_isize + 4 >> %d Failed",pui_ap_isize + 4);
+ }
+ /* Set API object with the memory allocated */
+ mXheaacCodecHandle =
+ (pVOID)((WORD8*)mMemoryArray[mMallocCount]);
+ mMallocCount++;
+
+ /* Set the config params to default values */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_INIT,
+ IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS,
+ NULL);
+ ALOGV("return code of IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS: %d",err_code);
+
+ /* ******************************************************************/
+ /* Set config parameters */
+ /* ******************************************************************/
+ UWORD32 ui_mp4_flag = 1;
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4,
+ &ui_mp4_flag);
+ ALOGV("return code of IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4: %d",err_code);
+
+ /* ******************************************************************/
+ /* Initialize Memory info tables */
+ /* ******************************************************************/
+
+ /* Get memory info tables size */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_MEMTABS_SIZE,
+ 0,
+ &ui_proc_mem_tabs_size);
+ ALOGV("return code of IA_API_CMD_GET_MEMTABS_SIZE: %d",err_code);
+ mMemoryArray[mMallocCount] = memalign(4, ui_proc_mem_tabs_size);
+ if (mMemoryArray[mMallocCount] == NULL) {
+ ALOGE("Malloc for size (ui_proc_mem_tabs_size + 4) = %d failed!",ui_proc_mem_tabs_size + 4);
+ }
+
+ /* Set pointer for process memory tables */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_MEMTABS_PTR,
+ 0,
+ (pVOID)((WORD8*)mMemoryArray[mMallocCount]));
+ ALOGV("return code of IA_API_CMD_SET_MEMTABS_PTR: %d",err_code);
+ mMallocCount++;
+
+ /* initialize the API, post config, fill memory tables */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_INIT,
+ IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS,
+ NULL);
+ ALOGV("return code of IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS: %d",err_code);
+
+ /* ******************************************************************/
+ /* Allocate Memory with info from library */
+ /* ******************************************************************/
+
+ /* Get number of memory tables required */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_N_MEMTABS,
+ 0,
+ &n_mems);
+ ALOGV("return code of IA_API_CMD_GET_N_MEMTABS: %d",err_code);
+
+ for(i = 0; i < (WORD32)n_mems; i++) {
+ int ui_size = 0, ui_alignment = 0, ui_type = 0;
+ pVOID pv_alloc_ptr;
+
+ /* Get memory size */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_MEM_INFO_SIZE,
+ i,
+ &ui_size);
+ ALOGV("return code of IA_API_CMD_GET_MEM_INFO_SIZE: %d",err_code);
+
+ /* Get memory alignment */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_MEM_INFO_ALIGNMENT,
+ i,
+ &ui_alignment);
+ ALOGV("return code of IA_API_CMD_GET_MEM_INFO_ALIGNMENT: %d",err_code);
+
+ /* Get memory type */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_MEM_INFO_TYPE,
+ i,
+ &ui_type);
+ ALOGV("return code of IA_API_CMD_GET_MEM_INFO_TYPE: %d",err_code);
+
+ mMemoryArray[mMallocCount] =
+ memalign(ui_alignment , ui_size);
+ if (mMemoryArray[mMallocCount] == NULL) {
+ ALOGE("Malloc for size (ui_size + ui_alignment) = %d failed!",ui_size + ui_alignment);
+ }
+ pv_alloc_ptr =
+ (pVOID )((WORD8*)mMemoryArray[mMallocCount]);
+ mMallocCount++;
+
+ /* Set the buffer pointer */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_MEM_PTR,
+ i,
+ pv_alloc_ptr);
+ ALOGV("return code of IA_API_CMD_SET_MEM_PTR: %d",err_code);
+ if (ui_type == IA_MEMTYPE_INPUT) {
+ mInputBuffer = (pWORD8)pv_alloc_ptr;
+ mInputBufferSize = ui_size;
+
+ }
+
+ if (ui_type == IA_MEMTYPE_OUTPUT) {
+ mOutputBuffer = (pWORD8)pv_alloc_ptr;
+ }
+
+ }
+ /* End first part */
+
+ return IA_NO_ERROR;
+}
+
+int SoftXAAC::configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength) {
+
+ UWORD32 ui_init_done;
+ int32_t i_bytes_consumed;
+
+ if (mInputBufferSize < inBufferLength) {
+ ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d",mInputBufferSize,inBufferLength);
+ return false;
+ }
+
+ /* Copy the buffer passed by Android plugin to codec input buffer */
+ memcpy(mInputBuffer, inBuffer, inBufferLength);
+
+ /* Set number of bytes to be processed */
+ IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_INPUT_BYTES,
+ 0,
+ &inBufferLength);
+ ALOGV("return code of IA_API_CMD_SET_INPUT_BYTES: %d",err_code);
+
+ if (mIsCodecConfigFlushRequired) {
+ /* If codec is already initialized, then GA header is passed again */
+ /* Need to call the Flush API instead of INIT_PROCESS */
+ mIsCodecInitialized = false; /* Codec needs to be Reinitialized after flush */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_INIT,
+ IA_CMD_TYPE_GA_HDR,
+ NULL);
+ ALOGV("return code of IA_CMD_TYPE_GA_HDR: %d",err_code);
+ }
+ else {
+ /* Initialize the process */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_INIT,
+ IA_CMD_TYPE_INIT_PROCESS,
+ NULL);
+ ALOGV("return code of IA_CMD_TYPE_INIT_PROCESS: %d",err_code);
+ }
+
+ /* Checking for end of initialization */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_INIT,
+ IA_CMD_TYPE_INIT_DONE_QUERY,
+ &ui_init_done);
+ ALOGV("return code of IA_CMD_TYPE_INIT_DONE_QUERY: %d",err_code);
+
+ /* How much buffer is used in input buffers */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_CURIDX_INPUT_BUF,
+ 0,
+ &i_bytes_consumed);
+ ALOGV("return code of IA_API_CMD_GET_CURIDX_INPUT_BUF: %d",err_code);
+
+ if(ui_init_done){
+ err_code = getXAACStreamInfo();
+ ALOGI("Found Codec with below config---\nsampFreq %d\nnumChannels %d\npcmWdSz %d\nchannelMask %d\noutputFrameLength %d",
+ mSampFreq,mNumChannels,mPcmWdSz,mChannelMask,mOutputFrameLength);
+ mIsCodecInitialized = true;
+ }
+
+ return err_code;
+}
+
+int SoftXAAC::decodeXAACStream(uint8_t* inBuffer,
+ uint32_t inBufferLength,
+ int32_t *bytesConsumed,
+ int32_t *outBytes) {
+ if (mInputBufferSize < inBufferLength) {
+ ALOGE("Cannot config AAC, input buffer size %d < inBufferLength %d",mInputBufferSize,inBufferLength);
+ return -1;
+ }
+
+ /* Copy the buffer passed by Android plugin to codec input buffer */
+ memcpy(mInputBuffer,inBuffer,inBufferLength);
+
+ /* Set number of bytes to be processed */
+ IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_INPUT_BYTES,
+ 0,
+ &inBufferLength);
+ ALOGV("return code of IA_API_CMD_SET_INPUT_BYTES: %d",err_code);
+
+ /* Execute process */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_EXECUTE,
+ IA_CMD_TYPE_DO_EXECUTE,
+ NULL);
+ ALOGV("return code of IA_CMD_TYPE_DO_EXECUTE: %d",err_code);
+
+ UWORD32 ui_exec_done;
+ /* Checking for end of processing */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_EXECUTE,
+ IA_CMD_TYPE_DONE_QUERY,
+ &ui_exec_done);
+ ALOGV("return code of IA_CMD_TYPE_DONE_QUERY: %d",err_code);
+
+ /* How much buffer is used in input buffers */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_CURIDX_INPUT_BUF,
+ 0,
+ bytesConsumed);
+ ALOGV("return code of IA_API_CMD_GET_CURIDX_INPUT_BUF: %d",err_code);
+
+ /* Get the output bytes */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_OUTPUT_BYTES,
+ 0,
+ outBytes);
+ ALOGV("return code of IA_API_CMD_GET_OUTPUT_BYTES: %d",err_code);
+
+ return err_code;
+}
+
+int SoftXAAC::deInitXAACDecoder() {
+ ALOGI("deInitXAACDecoder");
+
+ /* Tell that the input is over in this buffer */
+ IA_ERRORCODE err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_INPUT_OVER,
+ 0,
+ NULL);
+ ALOGV("return code of IA_API_CMD_INPUT_OVER: %d",err_code);
+
+ for(int i = 0; i < mMallocCount; i++)
+ {
+ if(mMemoryArray[i])
+ free(mMemoryArray[i]);
+ }
+ mMallocCount = 0;
+
+ return err_code;
+}
+
+IA_ERRORCODE SoftXAAC::getXAACStreamInfo() {
+ IA_ERRORCODE err_code = IA_NO_ERROR;
+
+ /* Sampling frequency */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ,
+ &mSampFreq);
+ ALOGV("return code of IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ: %d",err_code);
+
+ /* Total Number of Channels */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS,
+ &mNumChannels);
+ ALOGV("return code of IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS: %d",err_code);
+
+ /* PCM word size */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ,
+ &mPcmWdSz);
+ ALOGV("return code of IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ: %d",err_code);
+
+ /* channel mask to tell the arrangement of channels in bit stream */
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK,
+ &mChannelMask);
+ ALOGV("return code of IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK: %d",err_code);
+
+ /* Channel mode to tell MONO/STEREO/DUAL-MONO/NONE_OF_THESE */
+ UWORD32 ui_channel_mode;
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE,
+ &ui_channel_mode);
+ ALOGV("return code of IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE: %d",err_code);
+ if(ui_channel_mode == 0)
+ ALOGV("Channel Mode: MONO_OR_PS\n");
+ else if(ui_channel_mode == 1)
+ ALOGV("Channel Mode: STEREO\n");
+ else if(ui_channel_mode == 2)
+ ALOGV("Channel Mode: DUAL-MONO\n");
+ else
+ ALOGV("Channel Mode: NONE_OF_THESE or MULTICHANNEL\n");
+
+ /* Channel mode to tell SBR PRESENT/NOT_PRESENT */
+ UWORD32 ui_sbr_mode;
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_GET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE,
+ &ui_sbr_mode);
+ ALOGV("return code of IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE: %d",err_code);
+ if(ui_sbr_mode == 0)
+ ALOGV("SBR Mode: NOT_PRESENT\n");
+ else if(ui_sbr_mode == 1)
+ ALOGV("SBR Mode: PRESENT\n");
+ else
+ ALOGV("SBR Mode: ILLEGAL\n");
+
+ /* mOutputFrameLength = 1024 * (1 + SBR_MODE) for AAC */
+ /* For USAC it could be 1024 * 3 , support to query */
+ /* not yet added in codec */
+ mOutputFrameLength = 1024 * (1 + ui_sbr_mode);
+
+ ALOGI("mOutputFrameLength %d ui_sbr_mode %d",mOutputFrameLength,ui_sbr_mode);
+
+ return IA_NO_ERROR;
+}
+
+IA_ERRORCODE SoftXAAC::setXAACDRCInfo(int32_t drcCut,
+ int32_t drcBoost,
+ int32_t drcRefLevel,
+ int32_t drcHeavyCompression) {
+ IA_ERRORCODE err_code = IA_NO_ERROR;
+
+ int32_t ui_drc_enable = 1;
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE,
+ &ui_drc_enable);
+ ALOGV("return code of IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE: %d",err_code);
+ if (drcCut !=-1) {
+ ALOGI("set drcCut=%d", drcCut);
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT,
+ &drcCut);
+ ALOGV("return code of IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT: %d",err_code);
+ }
+
+ if (drcBoost !=-1) {
+ ALOGI("set drcBoost=%d", drcBoost);
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST,
+ &drcBoost);
+ ALOGV("return code of IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST: %d",err_code);
+ }
+
+ if (drcRefLevel != -1) {
+ ALOGI("set drcRefLevel=%d", drcRefLevel);
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL,
+ &drcRefLevel);
+ ALOGV("return code of IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL: %d",err_code);
+ }
+
+ if (drcHeavyCompression != -1) {
+ ALOGI("set drcHeavyCompression=%d", drcHeavyCompression);
+ err_code = ixheaacd_dec_api(mXheaacCodecHandle,
+ IA_API_CMD_SET_CONFIG_PARAM,
+ IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP,
+ &drcHeavyCompression);
+ ALOGV("return code of IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP: %d",err_code);
+ }
+
+ return IA_NO_ERROR;
+}
+
+} // namespace android
+
+android::SoftOMXComponent *createSoftOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ ALOGI("createSoftOMXComponent for SoftXAACDEC");
+ return new android::SoftXAAC(name, callbacks, appData, component);
+}
diff --git a/media/libstagefright/codecs/xaacdec/SoftXAAC.h b/media/libstagefright/codecs/xaacdec/SoftXAAC.h
new file mode 100644
index 0000000..f4b4c54
--- /dev/null
+++ b/media/libstagefright/codecs/xaacdec/SoftXAAC.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SOFTXAAC_H_
+#define SOFTXAAC_H_
+
+#include <media/stagefright/omx/SimpleSoftOMXComponent.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "ixheaacd_type_def.h"
+#include "ixheaacd_error_standards.h"
+#include "ixheaacd_error_handler.h"
+#include "ixheaacd_apicmd_standards.h"
+#include "ixheaacd_memory_standards.h"
+#include "ixheaacd_aac_config.h"
+//#include "ixheaacd_aac_dec_error.h"
+
+#define MAX_MEM_ALLOCS 100
+
+extern "C" IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_module_obj,
+ WORD32 i_cmd, WORD32 i_idx, pVOID pv_value);
+
+namespace android {
+
+struct SoftXAAC : public SimpleSoftOMXComponent {
+ SoftXAAC(const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~SoftXAAC();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+ virtual void onPortFlushCompleted(OMX_U32 portIndex);
+ virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+ virtual void onReset();
+
+private:
+ enum {
+ kNumInputBuffers = 4,
+ kNumOutputBuffers = 4,
+ kNumDelayBlocksMax = 8,
+ };
+
+ bool mIsADTS;
+ size_t mInputBufferCount;
+ size_t mOutputBufferCount;
+ bool mSignalledError;
+ OMX_BUFFERHEADERTYPE *mLastInHeader;
+ int64_t mPrevTimestamp;
+ int64_t mCurrentTimestamp;
+ uint32_t mBufSize;
+
+ enum {
+ NONE,
+ AWAITING_DISABLED,
+ AWAITING_ENABLED
+ } mOutputPortSettingsChange;
+
+ void initPorts();
+ status_t initDecoder();
+ bool isConfigured() const;
+ int drainDecoder();
+ int initXAACDecoder();
+ int deInitXAACDecoder();
+
+ int configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength);
+ int decodeXAACStream(uint8_t* inBuffer,
+ uint32_t inBufferLength,
+ int32_t *bytesConsumed,
+ int32_t *outBytes);
+
+ void configflushDecode();
+ IA_ERRORCODE getXAACStreamInfo();
+ IA_ERRORCODE setXAACDRCInfo(int32_t drcCut,
+ int32_t drcBoost,
+ int32_t drcRefLevel,
+ int32_t drcHeavyCompression);
+
+ bool mEndOfInput;
+ bool mEndOfOutput;
+
+ void* mXheaacCodecHandle;
+ uint32_t mInputBufferSize;
+ uint32_t mOutputFrameLength;
+ int8_t* mInputBuffer;
+ int8_t* mOutputBuffer;
+ int32_t mSampFreq;
+ int32_t mNumChannels;
+ int32_t mPcmWdSz;
+ int32_t mChannelMask;
+ bool mIsCodecInitialized;
+ bool mIsCodecConfigFlushRequired;
+
+ void* mMemoryArray[MAX_MEM_ALLOCS];
+ int32_t mMallocCount;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftXAAC);
+
+};
+
+} // namespace android
+
+#endif // SOFTXAAC_H_
diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp
index 4946ada..1f3e8c1 100644
--- a/media/libstagefright/omx/SoftOMXPlugin.cpp
+++ b/media/libstagefright/omx/SoftOMXPlugin.cpp
@@ -34,7 +34,12 @@
const char *mRole;
} kComponents[] = {
+ // two choices for aac decoding.
+ // configurable in media/libstagefright/data/media_codecs_google_audio.xml
+ // default implementation
{ "OMX.google.aac.decoder", "aacdec", "audio_decoder.aac" },
+ // alternate implementation
+ { "OMX.google.xaac.decoder", "xaacdec", "audio_decoder.aac" },
{ "OMX.google.aac.encoder", "aacenc", "audio_encoder.aac" },
{ "OMX.google.amrnb.decoder", "amrdec", "audio_decoder.amrnb" },
{ "OMX.google.amrnb.encoder", "amrnbenc", "audio_encoder.amrnb" },
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index d6dae5b..c8da34d 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -21,6 +21,7 @@
"MemoryLeakTrackUtil.cpp",
"ProcessInfo.cpp",
"SchedulingPolicyService.cpp",
+ "ServiceUtilities.cpp",
],
shared_libs: [
"libbinder",
diff --git a/services/audioflinger/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
similarity index 99%
rename from services/audioflinger/ServiceUtilities.cpp
rename to media/utils/ServiceUtilities.cpp
index aa267ea..c4a4374 100644
--- a/services/audioflinger/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -19,7 +19,7 @@
#include <binder/IServiceManager.h>
#include <binder/PermissionCache.h>
#include <private/android_filesystem_config.h>
-#include "ServiceUtilities.h"
+#include "mediautils/ServiceUtilities.h"
/* When performing permission checks we do not use permission cache for
* runtime permissions (protection level dangerous) as they may change at
diff --git a/services/audioflinger/ServiceUtilities.h b/media/utils/include/mediautils/ServiceUtilities.h
similarity index 97%
rename from services/audioflinger/ServiceUtilities.h
rename to media/utils/include/mediautils/ServiceUtilities.h
index f45ada1..8ead410 100644
--- a/services/audioflinger/ServiceUtilities.h
+++ b/media/utils/include/mediautils/ServiceUtilities.h
@@ -20,6 +20,8 @@
namespace android {
+// Audio permission utilities
+
extern pid_t getpid_cached;
bool isTrustedCallingUid(uid_t uid);
bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
diff --git a/packages/MediaComponents/Android.mk b/packages/MediaComponents/Android.mk
index def9dc5..55a5424 100644
--- a/packages/MediaComponents/Android.mk
+++ b/packages/MediaComponents/Android.mk
@@ -42,7 +42,7 @@
#
#LOCAL_MULTILIB := first
#
-#LOCAL_JAVA_LIBRARIES += android-support-annotations
+#LOCAL_JAVA_LIBRARIES += androidx.annotation_annotation
#
## To embed native libraries in package, uncomment the lines below.
##LOCAL_MODULE_TAGS := samples
@@ -60,9 +60,9 @@
#
## TODO: Remove dependency with other support libraries.
#LOCAL_STATIC_ANDROID_LIBRARIES += \
-# android-support-v4 \
-# android-support-v7-appcompat \
-# android-support-v7-palette
+# androidx.legacy_legacy-support-v4 \
+# androidx.appcompat_appcompat \
+# androidx.palette_palette
#LOCAL_USE_AAPT2 := true
#
#include $(BUILD_PACKAGE)
diff --git a/packages/MediaComponents/res/layout/mr_controller_material_dialog_b.xml b/packages/MediaComponents/res/layout/mr_controller_material_dialog_b.xml
index b304471..f6f7be5 100644
--- a/packages/MediaComponents/res/layout/mr_controller_material_dialog_b.xml
+++ b/packages/MediaComponents/res/layout/mr_controller_material_dialog_b.xml
@@ -169,7 +169,7 @@
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollIndicators="top|bottom">
- <android.support.v7.widget.ButtonBarLayout
+ <androidx.appcompat.widget.ButtonBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
@@ -184,7 +184,7 @@
style="?android:attr/buttonBarNeutralButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
- <android.support.v4.widget.Space
+ <androidx.legacy.widget.Space
android:id="@+id/spacer"
android:layout_width="0dp"
android:layout_height="0dp"
@@ -200,7 +200,7 @@
style="?android:attr/buttonBarPositiveButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
- </android.support.v7.widget.ButtonBarLayout>
+ </androidx.appcompat.widget.ButtonBarLayout>
</ScrollView>
</LinearLayout>
</FrameLayout>
diff --git a/packages/MediaComponents/res/layout/mr_controller_volume_item.xml b/packages/MediaComponents/res/layout/mr_controller_volume_item.xml
index a89058b..12d85ae 100644
--- a/packages/MediaComponents/res/layout/mr_controller_volume_item.xml
+++ b/packages/MediaComponents/res/layout/mr_controller_volume_item.xml
@@ -40,7 +40,7 @@
android:layout_marginBottom="8dp"
android:scaleType="fitCenter"
android:src="?attr/mediaRouteAudioTrackDrawable" />
- <android.support.v7.app.MediaRouteVolumeSlider
+ <androidx.mediarouter.app.MediaRouteVolumeSlider
android:id="@+id/mr_volume_slider"
android:layout_width="fill_parent"
android:layout_height="40dp"
diff --git a/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java b/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java
index c909099..0327beb 100644
--- a/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaBrowser2Impl.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.media.MediaBrowser2;
import android.media.MediaBrowser2.BrowserCallback;
-import android.media.MediaController2;
import android.media.MediaItem2;
import android.media.SessionToken2;
import android.media.update.MediaBrowser2Provider;
diff --git a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java b/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
index 249365a..2883087 100644
--- a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
@@ -16,7 +16,6 @@
package com.android.media;
-import static android.media.SessionCommand2.COMMAND_CODE_SET_VOLUME;
import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_ADD_ITEM;
import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_REMOVE_ITEM;
import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM;
@@ -30,6 +29,7 @@
import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID;
import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH;
import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_URI;
+import static android.media.SessionCommand2.COMMAND_CODE_SET_VOLUME;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -44,11 +44,11 @@
import android.media.MediaMetadata2;
import android.media.MediaPlaylistAgent.RepeatMode;
import android.media.MediaPlaylistAgent.ShuffleMode;
-import android.media.SessionCommand2;
import android.media.MediaSession2.CommandButton;
-import android.media.SessionCommandGroup2;
import android.media.MediaSessionService2;
import android.media.Rating2;
+import android.media.SessionCommand2;
+import android.media.SessionCommandGroup2;
import android.media.SessionToken2;
import android.media.update.MediaController2Provider;
import android.net.Uri;
@@ -58,10 +58,11 @@
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.UserHandle;
-import android.support.annotation.GuardedBy;
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.GuardedBy;
+
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
diff --git a/packages/MediaComponents/src/com/android/media/MediaController2Stub.java b/packages/MediaComponents/src/com/android/media/MediaController2Stub.java
index 2cfc5df..ece4a00 100644
--- a/packages/MediaComponents/src/com/android/media/MediaController2Stub.java
+++ b/packages/MediaComponents/src/com/android/media/MediaController2Stub.java
@@ -21,8 +21,8 @@
import android.media.MediaController2;
import android.media.MediaItem2;
import android.media.MediaMetadata2;
-import android.media.SessionCommand2;
import android.media.MediaSession2.CommandButton;
+import android.media.SessionCommand2;
import android.media.SessionCommandGroup2;
import android.os.Bundle;
import android.os.ResultReceiver;
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
index 4ec6042..72ecf54 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
@@ -44,13 +44,13 @@
import android.media.MediaPlaylistAgent.PlaylistEventCallback;
import android.media.MediaSession2;
import android.media.MediaSession2.Builder;
-import android.media.SessionCommand2;
import android.media.MediaSession2.CommandButton;
-import android.media.SessionCommandGroup2;
import android.media.MediaSession2.ControllerInfo;
import android.media.MediaSession2.OnDataSourceMissingHelper;
import android.media.MediaSession2.SessionCallback;
import android.media.MediaSessionService2;
+import android.media.SessionCommand2;
+import android.media.SessionCommandGroup2;
import android.media.SessionToken2;
import android.media.VolumeProvider2;
import android.media.session.MediaSessionManager;
@@ -60,10 +60,11 @@
import android.os.Parcelable;
import android.os.Process;
import android.os.ResultReceiver;
-import android.support.annotation.GuardedBy;
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.GuardedBy;
+
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.ArrayList;
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java b/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
index ec657d7..11ccd9f 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
@@ -22,11 +22,11 @@
import android.media.MediaItem2;
import android.media.MediaLibraryService2.LibraryRoot;
import android.media.MediaMetadata2;
-import android.media.SessionCommand2;
import android.media.MediaSession2.CommandButton;
-import android.media.SessionCommandGroup2;
import android.media.MediaSession2.ControllerInfo;
import android.media.Rating2;
+import android.media.SessionCommand2;
+import android.media.SessionCommandGroup2;
import android.media.VolumeProvider2;
import android.net.Uri;
import android.os.Binder;
@@ -35,13 +35,14 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ResultReceiver;
-import android.support.annotation.GuardedBy;
-import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
+import androidx.annotation.GuardedBy;
+import androidx.annotation.NonNull;
+
import com.android.media.MediaLibraryService2Impl.MediaLibrarySessionImpl;
import com.android.media.MediaSession2Impl.CommandButtonImpl;
import com.android.media.MediaSession2Impl.CommandGroupImpl;
diff --git a/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
index c33eb65..d975839 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
@@ -20,7 +20,6 @@
import android.app.Notification;
import android.app.NotificationManager;
-import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayerBase;
import android.media.MediaPlayerBase.PlayerEventCallback;
@@ -31,9 +30,10 @@
import android.media.SessionToken2.TokenType;
import android.media.update.MediaSessionService2Provider;
import android.os.IBinder;
-import android.support.annotation.GuardedBy;
import android.util.Log;
+import androidx.annotation.GuardedBy;
+
// TODO(jaewan): Need a test for session service itself.
public class MediaSessionService2Impl implements MediaSessionService2Provider {
diff --git a/packages/MediaComponents/src/com/android/media/Rating2Impl.java b/packages/MediaComponents/src/com/android/media/Rating2Impl.java
index d558129..e2b9f0a 100644
--- a/packages/MediaComponents/src/com/android/media/Rating2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/Rating2Impl.java
@@ -18,7 +18,6 @@
import static android.media.Rating2.*;
-import android.content.Context;
import android.media.Rating2;
import android.media.Rating2.Style;
import android.media.update.Rating2Provider;
diff --git a/packages/MediaComponents/src/com/android/media/RoutePlayer.java b/packages/MediaComponents/src/com/android/media/RoutePlayer.java
index 9450d34..ebff0e2 100644
--- a/packages/MediaComponents/src/com/android/media/RoutePlayer.java
+++ b/packages/MediaComponents/src/com/android/media/RoutePlayer.java
@@ -23,7 +23,8 @@
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
-import android.support.annotation.RequiresApi;
+
+import androidx.annotation.RequiresApi;
import com.android.support.mediarouter.media.MediaItemStatus;
import com.android.support.mediarouter.media.MediaRouter;
@@ -33,8 +34,6 @@
import com.android.support.mediarouter.media.RemotePlaybackClient.SessionActionCallback;
import com.android.support.mediarouter.media.RemotePlaybackClient.StatusCallback;
-import java.util.Map;
-
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class RoutePlayer extends MediaSession.Callback {
public static final long PLAYBACK_ACTIONS = PlaybackState.ACTION_PAUSE
diff --git a/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java b/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
index a5cf8c4..f792712 100644
--- a/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
@@ -16,9 +16,9 @@
package com.android.media;
+import static android.media.SessionToken2.TYPE_LIBRARY_SERVICE;
import static android.media.SessionToken2.TYPE_SESSION;
import static android.media.SessionToken2.TYPE_SESSION_SERVICE;
-import static android.media.SessionToken2.TYPE_LIBRARY_SERVICE;
import android.content.Context;
import android.content.Intent;
diff --git a/packages/MediaComponents/src/com/android/media/subtitle/SubtitleController.java b/packages/MediaComponents/src/com/android/media/subtitle/SubtitleController.java
index a4d55d7..97d3927 100644
--- a/packages/MediaComponents/src/com/android/media/subtitle/SubtitleController.java
+++ b/packages/MediaComponents/src/com/android/media/subtitle/SubtitleController.java
@@ -16,12 +16,8 @@
package com.android.media.subtitle;
-import java.util.Locale;
-import java.util.Vector;
-
import android.content.Context;
import android.media.MediaFormat;
-import android.media.MediaPlayer2;
import android.media.MediaPlayer2.TrackInfo;
import android.os.Handler;
import android.os.Looper;
@@ -30,6 +26,9 @@
import com.android.media.subtitle.SubtitleTrack.RenderingWidget;
+import java.util.Locale;
+import java.util.Vector;
+
// Note: This is forked from android.media.SubtitleController since P
/**
* The subtitle controller provides the architecture to display subtitles for a
diff --git a/packages/MediaComponents/src/com/android/media/update/ApiFactory.java b/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
index d7be549..f75b75e 100644
--- a/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
+++ b/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
@@ -31,13 +31,13 @@
import android.media.MediaMetadata2;
import android.media.MediaPlaylistAgent;
import android.media.MediaSession2;
-import android.media.SessionCommand2;
-import android.media.SessionCommandGroup2;
import android.media.MediaSession2.ControllerInfo;
import android.media.MediaSession2.SessionCallback;
import android.media.MediaSessionService2;
import android.media.MediaSessionService2.MediaNotification;
import android.media.Rating2;
+import android.media.SessionCommand2;
+import android.media.SessionCommandGroup2;
import android.media.SessionToken2;
import android.media.VolumeProvider2;
import android.media.update.MediaBrowser2Provider;
@@ -59,11 +59,12 @@
import android.media.update.VolumeProvider2Provider;
import android.os.Bundle;
import android.os.IInterface;
-import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.MediaControlView2;
import android.widget.VideoView2;
+import androidx.annotation.Nullable;
+
import com.android.media.IMediaController2;
import com.android.media.MediaBrowser2Impl;
import com.android.media.MediaController2Impl;
diff --git a/packages/MediaComponents/src/com/android/media/update/ApiHelper.java b/packages/MediaComponents/src/com/android/media/update/ApiHelper.java
index ad8bb48..dc5e5e2 100644
--- a/packages/MediaComponents/src/com/android/media/update/ApiHelper.java
+++ b/packages/MediaComponents/src/com/android/media/update/ApiHelper.java
@@ -18,21 +18,21 @@
import android.annotation.Nullable;
import android.content.Context;
-import android.content.ContextWrapper;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.XmlResourceParser;
-import android.support.annotation.GuardedBy;
-import android.support.v4.widget.Space;
-import android.support.v7.widget.ButtonBarLayout;
import android.util.AttributeSet;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import androidx.annotation.GuardedBy;
+import androidx.appcompat.widget.ButtonBarLayout;
+import androidx.legacy.widget.Space;
+
import com.android.support.mediarouter.app.MediaRouteButton;
import com.android.support.mediarouter.app.MediaRouteExpandCollapseButton;
import com.android.support.mediarouter.app.MediaRouteVolumeSlider;
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteActionProvider.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteActionProvider.java
index d3e8d47..98c0d17 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteActionProvider.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteActionProvider.java
@@ -19,11 +19,12 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
-import android.support.v4.view.ActionProvider;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
+import androidx.core.view.ActionProvider;
+
import com.android.support.mediarouter.media.MediaRouteSelector;
import com.android.support.mediarouter.media.MediaRouter;
@@ -48,7 +49,7 @@
* <h3>Prerequisites</h3>
* <p>
* To use the media route action provider, the activity must be a subclass of
- * {@link AppCompatActivity} from the <code>android.support.v7.appcompat</code>
+ * {@link AppCompatActivity} from the <code>androidx.appcompat.appcompat</code>
* support library. Refer to support library documentation for details.
* </p>
*
@@ -65,7 +66,7 @@
* <item android:id="@+id/media_route_menu_item"
* android:title="@string/media_route_menu_title"
* app:showAsAction="always"
- * app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"/>
+ * app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"/>
* </menu>
* </pre><p>
* Then configure the menu and set the route selector for the chooser.
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteButton.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteButton.java
index fde8a63..e82fcb9 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteButton.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteButton.java
@@ -28,14 +28,15 @@
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
-import android.support.v4.graphics.drawable.DrawableCompat;
-import android.support.v7.widget.TooltipCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.view.SoundEffectConstants;
import android.view.View;
+import androidx.appcompat.widget.TooltipCompat;
+import androidx.core.graphics.drawable.DrawableCompat;
+
import com.android.media.update.ApiHelper;
import com.android.media.update.R;
import com.android.support.mediarouter.media.MediaRouteSelector;
@@ -70,7 +71,7 @@
* <h3>Prerequisites</h3>
* <p>
* To use the media route button, the activity must be a subclass of
- * {@link FragmentActivity} from the <code>android.support.v4</code>
+ * {@link FragmentActivity} from the <code>androidx.core./code>
* support library. Refer to support library documentation for details.
* </p>
*
@@ -81,9 +82,9 @@
private static final String TAG = "MediaRouteButton";
private static final String CHOOSER_FRAGMENT_TAG =
- "android.support.v7.mediarouter:MediaRouteChooserDialogFragment";
+ "androidx.mediarouter.media.outer:MediaRouteChooserDialogFragment";
private static final String CONTROLLER_FRAGMENT_TAG =
- "android.support.v7.mediarouter:MediaRouteControllerDialogFragment";
+ "androidx.mediarouter.media.outer:MediaRouteControllerDialogFragment";
private final MediaRouter mRouter;
private final MediaRouterCallback mCallback;
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialog.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialog.java
index cac64d9..f24028a 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialog.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteChooserDialog.java
@@ -16,13 +16,14 @@
package com.android.support.mediarouter.app;
-import static com.android.support.mediarouter.media.MediaRouter.RouteInfo.CONNECTION_STATE_CONNECTED;
-import static com.android.support.mediarouter.media.MediaRouter.RouteInfo.CONNECTION_STATE_CONNECTING;
+import static com.android.support.mediarouter.media.MediaRouter.RouteInfo
+ .CONNECTION_STATE_CONNECTED;
+import static com.android.support.mediarouter.media.MediaRouter.RouteInfo
+ .CONNECTION_STATE_CONNECTING;
import android.annotation.NonNull;
import android.app.Dialog;
import android.content.Context;
-import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.net.Uri;
@@ -30,12 +31,10 @@
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
-import android.support.v7.app.AppCompatDialog;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialog.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialog.java
index 060cfca..f6c1d2f 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialog.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteControllerDialog.java
@@ -40,9 +40,6 @@
import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
-import android.support.v4.util.ObjectsCompat;
-import android.support.v4.view.accessibility.AccessibilityEventCompat;
-import android.support.v7.graphics.Palette;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextThemeWrapper;
@@ -72,11 +69,15 @@
import android.widget.SeekBar;
import android.widget.TextView;
+import androidx.core.util.ObjectsCompat;
+import androidx.core.view.accessibility.AccessibilityEventCompat;
+import androidx.palette.graphics.Palette;
+
import com.android.media.update.ApiHelper;
import com.android.media.update.R;
+import com.android.support.mediarouter.app.OverlayListView.OverlayObject;
import com.android.support.mediarouter.media.MediaRouteSelector;
import com.android.support.mediarouter.media.MediaRouter;
-import com.android.support.mediarouter.app.OverlayListView.OverlayObject;
import java.io.BufferedInputStream;
import java.io.IOException;
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogFactory.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogFactory.java
index a9eaf39..b5ee63e 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogFactory.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDialogFactory.java
@@ -16,7 +16,7 @@
package com.android.support.mediarouter.app;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
/**
* The media route dialog factory is responsible for creating the media route
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDiscoveryFragment.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDiscoveryFragment.java
index 02ee118..52aecd88 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDiscoveryFragment.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteDiscoveryFragment.java
@@ -17,10 +17,11 @@
package com.android.support.mediarouter.app;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import com.android.support.mediarouter.media.MediaRouter;
+import androidx.fragment.app.Fragment;
+
import com.android.support.mediarouter.media.MediaRouteSelector;
+import com.android.support.mediarouter.media.MediaRouter;
/**
* Media route discovery fragment.
@@ -34,7 +35,7 @@
* provide the {@link MediaRouter} callback to register.
* </p><p>
* Note that the discovery callback makes the application be connected with all the
- * {@link android.support.v7.media.MediaRouteProviderService media route provider services}
+ * {@link androidx.mediarouter.media.MediaRouteProviderService media route provider services}
* while it is registered.
* </p>
*/
@@ -114,7 +115,7 @@
}
/**
- * Called to create the {@link android.support.v7.media.MediaRouter.Callback callback}
+ * Called to create the {@link androidx.mediarouter.media.MediaRouter.Callback callback}
* that will be registered.
* <p>
* The default callback does nothing. The application may override this method to
@@ -129,7 +130,7 @@
/**
* Called to prepare the callback flags that will be used when the
- * {@link android.support.v7.media.MediaRouter.Callback callback} is registered.
+ * {@link androidx.mediarouter.media.MediaRouter.Callback callback} is registered.
* <p>
* The default implementation returns {@link MediaRouter#CALLBACK_FLAG_REQUEST_DISCOVERY}.
* </p>
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteExpandCollapseButton.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteExpandCollapseButton.java
index 6a0a95a..dcca6a0 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteExpandCollapseButton.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouteExpandCollapseButton.java
@@ -21,7 +21,6 @@
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.AnimationDrawable;
-import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageButton;
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouterThemeHelper.java b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouterThemeHelper.java
index 63f042f..b4bf8d1 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouterThemeHelper.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/app/MediaRouterThemeHelper.java
@@ -19,12 +19,13 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
-import android.support.annotation.IntDef;
-import android.support.v4.graphics.ColorUtils;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.View;
+import androidx.annotation.IntDef;
+import androidx.core.graphics.ColorUtils;
+
import com.android.media.update.R;
import java.lang.annotation.Retention;
@@ -170,7 +171,7 @@
private static boolean isLightTheme(Context context) {
TypedValue value = new TypedValue();
// TODO(sungsoo): Switch to com.android.internal.R.attr.isLightTheme
- return context.getTheme().resolveAttribute(android.support.v7.appcompat.R.attr.isLightTheme,
+ return context.getTheme().resolveAttribute(androidx.appcompat.R.attr.isLightTheme,
value, true) && value.data != 0;
}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/jellybean-mr1/MediaRouterJellybeanMr1.java b/packages/MediaComponents/src/com/android/support/mediarouter/jellybean-mr1/MediaRouterJellybeanMr1.java
index f8539bd..5a0bc95 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/jellybean-mr1/MediaRouterJellybeanMr1.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/jellybean-mr1/MediaRouterJellybeanMr1.java
@@ -20,7 +20,6 @@
import android.hardware.display.DisplayManager;
import android.os.Build;
import android.os.Handler;
-import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.Display;
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaItemStatus.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaItemStatus.java
index 90ea2d5..92f608b 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaItemStatus.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaItemStatus.java
@@ -19,7 +19,8 @@
import android.app.PendingIntent;
import android.os.Bundle;
import android.os.SystemClock;
-import android.support.v4.util.TimeUtils;
+
+import androidx.core.util.TimeUtils;
/**
* Describes the playback status of a media item.
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProvider.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProvider.java
index 91a2e1a..7ea328c 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProvider.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProvider.java
@@ -23,7 +23,8 @@
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
-import android.support.v4.util.ObjectsCompat;
+
+import androidx.core.util.ObjectsCompat;
import com.android.support.mediarouter.media.MediaRouter.ControlRequestCallback;
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProviderService.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProviderService.java
index 43cde10..a186fee 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProviderService.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteProviderService.java
@@ -29,12 +29,14 @@
.CLIENT_MSG_RELEASE_ROUTE_CONTROLLER;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
.CLIENT_MSG_ROUTE_CONTROL_REQUEST;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_MSG_SELECT_ROUTE;
+import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
+ .CLIENT_MSG_SELECT_ROUTE;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
.CLIENT_MSG_SET_DISCOVERY_REQUEST;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
.CLIENT_MSG_SET_ROUTE_VOLUME;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_MSG_UNREGISTER;
+import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
+ .CLIENT_MSG_UNREGISTER;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
.CLIENT_MSG_UNSELECT_ROUTE;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
@@ -51,9 +53,12 @@
.SERVICE_MSG_GENERIC_FAILURE;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
.SERVICE_MSG_GENERIC_SUCCESS;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.SERVICE_MSG_REGISTERED;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.SERVICE_VERSION_CURRENT;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.isValidRemoteMessenger;
+import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
+ .SERVICE_MSG_REGISTERED;
+import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
+ .SERVICE_VERSION_CURRENT;
+import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
+ .isValidRemoteMessenger;
import android.app.Service;
import android.content.Intent;
@@ -65,11 +70,12 @@
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
-import android.support.annotation.VisibleForTesting;
-import android.support.v4.util.ObjectsCompat;
import android.util.Log;
import android.util.SparseArray;
+import androidx.annotation.VisibleForTesting;
+import androidx.core.util.ObjectsCompat;
+
import java.lang.ref.WeakReference;
import java.util.ArrayList;
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteSelector.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteSelector.java
index 5669b19..f20dcc0 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteSelector.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouteSelector.java
@@ -17,8 +17,9 @@
import android.content.IntentFilter;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouter.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouter.java
index db0052e..4b56b19 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouter.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaRouter.java
@@ -33,15 +33,16 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.support.v4.app.ActivityManagerCompat;
-import android.support.v4.hardware.display.DisplayManagerCompat;
-import android.support.v4.media.VolumeProviderCompat;
import android.support.v4.media.session.MediaSessionCompat;
-import android.support.v4.util.Pair;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
+import androidx.core.app.ActivityManagerCompat;
+import androidx.core.hardware.display.DisplayManagerCompat;
+import androidx.core.util.Pair;
+import androidx.media.VolumeProviderCompat;
+
import com.android.support.mediarouter.media.MediaRouteProvider.ProviderMetadata;
import com.android.support.mediarouter.media.MediaRouteProvider.RouteController;
@@ -81,13 +82,13 @@
static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
/**
- * Passed to {@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect(int)}
+ * Passed to {@link androidx.mediarouter.media.MediaRouteProvider.RouteController#onUnselect(int)}
* and {@link Callback#onRouteUnselected(MediaRouter, RouteInfo, int)} when the reason the route
* was unselected is unknown.
*/
public static final int UNSELECT_REASON_UNKNOWN = 0;
/**
- * Passed to {@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect(int)}
+ * Passed to {@link androidx.mediarouter.media.MediaRouteProvider.RouteController#onUnselect(int)}
* and {@link Callback#onRouteUnselected(MediaRouter, RouteInfo, int)} when the user pressed
* the disconnect button to disconnect and keep playing.
* <p>
@@ -96,13 +97,13 @@
*/
public static final int UNSELECT_REASON_DISCONNECTED = 1;
/**
- * Passed to {@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect(int)}
+ * Passed to {@link androidx.mediarouter.media.MediaRouteProvider.RouteController#onUnselect(int)}
* and {@link Callback#onRouteUnselected(MediaRouter, RouteInfo, int)} when the user pressed
* the stop casting button.
*/
public static final int UNSELECT_REASON_STOPPED = 2;
/**
- * Passed to {@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect(int)}
+ * Passed to {@link androidx.mediarouter.media.MediaRouteProvider.RouteController#onUnselect(int)}
* and {@link Callback#onRouteUnselected(MediaRouter, RouteInfo, int)} when the user selected
* a different route.
*/
@@ -174,7 +175,7 @@
* Applications should typically add a callback using this flag in the
* {@link android.app.Activity activity's} {@link android.app.Activity#onStart onStart}
* method and remove it in the {@link android.app.Activity#onStop onStop} method.
- * The {@link android.support.v7.app.MediaRouteDiscoveryFragment} fragment may
+ * The {@link androidx.mediarouter.app.MediaRouteDiscoveryFragment} fragment may
* also be used for this purpose.
* </p><p class="note">
* On {@link ActivityManager#isLowRamDevice low-RAM devices} this flag
@@ -182,7 +183,7 @@
* {@link #addCallback(MediaRouteSelector, Callback, int) addCallback} for details.
* </p>
*
- * @see android.support.v7.app.MediaRouteDiscoveryFragment
+ * @see androidx.mediarouter.app.MediaRouteDiscoveryFragment
*/
public static final int CALLBACK_FLAG_REQUEST_DISCOVERY = 1 << 2;
@@ -197,7 +198,7 @@
* {@link #addCallback(MediaRouteSelector, Callback, int) addCallback} for details.
* </p>
*
- * @see android.support.v7.app.MediaRouteDiscoveryFragment
+ * @see androidx.mediarouter.app.MediaRouteDiscoveryFragment
*/
public static final int CALLBACK_FLAG_FORCE_DISCOVERY = 1 << 3;
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaSessionStatus.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaSessionStatus.java
index 3206596..0e7514c 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaSessionStatus.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/media/MediaSessionStatus.java
@@ -19,7 +19,8 @@
import android.app.PendingIntent;
import android.os.Bundle;
import android.os.SystemClock;
-import android.support.v4.util.TimeUtils;
+
+import androidx.core.util.TimeUtils;
/**
* Describes the playback status of a media session.
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/RegisteredMediaRouteProvider.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/RegisteredMediaRouteProvider.java
index 98e4e28..eacf1c8 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/RegisteredMediaRouteProvider.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/media/RegisteredMediaRouteProvider.java
@@ -29,17 +29,20 @@
.CLIENT_MSG_RELEASE_ROUTE_CONTROLLER;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
.CLIENT_MSG_ROUTE_CONTROL_REQUEST;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_MSG_SELECT_ROUTE;
+import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
+ .CLIENT_MSG_SELECT_ROUTE;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
.CLIENT_MSG_SET_DISCOVERY_REQUEST;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
.CLIENT_MSG_SET_ROUTE_VOLUME;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_MSG_UNREGISTER;
+import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
+ .CLIENT_MSG_UNREGISTER;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
.CLIENT_MSG_UNSELECT_ROUTE;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
.CLIENT_MSG_UPDATE_ROUTE_VOLUME;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.CLIENT_VERSION_CURRENT;
+import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
+ .CLIENT_VERSION_CURRENT;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.SERVICE_DATA_ERROR;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
.SERVICE_MSG_CONTROL_REQUEST_FAILED;
@@ -51,9 +54,11 @@
.SERVICE_MSG_GENERIC_FAILURE;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
.SERVICE_MSG_GENERIC_SUCCESS;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.SERVICE_MSG_REGISTERED;
+import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
+ .SERVICE_MSG_REGISTERED;
import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.SERVICE_VERSION_1;
-import static com.android.support.mediarouter.media.MediaRouteProviderProtocol.isValidRemoteMessenger;
+import static com.android.support.mediarouter.media.MediaRouteProviderProtocol
+ .isValidRemoteMessenger;
import android.annotation.NonNull;
import android.content.ComponentName;
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/RemoteControlClientCompat.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/RemoteControlClientCompat.java
index 826449b..65c5518 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/RemoteControlClientCompat.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/media/RemoteControlClientCompat.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.media.AudioManager;
import android.os.Build;
-import android.support.annotation.RequiresApi;
import java.lang.ref.WeakReference;
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/RemotePlaybackClient.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/RemotePlaybackClient.java
index f6e1497..e76564e 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/RemotePlaybackClient.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/media/RemotePlaybackClient.java
@@ -22,9 +22,10 @@
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
-import android.support.v4.util.ObjectsCompat;
import android.util.Log;
+import androidx.core.util.ObjectsCompat;
+
/**
* A helper class for playing media on remote routes using the remote playback protocol
* defined by {@link MediaControlIntent}.
@@ -867,11 +868,11 @@
private final class ActionReceiver extends BroadcastReceiver {
public static final String ACTION_ITEM_STATUS_CHANGED =
- "android.support.v7.media.actions.ACTION_ITEM_STATUS_CHANGED";
+ "androidx.mediarouter.media.actions.ACTION_ITEM_STATUS_CHANGED";
public static final String ACTION_SESSION_STATUS_CHANGED =
- "android.support.v7.media.actions.ACTION_SESSION_STATUS_CHANGED";
+ "androidx.mediarouter.media.actions.ACTION_SESSION_STATUS_CHANGED";
public static final String ACTION_MESSAGE_RECEIVED =
- "android.support.v7.media.actions.ACTION_MESSAGE_RECEIVED";
+ "androidx.mediarouter.media.actions.ACTION_MESSAGE_RECEIVED";
ActionReceiver() {
}
diff --git a/packages/MediaComponents/src/com/android/support/mediarouter/media/SystemMediaRouteProvider.java b/packages/MediaComponents/src/com/android/support/mediarouter/media/SystemMediaRouteProvider.java
index a38491f..53901a4 100644
--- a/packages/MediaComponents/src/com/android/support/mediarouter/media/SystemMediaRouteProvider.java
+++ b/packages/MediaComponents/src/com/android/support/mediarouter/media/SystemMediaRouteProvider.java
@@ -24,7 +24,6 @@
import android.content.res.Resources;
import android.media.AudioManager;
import android.os.Build;
-import android.support.annotation.RequiresApi;
import android.view.Display;
import com.android.media.update.ApiHelper;
diff --git a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
index 3aff150..ad85af4 100644
--- a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
@@ -20,15 +20,13 @@
import android.content.res.Resources;
import android.graphics.Point;
import android.media.MediaMetadata;
+import android.media.SessionToken2;
import android.media.session.MediaController;
import android.media.session.PlaybackState;
-import android.media.SessionToken2;
import android.media.update.MediaControlView2Provider;
import android.media.update.ViewGroupProvider;
import android.os.Bundle;
-import android.support.annotation.Nullable;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
@@ -36,27 +34,28 @@
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
-import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.MediaControlView2;
-import android.widget.ProgressBar;
import android.widget.PopupWindow;
+import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
+import androidx.annotation.Nullable;
+
import com.android.media.update.ApiHelper;
import com.android.media.update.R;
import com.android.support.mediarouter.app.MediaRouteButton;
-import com.android.support.mediarouter.media.MediaRouter;
import com.android.support.mediarouter.media.MediaRouteSelector;
+import com.android.support.mediarouter.media.MediaRouter;
-import java.util.Arrays;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Formatter;
import java.util.List;
import java.util.Locale;
diff --git a/packages/MediaComponents/src/com/android/widget/SubtitleView.java b/packages/MediaComponents/src/com/android/widget/SubtitleView.java
index 67b2cd1..db0ae33 100644
--- a/packages/MediaComponents/src/com/android/widget/SubtitleView.java
+++ b/packages/MediaComponents/src/com/android/widget/SubtitleView.java
@@ -19,10 +19,11 @@
import android.content.Context;
import android.graphics.Canvas;
import android.os.Looper;
-import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.FrameLayout;
+import androidx.annotation.Nullable;
+
import com.android.media.subtitle.SubtitleController.Anchor;
import com.android.media.subtitle.SubtitleTrack.RenderingWidget;
diff --git a/packages/MediaComponents/src/com/android/widget/VideoSurfaceView.java b/packages/MediaComponents/src/com/android/widget/VideoSurfaceView.java
index fc92e85..c9869c0 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoSurfaceView.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoSurfaceView.java
@@ -16,17 +16,18 @@
package com.android.widget;
+import static android.widget.VideoView2.VIEW_TYPE_SURFACEVIEW;
+
import android.content.Context;
import android.graphics.Rect;
import android.media.MediaPlayer2;
-import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
-import static android.widget.VideoView2.VIEW_TYPE_SURFACEVIEW;
+import androidx.annotation.NonNull;
class VideoSurfaceView extends SurfaceView implements VideoViewInterface, SurfaceHolder.Callback {
private static final String TAG = "VideoSurfaceView";
diff --git a/packages/MediaComponents/src/com/android/widget/VideoTextureView.java b/packages/MediaComponents/src/com/android/widget/VideoTextureView.java
index 024a3aa..40fb046 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoTextureView.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoTextureView.java
@@ -16,18 +16,19 @@
package com.android.widget;
+import static android.widget.VideoView2.VIEW_TYPE_TEXTUREVIEW;
+
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer2;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
-import static android.widget.VideoView2.VIEW_TYPE_TEXTUREVIEW;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
@RequiresApi(26)
class VideoTextureView extends TextureView
diff --git a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
index 97279d6..ffb145a 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
@@ -28,30 +28,29 @@
import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.media.DataSourceDesc;
+import android.media.MediaItem2;
import android.media.MediaMetadata;
+import android.media.MediaMetadata2;
+import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer2;
import android.media.MediaPlayer2.MediaPlayer2EventCallback;
import android.media.MediaPlayer2.OnSubtitleDataListener;
import android.media.MediaPlayer2Impl;
-import android.media.SubtitleData;
-import android.media.MediaItem2;
-import android.media.MediaMetadata2;
-import android.media.MediaMetadataRetriever;
import android.media.Metadata;
import android.media.PlaybackParams;
+import android.media.SessionToken2;
+import android.media.SubtitleData;
import android.media.TimedText;
import android.media.session.MediaController;
import android.media.session.MediaController.PlaybackInfo;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
-import android.media.SessionToken2;
import android.media.update.VideoView2Provider;
import android.media.update.ViewGroupProvider;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.ResultReceiver;
-import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -66,6 +65,8 @@
import android.widget.TextView;
import android.widget.VideoView2;
+import androidx.annotation.Nullable;
+
import com.android.internal.graphics.palette.Palette;
import com.android.media.RoutePlayer;
import com.android.media.subtitle.ClosedCaptionRenderer;
@@ -73,10 +74,10 @@
import com.android.media.subtitle.SubtitleTrack;
import com.android.media.update.ApiHelper;
import com.android.media.update.R;
-import com.android.support.mediarouter.media.MediaItemStatus;
import com.android.support.mediarouter.media.MediaControlIntent;
-import com.android.support.mediarouter.media.MediaRouter;
+import com.android.support.mediarouter.media.MediaItemStatus;
import com.android.support.mediarouter.media.MediaRouteSelector;
+import com.android.support.mediarouter.media.MediaRouter;
import java.util.ArrayList;
import java.util.List;
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 7419e64..78a62ca 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -2,24 +2,6 @@
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := \
- ServiceUtilities.cpp
-
-# FIXME Move this library to frameworks/native
-LOCAL_MODULE := libserviceutility
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- liblog \
- libbinder
-
-LOCAL_CFLAGS := -Wall -Werror
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
LOCAL_SRC_FILES:= \
AudioFlinger.cpp \
Threads.cpp \
@@ -53,7 +35,6 @@
libnbaio \
libnblog \
libpowermanager \
- libserviceutility \
libmediautils \
libmemunreachable \
libmedia_helper
@@ -82,6 +63,7 @@
LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_CFLAGS += -Werror -Wall
+LOCAL_SANITIZE := integer_overflow
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index bdd39c6..f165c31 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -47,7 +47,6 @@
#include <system/audio.h>
#include "AudioFlinger.h"
-#include "ServiceUtilities.h"
#include <media/AudioResamplerPublic.h>
@@ -66,6 +65,7 @@
#include <media/nbaio/PipeReader.h>
#include <media/AudioParameter.h>
#include <mediautils/BatteryNotifier.h>
+#include <mediautils/ServiceUtilities.h>
#include <private/android_filesystem_config.h>
//#define BUFLOG_NDEBUG 0
@@ -160,6 +160,7 @@
mTotalMemory(0),
mClientSharedHeapSize(kMinimumClientSharedHeapSizeBytes),
mGlobalEffectEnableTime(0),
+ mPatchPanel(this),
mSystemReady(false)
{
// unsigned instead of audio_unique_id_use_t, because ++ operator is unavailable for enum
@@ -226,8 +227,6 @@
}
}
- mPatchPanel = new PatchPanel(this);
-
mMode = AUDIO_MODE_NORMAL;
gAudioFlinger = this;
@@ -534,6 +533,8 @@
dev->dump(fd);
}
+ mPatchPanel.dump(fd);
+
#ifdef TEE_SINK
// dump the serially shared record tee sink
if (mRecordTeeSource != 0) {
@@ -1930,6 +1931,28 @@
return mClientSharedHeapSize;
}
+status_t AudioFlinger::setAudioPortConfig(const struct audio_port_config *config)
+{
+ ALOGV(__func__);
+
+ audio_module_handle_t module;
+ if (config->type == AUDIO_PORT_TYPE_DEVICE) {
+ module = config->ext.device.hw_module;
+ } else {
+ module = config->ext.mix.hw_module;
+ }
+
+ Mutex::Autolock _l(mLock);
+ ssize_t index = mAudioHwDevs.indexOfKey(module);
+ if (index < 0) {
+ ALOGW("%s() bad hw module %d", __func__, module);
+ return BAD_VALUE;
+ }
+
+ AudioHwDevice *audioHwDevice = mAudioHwDevs.valueAt(index);
+ return audioHwDevice->hwDevice()->setAudioPortConfig(config);
+}
+
audio_hw_sync_t AudioFlinger::getAudioHwSyncForSession(audio_session_t sessionId)
{
Mutex::Autolock _l(mLock);
@@ -2274,7 +2297,7 @@
delete out;
}
-void AudioFlinger::closeOutputInternal_l(const sp<PlaybackThread>& thread)
+void AudioFlinger::closeThreadInternal_l(const sp<PlaybackThread>& thread)
{
mPlaybackThreads.removeItem(thread->mId);
thread->exit();
@@ -2567,7 +2590,7 @@
delete in;
}
-void AudioFlinger::closeInputInternal_l(const sp<RecordThread>& thread)
+void AudioFlinger::closeThreadInternal_l(const sp<RecordThread>& thread)
{
mRecordThreads.removeItem(thread->mId);
closeInputFinish(thread);
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 963a87d..7cfe542 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -791,9 +791,9 @@
// for use from destructor
status_t closeOutput_nonvirtual(audio_io_handle_t output);
- void closeOutputInternal_l(const sp<PlaybackThread>& thread);
+ void closeThreadInternal_l(const sp<PlaybackThread>& thread);
status_t closeInput_nonvirtual(audio_io_handle_t input);
- void closeInputInternal_l(const sp<RecordThread>& thread);
+ void closeThreadInternal_l(const sp<RecordThread>& thread);
void setAudioHwSyncForSession_l(PlaybackThread *thread, audio_session_t sessionId);
status_t checkStreamType(audio_stream_type_t stream) const;
@@ -843,7 +843,8 @@
nsecs_t mGlobalEffectEnableTime; // when a global effect was last enabled
- sp<PatchPanel> mPatchPanel;
+ // protected by mLock
+ PatchPanel mPatchPanel;
sp<EffectsFactoryHalInterface> mEffectsFactoryHal;
bool mSystemReady;
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 2047dfd..f89c6db 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -31,9 +31,9 @@
#include <media/AudioEffect.h>
#include <media/audiohal/EffectHalInterface.h>
#include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <mediautils/ServiceUtilities.h>
#include "AudioFlinger.h"
-#include "ServiceUtilities.h"
// ----------------------------------------------------------------------------
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index e5cb8a2..a08da96 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -24,8 +24,9 @@
#include <audio_utils/primitives.h>
#include "AudioFlinger.h"
-#include "ServiceUtilities.h"
#include <media/AudioParameter.h>
+#include <media/PatchBuilder.h>
+#include <mediautils/ServiceUtilities.h>
// ----------------------------------------------------------------------------
@@ -49,107 +50,65 @@
struct audio_port *ports)
{
Mutex::Autolock _l(mLock);
- if (mPatchPanel != 0) {
- return mPatchPanel->listAudioPorts(num_ports, ports);
- }
- return NO_INIT;
+ return mPatchPanel.listAudioPorts(num_ports, ports);
}
/* Get supported attributes for a given audio port */
status_t AudioFlinger::getAudioPort(struct audio_port *port)
{
Mutex::Autolock _l(mLock);
- if (mPatchPanel != 0) {
- return mPatchPanel->getAudioPort(port);
- }
- return NO_INIT;
+ return mPatchPanel.getAudioPort(port);
}
-
/* Connect a patch between several source and sink ports */
status_t AudioFlinger::createAudioPatch(const struct audio_patch *patch,
audio_patch_handle_t *handle)
{
Mutex::Autolock _l(mLock);
- if (mPatchPanel != 0) {
- return mPatchPanel->createAudioPatch(patch, handle);
- }
- return NO_INIT;
+ return mPatchPanel.createAudioPatch(patch, handle);
}
/* Disconnect a patch */
status_t AudioFlinger::releaseAudioPatch(audio_patch_handle_t handle)
{
Mutex::Autolock _l(mLock);
- if (mPatchPanel != 0) {
- return mPatchPanel->releaseAudioPatch(handle);
- }
- return NO_INIT;
+ return mPatchPanel.releaseAudioPatch(handle);
}
-
/* List connected audio ports and they attributes */
status_t AudioFlinger::listAudioPatches(unsigned int *num_patches,
struct audio_patch *patches)
{
Mutex::Autolock _l(mLock);
- if (mPatchPanel != 0) {
- return mPatchPanel->listAudioPatches(num_patches, patches);
- }
- return NO_INIT;
-}
-
-/* Set audio port configuration */
-status_t AudioFlinger::setAudioPortConfig(const struct audio_port_config *config)
-{
- Mutex::Autolock _l(mLock);
- if (mPatchPanel != 0) {
- return mPatchPanel->setAudioPortConfig(config);
- }
- return NO_INIT;
-}
-
-
-AudioFlinger::PatchPanel::PatchPanel(const sp<AudioFlinger>& audioFlinger)
- : mAudioFlinger(audioFlinger)
-{
-}
-
-AudioFlinger::PatchPanel::~PatchPanel()
-{
+ return mPatchPanel.listAudioPatches(num_patches, patches);
}
/* List connected audio ports and their attributes */
status_t AudioFlinger::PatchPanel::listAudioPorts(unsigned int *num_ports __unused,
struct audio_port *ports __unused)
{
- ALOGV("listAudioPorts");
+ ALOGV(__func__);
return NO_ERROR;
}
/* Get supported attributes for a given audio port */
status_t AudioFlinger::PatchPanel::getAudioPort(struct audio_port *port __unused)
{
- ALOGV("getAudioPort");
+ ALOGV(__func__);
return NO_ERROR;
}
-
/* Connect a patch between several source and sink ports */
status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *patch,
audio_patch_handle_t *handle)
{
- status_t status = NO_ERROR;
- audio_patch_handle_t halHandle = AUDIO_PATCH_HANDLE_NONE;
- sp<AudioFlinger> audioflinger = mAudioFlinger.promote();
if (handle == NULL || patch == NULL) {
return BAD_VALUE;
}
- ALOGV("createAudioPatch() num_sources %d num_sinks %d handle %d",
- patch->num_sources, patch->num_sinks, *handle);
- if (audioflinger == 0) {
- return NO_INIT;
- }
+ ALOGV("%s() num_sources %d num_sinks %d handle %d",
+ __func__, patch->num_sources, patch->num_sinks, *handle);
+ status_t status = NO_ERROR;
+ audio_patch_handle_t halHandle = AUDIO_PATCH_HANDLE_NONE;
if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX ||
(patch->num_sinks == 0 && patch->num_sources != 2) ||
@@ -163,81 +122,73 @@
}
if (*handle != AUDIO_PATCH_HANDLE_NONE) {
- for (size_t index = 0; *handle != 0 && index < mPatches.size(); index++) {
- if (*handle == mPatches[index]->mHandle) {
- ALOGV("createAudioPatch() removing patch handle %d", *handle);
- halHandle = mPatches[index]->mHalHandle;
- Patch *removedPatch = mPatches[index];
- // free resources owned by the removed patch if applicable
- // 1) if a software patch is present, release the playback and capture threads and
- // tracks created. This will also release the corresponding audio HAL patches
- if ((removedPatch->mRecordPatchHandle
- != AUDIO_PATCH_HANDLE_NONE) ||
- (removedPatch->mPlaybackPatchHandle !=
- AUDIO_PATCH_HANDLE_NONE)) {
- clearPatchConnections(removedPatch);
- }
- // 2) if the new patch and old patch source or sink are devices from different
- // hw modules, clear the audio HAL patches now because they will not be updated
- // by call to create_audio_patch() below which will happen on a different HW module
- if (halHandle != AUDIO_PATCH_HANDLE_NONE) {
- audio_module_handle_t hwModule = AUDIO_MODULE_HANDLE_NONE;
- if ((removedPatch->mAudioPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE) &&
- ((patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE) ||
- (removedPatch->mAudioPatch.sources[0].ext.device.hw_module !=
- patch->sources[0].ext.device.hw_module))) {
- hwModule = removedPatch->mAudioPatch.sources[0].ext.device.hw_module;
- } else if ((patch->num_sinks == 0) ||
- ((removedPatch->mAudioPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE) &&
- ((patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE) ||
- (removedPatch->mAudioPatch.sinks[0].ext.device.hw_module !=
- patch->sinks[0].ext.device.hw_module)))) {
- // Note on (patch->num_sinks == 0): this situation should not happen as
- // these special patches are only created by the policy manager but just
- // in case, systematically clear the HAL patch.
- // Note that removedPatch->mAudioPatch.num_sinks cannot be 0 here because
- // halHandle would be AUDIO_PATCH_HANDLE_NONE in this case.
- hwModule = removedPatch->mAudioPatch.sinks[0].ext.device.hw_module;
- }
- if (hwModule != AUDIO_MODULE_HANDLE_NONE) {
- ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(hwModule);
- if (index >= 0) {
- sp<DeviceHalInterface> hwDevice =
- audioflinger->mAudioHwDevs.valueAt(index)->hwDevice();
- hwDevice->releaseAudioPatch(halHandle);
- }
- }
- }
- mPatches.removeAt(index);
- delete removedPatch;
- break;
+ auto iter = mPatches.find(*handle);
+ if (iter != mPatches.end()) {
+ ALOGV("%s() removing patch handle %d", __func__, *handle);
+ Patch &removedPatch = iter->second;
+ // free resources owned by the removed patch if applicable
+ // 1) if a software patch is present, release the playback and capture threads and
+ // tracks created. This will also release the corresponding audio HAL patches
+ if (removedPatch.isSoftware()) {
+ removedPatch.clearConnections(this);
}
+ // 2) if the new patch and old patch source or sink are devices from different
+ // hw modules, clear the audio HAL patches now because they will not be updated
+ // by call to create_audio_patch() below which will happen on a different HW module
+ if (removedPatch.mHalHandle != AUDIO_PATCH_HANDLE_NONE) {
+ audio_module_handle_t hwModule = AUDIO_MODULE_HANDLE_NONE;
+ const struct audio_patch &oldPatch = removedPatch.mAudioPatch;
+ if (oldPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE &&
+ (patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE ||
+ oldPatch.sources[0].ext.device.hw_module !=
+ patch->sources[0].ext.device.hw_module)) {
+ hwModule = oldPatch.sources[0].ext.device.hw_module;
+ } else if (patch->num_sinks == 0 ||
+ (oldPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE &&
+ (patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE ||
+ oldPatch.sinks[0].ext.device.hw_module !=
+ patch->sinks[0].ext.device.hw_module))) {
+ // Note on (patch->num_sinks == 0): this situation should not happen as
+ // these special patches are only created by the policy manager but just
+ // in case, systematically clear the HAL patch.
+ // Note that removedPatch.mAudioPatch.num_sinks cannot be 0 here because
+ // removedPatch.mHalHandle would be AUDIO_PATCH_HANDLE_NONE in this case.
+ hwModule = oldPatch.sinks[0].ext.device.hw_module;
+ }
+ sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(hwModule);
+ if (hwDevice != 0) {
+ hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
+ }
+ }
+ mPatches.erase(iter);
}
}
- Patch *newPatch = new Patch(patch);
+ Patch newPatch{*patch};
switch (patch->sources[0].type) {
case AUDIO_PORT_TYPE_DEVICE: {
audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module;
- ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(srcModule);
+ ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(srcModule);
if (index < 0) {
- ALOGW("createAudioPatch() bad src hw module %d", srcModule);
+ ALOGW("%s() bad src hw module %d", __func__, srcModule);
status = BAD_VALUE;
goto exit;
}
- AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index);
+ AudioHwDevice *audioHwDevice = mAudioFlinger.mAudioHwDevs.valueAt(index);
for (unsigned int i = 0; i < patch->num_sinks; i++) {
// support only one sink if connection to a mix or across HW modules
if ((patch->sinks[i].type == AUDIO_PORT_TYPE_MIX ||
- patch->sinks[i].ext.mix.hw_module != srcModule) &&
+ (patch->sinks[i].type == AUDIO_PORT_TYPE_DEVICE &&
+ patch->sinks[i].ext.device.hw_module != srcModule)) &&
patch->num_sinks > 1) {
+ ALOGW("%s() multiple sinks for mix or across modules not supported", __func__);
status = INVALID_OPERATION;
goto exit;
}
// reject connection to different sink types
if (patch->sinks[i].type != patch->sinks[0].type) {
- ALOGW("createAudioPatch() different sink types in same patch not supported");
+ ALOGW("%s() different sink types in same patch not supported", __func__);
status = BAD_VALUE;
goto exit;
}
@@ -256,38 +207,39 @@
if (patch->sources[1].type != AUDIO_PORT_TYPE_MIX ||
(patch->num_sinks != 0 && patch->sinks[0].ext.device.hw_module !=
patch->sources[1].ext.mix.hw_module)) {
- ALOGW("createAudioPatch() invalid source combination");
+ ALOGW("%s() invalid source combination", __func__);
status = INVALID_OPERATION;
goto exit;
}
sp<ThreadBase> thread =
- audioflinger->checkPlaybackThread_l(patch->sources[1].ext.mix.handle);
- newPatch->mPlaybackThread = (MixerThread *)thread.get();
+ mAudioFlinger.checkPlaybackThread_l(patch->sources[1].ext.mix.handle);
if (thread == 0) {
- ALOGW("createAudioPatch() cannot get playback thread");
+ ALOGW("%s() cannot get playback thread", __func__);
status = INVALID_OPERATION;
goto exit;
}
+ // existing playback thread is reused, so it is not closed when patch is cleared
+ newPatch.mPlayback.setThread(
+ reinterpret_cast<PlaybackThread*>(thread.get()), false /*closeThread*/);
} else {
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
audio_devices_t device = patch->sinks[0].ext.device.type;
String8 address = String8(patch->sinks[0].ext.device.address);
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
- sp<ThreadBase> thread = audioflinger->openOutput_l(
+ sp<ThreadBase> thread = mAudioFlinger.openOutput_l(
patch->sinks[0].ext.device.hw_module,
&output,
&config,
device,
address,
AUDIO_OUTPUT_FLAG_NONE);
- newPatch->mPlaybackThread = (PlaybackThread *)thread.get();
- ALOGV("audioflinger->openOutput_l() returned %p",
- newPatch->mPlaybackThread.get());
- if (newPatch->mPlaybackThread == 0) {
+ ALOGV("mAudioFlinger.openOutput_l() returned %p", thread.get());
+ if (thread == 0) {
status = NO_MEMORY;
goto exit;
}
+ newPatch.mPlayback.setThread(reinterpret_cast<PlaybackThread*>(thread.get()));
}
audio_devices_t device = patch->sources[0].ext.device.type;
String8 address = String8(patch->sources[0].ext.device.address);
@@ -297,47 +249,47 @@
if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
config.sample_rate = patch->sources[0].sample_rate;
} else {
- config.sample_rate = newPatch->mPlaybackThread->sampleRate();
+ config.sample_rate = newPatch.mPlayback.thread()->sampleRate();
}
if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
config.channel_mask = patch->sources[0].channel_mask;
} else {
- config.channel_mask =
- audio_channel_in_mask_from_count(newPatch->mPlaybackThread->channelCount());
+ config.channel_mask = audio_channel_in_mask_from_count(
+ newPatch.mPlayback.thread()->channelCount());
}
if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) {
config.format = patch->sources[0].format;
} else {
- config.format = newPatch->mPlaybackThread->format();
+ config.format = newPatch.mPlayback.thread()->format();
}
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
- sp<ThreadBase> thread = audioflinger->openInput_l(srcModule,
+ sp<ThreadBase> thread = mAudioFlinger.openInput_l(srcModule,
&input,
&config,
device,
address,
AUDIO_SOURCE_MIC,
AUDIO_INPUT_FLAG_NONE);
- newPatch->mRecordThread = (RecordThread *)thread.get();
- ALOGV("audioflinger->openInput_l() returned %p inChannelMask %08x",
- newPatch->mRecordThread.get(), config.channel_mask);
- if (newPatch->mRecordThread == 0) {
+ ALOGV("mAudioFlinger.openInput_l() returned %p inChannelMask %08x",
+ thread.get(), config.channel_mask);
+ if (thread == 0) {
status = NO_MEMORY;
goto exit;
}
- status = createPatchConnections(newPatch, patch);
+ newPatch.mRecord.setThread(reinterpret_cast<RecordThread*>(thread.get()));
+ status = newPatch.createConnections(this);
if (status != NO_ERROR) {
goto exit;
}
} else {
if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
- sp<ThreadBase> thread = audioflinger->checkRecordThread_l(
+ sp<ThreadBase> thread = mAudioFlinger.checkRecordThread_l(
patch->sinks[0].ext.mix.handle);
if (thread == 0) {
- thread = audioflinger->checkMmapThread_l(patch->sinks[0].ext.mix.handle);
+ thread = mAudioFlinger.checkMmapThread_l(patch->sinks[0].ext.mix.handle);
if (thread == 0) {
- ALOGW("createAudioPatch() bad capture I/O handle %d",
- patch->sinks[0].ext.mix.handle);
+ ALOGW("%s() bad capture I/O handle %d",
+ __func__, patch->sinks[0].ext.mix.handle);
status = BAD_VALUE;
goto exit;
}
@@ -356,9 +308,9 @@
} break;
case AUDIO_PORT_TYPE_MIX: {
audio_module_handle_t srcModule = patch->sources[0].ext.mix.hw_module;
- ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(srcModule);
+ ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(srcModule);
if (index < 0) {
- ALOGW("createAudioPatch() bad src hw module %d", srcModule);
+ ALOGW("%s() bad src hw module %d", __func__, srcModule);
status = BAD_VALUE;
goto exit;
}
@@ -366,8 +318,8 @@
audio_devices_t type = AUDIO_DEVICE_NONE;
for (unsigned int i = 0; i < patch->num_sinks; i++) {
if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
- ALOGW("createAudioPatch() invalid sink type %d for mix source",
- patch->sinks[i].type);
+ ALOGW("%s() invalid sink type %d for mix source",
+ __func__, patch->sinks[i].type);
status = BAD_VALUE;
goto exit;
}
@@ -379,21 +331,21 @@
type |= patch->sinks[i].ext.device.type;
}
sp<ThreadBase> thread =
- audioflinger->checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
+ mAudioFlinger.checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
if (thread == 0) {
- thread = audioflinger->checkMmapThread_l(patch->sources[0].ext.mix.handle);
+ thread = mAudioFlinger.checkMmapThread_l(patch->sources[0].ext.mix.handle);
if (thread == 0) {
- ALOGW("createAudioPatch() bad playback I/O handle %d",
- patch->sources[0].ext.mix.handle);
+ ALOGW("%s() bad playback I/O handle %d",
+ __func__, patch->sources[0].ext.mix.handle);
status = BAD_VALUE;
goto exit;
}
}
- if (thread == audioflinger->primaryPlaybackThread_l()) {
+ if (thread == mAudioFlinger.primaryPlaybackThread_l()) {
AudioParameter param = AudioParameter();
param.addInt(String8(AudioParameter::keyRouting), (int)type);
- audioflinger->broacastParametersToRecordThreads_l(param.toString());
+ mAudioFlinger.broacastParametersToRecordThreads_l(param.toString());
}
status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
@@ -403,72 +355,70 @@
goto exit;
}
exit:
- ALOGV("createAudioPatch() status %d", status);
+ ALOGV("%s() status %d", __func__, status);
if (status == NO_ERROR) {
- *handle = (audio_patch_handle_t) audioflinger->nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH);
- newPatch->mHandle = *handle;
- newPatch->mHalHandle = halHandle;
- mPatches.add(newPatch);
- ALOGV("createAudioPatch() added new patch handle %d halHandle %d", *handle, halHandle);
+ *handle = (audio_patch_handle_t) mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH);
+ newPatch.mHalHandle = halHandle;
+ mPatches.insert(std::make_pair(*handle, std::move(newPatch)));
+ ALOGV("%s() added new patch handle %d halHandle %d", __func__, *handle, halHandle);
} else {
- clearPatchConnections(newPatch);
- delete newPatch;
+ newPatch.clearConnections(this);
}
return status;
}
-status_t AudioFlinger::PatchPanel::createPatchConnections(Patch *patch,
- const struct audio_patch *audioPatch)
+AudioFlinger::PatchPanel::Patch::~Patch()
+{
+ ALOGE_IF(isSoftware(), "Software patch connections leaked %d %d",
+ mRecord.handle(), mPlayback.handle());
+}
+
+status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
{
// create patch from source device to record thread input
- struct audio_patch subPatch;
- subPatch.num_sources = 1;
- subPatch.sources[0] = audioPatch->sources[0];
- subPatch.num_sinks = 1;
-
- patch->mRecordThread->getAudioPortConfig(&subPatch.sinks[0]);
- subPatch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_MIC;
-
- status_t status = createAudioPatch(&subPatch, &patch->mRecordPatchHandle);
+ status_t status = panel->createAudioPatch(
+ PatchBuilder().addSource(mAudioPatch.sources[0]).
+ addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(),
+ mRecord.handlePtr());
if (status != NO_ERROR) {
- patch->mRecordPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+ *mRecord.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
return status;
}
// create patch from playback thread output to sink device
- if (audioPatch->num_sinks != 0) {
- patch->mPlaybackThread->getAudioPortConfig(&subPatch.sources[0]);
- subPatch.sinks[0] = audioPatch->sinks[0];
- status = createAudioPatch(&subPatch, &patch->mPlaybackPatchHandle);
+ if (mAudioPatch.num_sinks != 0) {
+ status = panel->createAudioPatch(
+ PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(),
+ mPlayback.handlePtr());
if (status != NO_ERROR) {
- patch->mPlaybackPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+ *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
return status;
}
} else {
- patch->mPlaybackPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+ *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
}
// use a pseudo LCM between input and output framecount
- size_t playbackFrameCount = patch->mPlaybackThread->frameCount();
+ size_t playbackFrameCount = mPlayback.thread()->frameCount();
int playbackShift = __builtin_ctz(playbackFrameCount);
- size_t recordFramecount = patch->mRecordThread->frameCount();
+ size_t recordFramecount = mRecord.thread()->frameCount();
int shift = __builtin_ctz(recordFramecount);
if (playbackShift < shift) {
shift = playbackShift;
}
size_t frameCount = (playbackFrameCount * recordFramecount) >> shift;
- ALOGV("createPatchConnections() playframeCount %zu recordFramecount %zu frameCount %zu",
- playbackFrameCount, recordFramecount, frameCount);
+ ALOGV("%s() playframeCount %zu recordFramecount %zu frameCount %zu",
+ __func__, playbackFrameCount, recordFramecount, frameCount);
// create a special record track to capture from record thread
- uint32_t channelCount = patch->mPlaybackThread->channelCount();
+ uint32_t channelCount = mPlayback.thread()->channelCount();
audio_channel_mask_t inChannelMask = audio_channel_in_mask_from_count(channelCount);
- audio_channel_mask_t outChannelMask = patch->mPlaybackThread->channelMask();
- uint32_t sampleRate = patch->mPlaybackThread->sampleRate();
- audio_format_t format = patch->mPlaybackThread->format();
+ audio_channel_mask_t outChannelMask = mPlayback.thread()->channelMask();
+ uint32_t sampleRate = mPlayback.thread()->sampleRate();
+ audio_format_t format = mPlayback.thread()->format();
- patch->mPatchRecord = new RecordThread::PatchRecord(
- patch->mRecordThread.get(),
+ sp<RecordThread::PatchRecord> tempRecordTrack = new (std::nothrow) RecordThread::PatchRecord(
+ mRecord.thread().get(),
sampleRate,
inChannelMask,
format,
@@ -476,222 +426,165 @@
NULL,
(size_t)0 /* bufferSize */,
AUDIO_INPUT_FLAG_NONE);
- if (patch->mPatchRecord == 0) {
- return NO_MEMORY;
- }
- status = patch->mPatchRecord->initCheck();
+ status = mRecord.checkTrack(tempRecordTrack.get());
if (status != NO_ERROR) {
return status;
}
- patch->mRecordThread->addPatchRecord(patch->mPatchRecord);
// create a special playback track to render to playback thread.
// this track is given the same buffer as the PatchRecord buffer
- patch->mPatchTrack = new PlaybackThread::PatchTrack(
- patch->mPlaybackThread.get(),
- audioPatch->sources[1].ext.mix.usecase.stream,
+ sp<PlaybackThread::PatchTrack> tempPatchTrack = new (std::nothrow) PlaybackThread::PatchTrack(
+ mPlayback.thread().get(),
+ mAudioPatch.sources[1].ext.mix.usecase.stream,
sampleRate,
outChannelMask,
format,
frameCount,
- patch->mPatchRecord->buffer(),
- patch->mPatchRecord->bufferSize(),
+ tempRecordTrack->buffer(),
+ tempRecordTrack->bufferSize(),
AUDIO_OUTPUT_FLAG_NONE);
- status = patch->mPatchTrack->initCheck();
+ status = mPlayback.checkTrack(tempPatchTrack.get());
if (status != NO_ERROR) {
return status;
}
- patch->mPlaybackThread->addPatchTrack(patch->mPatchTrack);
// tie playback and record tracks together
- patch->mPatchRecord->setPeerProxy(patch->mPatchTrack.get());
- patch->mPatchTrack->setPeerProxy(patch->mPatchRecord.get());
+ mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack.get());
+ mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack.get());
// start capture and playback
- patch->mPatchRecord->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
- patch->mPatchTrack->start();
+ mRecord.track()->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
+ mPlayback.track()->start();
return status;
}
-void AudioFlinger::PatchPanel::clearPatchConnections(Patch *patch)
+void AudioFlinger::PatchPanel::Patch::clearConnections(PatchPanel *panel)
{
- sp<AudioFlinger> audioflinger = mAudioFlinger.promote();
- if (audioflinger == 0) {
- return;
- }
+ ALOGV("%s() mRecord.handle %d mPlayback.handle %d",
+ __func__, mRecord.handle(), mPlayback.handle());
+ mRecord.stopTrack();
+ mPlayback.stopTrack();
+ mRecord.closeConnections(panel);
+ mPlayback.closeConnections(panel);
+}
- ALOGV("clearPatchConnections() patch->mRecordPatchHandle %d patch->mPlaybackPatchHandle %d",
- patch->mRecordPatchHandle, patch->mPlaybackPatchHandle);
-
- if (patch->mPatchRecord != 0) {
- patch->mPatchRecord->stop();
- }
- if (patch->mPatchTrack != 0) {
- patch->mPatchTrack->stop();
- }
- if (patch->mRecordPatchHandle != AUDIO_PATCH_HANDLE_NONE) {
- releaseAudioPatch(patch->mRecordPatchHandle);
- patch->mRecordPatchHandle = AUDIO_PATCH_HANDLE_NONE;
- }
- if (patch->mPlaybackPatchHandle != AUDIO_PATCH_HANDLE_NONE) {
- releaseAudioPatch(patch->mPlaybackPatchHandle);
- patch->mPlaybackPatchHandle = AUDIO_PATCH_HANDLE_NONE;
- }
- if (patch->mRecordThread != 0) {
- if (patch->mPatchRecord != 0) {
- patch->mRecordThread->deletePatchRecord(patch->mPatchRecord);
- }
- audioflinger->closeInputInternal_l(patch->mRecordThread);
- }
- if (patch->mPlaybackThread != 0) {
- if (patch->mPatchTrack != 0) {
- patch->mPlaybackThread->deletePatchTrack(patch->mPatchTrack);
- }
- // if num sources == 2 we are reusing an existing playback thread so we do not close it
- if (patch->mAudioPatch.num_sources != 2) {
- audioflinger->closeOutputInternal_l(patch->mPlaybackThread);
- }
- }
- if (patch->mRecordThread != 0) {
- if (patch->mPatchRecord != 0) {
- patch->mPatchRecord.clear();
- }
- patch->mRecordThread.clear();
- }
- if (patch->mPlaybackThread != 0) {
- if (patch->mPatchTrack != 0) {
- patch->mPatchTrack.clear();
- }
- patch->mPlaybackThread.clear();
- }
-
+String8 AudioFlinger::PatchPanel::Patch::dump(audio_patch_handle_t myHandle)
+{
+ String8 result;
+ result.appendFormat("Patch %d: thread %p => thread %p\n",
+ myHandle, mRecord.thread().get(), mPlayback.thread().get());
+ return result;
}
/* Disconnect a patch */
status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle)
{
- ALOGV("releaseAudioPatch handle %d", handle);
+ ALOGV("%s handle %d", __func__, handle);
status_t status = NO_ERROR;
- size_t index;
- sp<AudioFlinger> audioflinger = mAudioFlinger.promote();
- if (audioflinger == 0) {
- return NO_INIT;
- }
-
- for (index = 0; index < mPatches.size(); index++) {
- if (handle == mPatches[index]->mHandle) {
- break;
- }
- }
- if (index == mPatches.size()) {
+ auto iter = mPatches.find(handle);
+ if (iter == mPatches.end()) {
return BAD_VALUE;
}
- Patch *removedPatch = mPatches[index];
- mPatches.removeAt(index);
+ Patch &removedPatch = iter->second;
+ const struct audio_patch &patch = removedPatch.mAudioPatch;
- struct audio_patch *patch = &removedPatch->mAudioPatch;
-
- switch (patch->sources[0].type) {
+ const struct audio_port_config &src = patch.sources[0];
+ switch (src.type) {
case AUDIO_PORT_TYPE_DEVICE: {
- audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module;
- ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(srcModule);
- if (index < 0) {
- ALOGW("releaseAudioPatch() bad src hw module %d", srcModule);
+ sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(src.ext.device.hw_module);
+ if (hwDevice == 0) {
+ ALOGW("%s() bad src hw module %d", __func__, src.ext.device.hw_module);
status = BAD_VALUE;
break;
}
- if (removedPatch->mRecordPatchHandle != AUDIO_PATCH_HANDLE_NONE ||
- removedPatch->mPlaybackPatchHandle != AUDIO_PATCH_HANDLE_NONE) {
- clearPatchConnections(removedPatch);
+ if (removedPatch.isSoftware()) {
+ removedPatch.clearConnections(this);
break;
}
- if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
- sp<ThreadBase> thread = audioflinger->checkRecordThread_l(
- patch->sinks[0].ext.mix.handle);
+ if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) {
+ audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle;
+ sp<ThreadBase> thread = mAudioFlinger.checkRecordThread_l(ioHandle);
if (thread == 0) {
- thread = audioflinger->checkMmapThread_l(patch->sinks[0].ext.mix.handle);
+ thread = mAudioFlinger.checkMmapThread_l(ioHandle);
if (thread == 0) {
- ALOGW("releaseAudioPatch() bad capture I/O handle %d",
- patch->sinks[0].ext.mix.handle);
+ ALOGW("%s() bad capture I/O handle %d", __func__, ioHandle);
status = BAD_VALUE;
break;
}
}
- status = thread->sendReleaseAudioPatchConfigEvent(removedPatch->mHalHandle);
+ status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
} else {
- AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index);
- sp<DeviceHalInterface> hwDevice = audioHwDevice->hwDevice();
- status = hwDevice->releaseAudioPatch(removedPatch->mHalHandle);
+ status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
}
} break;
case AUDIO_PORT_TYPE_MIX: {
- audio_module_handle_t srcModule = patch->sources[0].ext.mix.hw_module;
- ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(srcModule);
- if (index < 0) {
- ALOGW("releaseAudioPatch() bad src hw module %d", srcModule);
+ if (findHwDeviceByModule(src.ext.mix.hw_module) == 0) {
+ ALOGW("%s() bad src hw module %d", __func__, src.ext.mix.hw_module);
status = BAD_VALUE;
break;
}
- sp<ThreadBase> thread =
- audioflinger->checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
+ audio_io_handle_t ioHandle = src.ext.mix.handle;
+ sp<ThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(ioHandle);
if (thread == 0) {
- thread = audioflinger->checkMmapThread_l(patch->sources[0].ext.mix.handle);
+ thread = mAudioFlinger.checkMmapThread_l(ioHandle);
if (thread == 0) {
- ALOGW("releaseAudioPatch() bad playback I/O handle %d",
- patch->sources[0].ext.mix.handle);
+ ALOGW("%s() bad playback I/O handle %d", __func__, ioHandle);
status = BAD_VALUE;
break;
}
}
- status = thread->sendReleaseAudioPatchConfigEvent(removedPatch->mHalHandle);
+ status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
} break;
default:
status = BAD_VALUE;
- break;
}
- delete removedPatch;
+ mPatches.erase(iter);
return status;
}
-
/* List connected audio ports and they attributes */
status_t AudioFlinger::PatchPanel::listAudioPatches(unsigned int *num_patches __unused,
struct audio_patch *patches __unused)
{
- ALOGV("listAudioPatches");
+ ALOGV(__func__);
return NO_ERROR;
}
-/* Set audio port configuration */
-status_t AudioFlinger::PatchPanel::setAudioPortConfig(const struct audio_port_config *config)
+sp<DeviceHalInterface> AudioFlinger::PatchPanel::findHwDeviceByModule(audio_module_handle_t module)
{
- ALOGV("setAudioPortConfig");
-
- sp<AudioFlinger> audioflinger = mAudioFlinger.promote();
- if (audioflinger == 0) {
- return NO_INIT;
- }
-
- audio_module_handle_t module;
- if (config->type == AUDIO_PORT_TYPE_DEVICE) {
- module = config->ext.device.hw_module;
- } else {
- module = config->ext.mix.hw_module;
- }
-
- ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(module);
+ if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr;
+ ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(module);
if (index < 0) {
- ALOGW("setAudioPortConfig() bad hw module %d", module);
- return BAD_VALUE;
+ return nullptr;
}
+ return mAudioFlinger.mAudioHwDevs.valueAt(index)->hwDevice();
+}
- AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index);
- return audioHwDevice->hwDevice()->setAudioPortConfig(config);
+void AudioFlinger::PatchPanel::dump(int fd)
+{
+ // Only dump software patches.
+ bool headerPrinted = false;
+ for (auto& iter : mPatches) {
+ if (iter.second.isSoftware()) {
+ if (!headerPrinted) {
+ String8 header("\nSoftware patches:\n");
+ write(fd, header.string(), header.size());
+ headerPrinted = true;
+ }
+ String8 patchDump(" ");
+ patchDump.append(iter.second.dump(iter.first));
+ write(fd, patchDump.string(), patchDump.size());
+ }
+ }
+ if (headerPrinted) {
+ String8 trailing("\n");
+ write(fd, trailing.string(), trailing.size());
+ }
}
} // namespace android
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index d37c0d3..dff8ad2 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -19,13 +19,10 @@
#error This header file should only be included from AudioFlinger.h
#endif
-class PatchPanel : public RefBase {
+// PatchPanel is concealed within AudioFlinger, their lifetimes are the same.
+class PatchPanel {
public:
-
- class Patch;
-
- explicit PatchPanel(const sp<AudioFlinger>& audioFlinger);
- virtual ~PatchPanel();
+ explicit PatchPanel(AudioFlinger* audioFlinger) : mAudioFlinger(*audioFlinger) {}
/* List connected audio ports and their attributes */
status_t listAudioPorts(unsigned int *num_ports,
@@ -45,46 +42,100 @@
status_t listAudioPatches(unsigned int *num_patches,
struct audio_patch *patches);
- /* Set audio port configuration */
- status_t setAudioPortConfig(const struct audio_port_config *config);
+ void dump(int fd);
- status_t createPatchConnections(Patch *patch,
- const struct audio_patch *audioPatch);
- void clearPatchConnections(Patch *patch);
+private:
+ template<typename ThreadType, typename TrackType>
+ class Endpoint {
+ public:
+ Endpoint() = default;
+ Endpoint(Endpoint&& other) { *this = std::move(other); }
+ Endpoint& operator=(Endpoint&& other) {
+ ALOGE_IF(mHandle != AUDIO_PATCH_HANDLE_NONE,
+ "A non empty Patch Endpoint leaked, handle %d", mHandle);
+ *this = other;
+ other.mHandle = AUDIO_PATCH_HANDLE_NONE;
+ return *this;
+ }
+
+ status_t checkTrack(TrackType *trackOrNull) const {
+ if (trackOrNull == nullptr) return NO_MEMORY;
+ return trackOrNull->initCheck();
+ }
+ audio_patch_handle_t handle() const { return mHandle; }
+ sp<ThreadType> thread() { return mThread; }
+ sp<TrackType> track() { return mTrack; }
+
+ void closeConnections(PatchPanel *panel) {
+ if (mHandle != AUDIO_PATCH_HANDLE_NONE) {
+ panel->releaseAudioPatch(mHandle);
+ mHandle = AUDIO_PATCH_HANDLE_NONE;
+ }
+ if (mThread != 0) {
+ if (mTrack != 0) {
+ mThread->deletePatchTrack(mTrack);
+ }
+ if (mCloseThread) {
+ panel->mAudioFlinger.closeThreadInternal_l(mThread);
+ }
+ }
+ }
+ audio_patch_handle_t* handlePtr() { return &mHandle; }
+ void setThread(const sp<ThreadType>& thread, bool closeThread = true) {
+ mThread = thread;
+ mCloseThread = closeThread;
+ }
+ void setTrackAndPeer(const sp<TrackType>& track,
+ ThreadBase::PatchProxyBufferProvider *peer) {
+ mTrack = track;
+ mThread->addPatchTrack(mTrack);
+ mTrack->setPeerProxy(peer);
+ }
+ void stopTrack() { if (mTrack) mTrack->stop(); }
+
+ private:
+ Endpoint(const Endpoint&) = default;
+ Endpoint& operator=(const Endpoint&) = default;
+
+ sp<ThreadType> mThread;
+ bool mCloseThread = true;
+ audio_patch_handle_t mHandle = AUDIO_PATCH_HANDLE_NONE;
+ sp<TrackType> mTrack;
+ };
class Patch {
public:
- explicit Patch(const struct audio_patch *patch) :
- mAudioPatch(*patch), mHandle(AUDIO_PATCH_HANDLE_NONE),
- mHalHandle(AUDIO_PATCH_HANDLE_NONE), mRecordPatchHandle(AUDIO_PATCH_HANDLE_NONE),
- mPlaybackPatchHandle(AUDIO_PATCH_HANDLE_NONE) {}
- ~Patch() {}
+ explicit Patch(const struct audio_patch &patch) : mAudioPatch(patch) {}
+ ~Patch();
+ Patch(const Patch&) = delete;
+ Patch(Patch&&) = default;
+ Patch& operator=(const Patch&) = delete;
+ Patch& operator=(Patch&&) = default;
+ status_t createConnections(PatchPanel *panel);
+ void clearConnections(PatchPanel *panel);
+ bool isSoftware() const {
+ return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE ||
+ mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE; }
+
+ String8 dump(audio_patch_handle_t myHandle);
+
+ // Note that audio_patch::id is only unique within a HAL module
struct audio_patch mAudioPatch;
- audio_patch_handle_t mHandle;
// handle for audio HAL patch handle present only when the audio HAL version is >= 3.0
- audio_patch_handle_t mHalHandle;
+ audio_patch_handle_t mHalHandle = AUDIO_PATCH_HANDLE_NONE;
// below members are used by a software audio patch connecting a source device from a
// given audio HW module to a sink device on an other audio HW module.
- // playback thread created by createAudioPatch() and released by clearPatchConnections() if
- // no existing playback thread can be used by the software patch
- sp<PlaybackThread> mPlaybackThread;
- // audio track created by createPatchConnections() and released by clearPatchConnections()
- sp<PlaybackThread::PatchTrack> mPatchTrack;
- // record thread created by createAudioPatch() and released by clearPatchConnections()
- sp<RecordThread> mRecordThread;
- // audio record created by createPatchConnections() and released by clearPatchConnections()
- sp<RecordThread::PatchRecord> mPatchRecord;
- // handle for audio patch connecting source device to record thread input.
- // created by createPatchConnections() and released by clearPatchConnections()
- audio_patch_handle_t mRecordPatchHandle;
- // handle for audio patch connecting playback thread output to sink device
- // created by createPatchConnections() and released by clearPatchConnections()
- audio_patch_handle_t mPlaybackPatchHandle;
-
+ // the objects are created by createConnections() and released by clearConnections()
+ // playback thread is created if no existing playback thread can be used
+ // connects playback thread output to sink device
+ Endpoint<PlaybackThread, PlaybackThread::PatchTrack> mPlayback;
+ // connects source device to record thread input
+ Endpoint<RecordThread, RecordThread::PatchRecord> mRecord;
};
-private:
- const wp<AudioFlinger> mAudioFlinger;
- SortedVector <Patch *> mPatches;
+ sp<DeviceHalInterface> findHwDeviceByModule(audio_module_handle_t module);
+
+ AudioFlinger &mAudioFlinger;
+ std::map<audio_patch_handle_t, Patch> mPatches;
};
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index dcad866..7b5d9e6 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -62,8 +62,8 @@
#include "AudioFlinger.h"
#include "FastMixer.h"
#include "FastCapture.h"
-#include "ServiceUtilities.h"
-#include "mediautils/SchedulingPolicyService.h"
+#include <mediautils/SchedulingPolicyService.h>
+#include <mediautils/ServiceUtilities.h>
#ifdef ADD_BATTERY_DATA
#include <media/IMediaPlayerService.h>
@@ -769,6 +769,8 @@
if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_LEFT) s.append("top-back-left, ");
if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_CENTER) s.append("top-back-center, " );
if (mask & AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT) s.append("top-back-right, " );
+ if (mask & AUDIO_CHANNEL_OUT_TOP_SIDE_LEFT) s.append("top-side-left, " );
+ if (mask & AUDIO_CHANNEL_OUT_TOP_SIDE_RIGHT) s.append("top-side-right, " );
if (mask & ~AUDIO_CHANNEL_OUT_ALL) s.append("unknown, ");
} else {
if (mask & AUDIO_CHANNEL_IN_LEFT) s.append("left, ");
@@ -783,6 +785,12 @@
if (mask & AUDIO_CHANNEL_IN_X_AXIS) s.append("X, ");
if (mask & AUDIO_CHANNEL_IN_Y_AXIS) s.append("Y, ");
if (mask & AUDIO_CHANNEL_IN_Z_AXIS) s.append("Z, ");
+ if (mask & AUDIO_CHANNEL_IN_BACK_LEFT) s.append("back-left, ");
+ if (mask & AUDIO_CHANNEL_IN_BACK_RIGHT) s.append("back-right, ");
+ if (mask & AUDIO_CHANNEL_IN_CENTER) s.append("center, ");
+ if (mask & AUDIO_CHANNEL_IN_LOW_FREQUENCY) s.append("low freq, ");
+ if (mask & AUDIO_CHANNEL_IN_TOP_LEFT) s.append("top-left, " );
+ if (mask & AUDIO_CHANNEL_IN_TOP_RIGHT) s.append("top-right, " );
if (mask & AUDIO_CHANNEL_IN_VOICE_UPLINK) s.append("voice-uplink, ");
if (mask & AUDIO_CHANNEL_IN_VOICE_DNLINK) s.append("voice-dnlink, ");
if (mask & ~AUDIO_CHANNEL_IN_ALL) s.append("unknown, ");
@@ -1519,7 +1527,7 @@
}
}
-void AudioFlinger::ThreadBase::getAudioPortConfig(struct audio_port_config *config)
+void AudioFlinger::ThreadBase::toAudioPortConfig(struct audio_port_config *config)
{
config->type = AUDIO_PORT_TYPE_MIX;
config->ext.mix.handle = mId;
@@ -3772,9 +3780,9 @@
destroyTrack_l(track);
}
-void AudioFlinger::PlaybackThread::getAudioPortConfig(struct audio_port_config *config)
+void AudioFlinger::PlaybackThread::toAudioPortConfig(struct audio_port_config *config)
{
- ThreadBase::getAudioPortConfig(config);
+ ThreadBase::toAudioPortConfig(config);
config->role = AUDIO_PORT_ROLE_SOURCE;
config->ext.mix.hw_module = mOutput->audioHwDev->handle();
config->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
@@ -7855,21 +7863,21 @@
return status;
}
-void AudioFlinger::RecordThread::addPatchRecord(const sp<PatchRecord>& record)
+void AudioFlinger::RecordThread::addPatchTrack(const sp<PatchRecord>& record)
{
Mutex::Autolock _l(mLock);
mTracks.add(record);
}
-void AudioFlinger::RecordThread::deletePatchRecord(const sp<PatchRecord>& record)
+void AudioFlinger::RecordThread::deletePatchTrack(const sp<PatchRecord>& record)
{
Mutex::Autolock _l(mLock);
destroyTrack_l(record);
}
-void AudioFlinger::RecordThread::getAudioPortConfig(struct audio_port_config *config)
+void AudioFlinger::RecordThread::toAudioPortConfig(struct audio_port_config *config)
{
- ThreadBase::getAudioPortConfig(config);
+ ThreadBase::toAudioPortConfig(config);
config->role = AUDIO_PORT_ROLE_SINK;
config->ext.mix.hw_module = mInput->audioHwDev->handle();
config->ext.mix.usecase.source = mAudioSource;
@@ -8454,9 +8462,9 @@
return status;
}
-void AudioFlinger::MmapThread::getAudioPortConfig(struct audio_port_config *config)
+void AudioFlinger::MmapThread::toAudioPortConfig(struct audio_port_config *config)
{
- ThreadBase::getAudioPortConfig(config);
+ ThreadBase::toAudioPortConfig(config);
if (isOutput()) {
config->role = AUDIO_PORT_ROLE_SOURCE;
config->ext.mix.hw_module = mAudioHwDev->handle();
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 28d4482..5e5e948 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -281,7 +281,7 @@
virtual status_t createAudioPatch_l(const struct audio_patch *patch,
audio_patch_handle_t *handle) = 0;
virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle) = 0;
- virtual void getAudioPortConfig(struct audio_port_config *config) = 0;
+ virtual void toAudioPortConfig(struct audio_port_config *config) = 0;
// see note at declaration of mStandby, mOutDevice and mInDevice
@@ -782,7 +782,7 @@
void addPatchTrack(const sp<PatchTrack>& track);
void deletePatchTrack(const sp<PatchTrack>& track);
- virtual void getAudioPortConfig(struct audio_port_config *config);
+ virtual void toAudioPortConfig(struct audio_port_config *config);
// Return the asynchronous signal wait time.
virtual int64_t computeWaitTimeNs_l() const { return INT64_MAX; }
@@ -1437,8 +1437,8 @@
audio_patch_handle_t *handle);
virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle);
- void addPatchRecord(const sp<PatchRecord>& record);
- void deletePatchRecord(const sp<PatchRecord>& record);
+ void addPatchTrack(const sp<PatchRecord>& record);
+ void deletePatchTrack(const sp<PatchRecord>& record);
void readInputParameters_l();
virtual uint32_t getInputFramesLost();
@@ -1459,7 +1459,7 @@
virtual size_t frameCount() const { return mFrameCount; }
bool hasFastCapture() const { return mFastCapture != 0; }
- virtual void getAudioPortConfig(struct audio_port_config *config);
+ virtual void toAudioPortConfig(struct audio_port_config *config);
virtual status_t checkEffectCompatibility_l(const effect_descriptor_t *desc,
audio_session_t sessionId);
@@ -1602,7 +1602,7 @@
virtual status_t createAudioPatch_l(const struct audio_patch *patch,
audio_patch_handle_t *handle);
virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle);
- virtual void getAudioPortConfig(struct audio_port_config *config);
+ virtual void toAudioPortConfig(struct audio_port_config *config);
virtual sp<StreamHalInterface> stream() const { return mHalStream; }
virtual status_t addEffectChain_l(const sp<EffectChain>& chain);
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index a7c4253..fc8f34b 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -28,11 +28,11 @@
#include <private/media/AudioTrackShared.h>
#include "AudioFlinger.h"
-#include "ServiceUtilities.h"
#include <media/nbaio/Pipe.h>
#include <media/nbaio/PipeReader.h>
#include <media/RecordBufferConverter.h>
+#include <mediautils/ServiceUtilities.h>
#include <audio_utils/minifloat.h>
// ----------------------------------------------------------------------------
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index d29cae1..b75e957 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -13,7 +13,6 @@
$(call include-path-for, audio-utils) \
frameworks/av/services/audiopolicy/common/include \
frameworks/av/services/audiopolicy/engine/interface \
- frameworks/av/services/audiopolicy/utilities
LOCAL_SHARED_LIBRARIES := \
libcutils \
@@ -22,10 +21,10 @@
libbinder \
libaudioclient \
libhardware_legacy \
- libserviceutility \
libaudiopolicymanager \
libmedia_helper \
libmediametrics \
+ libmediautils \
libeffectsconfig
LOCAL_STATIC_LIBRARIES := \
@@ -74,7 +73,6 @@
LOCAL_C_INCLUDES += \
frameworks/av/services/audiopolicy/common/include \
frameworks/av/services/audiopolicy/engine/interface \
- frameworks/av/services/audiopolicy/utilities
LOCAL_STATIC_LIBRARIES := \
libaudiopolicycomponents
diff --git a/services/audiopolicy/common/managerdefinitions/Android.mk b/services/audiopolicy/common/managerdefinitions/Android.mk
index e69e687..b3611c4 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.mk
+++ b/services/audiopolicy/common/managerdefinitions/Android.mk
@@ -35,8 +35,7 @@
$(LOCAL_PATH)/include \
frameworks/av/services/audiopolicy/common/include \
frameworks/av/services/audiopolicy \
- frameworks/av/services/audiopolicy/utilities \
- system/media/audio_utils/include \
+ $(call include-path-for, audio-utils) \
ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSessionInfoProvider.h b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
similarity index 67%
rename from services/audiopolicy/common/managerdefinitions/include/AudioSessionInfoProvider.h
rename to services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
index e0037fc..9f3fc0c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSessionInfoProvider.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
@@ -19,26 +19,27 @@
namespace android {
/**
- * Interface for input descriptors to implement so dependent audio sessions can query information
- * about their context
+ * Interface for I/O descriptors to implement so information about their context
+ * can be queried and updated.
*/
-class AudioSessionInfoProvider
+class AudioIODescriptorInterface
{
public:
- virtual ~AudioSessionInfoProvider() {};
+ virtual ~AudioIODescriptorInterface() {};
virtual audio_config_base_t getConfig() const = 0;
virtual audio_patch_handle_t getPatchHandle() const = 0;
+ virtual void setPatchHandle(audio_patch_handle_t handle) = 0;
};
-class AudioSessionInfoUpdateListener
+class AudioIODescriptorUpdateListener
{
public:
- virtual ~AudioSessionInfoUpdateListener() {};
+ virtual ~AudioIODescriptorUpdateListener() {};
- virtual void onSessionInfoUpdate() const = 0;;
+ virtual void onIODescriptorUpdate() const = 0;
};
} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index b25d6d4..85f3b86 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -16,9 +16,9 @@
#pragma once
+#include "AudioIODescriptorInterface.h"
#include "AudioPort.h"
#include "AudioSession.h"
-#include "AudioSessionInfoProvider.h"
#include <utils/Errors.h>
#include <system/audio.h>
#include <utils/SortedVector.h>
@@ -31,7 +31,7 @@
// descriptor for audio inputs. Used to maintain current configuration of each opened audio input
// and keep track of the usage of this input.
-class AudioInputDescriptor: public AudioPortConfig, public AudioSessionInfoProvider
+class AudioInputDescriptor: public AudioPortConfig, public AudioIODescriptorInterface
{
public:
explicit AudioInputDescriptor(const sp<IOProfile>& profile,
@@ -67,11 +67,10 @@
size_t getAudioSessionCount(bool activeOnly) const;
audio_source_t getHighestPrioritySource(bool activeOnly) const;
- // implementation of AudioSessionInfoProvider
- virtual audio_config_base_t getConfig() const;
- virtual audio_patch_handle_t getPatchHandle() const;
-
- void setPatchHandle(audio_patch_handle_t handle);
+ // implementation of AudioIODescriptorInterface
+ audio_config_base_t getConfig() const override;
+ audio_patch_handle_t getPatchHandle() const override;
+ void setPatchHandle(audio_patch_handle_t handle) override;
status_t open(const audio_config_t *config,
audio_devices_t device,
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 5e5d38b..57d1cfa 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -24,6 +24,7 @@
#include <utils/Timers.h>
#include <utils/KeyedVector.h>
#include <system/audio.h>
+#include "AudioIODescriptorInterface.h"
#include "AudioSourceDescriptor.h"
namespace android {
@@ -35,7 +36,7 @@
// descriptor for audio outputs. Used to maintain current configuration of each opened audio output
// and keep track of the usage of this output by each audio stream type.
-class AudioOutputDescriptor: public AudioPortConfig
+class AudioOutputDescriptor: public AudioPortConfig, public AudioIODescriptorInterface
{
public:
AudioOutputDescriptor(const sp<AudioPort>& port,
@@ -73,8 +74,10 @@
audio_module_handle_t getModuleHandle() const;
- audio_patch_handle_t getPatchHandle() const { return mPatchHandle; };
- void setPatchHandle(audio_patch_handle_t handle) { mPatchHandle = handle; };
+ // implementation of AudioIODescriptorInterface
+ audio_config_base_t getConfig() const override;
+ audio_patch_handle_t getPatchHandle() const override;
+ void setPatchHandle(audio_patch_handle_t handle) override;
sp<AudioPort> mPort;
audio_devices_t mDevice; // current device this output is routed to
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
index 43f6ed6..f747c36 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h
@@ -48,6 +48,14 @@
mIsSpeakerDrcEnabled(false)
{}
+ const std::string& getSource() const {
+ return mSource;
+ }
+
+ void setSource(const std::string& file) {
+ mSource = file;
+ }
+
void setVolumes(const VolumeCurvesCollection &volumes)
{
if (mVolumeCurves != nullptr) {
@@ -107,6 +115,7 @@
void setDefault(void)
{
+ mSource = "AudioPolicyConfig::setDefault";
mDefaultOutputDevices = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);
sp<HwModule> module;
sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC);
@@ -136,6 +145,7 @@
}
private:
+ std::string mSource;
HwModuleCollection &mHwModules; /**< Collection of Module, with Profiles, i.e. Mix Ports. */
DeviceVector &mAvailableOutputDevices;
DeviceVector &mAvailableInputDevices;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
index dd5247d..53e6ec9 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
@@ -23,13 +23,13 @@
#include <utils/KeyedVector.h>
#include <media/AudioPolicy.h>
#include <media/IAudioPolicyServiceClient.h>
-#include "AudioSessionInfoProvider.h"
+#include "AudioIODescriptorInterface.h"
namespace android {
class AudioPolicyClientInterface;
-class AudioSession : public RefBase, public AudioSessionInfoUpdateListener
+class AudioSession : public RefBase, public AudioIODescriptorUpdateListener
{
public:
AudioSession(audio_session_t session,
@@ -63,9 +63,9 @@
uint32_t changeOpenCount(int delta);
uint32_t changeActiveCount(int delta);
- void setInfoProvider(AudioSessionInfoProvider *provider);
- // implementation of AudioSessionInfoUpdateListener
- virtual void onSessionInfoUpdate() const;
+ void setInfoProvider(AudioIODescriptorInterface *provider);
+ // implementation of AudioIODescriptorUpdateListener
+ virtual void onIODescriptorUpdate() const;
private:
record_client_info_t mRecordClientInfo;
@@ -77,17 +77,17 @@
uint32_t mActiveCount;
AudioMix* mPolicyMix; // non NULL when used by a dynamic policy
AudioPolicyClientInterface* mClientInterface;
- const AudioSessionInfoProvider* mInfoProvider;
+ const AudioIODescriptorInterface* mInfoProvider;
};
class AudioSessionCollection :
public DefaultKeyedVector<audio_session_t, sp<AudioSession> >,
- public AudioSessionInfoUpdateListener
+ public AudioIODescriptorUpdateListener
{
public:
status_t addSession(audio_session_t session,
const sp<AudioSession>& audioSession,
- AudioSessionInfoProvider *provider);
+ AudioIODescriptorInterface *provider);
status_t removeSession(audio_session_t session);
@@ -99,8 +99,8 @@
bool isSourceActive(audio_source_t source) const;
audio_source_t getHighestPrioritySource(bool activeOnly) const;
- // implementation of AudioSessionInfoUpdateListener
- virtual void onSessionInfoUpdate() const;
+ // implementation of AudioIODescriptorUpdateListener
+ virtual void onIODescriptorUpdate() const;
status_t dump(int fd, int spaces) const;
};
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 92332fb..f0144db 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -164,7 +164,7 @@
status_t AudioInputDescriptor::addAudioSession(audio_session_t session,
const sp<AudioSession>& audioSession) {
- return mSessions.addSession(session, audioSession, /*AudioSessionInfoProvider*/this);
+ return mSessions.addSession(session, audioSession, /*AudioIODescriptorInterface*/this);
}
status_t AudioInputDescriptor::removeAudioSession(audio_session_t session) {
@@ -179,7 +179,7 @@
void AudioInputDescriptor::setPatchHandle(audio_patch_handle_t handle)
{
mPatchHandle = handle;
- mSessions.onSessionInfoUpdate();
+ mSessions.onIODescriptorUpdate();
}
audio_config_base_t AudioInputDescriptor::getConfig() const
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 294a2a6..3c69de5 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -55,11 +55,28 @@
}
}
+audio_config_base_t AudioOutputDescriptor::getConfig() const
+{
+ const audio_config_base_t config = { .sample_rate = mSamplingRate, .channel_mask = mChannelMask,
+ .format = mFormat };
+ return config;
+}
+
audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
{
return mPort.get() != nullptr ? mPort->getModuleHandle() : AUDIO_MODULE_HANDLE_NONE;
}
+audio_patch_handle_t AudioOutputDescriptor::getPatchHandle() const
+{
+ return mPatchHandle;
+}
+
+void AudioOutputDescriptor::setPatchHandle(audio_patch_handle_t handle)
+{
+ mPatchHandle = handle;
+}
+
audio_port_handle_t AudioOutputDescriptor::getId() const
{
return mId;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
index a9fe48d..e78e121 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
@@ -34,51 +34,32 @@
{
}
+static String8 dumpPatchEndpoints(
+ int spaces, const char *prefix, int count, const audio_port_config *cfgs)
+{
+ String8 result;
+ for (int i = 0; i < count; ++i) {
+ const audio_port_config &cfg = cfgs[i];
+ result.appendFormat("%*s [%s %d] ", spaces, "", prefix, i + 1);
+ if (cfg.type == AUDIO_PORT_TYPE_DEVICE) {
+ std::string device;
+ deviceToString(cfg.ext.device.type, device);
+ result.appendFormat("Device ID %d %s", cfg.id, device.c_str());
+ } else {
+ result.appendFormat("Mix ID %d I/O handle %d", cfg.id, cfg.ext.mix.handle);
+ }
+ result.append("\n");
+ }
+ return result;
+}
+
status_t AudioPatch::dump(int fd, int spaces, int index) const
{
- const size_t SIZE = 256;
- char buffer[SIZE];
String8 result;
-
- snprintf(buffer, SIZE, "%*sAudio patch %d:\n", spaces, "", index+1);
- result.append(buffer);
- snprintf(buffer, SIZE, "%*s- handle: %2d\n", spaces, "", mHandle);
- result.append(buffer);
- snprintf(buffer, SIZE, "%*s- audio flinger handle: %2d\n", spaces, "", mAfPatchHandle);
- result.append(buffer);
- snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mUid);
- result.append(buffer);
- snprintf(buffer, SIZE, "%*s- %d sources:\n", spaces, "", mPatch.num_sources);
- result.append(buffer);
- for (size_t i = 0; i < mPatch.num_sources; i++) {
- if (mPatch.sources[i].type == AUDIO_PORT_TYPE_DEVICE) {
- std::string device;
- deviceToString(mPatch.sources[i].ext.device.type, device);
- snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "",
- mPatch.sources[i].id,
- device.c_str());
- } else {
- snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "",
- mPatch.sources[i].id, mPatch.sources[i].ext.mix.handle);
- }
- result.append(buffer);
- }
- snprintf(buffer, SIZE, "%*s- %d sinks:\n", spaces, "", mPatch.num_sinks);
- result.append(buffer);
- for (size_t i = 0; i < mPatch.num_sinks; i++) {
- if (mPatch.sinks[i].type == AUDIO_PORT_TYPE_DEVICE) {
- std::string device;
- deviceToString(mPatch.sinks[i].ext.device.type, device);
- snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "",
- mPatch.sinks[i].id,
- device.c_str());
- } else {
- snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "",
- mPatch.sinks[i].id, mPatch.sinks[i].ext.mix.handle);
- }
- result.append(buffer);
- }
-
+ result.appendFormat("%*sPatch %d: owner uid %4d, handle %2d, af handle %2d\n",
+ spaces, "", index + 1, mUid, mHandle, mAfPatchHandle);
+ result.append(dumpPatchEndpoints(spaces, "src ", mPatch.num_sources, mPatch.sources));
+ result.append(dumpPatchEndpoints(spaces, "sink", mPatch.num_sinks, mPatch.sinks));
write(fd, result.string(), result.size());
return NO_ERROR;
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
index 7cda46b..91dee35 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
@@ -86,7 +86,7 @@
}
// Recording configuration callback:
- const AudioSessionInfoProvider* provider = mInfoProvider;
+ const AudioIODescriptorInterface* provider = mInfoProvider;
const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() :
AUDIO_CONFIG_BASE_INITIALIZER;
const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
@@ -114,16 +114,16 @@
return false;
}
-void AudioSession::setInfoProvider(AudioSessionInfoProvider *provider)
+void AudioSession::setInfoProvider(AudioIODescriptorInterface *provider)
{
mInfoProvider = provider;
}
-void AudioSession::onSessionInfoUpdate() const
+void AudioSession::onIODescriptorUpdate() const
{
if (mActiveCount > 0) {
// resend the callback after requerying the informations from the info provider
- const AudioSessionInfoProvider* provider = mInfoProvider;
+ const AudioIODescriptorInterface* provider = mInfoProvider;
const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() :
AUDIO_CONFIG_BASE_INITIALIZER;
const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
@@ -170,7 +170,7 @@
status_t AudioSessionCollection::addSession(audio_session_t session,
const sp<AudioSession>& audioSession,
- AudioSessionInfoProvider *provider)
+ AudioIODescriptorInterface *provider)
{
ssize_t index = indexOfKey(session);
@@ -271,10 +271,10 @@
return source;
}
-void AudioSessionCollection::onSessionInfoUpdate() const
+void AudioSessionCollection::onIODescriptorUpdate() const
{
for (size_t i = 0; i < size(); i++) {
- valueAt(i)->onSessionInfoUpdate();
+ valueAt(i)->onIODescriptorUpdate();
}
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp b/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp
index 1e105f5..19eac26 100644
--- a/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp
@@ -412,6 +412,7 @@
free(data);
ALOGI("loadAudioPolicyConfig() loaded %s\n", path);
+ config.setSource(path);
return NO_ERROR;
}
diff --git a/services/audiopolicy/config/audio_policy_configuration.xml b/services/audiopolicy/config/audio_policy_configuration.xml
index a75f1cb..9381f1f 100644
--- a/services/audiopolicy/config/audio_policy_configuration.xml
+++ b/services/audiopolicy/config/audio_policy_configuration.xml
@@ -185,6 +185,9 @@
<!-- Hearing aid Audio HAL -->
<xi:include href="hearing_aid_audio_policy_configuration.xml"/>
+ <!-- MSD Audio HAL (optional) -->
+ <xi:include href="msd_audio_policy_configuration.xml"/>
+
</modules>
<!-- End of Modules section -->
diff --git a/services/audiopolicy/config/msd_audio_policy_configuration.xml b/services/audiopolicy/config/msd_audio_policy_configuration.xml
new file mode 100644
index 0000000..a84117e
--- /dev/null
+++ b/services/audiopolicy/config/msd_audio_policy_configuration.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2017-2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- Multi Stream Decoder Audio Policy Configuration file -->
+<module name="msd" halVersion="2.0">
+ <attachedDevices>
+ <item>MS12 Input</item>
+ <item>MS12 Output</item>
+ </attachedDevices>
+ <mixPorts>
+ <mixPort name="ms12 input" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="ms12 compressed input" role="source"
+ flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
+ <profile name="" format="AUDIO_FORMAT_AC3"
+ samplingRates="32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_5POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_E_AC3"
+ samplingRates="32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_AC4"
+ samplingRates="32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+ </mixPort>
+ <mixPort name="ms12 output" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
+ <profile name="" format="AUDIO_FORMAT_AC3"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_5POINT1"/>
+ <profile name="" format="AUDIO_FORMAT_E_AC3"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_5POINT1"/>
+ </mixPort>
+ </mixPorts>
+ <devicePorts>
+ <devicePort tagName="MS12 Input" type="AUDIO_DEVICE_OUT_BUS" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </devicePort>
+ <devicePort tagName="MS12 Output" type="AUDIO_DEVICE_IN_BUS" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
+ </devicePort>
+ </devicePorts>
+ <routes>
+ <route type="mix" sink="MS12 Input" sources="ms12 input,ms12 compressed input"/>
+ <route type="mix" sink="ms12 output" sources="MS12 Output"/>
+ </routes>
+</module>
diff --git a/services/audiopolicy/engineconfigurable/wrapper/Android.mk b/services/audiopolicy/engineconfigurable/wrapper/Android.mk
index 36e0f42..b128a38 100644
--- a/services/audiopolicy/engineconfigurable/wrapper/Android.mk
+++ b/services/audiopolicy/engineconfigurable/wrapper/Android.mk
@@ -10,7 +10,6 @@
$(LOCAL_PATH)/include \
frameworks/av/services/audiopolicy/engineconfigurable/include \
frameworks/av/services/audiopolicy/engineconfigurable/interface \
- frameworks/av/services/audiopolicy/utilities/convert \
LOCAL_SRC_FILES:= ParameterManagerWrapper.cpp
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index dcd1f3b..6999ba5 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -38,6 +38,7 @@
#include <utils/Log.h>
#include <media/AudioParameter.h>
#include <media/AudioPolicyHelper.h>
+#include <media/PatchBuilder.h>
#include <soundtrigger/SoundTrigger.h>
#include <system/audio.h>
#include <audio_policy_conf.h>
@@ -476,20 +477,15 @@
sp<AudioPatch> AudioPolicyManager::createTelephonyPatch(
bool isRx, audio_devices_t device, uint32_t delayMs) {
- struct audio_patch patch;
- patch.num_sources = 1;
- patch.num_sinks = 1;
+ PatchBuilder patchBuilder;
sp<DeviceDescriptor> txSourceDeviceDesc;
if (isRx) {
- fillAudioPortConfigForDevice(mAvailableOutputDevices, device, &patch.sinks[0]);
- fillAudioPortConfigForDevice(
- mAvailableInputDevices, AUDIO_DEVICE_IN_TELEPHONY_RX, &patch.sources[0]);
+ patchBuilder.addSink(findDevice(mAvailableOutputDevices, device)).
+ addSource(findDevice(mAvailableInputDevices, AUDIO_DEVICE_IN_TELEPHONY_RX));
} else {
- txSourceDeviceDesc = fillAudioPortConfigForDevice(
- mAvailableInputDevices, device, &patch.sources[0]);
- fillAudioPortConfigForDevice(
- mAvailableOutputDevices, AUDIO_DEVICE_OUT_TELEPHONY_TX, &patch.sinks[0]);
+ patchBuilder.addSource(txSourceDeviceDesc = findDevice(mAvailableInputDevices, device)).
+ addSink(findDevice(mAvailableOutputDevices, AUDIO_DEVICE_OUT_TELEPHONY_TX));
}
audio_devices_t outputDevice = isRx ? device : AUDIO_DEVICE_OUT_TELEPHONY_TX;
@@ -500,9 +496,7 @@
sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
ALOG_ASSERT(!outputDesc->isDuplicated(),
"%s() %#x device output %d is duplicated", __func__, outputDevice, output);
- outputDesc->toAudioPortConfig(&patch.sources[1]);
- patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
- patch.num_sources = 2;
+ patchBuilder.addSource(outputDesc, { .stream = AUDIO_STREAM_PATCH });
}
if (!isRx) {
@@ -524,26 +518,25 @@
}
audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
- status_t status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
+ status_t status = mpClientInterface->createAudioPatch(
+ patchBuilder.patch(), &afPatchHandle, delayMs);
ALOGW_IF(status != NO_ERROR,
"%s() error %d creating %s audio patch", __func__, status, isRx ? "RX" : "TX");
sp<AudioPatch> audioPatch;
if (status == NO_ERROR) {
- audioPatch = new AudioPatch(&patch, mUidCached);
+ audioPatch = new AudioPatch(patchBuilder.patch(), mUidCached);
audioPatch->mAfPatchHandle = afPatchHandle;
audioPatch->mUid = mUidCached;
}
return audioPatch;
}
-sp<DeviceDescriptor> AudioPolicyManager::fillAudioPortConfigForDevice(
- const DeviceVector& devices, audio_devices_t device, audio_port_config *config) {
+sp<DeviceDescriptor> AudioPolicyManager::findDevice(
+ const DeviceVector& devices, audio_devices_t device) {
DeviceVector deviceList = devices.getDevicesFromType(device);
ALOG_ASSERT(!deviceList.isEmpty(),
"%s() selected device type %#x is not in devices list", __func__, device);
- sp<DeviceDescriptor> deviceDesc = deviceList.itemAt(0);
- deviceDesc->toAudioPortConfig(config);
- return deviceDesc;
+ return deviceList.itemAt(0);
}
void AudioPolicyManager::setPhoneState(audio_mode_t state)
@@ -2624,42 +2617,24 @@
status_t AudioPolicyManager::dump(int fd)
{
- const size_t SIZE = 256;
- char buffer[SIZE];
String8 result;
-
- snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
- result.append(buffer);
-
- snprintf(buffer, SIZE, " Primary Output: %d\n",
+ result.appendFormat("\nAudioPolicyManager Dump: %p\n", this);
+ result.appendFormat(" Primary Output: %d\n",
hasPrimaryOutput() ? mPrimaryOutput->mIoHandle : AUDIO_IO_HANDLE_NONE);
- result.append(buffer);
std::string stateLiteral;
AudioModeConverter::toString(mEngine->getPhoneState(), stateLiteral);
- snprintf(buffer, SIZE, " Phone state: %s\n", stateLiteral.c_str());
- result.append(buffer);
- snprintf(buffer, SIZE, " Force use for communications %d\n",
- mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION));
- result.append(buffer);
- snprintf(buffer, SIZE, " Force use for media %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA));
- result.append(buffer);
- snprintf(buffer, SIZE, " Force use for record %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD));
- result.append(buffer);
- snprintf(buffer, SIZE, " Force use for dock %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK));
- result.append(buffer);
- snprintf(buffer, SIZE, " Force use for system %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM));
- result.append(buffer);
- snprintf(buffer, SIZE, " Force use for hdmi system audio %d\n",
- mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO));
- result.append(buffer);
- snprintf(buffer, SIZE, " Force use for encoded surround output %d\n",
- mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND));
- result.append(buffer);
- snprintf(buffer, SIZE, " TTS output %s\n", mTtsOutputAvailable ? "available" : "not available");
- result.append(buffer);
- snprintf(buffer, SIZE, " Master mono: %s\n", mMasterMono ? "on" : "off");
- result.append(buffer);
-
+ result.appendFormat(" Phone state: %s\n", stateLiteral.c_str());
+ const char* forceUses[AUDIO_POLICY_FORCE_USE_CNT] = {
+ "communications", "media", "record", "dock", "system",
+ "HDMI system audio", "encoded surround output", "vibrate ringing" };
+ for (audio_policy_force_use_t i = AUDIO_POLICY_FORCE_FOR_COMMUNICATION;
+ i < AUDIO_POLICY_FORCE_USE_CNT; i = (audio_policy_force_use_t)((int)i + 1)) {
+ result.appendFormat(" Force use for %s: %d\n",
+ forceUses[i], mEngine->getForceUse(i));
+ }
+ result.appendFormat(" TTS output %savailable\n", mTtsOutputAvailable ? "" : "not ");
+ result.appendFormat(" Master mono: %s\n", mMasterMono ? "on" : "off");
+ result.appendFormat(" Config source: %s\n", getConfig().getSource().c_str());
write(fd, result.string(), result.size());
mAvailableOutputDevices.dump(fd, String8("Available output"));
@@ -3075,28 +3050,8 @@
}
// TODO: check from routing capabilities in config file and other conflicting patches
- audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
- if (index >= 0) {
- afPatchHandle = patchDesc->mAfPatchHandle;
- }
-
- status_t status = mpClientInterface->createAudioPatch(&newPatch,
- &afPatchHandle,
- 0);
- ALOGV("createAudioPatch() patch panel returned %d patchHandle %d",
- status, afPatchHandle);
- if (status == NO_ERROR) {
- if (index < 0) {
- patchDesc = new AudioPatch(&newPatch, uid);
- addAudioPatch(patchDesc->mHandle, patchDesc);
- } else {
- patchDesc->mPatch = newPatch;
- }
- patchDesc->mAfPatchHandle = afPatchHandle;
- *handle = patchDesc->mHandle;
- nextAudioPortGeneration();
- mpClientInterface->onAudioPatchListUpdate();
- } else {
+ status_t status = installPatch(__func__, index, handle, &newPatch, 0, uid, &patchDesc);
+ if (status != NO_ERROR) {
ALOGW("createAudioPatch() patch panel could not connect device patch, error %d",
status);
return INVALID_OPERATION;
@@ -3408,7 +3363,6 @@
mAvailableOutputDevices.getDevice(sinkDevice, String8(""));
audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
- struct audio_patch *patch = &sourceDesc->mPatchDesc->mPatch;
if (srcDeviceDesc->getAudioPort()->mModule->getHandle() ==
sinkDeviceDesc->getAudioPort()->mModule->getHandle() &&
@@ -3440,16 +3394,14 @@
// be connected as well as the stream type for volume control
// - the sink is defined by whatever output device is currently selected for the output
// though which this patch is routed.
- patch->num_sinks = 0;
- patch->num_sources = 2;
- srcDeviceDesc->toAudioPortConfig(&patch->sources[0], NULL);
- outputDesc->toAudioPortConfig(&patch->sources[1], NULL);
- patch->sources[1].ext.mix.usecase.stream = stream;
- status = mpClientInterface->createAudioPatch(patch,
+ PatchBuilder patchBuilder;
+ patchBuilder.addSource(srcDeviceDesc).addSource(outputDesc, { .stream = stream });
+ status = mpClientInterface->createAudioPatch(patchBuilder.patch(),
&afPatchHandle,
0);
ALOGV("%s patch panel returned %d patchHandle %d", __FUNCTION__,
status, afPatchHandle);
+ sourceDesc->mPatchDesc->mPatch = *patchBuilder.patch();
if (status != NO_ERROR) {
ALOGW("%s patch panel could not connect device patch, error %d",
__FUNCTION__, status);
@@ -3901,6 +3853,7 @@
"%s/%s", kConfigLocationList[i], fileName);
ret = serializer.deserialize(audioPolicyXmlConfigFile, config);
if (ret == NO_ERROR) {
+ config.setSource(audioPolicyXmlConfigFile);
return ret;
}
}
@@ -5237,48 +5190,12 @@
}
if (!deviceList.isEmpty()) {
- struct audio_patch patch;
- outputDesc->toAudioPortConfig(&patch.sources[0]);
- patch.num_sources = 1;
- patch.num_sinks = 0;
+ PatchBuilder patchBuilder;
+ patchBuilder.addSource(outputDesc);
for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) {
- deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]);
- patch.num_sinks++;
+ patchBuilder.addSink(deviceList.itemAt(i));
}
- ssize_t index;
- if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
- index = mAudioPatches.indexOfKey(*patchHandle);
- } else {
- index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
- }
- sp< AudioPatch> patchDesc;
- audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
- if (index >= 0) {
- patchDesc = mAudioPatches.valueAt(index);
- afPatchHandle = patchDesc->mAfPatchHandle;
- }
-
- status_t status = mpClientInterface->createAudioPatch(&patch,
- &afPatchHandle,
- delayMs);
- ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d"
- "num_sources %d num_sinks %d",
- status, afPatchHandle, patch.num_sources, patch.num_sinks);
- if (status == NO_ERROR) {
- if (index < 0) {
- patchDesc = new AudioPatch(&patch, mUidCached);
- addAudioPatch(patchDesc->mHandle, patchDesc);
- } else {
- patchDesc->mPatch = patch;
- }
- patchDesc->mAfPatchHandle = afPatchHandle;
- if (patchHandle) {
- *patchHandle = patchDesc->mHandle;
- }
- outputDesc->setPatchHandle(patchDesc->mHandle);
- nextAudioPortGeneration();
- mpClientInterface->onAudioPatchListUpdate();
- }
+ installPatch(__func__, patchHandle, outputDesc.get(), patchBuilder.patch(), delayMs);
}
// inform all input as well
@@ -5338,51 +5255,19 @@
DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device);
if (!deviceList.isEmpty()) {
- struct audio_patch patch;
- inputDesc->toAudioPortConfig(&patch.sinks[0]);
+ PatchBuilder patchBuilder;
+ patchBuilder.addSink(inputDesc,
// AUDIO_SOURCE_HOTWORD is for internal use only:
// handled as AUDIO_SOURCE_VOICE_RECOGNITION by the audio HAL
- if (patch.sinks[0].ext.mix.usecase.source == AUDIO_SOURCE_HOTWORD &&
- !inputDesc->isSoundTrigger()) {
- patch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_VOICE_RECOGNITION;
- }
- patch.num_sinks = 1;
+ [inputDesc](const PatchBuilder::mix_usecase_t& usecase) {
+ auto result = usecase;
+ if (result.source == AUDIO_SOURCE_HOTWORD && !inputDesc->isSoundTrigger()) {
+ result.source = AUDIO_SOURCE_VOICE_RECOGNITION;
+ }
+ return result; }).
//only one input device for now
- deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]);
- patch.num_sources = 1;
- ssize_t index;
- if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
- index = mAudioPatches.indexOfKey(*patchHandle);
- } else {
- index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
- }
- sp< AudioPatch> patchDesc;
- audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
- if (index >= 0) {
- patchDesc = mAudioPatches.valueAt(index);
- afPatchHandle = patchDesc->mAfPatchHandle;
- }
-
- status_t status = mpClientInterface->createAudioPatch(&patch,
- &afPatchHandle,
- 0);
- ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d",
- status, afPatchHandle);
- if (status == NO_ERROR) {
- if (index < 0) {
- patchDesc = new AudioPatch(&patch, mUidCached);
- addAudioPatch(patchDesc->mHandle, patchDesc);
- } else {
- patchDesc->mPatch = patch;
- }
- patchDesc->mAfPatchHandle = afPatchHandle;
- if (patchHandle) {
- *patchHandle = patchDesc->mHandle;
- }
- inputDesc->setPatchHandle(patchDesc->mHandle);
- nextAudioPortGeneration();
- mpClientInterface->onAudioPatchListUpdate();
- }
+ addSource(deviceList.itemAt(0));
+ status = installPatch(__func__, patchHandle, inputDesc.get(), patchBuilder.patch(), 0);
}
}
return status;
@@ -6135,4 +6020,58 @@
}
}
+status_t AudioPolicyManager::installPatch(const char *caller,
+ audio_patch_handle_t *patchHandle,
+ AudioIODescriptorInterface *ioDescriptor,
+ const struct audio_patch *patch,
+ int delayMs)
+{
+ ssize_t index = mAudioPatches.indexOfKey(
+ patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE ?
+ *patchHandle : ioDescriptor->getPatchHandle());
+ sp<AudioPatch> patchDesc;
+ status_t status = installPatch(
+ caller, index, patchHandle, patch, delayMs, mUidCached, &patchDesc);
+ if (status == NO_ERROR) {
+ ioDescriptor->setPatchHandle(patchDesc->mHandle);
+ }
+ return status;
+}
+
+status_t AudioPolicyManager::installPatch(const char *caller,
+ ssize_t index,
+ audio_patch_handle_t *patchHandle,
+ const struct audio_patch *patch,
+ int delayMs,
+ uid_t uid,
+ sp<AudioPatch> *patchDescPtr)
+{
+ sp<AudioPatch> patchDesc;
+ audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
+ if (index >= 0) {
+ patchDesc = mAudioPatches.valueAt(index);
+ afPatchHandle = patchDesc->mAfPatchHandle;
+ }
+
+ status_t status = mpClientInterface->createAudioPatch(patch, &afPatchHandle, delayMs);
+ ALOGV("%s() AF::createAudioPatch returned %d patchHandle %d num_sources %d num_sinks %d",
+ caller, status, afPatchHandle, patch->num_sources, patch->num_sinks);
+ if (status == NO_ERROR) {
+ if (index < 0) {
+ patchDesc = new AudioPatch(patch, uid);
+ addAudioPatch(patchDesc->mHandle, patchDesc);
+ } else {
+ patchDesc->mPatch = *patch;
+ }
+ patchDesc->mAfPatchHandle = afPatchHandle;
+ if (patchHandle) {
+ *patchHandle = patchDesc->mHandle;
+ }
+ nextAudioPortGeneration();
+ mpClientInterface->onAudioPatchListUpdate();
+ }
+ if (patchDescPtr) *patchDescPtr = patchDesc;
+ return status;
+}
+
} // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index b954714..c814ff9 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -502,8 +502,8 @@
uint32_t updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs = 0);
sp<AudioPatch> createTelephonyPatch(bool isRx, audio_devices_t device, uint32_t delayMs);
- sp<DeviceDescriptor> fillAudioPortConfigForDevice(
- const DeviceVector& devices, audio_devices_t device, audio_port_config *config);
+ sp<DeviceDescriptor> findDevice(
+ const DeviceVector& devices, audio_devices_t device);
// if argument "device" is different from AUDIO_DEVICE_NONE, startSource() will force
// the re-evaluation of the output device.
@@ -680,6 +680,18 @@
param.addInt(String8(AudioParameter::keyMonoOutput), (int)mMasterMono);
mpClientInterface->setParameters(output, param.toString());
}
+ status_t installPatch(const char *caller,
+ audio_patch_handle_t *patchHandle,
+ AudioIODescriptorInterface *ioDescriptor,
+ const struct audio_patch *patch,
+ int delayMs);
+ status_t installPatch(const char *caller,
+ ssize_t index,
+ audio_patch_handle_t *patchHandle,
+ const struct audio_patch *patch,
+ int delayMs,
+ uid_t uid,
+ sp<AudioPatch> *patchDescPtr);
bool soundTriggerSupportsConcurrentCapture();
bool mSoundTriggerSupportsConcurrentCapture;
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index c7dfe0f..fdae23b 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -24,6 +24,7 @@
#include <cutils/misc.h>
#include <media/AudioEffect.h>
#include <media/EffectsConfig.h>
+#include <mediautils/ServiceUtilities.h>
#include <system/audio.h>
#include <system/audio_effects/audio_effects_conf.h>
#include <utils/Vector.h>
@@ -31,7 +32,6 @@
#include <cutils/config_utils.h>
#include <binder/IPCThreadState.h>
#include "AudioPolicyEffects.h"
-#include "ServiceUtilities.h"
namespace android {
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 66ac050..de30f40 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -21,7 +21,7 @@
#include <media/MediaAnalyticsItem.h>
#include "AudioPolicyService.h"
-#include "ServiceUtilities.h"
+#include <mediautils/ServiceUtilities.h>
#include "TypeConverter.h"
namespace android {
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index f3cddc3..5d25ea8 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -35,10 +35,10 @@
#include <utils/String16.h>
#include <utils/threads.h>
#include "AudioPolicyService.h"
-#include "ServiceUtilities.h"
#include <hardware_legacy/power.h>
#include <media/AudioEffect.h>
#include <media/AudioParameter.h>
+#include <mediautils/ServiceUtilities.h>
#include <system/audio.h>
#include <system/audio_policy.h>
diff --git a/services/audiopolicy/tests/Android.mk b/services/audiopolicy/tests/Android.mk
index a43daea..cfa9ab1 100644
--- a/services/audiopolicy/tests/Android.mk
+++ b/services/audiopolicy/tests/Android.mk
@@ -6,7 +6,6 @@
frameworks/av/services/audiopolicy \
frameworks/av/services/audiopolicy/common/include \
frameworks/av/services/audiopolicy/engine/interface \
- frameworks/av/services/audiopolicy/utilities
LOCAL_SHARED_LIBRARIES := \
libaudiopolicymanagerdefault \
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index a9593b8..2d9260e 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -19,6 +19,8 @@
#include <gtest/gtest.h>
+#include <media/PatchBuilder.h>
+
#include "AudioPolicyTestClient.h"
#include "AudioPolicyTestManager.h"
@@ -166,29 +168,14 @@
}
TEST_F(AudioPolicyManagerTest, CreateAudioPatchFromMix) {
- audio_patch patch{};
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
uid_t uid = 42;
const size_t patchCountBefore = mClient->getActivePatchesCount();
- patch.num_sources = 1;
- {
- auto& src = patch.sources[0];
- src.role = AUDIO_PORT_ROLE_SOURCE;
- src.type = AUDIO_PORT_TYPE_MIX;
- src.id = mManager->getConfig().getAvailableInputDevices()[0]->getId();
- // Note: these are the parameters of the output device.
- src.sample_rate = 44100;
- src.format = AUDIO_FORMAT_PCM_16_BIT;
- src.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- }
- patch.num_sinks = 1;
- {
- auto& sink = patch.sinks[0];
- sink.role = AUDIO_PORT_ROLE_SINK;
- sink.type = AUDIO_PORT_TYPE_DEVICE;
- sink.id = mManager->getConfig().getDefaultOutputDevice()->getId();
- }
- ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(&patch, &handle, uid));
+ ASSERT_FALSE(mManager->getConfig().getAvailableInputDevices().isEmpty());
+ PatchBuilder patchBuilder;
+ patchBuilder.addSource(mManager->getConfig().getAvailableInputDevices()[0]).
+ addSink(mManager->getConfig().getDefaultOutputDevice());
+ ASSERT_EQ(NO_ERROR, mManager->createAudioPatch(patchBuilder.patch(), &handle, uid));
ASSERT_NE(AUDIO_PATCH_HANDLE_NONE, handle);
ASSERT_EQ(patchCountBefore + 1, mClient->getActivePatchesCount());
}
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index db5f0ff..089d62b 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -22,6 +22,7 @@
libstagefright_soft_vorbisdec \
libstagefright_soft_vpxdec \
libstagefright_soft_vpxenc \
+ libstagefright_soft_xaacdec \
# service executable
include $(CLEAR_VARS)
diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index 6a72e5b..94440b1 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -24,6 +24,7 @@
#include <aaudio/AAudio.h>
#include <mediautils/SchedulingPolicyService.h>
+#include <mediautils/ServiceUtilities.h>
#include <utils/String16.h>
#include "binding/AAudioServiceMessage.h"
@@ -33,7 +34,6 @@
#include "AAudioServiceStreamMMAP.h"
#include "AAudioServiceStreamShared.h"
#include "binding/IAAudioService.h"
-#include "ServiceUtilities.h"
using namespace android;
using namespace aaudio;
diff --git a/services/oboeservice/Android.mk b/services/oboeservice/Android.mk
index 584b2ef..3d5f140 100644
--- a/services/oboeservice/Android.mk
+++ b/services/oboeservice/Android.mk
@@ -53,7 +53,6 @@
libbinder \
libcutils \
libmediautils \
- libserviceutility \
libutils \
liblog
diff --git a/services/soundtrigger/Android.mk b/services/soundtrigger/Android.mk
index ad3666e..3c7d29d 100644
--- a/services/soundtrigger/Android.mk
+++ b/services/soundtrigger/Android.mk
@@ -34,8 +34,7 @@
libhardware \
libsoundtrigger \
libaudioclient \
- libserviceutility
-
+ libmediautils \
ifeq ($(USE_LEGACY_LOCAL_AUDIO_HAL),true)
# libhardware configuration
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index a7d6e83..6bf6e94 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -27,13 +27,13 @@
#include <cutils/properties.h>
#include <hardware/hardware.h>
#include <media/AudioSystem.h>
+#include <mediautils/ServiceUtilities.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <binder/IServiceManager.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
#include <system/sound_trigger.h>
-#include <ServiceUtilities.h>
#include "SoundTriggerHwService.h"
#ifdef SOUND_TRIGGER_USE_STUB_MODULE