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

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

Snap for 5012867 from 36e78578 to qt-release

Change-Id: I76cb365994dd9a12cff8072c79d3806904a74202
parents 66daae05 36e78578
Loading
Loading
Loading
Loading
+350 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.
 */

/**
 * @file system_fonts.h
 * @brief Provides the system font configurations.
 *
 * These APIs provides the list of system installed font files with additional metadata about the
 * font.
 *
 * The ASystemFontIterator_open method will give you an iterator which can iterate all system
 * installed font files as shown in the following example.
 *
 * <code>
 *   ASystemFontIterator* iterator = ASystemFontIterator_open();
 *   ASystemFont* font = NULL;
 *
 *   while ((font = ASystemFontIterator_next(iterator)) != nullptr) {
 *       // Look if the font is your desired one.
 *       if (ASystemFont_getWeight(font) == 400 && !ASystemFont_isItalic(font)
 *           && ASystemFont_getLocale(font) == NULL) {
 *           break;
 *       }
 *       ASystemFont_close(font);
 *   }
 *   ASystemFontIterator_close(iterator);
 *
 *   int fd = open(ASystemFont_getFontFilePath(font), O_RDONLY);
 *   int collectionIndex = ASystemFont_getCollectionINdex(font);
 *   std::vector<std::pair<uint32_t, float>> variationSettings;
 *   for (size_t i = 0; i < ASystemFont_getAxisCount(font); ++i) {
 *       variationSettings.push_back(std::make_pair(
 *           ASystemFont_getAxisTag(font, i),
 *           ASystemFont_getAxisValue(font, i)));
 *   }
 *   ASystemFont_close(font);
 *
 *   // Use this font for your text rendering engine.
 *
 * </code>
 *
 * Available since API level 29.
 */

#ifndef ANDROID_SYSTEM_FONTS_H
#define ANDROID_SYSTEM_FONTS_H

#include <stdbool.h>
#include <stddef.h>
#include <sys/cdefs.h>

/******************************************************************
 *
 * IMPORTANT NOTICE:
 *
 *   This file is part of Android's set of stable system headers
 *   exposed by the Android NDK (Native Development Kit).
 *
 *   Third-party source AND binary code relies on the definitions
 *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
 *
 *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
 *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
 *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
 *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
 */

__BEGIN_DECLS

#if __ANDROID_API__ >= 29

enum {
    /** The minimum value fot the font weight value. */
    ASYSTEM_FONT_WEIGHT_MIN = 0,

    /** A font weight value for the thin weight. */
    ASYSTEM_FONT_WEIGHT_THIN = 100,

    /** A font weight value for the extra-light weight. */
    ASYSTEM_FONT_WEIGHT_EXTRA_LIGHT = 200,

    /** A font weight value for the light weight. */
    ASYSTEM_FONT_WEIGHT_LIGHT = 300,

    /** A font weight value for the normal weight. */
    ASYSTEM_FONT_WEIGHT_NORMAL = 400,

    /** A font weight value for the medium weight. */
    ASYSTEM_FONT_WEIGHT_MEDIUM = 500,

    /** A font weight value for the semi-bold weight. */
    ASYSTEM_FONT_WEIGHT_SEMI_BOLD = 600,

    /** A font weight value for the bold weight. */
    ASYSTEM_FONT_WEIGHT_BOLD = 700,

    /** A font weight value for the extra-bold weight. */
    ASYSTEM_FONT_WEIGHT_EXTRA_BOLD = 800,

    /** A font weight value for the black weight. */
    ASYSTEM_FONT_WEIGHT_BLACK = 900,

    /** The maximum value for the font weight value. */
    ASYSTEM_FONT_WEIGHT_MAX = 1000
};

/**
 * ASystemFontIterator provides access to the system font configuration.
 *
 * ASystemFontIterator is an iterator for all available system font settings.
 * This iterator is not a thread-safe object. Do not pass this iterator to other threads.
 */
struct ASystemFontIterator;

/**
 * ASystemFont provides information of the single system font configuration.
 */
struct ASystemFont;

/**
 * Create a system font iterator.
 *
 * Use ASystemFont_close() to close the iterator.
 *
 * \return a pointer for a newly allocated iterator, nullptr on failure.
 */
ASystemFontIterator* _Nullable ASystemFontIterator_open() __INTRODUCED_IN(29);

/**
 * Close an opened system font iterator, freeing any related resources.
 *
 * \param a pointer of an iterator for the system fonts. Do nothing if NULL is passed.
 */
void ASystemFontIterator_close(ASystemFontIterator* _Nullable iterator) __INTRODUCED_IN(29);

/**
 * Move to the next system font.
 *
 * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
 * \return true if more system fonts are available, otherwise false.
 */
ASystemFont* _Nullable ASystemFontIterator_next(ASystemFontIterator* _Nonnull iterator) __INTRODUCED_IN(29);

/**
 * Close an ASystemFont returned by ASystemFontIterator_next.
 *
 * \param font a font returned by ASystemFontIterator_next. Do nothing if NULL is passed.
 */
void ASystemFont_close(ASystemFont* _Nullable font) __INTRODUCED_IN(29);


/**
 * Return an absolute path to the current font file.
 *
 * Here is a list of font formats returned by this method:
 * <ul>
 *   <li>OpenType</li>
 *   <li>OpenType Font Collection</li>
 *   <li>TrueType</li>
 *   <li>TrueType Collection</li>
 * </ul>
 * The file extension could be one of *.otf, *.ttf, *.otc or *.ttc.
 *
 * The font file returned is guaranteed to be opend with O_RDONLY.
 * Note that the returned pointer is valid until ASystemFont_close() is called for the given font.
 *
 * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
 * \return a string of the font file path.
 */
const char* _Nonnull ASystemFont_getFontFilePath(const ASystemFont* _Nonnull font) __INTRODUCED_IN(29);

/**
 * Return a weight value associated with the current font.
 *
 * The weight values are positive and less than or equal to 1000.
 * Here are pairs of the common names and their values.
 * <p>
 *  <table>
 *  <thead>
 *  <tr>
 *  <th align="center">Value</th>
 *  <th align="center">Name</th>
 *  <th align="center">NDK Definition</th>
 *  </tr>
 *  </thead>
 *  <tbody>
 *  <tr>
 *  <td align="center">100</td>
 *  <td align="center">Thin</td>
 *  <td align="center">{@link ASYSTEM_FONT_WEIGHT_THIN}</td>
 *  </tr>
 *  <tr>
 *  <td align="center">200</td>
 *  <td align="center">Extra Light (Ultra Light)</td>
 *  <td align="center">{@link ASYSTEM_FONT_WEIGHT_EXTRA_LIGHT}</td>
 *  </tr>
 *  <tr>
 *  <td align="center">300</td>
 *  <td align="center">Light</td>
 *  <td align="center">{@link ASYSTEM_FONT_WEIGHT_LIGHT}</td>
 *  </tr>
 *  <tr>
 *  <td align="center">400</td>
 *  <td align="center">Normal (Regular)</td>
 *  <td align="center">{@link ASYSTEM_FONT_WEIGHT_NORMAL}</td>
 *  </tr>
 *  <tr>
 *  <td align="center">500</td>
 *  <td align="center">Medium</td>
 *  <td align="center">{@link ASYSTEM_FONT_WEIGHT_MEDIUM}</td>
 *  </tr>
 *  <tr>
 *  <td align="center">600</td>
 *  <td align="center">Semi Bold (Demi Bold)</td>
 *  <td align="center">{@link ASYSTEM_FONT_WEIGHT_SEMI_BOLD}</td>
 *  </tr>
 *  <tr>
 *  <td align="center">700</td>
 *  <td align="center">Bold</td>
 *  <td align="center">{@link ASYSTEM_FONT_WEIGHT_BOLD}</td>
 *  </tr>
 *  <tr>
 *  <td align="center">800</td>
 *  <td align="center">Extra Bold (Ultra Bold)</td>
 *  <td align="center">{@link ASYSTEM_FONT_WEIGHT_EXTRA_BOLD}</td>
 *  </tr>
 *  <tr>
 *  <td align="center">900</td>
 *  <td align="center">Black (Heavy)</td>
 *  <td align="center">{@link ASYSTEM_FONT_WEIGHT_BLACK}</td>
 *  </tr>
 *  </tbody>
 * </p>
 * Note that the weight value may fall in between above values, e.g. 250 weight.
 *
 * For more information about font weight, read [OpenType usWeightClass](https://docs.microsoft.com/en-us/typography/opentype/spec/os2#usweightclass)
 *
 * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
 * \return a positive integer less than or equal to {@link ASYSTEM_FONT_MAX_WEIGHT} is returned.
 */
uint16_t ASystemFont_getWeight(const ASystemFont* _Nonnull font) __INTRODUCED_IN(29);

/**
 * Return true if the current font is italic, otherwise returns false.
 *
 * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
 * \return true if italic, otherwise false.
 */
bool ASystemFont_isItalic(const ASystemFont* _Nonnull font) __INTRODUCED_IN(29);

/**
 * Return a IETF BCP47 compliant language tag associated with the current font.
 *
 * For information about IETF BCP47, read [Locale.forLanguageTag(java.lang.String)](https://developer.android.com/reference/java/util/Locale.html#forLanguageTag(java.lang.String)")
 *
 * Note that the returned pointer is valid until ASystemFont_close() is called.
 *
 * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
 * \return a IETF BCP47 compliant langauge tag or nullptr if not available.
 */
const char* _Nullable ASystemFont_getLocale(const ASystemFont* _Nonnull font) __INTRODUCED_IN(29);

/**
 * Return a font collection index value associated with the current font.
 *
 * In case the target font file is a font collection (e.g. .ttc or .otc), this
 * returns a non-negative value as an font offset in the collection. This
 * always returns 0 if the target font file is a regular font.
 *
 * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
 * \return a font collection index.
 */
size_t ASystemFont_getCollectionIndex(const ASystemFont* _Nonnull font) __INTRODUCED_IN(29);

/**
 * Return a count of font variation settings associated with the current font
 *
 * The font variation settings are provided as multiple tag-values pairs.
 *
 * For example, bold italic font may have following font variation settings:
 *     'wght' 700, 'slnt' -12
 * In this case, ASystemFont_getAxisCount returns 2 and ASystemFont_getAxisTag
 * and ASystemFont_getAxisValue will return following values.
 * <code>
 *     ASystemFont* font = ASystemFontIterator_next(ite);
 *
 *     // Returns the number of axes
 *     ASystemFont_getAxisCount(font);  // Returns 2
 *
 *     // Returns the tag-value pair for the first axis.
 *     ASystemFont_getAxisTag(font, 0);  // Returns 'wght'(0x77676874)
 *     ASystemFont_getAxisValue(font, 0);  // Returns 700.0
 *
 *     // Returns the tag-value pair for the second axis.
 *     ASystemFont_getAxisTag(font, 1);  // Returns 'slnt'(0x736c6e74)
 *     ASystemFont_getAxisValue(font, 1);  // Returns -12.0
 * </code>
 *
 * For more information about font variation settings, read [Font Variations Table](https://docs.microsoft.com/en-us/typography/opentype/spec/fvar)
 *
 * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
 * \return a number of font variation settings.
 */
size_t ASystemFont_getAxisCount(const ASystemFont* _Nonnull font) __INTRODUCED_IN(29);


/**
 * Return an OpenType axis tag associated with the current font.
 *
 * See ASystemFont_getAxisCount for more details.
 *
 * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
 * \param an index to the font variation settings. Passing value larger than or
 *        equal to {@link ASystemFont_getAxisCount} is not allowed.
 * \return an OpenType axis tag value for the given font variation setting.
 */
uint32_t ASystemFont_getAxisTag(const ASystemFont* _Nonnull font, uint32_t axisIndex)
      __INTRODUCED_IN(29);

/**
 * Return an OpenType axis value associated with the current font.
 *
 * See ASystemFont_getAxisCount for more details.
 *
 * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
 * \param an index to the font variation settings. Passing value larger than or
 *         equal to {@link ASYstemFont_getAxisCount} is not allwed.
 * \return a float value for the given font variation setting.
 */
float ASystemFont_getAxisValue(const ASystemFont* _Nonnull font, uint32_t axisIndex)
      __INTRODUCED_IN(29);

#endif // __ANDROID_API__ >= 29

__END_DECLS

#endif // ANDROID_SYSTEM_FONTS_H
+20 −0
Original line number Diff line number Diff line
@@ -151,11 +151,31 @@ public:

    typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie);

    /**
     * This object is attached for the lifetime of this binder object. When
     * this binder object is destructed, the cleanup function of all attached
     * objects are invoked with their respective objectID, object, and
     * cleanupCookie. Access to these APIs can be made from multiple threads,
     * but calls from different threads are allowed to be interleaved.
     */
    virtual void            attachObject(   const void* objectID,
                                            void* object,
                                            void* cleanupCookie,
                                            object_cleanup_func func) = 0;
    /**
     * Returns object attached with attachObject.
     */
    virtual void*           findObject(const void* objectID) const = 0;
    /**
     * WARNING: this API does not call the cleanup function for legacy reasons.
     * It also does not return void* for legacy reasons. If you need to detach
     * an object and destroy it, there are two options:
     * - if you can, don't call detachObject and instead wait for the destructor
     *   to clean it up.
     * - manually retrieve and destruct the object (if multiple of your threads
     *   are accessing these APIs, you must guarantee that attachObject isn't
     *   called after findObject and before detachObject is called).
     */
    virtual void            detachObject(const void* objectID) = 0;

    virtual BBinder*        localBinder();
+4 −4
Original line number Diff line number Diff line
@@ -24,10 +24,10 @@ cc_library {
    ],

    srcs: [
        "ABinderProcess.cpp",
        "AIBinder.cpp",
        "AParcel.cpp",
        "AServiceManager.cpp",
        "ibinder.cpp",
        "parcel.cpp",
        "process.cpp",
        "service_manager.cpp",
    ],

    shared_libs: [
+155 −6
Original line number Diff line number Diff line
@@ -15,13 +15,15 @@
 */

#include <android/binder_ibinder.h>
#include "AIBinder_internal.h"
#include "ibinder_internal.h"

#include <android/binder_status.h>
#include "AParcel_internal.h"
#include "parcel_internal.h"

#include <android-base/logging.h>

using DeathRecipient = ::android::IBinder::DeathRecipient;

using ::android::IBinder;
using ::android::Parcel;
using ::android::sp;
@@ -32,10 +34,10 @@ namespace ABBinderTag {

static const void* kId = "ABBinder";
static void* kValue = static_cast<void*>(new bool{true});
void cleanId(const void* /*id*/, void* /*obj*/, void* /*cookie*/){/* do nothing */};
void clean(const void* /*id*/, void* /*obj*/, void* /*cookie*/){/* do nothing */};

static void attach(const sp<IBinder>& binder) {
    binder->attachObject(kId, kValue, nullptr /*cookie*/, cleanId);
    binder->attachObject(kId, kValue, nullptr /*cookie*/, clean);
}
static bool has(const sp<IBinder>& binder) {
    return binder != nullptr && binder->findObject(kId) == kValue;
@@ -43,6 +45,21 @@ static bool has(const sp<IBinder>& binder) {

} // namespace ABBinderTag

namespace ABpBinderTag {

static std::mutex gLock;
static const void* kId = "ABpBinder";
struct Value {
    wp<ABpBinder> binder;
};
void clean(const void* id, void* obj, void* cookie) {
    CHECK(id == kId) << id << " " << obj << " " << cookie;

    delete static_cast<Value*>(obj);
};

} // namespace ABpBinderTag

AIBinder::AIBinder(const AIBinder_Class* clazz) : mClazz(clazz) {}
AIBinder::~AIBinder() {}

@@ -121,14 +138,51 @@ ABpBinder::ABpBinder(const ::android::sp<::android::IBinder>& binder)
}
ABpBinder::~ABpBinder() {}

sp<AIBinder> ABpBinder::fromBinder(const ::android::sp<::android::IBinder>& binder) {
void ABpBinder::onLastStrongRef(const void* id) {
    {
        std::lock_guard<std::mutex> lock(ABpBinderTag::gLock);
        // Since ABpBinder is OBJECT_LIFETIME_WEAK, we must remove this weak reference in order for
        // the ABpBinder to be deleted. Since a strong reference to this ABpBinder object should no
        // longer be able to exist at the time of this method call, there is no longer a need to
        // recover it.

        ABpBinderTag::Value* value =
                static_cast<ABpBinderTag::Value*>(remote()->findObject(ABpBinderTag::kId));
        if (value != nullptr) {
            value->binder = nullptr;
        }
    }

    BpRefBase::onLastStrongRef(id);
}

sp<AIBinder> ABpBinder::lookupOrCreateFromBinder(const ::android::sp<::android::IBinder>& binder) {
    if (binder == nullptr) {
        return nullptr;
    }
    if (ABBinderTag::has(binder)) {
        return static_cast<ABBinder*>(binder.get());
    }
    return new ABpBinder(binder);

    // The following code ensures that for a given binder object (remote or local), if it is not an
    // ABBinder then at most one ABpBinder object exists in a given process representing it.
    std::lock_guard<std::mutex> lock(ABpBinderTag::gLock);

    ABpBinderTag::Value* value =
            static_cast<ABpBinderTag::Value*>(binder->findObject(ABpBinderTag::kId));
    if (value == nullptr) {
        value = new ABpBinderTag::Value;
        binder->attachObject(ABpBinderTag::kId, static_cast<void*>(value), nullptr /*cookie*/,
                             ABpBinderTag::clean);
    }

    sp<ABpBinder> ret = value->binder.promote();
    if (ret == nullptr) {
        ret = new ABpBinder(binder);
        value->binder = ret;
    }

    return ret;
}

struct AIBinder_Weak {
@@ -179,6 +233,63 @@ AIBinder_Class* AIBinder_Class_define(const char* interfaceDescriptor,
    return new AIBinder_Class(interfaceDescriptor, onCreate, onDestroy, onTransact);
}

void AIBinder_DeathRecipient::TransferDeathRecipient::binderDied(const wp<IBinder>& who) {
    CHECK(who == mWho);

    mOnDied(mCookie);
    mWho = nullptr;
}

AIBinder_DeathRecipient::AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied)
      : mOnDied(onDied) {
    CHECK(onDied != nullptr);
}

binder_status_t AIBinder_DeathRecipient::linkToDeath(AIBinder* binder, void* cookie) {
    CHECK(binder != nullptr);

    std::lock_guard<std::mutex> l(mDeathRecipientsMutex);

    sp<TransferDeathRecipient> recipient =
            new TransferDeathRecipient(binder->getBinder(), cookie, mOnDied);

    binder_status_t status = binder->getBinder()->linkToDeath(recipient, cookie, 0 /*flags*/);
    if (status != EX_NONE) {
        return status;
    }

    mDeathRecipients.push_back(recipient);
    return EX_NONE;
}

binder_status_t AIBinder_DeathRecipient::unlinkToDeath(AIBinder* binder, void* cookie) {
    CHECK(binder != nullptr);

    std::lock_guard<std::mutex> l(mDeathRecipientsMutex);

    for (auto it = mDeathRecipients.rbegin(); it != mDeathRecipients.rend(); ++it) {
        sp<TransferDeathRecipient> recipient = *it;

        if (recipient->getCookie() == cookie &&

            recipient->getWho() == binder->getBinder()) {
            mDeathRecipients.erase(it.base() - 1);

            binder_status_t status =
                    binder->getBinder()->unlinkToDeath(recipient, cookie, 0 /*flags*/);
            if (status != EX_NONE) {
                LOG(ERROR) << __func__
                           << ": removed reference to death recipient but unlink failed.";
            }
            return status;
        }
    }

    return -ENOENT;
}

// start of C-API methods

AIBinder* AIBinder_new(const AIBinder_Class* clazz, void* args) {
    if (clazz == nullptr) {
        LOG(ERROR) << __func__ << ": Must provide class to construct local binder.";
@@ -218,6 +329,26 @@ binder_status_t AIBinder_ping(AIBinder* binder) {
    return binder->getBinder()->pingBinder();
}

binder_status_t AIBinder_linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
                                     void* cookie) {
    if (binder == nullptr || recipient == nullptr) {
        LOG(ERROR) << __func__ << ": Must provide binder and recipient.";
        return EX_NULL_POINTER;
    }

    return recipient->linkToDeath(binder, cookie);
}

binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
                                       void* cookie) {
    if (binder == nullptr || recipient == nullptr) {
        LOG(ERROR) << __func__ << ": Must provide binder and recipient.";
        return EX_NULL_POINTER;
    }

    return recipient->unlinkToDeath(binder, cookie);
}

void AIBinder_incStrong(AIBinder* binder) {
    if (binder == nullptr) {
        LOG(ERROR) << __func__ << ": on null binder";
@@ -347,3 +478,21 @@ binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, APa

    return parcelStatus;
}

AIBinder_DeathRecipient* AIBinder_DeathRecipient_new(
        AIBinder_DeathRecipient_onBinderDied onBinderDied) {
    if (onBinderDied == nullptr) {
        LOG(ERROR) << __func__ << ": requires non-null onBinderDied parameter.";
        return nullptr;
    }
    return new AIBinder_DeathRecipient(onBinderDied);
}

void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient** recipient) {
    if (recipient == nullptr) {
        return;
    }

    delete *recipient;
    *recipient = nullptr;
}
+46 −4
Original line number Diff line number Diff line
@@ -17,9 +17,11 @@
#pragma once

#include <android/binder_ibinder.h>
#include "AIBinder_internal.h"
#include "ibinder_internal.h"

#include <atomic>
#include <mutex>
#include <vector>

#include <binder/Binder.h>
#include <binder/IBinder.h>
@@ -79,13 +81,18 @@ private:
    void* mUserData;
};

// This binder object may be remote or local (even though it is 'Bp'). It is not yet associated with
// a class.
// This binder object may be remote or local (even though it is 'Bp'). The implication if it is
// local is that it is an IBinder object created outside of the domain of libbinder_ndk.
struct ABpBinder : public AIBinder, public ::android::BpRefBase {
    static ::android::sp<AIBinder> fromBinder(const ::android::sp<::android::IBinder>& binder);
    // Looks up to see if this object has or is an existing ABBinder or ABpBinder object, otherwise
    // it creates an ABpBinder object.
    static ::android::sp<AIBinder> lookupOrCreateFromBinder(
            const ::android::sp<::android::IBinder>& binder);

    virtual ~ABpBinder();

    void onLastStrongRef(const void* id) override;

    ::android::sp<::android::IBinder> getBinder() override { return remote(); }
    ABpBinder* asABpBinder() override { return this; }

@@ -108,3 +115,38 @@ private:
    // one.
    const ::android::String16 mInterfaceDescriptor;
};

// Ownership is like this (when linked to death):
//
//   AIBinder_DeathRecipient -sp-> TransferDeathRecipient <-wp-> IBinder
//
// When the AIBinder_DeathRecipient is dropped, so are the actual underlying death recipients. When
// the IBinder dies, only a wp to it is kept.
struct AIBinder_DeathRecipient {
    // One of these is created for every linkToDeath. This is to be able to recover data when a
    // binderDied receipt only gives us information about the IBinder.
    struct TransferDeathRecipient : ::android::IBinder::DeathRecipient {
        TransferDeathRecipient(const ::android::wp<::android::IBinder>& who, void* cookie,
                               const AIBinder_DeathRecipient_onBinderDied& onDied)
              : mWho(who), mCookie(cookie), mOnDied(onDied) {}

        void binderDied(const ::android::wp<::android::IBinder>& who) override;

        const ::android::wp<::android::IBinder>& getWho() { return mWho; }
        void* getCookie() { return mCookie; }

    private:
        ::android::wp<::android::IBinder> mWho;
        void* mCookie;
        const AIBinder_DeathRecipient_onBinderDied& mOnDied;
    };

    AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied);
    binder_status_t linkToDeath(AIBinder* binder, void* cookie);
    binder_status_t unlinkToDeath(AIBinder* binder, void* cookie);

private:
    std::mutex mDeathRecipientsMutex;
    std::vector<::android::sp<TransferDeathRecipient>> mDeathRecipients;
    AIBinder_DeathRecipient_onBinderDied mOnDied;
};
Loading