diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index e0dd8867b2..e76762e350 100644 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -249,6 +249,8 @@ import android.net.NetworkStack; import android.net.NetworkStateSnapshot; import android.net.NetworkTestResultParcelable; import android.net.OemNetworkPreferences; +import android.net.PacProxyManager; +import android.net.Proxy; import android.net.ProxyInfo; import android.net.QosCallbackException; import android.net.QosFilter; @@ -478,6 +480,7 @@ public class ConnectivityServiceTest { private Context mContext; private NetworkPolicyCallback mPolicyCallback; private WrappedMultinetworkPolicyTracker mPolicyTracker; + private ProxyTracker mProxyTracker; private HandlerThread mAlarmManagerThread; private TestNetIdManager mNetIdManager; private QosCallbackMockHelper mQosCallbackMockHelper; @@ -511,7 +514,7 @@ public class ConnectivityServiceTest { @Mock VpnProfileStore mVpnProfileStore; @Mock SystemConfigManager mSystemConfigManager; @Mock Resources mResources; - @Mock ProxyTracker mProxyTracker; + @Mock PacProxyManager mPacProxyManager; // BatteryStatsManager is final and cannot be mocked with regular mockito, so just mock the // underlying binder calls. @@ -613,6 +616,7 @@ public class ConnectivityServiceTest { if (Context.SYSTEM_CONFIG_SERVICE.equals(name)) return mSystemConfigManager; if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; if (Context.BATTERY_STATS_SERVICE.equals(name)) return mBatteryStatsManager; + if (Context.PAC_PROXY_SERVICE.equals(name)) return mPacProxyManager; return super.getSystemService(name); } @@ -1703,6 +1707,8 @@ public class ConnectivityServiceTest { mCsHandlerThread = new HandlerThread("TestConnectivityService"); mVMSHandlerThread = new HandlerThread("TestVpnManagerService"); + mProxyTracker = new ProxyTracker(mServiceContext, mock(Handler.class), + 16 /* EVENT_PROXY_HAS_CHANGED */); initMockedResources(); final Context mockResContext = mock(Context.class); @@ -2135,6 +2141,39 @@ public class ConnectivityServiceTest { return expected; } + private ExpectedBroadcast expectProxyChangeAction(ProxyInfo proxy) { + return registerPacProxyBroadcastThat(intent -> { + final ProxyInfo actualProxy = (ProxyInfo) intent.getExtra(Proxy.EXTRA_PROXY_INFO, + ProxyInfo.buildPacProxy(Uri.EMPTY)); + return proxy.equals(actualProxy); + }); + } + + private ExpectedBroadcast registerPacProxyBroadcast() { + return registerPacProxyBroadcastThat(intent -> true); + } + + private ExpectedBroadcast registerPacProxyBroadcastThat( + @NonNull final Predicate filter) { + final IntentFilter intentFilter = new IntentFilter(Proxy.PROXY_CHANGE_ACTION); + // AtomicReference allows receiver to access expected even though it is constructed later. + final AtomicReference expectedRef = new AtomicReference<>(); + final BroadcastReceiver receiver = new BroadcastReceiver() { + public void onReceive(Context context, Intent intent) { + final ProxyInfo proxy = (ProxyInfo) intent.getExtra( + Proxy.EXTRA_PROXY_INFO, ProxyInfo.buildPacProxy(Uri.EMPTY)); + Log.d(TAG, "Receive PROXY_CHANGE_ACTION, proxy = " + proxy); + if (filter.test(intent)) { + expectedRef.get().complete(intent); + } + } + }; + final ExpectedBroadcast expected = new ExpectedBroadcast(receiver); + expectedRef.set(expected); + mServiceContext.registerReceiver(receiver, intentFilter); + return expected; + } + private boolean extraInfoInBroadcastHasExpectedNullness(NetworkInfo ni) { final DetailedState state = ni.getDetailedState(); if (state == DetailedState.CONNECTED && ni.getExtraInfo() == null) return false; @@ -9945,7 +9984,7 @@ public class ConnectivityServiceTest { final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); final Network wifiNetwork = mWiFiNetworkAgent.getNetwork(); - doReturn(testProxyInfo).when(mService.mProxyTracker).getGlobalProxy(); + mProxyTracker.setGlobalProxy(testProxyInfo); assertEquals(testProxyInfo, mService.getProxyForNetwork(wifiNetwork)); } @@ -11353,6 +11392,7 @@ public class ConnectivityServiceTest { assertNull(mService.getProxyForNetwork(null)); assertNull(mCm.getDefaultProxy()); + final ExpectedBroadcast b1 = registerPacProxyBroadcast(); final LinkProperties lp = new LinkProperties(); lp.setInterfaceName("tun0"); lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null)); @@ -11362,9 +11402,10 @@ public class ConnectivityServiceTest { mMockVpn.establish(lp, VPN_UID, vpnRanges); assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); // VPN is connected but proxy is not set, so there is no need to send proxy broadcast. - verify(mProxyTracker, never()).sendProxyBroadcast(); + b1.expectNoBroadcast(500); // Update to new range which is old range minus APP1, i.e. only APP2 + final ExpectedBroadcast b2 = registerPacProxyBroadcast(); final Set newRanges = new HashSet<>(asList( new UidRange(vpnRange.start, APP1_UID - 1), new UidRange(APP1_UID + 1, vpnRange.stop))); @@ -11375,37 +11416,37 @@ public class ConnectivityServiceTest { assertVpnUidRangesUpdated(false, vpnRanges, VPN_UID); // Uid has changed but proxy is not set, so there is no need to send proxy broadcast. - verify(mProxyTracker, never()).sendProxyBroadcast(); + b2.expectNoBroadcast(500); final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); + final ExpectedBroadcast b3 = registerPacProxyBroadcast(); lp.setHttpProxy(testProxyInfo); mMockVpn.sendLinkProperties(lp); waitForIdle(); // Proxy is set, so send a proxy broadcast. - verify(mProxyTracker, times(1)).sendProxyBroadcast(); - reset(mProxyTracker); + b3.expectBroadcast(); + final ExpectedBroadcast b4 = registerPacProxyBroadcast(); mMockVpn.setUids(vpnRanges); waitForIdle(); // Uid has changed and proxy is already set, so send a proxy broadcast. - verify(mProxyTracker, times(1)).sendProxyBroadcast(); - reset(mProxyTracker); + b4.expectBroadcast(); + final ExpectedBroadcast b5 = registerPacProxyBroadcast(); // Proxy is removed, send a proxy broadcast. lp.setHttpProxy(null); mMockVpn.sendLinkProperties(lp); waitForIdle(); - verify(mProxyTracker, times(1)).sendProxyBroadcast(); - reset(mProxyTracker); + b5.expectBroadcast(); // Proxy is added in WiFi(default network), setDefaultProxy will be called. final LinkProperties wifiLp = mCm.getLinkProperties(mWiFiNetworkAgent.getNetwork()); assertNotNull(wifiLp); + final ExpectedBroadcast b6 = expectProxyChangeAction(testProxyInfo); wifiLp.setHttpProxy(testProxyInfo); mWiFiNetworkAgent.sendLinkProperties(wifiLp); waitForIdle(); - verify(mProxyTracker, times(1)).setDefaultProxy(eq(testProxyInfo)); - reset(mProxyTracker); + b6.expectBroadcast(); } @Test @@ -11424,18 +11465,21 @@ public class ConnectivityServiceTest { lp.setHttpProxy(testProxyInfo); final UidRange vpnRange = PRIMARY_UIDRANGE; final Set vpnRanges = Collections.singleton(vpnRange); + final ExpectedBroadcast b1 = registerPacProxyBroadcast(); mMockVpn.setOwnerAndAdminUid(VPN_UID); mMockVpn.registerAgent(false, vpnRanges, lp); // In any case, the proxy broadcast won't be sent before VPN goes into CONNECTED state. // Otherwise, the app that calls ConnectivityManager#getDefaultProxy() when it receives the // proxy broadcast will get null. - verify(mProxyTracker, never()).sendProxyBroadcast(); + b1.expectNoBroadcast(500); + + final ExpectedBroadcast b2 = registerPacProxyBroadcast(); mMockVpn.connect(true /* validated */, true /* hasInternet */, false /* isStrictMode */); waitForIdle(); assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID); // Vpn is connected with proxy, so the proxy broadcast will be sent to inform the apps to // update their proxy data. - verify(mProxyTracker, times(1)).sendProxyBroadcast(); + b2.expectBroadcast(); } @Test @@ -11464,10 +11508,10 @@ public class ConnectivityServiceTest { final LinkProperties cellularLp = new LinkProperties(); cellularLp.setInterfaceName(MOBILE_IFNAME); final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888); + final ExpectedBroadcast b = registerPacProxyBroadcast(); cellularLp.setHttpProxy(testProxyInfo); mCellNetworkAgent.sendLinkProperties(cellularLp); - waitForIdle(); - verify(mProxyTracker, times(1)).sendProxyBroadcast(); + b.expectBroadcast(); } @Test