Use IBinder as key for ConnectivityDiagnostics storage in CS.

This change updates ConnectivityService to use IBinder instances as keys
when storing ConnectivityDiagnosticsCallbacks.

When storing ConnectivityDiagnosticsCallbacks in ConnectivityService,
the IConnectivityDiagnsoticsCallback is used as the key for
ConnectivityService.mConnectivityDiagnosticsCallbacks. However,
IConnectivityDiagnosticsCallback instances are received as different
objects. This causes them to produce different hashCode() values, so
attempts to remove an IConnectivityDiagnosticsCallback fail.

Bug: 150867635
Test: atest FrameworksNetTests
Change-Id: Ib99e68d5ae47fa27e12428f9a60a2c1204ac59a2
Merged-In: Ib99e68d5ae47fa27e12428f9a60a2c1204ac59a2
(cherry picked from commit c7c6a4ac12beb7c216076958612869426da06da0)
This commit is contained in:
Cody Kesting
2020-03-05 10:46:02 -08:00
parent aebda983d3
commit b65e18e638
2 changed files with 18 additions and 22 deletions

View File

@@ -653,8 +653,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
final MultipathPolicyTracker mMultipathPolicyTracker;
@VisibleForTesting
final Map<IConnectivityDiagnosticsCallback, ConnectivityDiagnosticsCallbackInfo>
mConnectivityDiagnosticsCallbacks = new HashMap<>();
final Map<IBinder, ConnectivityDiagnosticsCallbackInfo> mConnectivityDiagnosticsCallbacks =
new HashMap<>();
/**
* Implements support for the legacy "one network per network type" model.
@@ -7835,11 +7835,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
ensureRunningOnConnectivityServiceThread();
final IConnectivityDiagnosticsCallback cb = cbInfo.mCb;
final IBinder iCb = cb.asBinder();
final NetworkRequestInfo nri = cbInfo.mRequestInfo;
// This means that the client registered the same callback multiple times. Do
// not override the previous entry, and exit silently.
if (mConnectivityDiagnosticsCallbacks.containsKey(cb)) {
if (mConnectivityDiagnosticsCallbacks.containsKey(iCb)) {
if (VDBG) log("Diagnostics callback is already registered");
// Decrement the reference count for this NetworkRequestInfo. The reference count is
@@ -7849,10 +7850,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
return;
}
mConnectivityDiagnosticsCallbacks.put(cb, cbInfo);
mConnectivityDiagnosticsCallbacks.put(iCb, cbInfo);
try {
cb.asBinder().linkToDeath(cbInfo, 0);
iCb.linkToDeath(cbInfo, 0);
} catch (RemoteException e) {
cbInfo.binderDied();
return;
@@ -7889,13 +7890,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void handleUnregisterConnectivityDiagnosticsCallback(
@NonNull IConnectivityDiagnosticsCallback cb, int uid) {
ensureRunningOnConnectivityServiceThread();
final IBinder iCb = cb.asBinder();
if (!mConnectivityDiagnosticsCallbacks.containsKey(cb)) {
if (!mConnectivityDiagnosticsCallbacks.containsKey(iCb)) {
if (VDBG) log("Removing diagnostics callback that is not currently registered");
return;
}
final NetworkRequestInfo nri = mConnectivityDiagnosticsCallbacks.get(cb).mRequestInfo;
final NetworkRequestInfo nri = mConnectivityDiagnosticsCallbacks.get(iCb).mRequestInfo;
if (uid != nri.mUid) {
if (VDBG) loge("Different uid than registrant attempting to unregister cb");
@@ -7907,7 +7909,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
// enforceRequestCountLimit().
decrementNetworkRequestPerUidCount(nri);
cb.asBinder().unlinkToDeath(mConnectivityDiagnosticsCallbacks.remove(cb), 0);
final ConnectivityDiagnosticsCallbackInfo cbInfo =
mConnectivityDiagnosticsCallbacks.remove(iCb);
iCb.unlinkToDeath(cbInfo, 0);
}
private void handleNetworkTestedWithExtras(
@@ -7982,14 +7986,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
private List<IConnectivityDiagnosticsCallback> getMatchingPermissionedCallbacks(
@NonNull NetworkAgentInfo nai) {
final List<IConnectivityDiagnosticsCallback> results = new ArrayList<>();
for (Entry<IConnectivityDiagnosticsCallback, ConnectivityDiagnosticsCallbackInfo> entry :
for (Entry<IBinder, ConnectivityDiagnosticsCallbackInfo> entry :
mConnectivityDiagnosticsCallbacks.entrySet()) {
final ConnectivityDiagnosticsCallbackInfo cbInfo = entry.getValue();
final NetworkRequestInfo nri = cbInfo.mRequestInfo;
if (nai.satisfies(nri.request)) {
if (checkConnectivityDiagnosticsPermissions(
nri.mPid, nri.mUid, nai, cbInfo.mCallingPackageName)) {
results.add(entry.getKey());
results.add(entry.getValue().mCb);
}
}
}

View File

@@ -6750,16 +6750,12 @@ public class ConnectivityServiceTest {
verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt());
verify(mConnectivityDiagnosticsCallback).asBinder();
assertTrue(
mService.mConnectivityDiagnosticsCallbacks.containsKey(
mConnectivityDiagnosticsCallback));
assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder));
mService.unregisterConnectivityDiagnosticsCallback(mConnectivityDiagnosticsCallback);
verify(mIBinder, timeout(TIMEOUT_MS))
.unlinkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt());
assertFalse(
mService.mConnectivityDiagnosticsCallbacks.containsKey(
mConnectivityDiagnosticsCallback));
assertFalse(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder));
verify(mConnectivityDiagnosticsCallback, atLeastOnce()).asBinder();
}
@@ -6777,9 +6773,7 @@ public class ConnectivityServiceTest {
verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt());
verify(mConnectivityDiagnosticsCallback).asBinder();
assertTrue(
mService.mConnectivityDiagnosticsCallbacks.containsKey(
mConnectivityDiagnosticsCallback));
assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder));
// Register the same callback again
mService.registerConnectivityDiagnosticsCallback(
@@ -6788,9 +6782,7 @@ public class ConnectivityServiceTest {
// Block until all other events are done processing.
HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
assertTrue(
mService.mConnectivityDiagnosticsCallbacks.containsKey(
mConnectivityDiagnosticsCallback));
assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder));
}
@Test