Function binder_ndk_sys::AIBinder_setExtension

source ยท
pub unsafe extern "C" fn AIBinder_setExtension(
    binder: *mut AIBinder,
    ext: *mut AIBinder,
) -> binder_status_t
Expand description

Gets the extension of a binder interface. This allows a downstream developer to add an extension to an interface without modifying its interface file. This should be called immediately when the object is created before it is passed to another thread. No thread safety is required.

For instance, imagine if we have this interface: interface IFoo { void doFoo(); }

A). Historical option that has proven to be BAD! Only the original author of an interface should change an interface. If someone downstream wants additional functionality, they should not ever change the interface or use this method.

BAD TO DO: interface IFoo { BAD TO DO BAD TO DO: void doFoo(); BAD TO DO BAD TO DO: + void doBar(); // adding a method BAD TO DO BAD TO DO: } BAD TO DO

B). Option that this method enables. Leave the original interface unchanged (do not change IFoo!). Instead, create a new interface in a downstream package:

    package com.<name>; // new functionality in a new package
    interface IBar { void doBar(); }

When registering the interface, add:
    std::shared_ptr<MyFoo> foo = new MyFoo; // class in AOSP codebase
    std::shared_ptr<MyBar> bar = new MyBar; // custom extension class
    SpAIBinder binder = foo->asBinder(); // target binder to extend
    ... = AIBinder_setExtension(binder.get(), bar->asBinder().get());
    ... = AServiceManager_addService(binder.get(), instanceName);
    // handle error

    Do not use foo->asBinder().get() as the target binder argument to
    AIBinder_setExtensions because asBinder it creates a new binder
    object that will be destroyed after the function is called. The same
    binder object must be used for AIBinder_setExtension and
    AServiceManager_addService to register the service with an extension.

Then, clients of IFoo can get this extension:
    SpAIBinder binder = ...;
    std::shared_ptr<IFoo> foo = IFoo::fromBinder(binder); // handle if null
    SpAIBinder barBinder;
    ... = AIBinder_getExtension(barBinder.get());
    // handle error
    std::shared_ptr<IBar> bar = IBar::fromBinder(barBinder);
    // type is checked with AIBinder_associateClass
    // if bar is null, then there is no extension or a different
    // type of extension

Available since API level 30.

\param binder the object to get the extension on. Must be local. \param ext the extension to set (binder will hold a strong reference to this)

\return OK on success, STATUS_INVALID_OPERATION if binder is not local, STATUS_UNEXPECTED_NULL if either binder is null.