libbinder_ndk: ABBinder objects are tagged.
This allows us to always cast an object directly to the underlying
object rather than temporarily putting it behind a proxy. This also
simplifies the AIBinder_associateClass API greatly.
As a side-effect, this also fixes reading null parcelables from
binder buffers due to a previously missing check.
Bug: 111445392
Test: runtests.sh
Change-Id: I0c9a75132f9da35a2500b1e83f218b180b2dda36
diff --git a/libs/binder/ndk/AIBinder_internal.h b/libs/binder/ndk/AIBinder_internal.h
index d44b937..ed3b37b 100644
--- a/libs/binder/ndk/AIBinder_internal.h
+++ b/libs/binder/ndk/AIBinder_internal.h
@@ -35,24 +35,14 @@
AIBinder(const AIBinder_Class* clazz);
virtual ~AIBinder();
- // This returns an AIBinder object with this class associated. If the class is already
- // associated, 'this' will be returned. If there is a local AIBinder implementation, that will
- // be returned. If this is a remote object, the class will be associated and this will be ready
- // to be used for transactions.
- ::android::sp<AIBinder> associateClass(const AIBinder_Class* clazz);
+ bool associateClass(const AIBinder_Class* clazz);
const AIBinder_Class* getClass() const { return mClazz; }
- // This does not create the binder if it does not exist in the process.
virtual ::android::sp<::android::IBinder> getBinder() = 0;
virtual ABBinder* asABBinder() { return nullptr; }
virtual ABpBinder* asABpBinder() { return nullptr; }
- bool isRemote() {
- auto binder = getBinder();
- // if the binder is nullptr, then it is a local object which hasn't been sent out of process
- // yet.
- return binder != nullptr && binder->remoteBinder() != nullptr;
- }
+ bool isRemote() { return getBinder()->remoteBinder() != nullptr; }
private:
// AIBinder instance is instance of this class for a local object. In order to transact on a
@@ -63,7 +53,6 @@
// This is a local AIBinder object with a known class.
struct ABBinder : public AIBinder, public ::android::BBinder {
- ABBinder(const AIBinder_Class* clazz, void* userData);
virtual ~ABBinder();
void* getUserData() { return mUserData; }
@@ -76,6 +65,11 @@
::android::Parcel* reply, binder_flags_t flags) override;
private:
+ ABBinder(const AIBinder_Class* clazz, void* userData);
+
+ // only thing that should create an ABBinder
+ friend AIBinder* AIBinder_new(const AIBinder_Class*, void*);
+
// Can contain implementation if this is a local binder. This can still be nullptr for a local
// binder. If it is nullptr, the implication is the implementation state is entirely external to
// this object and the functionality provided in the AIBinder_Class is sufficient.
@@ -85,11 +79,15 @@
// This binder object may be remote or local (even though it is 'Bp'). It is not yet associated with
// a class.
struct ABpBinder : public AIBinder, public ::android::BpRefBase {
- ABpBinder(::android::sp<::android::IBinder> binder);
+ static ::android::sp<AIBinder> fromBinder(const ::android::sp<::android::IBinder>& binder);
+
virtual ~ABpBinder();
::android::sp<::android::IBinder> getBinder() override { return remote(); }
ABpBinder* asABpBinder() override { return this; }
+
+private:
+ ABpBinder(const ::android::sp<::android::IBinder>& binder);
};
struct AIBinder_Class {