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

Commit 678722f9 authored by Anarghya Mitra's avatar Anarghya Mitra
Browse files

Change status bar icons upon capability changes in the default network.

SysUI status bar updates currently happen upon receiving either the
CONNECTIVITY_ACTION broadcast (which is deprecated) and
INET_CONDITION_ACTION broadcast (which is sent upon validation state
change of networks only).

This leads to status bar showing stale connectivity state. The correct
fix for this is to listen to changes in network state by registering
NetworkCallbacks (see more details in http://b/79286300#comment9).

In the P timeframe, not listening to the broadcasts completely is out of
scope. So this CL just listens for changing network capabilities of the
default data network, which should fix all the cases where the
broadcasts are not getting sent.

Later, when we stop relying on the broadcasts, we will also have to
override onAvailable and onLost (and perhaps the other callbacks too).

Test: runtest --path frameworks/base/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/
Bug: 71904788
Change-Id: I2e58b9cfceb9937a0b54874dee116ead5339b37b
parent 733a4b99
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
@@ -219,6 +220,38 @@ public class NetworkControllerImpl extends BroadcastReceiver
                        deviceProvisionedController.getCurrentUser()));
            }
        });

        ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback(){
            private Network mLastNetwork;
            private NetworkCapabilities mLastNetworkCapabilities;

            @Override
            public void onCapabilitiesChanged(
                Network network, NetworkCapabilities networkCapabilities) {
                boolean lastValidated = (mLastNetworkCapabilities != null) &&
                    mLastNetworkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED);
                boolean validated =
                    networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED);

                // This callback is invoked a lot (i.e. when RSSI changes), so avoid updating
                // icons when connectivity state has remained the same.
                if (network.equals(mLastNetwork) &&
                    networkCapabilities.equalsTransportTypes(mLastNetworkCapabilities) &&
                    validated == lastValidated) {
                    return;
                }
                mLastNetwork = network;
                mLastNetworkCapabilities = networkCapabilities;
                updateConnectivity();
            }
        };
        // Even though this callback runs on the receiver handler thread which also processes the
        // CONNECTIVITY_ACTION broadcasts, the broadcast and callback might come in at different
        // times. This is safe since updateConnectivity() builds the list of transports from
        // scratch.
        // TODO: Move off of the deprecated CONNECTIVITY_ACTION broadcast and rely on callbacks
        // exclusively for status bar icons.
        mConnectivityManager.registerDefaultNetworkCallback(callback, mReceiverHandler);
    }

    public DataSaverController getDataSaverController() {
+31 −5
Original line number Diff line number Diff line
@@ -17,20 +17,25 @@
package com.android.systemui.statusbar.policy;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.telephony.PhoneStateListener;
@@ -90,6 +95,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
    protected int mSubId;

    private NetworkCapabilities mNetCapabilities;
    private ConnectivityManager.NetworkCallback mNetworkCallback;

    @Rule
    public TestWatcher failWatcher = new TestWatcher() {
@@ -154,6 +160,13 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
        setSubscriptions(mSubId);
        mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
        mPhoneStateListener = mMobileSignalController.mPhoneStateListener;

        ArgumentCaptor<ConnectivityManager.NetworkCallback> callbackArg =
            ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
        Mockito.verify(mMockCm, atLeastOnce())
            .registerDefaultNetworkCallback(callbackArg.capture(), isA(Handler.class));
        mNetworkCallback = callbackArg.getValue();
        assertNotNull(mNetworkCallback);
    }

    protected void setDefaultSubId(int subId) {
@@ -195,24 +208,37 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
        setLevel(DEFAULT_LEVEL);
        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
                TelephonyManager.NETWORK_TYPE_UMTS);
        setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, true, true);
        setConnectivityViaBroadcast(
            NetworkCapabilities.TRANSPORT_CELLULAR, true, true);
    }

    public void setConnectivity(int networkType, boolean inetCondition, boolean isConnected) {
    public void setConnectivityViaBroadcast(
        int networkType, boolean validated, boolean isConnected) {
        setConnectivityCommon(networkType, validated, isConnected);
        Intent i = new Intent(ConnectivityManager.INET_CONDITION_ACTION);
        mNetworkController.onReceive(mContext, i);
    }

    public void setConnectivityViaCallback(
        int networkType, boolean validated, boolean isConnected){
        setConnectivityCommon(networkType, validated, isConnected);
        mNetworkCallback.onCapabilitiesChanged(
            mock(Network.class), new NetworkCapabilities(mNetCapabilities));
    }

    private void setConnectivityCommon(
        int networkType, boolean validated, boolean isConnected){
        // TODO: Separate out into several NetworkCapabilities.
        if (isConnected) {
            mNetCapabilities.addTransportType(networkType);
        } else {
            mNetCapabilities.removeTransportType(networkType);
        }
        if (inetCondition) {
        if (validated) {
            mNetCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
        } else {
            mNetCapabilities.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
        }

        mNetworkController.onReceive(mContext, i);
    }

    public void setGsmRoaming(boolean isRoaming) {
+3 −3
Original line number Diff line number Diff line
@@ -118,7 +118,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
        when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
        setupDefaultSignal();
        updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
        setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);

        // Verify that a SignalDrawable with a cut out is used to display data disabled.
        verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, 0,
@@ -132,7 +132,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
        when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
        setupDefaultSignal();
        updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
        setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);

        // Verify that a SignalDrawable with a cut out is used to display data disabled.
        verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, 0,
@@ -146,7 +146,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
        when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
        setupDefaultSignal();
        updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
        setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
        when(mMockProvisionController.isUserSetup(anyInt())).thenReturn(false);
        mUserCallback.onUserSetupChanged();
        TestableLooper.get(this).processAllMessages();
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ public class NetworkControllerEthernetTest extends NetworkControllerBaseTest {
    }

    protected void setEthernetState(boolean connected, boolean validated) {
        setConnectivity(NetworkCapabilities.TRANSPORT_ETHERNET, validated, connected);
        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_ETHERNET, validated, connected);
    }

    protected void verifyLastEthernetIcon(boolean visible, int icon) {
+3 −3
Original line number Diff line number Diff line
@@ -143,7 +143,7 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
                    testStrength, DEFAULT_ICON);

            // Verify low inet number indexing.
            setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, true);
            setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, true);
            verifyLastMobileDataIndicators(true,
                    testStrength, DEFAULT_ICON, false, false);
        }
@@ -230,8 +230,8 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
    @Test
    public void testNoBangWithWifi() {
        setupDefaultSignal();
        setConnectivity(mMobileSignalController.mTransportType, false, false);
        setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
        setConnectivityViaBroadcast(mMobileSignalController.mTransportType, false, false);
        setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_WIFI, true, true);

        verifyLastMobileDataIndicators(true, DEFAULT_LEVEL, 0);
    }
Loading