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

Commit 4240e019 authored by Robert Quattlebaum's avatar Robert Quattlebaum
Browse files

lowpan: Use IBinder for comparison instead of interface

This change fixes a bug where the onInterfaceRemoved() callback for
LowpanManager was not working properly and causing crashes. This was
because we were using the ILowpanInterface objects as the key in a map
to for looking up the associated LowpanInterface objects. This doesn't
work because there may be more than one ILowpanInterface object for a
given IBinder---thus subsequent attempts to resolve ILowpanInterface
objects would always come up empty. The solution was to use the
underlying IBinder object as the map key.

(Cherry-picked from commit aa07c47441ae1e37f87248492459bef336b43155)

Bug: b/67718495
Test: manual
Change-Id: I7575743268cf67c6c2c24d8f327ce38d88d354c7
parent fdd755df
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ public class LowpanManager {
     * This design pattern allows us to skip removal of items
     * from this Map without leaking memory.
     */
    private final Map<ILowpanInterface, WeakReference<LowpanInterface>> mBinderCache =
    private final Map<IBinder, WeakReference<LowpanInterface>> mBinderCache =
            new WeakHashMap<>();

    private final ILowpanManager mService;
@@ -107,6 +107,20 @@ public class LowpanManager {
        mLooper = looper;
    }

    /** @hide */
    @Nullable
    public LowpanInterface getInterfaceNoCreate(@NonNull ILowpanInterface ifaceService) {
        LowpanInterface iface = null;

        synchronized (mBinderCache) {
            if (mBinderCache.containsKey(ifaceService.asBinder())) {
                iface = mBinderCache.get(ifaceService.asBinder()).get();
            }
        }

        return iface;
    }

    /** @hide */
    @Nullable
    public LowpanInterface getInterface(@NonNull ILowpanInterface ifaceService) {
@@ -114,8 +128,8 @@ public class LowpanManager {

        try {
            synchronized (mBinderCache) {
                if (mBinderCache.containsKey(ifaceService)) {
                    iface = mBinderCache.get(ifaceService).get();
                if (mBinderCache.containsKey(ifaceService.asBinder())) {
                    iface = mBinderCache.get(ifaceService.asBinder()).get();
                }

                if (iface == null) {
@@ -127,7 +141,7 @@ public class LowpanManager {
                        mInterfaceCache.put(iface.getName(), iface);
                    }

                    mBinderCache.put(ifaceService, new WeakReference(iface));
                    mBinderCache.put(ifaceService.asBinder(), new WeakReference(iface));

                    /* Make sure we remove the object from the
                     * interface cache if the associated service
@@ -260,7 +274,7 @@ public class LowpanManager {
                    public void onInterfaceRemoved(ILowpanInterface ifaceService) {
                        Runnable runnable =
                                () -> {
                                    LowpanInterface iface = getInterface(ifaceService);
                                    LowpanInterface iface = getInterfaceNoCreate(ifaceService);

                                    if (iface != null) {
                                        cb.onInterfaceRemoved(iface);