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
17package com.android.bluetooth.mapclient;
18
19import android.bluetooth.BluetoothAdapter;
20import android.bluetooth.BluetoothDevice;
21import android.content.Context;
22import android.support.test.InstrumentationRegistry;
23import android.support.test.filters.MediumTest;
24import android.support.test.rule.ServiceTestRule;
25import android.support.test.runner.AndroidJUnit4;
26
27import com.android.bluetooth.R;
28import com.android.bluetooth.TestUtils;
29import com.android.bluetooth.btservice.AdapterService;
30
31import org.junit.After;
32import org.junit.Assert;
33import org.junit.Assume;
34import org.junit.Before;
35import org.junit.Rule;
36import org.junit.Test;
37import org.junit.runner.RunWith;
38import org.mockito.Mock;
39import org.mockito.MockitoAnnotations;
40
41import java.util.ArrayList;
42import java.util.List;
43import java.util.Map;
44
45@MediumTest
46@RunWith(AndroidJUnit4.class)
47public class MapClientTest {
48    private static final String TAG = MapClientTest.class.getSimpleName();
49    private MapClientService mService = null;
50    private BluetoothAdapter mAdapter = null;
51    private Context mTargetContext;
52
53    @Mock private AdapterService mAdapterService;
54    @Mock private MnsService mMockMnsService;
55
56    @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();
57
58    @Before
59    public void setUp() throws Exception {
60        mTargetContext = InstrumentationRegistry.getTargetContext();
61        Assume.assumeTrue("Ignore test when MapClientService is not enabled",
62                mTargetContext.getResources().getBoolean(R.bool.profile_supported_mapmce));
63        MockitoAnnotations.initMocks(this);
64        TestUtils.setAdapterService(mAdapterService);
65        MapUtils.setMnsService(mMockMnsService);
66        TestUtils.startService(mServiceRule, MapClientService.class);
67        mService = MapClientService.getMapClientService();
68        Assert.assertNotNull(mService);
69        cleanUpInstanceMap();
70        mAdapter = BluetoothAdapter.getDefaultAdapter();
71    }
72
73    @After
74    public void tearDown() throws Exception {
75        if (!mTargetContext.getResources().getBoolean(R.bool.profile_supported_mapmce)) {
76            return;
77        }
78        TestUtils.stopService(mServiceRule, MapClientService.class);
79        mService = MapClientService.getMapClientService();
80        Assert.assertNull(mService);
81        TestUtils.clearAdapterService(mAdapterService);
82    }
83
84    private void cleanUpInstanceMap() {
85        if (!mService.getInstanceMap().isEmpty()) {
86            List<BluetoothDevice> deviceList = mService.getConnectedDevices();
87            for (BluetoothDevice d : deviceList) {
88                mService.disconnect(d);
89            }
90        }
91        Assert.assertTrue(mService.getInstanceMap().isEmpty());
92    }
93
94    @Test
95    public void testInitialize() {
96        Assert.assertNotNull(MapClientService.getMapClientService());
97    }
98
99    /**
100     * Test connection of one device.
101     */
102    @Test
103    public void testConnect() {
104        // make sure there is no statemachine already defined for this device
105        BluetoothDevice device = makeBluetoothDevice("11:11:11:11:11:11");
106        Assert.assertNull(mService.getInstanceMap().get(device));
107
108        // connect a bluetooth device
109        Assert.assertTrue(mService.connect(device));
110
111        // is the statemachine created
112        Map<BluetoothDevice, MceStateMachine> map = mService.getInstanceMap();
113        Assert.assertEquals(1, map.size());
114        Assert.assertNotNull(map.get(device));
115    }
116
117    /**
118     * Test connecting MAXIMUM_CONNECTED_DEVICES devices.
119     */
120    @Test
121    public void testConnectMaxDevices() {
122        // Create bluetoothdevice & mock statemachine objects to be used in this test
123        List<BluetoothDevice> list = new ArrayList<>();
124        String address = "11:11:11:11:11:1";
125        for (int i = 0; i < MapClientService.MAXIMUM_CONNECTED_DEVICES; ++i) {
126            list.add(makeBluetoothDevice(address + i));
127        }
128
129        // make sure there is no statemachine already defined for the devices defined above
130        for (BluetoothDevice d : list) {
131            Assert.assertNull(mService.getInstanceMap().get(d));
132        }
133
134        // run the test - connect all devices
135        for (BluetoothDevice d : list) {
136            Assert.assertTrue(mService.connect(d));
137        }
138
139        // verify
140        Map<BluetoothDevice, MceStateMachine> map = mService.getInstanceMap();
141        Assert.assertEquals(MapClientService.MAXIMUM_CONNECTED_DEVICES, map.size());
142        for (BluetoothDevice d : list) {
143            Assert.assertNotNull(map.get(d));
144        }
145
146        // Try to connect one more device. Should fail.
147        BluetoothDevice last = makeBluetoothDevice("11:22:33:44:55:66");
148        Assert.assertFalse(mService.connect(last));
149    }
150
151    private BluetoothDevice makeBluetoothDevice(String address) {
152        return mAdapter.getRemoteDevice(address);
153    }
154}
155