Loading android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java +11 −2 Original line number Diff line number Diff line Loading @@ -99,6 +99,10 @@ class MceStateMachine extends StateMachine { private static final String TAG = "MceStateMachine"; private static final Boolean DBG = MapClientService.DBG; // SAVE_OUTBOUND_MESSAGES defaults to true to place the responsibility of managing content on // Bluetooth, to work with the default Car Messenger. This may need to be set to false if the // messaging app takes that responsibility. private static final Boolean SAVE_OUTBOUND_MESSAGES = true; private static final int DISCONNECT_TIMEOUT = 3000; private static final int CONNECT_TIMEOUT = 10000; private static final int MAX_MESSAGES = 20; Loading Loading @@ -589,7 +593,8 @@ class MceStateMachine extends StateMachine { if (message.obj instanceof RequestGetMessage) { processInboundMessage((RequestGetMessage) message.obj); } else if (message.obj instanceof RequestPushMessage) { String messageHandle = ((RequestPushMessage) message.obj).getMsgHandle(); RequestPushMessage requestPushMessage = (RequestPushMessage) message.obj; String messageHandle = requestPushMessage.getMsgHandle(); if (DBG) { Log.d(TAG, "Message Sent......." + messageHandle); } Loading @@ -597,8 +602,12 @@ class MceStateMachine extends StateMachine { // some test devices don't populate messageHandle field. // in such cases, no need to wait up for response for such messages. if (messageHandle != null && messageHandle.length() > 2) { if (SAVE_OUTBOUND_MESSAGES) { mDatabase.storeMessage(requestPushMessage.getBMsg(), messageHandle, System.currentTimeMillis()); } mSentMessageLog.put(messageHandle.substring(2), ((RequestPushMessage) message.obj).getBMsg()); requestPushMessage.getBMsg()); } } else if (message.obj instanceof RequestGetMessagesListing) { processMessageListing((RequestGetMessagesListing) message.obj); Loading android/app/src/com/android/bluetooth/mapclient/obex/RequestPushMessage.java +3 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.bluetooth.mapclient; import com.android.bluetooth.mapclient.MasClient.CharsetType; import com.android.internal.annotations.VisibleForTesting; import java.io.IOException; import java.math.BigInteger; Loading @@ -26,7 +27,8 @@ import javax.obex.HeaderSet; import javax.obex.ResponseCodes; /* Place a message into current directory on MSE. */ final class RequestPushMessage extends Request { @VisibleForTesting public class RequestPushMessage extends Request { private static final String TYPE = "x-bt/message"; private Bmessage mMsg; Loading android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java +98 −7 Original line number Diff line number Diff line Loading @@ -23,12 +23,15 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothMapClient; import android.bluetooth.BluetoothProfile; import android.bluetooth.SdpMasRecord; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.provider.Telephony.Sms; import android.telephony.SubscriptionManager; import android.test.mock.MockContentProvider; import android.test.mock.MockContentResolver; Loading @@ -44,6 +47,9 @@ import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.vcard.VCardConstants; import com.android.vcard.VCardEntry; import com.android.vcard.VCardProperty; import org.junit.After; import org.junit.Assert; Loading @@ -54,13 +60,18 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.HashMap; import java.util.Map; @MediumTest @RunWith(AndroidJUnit4.class) public class MapClientStateMachineTest { private static final String TAG = "MapStateMachineTest"; private static final String FOLDER_SENT = "sent"; private static final int ASYNC_CALL_TIMEOUT_MILLIS = 100; private static final int DISCONNECT_TIMEOUT = 3000; Loading @@ -79,10 +90,13 @@ public class MapClientStateMachineTest { @Mock private MapClientService mMockMapClientService; private MockContentResolver mMockContentResolver; private MockContentProvider mMockContentProvider; private MockSmsContentProvider mMockContentProvider; @Mock private MasClient mMockMasClient; @Mock private RequestPushMessage mMockRequestPushMessage; @Mock private SubscriptionManager mMockSubscriptionManager; Loading @@ -90,12 +104,7 @@ public class MapClientStateMachineTest { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mTargetContext = InstrumentationRegistry.getTargetContext(); mMockContentProvider = new MockContentProvider(mTargetContext) { @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } }; mMockContentProvider = new MockSmsContentProvider(); mMockContentResolver = new MockContentResolver(); Assume.assumeTrue("Ignore test when MapClientService is not enabled", Loading Loading @@ -321,6 +330,59 @@ public class MapClientStateMachineTest { Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, mMceStateMachine.getState()); } /** * Test sending a message */ @Test public void testSendSMSMessage() { setupSdpRecordReceipt(); Message msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_CONNECTED); mMceStateMachine.sendMessage(msg); TestUtils.waitForLooperToFinishScheduledTask(mMceStateMachine.getHandler().getLooper()); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mMceStateMachine.getState()); String testMessage = "Hello World!"; Uri[] contacts = new Uri[] {Uri.parse("tel://5551212")}; verify(mMockMasClient, times(0)).makeRequest(any(RequestPushMessage.class)); mMceStateMachine.sendMapMessage(contacts, testMessage, null, null); verify(mMockMasClient, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .makeRequest(any(RequestPushMessage.class)); } /** * Test message sent successfully */ @Test public void testSMSMessageSent() { setupSdpRecordReceipt(); Message msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_CONNECTED); mMceStateMachine.sendMessage(msg); TestUtils.waitForLooperToFinishScheduledTask(mMceStateMachine.getHandler().getLooper()); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mMceStateMachine.getState()); String testMessage = "Hello World!"; VCardEntry recipient = new VCardEntry(); VCardProperty property = new VCardProperty(); property.setName(VCardConstants.PROPERTY_TEL); property.addValues("555-1212"); recipient.addProperty(property); Bmessage testBmessage = new Bmessage(); testBmessage.setType(Bmessage.Type.SMS_GSM); testBmessage.setBodyContent(testMessage); testBmessage.addRecipient(recipient); RequestPushMessage testRequest = new RequestPushMessage(FOLDER_SENT, testBmessage, null, false, false); when(mMockRequestPushMessage.getMsgHandle()).thenReturn("12345"); when(mMockRequestPushMessage.getBMsg()).thenReturn(testBmessage); Message msgSent = Message.obtain(mHandler, MceStateMachine.MSG_MAS_REQUEST_COMPLETED, mMockRequestPushMessage); mMceStateMachine.sendMessage(msgSent); TestUtils.waitForLooperToFinishScheduledTask(mMceStateMachine.getHandler().getLooper()); Assert.assertEquals(1, mMockContentProvider.mInsertOperationCount); } private void setupSdpRecordReceipt() { // Perform first part of MAP connection logic. verify(mMockMapClientService, Loading @@ -334,4 +396,33 @@ public class MapClientStateMachineTest { mMceStateMachine.sendMessage(msg); } private class MockSmsContentProvider extends MockContentProvider { Map<Uri, ContentValues> mContentValues = new HashMap<>(); int mInsertOperationCount = 0; @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public Uri insert(Uri uri, ContentValues values) { mInsertOperationCount++; return Uri.withAppendedPath(Sms.CONTENT_URI, String.valueOf(mInsertOperationCount)); } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor cursor = Mockito.mock(Cursor.class); when(cursor.moveToFirst()).thenReturn(true); when(cursor.moveToNext()).thenReturn(true).thenReturn(false); when(cursor.getLong(anyInt())).thenReturn((long) mContentValues.size()); when(cursor.getString(anyInt())).thenReturn(String.valueOf(mContentValues.size())); return cursor; } } } Loading
android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java +11 −2 Original line number Diff line number Diff line Loading @@ -99,6 +99,10 @@ class MceStateMachine extends StateMachine { private static final String TAG = "MceStateMachine"; private static final Boolean DBG = MapClientService.DBG; // SAVE_OUTBOUND_MESSAGES defaults to true to place the responsibility of managing content on // Bluetooth, to work with the default Car Messenger. This may need to be set to false if the // messaging app takes that responsibility. private static final Boolean SAVE_OUTBOUND_MESSAGES = true; private static final int DISCONNECT_TIMEOUT = 3000; private static final int CONNECT_TIMEOUT = 10000; private static final int MAX_MESSAGES = 20; Loading Loading @@ -589,7 +593,8 @@ class MceStateMachine extends StateMachine { if (message.obj instanceof RequestGetMessage) { processInboundMessage((RequestGetMessage) message.obj); } else if (message.obj instanceof RequestPushMessage) { String messageHandle = ((RequestPushMessage) message.obj).getMsgHandle(); RequestPushMessage requestPushMessage = (RequestPushMessage) message.obj; String messageHandle = requestPushMessage.getMsgHandle(); if (DBG) { Log.d(TAG, "Message Sent......." + messageHandle); } Loading @@ -597,8 +602,12 @@ class MceStateMachine extends StateMachine { // some test devices don't populate messageHandle field. // in such cases, no need to wait up for response for such messages. if (messageHandle != null && messageHandle.length() > 2) { if (SAVE_OUTBOUND_MESSAGES) { mDatabase.storeMessage(requestPushMessage.getBMsg(), messageHandle, System.currentTimeMillis()); } mSentMessageLog.put(messageHandle.substring(2), ((RequestPushMessage) message.obj).getBMsg()); requestPushMessage.getBMsg()); } } else if (message.obj instanceof RequestGetMessagesListing) { processMessageListing((RequestGetMessagesListing) message.obj); Loading
android/app/src/com/android/bluetooth/mapclient/obex/RequestPushMessage.java +3 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.bluetooth.mapclient; import com.android.bluetooth.mapclient.MasClient.CharsetType; import com.android.internal.annotations.VisibleForTesting; import java.io.IOException; import java.math.BigInteger; Loading @@ -26,7 +27,8 @@ import javax.obex.HeaderSet; import javax.obex.ResponseCodes; /* Place a message into current directory on MSE. */ final class RequestPushMessage extends Request { @VisibleForTesting public class RequestPushMessage extends Request { private static final String TYPE = "x-bt/message"; private Bmessage mMsg; Loading
android/app/tests/unit/src/com/android/bluetooth/mapclient/MapClientStateMachineTest.java +98 −7 Original line number Diff line number Diff line Loading @@ -23,12 +23,15 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothMapClient; import android.bluetooth.BluetoothProfile; import android.bluetooth.SdpMasRecord; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.provider.Telephony.Sms; import android.telephony.SubscriptionManager; import android.test.mock.MockContentProvider; import android.test.mock.MockContentResolver; Loading @@ -44,6 +47,9 @@ import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.vcard.VCardConstants; import com.android.vcard.VCardEntry; import com.android.vcard.VCardProperty; import org.junit.After; import org.junit.Assert; Loading @@ -54,13 +60,18 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.HashMap; import java.util.Map; @MediumTest @RunWith(AndroidJUnit4.class) public class MapClientStateMachineTest { private static final String TAG = "MapStateMachineTest"; private static final String FOLDER_SENT = "sent"; private static final int ASYNC_CALL_TIMEOUT_MILLIS = 100; private static final int DISCONNECT_TIMEOUT = 3000; Loading @@ -79,10 +90,13 @@ public class MapClientStateMachineTest { @Mock private MapClientService mMockMapClientService; private MockContentResolver mMockContentResolver; private MockContentProvider mMockContentProvider; private MockSmsContentProvider mMockContentProvider; @Mock private MasClient mMockMasClient; @Mock private RequestPushMessage mMockRequestPushMessage; @Mock private SubscriptionManager mMockSubscriptionManager; Loading @@ -90,12 +104,7 @@ public class MapClientStateMachineTest { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mTargetContext = InstrumentationRegistry.getTargetContext(); mMockContentProvider = new MockContentProvider(mTargetContext) { @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } }; mMockContentProvider = new MockSmsContentProvider(); mMockContentResolver = new MockContentResolver(); Assume.assumeTrue("Ignore test when MapClientService is not enabled", Loading Loading @@ -321,6 +330,59 @@ public class MapClientStateMachineTest { Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, mMceStateMachine.getState()); } /** * Test sending a message */ @Test public void testSendSMSMessage() { setupSdpRecordReceipt(); Message msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_CONNECTED); mMceStateMachine.sendMessage(msg); TestUtils.waitForLooperToFinishScheduledTask(mMceStateMachine.getHandler().getLooper()); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mMceStateMachine.getState()); String testMessage = "Hello World!"; Uri[] contacts = new Uri[] {Uri.parse("tel://5551212")}; verify(mMockMasClient, times(0)).makeRequest(any(RequestPushMessage.class)); mMceStateMachine.sendMapMessage(contacts, testMessage, null, null); verify(mMockMasClient, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(1)) .makeRequest(any(RequestPushMessage.class)); } /** * Test message sent successfully */ @Test public void testSMSMessageSent() { setupSdpRecordReceipt(); Message msg = Message.obtain(mHandler, MceStateMachine.MSG_MAS_CONNECTED); mMceStateMachine.sendMessage(msg); TestUtils.waitForLooperToFinishScheduledTask(mMceStateMachine.getHandler().getLooper()); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mMceStateMachine.getState()); String testMessage = "Hello World!"; VCardEntry recipient = new VCardEntry(); VCardProperty property = new VCardProperty(); property.setName(VCardConstants.PROPERTY_TEL); property.addValues("555-1212"); recipient.addProperty(property); Bmessage testBmessage = new Bmessage(); testBmessage.setType(Bmessage.Type.SMS_GSM); testBmessage.setBodyContent(testMessage); testBmessage.addRecipient(recipient); RequestPushMessage testRequest = new RequestPushMessage(FOLDER_SENT, testBmessage, null, false, false); when(mMockRequestPushMessage.getMsgHandle()).thenReturn("12345"); when(mMockRequestPushMessage.getBMsg()).thenReturn(testBmessage); Message msgSent = Message.obtain(mHandler, MceStateMachine.MSG_MAS_REQUEST_COMPLETED, mMockRequestPushMessage); mMceStateMachine.sendMessage(msgSent); TestUtils.waitForLooperToFinishScheduledTask(mMceStateMachine.getHandler().getLooper()); Assert.assertEquals(1, mMockContentProvider.mInsertOperationCount); } private void setupSdpRecordReceipt() { // Perform first part of MAP connection logic. verify(mMockMapClientService, Loading @@ -334,4 +396,33 @@ public class MapClientStateMachineTest { mMceStateMachine.sendMessage(msg); } private class MockSmsContentProvider extends MockContentProvider { Map<Uri, ContentValues> mContentValues = new HashMap<>(); int mInsertOperationCount = 0; @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public Uri insert(Uri uri, ContentValues values) { mInsertOperationCount++; return Uri.withAppendedPath(Sms.CONTENT_URI, String.valueOf(mInsertOperationCount)); } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor cursor = Mockito.mock(Cursor.class); when(cursor.moveToFirst()).thenReturn(true); when(cursor.moveToNext()).thenReturn(true).thenReturn(false); when(cursor.getLong(anyInt())).thenReturn((long) mContentValues.size()); when(cursor.getString(anyInt())).thenReturn(String.valueOf(mContentValues.size())); return cursor; } } }