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
This commit is contained in:
Robert Quattlebaum
2017-10-11 18:05:39 -07:00
parent fdd755df14
commit 4240e019d8

View File

@@ -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);