Merge "Fix a possible system server crash"

This commit is contained in:
Chalard Jean
2021-07-27 04:37:43 +00:00
committed by Gerrit Code Review
2 changed files with 47 additions and 1 deletions

View File

@@ -5907,7 +5907,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
public void binderDied() { public void binderDied() {
log("ConnectivityService NetworkRequestInfo binderDied(" + log("ConnectivityService NetworkRequestInfo binderDied(" +
"uid/pid:" + mUid + "/" + mPid + ", " + mBinder + ")"); "uid/pid:" + mUid + "/" + mPid + ", " + mBinder + ")");
mHandler.post(() -> handleRemoveNetworkRequest(this)); // As an immutable collection, mRequests cannot change by the time the
// lambda is evaluated on the handler thread so calling .get() from a binder thread
// is acceptable. Use handleReleaseNetworkRequest and not directly
// handleRemoveNetworkRequest so as to force a lookup in the requests map, in case
// the app already unregistered the request.
mHandler.post(() -> handleReleaseNetworkRequest(mRequests.get(0),
mUid, false /* callOnUnavailable */));
} }
@Override @Override

View File

@@ -280,6 +280,7 @@ import android.os.HandlerThread;
import android.os.IBinder; import android.os.IBinder;
import android.os.INetworkManagementService; import android.os.INetworkManagementService;
import android.os.Looper; import android.os.Looper;
import android.os.Messenger;
import android.os.Parcel; import android.os.Parcel;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.Parcelable; import android.os.Parcelable;
@@ -2168,6 +2169,45 @@ public class ConnectivityServiceTest {
mCm.unregisterNetworkCallback(fgMobileListenCallback); mCm.unregisterNetworkCallback(fgMobileListenCallback);
} }
@Test
public void testBinderDeathAfterUnregister() throws Exception {
final NetworkCapabilities caps = new NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_WIFI)
.build();
final Handler handler = new Handler(ConnectivityThread.getInstanceLooper());
final Messenger messenger = new Messenger(handler);
final CompletableFuture<Binder.DeathRecipient> deathRecipient = new CompletableFuture<>();
final Binder binder = new Binder() {
private DeathRecipient mDeathRecipient;
@Override
public void linkToDeath(@NonNull final DeathRecipient recipient, final int flags) {
synchronized (this) {
mDeathRecipient = recipient;
}
super.linkToDeath(recipient, flags);
deathRecipient.complete(recipient);
}
@Override
public boolean unlinkToDeath(@NonNull final DeathRecipient recipient, final int flags) {
synchronized (this) {
if (null == mDeathRecipient) {
throw new IllegalStateException();
}
mDeathRecipient = null;
}
return super.unlinkToDeath(recipient, flags);
}
};
final NetworkRequest request = mService.listenForNetwork(caps, messenger, binder,
NetworkCallback.FLAG_NONE, mContext.getOpPackageName(),
mContext.getAttributionTag());
mService.releaseNetworkRequest(request);
deathRecipient.get().binderDied();
// Wait for the release message to be processed.
waitForIdle();
}
@Test @Test
public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception { public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception {
// Test bringing up unvalidated WiFi // Test bringing up unvalidated WiFi