blob: fe34bb6e7f29b794f293b1096a1f2321f38a1d76 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.net;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Proxy;
import android.os.Build;
import android.os.Looper;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.chromium.base.ContextUtils;
import org.chromium.base.test.BaseJUnit4ClassRunner;
import org.chromium.base.test.util.AdvancedMockContext;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* Tests for {@link ProxyChangeListener}.
*/
@RunWith(BaseJUnit4ClassRunner.class)
public class ProxyChangeListenerTest {
FakeContext mAppContext;
ProxyChangeListener mListener;
ProxyChangeListener.Delegate mDelegate;
private static class FakeContext extends AdvancedMockContext {
private class RegisteredReceiver {
final BroadcastReceiver mReceiver;
final IntentFilter mFilter;
RegisteredReceiver(BroadcastReceiver receiver, IntentFilter filter) {
mReceiver = receiver;
mFilter = filter;
}
void filterAndPostBroadcast(final Intent broadcast) {
if (mFilter != null) {
if (mFilter.match(null, broadcast, false, "sendBroadcast") < 0) {
return;
}
}
mReceiver.onReceive(FakeContext.this, broadcast);
}
}
private List<RegisteredReceiver> mReceivers = new ArrayList<>();
FakeContext() {
super(InstrumentationRegistry.getInstrumentation()
.getTargetContext()
.getApplicationContext());
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
mReceivers.add(new RegisteredReceiver(receiver, filter));
return null;
}
@Override
public void unregisterReceiver(BroadcastReceiver receiver) {
for (RegisteredReceiver r : mReceivers) {
if (r.mReceiver == receiver) {
mReceivers.remove(r);
return;
}
}
throw new IllegalStateException("Receiver not found.");
}
@Override
public void sendBroadcast(Intent intent) {
for (final RegisteredReceiver r : mReceivers) {
r.filterAndPostBroadcast(intent);
}
}
public List<BroadcastReceiver> getReceivers() {
ArrayList<BroadcastReceiver> result = new ArrayList<>(mReceivers.size());
for (final RegisteredReceiver r : mReceivers) {
result.add(r.mReceiver);
}
return result;
}
}
@Before
public void setUp() {
mAppContext = Mockito.spy(new FakeContext());
ContextUtils.initApplicationContextForTests(mAppContext);
Looper.prepare();
// Create the listener that's going to be used for tests
mListener = ProxyChangeListener.create();
mListener.setDelegateForTesting(
mDelegate = Mockito.mock(ProxyChangeListener.Delegate.class));
mListener.start(0);
Mockito.verify(mAppContext)
.registerReceiver(Mockito.anyObject(),
Mockito.argThat((IntentFilter filter)
-> filter.matchAction(Proxy.PROXY_CHANGE_ACTION)));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Mockito.verify(mAppContext)
.registerReceiver(Mockito.anyObject(),
Mockito.argThat(
(IntentFilter filter)
-> !filter.matchAction(Proxy.PROXY_CHANGE_ACTION)));
}
}
@After
public void tearDown() {
mListener.stop();
Assert.assertEquals("All receivers should have been unregistered",
mAppContext.getReceivers().size(), 0);
}
@Test
@SmallTest
public void testProxyChangeListenerDelegateCalled() {
Intent intent = new Intent();
intent.setAction(Proxy.PROXY_CHANGE_ACTION);
mAppContext.sendBroadcast(intent);
Mockito.verify(mDelegate, Mockito.times(1)).proxySettingsChanged();
}
@Test
@SmallTest
public void testProxyChangeListenerDelegateCalledByReflection() throws Exception {
// Assuming that the reflection to get the LoadedApk list of broadcast receivers worked,
// this tests that an app can correctly find the ProxyChangeListener (which may be fake),
// and call its onReceived method, resulting in one delegate invocation.
for (Object rec : mAppContext.getReceivers()) {
Class<?> clazz = rec.getClass();
if (clazz.getName().contains("ProxyChangeListener")) {
Method onReceiveMethod =
clazz.getDeclaredMethod("onReceive", Context.class, Intent.class);
Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
onReceiveMethod.invoke(rec, mAppContext, intent);
}
}
Mockito.verify(mDelegate, Mockito.times(1)).proxySettingsChanged();
}
}