• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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.bluetooth.opp;
18 
19 import static androidx.test.espresso.intent.Intents.intended;
20 import static androidx.test.espresso.intent.Intents.intending;
21 import static androidx.test.espresso.intent.matcher.IntentMatchers.anyIntent;
22 import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent;
23 
24 import static com.android.bluetooth.opp.BluetoothOppManager.ALLOWED_INSERT_SHARE_THREAD_NUMBER;
25 import static com.android.bluetooth.opp.BluetoothOppManager.OPP_PREFERENCE_FILE;
26 
27 import static com.google.common.truth.Truth.assertThat;
28 
29 import static org.mockito.Mockito.any;
30 import static org.mockito.Mockito.doReturn;
31 import static org.mockito.Mockito.eq;
32 import static org.mockito.Mockito.nullable;
33 import static org.mockito.Mockito.spy;
34 import static org.mockito.Mockito.timeout;
35 import static org.mockito.Mockito.verify;
36 
37 import android.bluetooth.BluetoothDevice;
38 import android.bluetooth.BluetoothManager;
39 import android.content.ContentValues;
40 import android.content.Context;
41 import android.content.ContextWrapper;
42 import android.net.Uri;
43 import android.util.Log;
44 
45 import androidx.test.espresso.intent.Intents;
46 import androidx.test.platform.app.InstrumentationRegistry;
47 import androidx.test.runner.AndroidJUnit4;
48 
49 import com.android.bluetooth.BluetoothMethodProxy;
50 
51 import org.junit.After;
52 import org.junit.Before;
53 import org.junit.Ignore;
54 import org.junit.Test;
55 import org.junit.runner.RunWith;
56 import org.mockito.MockitoAnnotations;
57 
58 import java.util.ArrayList;
59 import java.util.List;
60 import java.util.concurrent.atomic.AtomicBoolean;
61 
62 @RunWith(AndroidJUnit4.class)
63 public class BluetoothOppManagerTest {
64     Context mContext;
65 
66     BluetoothMethodProxy mCallProxy;
67 
68     @Before
setUp()69     public void setUp() {
70         MockitoAnnotations.initMocks(this);
71         mContext = spy(new ContextWrapper(
72                 InstrumentationRegistry.getInstrumentation().getTargetContext()));
73 
74         mCallProxy = spy(BluetoothMethodProxy.getInstance());
75         BluetoothMethodProxy.setInstanceForTesting(mCallProxy);
76 
77         doReturn(null).when(mCallProxy).contentResolverInsert(
78                 any(), eq(BluetoothShare.CONTENT_URI), any());
79 
80         Intents.init();
81     }
82 
83     @After
tearDown()84     public void tearDown() {
85         BluetoothMethodProxy.setInstanceForTesting(null);
86         BluetoothOppUtility.sSendFileMap.clear();
87         mContext.getSharedPreferences(OPP_PREFERENCE_FILE, 0).edit().clear().apply();
88         BluetoothOppManager.sInstance = null;
89 
90         Intents.release();
91     }
92 
93     @Test
94     public void
restoreApplicationData_afterSavingSingleSendingFileInfo_containsSendingFileInfoSaved()95     restoreApplicationData_afterSavingSingleSendingFileInfo_containsSendingFileInfoSaved() {
96         BluetoothOppManager bluetoothOppManager = BluetoothOppManager.getInstance(mContext);
97         bluetoothOppManager.mSendingFlag = true;
98         bluetoothOppManager.saveSendingFileInfo("text/plain", "content:///abc/xyz.txt", false,
99                 true);
100 
101         BluetoothOppManager.sInstance = null;
102         BluetoothOppManager restartedBluetoothOppManager = BluetoothOppManager.getInstance(
103                 mContext);
104         assertThat(bluetoothOppManager.mSendingFlag).isEqualTo(
105                 restartedBluetoothOppManager.mSendingFlag);
106         assertThat(bluetoothOppManager.mMultipleFlag).isEqualTo(
107                 restartedBluetoothOppManager.mMultipleFlag);
108         assertThat(bluetoothOppManager.mUriOfSendingFile).isEqualTo(
109                 restartedBluetoothOppManager.mUriOfSendingFile);
110         assertThat(bluetoothOppManager.mUrisOfSendingFiles).isEqualTo(
111                 restartedBluetoothOppManager.mUrisOfSendingFiles);
112         assertThat(bluetoothOppManager.mMimeTypeOfSendingFile).isEqualTo(
113                 restartedBluetoothOppManager.mMimeTypeOfSendingFile);
114         assertThat(bluetoothOppManager.mMimeTypeOfSendingFiles).isEqualTo(
115                 restartedBluetoothOppManager.mMimeTypeOfSendingFiles);
116     }
117 
118     @Test
119     public void
restoreApplicationData_afterSavingMultipleSendingFileInfo_containsSendingFileInfoSaved()120     restoreApplicationData_afterSavingMultipleSendingFileInfo_containsSendingFileInfoSaved() {
121         BluetoothOppManager bluetoothOppManager = BluetoothOppManager.getInstance(mContext);
122         bluetoothOppManager.mSendingFlag = true;
123         bluetoothOppManager.saveSendingFileInfo("text/plain", new ArrayList<Uri>(
124                         List.of(Uri.parse("content:///abc/xyz.txt"), Uri.parse("content:///123"
125                                 + "/456.txt"))),
126                 false, true);
127 
128         BluetoothOppManager.sInstance = null;
129         BluetoothOppManager restartedBluetoothOppManager = BluetoothOppManager.getInstance(
130                 mContext);
131         assertThat(bluetoothOppManager.mSendingFlag).isEqualTo(
132                 restartedBluetoothOppManager.mSendingFlag);
133         assertThat(bluetoothOppManager.mMultipleFlag).isEqualTo(
134                 restartedBluetoothOppManager.mMultipleFlag);
135         assertThat(bluetoothOppManager.mUriOfSendingFile).isEqualTo(
136                 restartedBluetoothOppManager.mUriOfSendingFile);
137         assertThat(bluetoothOppManager.mUrisOfSendingFiles).isEqualTo(
138                 restartedBluetoothOppManager.mUrisOfSendingFiles);
139         assertThat(bluetoothOppManager.mMimeTypeOfSendingFile).isEqualTo(
140                 restartedBluetoothOppManager.mMimeTypeOfSendingFile);
141         assertThat(bluetoothOppManager.mMimeTypeOfSendingFiles).isEqualTo(
142                 restartedBluetoothOppManager.mMimeTypeOfSendingFiles);
143     }
144 
145     @Test
isAcceptedList_inAcceptList_returnsTrue()146     public void isAcceptedList_inAcceptList_returnsTrue() {
147         BluetoothOppManager bluetoothOppManager = BluetoothOppManager.getInstance(mContext);
148         String address1 = "AA:BB:CC:DD:EE:FF";
149         String address2 = "00:11:22:33:44:55";
150 
151         bluetoothOppManager.addToAcceptlist(address1);
152         bluetoothOppManager.addToAcceptlist(address2);
153         assertThat(bluetoothOppManager.isAcceptlisted(address1)).isTrue();
154         assertThat(bluetoothOppManager.isAcceptlisted(address2)).isTrue();
155     }
156 
157     @Test
isAcceptedList_notInAcceptList_returnsFalse()158     public void isAcceptedList_notInAcceptList_returnsFalse() {
159         BluetoothOppManager bluetoothOppManager = BluetoothOppManager.getInstance(mContext);
160         String address = "01:23:45:67:89:AB";
161 
162         assertThat(bluetoothOppManager.isAcceptlisted(address)).isFalse();
163 
164         bluetoothOppManager.addToAcceptlist(address);
165         assertThat(bluetoothOppManager.isAcceptlisted(address)).isTrue();
166     }
167 
168     @Test
startTransfer_withMultipleUris_contentResolverInsertMultipleTimes()169     public void startTransfer_withMultipleUris_contentResolverInsertMultipleTimes() {
170         BluetoothOppManager bluetoothOppManager = BluetoothOppManager.getInstance(mContext);
171         String address = "AA:BB:CC:DD:EE:FF";
172         bluetoothOppManager.saveSendingFileInfo("text/plain", new ArrayList<Uri>(
173                 List.of(Uri.parse("content:///abc/xyz.txt"),
174                         Uri.parse("content:///a/b/c/d/x/y/z.docs"),
175                         Uri.parse("content:///123/456.txt"))), false, true);
176         BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class))
177                 .getAdapter().getRemoteDevice(address);
178         bluetoothOppManager.startTransfer(device);
179         // add 2 files
180         verify(mCallProxy, timeout(5_000)
181                 .times(3)).contentResolverInsert(any(), nullable(Uri.class),
182                 nullable(ContentValues.class));
183     }
184 
185     @Test
startTransfer_withOneUri_contentResolverInsertOnce()186     public void startTransfer_withOneUri_contentResolverInsertOnce() {
187         BluetoothOppManager bluetoothOppManager = BluetoothOppManager.getInstance(mContext);
188         String address = "AA:BB:CC:DD:EE:FF";
189         bluetoothOppManager.saveSendingFileInfo("text/plain", "content:///abc/xyz.txt",
190                 false, true);
191         BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class))
192                 .getAdapter().getRemoteDevice(address);
193         bluetoothOppManager.startTransfer(device);
194         verify(mCallProxy, timeout(5_000).times(1)).contentResolverInsert(any(),
195                 nullable(Uri.class), nullable(ContentValues.class));
196     }
197 
198     @Ignore("b/267270055")
199     @Test
startTransferMoreThanAllowedInsertShareThreadNumberTimes_blockExceedingTransfer()200     public void startTransferMoreThanAllowedInsertShareThreadNumberTimes_blockExceedingTransfer()
201             throws InterruptedException {
202         BluetoothOppManager bluetoothOppManager = BluetoothOppManager.getInstance(mContext);
203         String address = "AA:BB:CC:DD:EE:FF";
204         bluetoothOppManager.saveSendingFileInfo("text/plain", "content:///abc/xyz.txt",
205                 false, true);
206         BluetoothDevice device = (mContext.getSystemService(BluetoothManager.class))
207                 .getAdapter().getRemoteDevice(address);
208 
209         AtomicBoolean intended = new AtomicBoolean(false);
210         intending(anyIntent()).respondWithFunction(
211                 intent -> {
212                     // verify that at least one exceeding thread is blocked
213                     intended.set(true);
214                     return null;
215                 });
216 
217         // try flushing the transferring queue,
218         for (int i = 0; i < ALLOWED_INSERT_SHARE_THREAD_NUMBER + 15; i++) {
219             bluetoothOppManager.startTransfer(device);
220         }
221 
222         // success at least ALLOWED_INSERT_SHARE_THREAD_NUMBER times
223         verify(mCallProxy,
224                 timeout(5_000).atLeast(ALLOWED_INSERT_SHARE_THREAD_NUMBER)).contentResolverInsert(
225                 any(), nullable(Uri.class), nullable(ContentValues.class));
226 
227         // there is at least a failed attempt
228         assertThat(intended.get()).isTrue();
229     }
230 
231     @Test
isEnabled()232     public void isEnabled() {
233         BluetoothOppManager bluetoothOppManager = BluetoothOppManager.getInstance(mContext);
234         doReturn(true).when(mCallProxy).bluetoothAdapterIsEnabled(any());
235         assertThat(bluetoothOppManager.isEnabled()).isTrue();
236         doReturn(false).when(mCallProxy).bluetoothAdapterIsEnabled(any());
237         assertThat(bluetoothOppManager.isEnabled()).isFalse();
238     }
239 
240     @Test
cleanUpSendingFileInfo_fileInfoCleaned()241     public void cleanUpSendingFileInfo_fileInfoCleaned() {
242         BluetoothOppUtility.sSendFileMap.clear();
243         Uri uri = Uri.parse("content:///a/new/folder/abc/xyz.txt");
244         assertThat(BluetoothOppUtility.sSendFileMap.size()).isEqualTo(0);
245         BluetoothOppManager.getInstance(mContext).saveSendingFileInfo("text/plain",
246                 uri.toString(), false, true);
247         assertThat(BluetoothOppUtility.sSendFileMap.size()).isEqualTo(1);
248 
249         BluetoothOppManager.getInstance(mContext).cleanUpSendingFileInfo();
250         assertThat(BluetoothOppUtility.sSendFileMap.size()).isEqualTo(0);
251     }
252 }
253