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

Commit c69deb5a authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 4418112 from a6c44309 to pi-release

Change-Id: Ic36689c154d3c7769e49d66e9cff1fdfeeb24f61
parents c78daebf a6c44309
Loading
Loading
Loading
Loading

include/layerproto

0 → 120000
+1 −0
Original line number Diff line number Diff line
../services/surfaceflinger/layerproto/include/layerproto/
 No newline at end of file
+109 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@

#include <binder/IPCThreadState.h>
#include <binder/IResultReceiver.h>
#include <cutils/compiler.h>
#include <utils/Log.h>

#include <stdio.h>
@@ -32,6 +33,23 @@ namespace android {

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

Mutex BpBinder::sTrackingLock;
std::unordered_map<int32_t,uint32_t> BpBinder::sTrackingMap;
int BpBinder::sNumTrackedUids = 0;
std::atomic_bool BpBinder::sCountByUidEnabled(false);
binder_proxy_limit_callback BpBinder::sLimitCallback;
bool BpBinder::sBinderProxyThrottleCreate = false;

// Arbitrarily high value that probably distinguishes a bad behaving app
uint32_t BpBinder::sBinderProxyCountHighWatermark = 2500;
// Another arbitrary value a binder count needs to drop below before another callback will be called
uint32_t BpBinder::sBinderProxyCountLowWatermark = 2000;

enum {
    CALLBACK_TRIGGERED_MASK = 0x80000000,   // A flag denoting that the callback has been called
    COUNTING_VALUE_MASK = 0x7FFFFFFF,       // A mask of the remaining bits for the count value
};

BpBinder::ObjectManager::ObjectManager()
{
}
@@ -87,11 +105,47 @@ void BpBinder::ObjectManager::kill()

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

BpBinder::BpBinder(int32_t handle)

BpBinder* BpBinder::create(int32_t handle) {
    int32_t trackedUid = -1;
    if (sCountByUidEnabled) {
        BpBinder* out;
        trackedUid = IPCThreadState::self()->getCallingUid();
        AutoMutex _l(sTrackingLock);
        if ((sTrackingMap[trackedUid] & COUNTING_VALUE_MASK) >= sBinderProxyCountHighWatermark) {
            ALOGE("Too many binder proxy objects sent to uid %d from uid %d (over %d proxies held)",
                   getuid(), trackedUid, sBinderProxyCountHighWatermark);

            if (sBinderProxyThrottleCreate) {
                ALOGE("Returning Null Binder Proxy Object to uid %d", trackedUid);
                out = nullptr;
            } else {
                // increment and construct here in case callback has an async kill causing a race
                sTrackingMap[trackedUid]++;
                out = new BpBinder(handle, trackedUid);
            }

            if (sLimitCallback && !(sTrackingMap[trackedUid] & CALLBACK_TRIGGERED_MASK)) {
                sTrackingMap[trackedUid] |= CALLBACK_TRIGGERED_MASK;
                sLimitCallback(trackedUid);
            }
        } else {
            sTrackingMap[trackedUid]++;
            out = new BpBinder(handle, trackedUid);
        }

        return out;
    } else {
        return new BpBinder(handle, trackedUid);
    }
}

BpBinder::BpBinder(int32_t handle, int32_t trackedUid)
    : mHandle(handle)
    , mAlive(1)
    , mObitsSent(0)
    , mObituaries(NULL)
    , mTrackedUid(trackedUid)
{
    ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);

@@ -315,6 +369,24 @@ BpBinder::~BpBinder()

    IPCThreadState* ipc = IPCThreadState::self();

    if (mTrackedUid >= 0) {
        AutoMutex _l(sTrackingLock);
        if (CC_UNLIKELY(sTrackingMap[mTrackedUid] == 0)) {
            ALOGE("Unexpected Binder Proxy tracking decrement in %p handle %d\n", this, mHandle);
        } else {
            if (CC_UNLIKELY(
                (sTrackingMap[mTrackedUid] & CALLBACK_TRIGGERED_MASK) &&
                ((sTrackingMap[mTrackedUid] & COUNTING_VALUE_MASK) <= sBinderProxyCountLowWatermark)
                )) {
                // Clear the Callback Triggered bit when crossing below the low watermark
                sTrackingMap[mTrackedUid] &= ~CALLBACK_TRIGGERED_MASK;
            }
            if (--sTrackingMap[mTrackedUid] == 0) {
                sTrackingMap.erase(mTrackedUid);
            }
        }
    }

    mLock.lock();
    Vector<Obituary>* obits = mObituaries;
    if(obits != NULL) {
@@ -360,6 +432,42 @@ bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
    return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
}

uint32_t BpBinder::getBinderProxyCount(uint32_t uid)
{
    AutoMutex _l(sTrackingLock);
    auto it = sTrackingMap.find(uid);
    if (it != sTrackingMap.end()) {
        return it->second & COUNTING_VALUE_MASK;
    }
    return 0;
}

void BpBinder::getCountByUid(Vector<uint32_t>& uids, Vector<uint32_t>& counts)
{
    AutoMutex _l(sTrackingLock);
    uids.setCapacity(sTrackingMap.size());
    counts.setCapacity(sTrackingMap.size());
    for (const auto& it : sTrackingMap) {
        uids.push_back(it.first);
        counts.push_back(it.second & COUNTING_VALUE_MASK);
    }
}

void BpBinder::enableCountByUid() { sCountByUidEnabled.store(true); }
void BpBinder::disableCountByUid() { sCountByUidEnabled.store(false); }
void BpBinder::setCountByUidEnabled(bool enable) { sCountByUidEnabled.store(enable); }

void BpBinder::setLimitCallback(binder_proxy_limit_callback cb) {
    AutoMutex _l(sTrackingLock);
    sLimitCallback = cb;
}

void BpBinder::setBinderProxyCountWatermarks(int high, int low) {
    AutoMutex _l(sTrackingLock);
    sBinderProxyCountHighWatermark = high;
    sBinderProxyCountLowWatermark = low;
}

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

}; // namespace android
+2 −2
Original line number Diff line number Diff line
@@ -276,7 +276,7 @@ sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
                   return NULL;
            }

            b = new BpBinder(handle); 
            b = BpBinder::create(handle);
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
@@ -310,7 +310,7 @@ wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
        // arriving from the driver.
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            b = new BpBinder(handle);
            b = BpBinder::create(handle);
            result = b;
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
+25 −1
Original line number Diff line number Diff line
@@ -19,15 +19,20 @@

#include <binder/IBinder.h>
#include <utils/KeyedVector.h>
#include <utils/Mutex.h>
#include <utils/threads.h>

#include <unordered_map>

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

using binder_proxy_limit_callback = void(*)(int);

class BpBinder : public IBinder
{
public:
                        BpBinder(int32_t handle);
    static BpBinder*    create(int32_t handle);

    inline  int32_t     handle() const { return mHandle; }

@@ -61,6 +66,14 @@ public:
            status_t    setConstantData(const void* data, size_t size);
            void        sendObituary();

    static uint32_t     getBinderProxyCount(uint32_t uid);
    static void         getCountByUid(Vector<uint32_t>& uids, Vector<uint32_t>& counts);
    static void         enableCountByUid();
    static void         disableCountByUid();
    static void         setCountByUidEnabled(bool enable);
    static void         setLimitCallback(binder_proxy_limit_callback cb);
    static void         setBinderProxyCountWatermarks(int high, int low);

    class ObjectManager
    {
    public:
@@ -91,6 +104,7 @@ public:
    };

protected:
                        BpBinder(int32_t handle,int32_t trackedUid);
    virtual             ~BpBinder();
    virtual void        onFirstRef();
    virtual void        onLastStrongRef(const void* id);
@@ -115,6 +129,16 @@ private:
            ObjectManager       mObjects;
            Parcel*             mConstantData;
    mutable String16            mDescriptorCache;
            int32_t             mTrackedUid;

    static Mutex                                sTrackingLock;
    static std::unordered_map<int32_t,uint32_t> sTrackingMap;
    static int                                  sNumTrackedUids;
    static std::atomic_bool                     sCountByUidEnabled;
    static binder_proxy_limit_callback          sLimitCallback;
    static uint32_t                             sBinderProxyCountHighWatermark;
    static uint32_t                             sBinderProxyCountLowWatermark;
    static bool                                 sBinderProxyThrottleCreate;
};

}; // namespace android
+1 −1
Original line number Diff line number Diff line
@@ -5,4 +5,4 @@ cc_library_static {
    export_static_lib_headers = ["libserviceutils"],
}

subdirs = ["tests/fakehwc"]
 No newline at end of file
subdirs = ["tests/fakehwc", "layerproto"]
 No newline at end of file
Loading