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

Commit 156c6873 authored by jiabin's avatar jiabin
Browse files

Add AudioRouting interface for MediaPlayer

Bug: 64038649
Test: Run cts in RoutingTest
      Switch output device when playing music/video with MediaPlayer

Change-Id: I5b5c288e6557199b0a6986785f9335a18a80ab89
parent ef9fc779
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -216,19 +216,19 @@ AudioTrack::AudioTrack(
        pid_t pid,
        const audio_attributes_t* pAttributes,
        bool doNotReconnect,
        float maxRequiredSpeed)
        float maxRequiredSpeed,
        audio_port_handle_t selectedDeviceId)
    : mStatus(NO_INIT),
      mState(STATE_STOPPED),
      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
      mPreviousSchedulingGroup(SP_DEFAULT),
      mPausedPosition(0),
      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
      mPortId(AUDIO_PORT_HANDLE_NONE)
{
    mStatus = set(streamType, sampleRate, format, channelMask,
            frameCount, flags, cbf, user, notificationFrames,
            0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType,
            offloadInfo, uid, pid, pAttributes, doNotReconnect, maxRequiredSpeed);
            offloadInfo, uid, pid, pAttributes, doNotReconnect, maxRequiredSpeed, selectedDeviceId);
}

AudioTrack::AudioTrack(
@@ -310,7 +310,8 @@ status_t AudioTrack::set(
        pid_t pid,
        const audio_attributes_t* pAttributes,
        bool doNotReconnect,
        float maxRequiredSpeed)
        float maxRequiredSpeed,
        audio_port_handle_t selectedDeviceId)
{
    ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
          "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d",
@@ -318,6 +319,7 @@ status_t AudioTrack::set(
          sessionId, transferType, uid, pid);

    mThreadCanCallJava = threadCanCallJava;
    mSelectedDeviceId = selectedDeviceId;

    switch (transferType) {
    case TRANSFER_DEFAULT:
@@ -1221,6 +1223,7 @@ status_t AudioTrack::setOutputDevice(audio_port_handle_t deviceId) {
        mSelectedDeviceId = deviceId;
        if (mStatus == NO_ERROR) {
            android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
            mProxy->interrupt();
        }
    }
    return NO_ERROR;
+6 −2
Original line number Diff line number Diff line
@@ -218,6 +218,8 @@ public:
     *                     maxRequiredSpeed playback. Values less than 1.0f and greater than
     *                     AUDIO_TIMESTRETCH_SPEED_MAX will be clamped.  For non-PCM tracks
     *                     and direct or offloaded tracks, this parameter is ignored.
     * selectedDeviceId:   Selected device id of the app which initially requested the AudioTrack
     *                     to open with a specific device.
     * threadCanCallJava:  Not present in parameter list, and so is fixed at false.
     */

@@ -237,7 +239,8 @@ public:
                                    pid_t pid = -1,
                                    const audio_attributes_t* pAttributes = NULL,
                                    bool doNotReconnect = false,
                                    float maxRequiredSpeed = 1.0f);
                                    float maxRequiredSpeed = 1.0f,
                                    audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);

    /* Creates an audio track and registers it with AudioFlinger.
     * With this constructor, the track is configured for static buffer mode.
@@ -313,7 +316,8 @@ public:
                            pid_t pid = -1,
                            const audio_attributes_t* pAttributes = NULL,
                            bool doNotReconnect = false,
                            float maxRequiredSpeed = 1.0f);
                            float maxRequiredSpeed = 1.0f,
                            audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);

    /* Result of constructing the AudioTrack. This must be checked for successful initialization
     * before using any AudioTrack API (except for set()), because using
+92 −0
Original line number Diff line number Diff line
@@ -78,6 +78,10 @@ enum {
    // Modular DRM
    PREPARE_DRM,
    RELEASE_DRM,
    // AudioRouting
    SET_OUTPUT_DEVICE,
    GET_ROUTED_DEVICE_ID,
    ENABLE_AUDIO_DEVICE_CALLBACK,
};

// ModDrm helpers
@@ -559,6 +563,59 @@ public:

        return reply.readInt32();
    }

    status_t setOutputDevice(audio_port_handle_t deviceId)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());

        data.writeInt32(deviceId);

        status_t status = remote()->transact(SET_OUTPUT_DEVICE, data, &reply);
        if (status != OK) {
            ALOGE("setOutputDevice: binder call failed: %d", status);
            return status;
        }

        return reply.readInt32();
    }

    status_t getRoutedDeviceId(audio_port_handle_t* deviceId)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());

        status_t status = remote()->transact(GET_ROUTED_DEVICE_ID, data, &reply);
        if (status != OK) {
            ALOGE("getRoutedDeviceid: binder call failed: %d", status);
            *deviceId = AUDIO_PORT_HANDLE_NONE;
            return status;
        }

        status = reply.readInt32();
        if (status != NO_ERROR) {
            *deviceId = AUDIO_PORT_HANDLE_NONE;
        } else {
            *deviceId = reply.readInt32();
        }
        return status;
    }

    status_t enableAudioDeviceCallback(bool enabled)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());

        data.writeBool(enabled);

        status_t status = remote()->transact(ENABLE_AUDIO_DEVICE_CALLBACK, data, &reply);
        if (status != OK) {
            ALOGE("enableAudioDeviceCallback: binder call failed: %d, %d", enabled, status);
            return status;
        }

        return reply.readInt32();
    }
};

IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
@@ -916,6 +973,41 @@ status_t BnMediaPlayer::onTransact(
            reply->writeInt32(result);
            return OK;
        }

        // AudioRouting
        case SET_OUTPUT_DEVICE: {
            CHECK_INTERFACE(IMediaPlayer, data, reply);
            int deviceId;
            status_t status = data.readInt32(&deviceId);
            if (status == NO_ERROR) {
                reply->writeInt32(setOutputDevice(deviceId));
            } else {
                reply->writeInt32(BAD_VALUE);
            }
            return NO_ERROR;
        }
        case GET_ROUTED_DEVICE_ID: {
            CHECK_INTERFACE(IMediaPlayer, data, reply);
            audio_port_handle_t deviceId;
            status_t ret = getRoutedDeviceId(&deviceId);
            reply->writeInt32(ret);
            if (ret == NO_ERROR) {
                reply->writeInt32(deviceId);
            }
            return NO_ERROR;
        } break;
        case ENABLE_AUDIO_DEVICE_CALLBACK: {
            CHECK_INTERFACE(IMediaPlayer, data, reply);
            bool enabled;
            status_t status = data.readBool(&enabled);
            if (status == NO_ERROR) {
                reply->writeInt32(enableAudioDeviceCallback(enabled));
            } else {
                reply->writeInt32(BAD_VALUE);
            }
            return NO_ERROR;
        } break;

        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
+5 −0
Original line number Diff line number Diff line
@@ -131,6 +131,11 @@ public:
    virtual status_t        getMetadata(bool update_only,
                                        bool apply_filter,
                                        Parcel *metadata) = 0;

    // AudioRouting
    virtual status_t        setOutputDevice(audio_port_handle_t deviceId) = 0;
    virtual status_t        getRoutedDeviceId(audio_port_handle_t *deviceId) = 0;
    virtual status_t        enableAudioDeviceCallback(bool enabled) = 0;
};

// ----------------------------------------------------------------------------
+5 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ enum media_event_type {
    MEDIA_SUBTITLE_DATA     = 201,
    MEDIA_META_DATA         = 202,
    MEDIA_DRM_INFO          = 210,
    MEDIA_AUDIO_ROUTING_CHANGED = 10000,
};

// Generic error codes for the media player framework.  Errors are fatal, the
@@ -275,6 +276,10 @@ public:
            // Modular DRM
            status_t        prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId);
            status_t        releaseDrm();
            // AudioRouting
            status_t        setOutputDevice(audio_port_handle_t deviceId);
            audio_port_handle_t getRoutedDeviceId();
            status_t        enableAudioDeviceCallback(bool enabled);

private:
            void            clear_l();
Loading