Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d116126 authored by jiabin's avatar jiabin
Browse files

Add callback for output stream.

The callback is targeted for events related to an output stream.
Currently, there is one callback event defined, which is codec
format changed event.

Bug: 133526565
Test: manual
Test: atest VtsHalAudioV6_0TargetTest
Change-Id: I73a4914c1ffc30e1c88b8fedd61a031e24a069f6
parent 7aab1010
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ hidl_interface {
        "IStreamIn.hal",
        "IStreamOut.hal",
        "IStreamOutCallback.hal",
        "IStreamOutEventCallback.hal",
    ],
    interfaces: [
        "android.hardware.audio.common@6.0",
+13 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.hardware.audio@6.0;
import android.hardware.audio.common@6.0;
import IStream;
import IStreamOutCallback;
import IStreamOutEventCallback;

interface IStreamOut extends IStream {
    /**
@@ -167,6 +168,18 @@ interface IStreamOut extends IStream {
     */
    clearCallback() generates (Result retval);

    /**
     * Set the callback interface for notifying about an output stream event.
     *
     * Calling this method with a null pointer will result in releasing
     * the local callback proxy on the server side and thus dereference
     * the callback implementation on the client side.
     *
     * @return retval operation completion status.
     */
    setEventCallback(IStreamOutEventCallback callback)
            generates (Result retval);

    /**
     * Returns whether HAL supports pausing and resuming of streams.
     *
+35 −0
Original line number Diff line number Diff line
/*
 * 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.hardware.audio@6.0;

/**
 * Asynchronous stream out event callback interface. The interface provides
 * a way for the HAL to notify platform when there are changes, e.g. codec
 * format change, from the lower layer.
 */
interface IStreamOutEventCallback {
    /**
     * Codec format changed.
     *
     * @param audioMetadata is a buffer containing decoded format changes
     *     reported by codec. The buffer contains data that can be transformed
     *     to audio metadata, which is a C++ object based map. See
     *     `system/media/audio_utils/include/audio_utils/Metadata.h` for
     *     more details.
     */
    oneway onCodecFormatChanged(vec<uint8_t> audioMetadata);
};
+29 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
//#define LOG_NDEBUG 0
#define ATRACE_TAG ATRACE_TAG_AUDIO

#include <string.h>

#include <memory>

#include <android/log.h>
@@ -612,6 +614,33 @@ Return<Result> StreamOut::setPlaybackRateParameters(const PlaybackRate& /*playba
    return Result::NOT_SUPPORTED;
}

Return<Result> StreamOut::setEventCallback(const sp<IStreamOutEventCallback>& callback) {
    if (mStream->set_event_callback == nullptr) return Result::NOT_SUPPORTED;
    int result = mStream->set_event_callback(mStream, StreamOut::asyncEventCallback, this);
    if (result == 0) {
        mEventCallback = callback;
    }
    return Stream::analyzeStatus("set_stream_out_callback", result, {ENOSYS} /*ignore*/);
}

// static
int StreamOut::asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie) {
    StreamOut* self = reinterpret_cast<StreamOut*>(cookie);
    sp<IStreamOutEventCallback> eventCallback = self->mEventCallback;
    if (eventCallback.get() == nullptr) return 0;
    ALOGV("%s event %d", __func__, event);
    switch (event) {
        case STREAM_EVENT_CBK_TYPE_CODEC_FORMAT_CHANGED: {
            hidl_vec<uint8_t> audioMetadata;
            audioMetadata.setToExternal((uint8_t*)param, strlen((char*)param));
            eventCallback->onCodecFormatChanged(audioMetadata);
        } break;
        default:
            ALOGW("%s unknown event %d", __func__, event);
            break;
    }
    return 0;
}
#endif

}  // namespace implementation
+13 −2
Original line number Diff line number Diff line
@@ -133,12 +133,19 @@ struct StreamOut : public IStreamOut {
    static Result getPresentationPositionImpl(audio_stream_out_t* stream, uint64_t* frames,
                                              TimeSpec* timeStamp);

#if MAJOR_VERSION >= 6
    Return<Result> setEventCallback(const sp<IStreamOutEventCallback>& callback) override;
#endif

  private:
    const sp<Device> mDevice;
    audio_stream_out_t* mStream;
    const sp<Stream> mStreamCommon;
    const sp<StreamMmap<audio_stream_out_t>> mStreamMmap;
    sp<IStreamOutCallback> mCallback;
    sp<IStreamOutCallback> mCallback;  // Callback for non-blocking write and drain
#if MAJOR_VERSION >= 6
    sp<IStreamOutEventCallback> mEventCallback;
#endif
    std::unique_ptr<CommandMQ> mCommandMQ;
    std::unique_ptr<DataMQ> mDataMQ;
    std::unique_ptr<StatusMQ> mStatusMQ;
@@ -149,6 +156,10 @@ struct StreamOut : public IStreamOut {
    virtual ~StreamOut();

    static int asyncCallback(stream_callback_event_t event, void* param, void* cookie);

#if MAJOR_VERSION >= 6
    static int asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie);
#endif
};

}  // namespace implementation
Loading