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

Commit 4521b9bb authored by Andy Hung's avatar Andy Hung
Browse files

AudioTrack: Clean up ctor initialization

Move key AudioTrack parameters to member variable initialization
to ensure consistent state.

Test: atest CtsMediaAudioTestCases
Test: atest audiotrack_tests
Bug: 333897807
Change-Id: I56dc786c4c291640ad3b0aba600dd5443dca7c6e
parent 0ea9f9c8
Loading
Loading
Loading
Loading
+7 −30
Original line number Diff line number Diff line
@@ -233,25 +233,10 @@ status_t AudioTrack::getMetrics(mediametrics::Item * &item)
    return NO_ERROR;
}

AudioTrack::AudioTrack() : AudioTrack(AttributionSourceState())
{
}

AudioTrack::AudioTrack(const AttributionSourceState& attributionSource)
    : mStatus(NO_INIT),
      mState(STATE_STOPPED),
      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
      mPreviousSchedulingGroup(SP_DEFAULT),
      mPausedPosition(0),
      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
      mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE),
      mClientAttributionSource(attributionSource),
      mAudioTrackCallback(new AudioTrackCallback())
    : mClientAttributionSource(attributionSource)
{
    mAttributes.content_type = AUDIO_CONTENT_TYPE_UNKNOWN;
    mAttributes.usage = AUDIO_USAGE_UNKNOWN;
    mAttributes.flags = AUDIO_FLAG_NONE;
    strcpy(mAttributes.tags, "");

}

AudioTrack::AudioTrack(
@@ -271,21 +256,13 @@ AudioTrack::AudioTrack(
        bool doNotReconnect,
        float maxRequiredSpeed,
        audio_port_handle_t selectedDeviceId)
    : mStatus(NO_INIT),
      mState(STATE_STOPPED),
      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
      mPreviousSchedulingGroup(SP_DEFAULT),
      mPausedPosition(0),
      mAudioTrackCallback(new AudioTrackCallback())
{
    mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;

    // make_unique does not aggregate init until c++20
    mSetParams = std::unique_ptr<SetParams>{
            new SetParams{streamType, sampleRate, format, channelMask, frameCount, flags, callback,
                          notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/,
    mSetParams = std::make_unique<SetParams>(
        streamType, sampleRate, format, channelMask, frameCount, flags, callback,
        notificationFrames, nullptr /*sharedBuffer*/, false /*threadCanCallJava*/,
        sessionId, transferType, offloadInfo, attributionSource, pAttributes,
                          doNotReconnect, maxRequiredSpeed, selectedDeviceId}};
        doNotReconnect, maxRequiredSpeed, selectedDeviceId);
}

namespace {
+15 −14
Original line number Diff line number Diff line
@@ -257,9 +257,7 @@ public:
    /* Constructs an uninitialized AudioTrack. No connection with
     * AudioFlinger takes place.  Use set() after this.
     */
                        AudioTrack();

                        AudioTrack(const AttributionSourceState& attributionSourceState);
    explicit AudioTrack(const AttributionSourceState& attributionSourceState = {});

    /* Creates an AudioTrack object and registers it with AudioFlinger.
     * Once created, the track needs to be started before it can be used.
@@ -1312,11 +1310,11 @@ public:
    sp<IMemory>             mSharedBuffer;
    transfer_type           mTransfer;
    audio_offload_info_t    mOffloadInfoCopy;
    audio_attributes_t      mAttributes;
    audio_attributes_t mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;

    size_t                  mFrameSize;             // frame size in bytes

    status_t                mStatus;
    status_t mStatus = NO_INIT;

    // can change dynamically when IAudioTrack invalidated
    uint32_t                mLatency;               // in ms
@@ -1329,7 +1327,7 @@ public:
        STATE_PAUSED_STOPPING,
        STATE_FLUSHED,
        STATE_STOPPING,
    }                       mState;
    } mState = STATE_STOPPED;

    static constexpr const char *stateToString(State state)
    {
@@ -1459,8 +1457,8 @@ public:

    mutable Mutex           mLock;

    int                     mPreviousPriority;          // before start()
    SchedPolicy             mPreviousSchedulingGroup;
    int mPreviousPriority = ANDROID_PRIORITY_NORMAL;  // before start()
    SchedPolicy mPreviousSchedulingGroup = SP_DEFAULT;
    bool                    mAwaitBoost;    // thread should wait for priority boost before running

    // The proxy should only be referenced while a lock is held because the proxy isn't
@@ -1472,14 +1470,17 @@ public:
    sp<AudioTrackClientProxy>       mProxy;         // primary owner of the memory

    bool                    mInUnderrun;            // whether track is currently in underrun state
    uint32_t                mPausedPosition;
    uint32_t mPausedPosition = 0;

    // For Device Selection API
    //  a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
    audio_port_handle_t    mSelectedDeviceId; // Device requested by the application.
    audio_port_handle_t    mRoutedDeviceId;   // Device actually selected by audio policy manager:
                                              // May not match the app selection depending on other
                                              // activity and connected devices.

    // Device requested by the application.
    audio_port_handle_t mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;

    // Device actually selected by AudioPolicyManager: This may not match the app
    // selection depending on other activity and connected devices.
    audio_port_handle_t mRoutedDeviceId = AUDIO_PORT_HANDLE_NONE;

    sp<media::VolumeHandler>       mVolumeHandler;

@@ -1537,7 +1538,7 @@ private:
        Mutex mAudioTrackCbLock;
        wp<media::IAudioTrackCallback> mCallback;
    };
    sp<AudioTrackCallback> mAudioTrackCallback;
    sp<AudioTrackCallback> mAudioTrackCallback = sp<AudioTrackCallback>::make();
};

}; // namespace android
+15 −0
Original line number Diff line number Diff line
@@ -25,6 +25,21 @@

using namespace android;

// Test that the basic constructor returns an object that doesn't crash
// on stop() or destruction.

TEST(AudioTrackTestBasic, EmptyAudioTrack) {
    AttributionSourceState attributionSource;
    attributionSource.packageName = "AudioTrackTest";
    attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
    attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
    attributionSource.token = sp<BBinder>::make();
    const auto at = sp<AudioTrack>::make(attributionSource);

    EXPECT_EQ(NO_INIT, at->initCheck());
    EXPECT_EQ(true, at->stopped());
}

TEST(AudioTrackTest, TestPlayTrack) {
    const auto ap = sp<AudioPlayback>::make(44100 /* sampleRate */, AUDIO_FORMAT_PCM_16_BIT,
                                            AUDIO_CHANNEL_OUT_STEREO, AUDIO_OUTPUT_FLAG_NONE,