diff options
author | Kevin F. Haggerty <haggertk@lineageos.org> | 2020-06-01 20:43:45 -0600 |
---|---|---|
committer | Kevin F. Haggerty <haggertk@lineageos.org> | 2020-06-01 20:43:45 -0600 |
commit | cf38327eba534b6354b44e4d29a3fef8190b481e (patch) | |
tree | 84195c87dacf64c2d7df6be202f9f62a62258aba /tests | |
parent | 837b47f2b5613cb2e6235229831f9c80ec28c741 (diff) | |
parent | 906df07061fcf46aac856894fb6d68b2ccccfa2c (diff) | |
download | android_packages_apps_Bluetooth-cf38327eba534b6354b44e4d29a3fef8190b481e.tar.gz android_packages_apps_Bluetooth-cf38327eba534b6354b44e4d29a3fef8190b481e.tar.bz2 android_packages_apps_Bluetooth-cf38327eba534b6354b44e4d29a3fef8190b481e.zip |
Merge tag 'android-10.0.0_r37' into staging/lineage-17.1_merge-android-10.0.0_r37lineage-17.1
Android 10.0.0 Release 37 (QQ3A.200605.001)
* tag 'android-10.0.0_r37': (37 commits)
Import translations. DO NOT MERGE
Revert "PBAP server, send favorite contacts"
Import translations. DO NOT MERGE
Delete call logs when calls are made without PBAP
Set Browsing bit to 0 in PbapSupportedFeatures
Prevent phone's bd_addr from appearing in Accounts
Return an empty list when the requested node is not in the tree
AvrcpController Test update
AVRCP Controller Media Controller not ready
Allow subsequent requests for media keys to replay the silent audio sample
HFP Client call status update
PBAP server, send favorite contacts
AVRCP Controller Disable Automatic Focus Request
A2DP Sink: Focus gain while transient loss
AVRCP Controller State without Browsing
Add bluetooth prefs for Android Automotive
MAP Client disconnect state machine if MAS client disconnected
MAP Client close connection on MNS disconnect
MAP Client Only connect MNS in connected state
MAP Client BMessage parser length
...
Change-Id: I1398f4ffe79e4ac0a37765927e4afd2e05ee0908
Diffstat (limited to 'tests')
6 files changed, 418 insertions, 15 deletions
diff --git a/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java b/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java index c759a8a1f..b8fbbb9ef 100644 --- a/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java +++ b/tests/unit/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java @@ -195,6 +195,21 @@ public class A2dpSinkStreamHandlerTest { } @Test + public void testFocusRerequest() { + // Focus was lost transiently, expect streaming to stop. + testSnkPlay(); + mStreamHandler.handleMessage( + mStreamHandler.obtainMessage(A2dpSinkStreamHandler.AUDIO_FOCUS_CHANGE, + AudioManager.AUDIOFOCUS_LOSS_TRANSIENT)); + verify(mMockAudioManager, times(0)).abandonAudioFocus(any()); + verify(mMockA2dpSink, times(0)).informAudioFocusStateNative(0); + verify(mMockA2dpSink, times(1)).informAudioTrackGainNative(0); + mStreamHandler.handleMessage( + mStreamHandler.obtainMessage(A2dpSinkStreamHandler.REQUEST_FOCUS, true)); + verify(mMockAudioManager, times(2)).requestAudioFocus(any()); + } + + @Test public void testFocusGainTransient() { // Focus was lost then regained. testSnkPlay(); diff --git a/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java b/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java index 4fedc889a..907f0dcdc 100644 --- a/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java +++ b/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java @@ -23,9 +23,11 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.content.Intent; +import android.content.res.Resources; import android.media.AudioManager; -import android.media.session.MediaController; import android.os.Looper; +import android.support.v4.media.session.MediaControllerCompat; +import android.support.v4.media.session.PlaybackStateCompat; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; @@ -34,6 +36,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.R; import com.android.bluetooth.TestUtils; +import com.android.bluetooth.a2dpsink.A2dpSinkService; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; @@ -66,15 +69,23 @@ public class AvrcpControllerStateMachineTest { private ArgumentCaptor<Intent> mIntentArgument = ArgumentCaptor.forClass(Intent.class); private byte[] mTestAddress = new byte[]{00, 01, 02, 03, 04, 05}; - @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); + @Rule public final ServiceTestRule mAvrcpServiceRule = new ServiceTestRule(); + @Rule public final ServiceTestRule mA2dpServiceRule = new ServiceTestRule(); @Mock - private AdapterService mAdapterService; + private AdapterService mAvrcpAdapterService; + + @Mock + private AdapterService mA2dpAdapterService; + @Mock private AudioManager mAudioManager; @Mock private AvrcpControllerService mAvrcpControllerService; + @Mock + private Resources mMockResources; + AvrcpControllerStateMachine mAvrcpStateMachine; @Before @@ -90,9 +101,14 @@ public class AvrcpControllerStateMachineTest { // Setup mocks and test assets MockitoAnnotations.initMocks(this); - TestUtils.setAdapterService(mAdapterService); - TestUtils.startService(mServiceRule, AvrcpControllerService.class); - doReturn(mTargetContext.getResources()).when(mAvrcpControllerService).getResources(); + TestUtils.setAdapterService(mAvrcpAdapterService); + TestUtils.startService(mAvrcpServiceRule, AvrcpControllerService.class); + TestUtils.clearAdapterService(mAvrcpAdapterService); + TestUtils.setAdapterService(mA2dpAdapterService); + TestUtils.startService(mA2dpServiceRule, A2dpSinkService.class); + when(mMockResources.getBoolean(R.bool.a2dp_sink_automatically_request_audio_focus)) + .thenReturn(true); + doReturn(mMockResources).when(mAvrcpControllerService).getResources(); doReturn(15).when(mAudioManager).getStreamMaxVolume(anyInt()); doReturn(8).when(mAudioManager).getStreamVolume(anyInt()); doReturn(true).when(mAudioManager).isVolumeFixed(); @@ -113,7 +129,7 @@ public class AvrcpControllerStateMachineTest { if (!mTargetContext.getResources().getBoolean(R.bool.profile_supported_avrcp_controller)) { return; } - TestUtils.clearAdapterService(mAdapterService); + TestUtils.clearAdapterService(mA2dpAdapterService); } /** @@ -141,6 +157,10 @@ public class AvrcpControllerStateMachineTest { IsInstanceOf.instanceOf(AvrcpControllerStateMachine.Disconnected.class)); Assert.assertEquals(mAvrcpStateMachine.getState(), BluetoothProfile.STATE_DISCONNECTED); verify(mAvrcpControllerService).removeStateMachine(eq(mAvrcpStateMachine)); + MediaControllerCompat.TransportControls transportControls = + BluetoothMediaBrowserService.getTransportControls(); + Assert.assertEquals(PlaybackStateCompat.STATE_ERROR, + BluetoothMediaBrowserService.getPlaybackState()); } /** @@ -149,6 +169,11 @@ public class AvrcpControllerStateMachineTest { @Test public void testControlOnly() { int numBroadcastsSent = setUpConnectedState(true, false); + MediaControllerCompat.TransportControls transportControls = + BluetoothMediaBrowserService.getTransportControls(); + Assert.assertNotNull(transportControls); + Assert.assertEquals(PlaybackStateCompat.STATE_NONE, + BluetoothMediaBrowserService.getPlaybackState()); StackEvent event = StackEvent.connectionStateChanged(false, false); mAvrcpStateMachine.disconnect(); @@ -166,6 +191,8 @@ public class AvrcpControllerStateMachineTest { IsInstanceOf.instanceOf(AvrcpControllerStateMachine.Disconnected.class)); Assert.assertEquals(mAvrcpStateMachine.getState(), BluetoothProfile.STATE_DISCONNECTED); verify(mAvrcpControllerService).removeStateMachine(eq(mAvrcpStateMachine)); + Assert.assertEquals(PlaybackStateCompat.STATE_ERROR, + BluetoothMediaBrowserService.getPlaybackState()); } /** @@ -176,6 +203,8 @@ public class AvrcpControllerStateMachineTest { Assert.assertEquals(0, mAvrcpControllerService.sBrowseTree.mRootNode.getChildrenCount()); int numBroadcastsSent = setUpConnectedState(false, true); Assert.assertEquals(1, mAvrcpControllerService.sBrowseTree.mRootNode.getChildrenCount()); + Assert.assertEquals(PlaybackStateCompat.STATE_NONE, + BluetoothMediaBrowserService.getPlaybackState()); StackEvent event = StackEvent.connectionStateChanged(false, false); mAvrcpStateMachine.disconnect(); @@ -193,6 +222,10 @@ public class AvrcpControllerStateMachineTest { IsInstanceOf.instanceOf(AvrcpControllerStateMachine.Disconnected.class)); Assert.assertEquals(mAvrcpStateMachine.getState(), BluetoothProfile.STATE_DISCONNECTED); verify(mAvrcpControllerService).removeStateMachine(eq(mAvrcpStateMachine)); + MediaControllerCompat.TransportControls transportControls = + BluetoothMediaBrowserService.getTransportControls(); + Assert.assertEquals(PlaybackStateCompat.STATE_ERROR, + BluetoothMediaBrowserService.getPlaybackState()); } /** @@ -221,7 +254,7 @@ public class AvrcpControllerStateMachineTest { @Test public void testPlay() throws Exception { setUpConnectedState(true, true); - MediaController.TransportControls transportControls = + MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); //Play @@ -240,7 +273,7 @@ public class AvrcpControllerStateMachineTest { @Test public void testPause() throws Exception { setUpConnectedState(true, true); - MediaController.TransportControls transportControls = + MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); //Pause @@ -259,7 +292,7 @@ public class AvrcpControllerStateMachineTest { @Test public void testStop() throws Exception { setUpConnectedState(true, true); - MediaController.TransportControls transportControls = + MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); //Stop @@ -278,7 +311,7 @@ public class AvrcpControllerStateMachineTest { @Test public void testNext() throws Exception { setUpConnectedState(true, true); - MediaController.TransportControls transportControls = + MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); //Next @@ -298,7 +331,7 @@ public class AvrcpControllerStateMachineTest { @Test public void testPrevious() throws Exception { setUpConnectedState(true, true); - MediaController.TransportControls transportControls = + MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); //Previous @@ -318,7 +351,7 @@ public class AvrcpControllerStateMachineTest { @Test public void testFastForward() throws Exception { setUpConnectedState(true, true); - MediaController.TransportControls transportControls = + MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); //FastForward @@ -339,7 +372,7 @@ public class AvrcpControllerStateMachineTest { @Test public void testRewind() throws Exception { setUpConnectedState(true, true); - MediaController.TransportControls transportControls = + MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); //Rewind @@ -355,6 +388,69 @@ public class AvrcpControllerStateMachineTest { } /** + * Test media browser skip to queue item + */ + @Test + public void testSkipToQueueInvalid() throws Exception { + byte scope = 1; + int minSize = 0; + int maxSize = 255; + setUpConnectedState(true, true); + MediaControllerCompat.TransportControls transportControls = + BluetoothMediaBrowserService.getTransportControls(); + + //Play an invalid item below start + transportControls.skipToQueueItem(minSize - 1); + verify(mAvrcpControllerService, + timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(0)).playItemNative( + eq(mTestAddress), eq(scope), anyLong(), anyInt()); + + //Play an invalid item beyond end + transportControls.skipToQueueItem(maxSize + 1); + verify(mAvrcpControllerService, + timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(0)).playItemNative( + eq(mTestAddress), eq(scope), anyLong(), anyInt()); + } + + /** + * Test media browser shuffle command + */ + @Test + public void testShuffle() throws Exception { + byte[] shuffleSetting = new byte[]{3}; + byte[] shuffleMode = new byte[]{2}; + + setUpConnectedState(true, true); + MediaControllerCompat.TransportControls transportControls = + BluetoothMediaBrowserService.getTransportControls(); + + //Shuffle + transportControls.setShuffleMode(1); + verify(mAvrcpControllerService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) + .setPlayerApplicationSettingValuesNative( + eq(mTestAddress), eq((byte) 1), eq(shuffleSetting), eq(shuffleMode)); + } + + /** + * Test media browser repeat command + */ + @Test + public void testRepeat() throws Exception { + byte[] repeatSetting = new byte[]{2}; + byte[] repeatMode = new byte[]{3}; + + setUpConnectedState(true, true); + MediaControllerCompat.TransportControls transportControls = + BluetoothMediaBrowserService.getTransportControls(); + + //Shuffle + transportControls.setRepeatMode(2); + verify(mAvrcpControllerService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) + .setPlayerApplicationSettingValuesNative( + eq(mTestAddress), eq((byte) 1), eq(repeatSetting), eq(repeatMode)); + } + + /** * Test media browsing * Verify that a browse tree is created with the proper root * Verify that a player can be fetched and added to the browse tree @@ -483,7 +579,7 @@ public class AvrcpControllerStateMachineTest { BrowseTree.BrowseNode playerNodes = mAvrcpStateMachine.findNode(results.getID()); mAvrcpStateMachine.requestContents(results); - MediaController.TransportControls transportControls = + MediaControllerCompat.TransportControls transportControls = BluetoothMediaBrowserService.getTransportControls(); transportControls.play(); verify(mAvrcpControllerService, @@ -507,6 +603,45 @@ public class AvrcpControllerStateMachineTest { } /** + * Test playback does not request focus when another app is playing music. + */ + @Test + public void testPlaybackWhileMusicPlaying() { + when(mMockResources.getBoolean(R.bool.a2dp_sink_automatically_request_audio_focus)) + .thenReturn(false); + Assert.assertEquals(AudioManager.AUDIOFOCUS_NONE, A2dpSinkService.getFocusState()); + doReturn(true).when(mAudioManager).isMusicActive(); + setUpConnectedState(true, true); + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_PLAY_STATUS_CHANGED, + PlaybackStateCompat.STATE_PLAYING); + TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); + verify(mAvrcpControllerService, + timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)).sendPassThroughCommandNative( + eq(mTestAddress), eq(AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE), eq(KEY_DOWN)); + TestUtils.waitForLooperToFinishScheduledTask( + A2dpSinkService.getA2dpSinkService().getMainLooper()); + Assert.assertEquals(AudioManager.AUDIOFOCUS_NONE, A2dpSinkService.getFocusState()); + } + + /** + * Test playback requests focus while nothing is playing music. + */ + @Test + public void testPlaybackWhileIdle() { + Assert.assertEquals(AudioManager.AUDIOFOCUS_NONE, A2dpSinkService.getFocusState()); + doReturn(false).when(mAudioManager).isMusicActive(); + setUpConnectedState(true, true); + mAvrcpStateMachine.sendMessage( + AvrcpControllerStateMachine.MESSAGE_PROCESS_PLAY_STATUS_CHANGED, + PlaybackStateCompat.STATE_PLAYING); + TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper()); + TestUtils.waitForLooperToFinishScheduledTask( + A2dpSinkService.getA2dpSinkService().getMainLooper()); + Assert.assertEquals(AudioManager.AUDIOFOCUS_GAIN, A2dpSinkService.getFocusState()); + } + + /** * Setup Connected State * * @return number of times mAvrcpControllerService.sendBroadcastAsUser() has been invoked diff --git a/tests/unit/src/com/android/bluetooth/mapclient/BmessageTest.java b/tests/unit/src/com/android/bluetooth/mapclient/BmessageTest.java new file mode 100644 index 000000000..acd05ed02 --- /dev/null +++ b/tests/unit/src/com/android/bluetooth/mapclient/BmessageTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2019 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.mapclient; + +import static org.mockito.Mockito.*; + +import androidx.test.filters.MediumTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +@MediumTest +@RunWith(AndroidJUnit4.class) +public class BmessageTest { + private static final String TAG = BmessageTest.class.getSimpleName(); + private static final String SIMPLE_MMS_MESSAGE = + "BEGIN:BMSG\r\nVERSION:1.0\r\nSTATUS:READ\r\nTYPE:MMS\r\nFOLDER:null\r\nBEGIN:BENV\r\n" + + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" + + "BEGIN:BBODY\r\nLENGTH:39\r\nBEGIN:MSG\r\nThis is a new msg\r\nEND:MSG\r\n" + + "END:BBODY\r\nEND:BENV\r\nEND:BMSG\r\n"; + + private static final String NO_END_MESSAGE = + "BEGIN:BMSG\r\nVERSION:1.0\r\nSTATUS:READ\r\nTYPE:MMS\r\nFOLDER:null\r\nBEGIN:BENV\r\n" + + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" + + "BEGIN:BBODY\r\nLENGTH:39\r\nBEGIN:MSG\r\nThis is a new msg\r\n"; + + private static final String WRONG_LENGTH_MESSAGE = + "BEGIN:BMSG\r\nVERSION:1.0\r\nSTATUS:READ\r\nTYPE:MMS\r\nFOLDER:null\r\nBEGIN:BENV\r\n" + + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" + + "BEGIN:BBODY\r\nLENGTH:200\r\nBEGIN:MSG\r\nThis is a new msg\r\nEND:MSG\r\n" + + "END:BBODY\r\nEND:BENV\r\nEND:BMSG\r\n"; + + private static final String NO_BODY_MESSAGE = + "BEGIN:BMSG\r\nVERSION:1.0\r\nSTATUS:READ\r\nTYPE:MMS\r\nFOLDER:null\r\nBEGIN:BENV\r\n" + + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" + + "BEGIN:BBODY\r\nLENGTH:\r\n"; + + private static final String NEGATIVE_LENGTH_MESSAGE = + "BEGIN:BMSG\r\nVERSION:1.0\r\nSTATUS:READ\r\nTYPE:MMS\r\nFOLDER:null\r\nBEGIN:BENV\r\n" + + "BEGIN:VCARD\r\nVERSION:2.1\r\nN:null;;;;\r\nTEL:555-5555\r\nEND:VCARD\r\n" + + "BEGIN:BBODY\r\nLENGTH:-1\r\nBEGIN:MSG\r\nThis is a new msg\r\nEND:MSG\r\n" + + "END:BBODY\r\nEND:BENV\r\nEND:BMSG\r\n"; + + @Test + public void testNormalMessages() { + Bmessage message = BmessageParser.createBmessage(SIMPLE_MMS_MESSAGE); + Assert.assertNotNull(message); + } + + @Test + public void testParseWrongLengthMessage() { + Bmessage message = BmessageParser.createBmessage(WRONG_LENGTH_MESSAGE); + Assert.assertNull(message); + } + + @Test + public void testParseNoEndMessage() { + Bmessage message = BmessageParser.createBmessage(NO_END_MESSAGE); + Assert.assertNull(message); + } + + @Test + public void testParseReallyLongMessage() { + String testMessage = new String(new char[68048]).replace('\0', 'A'); + Bmessage message = BmessageParser.createBmessage(testMessage); + Assert.assertNull(message); + } + + @Test + public void testNoBodyMessage() { + Bmessage message = BmessageParser.createBmessage(NO_BODY_MESSAGE); + Assert.assertNull(message); + } + + @Test + public void testNegativeLengthMessage() { + Bmessage message = BmessageParser.createBmessage(NEGATIVE_LENGTH_MESSAGE); + Assert.assertNull(message); + } +} diff --git a/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java b/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java index 70854d8d1..ccfd9f810 100644 --- a/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java +++ b/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java @@ -150,6 +150,36 @@ public class MapClientStateMachineTest { Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mMceStateMachine.getState()); } + /** + * Test transition from STATE_CONNECTING --> (receive MSG_MAS_CONNECTED) --> STATE_CONNECTED + * --> (receive MSG_MAS_DISCONNECTED) --> STATE_DISCONNECTED + */ + @Test + public void testStateTransitionFromConnectedWithMasDisconnected() { + Log.i(TAG, "in testStateTransitionFromConnectedWithMasDisconnected"); + + setupSdpRecordReceipt(); + Message msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_CONNECTED); + mMceStateMachine.sendMessage(msg); + + // Wait until the message is processed and a broadcast request is sent to + // to MapClientService to change + // state from STATE_CONNECTING to STATE_CONNECTED + verify(mMockMapClientService, + timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).sendBroadcast( + mIntentArgument.capture(), eq(ProfileService.BLUETOOTH_PERM)); + Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mMceStateMachine.getState()); + + msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_DISCONNECTED); + mMceStateMachine.sendMessage(msg); + verify(mMockMapClientService, + timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(4)).sendBroadcast( + mIntentArgument.capture(), eq(ProfileService.BLUETOOTH_PERM)); + + Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, mMceStateMachine.getState()); + } + + /** * Test receiving an empty event report */ diff --git a/tests/unit/src/com/android/bluetooth/mapclient/ObexTimeTest.java b/tests/unit/src/com/android/bluetooth/mapclient/ObexTimeTest.java new file mode 100644 index 000000000..5ef2d455b --- /dev/null +++ b/tests/unit/src/com/android/bluetooth/mapclient/ObexTimeTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2019 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.mapclient; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Date; +import java.util.TimeZone; + +@RunWith(AndroidJUnit4.class) +public class ObexTimeTest { + private static final String TAG = ObexTimeTest.class.getSimpleName(); + + private static final String VALID_TIME_STRING = "20190101T121314"; + private static final String VALID_TIME_STRING_WITH_OFFSET_POS = "20190101T121314+0130"; + private static final String VALID_TIME_STRING_WITH_OFFSET_NEG = "20190101T121314-0130"; + + private static final String INVALID_TIME_STRING_OFFSET_EXTRA_DIGITS = "20190101T121314-99999"; + private static final String INVALID_TIME_STRING_BAD_DELIMITER = "20190101Q121314"; + + // MAP message listing times, per spec, use "local time basis" if UTC offset isn't given. The + // ObexTime class parses using the current default timezone (assumed to be the "local timezone") + // in the case that UTC isn't provided. However, the Date class assumes UTC ALWAYS when + // initializing off of a long value. We have to take that into account when determining our + // expected results for time strings that don't have an offset. + private static final long LOCAL_TIMEZONE_OFFSET = TimeZone.getDefault().getRawOffset(); + + // If you are a positive offset from GMT then GMT is in the "past" and you need to subtract that + // offset from the time. If you are negative then GMT is in the future and you need to add that + // offset to the time. + private static final long VALID_TS = 1546344794000L; // Jan 01, 2019 at 12:13:14 GMT + private static final long TS_OFFSET = 5400000L; // 1 Hour, 30 minutes -> milliseconds + private static final long VALID_TS_LOCAL_TZ = VALID_TS - LOCAL_TIMEZONE_OFFSET; + private static final long VALID_TS_OFFSET_POS = VALID_TS - TS_OFFSET; + private static final long VALID_TS_OFFSET_NEG = VALID_TS + TS_OFFSET; + + private static final Date VALID_DATE_LOCAL_TZ = new Date(VALID_TS_LOCAL_TZ); + private static final Date VALID_DATE_WITH_OFFSET_POS = new Date(VALID_TS_OFFSET_POS); + private static final Date VALID_DATE_WITH_OFFSET_NEG = new Date(VALID_TS_OFFSET_NEG); + + @Test + public void createWithValidDateTimeString_TimestampCorrect() { + ObexTime timestamp = new ObexTime(VALID_TIME_STRING); + Assert.assertEquals("Parsed timestamp must match expected", VALID_DATE_LOCAL_TZ, + timestamp.getTime()); + } + + @Test + public void createWithValidDateTimeStringWithPosOffset_TimestampCorrect() { + ObexTime timestamp = new ObexTime(VALID_TIME_STRING_WITH_OFFSET_POS); + Assert.assertEquals("Parsed timestamp must match expected", VALID_DATE_WITH_OFFSET_POS, + timestamp.getTime()); + } + + @Test + public void createWithValidDateTimeStringWithNegOffset_TimestampCorrect() { + ObexTime timestamp = new ObexTime(VALID_TIME_STRING_WITH_OFFSET_NEG); + Assert.assertEquals("Parsed timestamp must match expected", VALID_DATE_WITH_OFFSET_NEG, + timestamp.getTime()); + } + + @Test + public void createWithValidDate_TimestampCorrect() { + ObexTime timestamp = new ObexTime(VALID_DATE_LOCAL_TZ); + Assert.assertEquals("ObexTime created with a date must return the same date", + VALID_DATE_LOCAL_TZ, timestamp.getTime()); + } + + @Test + public void printValidTime_TimestampMatchesInput() { + ObexTime timestamp = new ObexTime(VALID_TIME_STRING); + Assert.assertEquals("Timestamp as a string must match the input string", VALID_TIME_STRING, + timestamp.toString()); + } + + @Test + public void createWithInvalidDelimiterString_TimestampIsNull() { + ObexTime timestamp = new ObexTime(INVALID_TIME_STRING_BAD_DELIMITER); + Assert.assertEquals("Parsed timestamp was invalid and must result in a null object", null, + timestamp.getTime()); + } + + @Test + public void createWithInvalidOffsetString_TimestampIsNull() { + ObexTime timestamp = new ObexTime(INVALID_TIME_STRING_OFFSET_EXTRA_DIGITS); + Assert.assertEquals("Parsed timestamp was invalid and must result in a null object", null, + timestamp.getTime()); + } + + @Test + public void printInvalidTime_ReturnsNull() { + ObexTime timestamp = new ObexTime(INVALID_TIME_STRING_BAD_DELIMITER); + Assert.assertEquals("Invalid timestamps must return null for toString()", null, + timestamp.toString()); + } +} diff --git a/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java b/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java index 6d4574f11..3573f847a 100644 --- a/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java +++ b/tests/unit/src/com/android/bluetooth/pan/PanServiceTest.java @@ -15,8 +15,12 @@ */ package com.android.bluetooth.pan; +import static org.mockito.Mockito.when; + import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; import android.content.Context; +import android.os.UserManager; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; @@ -47,6 +51,7 @@ public class PanServiceTest { @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); @Mock private AdapterService mAdapterService; + @Mock private UserManager mMockUserManager; @Before public void setUp() throws Exception { @@ -61,6 +66,7 @@ public class PanServiceTest { // Try getting the Bluetooth adapter mAdapter = BluetoothAdapter.getDefaultAdapter(); Assert.assertNotNull(mAdapter); + mService.mUserManager = mMockUserManager; } @After @@ -78,4 +84,11 @@ public class PanServiceTest { public void testInitialize() { Assert.assertNotNull(PanService.getPanService()); } + + @Test + public void testGuestUserConnect() { + BluetoothDevice device = TestUtils.getTestDevice(mAdapter, 0); + when(mMockUserManager.isGuestUser()).thenReturn(true); + Assert.assertFalse(mService.connect(device)); + } } |