Loading android/app/src/com/android/bluetooth/BluetoothMethodProxy.java +10 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.bluetooth; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.le.PeriodicAdvertisingCallback; import android.bluetooth.le.PeriodicAdvertisingManager; import android.bluetooth.le.ScanResult; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; Loading Loading @@ -161,6 +163,14 @@ public class BluetoothMethodProxy { return contentResolver.openInputStream(uri); } /** * Proxies {@link ContentResolver#acquireUnstableContentProviderClient(String)}. */ public ContentProviderClient contentResolverAcquireUnstableContentProviderClient( ContentResolver contentResolver, @NonNull String name) { return contentResolver.acquireUnstableContentProviderClient(name); } /** * Proxies {@link Context#sendBroadcast(Intent)}. */ Loading android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java +7 −3 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.bluetooth.ObexServerSockets; import com.android.bluetooth.map.BluetoothMapContentObserver.Msg; import com.android.bluetooth.map.BluetoothMapUtils.TYPE; import com.android.bluetooth.sdp.SdpManager; import com.android.internal.annotations.VisibleForTesting; import com.android.obex.ServerSession; import java.io.IOException; Loading @@ -39,8 +40,10 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicLong; public class BluetoothMapMasInstance implements IObexConnectionHandler { private final String mTag; private static volatile int sInstanceCounter = 0; @VisibleForTesting final String mTag; @VisibleForTesting static volatile int sInstanceCounter = 0; private static final boolean D = BluetoothMapService.DEBUG; private static final boolean V = BluetoothMapService.VERBOSE; Loading Loading @@ -146,7 +149,8 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { } /* Needed only for test */ protected BluetoothMapMasInstance() { @VisibleForTesting BluetoothMapMasInstance() { mTag = "BluetoothMapMasInstance" + sInstanceCounter++; } Loading android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java +10 −6 Original line number Diff line number Diff line Loading @@ -29,9 +29,11 @@ import android.telephony.TelephonyManager; import android.text.format.DateUtils; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.SignedLongLong; import com.android.bluetooth.map.BluetoothMapUtils.TYPE; import com.android.bluetooth.mapapi.BluetoothMapContract; import com.android.internal.annotations.VisibleForTesting; import com.android.obex.HeaderSet; import com.android.obex.Operation; import com.android.obex.ResponseCodes; Loading Loading @@ -168,8 +170,8 @@ public class BluetoothMapObexServer extends ServerRequestHandler { * */ private ContentProviderClient acquireUnstableContentProviderOrThrow() throws RemoteException { ContentProviderClient providerClient = mResolver.acquireUnstableContentProviderClient(mAuthority); ContentProviderClient providerClient = BluetoothMethodProxy.getInstance() .contentResolverAcquireUnstableContentProviderClient(mResolver, mAuthority); if (providerClient == null) { throw new RemoteException("Failed to acquire provider for " + mAuthority); } Loading Loading @@ -276,7 +278,8 @@ public class BluetoothMapObexServer extends ServerRequestHandler { * folder.getFolderId() will be used to query sub-folders. * Use a parentFolder with id -1 to get all folders from root. */ private void addEmailFolders(BluetoothMapFolderElement parentFolder) throws RemoteException { @VisibleForTesting void addEmailFolders(BluetoothMapFolderElement parentFolder) throws RemoteException { // Select all parent folders BluetoothMapFolderElement newFolder; Loading Loading @@ -529,7 +532,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { + appParams.getChatState() + ", ChatStatusConvoId: " + appParams.getChatStateConvoIdString()); } return setOwnerStatus(name, appParams); return setOwnerStatus(appParams); } } catch (RemoteException e) { Loading Loading @@ -841,7 +844,8 @@ public class BluetoothMapObexServer extends ServerRequestHandler { return ResponseCodes.OBEX_HTTP_OK; } private int setOwnerStatus(String msgHandle, BluetoothMapAppParams appParams) @VisibleForTesting int setOwnerStatus(BluetoothMapAppParams appParams) throws RemoteException { // This does only work for IM if (mAccount != null && mAccount.getType() == BluetoothMapUtils.TYPE.IM) { Loading Loading @@ -1845,7 +1849,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { + appParams.getChatState() + ", ChatStatusConvoId: " + appParams.getChatStateConvoIdString()); } return setOwnerStatus(name, appParams); return setOwnerStatus(appParams); } } catch (RemoteException e) { Loading android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java 0 → 100644 +80 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.bluetooth.map; import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidJUnit4.class) public class BluetoothMapMasInstanceTest { private static final int TEST_MAS_ID = 1; private static final boolean TEST_ENABLE_SMS_MMS = true; private static final String TEST_NAME = "test_name"; private static final String TEST_PACKAGE_NAME = "test.package.name"; private static final String TEST_ID = "1111"; private static final String TEST_PROVIDER_AUTHORITY = "test.project.provider"; private static final Drawable TEST_DRAWABLE = new ColorDrawable(); private static final BluetoothMapUtils.TYPE TEST_TYPE = BluetoothMapUtils.TYPE.EMAIL; private static final String TEST_UCI = "uci"; private static final String TEST_UCI_PREFIX = "uci_prefix"; private BluetoothMapAccountItem mAccountItem; @Mock private Context mContext; @Mock private BluetoothMapService mMapService; @Before public void setUp() { MockitoAnnotations.initMocks(this); mAccountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); } @Test public void constructor_withNoParameters() { BluetoothMapMasInstance instance = new BluetoothMapMasInstance(); assertThat(instance.mTag).isEqualTo( "BluetoothMapMasInstance" + (BluetoothMapMasInstance.sInstanceCounter - 1)); } @Test public void toString_returnsInfo() { BluetoothMapMasInstance instance = new BluetoothMapMasInstance(mMapService, mContext, mAccountItem, TEST_MAS_ID, TEST_ENABLE_SMS_MMS); String expected = "MasId: " + TEST_MAS_ID + " Uri:" + mAccountItem.mBase_uri + " SMS/MMS:" + TEST_ENABLE_SMS_MMS; assertThat(instance.toString()).isEqualTo(expected); } } android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java 0 → 100644 +195 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.bluetooth.map; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.content.ContentProviderClient; import android.content.Context; import android.database.MatrixCursor; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.RemoteException; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.mapapi.BluetoothMapContract; import com.android.obex.ResponseCodes; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; @SmallTest @RunWith(AndroidJUnit4.class) public class BluetoothMapObexServerTest { private static final int TEST_MAS_ID = 1; private static final boolean TEST_ENABLE_SMS_MMS = true; private static final String TEST_NAME = "test_name"; private static final String TEST_PACKAGE_NAME = "test.package.name"; private static final String TEST_ID = "1111"; private static final String TEST_PROVIDER_AUTHORITY = "test.project.provider"; private static final Drawable TEST_DRAWABLE = new ColorDrawable(); private static final BluetoothMapUtils.TYPE TEST_TYPE = BluetoothMapUtils.TYPE.IM; private static final String TEST_UCI = "uci"; private static final String TEST_UCI_PREFIX = "uci_prefix"; private BluetoothMapAccountItem mAccountItem; private BluetoothMapMasInstance mMasInstance; private BluetoothMapObexServer mObexServer; private BluetoothMapAppParams mParams; @Mock private Context mContext; @Mock private BluetoothMapService mMapService; @Mock private ContentProviderClient mProviderClient; @Mock private BluetoothMapContentObserver mObserver; @Spy private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance(); @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); BluetoothMethodProxy.setInstanceForTesting(mMapMethodProxy); doReturn(mProviderClient).when( mMapMethodProxy).contentResolverAcquireUnstableContentProviderClient(any(), any()); mAccountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); mMasInstance = new BluetoothMapMasInstance(mMapService, mContext, mAccountItem, TEST_MAS_ID, TEST_ENABLE_SMS_MMS); mParams = new BluetoothMapAppParams(); mObexServer = new BluetoothMapObexServer(null, mContext, mObserver, mMasInstance, mAccountItem, TEST_ENABLE_SMS_MMS); } @Test public void setOwnerStatus_withAccountTypeEmail() throws Exception { doReturn(null).when(mProviderClient).query(any(), any(), any(), any(), any()); BluetoothMapAccountItem accountItemWithTypeEmail = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, BluetoothMapUtils.TYPE.EMAIL, TEST_UCI, TEST_UCI_PREFIX); BluetoothMapObexServer obexServer = new BluetoothMapObexServer(null, mContext, mObserver, mMasInstance, accountItemWithTypeEmail, TEST_ENABLE_SMS_MMS); assertThat(obexServer.setOwnerStatus(mParams)).isEqualTo( ResponseCodes.OBEX_HTTP_UNAVAILABLE); } @Test public void setOwnerStatus_withAppParamsInvalid() throws Exception { BluetoothMapAppParams params = mock(BluetoothMapAppParams.class); when(params.getPresenceAvailability()).thenReturn( BluetoothMapAppParams.INVALID_VALUE_PARAMETER); when(params.getPresenceStatus()).thenReturn(null); when(params.getLastActivity()).thenReturn( (long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); when(params.getChatState()).thenReturn(BluetoothMapAppParams.INVALID_VALUE_PARAMETER); when(params.getChatStateConvoIdString()).thenReturn(null); assertThat(mObexServer.setOwnerStatus(params)).isEqualTo( ResponseCodes.OBEX_HTTP_PRECON_FAILED); } @Test public void setOwnerStatus_withNonNullBundle() throws Exception { setUpBluetoothMapAppParams(mParams); Bundle bundle = new Bundle(); when(mProviderClient.call(any(), any(), any())).thenReturn(bundle); assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( ResponseCodes.OBEX_HTTP_OK); } @Test public void setOwnerStatus_withNullBundle() throws Exception { setUpBluetoothMapAppParams(mParams); when(mProviderClient.call(any(), any(), any())).thenReturn(null); assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED); } @Test public void setOwnerStatus_withRemoteExceptionThrown() throws Exception { setUpBluetoothMapAppParams(mParams); doThrow(RemoteException.class).when(mProviderClient).call(any(), any(), any()); assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( ResponseCodes.OBEX_HTTP_UNAVAILABLE); } @Test public void setOwnerStatus_withNullPointerExceptionThrown() throws Exception { setUpBluetoothMapAppParams(mParams); doThrow(NullPointerException.class).when(mProviderClient).call(any(), any(), any()); assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( ResponseCodes.OBEX_HTTP_UNAVAILABLE); } @Test public void setOwnerStatus_withIllegalArgumentExceptionThrown() throws Exception { setUpBluetoothMapAppParams(mParams); doThrow(IllegalArgumentException.class).when(mProviderClient).call(any(), any(), any()); assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( ResponseCodes.OBEX_HTTP_UNAVAILABLE); } @Test public void addEmailFolders() throws Exception { MatrixCursor cursor = new MatrixCursor(new String[]{BluetoothMapContract.FolderColumns.NAME, BluetoothMapContract.FolderColumns._ID}); long parentId = 1; long childId = 2; cursor.addRow(new Object[]{"test_name", childId}); cursor.moveToFirst(); BluetoothMapFolderElement parentFolder = new BluetoothMapFolderElement("parent", null); parentFolder.setFolderId(parentId); doReturn(cursor).when(mProviderClient).query(any(), any(), eq(BluetoothMapContract.FolderColumns.PARENT_FOLDER_ID + " = " + parentId), any(), any()); mObexServer.addEmailFolders(parentFolder); assertThat(parentFolder.getFolderById(childId)).isNotNull(); } private void setUpBluetoothMapAppParams(BluetoothMapAppParams params) { params.setPresenceAvailability(1); params.setPresenceStatus("test_presence_status"); params.setLastActivity(0); params.setChatState(1); params.setChatStateConvoId(1, 1); } } Loading
android/app/src/com/android/bluetooth/BluetoothMethodProxy.java +10 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.bluetooth; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.le.PeriodicAdvertisingCallback; import android.bluetooth.le.PeriodicAdvertisingManager; import android.bluetooth.le.ScanResult; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; Loading Loading @@ -161,6 +163,14 @@ public class BluetoothMethodProxy { return contentResolver.openInputStream(uri); } /** * Proxies {@link ContentResolver#acquireUnstableContentProviderClient(String)}. */ public ContentProviderClient contentResolverAcquireUnstableContentProviderClient( ContentResolver contentResolver, @NonNull String name) { return contentResolver.acquireUnstableContentProviderClient(name); } /** * Proxies {@link Context#sendBroadcast(Intent)}. */ Loading
android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java +7 −3 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.bluetooth.ObexServerSockets; import com.android.bluetooth.map.BluetoothMapContentObserver.Msg; import com.android.bluetooth.map.BluetoothMapUtils.TYPE; import com.android.bluetooth.sdp.SdpManager; import com.android.internal.annotations.VisibleForTesting; import com.android.obex.ServerSession; import java.io.IOException; Loading @@ -39,8 +40,10 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicLong; public class BluetoothMapMasInstance implements IObexConnectionHandler { private final String mTag; private static volatile int sInstanceCounter = 0; @VisibleForTesting final String mTag; @VisibleForTesting static volatile int sInstanceCounter = 0; private static final boolean D = BluetoothMapService.DEBUG; private static final boolean V = BluetoothMapService.VERBOSE; Loading Loading @@ -146,7 +149,8 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { } /* Needed only for test */ protected BluetoothMapMasInstance() { @VisibleForTesting BluetoothMapMasInstance() { mTag = "BluetoothMapMasInstance" + sInstanceCounter++; } Loading
android/app/src/com/android/bluetooth/map/BluetoothMapObexServer.java +10 −6 Original line number Diff line number Diff line Loading @@ -29,9 +29,11 @@ import android.telephony.TelephonyManager; import android.text.format.DateUtils; import android.util.Log; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.SignedLongLong; import com.android.bluetooth.map.BluetoothMapUtils.TYPE; import com.android.bluetooth.mapapi.BluetoothMapContract; import com.android.internal.annotations.VisibleForTesting; import com.android.obex.HeaderSet; import com.android.obex.Operation; import com.android.obex.ResponseCodes; Loading Loading @@ -168,8 +170,8 @@ public class BluetoothMapObexServer extends ServerRequestHandler { * */ private ContentProviderClient acquireUnstableContentProviderOrThrow() throws RemoteException { ContentProviderClient providerClient = mResolver.acquireUnstableContentProviderClient(mAuthority); ContentProviderClient providerClient = BluetoothMethodProxy.getInstance() .contentResolverAcquireUnstableContentProviderClient(mResolver, mAuthority); if (providerClient == null) { throw new RemoteException("Failed to acquire provider for " + mAuthority); } Loading Loading @@ -276,7 +278,8 @@ public class BluetoothMapObexServer extends ServerRequestHandler { * folder.getFolderId() will be used to query sub-folders. * Use a parentFolder with id -1 to get all folders from root. */ private void addEmailFolders(BluetoothMapFolderElement parentFolder) throws RemoteException { @VisibleForTesting void addEmailFolders(BluetoothMapFolderElement parentFolder) throws RemoteException { // Select all parent folders BluetoothMapFolderElement newFolder; Loading Loading @@ -529,7 +532,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { + appParams.getChatState() + ", ChatStatusConvoId: " + appParams.getChatStateConvoIdString()); } return setOwnerStatus(name, appParams); return setOwnerStatus(appParams); } } catch (RemoteException e) { Loading Loading @@ -841,7 +844,8 @@ public class BluetoothMapObexServer extends ServerRequestHandler { return ResponseCodes.OBEX_HTTP_OK; } private int setOwnerStatus(String msgHandle, BluetoothMapAppParams appParams) @VisibleForTesting int setOwnerStatus(BluetoothMapAppParams appParams) throws RemoteException { // This does only work for IM if (mAccount != null && mAccount.getType() == BluetoothMapUtils.TYPE.IM) { Loading Loading @@ -1845,7 +1849,7 @@ public class BluetoothMapObexServer extends ServerRequestHandler { + appParams.getChatState() + ", ChatStatusConvoId: " + appParams.getChatStateConvoIdString()); } return setOwnerStatus(name, appParams); return setOwnerStatus(appParams); } } catch (RemoteException e) { Loading
android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapMasInstanceTest.java 0 → 100644 +80 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.bluetooth.map; import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidJUnit4.class) public class BluetoothMapMasInstanceTest { private static final int TEST_MAS_ID = 1; private static final boolean TEST_ENABLE_SMS_MMS = true; private static final String TEST_NAME = "test_name"; private static final String TEST_PACKAGE_NAME = "test.package.name"; private static final String TEST_ID = "1111"; private static final String TEST_PROVIDER_AUTHORITY = "test.project.provider"; private static final Drawable TEST_DRAWABLE = new ColorDrawable(); private static final BluetoothMapUtils.TYPE TEST_TYPE = BluetoothMapUtils.TYPE.EMAIL; private static final String TEST_UCI = "uci"; private static final String TEST_UCI_PREFIX = "uci_prefix"; private BluetoothMapAccountItem mAccountItem; @Mock private Context mContext; @Mock private BluetoothMapService mMapService; @Before public void setUp() { MockitoAnnotations.initMocks(this); mAccountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); } @Test public void constructor_withNoParameters() { BluetoothMapMasInstance instance = new BluetoothMapMasInstance(); assertThat(instance.mTag).isEqualTo( "BluetoothMapMasInstance" + (BluetoothMapMasInstance.sInstanceCounter - 1)); } @Test public void toString_returnsInfo() { BluetoothMapMasInstance instance = new BluetoothMapMasInstance(mMapService, mContext, mAccountItem, TEST_MAS_ID, TEST_ENABLE_SMS_MMS); String expected = "MasId: " + TEST_MAS_ID + " Uri:" + mAccountItem.mBase_uri + " SMS/MMS:" + TEST_ENABLE_SMS_MMS; assertThat(instance.toString()).isEqualTo(expected); } }
android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapObexServerTest.java 0 → 100644 +195 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.bluetooth.map; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.content.ContentProviderClient; import android.content.Context; import android.database.MatrixCursor; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.RemoteException; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.mapapi.BluetoothMapContract; import com.android.obex.ResponseCodes; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; @SmallTest @RunWith(AndroidJUnit4.class) public class BluetoothMapObexServerTest { private static final int TEST_MAS_ID = 1; private static final boolean TEST_ENABLE_SMS_MMS = true; private static final String TEST_NAME = "test_name"; private static final String TEST_PACKAGE_NAME = "test.package.name"; private static final String TEST_ID = "1111"; private static final String TEST_PROVIDER_AUTHORITY = "test.project.provider"; private static final Drawable TEST_DRAWABLE = new ColorDrawable(); private static final BluetoothMapUtils.TYPE TEST_TYPE = BluetoothMapUtils.TYPE.IM; private static final String TEST_UCI = "uci"; private static final String TEST_UCI_PREFIX = "uci_prefix"; private BluetoothMapAccountItem mAccountItem; private BluetoothMapMasInstance mMasInstance; private BluetoothMapObexServer mObexServer; private BluetoothMapAppParams mParams; @Mock private Context mContext; @Mock private BluetoothMapService mMapService; @Mock private ContentProviderClient mProviderClient; @Mock private BluetoothMapContentObserver mObserver; @Spy private BluetoothMethodProxy mMapMethodProxy = BluetoothMethodProxy.getInstance(); @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); BluetoothMethodProxy.setInstanceForTesting(mMapMethodProxy); doReturn(mProviderClient).when( mMapMethodProxy).contentResolverAcquireUnstableContentProviderClient(any(), any()); mAccountItem = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, TEST_TYPE, TEST_UCI, TEST_UCI_PREFIX); mMasInstance = new BluetoothMapMasInstance(mMapService, mContext, mAccountItem, TEST_MAS_ID, TEST_ENABLE_SMS_MMS); mParams = new BluetoothMapAppParams(); mObexServer = new BluetoothMapObexServer(null, mContext, mObserver, mMasInstance, mAccountItem, TEST_ENABLE_SMS_MMS); } @Test public void setOwnerStatus_withAccountTypeEmail() throws Exception { doReturn(null).when(mProviderClient).query(any(), any(), any(), any(), any()); BluetoothMapAccountItem accountItemWithTypeEmail = BluetoothMapAccountItem.create(TEST_ID, TEST_NAME, TEST_PACKAGE_NAME, TEST_PROVIDER_AUTHORITY, TEST_DRAWABLE, BluetoothMapUtils.TYPE.EMAIL, TEST_UCI, TEST_UCI_PREFIX); BluetoothMapObexServer obexServer = new BluetoothMapObexServer(null, mContext, mObserver, mMasInstance, accountItemWithTypeEmail, TEST_ENABLE_SMS_MMS); assertThat(obexServer.setOwnerStatus(mParams)).isEqualTo( ResponseCodes.OBEX_HTTP_UNAVAILABLE); } @Test public void setOwnerStatus_withAppParamsInvalid() throws Exception { BluetoothMapAppParams params = mock(BluetoothMapAppParams.class); when(params.getPresenceAvailability()).thenReturn( BluetoothMapAppParams.INVALID_VALUE_PARAMETER); when(params.getPresenceStatus()).thenReturn(null); when(params.getLastActivity()).thenReturn( (long) BluetoothMapAppParams.INVALID_VALUE_PARAMETER); when(params.getChatState()).thenReturn(BluetoothMapAppParams.INVALID_VALUE_PARAMETER); when(params.getChatStateConvoIdString()).thenReturn(null); assertThat(mObexServer.setOwnerStatus(params)).isEqualTo( ResponseCodes.OBEX_HTTP_PRECON_FAILED); } @Test public void setOwnerStatus_withNonNullBundle() throws Exception { setUpBluetoothMapAppParams(mParams); Bundle bundle = new Bundle(); when(mProviderClient.call(any(), any(), any())).thenReturn(bundle); assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( ResponseCodes.OBEX_HTTP_OK); } @Test public void setOwnerStatus_withNullBundle() throws Exception { setUpBluetoothMapAppParams(mParams); when(mProviderClient.call(any(), any(), any())).thenReturn(null); assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED); } @Test public void setOwnerStatus_withRemoteExceptionThrown() throws Exception { setUpBluetoothMapAppParams(mParams); doThrow(RemoteException.class).when(mProviderClient).call(any(), any(), any()); assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( ResponseCodes.OBEX_HTTP_UNAVAILABLE); } @Test public void setOwnerStatus_withNullPointerExceptionThrown() throws Exception { setUpBluetoothMapAppParams(mParams); doThrow(NullPointerException.class).when(mProviderClient).call(any(), any(), any()); assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( ResponseCodes.OBEX_HTTP_UNAVAILABLE); } @Test public void setOwnerStatus_withIllegalArgumentExceptionThrown() throws Exception { setUpBluetoothMapAppParams(mParams); doThrow(IllegalArgumentException.class).when(mProviderClient).call(any(), any(), any()); assertThat(mObexServer.setOwnerStatus(mParams)).isEqualTo( ResponseCodes.OBEX_HTTP_UNAVAILABLE); } @Test public void addEmailFolders() throws Exception { MatrixCursor cursor = new MatrixCursor(new String[]{BluetoothMapContract.FolderColumns.NAME, BluetoothMapContract.FolderColumns._ID}); long parentId = 1; long childId = 2; cursor.addRow(new Object[]{"test_name", childId}); cursor.moveToFirst(); BluetoothMapFolderElement parentFolder = new BluetoothMapFolderElement("parent", null); parentFolder.setFolderId(parentId); doReturn(cursor).when(mProviderClient).query(any(), any(), eq(BluetoothMapContract.FolderColumns.PARENT_FOLDER_ID + " = " + parentId), any(), any()); mObexServer.addEmailFolders(parentFolder); assertThat(parentFolder.getFolderById(childId)).isNotNull(); } private void setUpBluetoothMapAppParams(BluetoothMapAppParams params) { params.setPresenceAvailability(1); params.setPresenceStatus("test_presence_status"); params.setLastActivity(0); params.setChatState(1); params.setChatStateConvoId(1, 1); } }