RttServiceTest.java revision f4267b6840dbc7f430638c35c5448187b6e83846
1/* 2 * Copyright (C) 2016 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 17package com.android.server.wifi; 18 19import static org.junit.Assert.assertEquals; 20import static org.mockito.Matchers.any; 21import static org.mockito.Matchers.anyInt; 22import static org.mockito.Mockito.atLeastOnce; 23import static org.mockito.Mockito.mock; 24import static org.mockito.Mockito.times; 25import static org.mockito.Mockito.validateMockitoUsage; 26import static org.mockito.Mockito.verify; 27import static org.mockito.Mockito.verifyNoMoreInteractions; 28import static org.mockito.Mockito.when; 29 30import android.content.BroadcastReceiver; 31import android.content.Context; 32import android.content.IntentFilter; 33import android.net.wifi.RttManager; 34import android.net.wifi.RttManager.ParcelableRttParams; 35import android.net.wifi.RttManager.ResponderConfig; 36import android.net.wifi.WifiManager; 37import android.os.Handler; 38import android.os.Message; 39import android.os.test.TestLooper; 40import android.test.suitebuilder.annotation.SmallTest; 41 42import com.android.internal.util.test.BidirectionalAsyncChannel; 43 44import org.junit.After; 45import org.junit.Before; 46import org.junit.Test; 47import org.mockito.ArgumentCaptor; 48import org.mockito.Mock; 49import org.mockito.MockitoAnnotations; 50 51/** 52 * Unit test for {@link com.android.server.wifi.RttService} 53 */ 54@SmallTest 55public class RttServiceTest { 56 57 // Some constants for running Rtt tests. 58 private static final String MAC = "12:34:56:78:9A:BC"; 59 private static final int CLIENT_KEY1 = 1; 60 private static final int CLIENT_KEY2 = 2; 61 62 @Mock 63 Context mContext; 64 @Mock 65 WifiNative mWifiNative; 66 TestLooper mLooper; 67 68 RttService.RttServiceImpl mRttServiceImpl; 69 ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor = ArgumentCaptor 70 .forClass(BroadcastReceiver.class); 71 72 @Before 73 public void setUp() throws Exception { 74 MockitoAnnotations.initMocks(this); 75 TestUtil.installWlanWifiNative(mWifiNative); 76 mLooper = new TestLooper(); 77 mRttServiceImpl = new RttService.RttServiceImpl(mContext, mLooper.getLooper()); 78 mRttServiceImpl.startService(); 79 } 80 81 @After 82 public void cleanup() { 83 validateMockitoUsage(); 84 } 85 86 private void startWifi() { 87 verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(), 88 any(IntentFilter.class)); 89 TestUtil.sendWifiScanAvailable(mBroadcastReceiverCaptor.getValue(), 90 mContext, WifiManager.WIFI_STATE_ENABLED); 91 } 92 93 // Create and connect a bi-directional async channel. 94 private BidirectionalAsyncChannel connectChannel(Handler handler) { 95 BidirectionalAsyncChannel channel = new BidirectionalAsyncChannel(); 96 channel.connect(mLooper.getLooper(), mRttServiceImpl.getMessenger(), 97 handler); 98 mLooper.dispatchAll(); 99 channel.assertConnected(); 100 return channel; 101 } 102 103 private void sendRangingRequestFailed(BidirectionalAsyncChannel channel, Handler handler, 104 int clientKey, ParcelableRttParams params) { 105 Message message = sendRangingRequest(channel, handler, clientKey, params); 106 assertEquals("ranging request did not fail", 107 RttManager.CMD_OP_FAILED, message.what); 108 verifyNoMoreInteractions(mWifiNative); 109 } 110 111 // Send rtt ranging request message and verify failure. 112 private Message sendRangingRequest(BidirectionalAsyncChannel channel, Handler handler, 113 int clientKey, ParcelableRttParams params) { 114 Message message = new Message(); 115 message.what = RttManager.CMD_OP_START_RANGING; 116 message.arg2 = clientKey; 117 message.obj = params; 118 channel.sendMessage(message); 119 mLooper.dispatchAll(); 120 ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); 121 verify(handler, atLeastOnce()).handleMessage(messageCaptor.capture()); 122 return messageCaptor.getValue(); 123 } 124 125 // Send enable responder message and verify success. 126 private void sendEnableResponderSucceed(BidirectionalAsyncChannel channel, 127 Handler handler, int clientKey) { 128 Message message = sendEnableResponder(channel, handler, clientKey, 129 createResponderConfig()); 130 verify(mWifiNative).enableRttResponder(anyInt()); 131 assertEquals("reponse status is not success", 132 RttManager.CMD_OP_ENALBE_RESPONDER_SUCCEEDED, message.what); 133 String actualMac = ((ResponderConfig) message.obj).macAddress; 134 assertEquals("mac address mismatch", MAC, actualMac); 135 } 136 137 // Send enable responder message and verify failure. 138 private void sendEnableResponderFailed(BidirectionalAsyncChannel channel, 139 Handler handler, int clientKey, int reason) { 140 Message message = sendEnableResponder(channel, handler, clientKey, null); 141 assertEquals("reponse status is not failure", 142 RttManager.CMD_OP_ENALBE_RESPONDER_FAILED, message.what); 143 assertEquals("failure reason is not " + reason, 144 reason, message.arg1); 145 } 146 147 private Message sendEnableResponder(BidirectionalAsyncChannel channel, Handler handler, 148 int clientKey, ResponderConfig config) { 149 when(mWifiNative.enableRttResponder(anyInt())).thenReturn(config); 150 when(mWifiNative.getMacAddress()).thenReturn(MAC); 151 Message message = new Message(); 152 message.what = RttManager.CMD_OP_ENABLE_RESPONDER; 153 message.arg2 = clientKey; 154 channel.sendMessage(message); 155 mLooper.dispatchAll(); 156 ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); 157 verify(handler, atLeastOnce()).handleMessage(messageCaptor.capture()); 158 return messageCaptor.getValue(); 159 } 160 161 private void sendDisableResponder(BidirectionalAsyncChannel channel, int key, boolean success) { 162 when(mWifiNative.disableRttResponder()).thenReturn(success); 163 Message message = new Message(); 164 message.what = RttManager.CMD_OP_DISABLE_RESPONDER; 165 message.arg2 = key; 166 channel.sendMessage(message); 167 mLooper.dispatchAll(); 168 } 169 170 private ResponderConfig createResponderConfig() { 171 ResponderConfig config = new ResponderConfig(); 172 config.macAddress = MAC; 173 return config; 174 } 175 176 @Test 177 public void testEnableResponderSuccess() throws Exception { 178 startWifi(); 179 Handler handler = mock(Handler.class); 180 BidirectionalAsyncChannel channel = connectChannel(handler); 181 // Successfully enabled responder. 182 sendEnableResponderSucceed(channel, handler, CLIENT_KEY1); 183 } 184 185 @Test 186 public void testEnableResponderSecondTime() throws Exception { 187 startWifi(); 188 Handler handler = mock(Handler.class); 189 BidirectionalAsyncChannel channel = connectChannel(handler); 190 sendEnableResponderSucceed(channel, handler, CLIENT_KEY1); 191 // Calling enabling responder with the same key should succeed. 192 sendEnableResponderSucceed(channel, handler, CLIENT_KEY1); 193 } 194 195 @Test 196 public void testEnableResponderMultiClient() throws Exception { 197 startWifi(); 198 Handler handler = mock(Handler.class); 199 BidirectionalAsyncChannel channel = connectChannel(handler); 200 sendEnableResponderSucceed(channel, handler, CLIENT_KEY1); 201 sendEnableResponderSucceed(channel, handler, CLIENT_KEY2); 202 // Native method should be called only once when multiple clients enabled responder. 203 verify(mWifiNative, times(1)).enableRttResponder(anyInt()); 204 } 205 206 @Test 207 public void testDisableResponderSuccess() throws Exception { 208 startWifi(); 209 Handler handler = mock(Handler.class); 210 BidirectionalAsyncChannel channel = connectChannel(handler); 211 sendEnableResponderSucceed(channel, handler, CLIENT_KEY1); 212 // Disable after successfully enabling. 213 sendDisableResponder(channel, CLIENT_KEY1, false); 214 verify(mWifiNative).disableRttResponder(); 215 } 216 217 /** 218 * Enable responder failed because of internal error. 219 */ 220 @Test 221 public void testEnableResponderFailure() throws Exception { 222 startWifi(); 223 Handler handler = mock(Handler.class); 224 when(mWifiNative.enableRttResponder(anyInt())).thenReturn(null); 225 BidirectionalAsyncChannel channel = connectChannel(handler); 226 // Disable failed. 227 sendEnableResponderFailed(channel, handler, CLIENT_KEY1, RttManager.REASON_UNSPECIFIED); 228 } 229 230 @Test 231 public void testDisableResponderNotStarted() throws Exception { 232 startWifi(); 233 Handler handler = mock(Handler.class); 234 BidirectionalAsyncChannel channel = connectChannel(handler); 235 // Disable without enabling should fail. 236 sendDisableResponder(channel, CLIENT_KEY1, false); 237 // Native disable method shouldn't be called. 238 verifyNoMoreInteractions(mWifiNative); 239 } 240 241 @Test 242 public void testDisableResponderMultiClient() throws Exception { 243 startWifi(); 244 Handler handler = mock(Handler.class); 245 BidirectionalAsyncChannel channel = connectChannel(handler); 246 sendEnableResponderSucceed(channel, handler, CLIENT_KEY1); 247 sendEnableResponderSucceed(channel, handler, CLIENT_KEY2); 248 // Two clients enabled, one client disabled. 249 sendDisableResponder(channel, CLIENT_KEY1, true); 250 verify(mWifiNative, times(1)).getMacAddress(); 251 verifyNoMoreInteractions(mWifiNative); 252 } 253 254 /** 255 * Enable responder failed because wifi is not enabled. 256 */ 257 @Test 258 public void testEnableResponderFailedWifiDisabled() throws Exception { 259 Handler handler = mock(Handler.class); 260 BidirectionalAsyncChannel channel = connectChannel(handler); 261 // Wifi is disabled as startWifi() is not invoked. 262 sendEnableResponderFailed(channel, handler, CLIENT_KEY1, RttManager.REASON_NOT_AVAILABLE); 263 verifyNoMoreInteractions(mWifiNative); 264 } 265 266 /** 267 * Test RTT ranging with empty RttParams. 268 */ 269 @Test 270 public void testInitiatorEmptyParams() throws Exception { 271 startWifi(); 272 Handler handler = mock(Handler.class); 273 BidirectionalAsyncChannel channel = connectChannel(handler); 274 sendRangingRequestFailed(channel, handler, CLIENT_KEY1, new ParcelableRttParams(null)); 275 } 276} 277