/*
 * Copyright 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.
 */

#ifndef ANDROID_VOLUME_SHAPER_H
#define ANDROID_VOLUME_SHAPER_H

#include <cmath>
#include <list>
#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>
#include <utils/RefBase.h>

#pragma push_macro("LOG_TAG")
#undef LOG_TAG
#define LOG_TAG "VolumeShaper"

// turn on VolumeShaper logging
#define VS_LOGGING 0
#define VS_LOG(...) ALOGD_IF(VS_LOGGING, __VA_ARGS__)

namespace android {

namespace media {

// The native VolumeShaper class mirrors the java VolumeShaper class;
// in addition, the native class contains implementation for actual operation.
//
// VolumeShaper methods are not safe for multiple thread access.
// Use VolumeHandler for thread-safe encapsulation of multiple VolumeShapers.
//
// Classes below written are to avoid naked pointers so there are no
// explicit destructors required.

class VolumeShaper {
public:
    // S and T are like template typenames (matching the Interpolator<S, T>)
    using S = float; // time type
    using T = float; // volume type

// Curve and dimension information
// TODO: member static const or constexpr float initialization not permitted in C++11
#define MIN_CURVE_TIME    0.f  // type S: start of VolumeShaper curve (normalized)
#define MAX_CURVE_TIME    1.f  // type S: end of VolumeShaper curve (normalized)
#define MIN_LINEAR_VOLUME 0.f  // type T: silence / mute audio
#define MAX_LINEAR_VOLUME 1.f  // type T: max volume, unity gain
#define MAX_LOG_VOLUME    0.f  // type T: max volume, unity gain in dBFS

    /* kSystemVolumeShapersMax is the maximum number of system VolumeShapers.
     * Each system VolumeShapers has a predefined Id, which ranges from 0
     * to kSystemVolumeShapersMax - 1 and is unique for its usage.
     *
     * "1" is reserved for system ducking.
     */
    static const int kSystemVolumeShapersMax = 16;

    /* kUserVolumeShapersMax is the maximum number of application
     * VolumeShapers for a player/track.  Application VolumeShapers are
     * assigned on creation by the client, and have Ids ranging
     * from kSystemVolumeShapersMax to INT32_MAX.
     *
     * The number of user/application volume shapers is independent to the
     * system volume shapers. If an application tries to create more than
     * kUserVolumeShapersMax to a player, then the apply() will fail.
     * This prevents exhausting server side resources by a potentially malicious
     * application.
     */
    static const int kUserVolumeShapersMax = 16;

    /* VolumeShaper::Status is equivalent to status_t if negative
     * but if non-negative represents the id operated on.
     * It must be expressible as an int32_t for binder purposes.
     */
    using Status = status_t;

    // Local definition for clamp as std::clamp is included in C++17 only.
    // TODO: use the std::clamp version when Android build uses C++17.
    template<typename R>
    static constexpr const R &clamp(const R &v, const R &lo, const R &hi) {
        return (v < lo) ? lo : (hi < v) ? hi : v;
    }

    /* VolumeShaper.Configuration derives from the Interpolator class and adds
     * parameters relating to the volume shape.
     *
     * This parallels the Java implementation and the enums must match.
     * See "frameworks/base/media/java/android/media/VolumeShaper.java" for
     * details on the Java implementation.
     */
    class Configuration : public Interpolator<S, T>, public RefBase, public Parcelable {
    public:
        // Must match with VolumeShaper.java in frameworks/base.
        enum Type : int32_t {
            TYPE_ID,
            TYPE_SCALE,
        };

        // Must match with VolumeShaper.java in frameworks/base.
        enum OptionFlag : int32_t {
            OPTION_FLAG_NONE           = 0,
            OPTION_FLAG_VOLUME_IN_DBFS = (1 << 0),
            OPTION_FLAG_CLOCK_TIME     = (1 << 1),

            OPTION_FLAG_ALL            = (OPTION_FLAG_VOLUME_IN_DBFS | OPTION_FLAG_CLOCK_TIME),
        };

        // Bring from base class; must match with VolumeShaper.java in frameworks/base.
        using InterpolatorType = Interpolator<S, T>::InterpolatorType;

        Configuration()
            : Interpolator<S, T>()
            , RefBase()
            , mType(TYPE_SCALE)
            , mId(-1)
            , mOptionFlags(OPTION_FLAG_NONE)
            , mDurationMs(1000.) {
        }

        Configuration(const Configuration &configuration)
            : Interpolator<S, T>(*static_cast<const Interpolator<S, T> *>(&configuration))
            , RefBase()
            , mType(configuration.mType)
            , mId(configuration.mId)
            , mOptionFlags(configuration.mOptionFlags)
            , mDurationMs(configuration.mDurationMs) {
        }

        Type getType() const {
            return mType;
        }

        status_t setType(Type type) {
            switch (type) {
            case TYPE_ID:
            case TYPE_SCALE:
                mType = type;
                return NO_ERROR;
            default:
                ALOGE("invalid Type: %d", type);
                return BAD_VALUE;
            }
        }

        OptionFlag getOptionFlags() const {
            return mOptionFlags;
        }

        status_t setOptionFlags(OptionFlag optionFlags) {
            if ((optionFlags & ~OPTION_FLAG_ALL) != 0) {
                ALOGE("optionFlags has invalid bits: %#x", optionFlags);
                return BAD_VALUE;
            }
            mOptionFlags = optionFlags;
            return NO_ERROR;
        }

        double getDurationMs() const {
            return mDurationMs;
        }

        status_t setDurationMs(double durationMs) {
            if (durationMs > 0.) {
                mDurationMs = durationMs;
                return NO_ERROR;
            }
            // zero, negative, or nan. These values not possible from Java.
            return BAD_VALUE;
        }

        int32_t getId() const {
            return mId;
        }

        void setId(int32_t id) {
            // We permit a negative id here (representing invalid).
            mId = id;
        }

        /* Adjust the volume to be in linear range from MIN_LINEAR_VOLUME to MAX_LINEAR_VOLUME
         * and compensate for log dbFS volume as needed.
         */
        T adjustVolume(T volume) const {
            if ((getOptionFlags() & OPTION_FLAG_VOLUME_IN_DBFS) != 0) {
                const T out = powf(10.f, volume / 10.f);
                VS_LOG("in: %f  out: %f", volume, out);
                volume = out;
            }
            return clamp(volume, MIN_LINEAR_VOLUME /* lo */, MAX_LINEAR_VOLUME /* hi */);
        }

        /* Check if the existing curve is valid.
         */
        status_t checkCurve() const {
            if (mType == TYPE_ID) return NO_ERROR;
            if (this->size() < 2) {
                ALOGE("curve must have at least 2 points");
                return BAD_VALUE;
            }
            if (first().first != MIN_CURVE_TIME || last().first != MAX_CURVE_TIME) {
                ALOGE("curve must start at MIN_CURVE_TIME and end at MAX_CURVE_TIME");
                return BAD_VALUE;
            }
            if ((getOptionFlags() & OPTION_FLAG_VOLUME_IN_DBFS) != 0) {
                for (const auto &pt : *this) {
                    if (!(pt.second <= MAX_LOG_VOLUME) /* handle nan */) {
                        ALOGE("positive volume dbFS");
                        return BAD_VALUE;
                    }
                }
            } else {
                for (const auto &pt : *this) {
                    if (!(pt.second >= MIN_LINEAR_VOLUME)
                            || !(pt.second <= MAX_LINEAR_VOLUME) /* handle nan */) {
                        ALOGE("volume < MIN_LINEAR_VOLUME or > MAX_LINEAR_VOLUME");
                        return BAD_VALUE;
                    }
                }
            }
            return NO_ERROR;
        }

        /* Clamps the volume curve in the configuration to
         * the valid range for log or linear scale.
         */
        void clampVolume() {
            if ((mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0) {
                for (auto it = this->begin(); it != this->end(); ++it) {
                    if (!(it->second <= MAX_LOG_VOLUME) /* handle nan */) {
                        it->second = MAX_LOG_VOLUME;
                    }
                }
            } else {
                for (auto it = this->begin(); it != this->end(); ++it) {
                    if (!(it->second >= MIN_LINEAR_VOLUME) /* handle nan */) {
                        it->second = MIN_LINEAR_VOLUME;
                    } else if (!(it->second <= MAX_LINEAR_VOLUME)) {
                        it->second = MAX_LINEAR_VOLUME;
                    }
                }
            }
        }

        /* scaleToStartVolume() is used to set the start volume of a
         * new VolumeShaper curve, when replacing one VolumeShaper
         * with another using the "join" (volume match) option.
         *
         * It works best for monotonic volume ramps or ducks.
         */
        void scaleToStartVolume(T volume) {
            if (this->size() < 2) {
                return;
            }
            const T startVolume = first().second;
            const T endVolume = last().second;
            if (endVolume == startVolume) {
                // match with linear ramp
                const T offset = volume - startVolume;
                static const T scale =  1.f / (MAX_CURVE_TIME - MIN_CURVE_TIME); // nominally 1.f
                for (auto it = this->begin(); it != this->end(); ++it) {
                    it->second = it->second + offset * (MAX_CURVE_TIME - it->first) * scale;
                }
            } else {
                const T  scale = (volume - endVolume) / (startVolume - endVolume);
                for (auto it = this->begin(); it != this->end(); ++it) {
                    it->second = scale * (it->second - endVolume) + endVolume;
                }
            }
            clampVolume();
        }

        status_t writeToParcel(Parcel *parcel) const override {
            VolumeShaperConfiguration parcelable;
            writeToParcelable(&parcelable);
            return parcelable.writeToParcel(parcel);
        }

        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.
        std::string toString() const {
            std::stringstream ss;
            ss << "VolumeShaper::Configuration{mType=" << static_cast<int32_t>(mType);
            ss << ", mId=" << mId;
            if (mType != TYPE_ID) {
                ss << ", mOptionFlags=" << static_cast<int32_t>(mOptionFlags);
                ss << ", mDurationMs=" << mDurationMs;
                ss << ", " << Interpolator<S, T>::toString().c_str();
            }
            ss << "}";
            return ss.str();
        }

    private:
        Type mType;              // type of configuration
        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
     * configuration (either explicitly specified or an id).
     *
     * This parallels the Java implementation and the enums must match.
     * See "frameworks/base/media/java/android/media/VolumeShaper.java" for
     * details on the Java implementation.
     */
    class Operation : public RefBase, public Parcelable {
    public:
        // Must match with VolumeShaper.java.
        enum Flag : int32_t {
            FLAG_NONE      = 0,
            FLAG_REVERSE   = (1 << 0), // the absence of this indicates "play"
            FLAG_TERMINATE = (1 << 1),
            FLAG_JOIN      = (1 << 2),
            FLAG_DELAY     = (1 << 3),
            FLAG_CREATE_IF_NECESSARY = (1 << 4),

            FLAG_ALL       = (FLAG_REVERSE | FLAG_TERMINATE | FLAG_JOIN | FLAG_DELAY
                            | FLAG_CREATE_IF_NECESSARY),
        };

        Operation()
            : Operation(FLAG_NONE, -1 /* replaceId */) {
        }

        Operation(Flag flags, int replaceId)
            : Operation(flags, replaceId, std::numeric_limits<S>::quiet_NaN() /* xOffset */) {
        }

        Operation(const Operation &operation)
            : Operation(operation.mFlags, operation.mReplaceId, operation.mXOffset) {
        }

        explicit Operation(const sp<Operation> &operation)
            : Operation(*operation.get()) {
        }

        Operation(Flag flags, int replaceId, S xOffset)
            : mFlags(flags)
            , mReplaceId(replaceId)
            , mXOffset(xOffset) {
        }

        int32_t getReplaceId() const {
            return mReplaceId;
        }

        void setReplaceId(int32_t replaceId) {
            mReplaceId = replaceId;
        }

        S getXOffset() const {
            return mXOffset;
        }

        void setXOffset(S xOffset) {
            mXOffset = clamp(xOffset, MIN_CURVE_TIME /* lo */, MAX_CURVE_TIME /* hi */);
        }

        Flag getFlags() const {
            return mFlags;
        }

        /* xOffset is the position on the volume curve and may go backwards
         * if you are in reverse mode. This must be in the range from
         * [MIN_CURVE_TIME, MAX_CURVE_TIME].
         *
         * normalizedTime always increases as time or framecount increases.
         * normalizedTime is nominally from MIN_CURVE_TIME to MAX_CURVE_TIME when
         * running through the curve, but could be outside this range afterwards.
         * If you are reversing, this means the position on the curve, or xOffset,
         * is computed as MAX_CURVE_TIME - normalizedTime, clamped to
         * [MIN_CURVE_TIME, MAX_CURVE_TIME].
         */
        void setNormalizedTime(S normalizedTime) {
            setXOffset((mFlags & FLAG_REVERSE) != 0
                    ? MAX_CURVE_TIME - normalizedTime : normalizedTime);
        }

        status_t setFlags(Flag flags) {
            if ((flags & ~FLAG_ALL) != 0) {
                ALOGE("flags has invalid bits: %#x", flags);
                return BAD_VALUE;
            }
            mFlags = flags;
            return NO_ERROR;
        }

        status_t writeToParcel(Parcel* parcel) const override {
            if (parcel == nullptr) return BAD_VALUE;
            VolumeShaperOperation op;
            writeToParcelable(&op);
            return op.writeToParcel(parcel);
        }

        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 {
            std::stringstream ss;
            ss << "VolumeShaper::Operation{mFlags=" << static_cast<int32_t>(mFlags) ;
            ss << ", mReplaceId=" << mReplaceId;
            ss << ", mXOffset=" << mXOffset;
            ss << "}";
            return ss.str();
        }

    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)
    }; // Operation

    /* VolumeShaper.State is returned when requesting the last
     * state of the VolumeShaper.
     *
     * This parallels the Java implementation.
     * See "frameworks/base/media/java/android/media/VolumeShaper.java" for
     * details on the Java implementation.
     */
    class State : public RefBase, public Parcelable {
    public:
        State(T volume, S xOffset)
            : mVolume(volume)
            , mXOffset(xOffset) {
        }

        State()
            : State(NAN, NAN) { }

        T getVolume() const {
            return mVolume;
        }

        void setVolume(T volume) {
            mVolume = volume;
        }

        S getXOffset() const {
            return mXOffset;
        }

        void setXOffset(S xOffset) {
            mXOffset = xOffset;
        }

        status_t writeToParcel(Parcel* parcel) const override {
            if (parcel == nullptr) return BAD_VALUE;
            VolumeShaperState state;
            writeToParcelable(&state);
            return state.writeToParcel(parcel);
        }

        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 {
            std::stringstream ss;
            ss << "VolumeShaper::State{mVolume=" << mVolume;
            ss << ", mXOffset=" << mXOffset;
            ss << "}";
            return ss.str();
        }

    private:
        T mVolume;   // linear volume in the range MIN_LINEAR_VOLUME to MAX_LINEAR_VOLUME
        S mXOffset;  // position on curve expressed from MIN_CURVE_TIME to MAX_CURVE_TIME
    }; // State

    // Internal helper class to do an affine transform for time and amplitude scaling.
    template <typename R>
    class Translate {
    public:
        Translate()
            : mOffset(0)
            , mScale(1) {
        }

        R getOffset() const {
            return mOffset;
        }

        void setOffset(R offset) {
            mOffset = offset;
        }

        R getScale() const {
            return mScale;
        }

        void setScale(R scale) {
            mScale = scale;
        }

        R operator()(R in) const {
            return mScale * (in - mOffset);
        }

        std::string toString() const {
            std::stringstream ss;
            ss << "VolumeShaper::Translate{mOffset=" << mOffset;
            ss << ", mScale=" << mScale;
            ss << "}";
            return ss.str();
        }

    private:
        R mOffset;
        R mScale;
    }; // Translate

    static int64_t convertTimespecToUs(const struct timespec &tv)
    {
        return tv.tv_sec * 1000000LL + tv.tv_nsec / 1000;
    }

    // current monotonic time in microseconds.
    static int64_t getNowUs()
    {
        struct timespec tv;
        if (clock_gettime(CLOCK_MONOTONIC, &tv) != 0) {
            return 0; // system is really sick, just return 0 for consistency.
        }
        return convertTimespecToUs(tv);
    }

    /* Native implementation of VolumeShaper.  This is NOT mirrored
     * on the Java side, so we don't need to mimic Java side layout
     * and data; furthermore, this isn't refcounted as a "RefBase" object.
     *
     * Since we pass configuration and operation as shared pointers (like
     * Java) there is a potential risk that the caller may modify
     * these after delivery.
     */
    VolumeShaper(
            const sp<VolumeShaper::Configuration> &configuration,
            const sp<VolumeShaper::Operation> &operation)
        : mConfiguration(configuration) // we do not make a copy
        , mOperation(operation)         // ditto
        , mStartFrame(-1)
        , mLastVolume(T(1))
        , mLastXOffset(MIN_CURVE_TIME)
        , mDelayXOffset(MIN_CURVE_TIME) {
        if (configuration.get() != nullptr
                && (getFlags() & VolumeShaper::Operation::FLAG_DELAY) == 0) {
            mLastVolume = configuration->first().second;
        }
    }

    // We allow a null operation here, though VolumeHandler always provides one.
    VolumeShaper::Operation::Flag getFlags() const {
        return mOperation == nullptr
                ? VolumeShaper::Operation::FLAG_NONE : mOperation->getFlags();
    }

    /* Returns the last volume and xoffset reported to the AudioFlinger.
     * If the VolumeShaper has not been started, compute what the volume
     * should be based on the initial offset specified.
     */
    sp<VolumeShaper::State> getState() const {
        if (!isStarted()) {
            const T volume = computeVolumeFromXOffset(mDelayXOffset);
            VS_LOG("delayed VolumeShaper, using cached offset:%f for volume:%f",
                    mDelayXOffset, volume);
            return new VolumeShaper::State(volume, mDelayXOffset);
        } else {
            return new VolumeShaper::State(mLastVolume, mLastXOffset);
        }
    }

    S getDelayXOffset() const {
        return mDelayXOffset;
    }

    void setDelayXOffset(S xOffset) {
        mDelayXOffset = clamp(xOffset, MIN_CURVE_TIME /* lo */, MAX_CURVE_TIME /* hi */);
    }

    bool isStarted() const {
        return mStartFrame >= 0;
    }

    /* getVolume() updates the last volume/xoffset state so it is not
     * const, even though logically it may be viewed as const.
     */
    std::pair<T /* volume */, bool /* active */> getVolume(
            int64_t trackFrameCount, double trackSampleRate) {
        if ((getFlags() & VolumeShaper::Operation::FLAG_DELAY) != 0) {
            // We haven't had PLAY called yet, so just return the value
            // as if PLAY were called just now.
            VS_LOG("delayed VolumeShaper, using cached offset %f", mDelayXOffset);
            const T volume = computeVolumeFromXOffset(mDelayXOffset);
            return std::make_pair(volume, false);
        }
        const bool clockTime = (mConfiguration->getOptionFlags()
                & VolumeShaper::Configuration::OPTION_FLAG_CLOCK_TIME) != 0;
        const int64_t frameCount = clockTime ? getNowUs() : trackFrameCount;
        const double sampleRate = clockTime ? 1000000 : trackSampleRate;

        if (mStartFrame < 0) {
            updatePosition(frameCount, sampleRate, mDelayXOffset);
            mStartFrame = frameCount;
        }
        VS_LOG("frameCount: %lld", (long long)frameCount);
        const S x = mXTranslate((T)frameCount);
        VS_LOG("translation to normalized time: %f", x);

        std::tuple<T /* volume */, S /* position */, bool /* active */> vt =
                computeStateFromNormalizedTime(x);

        mLastVolume = std::get<0>(vt);
        mLastXOffset = std::get<1>(vt);
        const bool active = std::get<2>(vt);
        VS_LOG("rescaled time:%f  volume:%f  xOffset:%f  active:%s",
                x, mLastVolume, mLastXOffset, active ? "true" : "false");
        return std::make_pair(mLastVolume, active);
    }

    std::string toString() const {
        std::stringstream ss;
        ss << "VolumeShaper{mStartFrame=" << mStartFrame;
        ss << ", mXTranslate=" << mXTranslate.toString().c_str();
        ss << ", mConfiguration=" <<
                (mConfiguration.get() == nullptr
                        ? "nullptr" : mConfiguration->toString().c_str());
        ss << ", mOperation=" <<
                (mOperation.get() == nullptr
                        ? "nullptr" :  mOperation->toString().c_str());
        ss << "}";
        return ss.str();
    }

    Translate<S> mXTranslate; // translation from frames (usec for clock time) to normalized time.
    sp<VolumeShaper::Configuration> mConfiguration;
    sp<VolumeShaper::Operation> mOperation;

private:
    int64_t mStartFrame; // starting frame, non-negative when started (in usec for clock time)
    T mLastVolume;       // last computed interpolated volume (y-axis)
    S mLastXOffset;      // last computed interpolated xOffset/time (x-axis)
    S mDelayXOffset;     // xOffset to use for first invocation of VolumeShaper.

    // Called internally to adjust mXTranslate for first time start.
    void updatePosition(int64_t startFrame, double sampleRate, S xOffset) {
        double scale = (mConfiguration->last().first - mConfiguration->first().first)
                        / (mConfiguration->getDurationMs() * 0.001 * sampleRate);
        const double minScale = 1. / static_cast<double>(INT64_MAX);
        scale = std::max(scale, minScale);
        VS_LOG("update position: scale %lf  frameCount:%lld, sampleRate:%lf, xOffset:%f",
                scale, (long long) startFrame, sampleRate, xOffset);

        S normalizedTime = (getFlags() & VolumeShaper::Operation::FLAG_REVERSE) != 0 ?
                MAX_CURVE_TIME - xOffset : xOffset;
        mXTranslate.setOffset(static_cast<float>(static_cast<double>(startFrame)
                                                 - static_cast<double>(normalizedTime) / scale));
        mXTranslate.setScale(static_cast<float>(scale));
        VS_LOG("translate: %s", mXTranslate.toString().c_str());
    }

    T computeVolumeFromXOffset(S xOffset) const {
        const T unscaledVolume = mConfiguration->findY(xOffset);
        const T volume = mConfiguration->adjustVolume(unscaledVolume); // handle log scale
        VS_LOG("computeVolumeFromXOffset %f -> %f -> %f", xOffset, unscaledVolume, volume);
        return volume;
    }

    std::tuple<T /* volume */, S /* position */, bool /* active */>
    computeStateFromNormalizedTime(S x) const {
        bool active = true;
        // handle reversal of position
        if (getFlags() & VolumeShaper::Operation::FLAG_REVERSE) {
            x = MAX_CURVE_TIME - x;
            VS_LOG("reversing to %f", x);
            if (x < MIN_CURVE_TIME) {
                x = MIN_CURVE_TIME;
                active = false; // at the end
            } else if (x > MAX_CURVE_TIME) {
                x = MAX_CURVE_TIME; //early
            }
        } else {
            if (x < MIN_CURVE_TIME) {
                x = MIN_CURVE_TIME; // early
            } else if (x > MAX_CURVE_TIME) {
                x = MAX_CURVE_TIME;
                active = false; // at end
            }
        }
        const S xOffset = x;
        const T volume = computeVolumeFromXOffset(xOffset);
        return std::make_tuple(volume, xOffset, active);
    }
}; // VolumeShaper

/* VolumeHandler combines the volume factors of multiple VolumeShapers associated
 * with a player.  It is thread safe by synchronizing all public methods.
 *
 * This is a native-only implementation.
 *
 * The server side VolumeHandler is used to maintain a list of volume handlers,
 * keep state, and obtain volume.
 *
 * The client side VolumeHandler is used to maintain a list of volume handlers,
 * keep some partial state, and restore if the server dies.
 */
class VolumeHandler : public RefBase {
public:
    using S = float;
    using T = float;

    // A volume handler which just keeps track of active VolumeShapers does not need sampleRate.
    VolumeHandler()
        : VolumeHandler(0 /* sampleRate */) {
    }

    explicit VolumeHandler(uint32_t sampleRate)
        : mSampleRate((double)sampleRate)
        , mLastFrame(0)
        , mVolumeShaperIdCounter(VolumeShaper::kSystemVolumeShapersMax)
        , mLastVolume(1.f, false) {
    }

    VolumeShaper::Status applyVolumeShaper(
            const sp<VolumeShaper::Configuration> &configuration,
            const sp<VolumeShaper::Operation> &operation_in) {
        // make a local copy of operation, as we modify it.
        sp<VolumeShaper::Operation> operation(new VolumeShaper::Operation(operation_in));
        VS_LOG("applyVolumeShaper:configuration: %s", configuration->toString().c_str());
        VS_LOG("applyVolumeShaper:operation: %s", operation->toString().c_str());
        AutoMutex _l(mLock);
        if (configuration == nullptr) {
            ALOGE("null configuration");
            return VolumeShaper::Status(BAD_VALUE);
        }
        if (operation == nullptr) {
            ALOGE("null operation");
            return VolumeShaper::Status(BAD_VALUE);
        }
        const int32_t id = configuration->getId();
        if (id < 0) {
            ALOGE("negative id: %d", id);
            return VolumeShaper::Status(BAD_VALUE);
        }
        VS_LOG("applyVolumeShaper id: %d", id);

        switch (configuration->getType()) {
        case VolumeShaper::Configuration::TYPE_SCALE: {
            const int replaceId = operation->getReplaceId();
            if (replaceId >= 0) {
                VS_LOG("replacing %d", replaceId);
                auto replaceIt = findId_l(replaceId);
                if (replaceIt == mVolumeShapers.end()) {
                    ALOGW("cannot find replace id: %d", replaceId);
                } else {
                    if ((operation->getFlags() & VolumeShaper::Operation::FLAG_JOIN) != 0) {
                        // For join, we scale the start volume of the current configuration
                        // to match the last-used volume of the replacing VolumeShaper.
                        auto state = replaceIt->getState();
                        ALOGD("join: state:%s", state->toString().c_str());
                        if (state->getXOffset() >= 0) { // valid
                            const T volume = state->getVolume();
                            ALOGD("join: scaling start volume to %f", volume);
                            configuration->scaleToStartVolume(volume);
                        }
                    }
                    (void)mVolumeShapers.erase(replaceIt);
                }
                operation->setReplaceId(-1);
            }
            // check if we have another of the same id.
            auto oldIt = findId_l(id);
            if (oldIt != mVolumeShapers.end()) {
                if ((operation->getFlags()
                        & VolumeShaper::Operation::FLAG_CREATE_IF_NECESSARY) != 0) {
                    // TODO: move the case to a separate function.
                    goto HANDLE_TYPE_ID; // no need to create, take over existing id.
                }
                ALOGW("duplicate id, removing old %d", id);
                (void)mVolumeShapers.erase(oldIt);
            }

            /* Check if too many application VolumeShapers (with id >= kSystemVolumeShapersMax).
             * We check on the server side to ensure synchronization and robustness.
             *
             * This shouldn't fail on a replace command unless the replaced id is
             * already invalid (which *should* be checked in the Java layer).
             */
            if (id >= VolumeShaper::kSystemVolumeShapersMax
                    && numberOfUserVolumeShapers_l() >= VolumeShaper::kUserVolumeShapersMax) {
                ALOGW("Too many app VolumeShapers, cannot add to VolumeHandler");
                return VolumeShaper::Status(INVALID_OPERATION);
            }

            // create new VolumeShaper with default behavior.
            mVolumeShapers.emplace_back(configuration, new VolumeShaper::Operation());
            VS_LOG("after adding, number of volumeShapers:%zu", mVolumeShapers.size());
        }
        // fall through to handle the operation
        HANDLE_TYPE_ID:
        case VolumeShaper::Configuration::TYPE_ID: {
            VS_LOG("trying to find id: %d", id);
            auto it = findId_l(id);
            if (it == mVolumeShapers.end()) {
                VS_LOG("couldn't find id: %d", id);
                return VolumeShaper::Status(INVALID_OPERATION);
            }
            if ((operation->getFlags() & VolumeShaper::Operation::FLAG_TERMINATE) != 0) {
                VS_LOG("terminate id: %d", id);
                mVolumeShapers.erase(it);
                break;
            }
            const bool clockTime = (it->mConfiguration->getOptionFlags()
                    & VolumeShaper::Configuration::OPTION_FLAG_CLOCK_TIME) != 0;
            if ((it->getFlags() & VolumeShaper::Operation::FLAG_REVERSE) !=
                    (operation->getFlags() & VolumeShaper::Operation::FLAG_REVERSE)) {
                if (it->isStarted()) {
                    const int64_t frameCount = clockTime ? VolumeShaper::getNowUs() : mLastFrame;
                    const S x = it->mXTranslate((T)frameCount);
                    VS_LOG("reverse normalizedTime: %f", x);
                    // reflect position
                    S target = MAX_CURVE_TIME - x;
                    if (target < MIN_CURVE_TIME) {
                        VS_LOG("clamp to start - begin immediately");
                        target = MIN_CURVE_TIME;
                    }
                    VS_LOG("reverse normalizedTime target: %f", target);
                    it->mXTranslate.setOffset(it->mXTranslate.getOffset()
                            + (x - target) / it->mXTranslate.getScale());
                }
                // if not started, the delay offset doesn't change.
            }
            const S xOffset = operation->getXOffset();
            if (!std::isnan(xOffset)) {
                if (it->isStarted()) {
                    const int64_t frameCount = clockTime ? VolumeShaper::getNowUs() : mLastFrame;
                    const S x = it->mXTranslate((T)frameCount);
                    VS_LOG("normalizedTime translation: %f", x);
                    const S target =
                            (operation->getFlags() & VolumeShaper::Operation::FLAG_REVERSE) != 0 ?
                                    MAX_CURVE_TIME - xOffset : xOffset;
                    VS_LOG("normalizedTime target x offset: %f", target);
                    it->mXTranslate.setOffset(it->mXTranslate.getOffset()
                            + (x - target) / it->mXTranslate.getScale());
                } else {
                    it->setDelayXOffset(xOffset);
                }
            }
            it->mOperation = operation; // replace the operation
        } break;
        }
        return VolumeShaper::Status(id);
    }

    sp<VolumeShaper::State> getVolumeShaperState(int id) {
        AutoMutex _l(mLock);
        auto it = findId_l(id);
        if (it == mVolumeShapers.end()) {
            VS_LOG("cannot find state for id: %d", id);
            return nullptr;
        }
        return it->getState();
    }

    /* getVolume() is not const, as it updates internal state.
     * Once called, any VolumeShapers not already started begin running.
     */
    std::pair<T /* volume */, bool /* active */> getVolume(int64_t trackFrameCount) {
        AutoMutex _l(mLock);
        mLastFrame = trackFrameCount;
        T volume(1);
        size_t activeCount = 0;
        for (auto it = mVolumeShapers.begin(); it != mVolumeShapers.end();) {
            const std::pair<T, bool> shaperVolume =
                    it->getVolume(trackFrameCount, mSampleRate);
            volume *= shaperVolume.first;
            activeCount += shaperVolume.second;
            ++it;
        }
        mLastVolume = std::make_pair(volume, activeCount != 0);
        VS_LOG("getVolume: <%f, %s>", mLastVolume.first, mLastVolume.second ? "true" : "false");
        return mLastVolume;
    }

    /* Used by a client side VolumeHandler to ensure all the VolumeShapers
     * indicate that they have been started.  Upon a change in audioserver
     * output sink, this information is used for restoration of the server side
     * VolumeHandler.
     */
    void setStarted() {
        (void)getVolume(mLastFrame);  // getVolume() will start the individual VolumeShapers.
    }

    std::pair<T /* volume */, bool /* active */> getLastVolume() const {
        AutoMutex _l(mLock);
        return mLastVolume;
    }

    std::string toString() const {
        AutoMutex _l(mLock);
        std::stringstream ss;
        ss << "VolumeHandler{mSampleRate=" << mSampleRate;
        ss << ", mLastFrame=" << mLastFrame;
        ss << ", mVolumeShapers={";
        bool first = true;
        for (const auto &shaper : mVolumeShapers) {
            if (first) {
                first = false;
            } else {
                ss << ", ";
            }
            ss << shaper.toString().c_str();
        }
        ss << "}}";
        return ss.str();
    }

    void forall(const std::function<VolumeShaper::Status (const VolumeShaper &)> &lambda) {
        AutoMutex _l(mLock);
        VS_LOG("forall: mVolumeShapers.size() %zu", mVolumeShapers.size());
        for (const auto &shaper : mVolumeShapers) {
            VolumeShaper::Status status = lambda(shaper);
            VS_LOG("forall applying lambda on shaper (%p): %d", &shaper, (int)status);
        }
    }

    void reset() {
        AutoMutex _l(mLock);
        mVolumeShapers.clear();
        mLastFrame = 0;
        // keep mVolumeShaperIdCounter as is.
    }

    /* Sets the configuration id if necessary - This is based on the counter
     * internal to the VolumeHandler.
     */
    void setIdIfNecessary(const sp<VolumeShaper::Configuration> &configuration) {
        if (configuration->getType() == VolumeShaper::Configuration::TYPE_SCALE) {
            const int id = configuration->getId();
            if (id == -1) {
                // Reassign to a unique id, skipping system ids.
                AutoMutex _l(mLock);
                while (true) {
                    if (mVolumeShaperIdCounter == INT32_MAX) {
                        mVolumeShaperIdCounter = VolumeShaper::kSystemVolumeShapersMax;
                    } else {
                        ++mVolumeShaperIdCounter;
                    }
                    if (findId_l(mVolumeShaperIdCounter) != mVolumeShapers.end()) {
                        continue; // collision with an existing id.
                    }
                    configuration->setId(mVolumeShaperIdCounter);
                    ALOGD("setting id to %d", mVolumeShaperIdCounter);
                    break;
                }
            }
        }
    }

private:
    std::list<VolumeShaper>::iterator findId_l(int32_t id) {
        std::list<VolumeShaper>::iterator it = mVolumeShapers.begin();
        for (; it != mVolumeShapers.end(); ++it) {
            if (it->mConfiguration->getId() == id) {
                break;
            }
        }
        return it;
    }

    size_t numberOfUserVolumeShapers_l() const {
        size_t count = 0;
        for (const auto &shaper : mVolumeShapers) {
            count += (shaper.mConfiguration->getId() >= VolumeShaper::kSystemVolumeShapersMax);
        }
        return count;
    }

    mutable Mutex mLock;
    double mSampleRate; // in samples (frames) per second
    int64_t mLastFrame; // logging purpose only, 0 on start
    int32_t mVolumeShaperIdCounter; // a counter to return a unique volume shaper id.
    std::pair<T /* volume */, bool /* active */> mLastVolume;
    std::list<VolumeShaper> mVolumeShapers; // list provides stable iterators on erase
}; // VolumeHandler

} // namespace media

} // namespace android

#pragma pop_macro("LOG_TAG")

#endif // ANDROID_VOLUME_SHAPER_H
