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

Commit 8decbf2e authored by Nate Myren's avatar Nate Myren
Browse files

Do not use synchronous ConnectivityManager APIs

These have race conditions when used in conjunction with the async
callbacks. Instead, use a default network callback to decide if the
default network is a trusted, validated wifi network

Fixes: 391153635
Test: atest NotificationManagerServiceTest
Flag: android.app.redact_sensitive_content_notifications_on_lockscreen
Change-Id: Idd2dd4fa6ba9a5e0d0b92153c1a22bc0e35620bd
parent 58c49cf0
Loading
Loading
Loading
Loading
+15 −24
Original line number Diff line number Diff line
@@ -258,7 +258,6 @@ import android.metrics.LogMaker;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -2833,33 +2832,25 @@ public class NotificationManagerService extends SystemService {
    }
    private void registerNetworkCallback() {
        NetworkRequest request = new NetworkRequest.Builder().addTransportType(
                NetworkCapabilities.TRANSPORT_WIFI).build();
        mConnectivityManager.registerNetworkCallback(request,
        mConnectivityManager.registerDefaultNetworkCallback(
                new ConnectivityManager.NetworkCallback() {
                // Need to post to another thread, as we can't call synchronous ConnectivityManager
                // methods from the callback itself, due to potential race conditions.
                    @Override
                public void onAvailable(@NonNull Network network) {
                    mHandler.post(() -> updateWifiConnectionState());
                    public void onCapabilitiesChanged(@NonNull Network network,
                            @NonNull NetworkCapabilities capabilities) {
                        updateWifiConnectionState(capabilities);
                    }
                    @Override
                    public void onLost(@NonNull Network network) {
                    mHandler.post(() -> updateWifiConnectionState());
                        mConnectedToWifi = false;
                    }
            });
        updateWifiConnectionState();
                }, mHandler);
    }
    @VisibleForTesting()
    void updateWifiConnectionState() {
        Network current = mConnectivityManager.getActiveNetwork();
        NetworkCapabilities capabilities = mConnectivityManager.getNetworkCapabilities(current);
        if (current == null || capabilities == null) {
            mConnectedToWifi = false;
            return;
        }
        mConnectedToWifi = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
    void updateWifiConnectionState(NetworkCapabilities capabilities) {
        mConnectedToWifi = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
                && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED);
    }
    /**
+15 −30
Original line number Diff line number Diff line
@@ -253,7 +253,6 @@ import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.session.MediaSession;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.Uri;
import android.os.Binder;
@@ -571,6 +570,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    @Mock
    NotificationAttentionHelper mAttentionHelper;
    @Mock
    NetworkCapabilities mWifiNetworkCapabilities;
    private NotificationManagerService.WorkerHandler mWorkerHandler;
    private class TestableToastCallback extends ITransientNotification.Stub {
@@ -771,7 +773,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        mActivityIntentImmutable = spy(PendingIntent.getActivity(mContext, 0,
                new Intent().setPackage(mPkg), FLAG_IMMUTABLE));
        when(mConnectivityManager.getActiveNetwork()).thenReturn(null);
        when(mWifiNetworkCapabilities.hasTransport(eq(NetworkCapabilities.TRANSPORT_WIFI)))
                .thenReturn(true);
        when(mWifiNetworkCapabilities
                .hasCapability(eq(NetworkCapabilities.NET_CAPABILITY_VALIDATED)))
                .thenReturn(true);
        when(mWifiNetworkCapabilities
                .hasCapability(eq(NetworkCapabilities.NET_CAPABILITY_TRUSTED)))
                .thenReturn(true);
        initNMS();
    }
@@ -14389,13 +14398,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    public void testMakeRankingUpdate_clearsHasSensitiveContentIfConnectedToWifi() {
        mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS,
                FLAG_REDACT_SENSITIVE_CONTENT_NOTIFICATIONS_ON_LOCKSCREEN);
        when(mConnectivityManager.getActiveNetwork()).thenReturn(mock(Network.class));
        when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn(
                new NetworkCapabilities.Builder()
                        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                        .build()
        );
        mService.updateWifiConnectionState();
        mService.updateWifiConnectionState(mWifiNetworkCapabilities);
        when(mListeners.hasSensitiveContent(any())).thenReturn(true);
        NotificationRecord pkgA = new NotificationRecord(mContext,
                generateSbn("a", 1000, 9, 0), mTestNotificationChannel);
@@ -14414,13 +14417,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    public void testMakeRankingUpdate_doesntClearHasSensitiveContentIfNotConnectedToWifi() {
        mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS,
                FLAG_REDACT_SENSITIVE_CONTENT_NOTIFICATIONS_ON_LOCKSCREEN);
        when(mConnectivityManager.getActiveNetwork()).thenReturn(mock(Network.class));
        when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn(
                new NetworkCapabilities.Builder()
                        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                        .build()
        );
        mService.updateWifiConnectionState();
        mService.updateWifiConnectionState(mock(NetworkCapabilities.class));
        when(mListeners.hasSensitiveContent(any())).thenReturn(true);
        NotificationRecord record = getSensitiveNotificationRecord();
        mService.addNotification(record);
@@ -14438,13 +14435,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    public void testMakeRankingUpdate_doesntClearHasSensitiveContentIfNotSysUi() {
        mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS);
        mSetFlagsRule.disableFlags(FLAG_REDACT_SENSITIVE_CONTENT_NOTIFICATIONS_ON_LOCKSCREEN);
        when(mConnectivityManager.getActiveNetwork()).thenReturn(mock(Network.class));
        when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn(
                new NetworkCapabilities.Builder()
                        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                        .build()
        );
        mService.updateWifiConnectionState();
        mService.updateWifiConnectionState(mWifiNetworkCapabilities);
        when(mListeners.hasSensitiveContent(any())).thenReturn(true);
        NotificationRecord record = getSensitiveNotificationRecord();
        mService.addNotification(record);
@@ -14461,13 +14452,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    public void testMakeRankingUpdate_doesntClearHasSensitiveContentIfFlagDisabled() {
        mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS);
        mSetFlagsRule.disableFlags(FLAG_REDACT_SENSITIVE_CONTENT_NOTIFICATIONS_ON_LOCKSCREEN);
        when(mConnectivityManager.getActiveNetwork()).thenReturn(mock(Network.class));
        when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn(
                new NetworkCapabilities.Builder()
                        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                        .build()
        );
        mService.updateWifiConnectionState();
        mService.updateWifiConnectionState(mWifiNetworkCapabilities);
        when(mListeners.hasSensitiveContent(any())).thenReturn(true);
        NotificationRecord record = getSensitiveNotificationRecord();
        mService.addNotification(record);