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