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

Commit b43a2921 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Jeff Sharkey
Browse files

Update network rules on meteredness changes.

The CONFIGURED_NETWORKS_CHANGED_ACTION broadcast can be dispatched
before WifiStateMachine has a chance to update NetworkCapabilities,
resulting in a race condition.  To fix this, update network rules
whenever we actually notice a meteredness change take place.

Test: builds, boots
Bug: 64274313
Change-Id: I490eaa789fc0754e4c1c413b6606378ef6f90662
parent 465a9560
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -113,16 +113,20 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.IConnectivityManager;
import android.net.INetworkManagementEventObserver;
import android.net.INetworkPolicyListener;
import android.net.INetworkPolicyManager;
import android.net.INetworkStatsService;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkIdentity;
import android.net.NetworkPolicy;
import android.net.NetworkPolicyManager;
import android.net.NetworkQuotaInfo;
import android.net.NetworkRequest;
import android.net.NetworkState;
import android.net.NetworkTemplate;
import android.net.TrafficStats;
@@ -444,6 +448,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
    @GuardedBy("mUidRulesFirstLock")
    final SparseIntArray mUidState = new SparseIntArray();

    /** Map from network ID to last observed meteredness state */
    @GuardedBy("mNetworkPoliciesSecondLock")
    private final SparseBooleanArray mNetworkMetered = new SparseBooleanArray();

    private final RemoteCallbackList<INetworkPolicyListener>
            mListeners = new RemoteCallbackList<>();

@@ -782,6 +790,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
                    ACTION_CARRIER_CONFIG_CHANGED);
            mContext.registerReceiver(mCarrierConfigReceiver, carrierConfigFilter, null, mHandler);

            // listen for meteredness changes
            mContext.getSystemService(ConnectivityManager.class).registerNetworkCallback(
                    new NetworkRequest.Builder().build(), mNetworkCallback);

            mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
            // tell systemReady() that the service has been initialized
            initCompleteSignal.countDown();
@@ -981,6 +993,26 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
            synchronized (mUidRulesFirstLock) {
                synchronized (mNetworkPoliciesSecondLock) {
                    upgradeWifiMeteredOverrideAL();
                }
            }
            // Only need to perform upgrade logic once
            mContext.unregisterReceiver(this);
        }
    };

    private final NetworkCallback mNetworkCallback = new NetworkCallback() {
        @Override
        public void onCapabilitiesChanged(Network network,
                NetworkCapabilities networkCapabilities) {
            if (network == null || networkCapabilities == null) return;

            synchronized (mNetworkPoliciesSecondLock) {
                final boolean oldMetered = mNetworkMetered.get(network.netId, false);
                final boolean newMetered = !networkCapabilities
                        .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);

                if ((oldMetered != newMetered) || mNetworkMetered.indexOfKey(network.netId) < 0) {
                    mNetworkMetered.put(network.netId, newMetered);
                    updateNetworkRulesNL();
                }
            }