1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.net.watchlist; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNull; 22 import static org.junit.Assert.assertTrue; 23 import static org.junit.Assert.fail; 24 25 import android.net.ConnectivityMetricsEvent; 26 import android.net.IIpConnectivityMetrics; 27 import android.net.INetdEventCallback; 28 import android.os.Handler; 29 import android.os.IBinder; 30 import android.os.Message; 31 import android.os.Process; 32 import android.os.RemoteException; 33 import android.support.test.InstrumentationRegistry; 34 import android.support.test.filters.MediumTest; 35 import android.support.test.runner.AndroidJUnit4; 36 37 import com.android.server.ServiceThread; 38 39 import org.junit.After; 40 import org.junit.Before; 41 import org.junit.Test; 42 import org.junit.runner.RunWith; 43 44 import java.util.concurrent.CountDownLatch; 45 import java.util.concurrent.TimeUnit; 46 47 /** 48 * runtest frameworks-services -c com.android.server.net.watchlist.NetworkWatchlistServiceTests 49 */ 50 @RunWith(AndroidJUnit4.class) 51 @MediumTest 52 public class NetworkWatchlistServiceTests { 53 54 private static final long NETWOR_EVENT_TIMEOUT_SEC = 1; 55 private static final String TEST_HOST = "testhost.com"; 56 private static final String TEST_IP = "7.6.8.9"; 57 private static final String[] TEST_IPS = 58 new String[] {"1.2.3.4", "4.6.8.9", "2001:0db8:0001:0000:0000:0ab9:C0A8:0102"}; 59 60 private static class TestHandler extends Handler { 61 @Override 62 public void handleMessage(Message msg) { 63 switch (msg.what) { 64 case WatchlistLoggingHandler.LOG_WATCHLIST_EVENT_MSG: 65 onLogEvent(); 66 break; 67 case WatchlistLoggingHandler.REPORT_RECORDS_IF_NECESSARY_MSG: 68 onAggregateEvent(); 69 break; 70 default: 71 fail("Unexpected message: " + msg.what); 72 } 73 } 74 75 public void onLogEvent() {} 76 public void onAggregateEvent() {} 77 } 78 79 private static class TestIIpConnectivityMetrics implements IIpConnectivityMetrics { 80 81 int counter = 0; 82 INetdEventCallback callback = null; 83 84 @Override 85 public IBinder asBinder() { 86 return null; 87 } 88 89 @Override 90 public int logEvent(ConnectivityMetricsEvent connectivityMetricsEvent) 91 throws RemoteException { 92 return 0; 93 } 94 95 @Override 96 public boolean addNetdEventCallback(int callerType, INetdEventCallback callback) { 97 counter++; 98 this.callback = callback; 99 return true; 100 } 101 102 @Override 103 public boolean removeNetdEventCallback(int callerType) { 104 counter--; 105 return true; 106 } 107 }; 108 109 ServiceThread mHandlerThread; 110 WatchlistLoggingHandler mWatchlistHandler; 111 NetworkWatchlistService mWatchlistService; 112 113 @Before 114 public void setUp() { 115 mHandlerThread = new ServiceThread("NetworkWatchlistServiceTests", 116 Process.THREAD_PRIORITY_BACKGROUND, /* allowIo */ false); 117 mHandlerThread.start(); 118 mWatchlistHandler = new WatchlistLoggingHandler(InstrumentationRegistry.getContext(), 119 mHandlerThread.getLooper()); 120 mWatchlistService = new NetworkWatchlistService(InstrumentationRegistry.getContext(), 121 mHandlerThread, mWatchlistHandler, null); 122 } 123 124 @After 125 public void tearDown() { 126 mHandlerThread.quitSafely(); 127 } 128 129 @Test 130 public void testStartStopWatchlistLogging() throws Exception { 131 TestIIpConnectivityMetrics connectivityMetrics = new TestIIpConnectivityMetrics() { 132 @Override 133 public boolean addNetdEventCallback(int callerType, INetdEventCallback callback) { 134 super.addNetdEventCallback(callerType, callback); 135 assertEquals(callerType, INetdEventCallback.CALLBACK_CALLER_NETWORK_WATCHLIST); 136 return true; 137 } 138 139 @Override 140 public boolean removeNetdEventCallback(int callerType) { 141 super.removeNetdEventCallback(callerType); 142 assertEquals(callerType, INetdEventCallback.CALLBACK_CALLER_NETWORK_WATCHLIST); 143 return true; 144 } 145 }; 146 assertEquals(connectivityMetrics.counter, 0); 147 mWatchlistService.mIpConnectivityMetrics = connectivityMetrics; 148 assertTrue(mWatchlistService.startWatchlistLoggingImpl()); 149 assertEquals(connectivityMetrics.counter, 1); 150 assertTrue(mWatchlistService.startWatchlistLoggingImpl()); 151 assertEquals(connectivityMetrics.counter, 1); 152 assertTrue(mWatchlistService.stopWatchlistLoggingImpl()); 153 assertEquals(connectivityMetrics.counter, 0); 154 assertTrue(mWatchlistService.stopWatchlistLoggingImpl()); 155 assertEquals(connectivityMetrics.counter, 0); 156 assertTrue(mWatchlistService.startWatchlistLoggingImpl()); 157 assertEquals(connectivityMetrics.counter, 1); 158 assertTrue(mWatchlistService.stopWatchlistLoggingImpl()); 159 assertEquals(connectivityMetrics.counter, 0); 160 } 161 162 @Test 163 public void testNetworkEvents() throws Exception { 164 TestIIpConnectivityMetrics connectivityMetrics = new TestIIpConnectivityMetrics(); 165 mWatchlistService.mIpConnectivityMetrics = connectivityMetrics; 166 assertTrue(mWatchlistService.startWatchlistLoggingImpl()); 167 168 // Test DNS events 169 final CountDownLatch testDnsLatch = new CountDownLatch(1); 170 final Object[] dnsParams = new Object[3]; 171 final WatchlistLoggingHandler testDnsHandler = 172 new WatchlistLoggingHandler(InstrumentationRegistry.getContext(), 173 mHandlerThread.getLooper()) { 174 @Override 175 public void asyncNetworkEvent(String host, String[] ipAddresses, int uid) { 176 dnsParams[0] = host; 177 dnsParams[1] = ipAddresses; 178 dnsParams[2] = uid; 179 testDnsLatch.countDown(); 180 } 181 }; 182 mWatchlistService.mNetworkWatchlistHandler = testDnsHandler; 183 connectivityMetrics.callback.onDnsEvent(TEST_HOST, TEST_IPS, TEST_IPS.length, 123L, 456); 184 if (!testDnsLatch.await(NETWOR_EVENT_TIMEOUT_SEC, TimeUnit.SECONDS)) { 185 fail("Timed out waiting for network event"); 186 } 187 assertEquals(TEST_HOST, dnsParams[0]); 188 for (int i = 0; i < TEST_IPS.length; i++) { 189 assertEquals(TEST_IPS[i], ((String[])dnsParams[1])[i]); 190 } 191 assertEquals(456, dnsParams[2]); 192 193 // Test connect events 194 final CountDownLatch testConnectLatch = new CountDownLatch(1); 195 final Object[] connectParams = new Object[3]; 196 final WatchlistLoggingHandler testConnectHandler = 197 new WatchlistLoggingHandler(InstrumentationRegistry.getContext(), 198 mHandlerThread.getLooper()) { 199 @Override 200 public void asyncNetworkEvent(String host, String[] ipAddresses, int uid) { 201 connectParams[0] = host; 202 connectParams[1] = ipAddresses; 203 connectParams[2] = uid; 204 testConnectLatch.countDown(); 205 } 206 }; 207 mWatchlistService.mNetworkWatchlistHandler = testConnectHandler; 208 connectivityMetrics.callback.onConnectEvent(TEST_IP, 80, 123L, 456); 209 if (!testConnectLatch.await(NETWOR_EVENT_TIMEOUT_SEC, TimeUnit.SECONDS)) { 210 fail("Timed out waiting for network event"); 211 } 212 assertNull(connectParams[0]); 213 assertEquals(1, ((String[]) connectParams[1]).length); 214 assertEquals(TEST_IP, ((String[]) connectParams[1])[0]); 215 assertEquals(456, connectParams[2]); 216 } 217 } 218