Convert IAudioTrack to AIDL
Test: Audio-related CTS tests from CtsMediaTestCases
Change-Id: Ia021b9152cf0cb62e3d1999f9c6184601efd2a93
diff --git a/media/libaudioclient/AidlConversion.cpp b/media/libaudioclient/AidlConversion.cpp
index 681d4d7..e844a6e 100644
--- a/media/libaudioclient/AidlConversion.cpp
+++ b/media/libaudioclient/AidlConversion.cpp
@@ -1683,4 +1683,22 @@
return aidl;
}
+ConversionResult<AudioTimestamp>
+aidl2legacy_AudioTimestamp(const media::AudioTimestampInternal& aidl) {
+ AudioTimestamp legacy;
+ legacy.mPosition = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.position));
+ legacy.mTime.tv_sec = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.sec));
+ legacy.mTime.tv_nsec = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.nsec));
+ return legacy;
+}
+
+ConversionResult<media::AudioTimestampInternal>
+legacy2aidl_AudioTimestamp(const AudioTimestamp& legacy) {
+ media::AudioTimestampInternal aidl;
+ aidl.position = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.mPosition));
+ aidl.sec = VALUE_OR_RETURN(convertIntegral<int64_t>(legacy.mTime.tv_sec));
+ aidl.nsec = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.mTime.tv_nsec));
+ return aidl;
+}
+
} // namespace android
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index c23c38c..5aee64a 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -84,7 +84,6 @@
"IAudioFlinger.cpp",
"IAudioPolicyService.cpp",
"IAudioPolicyServiceClient.cpp",
- "IAudioTrack.cpp",
"ToneGenerator.cpp",
"PlayerBase.cpp",
"RecordingActivityTracker.cpp",
@@ -262,6 +261,7 @@
"aidl/android/media/AudioPortType.aidl",
"aidl/android/media/AudioSourceType.aidl",
"aidl/android/media/AudioStreamType.aidl",
+ "aidl/android/media/AudioTimestampInternal.aidl",
"aidl/android/media/AudioUsage.aidl",
],
imports: [
@@ -291,10 +291,12 @@
"aidl/android/media/CreateTrackResponse.aidl",
"aidl/android/media/IAudioFlingerClient.aidl",
+ "aidl/android/media/IAudioTrack.aidl",
"aidl/android/media/IAudioTrackCallback.aidl",
],
imports: [
"audioclient-types-aidl",
+ "av-types-aidl",
"shared-file-region-aidl",
],
double_loadable: true,
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 14950a8..67938bc 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -784,7 +784,7 @@
int32_t flags = android_atomic_and(~(CBLK_STREAM_END_DONE | CBLK_DISABLED), &mCblk->mFlags);
if (!(flags & CBLK_INVALID)) {
- status = mAudioTrack->start();
+ mAudioTrack->start(&status);
if (status == DEAD_OBJECT) {
flags |= CBLK_INVALID;
}
@@ -1477,7 +1477,8 @@
status_t AudioTrack::attachAuxEffect(int effectId)
{
AutoMutex lock(mLock);
- status_t status = mAudioTrack->attachAuxEffect(effectId);
+ status_t status;
+ mAudioTrack->attachAuxEffect(effectId, &status);
if (status == NO_ERROR) {
mAuxEffectId = effectId;
}
@@ -1607,9 +1608,9 @@
input.opPackageName = mOpPackageName;
media::CreateTrackResponse response;
- sp<IAudioTrack> track = audioFlinger->createTrack(VALUE_OR_FATAL(input.toAidl()),
- response,
- &status);
+ sp<media::IAudioTrack> track = audioFlinger->createTrack(VALUE_OR_FATAL(input.toAidl()),
+ response,
+ &status);
IAudioFlinger::CreateTrackOutput output = VALUE_OR_FATAL(
IAudioFlinger::CreateTrackOutput::fromAidl(
response));
@@ -1644,7 +1645,9 @@
// so we are no longer responsible for releasing it.
// FIXME compare to AudioRecord
- sp<IMemory> iMem = track->getCblk();
+ std::optional<media::SharedFileRegion> sfr;
+ track->getCblk(&sfr);
+ sp<IMemory> iMem = VALUE_OR_FATAL(aidl2legacy_NullableSharedFileRegion_IMemory(sfr));
if (iMem == 0) {
ALOGE("%s(%d): Could not get control block", __func__, mPortId);
status = NO_INIT;
@@ -1721,7 +1724,7 @@
}
}
- mAudioTrack->attachAuxEffect(mAuxEffectId);
+ mAudioTrack->attachAuxEffect(mAuxEffectId, &status);
// If IAudioTrack is re-created, don't let the requested frameCount
// decrease. This can confuse clients that cache frameCount().
@@ -1965,7 +1968,8 @@
ALOGW("%s(%d): releaseBuffer() track %p disabled due to previous underrun, restarting",
__func__, mPortId, this);
// FIXME ignoring status
- mAudioTrack->start();
+ status_t status;
+ mAudioTrack->start(&status);
}
}
@@ -2573,11 +2577,17 @@
if (shaper.isStarted()) {
operationToEnd->setNormalizedTime(1.f);
}
- return mAudioTrack->applyVolumeShaper(shaper.mConfiguration, operationToEnd);
+ media::VolumeShaperConfiguration config;
+ shaper.mConfiguration->writeToParcelable(&config);
+ media::VolumeShaperOperation operation;
+ operationToEnd->writeToParcelable(&operation);
+ status_t status;
+ mAudioTrack->applyVolumeShaper(config, operation, &status);
+ return status;
});
if (mState == STATE_ACTIVE) {
- result = mAudioTrack->start();
+ mAudioTrack->start(&result);
}
// server resets to zero so we offset
mFramesWrittenServerOffset =
@@ -2647,7 +2657,9 @@
status_t AudioTrack::setParameters(const String8& keyValuePairs)
{
AutoMutex lock(mLock);
- return mAudioTrack->setParameters(keyValuePairs);
+ status_t status;
+ mAudioTrack->setParameters(keyValuePairs.c_str(), &status);
+ return status;
}
status_t AudioTrack::selectPresentation(int presentationId, int programId)
@@ -2659,7 +2671,9 @@
ALOGV("%s(%d): PresentationId/ProgramId[%s]",
__func__, mPortId, param.toString().string());
- return mAudioTrack->setParameters(param.toString());
+ status_t status;
+ mAudioTrack->setParameters(param.toString().c_str(), &status);
+ return status;
}
VolumeShaper::Status AudioTrack::applyVolumeShaper(
@@ -2668,11 +2682,16 @@
{
AutoMutex lock(mLock);
mVolumeHandler->setIdIfNecessary(configuration);
- VolumeShaper::Status status = mAudioTrack->applyVolumeShaper(configuration, operation);
+ media::VolumeShaperConfiguration config;
+ configuration->writeToParcelable(&config);
+ media::VolumeShaperOperation op;
+ operation->writeToParcelable(&op);
+ VolumeShaper::Status status;
+ mAudioTrack->applyVolumeShaper(config, op, &status);
if (status == DEAD_OBJECT) {
if (restoreTrack_l("applyVolumeShaper") == OK) {
- status = mAudioTrack->applyVolumeShaper(configuration, operation);
+ mAudioTrack->applyVolumeShaper(config, op, &status);
}
}
if (status >= 0) {
@@ -2692,10 +2711,20 @@
sp<VolumeShaper::State> AudioTrack::getVolumeShaperState(int id)
{
AutoMutex lock(mLock);
- sp<VolumeShaper::State> state = mAudioTrack->getVolumeShaperState(id);
+ std::optional<media::VolumeShaperState> vss;
+ mAudioTrack->getVolumeShaperState(id, &vss);
+ sp<VolumeShaper::State> state;
+ if (vss.has_value()) {
+ state = new VolumeShaper::State();
+ state->readFromParcelable(vss.value());
+ }
if (state.get() == nullptr && (mCblk->mFlags & CBLK_INVALID) != 0) {
if (restoreTrack_l("getVolumeShaperState") == OK) {
- state = mAudioTrack->getVolumeShaperState(id);
+ mAudioTrack->getVolumeShaperState(id, &vss);
+ if (vss.has_value()) {
+ state = new VolumeShaper::State();
+ state->readFromParcelable(vss.value());
+ }
}
}
return state;
@@ -2789,7 +2818,11 @@
status_t status;
if (isOffloadedOrDirect_l()) {
// use Binder to get timestamp
- status = mAudioTrack->getTimestamp(timestamp);
+ media::AudioTimestampInternal ts;
+ mAudioTrack->getTimestamp(&ts, &status);
+ if (status == OK) {
+ timestamp = VALUE_OR_FATAL(aidl2legacy_AudioTimestamp(ts));
+ }
} else {
// read timestamp from shared memory
ExtendedTimestamp ets;
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index adb16d4..a4e26ca 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -256,12 +256,12 @@
{
}
- virtual sp<IAudioTrack> createTrack(const media::CreateTrackRequest& input,
- media::CreateTrackResponse& output,
- status_t* status)
+ virtual sp<media::IAudioTrack> createTrack(const media::CreateTrackRequest& input,
+ media::CreateTrackResponse& output,
+ status_t* status)
{
Parcel data, reply;
- sp<IAudioTrack> track;
+ sp<media::IAudioTrack> track;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
if (status == nullptr) {
@@ -281,7 +281,7 @@
ALOGE("createTrack returned error %d", *status);
return track;
}
- track = interface_cast<IAudioTrack>(reply.readStrongBinder());
+ track = interface_cast<media::IAudioTrack>(reply.readStrongBinder());
if (track == 0) {
ALOGE("createTrack returned an NULL IAudioTrack with status OK");
*status = DEAD_OBJECT;
@@ -1199,9 +1199,9 @@
status_t status;
media::CreateTrackResponse output;
- sp<IAudioTrack> track= createTrack(input,
- output,
- &status);
+ sp<media::IAudioTrack> track= createTrack(input,
+ output,
+ &status);
LOG_ALWAYS_FATAL_IF((track != 0) != (status == NO_ERROR));
reply->writeInt32(status);
diff --git a/media/libaudioclient/IAudioTrack.cpp b/media/libaudioclient/IAudioTrack.cpp
deleted file mode 100644
index 6219e7a..0000000
--- a/media/libaudioclient/IAudioTrack.cpp
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
-**
-** Copyright 2007, 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_TAG "IAudioTrack"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-
-#include <media/IAudioTrack.h>
-
-namespace android {
-
-using media::VolumeShaper;
-
-enum {
- GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
- START,
- STOP,
- FLUSH,
- RESERVED, // was MUTE
- PAUSE,
- ATTACH_AUX_EFFECT,
- SET_PARAMETERS,
- SELECT_PRESENTATION,
- GET_TIMESTAMP,
- SIGNAL,
- APPLY_VOLUME_SHAPER,
- GET_VOLUME_SHAPER_STATE,
-};
-
-class BpAudioTrack : public BpInterface<IAudioTrack>
-{
-public:
- explicit BpAudioTrack(const sp<IBinder>& impl)
- : BpInterface<IAudioTrack>(impl)
- {
- }
-
- virtual sp<IMemory> getCblk() const
- {
- Parcel data, reply;
- sp<IMemory> cblk;
- data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
- status_t status = remote()->transact(GET_CBLK, data, &reply);
- if (status == NO_ERROR) {
- cblk = interface_cast<IMemory>(reply.readStrongBinder());
- if (cblk != 0 && cblk->unsecurePointer() == NULL) {
- cblk.clear();
- }
- }
- return cblk;
- }
-
- virtual status_t start()
- {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
- status_t status = remote()->transact(START, data, &reply);
- if (status == NO_ERROR) {
- status = reply.readInt32();
- } else {
- ALOGW("start() error: %s", strerror(-status));
- }
- return status;
- }
-
- virtual void stop()
- {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
- remote()->transact(STOP, data, &reply);
- }
-
- virtual void flush()
- {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
- remote()->transact(FLUSH, data, &reply);
- }
-
- virtual void pause()
- {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
- remote()->transact(PAUSE, data, &reply);
- }
-
- virtual status_t attachAuxEffect(int effectId)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
- data.writeInt32(effectId);
- status_t status = remote()->transact(ATTACH_AUX_EFFECT, data, &reply);
- if (status == NO_ERROR) {
- status = reply.readInt32();
- } else {
- ALOGW("attachAuxEffect() error: %s", strerror(-status));
- }
- return status;
- }
-
- virtual status_t setParameters(const String8& keyValuePairs) {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
- data.writeString8(keyValuePairs);
- status_t status = remote()->transact(SET_PARAMETERS, data, &reply);
- if (status == NO_ERROR) {
- status = reply.readInt32();
- }
- return status;
- }
-
- /* Selects the presentation (if available) */
- virtual status_t selectPresentation(int presentationId, int programId) {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
- data.writeInt32(presentationId);
- data.writeInt32(programId);
- status_t status = remote()->transact(SELECT_PRESENTATION, data, &reply);
- if (status == NO_ERROR) {
- status = reply.readInt32();
- }
- return status;
- }
-
- virtual status_t getTimestamp(AudioTimestamp& timestamp) {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
- status_t status = remote()->transact(GET_TIMESTAMP, data, &reply);
- if (status == NO_ERROR) {
- status = reply.readInt32();
- if (status == NO_ERROR) {
- timestamp.mPosition = reply.readInt32();
- timestamp.mTime.tv_sec = reply.readInt32();
- timestamp.mTime.tv_nsec = reply.readInt32();
- }
- }
- return status;
- }
-
- virtual void signal() {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
- remote()->transact(SIGNAL, data, &reply);
- }
-
- virtual VolumeShaper::Status applyVolumeShaper(
- const sp<VolumeShaper::Configuration>& configuration,
- const sp<VolumeShaper::Operation>& operation) {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-
- status_t status = configuration.get() == nullptr
- ? data.writeInt32(0)
- : data.writeInt32(1)
- ?: configuration->writeToParcel(&data);
- if (status != NO_ERROR) {
- return VolumeShaper::Status(status);
- }
-
- status = operation.get() == nullptr
- ? status = data.writeInt32(0)
- : data.writeInt32(1)
- ?: operation->writeToParcel(&data);
- if (status != NO_ERROR) {
- return VolumeShaper::Status(status);
- }
-
- int32_t remoteVolumeShaperStatus;
- status = remote()->transact(APPLY_VOLUME_SHAPER, data, &reply)
- ?: reply.readInt32(&remoteVolumeShaperStatus);
-
- return VolumeShaper::Status(status ?: remoteVolumeShaperStatus);
- }
-
- virtual sp<VolumeShaper::State> getVolumeShaperState(int id) {
- Parcel data, reply;
- data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
-
- data.writeInt32(id);
- status_t status = remote()->transact(GET_VOLUME_SHAPER_STATE, data, &reply);
- if (status != NO_ERROR) {
- return nullptr;
- }
- sp<VolumeShaper::State> state = new VolumeShaper::State;
- status = state->readFromParcel(&reply);
- if (status != NO_ERROR) {
- return nullptr;
- }
- return state;
- }
-};
-
-IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack");
-
-// ----------------------------------------------------------------------
-
-status_t BnAudioTrack::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch (code) {
- case GET_CBLK: {
- CHECK_INTERFACE(IAudioTrack, data, reply);
- reply->writeStrongBinder(IInterface::asBinder(getCblk()));
- return NO_ERROR;
- } break;
- case START: {
- CHECK_INTERFACE(IAudioTrack, data, reply);
- reply->writeInt32(start());
- return NO_ERROR;
- } break;
- case STOP: {
- CHECK_INTERFACE(IAudioTrack, data, reply);
- stop();
- return NO_ERROR;
- } break;
- case FLUSH: {
- CHECK_INTERFACE(IAudioTrack, data, reply);
- flush();
- return NO_ERROR;
- } break;
- case PAUSE: {
- CHECK_INTERFACE(IAudioTrack, data, reply);
- pause();
- return NO_ERROR;
- }
- case ATTACH_AUX_EFFECT: {
- CHECK_INTERFACE(IAudioTrack, data, reply);
- reply->writeInt32(attachAuxEffect(data.readInt32()));
- return NO_ERROR;
- } break;
- case SET_PARAMETERS: {
- CHECK_INTERFACE(IAudioTrack, data, reply);
- String8 keyValuePairs(data.readString8());
- reply->writeInt32(setParameters(keyValuePairs));
- return NO_ERROR;
- } break;
- case SELECT_PRESENTATION: {
- CHECK_INTERFACE(IAudioTrack, data, reply);
- reply->writeInt32(selectPresentation(data.readInt32(), data.readInt32()));
- return NO_ERROR;
- } break;
- case GET_TIMESTAMP: {
- CHECK_INTERFACE(IAudioTrack, data, reply);
- AudioTimestamp timestamp;
- status_t status = getTimestamp(timestamp);
- reply->writeInt32(status);
- if (status == NO_ERROR) {
- reply->writeInt32(timestamp.mPosition);
- reply->writeInt32(timestamp.mTime.tv_sec);
- reply->writeInt32(timestamp.mTime.tv_nsec);
- }
- return NO_ERROR;
- } break;
- case SIGNAL: {
- CHECK_INTERFACE(IAudioTrack, data, reply);
- signal();
- return NO_ERROR;
- } break;
- case APPLY_VOLUME_SHAPER: {
- CHECK_INTERFACE(IAudioTrack, data, reply);
- sp<VolumeShaper::Configuration> configuration;
- sp<VolumeShaper::Operation> operation;
-
- int32_t present;
- status_t status = data.readInt32(&present);
- if (status == NO_ERROR && present != 0) {
- configuration = new VolumeShaper::Configuration();
- status = configuration->readFromParcel(&data);
- }
- status = status ?: data.readInt32(&present);
- if (status == NO_ERROR && present != 0) {
- operation = new VolumeShaper::Operation();
- status = operation->readFromParcel(&data);
- }
- if (status == NO_ERROR) {
- status = (status_t)applyVolumeShaper(configuration, operation);
- }
- reply->writeInt32(status);
- return NO_ERROR;
- } break;
- case GET_VOLUME_SHAPER_STATE: {
- CHECK_INTERFACE(IAudioTrack, data, reply);
- int id;
- status_t status = data.readInt32(&id);
- if (status == NO_ERROR) {
- sp<VolumeShaper::State> state = getVolumeShaperState(id);
- if (state.get() != nullptr) {
- status = state->writeToParcel(reply);
- }
- }
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-} // namespace android
diff --git a/media/libaudioclient/aidl/android/media/AudioTimestampInternal.aidl b/media/libaudioclient/aidl/android/media/AudioTimestampInternal.aidl
new file mode 100644
index 0000000..8bbfb57
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/AudioTimestampInternal.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+/**
+ * The "Internal" timestamp is intended to disambiguate from the android.media.AudioTimestamp type.
+ *
+ * {@hide}
+ */
+parcelable AudioTimestampInternal {
+ /** A frame position in AudioTrack::getPosition() units. */
+ int position;
+ /** corresponding CLOCK_MONOTONIC when frame is expected to present. */
+ long sec;
+ int nsec;
+}
diff --git a/media/libaudioclient/aidl/android/media/IAudioTrack.aidl b/media/libaudioclient/aidl/android/media/IAudioTrack.aidl
new file mode 100644
index 0000000..3a835d3
--- /dev/null
+++ b/media/libaudioclient/aidl/android/media/IAudioTrack.aidl
@@ -0,0 +1,83 @@
+/*
+ * 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.AudioTimestampInternal;
+import android.media.SharedFileRegion;
+import android.media.VolumeShaperConfiguration;
+import android.media.VolumeShaperOperation;
+import android.media.VolumeShaperState;
+
+/**
+ * Unless otherwise noted, methods returning int expect it to be interpreted as a status_t.
+ * @hide
+ */
+interface IAudioTrack {
+ /** Get this track's control block */
+ @nullable SharedFileRegion getCblk();
+
+ /**
+ * After it's created the track is not active. Call start() to
+ * make it active.
+ */
+ int start();
+
+ /**
+ * Stop a track. If set, the callback will cease being called and
+ * obtainBuffer will return an error. Buffers that are already released
+ * will continue to be processed, unless/until flush() is called.
+ */
+ void stop();
+
+ /**
+ * Flush a stopped or paused track. All pending/released buffers are discarded.
+ * This function has no effect if the track is not stopped or paused.
+ */
+ void flush();
+
+ /**
+ * Pause a track. If set, the callback will cease being called and
+ * obtainBuffer will return an error. Buffers that are already released
+ * will continue to be processed, unless/until flush() is called.
+ */
+ void pause();
+
+ /**
+ * Attach track auxiliary output to specified effect. Use effectId = 0
+ * to detach track from effect.
+ */
+ int attachAuxEffect(int effectId);
+
+ /** Send parameters to the audio hardware. */
+ int setParameters(@utf8InCpp String keyValuePairs);
+
+ /** Selects the presentation (if available). */
+ int selectPresentation(int presentationId, int programId);
+
+ /** Return NO_ERROR if timestamp is valid. */
+ int getTimestamp(out AudioTimestampInternal timestamp);
+
+ /** Signal the playback thread for a change in control block. */
+ void signal();
+
+ /** Sets the volume shaper. Returns the volume shaper status. */
+ int applyVolumeShaper(in VolumeShaperConfiguration configuration,
+ in VolumeShaperOperation operation);
+
+ /** Gets the volume shaper state. */
+ @nullable VolumeShaperState getVolumeShaperState(int id);
+}
diff --git a/media/libaudioclient/include/media/AidlConversion.h b/media/libaudioclient/include/media/AidlConversion.h
index 4df8083..e429ea1 100644
--- a/media/libaudioclient/include/media/AidlConversion.h
+++ b/media/libaudioclient/include/media/AidlConversion.h
@@ -34,12 +34,14 @@
#include <android/media/AudioIoDescriptor.h>
#include <android/media/AudioOutputFlags.h>
#include <android/media/AudioPortConfigType.h>
+#include <android/media/AudioTimestampInternal.h>
#include <android/media/SharedFileRegion.h>
#include <binder/IMemory.h>
#include <media/AudioClient.h>
#include <media/AudioIoDescriptor.h>
+#include <media/AudioTimestamp.h>
namespace android {
@@ -280,4 +282,9 @@
ConversionResult<std::optional<media::SharedFileRegion>>
legacy2aidl_NullableIMemory_SharedFileRegion(const sp<IMemory>& legacy);
+ConversionResult<AudioTimestamp>
+aidl2legacy_AudioTimestamp(const media::AudioTimestampInternal& aidl);
+ConversionResult<media::AudioTimestampInternal>
+legacy2aidl_AudioTimestamp(const AudioTimestamp& legacy);
+
} // namespace android
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index de183d8..3728a16 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -17,18 +17,20 @@
#ifndef ANDROID_AUDIOTRACK_H
#define ANDROID_AUDIOTRACK_H
+#include <binder/IMemory.h>
#include <cutils/sched_policy.h>
#include <media/AudioSystem.h>
#include <media/AudioTimestamp.h>
-#include <media/IAudioTrack.h>
#include <media/AudioResamplerPublic.h>
#include <media/MediaMetricsItem.h>
#include <media/Modulo.h>
+#include <media/VolumeShaper.h>
#include <utils/threads.h>
#include <string>
#include "android/media/BnAudioTrackCallback.h"
+#include "android/media/IAudioTrack.h"
#include "android/media/IAudioTrackCallback.h"
namespace android {
@@ -1071,7 +1073,7 @@
void updateRoutedDeviceId_l();
// Next 4 fields may be changed if IAudioTrack is re-created, but always != 0
- sp<IAudioTrack> mAudioTrack;
+ sp<media::IAudioTrack> mAudioTrack;
sp<IMemory> mCblkMemory;
audio_track_cblk_t* mCblk; // re-load after mLock.unlock()
audio_io_handle_t mOutput = AUDIO_IO_HANDLE_NONE; // from AudioSystem::getOutputForAttr()
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index db7e4f6..20aabf9 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -29,7 +29,6 @@
#include <media/AidlConversion.h>
#include <media/AudioClient.h>
#include <media/DeviceDescriptorBase.h>
-#include <media/IAudioTrack.h>
#include <system/audio.h>
#include <system/audio_effect.h>
#include <system/audio_policy.h>
@@ -44,6 +43,7 @@
#include "android/media/CreateTrackResponse.h"
#include "android/media/IAudioRecord.h"
#include "android/media/IAudioFlingerClient.h"
+#include "android/media/IAudioTrack.h"
#include "android/media/IAudioTrackCallback.h"
#include "android/media/IEffect.h"
#include "android/media/IEffectClient.h"
@@ -163,9 +163,9 @@
/* create an audio track and registers it with AudioFlinger.
* return null if the track cannot be created.
*/
- virtual sp<IAudioTrack> createTrack(const media::CreateTrackRequest& input,
- media::CreateTrackResponse& output,
- status_t* status) = 0;
+ virtual sp<media::IAudioTrack> createTrack(const media::CreateTrackRequest& input,
+ media::CreateTrackResponse& output,
+ status_t* status) = 0;
virtual sp<media::IAudioRecord> createRecord(const media::CreateRecordRequest& input,
media::CreateRecordResponse& output,
diff --git a/media/libaudioclient/include/media/IAudioTrack.h b/media/libaudioclient/include/media/IAudioTrack.h
deleted file mode 100644
index 06e786d..0000000
--- a/media/libaudioclient/include/media/IAudioTrack.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2007 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_IAUDIOTRACK_H
-#define ANDROID_IAUDIOTRACK_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/RefBase.h>
-#include <utils/Errors.h>
-#include <binder/IInterface.h>
-#include <binder/IMemory.h>
-#include <utils/String8.h>
-#include <media/AudioTimestamp.h>
-#include <media/VolumeShaper.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class IAudioTrack : public IInterface
-{
-public:
- DECLARE_META_INTERFACE(AudioTrack);
-
- /* Get this track's control block */
- virtual sp<IMemory> getCblk() const = 0;
-
- /* After it's created the track is not active. Call start() to
- * make it active.
- */
- virtual status_t start() = 0;
-
- /* Stop a track. If set, the callback will cease being called and
- * obtainBuffer will return an error. Buffers that are already released
- * will continue to be processed, unless/until flush() is called.
- */
- virtual void stop() = 0;
-
- /* Flush a stopped or paused track. All pending/released buffers are discarded.
- * This function has no effect if the track is not stopped or paused.
- */
- virtual void flush() = 0;
-
- /* Pause a track. If set, the callback will cease being called and
- * obtainBuffer will return an error. Buffers that are already released
- * will continue to be processed, unless/until flush() is called.
- */
- virtual void pause() = 0;
-
- /* Attach track auxiliary output to specified effect. Use effectId = 0
- * to detach track from effect.
- */
- virtual status_t attachAuxEffect(int effectId) = 0;
-
- /* Send parameters to the audio hardware */
- virtual status_t setParameters(const String8& keyValuePairs) = 0;
-
- /* Selects the presentation (if available) */
- virtual status_t selectPresentation(int presentationId, int programId) = 0;
-
- /* Return NO_ERROR if timestamp is valid. timestamp is undefined otherwise. */
- virtual status_t getTimestamp(AudioTimestamp& timestamp) = 0;
-
- /* Signal the playback thread for a change in control block */
- virtual void signal() = 0;
-
- /* Sets the volume shaper */
- virtual media::VolumeShaper::Status applyVolumeShaper(
- const sp<media::VolumeShaper::Configuration>& configuration,
- const sp<media::VolumeShaper::Operation>& operation) = 0;
-
- /* gets the volume shaper state */
- virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnAudioTrack : public BnInterface<IAudioTrack>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_IAUDIOTRACK_H
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 959e858..a7f0980 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -757,9 +757,9 @@
// IAudioFlinger interface
-sp<IAudioTrack> AudioFlinger::createTrack(const media::CreateTrackRequest& _input,
- media::CreateTrackResponse& _output,
- status_t* status)
+sp<media::IAudioTrack> AudioFlinger::createTrack(const media::CreateTrackRequest& _input,
+ media::CreateTrackResponse& _output,
+ status_t* status)
{
// Local version of VALUE_OR_RETURN, specific to this method's calling conventions.
#define VALUE_OR_EXIT(expr) \
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index b7206b0..60d878a 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -33,6 +33,7 @@
#include <sys/types.h>
#include <limits.h>
+#include <android/media/BnAudioTrack.h>
#include <android/media/IAudioFlingerClient.h>
#include <android/media/IAudioTrackCallback.h>
#include <android/os/BnExternalVibrationController.h>
@@ -43,7 +44,6 @@
#include <cutils/properties.h>
#include <media/IAudioFlinger.h>
-#include <media/IAudioTrack.h>
#include <media/AudioSystem.h>
#include <media/AudioTrack.h>
#include <media/MmapStreamInterface.h>
@@ -135,9 +135,9 @@
virtual status_t dump(int fd, const Vector<String16>& args);
// IAudioFlinger interface, in binder opcode order
- virtual sp<IAudioTrack> createTrack(const media::CreateTrackRequest& input,
- media::CreateTrackResponse& output,
- status_t* status) override;
+ virtual sp<media::IAudioTrack> createTrack(const media::CreateTrackRequest& input,
+ media::CreateTrackResponse& output,
+ status_t* status) override;
virtual sp<media::IAudioRecord> createRecord(const media::CreateRecordRequest& input,
media::CreateRecordResponse& output,
@@ -626,27 +626,30 @@
}
// server side of the client's IAudioTrack
- class TrackHandle : public android::BnAudioTrack {
+ class TrackHandle : public android::media::BnAudioTrack {
public:
explicit TrackHandle(const sp<PlaybackThread::Track>& track);
virtual ~TrackHandle();
- virtual sp<IMemory> getCblk() const;
- virtual status_t start();
- virtual void stop();
- virtual void flush();
- virtual void pause();
- virtual status_t attachAuxEffect(int effectId);
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual status_t selectPresentation(int presentationId, int programId);
- virtual media::VolumeShaper::Status applyVolumeShaper(
- const sp<media::VolumeShaper::Configuration>& configuration,
- const sp<media::VolumeShaper::Operation>& operation) override;
- virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) override;
- virtual status_t getTimestamp(AudioTimestamp& timestamp);
- virtual void signal(); // signal playback thread for a change in control block
- virtual status_t onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+ binder::Status getCblk(std::optional<media::SharedFileRegion>* _aidl_return) override;
+ binder::Status start(int32_t* _aidl_return) override;
+ binder::Status stop() override;
+ binder::Status flush() override;
+ binder::Status pause() override;
+ binder::Status attachAuxEffect(int32_t effectId, int32_t* _aidl_return) override;
+ binder::Status setParameters(const std::string& keyValuePairs,
+ int32_t* _aidl_return) override;
+ binder::Status selectPresentation(int32_t presentationId, int32_t programId,
+ int32_t* _aidl_return) override;
+ binder::Status getTimestamp(media::AudioTimestampInternal* timestamp,
+ int32_t* _aidl_return) override;
+ binder::Status signal() override;
+ binder::Status applyVolumeShaper(const media::VolumeShaperConfiguration& configuration,
+ const media::VolumeShaperOperation& operation,
+ int32_t* _aidl_return) override;
+ binder::Status getVolumeShaperState(
+ int32_t id,
+ std::optional<media::VolumeShaperState>* _aidl_return) override;
private:
const sp<PlaybackThread::Track> mTrack;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 1a12a5f..5c4d4b9 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -54,6 +54,7 @@
namespace android {
+using binder::Status;
using media::VolumeShaper;
// ----------------------------------------------------------------------------
// TrackBase
@@ -319,64 +320,98 @@
mTrack->destroy();
}
-sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
- return mTrack->getCblk();
+Status AudioFlinger::TrackHandle::getCblk(
+ std::optional<media::SharedFileRegion>* _aidl_return) {
+ *_aidl_return = legacy2aidl_NullableIMemory_SharedFileRegion(mTrack->getCblk()).value();
+ return Status::ok();
}
-status_t AudioFlinger::TrackHandle::start() {
- return mTrack->start();
+Status AudioFlinger::TrackHandle::start(int32_t* _aidl_return) {
+ *_aidl_return = mTrack->start();
+ return Status::ok();
}
-void AudioFlinger::TrackHandle::stop() {
+Status AudioFlinger::TrackHandle::stop() {
mTrack->stop();
+ return Status::ok();
}
-void AudioFlinger::TrackHandle::flush() {
+Status AudioFlinger::TrackHandle::flush() {
mTrack->flush();
+ return Status::ok();
}
-void AudioFlinger::TrackHandle::pause() {
+Status AudioFlinger::TrackHandle::pause() {
mTrack->pause();
+ return Status::ok();
}
-status_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId)
-{
- return mTrack->attachAuxEffect(EffectId);
+Status AudioFlinger::TrackHandle::attachAuxEffect(int32_t effectId,
+ int32_t* _aidl_return) {
+ *_aidl_return = mTrack->attachAuxEffect(effectId);
+ return Status::ok();
}
-status_t AudioFlinger::TrackHandle::setParameters(const String8& keyValuePairs) {
- return mTrack->setParameters(keyValuePairs);
+Status AudioFlinger::TrackHandle::setParameters(const std::string& keyValuePairs,
+ int32_t* _aidl_return) {
+ *_aidl_return = mTrack->setParameters(String8(keyValuePairs.c_str()));
+ return Status::ok();
}
-status_t AudioFlinger::TrackHandle::selectPresentation(int presentationId, int programId) {
- return mTrack->selectPresentation(presentationId, programId);
+Status AudioFlinger::TrackHandle::selectPresentation(int32_t presentationId, int32_t programId,
+ int32_t* _aidl_return) {
+ *_aidl_return = mTrack->selectPresentation(presentationId, programId);
+ return Status::ok();
}
-VolumeShaper::Status AudioFlinger::TrackHandle::applyVolumeShaper(
- const sp<VolumeShaper::Configuration>& configuration,
- const sp<VolumeShaper::Operation>& operation) {
- return mTrack->applyVolumeShaper(configuration, operation);
+Status AudioFlinger::TrackHandle::getTimestamp(media::AudioTimestampInternal* timestamp,
+ int32_t* _aidl_return) {
+ AudioTimestamp legacy;
+ *_aidl_return = mTrack->getTimestamp(legacy);
+ if (*_aidl_return != OK) {
+ return Status::ok();
+ }
+ *timestamp = legacy2aidl_AudioTimestamp(legacy).value();
+ return Status::ok();
}
-sp<VolumeShaper::State> AudioFlinger::TrackHandle::getVolumeShaperState(int id) {
- return mTrack->getVolumeShaperState(id);
+Status AudioFlinger::TrackHandle::signal() {
+ mTrack->signal();
+ return Status::ok();
}
-status_t AudioFlinger::TrackHandle::getTimestamp(AudioTimestamp& timestamp)
-{
- return mTrack->getTimestamp(timestamp);
+Status AudioFlinger::TrackHandle::applyVolumeShaper(
+ const media::VolumeShaperConfiguration& configuration,
+ const media::VolumeShaperOperation& operation,
+ int32_t* _aidl_return) {
+ sp<VolumeShaper::Configuration> conf = new VolumeShaper::Configuration();
+ *_aidl_return = conf->readFromParcelable(configuration);
+ if (*_aidl_return != OK) {
+ return Status::ok();
+ }
+
+ sp<VolumeShaper::Operation> op = new VolumeShaper::Operation();
+ *_aidl_return = op->readFromParcelable(operation);
+ if (*_aidl_return != OK) {
+ return Status::ok();
+ }
+
+ *_aidl_return = mTrack->applyVolumeShaper(conf, op);
+ return Status::ok();
}
-
-void AudioFlinger::TrackHandle::signal()
-{
- return mTrack->signal();
-}
-
-status_t AudioFlinger::TrackHandle::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- return BnAudioTrack::onTransact(code, data, reply, flags);
+Status AudioFlinger::TrackHandle::getVolumeShaperState(
+ int32_t id,
+ std::optional<media::VolumeShaperState>* _aidl_return) {
+ sp<VolumeShaper::State> legacy = mTrack->getVolumeShaperState(id);
+ if (legacy == nullptr) {
+ _aidl_return->reset();
+ return Status::ok();
+ }
+ media::VolumeShaperState aidl;
+ legacy->writeToParcelable(&aidl);
+ *_aidl_return = aidl;
+ return Status::ok();
}
// ----------------------------------------------------------------------------