• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.server.wifi.aware;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertTrue;
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyBoolean;
23 import static org.mockito.ArgumentMatchers.anyInt;
24 import static org.mockito.ArgumentMatchers.anyString;
25 import static org.mockito.ArgumentMatchers.eq;
26 import static org.mockito.Mockito.doNothing;
27 import static org.mockito.Mockito.doThrow;
28 import static org.mockito.Mockito.inOrder;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
32 
33 import android.Manifest;
34 import android.app.AppOpsManager;
35 import android.content.Context;
36 import android.content.pm.PackageManager;
37 import android.net.wifi.aware.Characteristics;
38 import android.net.wifi.aware.ConfigRequest;
39 import android.net.wifi.aware.IWifiAwareDiscoverySessionCallback;
40 import android.net.wifi.aware.IWifiAwareEventCallback;
41 import android.net.wifi.aware.IWifiAwareMacAddressProvider;
42 import android.net.wifi.aware.PublishConfig;
43 import android.net.wifi.aware.SubscribeConfig;
44 import android.os.HandlerThread;
45 import android.os.IBinder;
46 import android.os.RemoteException;
47 import android.os.test.TestLooper;
48 import android.util.SparseArray;
49 import android.util.SparseIntArray;
50 
51 import androidx.test.filters.SmallTest;
52 
53 import com.android.server.wifi.FrameworkFacade;
54 import com.android.server.wifi.util.WifiPermissionsUtil;
55 import com.android.server.wifi.util.WifiPermissionsWrapper;
56 
57 import org.junit.Before;
58 import org.junit.Test;
59 import org.mockito.ArgumentCaptor;
60 import org.mockito.InOrder;
61 import org.mockito.Mock;
62 import org.mockito.MockitoAnnotations;
63 
64 import java.lang.reflect.Field;
65 import java.util.ArrayList;
66 import java.util.List;
67 import java.util.Map;
68 
69 
70 /**
71  * Unit test harness for WifiAwareStateManager.
72  */
73 @SmallTest
74 public class WifiAwareServiceImplTest {
75     private static final int MAX_LENGTH = 255;
76 
77     private WifiAwareServiceImplSpy mDut;
78     private int mDefaultUid = 1500;
79     private String mPackageName = "some.package";
80     private TestLooper mMockLooper;
81 
82     @Mock
83     private Context mContextMock;
84     @Mock
85     private HandlerThread mHandlerThreadMock;
86     @Mock
87     private PackageManager mPackageManagerMock;
88     @Mock
89     private WifiAwareStateManager mAwareStateManagerMock;
90     @Mock
91     private WifiAwareShellCommand mWifiAwareShellCommandMock;
92     @Mock
93     private IBinder mBinderMock;
94     @Mock
95     private IWifiAwareEventCallback mCallbackMock;
96     @Mock
97     private IWifiAwareDiscoverySessionCallback mSessionCallbackMock;
98     @Mock private WifiAwareMetrics mAwareMetricsMock;
99     @Mock private WifiPermissionsUtil mWifiPermissionsUtil;
100     @Mock private WifiPermissionsWrapper mPermissionsWrapperMock;
101     @Mock
102     FrameworkFacade mFrameworkFacade;
103 
104     /**
105      * Using instead of spy to avoid native crash failures - possibly due to
106      * spy's copying of state.
107      */
108     private class WifiAwareServiceImplSpy extends WifiAwareServiceImpl {
109         public int fakeUid;
110 
WifiAwareServiceImplSpy(Context context)111         WifiAwareServiceImplSpy(Context context) {
112             super(context);
113         }
114 
115         /**
116          * Return the fake UID instead of the real one: pseudo-spy
117          * implementation.
118          */
119         @Override
getMockableCallingUid()120         public int getMockableCallingUid() {
121             return fakeUid;
122         }
123     }
124 
125     /**
126      * Initializes mocks.
127      */
128     @Before
setup()129     public void setup() throws Exception {
130         MockitoAnnotations.initMocks(this);
131         mMockLooper = new TestLooper();
132 
133         when(mHandlerThreadMock.getLooper()).thenReturn(mMockLooper.getLooper());
134         doNothing().when(mFrameworkFacade).registerContentObserver(eq(mContextMock), any(),
135                 anyBoolean(), any());
136 
137         AppOpsManager appOpsMock = mock(AppOpsManager.class);
138         when(mContextMock.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(appOpsMock);
139 
140         when(mContextMock.getApplicationContext()).thenReturn(mContextMock);
141         when(mContextMock.getPackageManager()).thenReturn(mPackageManagerMock);
142         when(mPackageManagerMock.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE))
143                 .thenReturn(true);
144         when(mPackageManagerMock.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT))
145                 .thenReturn(true);
146         when(mAwareStateManagerMock.getCharacteristics()).thenReturn(getCharacteristics());
147 
148         mDut = new WifiAwareServiceImplSpy(mContextMock);
149         mDut.fakeUid = mDefaultUid;
150         mDut.start(mHandlerThreadMock, mAwareStateManagerMock, mWifiAwareShellCommandMock,
151                 mAwareMetricsMock, mWifiPermissionsUtil, mPermissionsWrapperMock, mFrameworkFacade,
152                 mock(WifiAwareNativeManager.class), mock(WifiAwareNativeApi.class),
153                 mock(WifiAwareNativeCallback.class));
154         verify(mAwareStateManagerMock).start(eq(mContextMock), any(), eq(mAwareMetricsMock),
155                 eq(mWifiPermissionsUtil), eq(mPermissionsWrapperMock), any());
156     }
157 
158     /**
159      * Validate isUsageEnabled() function
160      */
161     @Test
testIsUsageEnabled()162     public void testIsUsageEnabled() {
163         mDut.isUsageEnabled();
164 
165         verify(mAwareStateManagerMock).isUsageEnabled();
166     }
167 
168 
169     /**
170      * Validate connect() - returns and uses a client ID.
171      */
172     @Test
testConnect()173     public void testConnect() {
174         doConnect();
175     }
176 
177     /**
178      * Validate connect() when a non-null config is passed.
179      */
180     @Test
testConnectWithConfig()181     public void testConnectWithConfig() {
182         ConfigRequest configRequest = new ConfigRequest.Builder().setMasterPreference(55).build();
183         String callingPackage = "com.google.somePackage";
184 
185         mDut.connect(mBinderMock, callingPackage, mCallbackMock,
186                 configRequest, false);
187 
188         verify(mAwareStateManagerMock).connect(anyInt(), anyInt(), anyInt(),
189                 eq(callingPackage), eq(mCallbackMock), eq(configRequest), eq(false));
190     }
191 
192     /**
193      * Validate disconnect() - correct pass-through args.
194      *
195      * @throws Exception
196      */
197     @Test
testDisconnect()198     public void testDisconnect() throws Exception {
199         int clientId = doConnect();
200 
201         mDut.disconnect(clientId, mBinderMock);
202 
203         verify(mAwareStateManagerMock).disconnect(clientId);
204         validateInternalStateCleanedUp(clientId);
205     }
206 
207     /**
208      * Validate that security exception thrown when attempting operation using
209      * an invalid client ID.
210      */
211     @Test(expected = SecurityException.class)
testFailOnInvalidClientId()212     public void testFailOnInvalidClientId() {
213         mDut.disconnect(-1, mBinderMock);
214     }
215 
216     /**
217      * Validate that security exception thrown when attempting operation using a
218      * client ID which was already cleared-up.
219      */
220     @Test(expected = SecurityException.class)
testFailOnClearedUpClientId()221     public void testFailOnClearedUpClientId() throws Exception {
222         int clientId = doConnect();
223 
224         mDut.disconnect(clientId, mBinderMock);
225 
226         verify(mAwareStateManagerMock).disconnect(clientId);
227         validateInternalStateCleanedUp(clientId);
228 
229         mDut.disconnect(clientId, mBinderMock);
230     }
231 
232     /**
233      * Validate that trying to use a client ID from a UID which is different
234      * from the one that created it fails - and that the internal state is not
235      * modified so that a valid call (from the correct UID) will subsequently
236      * succeed.
237      */
238     @Test
testFailOnAccessClientIdFromWrongUid()239     public void testFailOnAccessClientIdFromWrongUid() throws Exception {
240         int clientId = doConnect();
241 
242         mDut.fakeUid = mDefaultUid + 1;
243 
244         /*
245          * Not using thrown.expect(...) since want to test that subsequent
246          * access works.
247          */
248         boolean failsAsExpected = false;
249         try {
250             mDut.disconnect(clientId, mBinderMock);
251         } catch (SecurityException e) {
252             failsAsExpected = true;
253         }
254 
255         mDut.fakeUid = mDefaultUid;
256 
257         PublishConfig publishConfig = new PublishConfig.Builder().setServiceName("valid.value")
258                 .build();
259         mDut.publish(mPackageName, clientId, publishConfig, mSessionCallbackMock);
260 
261         verify(mAwareStateManagerMock).publish(clientId, publishConfig, mSessionCallbackMock);
262         assertTrue("SecurityException for invalid access from wrong UID thrown", failsAsExpected);
263     }
264 
265     /**
266      * Validate that the RTT feature support is checked when attempting a Publish with ranging.
267      */
268     @Test(expected = IllegalArgumentException.class)
testFailOnPublishRangingWithoutRttFeature()269     public void testFailOnPublishRangingWithoutRttFeature() throws Exception {
270         when(mPackageManagerMock.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)).thenReturn(
271                 false);
272 
273         PublishConfig publishConfig = new PublishConfig.Builder().setServiceName("something.valid")
274                 .setRangingEnabled(true).build();
275         int clientId = doConnect();
276         IWifiAwareDiscoverySessionCallback mockCallback = mock(
277                 IWifiAwareDiscoverySessionCallback.class);
278 
279         mDut.publish(mPackageName, clientId, publishConfig, mockCallback);
280     }
281 
282     /**
283      * Validate that the RTT feature support is checked when attempting a Subscribe with ranging.
284      */
285     @Test(expected = IllegalArgumentException.class)
testFailOnSubscribeRangingWithoutRttFeature()286     public void testFailOnSubscribeRangingWithoutRttFeature() throws Exception {
287         when(mPackageManagerMock.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT)).thenReturn(
288                 false);
289 
290         SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(
291                 "something.valid").setMaxDistanceMm(100).build();
292         int clientId = doConnect();
293         IWifiAwareDiscoverySessionCallback mockCallback = mock(
294                 IWifiAwareDiscoverySessionCallback.class);
295 
296         mDut.subscribe(mPackageName, clientId, subscribeConfig, mockCallback);
297     }
298 
299 
300     /**
301      * Validates that on binder death we get a disconnect().
302      */
303     @Test
testBinderDeath()304     public void testBinderDeath() throws Exception {
305         ArgumentCaptor<IBinder.DeathRecipient> deathRecipient = ArgumentCaptor
306                 .forClass(IBinder.DeathRecipient.class);
307 
308         int clientId = doConnect();
309 
310         verify(mBinderMock).linkToDeath(deathRecipient.capture(), eq(0));
311         deathRecipient.getValue().binderDied();
312         verify(mAwareStateManagerMock).disconnect(clientId);
313         validateInternalStateCleanedUp(clientId);
314     }
315 
316     /**
317      * Validates that sequential connect() calls return increasing client IDs.
318      */
319     @Test
testClientIdIncrementing()320     public void testClientIdIncrementing() {
321         int loopCount = 100;
322 
323         InOrder inOrder = inOrder(mAwareStateManagerMock);
324         ArgumentCaptor<Integer> clientIdCaptor = ArgumentCaptor.forClass(Integer.class);
325 
326         int prevId = 0;
327         for (int i = 0; i < loopCount; ++i) {
328             mDut.connect(mBinderMock, "", mCallbackMock, null, false);
329             inOrder.verify(mAwareStateManagerMock).connect(clientIdCaptor.capture(), anyInt(),
330                     anyInt(), any(), eq(mCallbackMock), any(), eq(false));
331             int id = clientIdCaptor.getValue();
332             if (i != 0) {
333                 assertTrue("Client ID incrementing", id > prevId);
334             }
335             prevId = id;
336         }
337     }
338 
339     /**
340      * Validate terminateSession() - correct pass-through args.
341      */
342     @Test
testTerminateSession()343     public void testTerminateSession() {
344         int sessionId = 1024;
345         int clientId = doConnect();
346 
347         mDut.terminateSession(clientId, sessionId);
348 
349         verify(mAwareStateManagerMock).terminateSession(clientId, sessionId);
350     }
351 
352     /**
353      * Validate publish() - correct pass-through args.
354      */
355     @Test
testPublish()356     public void testPublish() {
357         PublishConfig publishConfig = new PublishConfig.Builder().setServiceName("something.valid")
358                 .setRangingEnabled(true).build();
359         int clientId = doConnect();
360         IWifiAwareDiscoverySessionCallback mockCallback = mock(
361                 IWifiAwareDiscoverySessionCallback.class);
362 
363         mDut.publish(mPackageName, clientId, publishConfig, mockCallback);
364 
365         verify(mAwareStateManagerMock).publish(clientId, publishConfig, mockCallback);
366     }
367 
368     /**
369      * Validate that publish() verifies the input PublishConfig and fails on an invalid service
370      * name.
371      */
372     @Test(expected = IllegalArgumentException.class)
testPublishInvalidServiceName()373     public void testPublishInvalidServiceName() {
374         doBadPublishConfiguration("Including invalid characters - spaces", null, null);
375     }
376 
377     /**
378      * Validate that publish() verifies the input PublishConfig and fails on a "very long"
379      * service name.
380      */
381     @Test(expected = IllegalArgumentException.class)
testPublishServiceNameTooLong()382     public void testPublishServiceNameTooLong() {
383         byte[] byteArray = new byte[MAX_LENGTH + 1];
384         for (int i = 0; i < MAX_LENGTH + 1; ++i) {
385             byteArray[i] = 'a';
386         }
387         doBadPublishConfiguration(new String(byteArray), null, null);
388     }
389 
390     /**
391      * Validate that publish() verifies the input PublishConfig and fails on a "very long" ssi.
392      */
393     @Test(expected = IllegalArgumentException.class)
testPublishSsiTooLong()394     public void testPublishSsiTooLong() {
395         doBadPublishConfiguration("correctservicename", new byte[MAX_LENGTH + 1], null);
396     }
397 
398     /**
399      * Validate that publish() verifies the input PublishConfig and fails on a "very long" match
400      * filter.
401      */
402     @Test(expected = IllegalArgumentException.class)
testPublishMatchFilterTooLong()403     public void testPublishMatchFilterTooLong() {
404         doBadPublishConfiguration("correctservicename", null, new byte[MAX_LENGTH + 1]);
405     }
406 
407     /**
408      * Validate that publish() verifies the input PublishConfig and fails on a bad match filter -
409      * invalid LV.
410      */
411     @Test(expected = IllegalArgumentException.class)
testPublishMatchFilterBadLv()412     public void testPublishMatchFilterBadLv() {
413         byte[] badLv = { 0, 1, 127, 2, 126, 125, 3 };
414         doBadPublishConfiguration("correctservicename", null, badLv);
415     }
416 
417     /**
418      * Validate updatePublish() - correct pass-through args.
419      */
420     @Test
testUpdatePublish()421     public void testUpdatePublish() {
422         int sessionId = 1232;
423         PublishConfig publishConfig = new PublishConfig.Builder().setServiceName("something.valid")
424                 .build();
425         int clientId = doConnect();
426 
427         mDut.updatePublish(clientId, sessionId, publishConfig);
428 
429         verify(mAwareStateManagerMock).updatePublish(clientId, sessionId, publishConfig);
430     }
431 
432     /**
433      * Validate updatePublish() error checking.
434      */
435     @Test(expected = IllegalArgumentException.class)
testUpdatePublishInvalid()436     public void testUpdatePublishInvalid() {
437         int sessionId = 1232;
438         PublishConfig publishConfig = new PublishConfig.Builder()
439                 .setServiceName("something with spaces").build();
440         int clientId = doConnect();
441 
442         mDut.updatePublish(clientId, sessionId, publishConfig);
443 
444         verify(mAwareStateManagerMock).updatePublish(clientId, sessionId, publishConfig);
445     }
446 
447     /**
448      * Validate subscribe() - correct pass-through args.
449      */
450     @Test
testSubscribe()451     public void testSubscribe() {
452         SubscribeConfig subscribeConfig = new SubscribeConfig.Builder()
453                 .setServiceName("something.valid").setMaxDistanceMm(100).build();
454         int clientId = doConnect();
455         IWifiAwareDiscoverySessionCallback mockCallback = mock(
456                 IWifiAwareDiscoverySessionCallback.class);
457 
458         mDut.subscribe(mPackageName, clientId, subscribeConfig, mockCallback);
459 
460         verify(mAwareStateManagerMock).subscribe(clientId, subscribeConfig, mockCallback);
461     }
462 
463     /**
464      * Validate that subscribe() verifies the input SubscribeConfig and fails on an invalid service
465      * name.
466      */
467     @Test(expected = IllegalArgumentException.class)
testSubscribeInvalidServiceName()468     public void testSubscribeInvalidServiceName() {
469         doBadSubscribeConfiguration("Including invalid characters - spaces", null, null);
470     }
471 
472     /**
473      * Validate that subscribe() verifies the input SubscribeConfig and fails on a "very long"
474      * service name.
475      */
476     @Test(expected = IllegalArgumentException.class)
testSubscribeServiceNameTooLong()477     public void testSubscribeServiceNameTooLong() {
478         byte[] byteArray = new byte[MAX_LENGTH + 1];
479         for (int i = 0; i < MAX_LENGTH + 1; ++i) {
480             byteArray[i] = 'a';
481         }
482         doBadSubscribeConfiguration(new String(byteArray), null, null);
483     }
484 
485     /**
486      * Validate that subscribe() verifies the input SubscribeConfig and fails on a "very long" ssi.
487      */
488     @Test(expected = IllegalArgumentException.class)
testSubscribeSsiTooLong()489     public void testSubscribeSsiTooLong() {
490         doBadSubscribeConfiguration("correctservicename", new byte[MAX_LENGTH + 1], null);
491     }
492 
493     /**
494      * Validate that subscribe() verifies the input SubscribeConfig and fails on a "very long" match
495      * filter.
496      */
497     @Test(expected = IllegalArgumentException.class)
testSubscribeMatchFilterTooLong()498     public void testSubscribeMatchFilterTooLong() {
499         doBadSubscribeConfiguration("correctservicename", null, new byte[MAX_LENGTH + 1]);
500     }
501 
502     /**
503      * Validate that subscribe() verifies the input SubscribeConfig and fails on a bad match filter
504      * - invalid LV.
505      */
506     @Test(expected = IllegalArgumentException.class)
testSubscribeMatchFilterBadLv()507     public void testSubscribeMatchFilterBadLv() {
508         byte[] badLv = { 0, 1, 127, 2, 126, 125, 3 };
509         doBadSubscribeConfiguration("correctservicename", null, badLv);
510     }
511 
512     /**
513      * Validate updateSubscribe() error checking.
514      */
515     @Test(expected = IllegalArgumentException.class)
testUpdateSubscribeInvalid()516     public void testUpdateSubscribeInvalid() {
517         int sessionId = 1232;
518         SubscribeConfig subscribeConfig = new SubscribeConfig.Builder()
519                 .setServiceName("something.valid")
520                 .setServiceSpecificInfo(new byte[MAX_LENGTH + 1]).build();
521         int clientId = doConnect();
522 
523         mDut.updateSubscribe(clientId, sessionId, subscribeConfig);
524 
525         verify(mAwareStateManagerMock).updateSubscribe(clientId, sessionId, subscribeConfig);
526     }
527 
528     /**
529      * Validate updateSubscribe() validates configuration.
530      */
531     @Test
testUpdateSubscribe()532     public void testUpdateSubscribe() {
533         int sessionId = 1232;
534         SubscribeConfig subscribeConfig = new SubscribeConfig.Builder()
535                 .setServiceName("something.valid").build();
536         int clientId = doConnect();
537 
538         mDut.updateSubscribe(clientId, sessionId, subscribeConfig);
539 
540         verify(mAwareStateManagerMock).updateSubscribe(clientId, sessionId, subscribeConfig);
541     }
542 
543     /**
544      * Validate sendMessage() - correct pass-through args.
545      */
546     @Test
testSendMessage()547     public void testSendMessage() {
548         int sessionId = 2394;
549         int peerId = 2032;
550         byte[] message = new byte[MAX_LENGTH];
551         int messageId = 2043;
552         int clientId = doConnect();
553 
554         mDut.sendMessage(clientId, sessionId, peerId, message, messageId, 0);
555 
556         verify(mAwareStateManagerMock).sendMessage(clientId, sessionId, peerId, message, messageId,
557                 0);
558     }
559 
560     /**
561      * Validate sendMessage() validates that message length is correct.
562      */
563     @Test(expected = IllegalArgumentException.class)
testSendMessageTooLong()564     public void testSendMessageTooLong() {
565         int sessionId = 2394;
566         int peerId = 2032;
567         byte[] message = new byte[MAX_LENGTH + 1];
568         int messageId = 2043;
569         int clientId = doConnect();
570 
571         mDut.sendMessage(clientId, sessionId, peerId, message, messageId, 0);
572 
573         verify(mAwareStateManagerMock).sendMessage(clientId, sessionId, peerId, message, messageId,
574                 0);
575     }
576 
577     @Test
testRequestMacAddress()578     public void testRequestMacAddress() {
579         int uid = 1005;
580         List<Integer> list = new ArrayList<>();
581         IWifiAwareMacAddressProvider callback = new IWifiAwareMacAddressProvider() { // dummy
582             @Override
583             public void macAddress(Map peerIdToMacMap) throws RemoteException {
584                 // empty
585             }
586 
587             @Override
588             public IBinder asBinder() {
589                 return null;
590             }
591         };
592 
593         mDut.requestMacAddresses(uid, list, callback);
594 
595         verify(mAwareStateManagerMock).requestMacAddresses(uid, list, callback);
596     }
597 
598     @Test(expected = SecurityException.class)
testRequestMacAddressWithoutPermission()599     public void testRequestMacAddressWithoutPermission() {
600         doThrow(new SecurityException()).when(mContextMock).enforceCallingOrSelfPermission(
601                 eq(Manifest.permission.NETWORK_STACK), anyString());
602 
603         mDut.requestMacAddresses(1005, new ArrayList<>(), new IWifiAwareMacAddressProvider() {
604             @Override
605             public void macAddress(Map peerIdToMacMap) throws RemoteException {
606             }
607 
608             @Override
609             public IBinder asBinder() {
610                 return null;
611             }
612         });
613     }
614 
615     /*
616      * Utilities
617      */
618 
619     /*
620      * Tests of internal state of WifiAwareServiceImpl: very limited (not usually
621      * a good idea). However, these test that the internal state is cleaned-up
622      * appropriately. Alternatively would cause issues with memory leaks or
623      * information leak between sessions.
624      */
validateInternalStateCleanedUp(int clientId)625     private void validateInternalStateCleanedUp(int clientId) throws Exception {
626         int uidEntry = getInternalStateUid(clientId);
627         assertEquals(-1, uidEntry);
628 
629         IBinder.DeathRecipient dr = getInternalStateDeathRecipient(clientId);
630         assertEquals(null, dr);
631     }
632 
doBadPublishConfiguration(String serviceName, byte[] ssi, byte[] matchFilter)633     private void doBadPublishConfiguration(String serviceName, byte[] ssi, byte[] matchFilter)
634             throws IllegalArgumentException {
635         // using the hidden constructor since may be passing invalid parameters which would be
636         // caught by the Builder. Want to test whether service side will catch invalidly
637         // constructed configs.
638         PublishConfig publishConfig = new PublishConfig(serviceName.getBytes(), ssi, matchFilter,
639                 PublishConfig.PUBLISH_TYPE_UNSOLICITED, 0, true, false);
640         int clientId = doConnect();
641         IWifiAwareDiscoverySessionCallback mockCallback = mock(
642                 IWifiAwareDiscoverySessionCallback.class);
643 
644         mDut.publish(mPackageName, clientId, publishConfig, mockCallback);
645 
646         verify(mAwareStateManagerMock).publish(clientId, publishConfig, mockCallback);
647     }
648 
doBadSubscribeConfiguration(String serviceName, byte[] ssi, byte[] matchFilter)649     private void doBadSubscribeConfiguration(String serviceName, byte[] ssi, byte[] matchFilter)
650             throws IllegalArgumentException {
651         // using the hidden constructor since may be passing invalid parameters which would be
652         // caught by the Builder. Want to test whether service side will catch invalidly
653         // constructed configs.
654         SubscribeConfig subscribeConfig = new SubscribeConfig(serviceName.getBytes(), ssi,
655                 matchFilter, SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE, 0, true, false, 0, false, 0);
656         int clientId = doConnect();
657         IWifiAwareDiscoverySessionCallback mockCallback = mock(
658                 IWifiAwareDiscoverySessionCallback.class);
659 
660         mDut.subscribe(mPackageName, clientId, subscribeConfig, mockCallback);
661 
662         verify(mAwareStateManagerMock).subscribe(clientId, subscribeConfig, mockCallback);
663     }
664 
doConnect()665     private int doConnect() {
666         String callingPackage = "com.google.somePackage";
667 
668         mDut.connect(mBinderMock, callingPackage, mCallbackMock, null, false);
669 
670         ArgumentCaptor<Integer> clientId = ArgumentCaptor.forClass(Integer.class);
671         verify(mAwareStateManagerMock).connect(clientId.capture(), anyInt(), anyInt(),
672                 eq(callingPackage), eq(mCallbackMock), eq(new ConfigRequest.Builder().build()),
673                 eq(false));
674 
675         return clientId.getValue();
676     }
677 
getCharacteristics()678     private static Characteristics getCharacteristics() {
679         Capabilities cap = new Capabilities();
680         cap.maxConcurrentAwareClusters = 1;
681         cap.maxPublishes = 2;
682         cap.maxSubscribes = 2;
683         cap.maxServiceNameLen = MAX_LENGTH;
684         cap.maxMatchFilterLen = MAX_LENGTH;
685         cap.maxTotalMatchFilterLen = 255;
686         cap.maxServiceSpecificInfoLen = MAX_LENGTH;
687         cap.maxExtendedServiceSpecificInfoLen = MAX_LENGTH;
688         cap.maxNdiInterfaces = 1;
689         cap.maxNdpSessions = 1;
690         cap.maxAppInfoLen = 255;
691         cap.maxQueuedTransmitMessages = 6;
692         return cap.toPublicCharacteristics();
693     }
694 
getInternalStateUid(int clientId)695     private int getInternalStateUid(int clientId) throws Exception {
696         Field field = WifiAwareServiceImpl.class.getDeclaredField("mUidByClientId");
697         field.setAccessible(true);
698         @SuppressWarnings("unchecked")
699         SparseIntArray uidByClientId = (SparseIntArray) field.get(mDut);
700 
701         return uidByClientId.get(clientId, -1);
702     }
703 
getInternalStateDeathRecipient(int clientId)704     private IBinder.DeathRecipient getInternalStateDeathRecipient(int clientId) throws Exception {
705         Field field = WifiAwareServiceImpl.class.getDeclaredField("mDeathRecipientsByClientId");
706         field.setAccessible(true);
707         @SuppressWarnings("unchecked")
708         SparseArray<IBinder.DeathRecipient> deathRecipientsByClientId =
709                             (SparseArray<IBinder.DeathRecipient>) field.get(mDut);
710 
711         return deathRecipientsByClientId.get(clientId);
712     }
713 }
714