/*
 * Copyright (C) 2008 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_HARDWARE_BINDER_H
#define ANDROID_HARDWARE_BINDER_H

#include <atomic>
#include <stdint.h>
#include <hwbinder/IBinder.h>

// ---------------------------------------------------------------------------
namespace android {
namespace hardware {

class BHwBinder : public IBinder
{
public:
                        BHwBinder();

    virtual status_t    transact(   uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0,
                                    TransactCallback callback = nullptr);

    virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,
                                    void* cookie = nullptr,
                                    uint32_t flags = 0);

    virtual status_t    unlinkToDeath(  const wp<DeathRecipient>& recipient,
                                        void* cookie = nullptr,
                                        uint32_t flags = 0,
                                        wp<DeathRecipient>* outRecipient = nullptr);

    virtual void        attachObject(   const void* objectID,
                                        void* object,
                                        void* cleanupCookie,
                                        object_cleanup_func func);
    virtual void*       findObject(const void* objectID) const;
    virtual void        detachObject(const void* objectID);

    virtual BHwBinder*    localBinder();

    int                 getMinSchedulingPolicy();
    int                 getMinSchedulingPriority();

    bool                isRequestingSid();

protected:
    virtual             ~BHwBinder();

    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0,
                                    TransactCallback callback = nullptr);

    // This must be called before the object is sent to another process. Not thread safe.
    void                setRequestingSid(bool requestSid);

    int                 mSchedPolicy; // policy to run transaction from this node at
    // priority [-20..19] for SCHED_NORMAL, [1..99] for SCHED_FIFO/RT
    int                 mSchedPriority;
private:
                        BHwBinder(const BHwBinder& o);
            BHwBinder&    operator=(const BHwBinder& o);

    class Extras;

    Extras*             getOrCreateExtras();

    std::atomic<Extras*> mExtras;
            void*       mReserved0;
};

// ---------------------------------------------------------------------------

class BpHwRefBase : public virtual RefBase
{
protected:
    explicit                BpHwRefBase(const sp<IBinder>& o);
    virtual                 ~BpHwRefBase();
    virtual void            onFirstRef();
    virtual void            onLastStrongRef(const void* id);
    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);

public:
    inline  IBinder*        remote() const          { return mRemote; }

private:
                            BpHwRefBase(const BpHwRefBase& o);
    BpHwRefBase&              operator=(const BpHwRefBase& o);

    IBinder* const          mRemote;
    RefBase::weakref_type*  mRefs;
    std::atomic<int32_t>    mState;
};

} // namespace hardware
} // namespace android

// ---------------------------------------------------------------------------

#endif // ANDROID_HARDWARE_BINDER_H
