Remove manual parceling from Interpolator and VolumeShaper
Created stable parcelables to hold all the data that gets parceled.
Replaced manual parceling with a two-step approach, where we first
write into the auto-generated parcelable, then parcel it.
Test: Ran audio-related CTS tests
Bug: 160253486
Change-Id: I5a4d51fb1244ed49bcd70e446aaa26e2aa8ed7b1
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..87a8f41
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,27 @@
+aidl_interface {
+ name: "av-types-aidl",
+ unstable: true,
+ host_supported: true,
+ vendor_available: true,
+ double_loadable: true,
+ local_include_dir: "aidl",
+ srcs: [
+ "aidl/android/media/InterpolatorConfig.aidl",
+ "aidl/android/media/InterpolatorType.aidl",
+ "aidl/android/media/VolumeShaperConfiguration.aidl",
+ "aidl/android/media/VolumeShaperConfigurationOptionFlag.aidl",
+ "aidl/android/media/VolumeShaperConfigurationType.aidl",
+ "aidl/android/media/VolumeShaperOperation.aidl",
+ "aidl/android/media/VolumeShaperOperationFlag.aidl",
+ "aidl/android/media/VolumeShaperState.aidl",
+ ],
+ backend: {
+ cpp: {
+ min_sdk_version: "29",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media",
+ ],
+ },
+ },
+}
diff --git a/aidl/android/media/InterpolatorConfig.aidl b/aidl/android/media/InterpolatorConfig.aidl
new file mode 100644
index 0000000..ef7486e
--- /dev/null
+++ b/aidl/android/media/InterpolatorConfig.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+package android.media;
+
+import android.media.InterpolatorType;
+
+/**
+ * {@hide}
+ */
+parcelable InterpolatorConfig {
+ InterpolatorType type;
+ /** For cubic interpolation, the boundary conditions in slope. */
+ float firstSlope;
+ float lastSlope;
+ /** A flattened list of <x, y> pairs, monotonically increasing in x. */
+ float[] xy;
+}
diff --git a/aidl/android/media/InterpolatorType.aidl b/aidl/android/media/InterpolatorType.aidl
new file mode 100644
index 0000000..b722cad
--- /dev/null
+++ b/aidl/android/media/InterpolatorType.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+package android.media;
+
+/**
+ * Polynomial spline interpolators.
+ *
+ * {@hide}
+ */
+@Backing(type="int")
+enum InterpolatorType {
+ /** Not continuous. */
+ STEP,
+ /** C0. */
+ LINEAR,
+ /** C1. */
+ CUBIC,
+ /** C1 (to provide locally monotonic curves). */
+ CUBIC_MONOTONIC,
+ // CUBIC_C2, // TODO - requires global computation / cache
+}
diff --git a/aidl/android/media/VolumeShaperConfiguration.aidl b/aidl/android/media/VolumeShaperConfiguration.aidl
new file mode 100644
index 0000000..6361851
--- /dev/null
+++ b/aidl/android/media/VolumeShaperConfiguration.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+package android.media;
+
+import android.media.InterpolatorConfig;
+import android.media.VolumeShaperConfigurationOptionFlag;
+import android.media.VolumeShaperConfigurationType;
+
+/**
+ * {@hide}
+ */
+parcelable VolumeShaperConfiguration {
+ VolumeShaperConfigurationType type;
+ int id;
+ /** Bitmask, indexed by VolumeShaperConfigurationOptionFlag. */
+ int optionFlags;
+ double durationMs;
+ InterpolatorConfig interpolatorConfig;
+}
diff --git a/media/libaudioclient/aidl/android/media/VolumeShaper/State.aidl b/aidl/android/media/VolumeShaperConfigurationOptionFlag.aidl
similarity index 75%
copy from media/libaudioclient/aidl/android/media/VolumeShaper/State.aidl
copy to aidl/android/media/VolumeShaperConfigurationOptionFlag.aidl
index f6a22b8..f583cee 100644
--- a/media/libaudioclient/aidl/android/media/VolumeShaper/State.aidl
+++ b/aidl/android/media/VolumeShaperConfigurationOptionFlag.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -13,7 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package android.media;
-package android.media.VolumeShaper;
-
-parcelable State cpp_header "media/VolumeShaper.h";
+@Backing(type="int")
+enum VolumeShaperConfigurationOptionFlag {
+ VOLUME_IN_DBFS,
+ CLOCK_TIME,
+}
diff --git a/media/libaudioclient/aidl/android/media/VolumeShaper/State.aidl b/aidl/android/media/VolumeShaperConfigurationType.aidl
similarity index 77%
rename from media/libaudioclient/aidl/android/media/VolumeShaper/State.aidl
rename to aidl/android/media/VolumeShaperConfigurationType.aidl
index f6a22b8..aa6334e 100644
--- a/media/libaudioclient/aidl/android/media/VolumeShaper/State.aidl
+++ b/aidl/android/media/VolumeShaperConfigurationType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -13,7 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package android.media;
-package android.media.VolumeShaper;
-
-parcelable State cpp_header "media/VolumeShaper.h";
+@Backing(type="int")
+enum VolumeShaperConfigurationType {
+ ID,
+ SCALE,
+}
diff --git a/aidl/android/media/VolumeShaperOperation.aidl b/aidl/android/media/VolumeShaperOperation.aidl
new file mode 100644
index 0000000..dd9a0e7
--- /dev/null
+++ b/aidl/android/media/VolumeShaperOperation.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+package android.media;
+
+/**
+ * {@hide}
+ */
+parcelable VolumeShaperOperation {
+ /** Operations to do. Bitmask of VolumeShaperOperationFlag. */
+ int flags;
+ /** If >= 0 the id to remove in a replace operation. */
+ int replaceId;
+ /** Position in the curve to set if a valid number (not nan). */
+ float xOffset;
+}
diff --git a/media/libaudioclient/aidl/android/media/VolumeShaper/State.aidl b/aidl/android/media/VolumeShaperOperationFlag.aidl
similarity index 67%
copy from media/libaudioclient/aidl/android/media/VolumeShaper/State.aidl
copy to aidl/android/media/VolumeShaperOperationFlag.aidl
index f6a22b8..8fe5275 100644
--- a/media/libaudioclient/aidl/android/media/VolumeShaper/State.aidl
+++ b/aidl/android/media/VolumeShaperOperationFlag.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -13,7 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package android.media;
-package android.media.VolumeShaper;
-
-parcelable State cpp_header "media/VolumeShaper.h";
+@Backing(type="int")
+enum VolumeShaperOperationFlag {
+ /** The absence of this flag indicates "play". */
+ REVERSE,
+ TERMINATE,
+ JOIN,
+ DELAY,
+ CREATE_IF_NECESSARY,
+}
diff --git a/media/libaudioclient/aidl/android/media/VolumeShaper/State.aidl b/aidl/android/media/VolumeShaperState.aidl
similarity index 63%
copy from media/libaudioclient/aidl/android/media/VolumeShaper/State.aidl
copy to aidl/android/media/VolumeShaperState.aidl
index f6a22b8..4085e2b 100644
--- a/media/libaudioclient/aidl/android/media/VolumeShaper/State.aidl
+++ b/aidl/android/media/VolumeShaperState.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,6 +14,14 @@
* limitations under the License.
*/
-package android.media.VolumeShaper;
+package android.media;
-parcelable State cpp_header "media/VolumeShaper.h";
+/**
+ * {@hide}
+ */
+parcelable VolumeShaperState {
+ /** Linear volume in the range MIN_LINEAR_VOLUME to MAX_LINEAR_VOLUME. */
+ float volume;
+ /** Position on curve expressed from MIN_CURVE_TIME to MAX_CURVE_TIME. */
+ float xOffset;
+}
diff --git a/include/media/Interpolator.h b/include/media/Interpolator.h
index 703cf77..2004acb 100644
--- a/include/media/Interpolator.h
+++ b/include/media/Interpolator.h
@@ -21,6 +21,7 @@
#include <sstream>
#include <unordered_map>
+#include <android/media/InterpolatorConfig.h>
#include <binder/Parcel.h>
#include <utils/RefBase.h>
@@ -39,17 +40,10 @@
class Interpolator : public std::map<S, T> {
public:
// Polynomial spline interpolators
- // Extend only at the end of enum, as this must match order in VolumeShapers.java.
- enum InterpolatorType : int32_t {
- INTERPOLATOR_TYPE_STEP, // Not continuous
- INTERPOLATOR_TYPE_LINEAR, // C0
- INTERPOLATOR_TYPE_CUBIC, // C1
- INTERPOLATOR_TYPE_CUBIC_MONOTONIC, // C1 (to provide locally monotonic curves)
- // INTERPOLATOR_TYPE_CUBIC_C2, // TODO - requires global computation / cache
- };
+ using InterpolatorType = media::InterpolatorType;
explicit Interpolator(
- InterpolatorType interpolatorType = INTERPOLATOR_TYPE_LINEAR,
+ InterpolatorType interpolatorType = InterpolatorType::LINEAR,
bool cache = true)
: mCache(cache)
, mFirstSlope(0)
@@ -82,13 +76,13 @@
// now that we have two adjacent points:
switch (mInterpolatorType) {
- case INTERPOLATOR_TYPE_STEP:
+ case InterpolatorType::STEP:
return high->first == x ? high->second : low->second;
- case INTERPOLATOR_TYPE_LINEAR:
+ case InterpolatorType::LINEAR:
return ((high->first - x) * low->second + (x - low->first) * high->second)
/ (high->first - low->first);
- case INTERPOLATOR_TYPE_CUBIC:
- case INTERPOLATOR_TYPE_CUBIC_MONOTONIC:
+ case InterpolatorType::CUBIC:
+ case InterpolatorType::CUBIC_MONOTONIC:
default: {
// See https://en.wikipedia.org/wiki/Cubic_Hermite_spline
@@ -116,7 +110,7 @@
// non catmullRom (finite difference) with regular cubic;
// the choices here minimize computation.
bool monotonic, catmullRom;
- if (mInterpolatorType == INTERPOLATOR_TYPE_CUBIC_MONOTONIC) {
+ if (mInterpolatorType == InterpolatorType::CUBIC_MONOTONIC) {
monotonic = true;
catmullRom = false;
} else {
@@ -202,11 +196,11 @@
status_t setInterpolatorType(InterpolatorType interpolatorType) {
switch (interpolatorType) {
- case INTERPOLATOR_TYPE_STEP: // Not continuous
- case INTERPOLATOR_TYPE_LINEAR: // C0
- case INTERPOLATOR_TYPE_CUBIC: // C1
- case INTERPOLATOR_TYPE_CUBIC_MONOTONIC: // C1 + other constraints
- // case INTERPOLATOR_TYPE_CUBIC_C2:
+ case InterpolatorType::STEP: // Not continuous
+ case InterpolatorType::LINEAR: // C0
+ case InterpolatorType::CUBIC: // C1
+ case InterpolatorType::CUBIC_MONOTONIC: // C1 + other constraints
+ // case InterpolatorType::CUBIC_C2:
mInterpolatorType = interpolatorType;
return NO_ERROR;
default:
@@ -235,49 +229,50 @@
mMemo.clear();
}
+ // TODO(ytai): remove this method once it is not used.
status_t writeToParcel(Parcel *parcel) const {
- if (parcel == nullptr) {
- return BAD_VALUE;
- }
- status_t res = parcel->writeInt32(mInterpolatorType)
- ?: parcel->writeFloat(mFirstSlope)
- ?: parcel->writeFloat(mLastSlope)
- ?: parcel->writeUint32((uint32_t)this->size()); // silent truncation
- if (res != NO_ERROR) {
- return res;
- }
- for (const auto &pt : *this) {
- res = parcel->writeFloat(pt.first)
- ?: parcel->writeFloat(pt.second);
- if (res != NO_ERROR) {
- return res;
- }
- }
- return NO_ERROR;
+ media::InterpolatorConfig config;
+ writeToConfig(&config);
+ return config.writeToParcel(parcel);
}
+ void writeToConfig(media::InterpolatorConfig *config) const {
+ config->type = mInterpolatorType;
+ config->firstSlope = mFirstSlope;
+ config->lastSlope = mLastSlope;
+ for (const auto &pt : *this) {
+ config->xy.push_back(pt.first);
+ config->xy.push_back(pt.second);
+ }
+ }
+
+ // TODO(ytai): remove this method once it is not used.
status_t readFromParcel(const Parcel &parcel) {
- this->clear();
- int32_t type;
- uint32_t size;
- status_t res = parcel.readInt32(&type)
- ?: parcel.readFloat(&mFirstSlope)
- ?: parcel.readFloat(&mLastSlope)
- ?: parcel.readUint32(&size)
- ?: setInterpolatorType((InterpolatorType)type);
+ media::InterpolatorConfig config;
+ status_t res = config.readFromParcel(&parcel);
if (res != NO_ERROR) {
return res;
}
+ return readFromConfig(config);
+ }
+
+ status_t readFromConfig(const media::InterpolatorConfig &config) {
+ this->clear();
+ setInterpolatorType(config.type);
+ if ((config.xy.size() & 1) != 0) {
+ // xy size must be even.
+ return BAD_VALUE;
+ }
+ uint32_t size = config.xy.size() / 2;
+ mFirstSlope = config.firstSlope;
+ mLastSlope = config.lastSlope;
+
// Note: We don't need to check size is within some bounds as
// the Parcel read will fail if size is incorrectly specified too large.
float lastx;
for (uint32_t i = 0; i < size; ++i) {
- float x, y;
- res = parcel.readFloat(&x)
- ?: parcel.readFloat(&y);
- if (res != NO_ERROR) {
- return res;
- }
+ float x = config.xy[i * 2];
+ float y = config.xy[i * 2 + 1];
if ((i > 0 && !(x > lastx)) /* handle nan */
|| y != y /* handle nan */) {
// This is a std::map object which imposes sorted order
diff --git a/include/media/VolumeShaper.h b/include/media/VolumeShaper.h
index fe519bb..f8ead2f 100644
--- a/include/media/VolumeShaper.h
+++ b/include/media/VolumeShaper.h
@@ -22,6 +22,11 @@
#include <math.h>
#include <sstream>
+#include <android/media/VolumeShaperConfiguration.h>
+#include <android/media/VolumeShaperConfigurationOptionFlag.h>
+#include <android/media/VolumeShaperOperation.h>
+#include <android/media/VolumeShaperOperationFlag.h>
+#include <android/media/VolumeShaperState.h>
#include <binder/Parcel.h>
#include <media/Interpolator.h>
#include <utils/Mutex.h>
@@ -284,30 +289,38 @@
clampVolume();
}
- // The parcel layout must match VolumeShaper.java
status_t writeToParcel(Parcel *parcel) const override {
- if (parcel == nullptr) return BAD_VALUE;
- return parcel->writeInt32((int32_t)mType)
- ?: parcel->writeInt32(mId)
- ?: mType == TYPE_ID
- ? NO_ERROR
- : parcel->writeInt32((int32_t)mOptionFlags)
- ?: parcel->writeDouble(mDurationMs)
- ?: Interpolator<S, T>::writeToParcel(parcel);
+ VolumeShaperConfiguration parcelable;
+ writeToParcelable(&parcelable);
+ return parcelable.writeToParcel(parcel);
}
- status_t readFromParcel(const Parcel *parcel) override {
- int32_t type, optionFlags;
- return parcel->readInt32(&type)
- ?: setType((Type)type)
- ?: parcel->readInt32(&mId)
- ?: mType == TYPE_ID
- ? NO_ERROR
- : parcel->readInt32(&optionFlags)
- ?: setOptionFlags((OptionFlag)optionFlags)
- ?: parcel->readDouble(&mDurationMs)
- ?: Interpolator<S, T>::readFromParcel(*parcel)
- ?: checkCurve();
+ void writeToParcelable(VolumeShaperConfiguration *parcelable) const {
+ parcelable->id = getId();
+ parcelable->type = getTypeAsAidl();
+ parcelable->optionFlags = 0;
+ if (mType != TYPE_ID) {
+ parcelable->optionFlags = getOptionFlagsAsAidl();
+ parcelable->durationMs = getDurationMs();
+ Interpolator<S, T>::writeToConfig(&parcelable->interpolatorConfig);
+ }
+ }
+
+ status_t readFromParcel(const Parcel* parcel) override {
+ VolumeShaperConfiguration data;
+ return data.readFromParcel(parcel)
+ ?: readFromParcelable(data);
+ }
+
+ status_t readFromParcelable(const VolumeShaperConfiguration& parcelable) {
+ setId(parcelable.id);
+ return setTypeFromAidl(parcelable.type)
+ ?: mType == TYPE_ID
+ ? NO_ERROR
+ : setOptionFlagsFromAidl(parcelable.optionFlags)
+ ?: setDurationMs(parcelable.durationMs)
+ ?: Interpolator<S, T>::readFromConfig(parcelable.interpolatorConfig)
+ ?: checkCurve();
}
// Returns a string for debug printing.
@@ -329,6 +342,51 @@
int32_t mId; // A valid id is >= 0.
OptionFlag mOptionFlags; // option flags for the configuration.
double mDurationMs; // duration, must be > 0; default is 1000 ms.
+
+ int32_t getOptionFlagsAsAidl() const {
+ int32_t result = 0;
+ if (getOptionFlags() & OPTION_FLAG_VOLUME_IN_DBFS) {
+ result |=
+ 1 << static_cast<int>(VolumeShaperConfigurationOptionFlag::VOLUME_IN_DBFS);
+ }
+ if (getOptionFlags() & OPTION_FLAG_CLOCK_TIME) {
+ result |= 1 << static_cast<int>(VolumeShaperConfigurationOptionFlag::CLOCK_TIME);
+ }
+ return result;
+ }
+
+ status_t setOptionFlagsFromAidl(int32_t aidl) {
+ std::underlying_type_t<OptionFlag> options = 0;
+ if (aidl & (1 << static_cast<int>(VolumeShaperConfigurationOptionFlag::VOLUME_IN_DBFS))) {
+ options |= OPTION_FLAG_VOLUME_IN_DBFS;
+ }
+ if (aidl & (1 << static_cast<int>(VolumeShaperConfigurationOptionFlag::CLOCK_TIME))) {
+ options |= OPTION_FLAG_CLOCK_TIME;
+ }
+ return setOptionFlags(static_cast<OptionFlag>(options));
+ }
+
+ status_t setTypeFromAidl(VolumeShaperConfigurationType aidl) {
+ switch (aidl) {
+ case VolumeShaperConfigurationType::ID:
+ return setType(TYPE_ID);
+ case VolumeShaperConfigurationType::SCALE:
+ return setType(TYPE_SCALE);
+ default:
+ return BAD_VALUE;
+ }
+ }
+
+ VolumeShaperConfigurationType getTypeAsAidl() const {
+ switch (getType()) {
+ case TYPE_ID:
+ return VolumeShaperConfigurationType::ID;
+ case TYPE_SCALE:
+ return VolumeShaperConfigurationType::SCALE;
+ default:
+ LOG_ALWAYS_FATAL("Shouldn't get here");
+ }
+ }
}; // Configuration
/* VolumeShaper::Operation expresses an operation to perform on the
@@ -420,19 +478,29 @@
return NO_ERROR;
}
- status_t writeToParcel(Parcel *parcel) const override {
+ status_t writeToParcel(Parcel* parcel) const override {
if (parcel == nullptr) return BAD_VALUE;
- return parcel->writeInt32((int32_t)mFlags)
- ?: parcel->writeInt32(mReplaceId)
- ?: parcel->writeFloat(mXOffset);
+ VolumeShaperOperation op;
+ writeToParcelable(&op);
+ return op.writeToParcel(parcel);
}
- status_t readFromParcel(const Parcel *parcel) override {
- int32_t flags;
- return parcel->readInt32(&flags)
- ?: parcel->readInt32(&mReplaceId)
- ?: parcel->readFloat(&mXOffset)
- ?: setFlags((Flag)flags);
+ void writeToParcelable(VolumeShaperOperation* op) const {
+ op->flags = getFlagsAsAidl();
+ op->replaceId = mReplaceId;
+ op->xOffset = mXOffset;
+ }
+
+ status_t readFromParcel(const Parcel* parcel) override {
+ VolumeShaperOperation op;
+ return op.readFromParcel(parcel)
+ ?: readFromParcelable(op);
+ }
+
+ status_t readFromParcelable(const VolumeShaperOperation& op) {
+ mReplaceId = op.replaceId;
+ mXOffset = op.xOffset;
+ return setFlagsFromAidl(op.flags);
}
std::string toString() const {
@@ -445,6 +513,48 @@
}
private:
+ status_t setFlagsFromAidl(int32_t aidl) {
+ std::underlying_type_t<Flag> flags = 0;
+ if (aidl & (1 << static_cast<int>(VolumeShaperOperationFlag::REVERSE))) {
+ flags |= FLAG_REVERSE;
+ }
+ if (aidl & (1 << static_cast<int>(VolumeShaperOperationFlag::TERMINATE))) {
+ flags |= FLAG_TERMINATE;
+ }
+ if (aidl & (1 << static_cast<int>(VolumeShaperOperationFlag::JOIN))) {
+ flags |= FLAG_JOIN;
+ }
+ if (aidl & (1 << static_cast<int>(VolumeShaperOperationFlag::DELAY))) {
+ flags |= FLAG_DELAY;
+ }
+ if (aidl & (1 << static_cast<int>(VolumeShaperOperationFlag::CREATE_IF_NECESSARY))) {
+ flags |= FLAG_CREATE_IF_NECESSARY;
+ }
+ return setFlags(static_cast<Flag>(flags));
+ }
+
+ int32_t getFlagsAsAidl() const {
+ int32_t aidl = 0;
+ std::underlying_type_t<Flag> flags = getFlags();
+ if (flags & FLAG_REVERSE) {
+ aidl |= (1 << static_cast<int>(VolumeShaperOperationFlag::REVERSE));
+ }
+ if (flags & FLAG_TERMINATE) {
+ aidl |= (1 << static_cast<int>(VolumeShaperOperationFlag::TERMINATE));
+ }
+ if (flags & FLAG_JOIN) {
+ aidl |= (1 << static_cast<int>(VolumeShaperOperationFlag::JOIN));
+ }
+ if (flags & FLAG_DELAY) {
+ aidl |= (1 << static_cast<int>(VolumeShaperOperationFlag::DELAY));
+ }
+ if (flags & FLAG_CREATE_IF_NECESSARY) {
+ aidl |= (1 << static_cast<int>(VolumeShaperOperationFlag::CREATE_IF_NECESSARY));
+ }
+ return aidl;
+ }
+
+ private:
Flag mFlags; // operation to do
int32_t mReplaceId; // if >= 0 the id to remove in a replace operation.
S mXOffset; // position in the curve to set if a valid number (not nan)
@@ -483,15 +593,28 @@
mXOffset = xOffset;
}
- status_t writeToParcel(Parcel *parcel) const override {
+ status_t writeToParcel(Parcel* parcel) const override {
if (parcel == nullptr) return BAD_VALUE;
- return parcel->writeFloat(mVolume)
- ?: parcel->writeFloat(mXOffset);
+ VolumeShaperState state;
+ writeToParcelable(&state);
+ return state.writeToParcel(parcel);
}
- status_t readFromParcel(const Parcel *parcel) override {
- return parcel->readFloat(&mVolume)
- ?: parcel->readFloat(&mXOffset);
+ void writeToParcelable(VolumeShaperState* parcelable) const {
+ parcelable->volume = mVolume;
+ parcelable->xOffset = mXOffset;
+ }
+
+ status_t readFromParcel(const Parcel* parcel) override {
+ VolumeShaperState state;
+ return state.readFromParcel(parcel)
+ ?: readFromParcelable(state);
+ }
+
+ status_t readFromParcelable(const VolumeShaperState& parcelable) {
+ mVolume = parcelable.volume;
+ mXOffset = parcelable.xOffset;
+ return OK;
}
std::string toString() const {
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 6881f42..c23c38c 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -15,9 +15,11 @@
],
static_libs: [
"audioflinger-aidl-unstable-cpp",
+ "av-types-aidl-unstable-cpp",
],
export_static_lib_headers: [
"audioflinger-aidl-unstable-cpp",
+ "av-types-aidl-unstable-cpp",
],
target: {
darwin: {
@@ -63,7 +65,7 @@
export_aidl_headers: true,
local_include_dirs: ["aidl"],
include_dirs: [
- "frameworks/av/media/libaudioclient/aidl",
+ "frameworks/av/aidl",
],
},
@@ -91,6 +93,7 @@
shared_libs: [
"audioclient-types-aidl-unstable-cpp",
"audioflinger-aidl-unstable-cpp",
+ "av-types-aidl-unstable-cpp",
"capture_state_listener-aidl-cpp",
"libaudioclient_aidl_conversion",
"libaudiofoundation",
@@ -260,10 +263,19 @@
"aidl/android/media/AudioSourceType.aidl",
"aidl/android/media/AudioStreamType.aidl",
"aidl/android/media/AudioUsage.aidl",
- ],
+ ],
imports: [
"audio_common-aidl",
],
+ backend: {
+ cpp: {
+ min_sdk_version: "29",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media",
+ ],
+ },
+ },
}
aidl_interface {
diff --git a/media/libaudioclient/PlayerBase.cpp b/media/libaudioclient/PlayerBase.cpp
index b0c68e5..c443865 100644
--- a/media/libaudioclient/PlayerBase.cpp
+++ b/media/libaudioclient/PlayerBase.cpp
@@ -22,7 +22,8 @@
namespace android {
-using media::VolumeShaper;
+using media::VolumeShaperConfiguration;
+using media::VolumeShaperOperation;
//--------------------------------------------------------------------------------------------------
PlayerBase::PlayerBase() : BnPlayer(),
@@ -178,8 +179,8 @@
}
binder::Status PlayerBase::applyVolumeShaper(
- const VolumeShaper::Configuration& configuration __unused,
- const VolumeShaper::Operation& operation __unused) {
+ const VolumeShaperConfiguration& configuration __unused,
+ const VolumeShaperOperation& operation __unused) {
ALOGW("applyVolumeShaper() is not supported");
return binder::Status::ok();
}
diff --git a/media/libaudioclient/TrackPlayerBase.cpp b/media/libaudioclient/TrackPlayerBase.cpp
index 0a914fc..e571838 100644
--- a/media/libaudioclient/TrackPlayerBase.cpp
+++ b/media/libaudioclient/TrackPlayerBase.cpp
@@ -106,11 +106,17 @@
binder::Status TrackPlayerBase::applyVolumeShaper(
- const VolumeShaper::Configuration& configuration,
- const VolumeShaper::Operation& operation) {
+ const media::VolumeShaperConfiguration& configuration,
+ const media::VolumeShaperOperation& operation) {
- sp<VolumeShaper::Configuration> spConfiguration = new VolumeShaper::Configuration(configuration);
- sp<VolumeShaper::Operation> spOperation = new VolumeShaper::Operation(operation);
+ sp<VolumeShaper::Configuration> spConfiguration = new VolumeShaper::Configuration();
+ sp<VolumeShaper::Operation> spOperation = new VolumeShaper::Operation();
+
+ status_t s = spConfiguration->readFromParcelable(configuration)
+ ?: spOperation->readFromParcelable(operation);
+ if (s != OK) {
+ return binder::Status::fromStatusT(s);
+ }
if (mAudioTrack != 0) {
ALOGD("TrackPlayerBase::applyVolumeShaper() from IPlayer");
diff --git a/media/libaudioclient/aidl/android/media/IPlayer.aidl b/media/libaudioclient/aidl/android/media/IPlayer.aidl
index a90fcdd..8c2c471 100644
--- a/media/libaudioclient/aidl/android/media/IPlayer.aidl
+++ b/media/libaudioclient/aidl/android/media/IPlayer.aidl
@@ -16,8 +16,8 @@
package android.media;
-import android.media.VolumeShaper.Configuration;
-import android.media.VolumeShaper.Operation;
+import android.media.VolumeShaperConfiguration;
+import android.media.VolumeShaperOperation;
/**
* @hide
@@ -29,6 +29,6 @@
oneway void setVolume(float vol);
oneway void setPan(float pan);
oneway void setStartDelayMs(int delayMs);
- oneway void applyVolumeShaper(in Configuration configuration,
- in Operation operation);
+ oneway void applyVolumeShaper(in VolumeShaperConfiguration configuration,
+ in VolumeShaperOperation operation);
}
diff --git a/media/libaudioclient/aidl/android/media/VolumeShaper/Configuration.aidl b/media/libaudioclient/aidl/android/media/VolumeShaper/Configuration.aidl
deleted file mode 100644
index fd0e60f..0000000
--- a/media/libaudioclient/aidl/android/media/VolumeShaper/Configuration.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package android.media.VolumeShaper;
-
-parcelable Configuration cpp_header "media/VolumeShaper.h";
diff --git a/media/libaudioclient/aidl/android/media/VolumeShaper/Operation.aidl b/media/libaudioclient/aidl/android/media/VolumeShaper/Operation.aidl
deleted file mode 100644
index 4290d9d..0000000
--- a/media/libaudioclient/aidl/android/media/VolumeShaper/Operation.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package android.media.VolumeShaper;
-
-parcelable Operation cpp_header "media/VolumeShaper.h";
diff --git a/media/libaudioclient/include/media/PlayerBase.h b/media/libaudioclient/include/media/PlayerBase.h
index e7a8abc..4aad9b4 100644
--- a/media/libaudioclient/include/media/PlayerBase.h
+++ b/media/libaudioclient/include/media/PlayerBase.h
@@ -19,6 +19,7 @@
#include <audiomanager/AudioManager.h>
#include <audiomanager/IAudioManager.h>
+#include <utils/Mutex.h>
#include "android/media/BnPlayer.h"
@@ -40,8 +41,8 @@
virtual binder::Status setPan(float pan) override;
virtual binder::Status setStartDelayMs(int32_t delayMs) override;
virtual binder::Status applyVolumeShaper(
- const media::VolumeShaper::Configuration& configuration,
- const media::VolumeShaper::Operation& operation) override;
+ const media::VolumeShaperConfiguration& configuration,
+ const media::VolumeShaperOperation& operation) override;
status_t startWithStatus();
status_t pauseWithStatus();
diff --git a/media/libaudioclient/include/media/TrackPlayerBase.h b/media/libaudioclient/include/media/TrackPlayerBase.h
index 66e9b3b..6d26e63 100644
--- a/media/libaudioclient/include/media/TrackPlayerBase.h
+++ b/media/libaudioclient/include/media/TrackPlayerBase.h
@@ -33,8 +33,8 @@
//IPlayer implementation
virtual binder::Status applyVolumeShaper(
- const media::VolumeShaper::Configuration& configuration,
- const media::VolumeShaper::Operation& operation);
+ const media::VolumeShaperConfiguration& configuration,
+ const media::VolumeShaperOperation& operation);
//FIXME move to protected field, so far made public to minimize changes to AudioTrack logic
sp<AudioTrack> mAudioTrack;
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 39523de..1a7eb6f 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -322,6 +322,8 @@
shared_libs: [
"android.hidl.token@1.0-utils",
+ "audioclient-types-aidl-unstable-cpp",
+ "av-types-aidl-unstable-cpp",
"liblog",
"libcutils",
"libprocessgroup",
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index 324f4ae..b62317a 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -15,6 +15,7 @@
shared_libs: [
"android.hardware.media.c2@1.0",
"android.hardware.media.omx@1.0",
+ "av-types-aidl-unstable-cpp",
"libbase",
"libandroid_net",
"libaudioclient",
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index 261af5a..7443320 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -37,6 +37,7 @@
shared_libs: [
"audioflinger-aidl-unstable-cpp",
"audioclient-types-aidl-unstable-cpp",
+ "av-types-aidl-unstable-cpp",
"libaudioclient_aidl_conversion",
"libaudiofoundation",
"libaudiohal",