Loading core/java/android/bluetooth/BluetoothMapClient.java +69 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,18 @@ public final class BluetoothMapClient implements BluetoothProfile { public static final String ACTION_MESSAGE_DELIVERED_SUCCESSFULLY = "android.bluetooth.mapmce.profile.action.MESSAGE_DELIVERED_SUCCESSFULLY"; /** * Action to notify read status changed */ public static final String ACTION_MESSAGE_READ_STATUS_CHANGED = "android.bluetooth.mapmce.profile.action.MESSAGE_READ_STATUS_CHANGED"; /** * Action to notify deleted status changed */ public static final String ACTION_MESSAGE_DELETED_STATUS_CHANGED = "android.bluetooth.mapmce.profile.action.MESSAGE_DELETED_STATUS_CHANGED"; /* Extras used in ACTION_MESSAGE_RECEIVED intent. * NOTE: HANDLE is only valid for a single session with the device. */ public static final String EXTRA_MESSAGE_HANDLE = Loading @@ -65,6 +77,25 @@ public final class BluetoothMapClient implements BluetoothProfile { public static final String EXTRA_SENDER_CONTACT_NAME = "android.bluetooth.mapmce.profile.extra.SENDER_CONTACT_NAME"; /** * Used as a boolean extra in ACTION_MESSAGE_DELETED_STATUS_CHANGED * Contains the MAP message deleted status * Possible values are: * true: deleted * false: undeleted */ public static final String EXTRA_MESSAGE_DELETED_STATUS = "android.bluetooth.mapmce.profile.extra.MESSAGE_DELETED_STATUS"; /** * Extra used in ACTION_MESSAGE_READ_STATUS_CHANGED or ACTION_MESSAGE_DELETED_STATUS_CHANGED * Possible values are: * 0: failure * 1: success */ public static final String EXTRA_RESULT_CODE = "android.bluetooth.device.extra.RESULT_CODE"; /** There was an error trying to obtain the state */ public static final int STATE_ERROR = -1; Loading @@ -75,6 +106,12 @@ public final class BluetoothMapClient implements BluetoothProfile { private static final int UPLOADING_FEATURE_BITMASK = 0x08; /** Parameters in setMessageStatus */ public static final int UNREAD = 0; public static final int READ = 1; public static final int UNDELETED = 2; public static final int DELETED = 3; private BluetoothAdapter mAdapter; private final BluetoothProfileConnector<IBluetoothMapClient> mProfileConnector = new BluetoothProfileConnector(this, BluetoothProfile.MAP_CLIENT, Loading Loading @@ -405,6 +442,38 @@ public final class BluetoothMapClient implements BluetoothProfile { return false; } /** * Set message status of message on MSE * <p> * When read status changed, the result will be published via * {@link #ACTION_MESSAGE_READ_STATUS_CHANGED} * When deleted status changed, the result will be published via * {@link #ACTION_MESSAGE_DELETED_STATUS_CHANGED} * * @param device Bluetooth device * @param handle message handle * @param status <code>UNREAD</code> for "unread", <code>READ</code> for * "read", <code>UNDELETED</code> for "undeleted", <code>DELETED</code> for * "deleted", otherwise return error * @return <code>true</code> if request has been sent, <code>false</code> on error * */ @RequiresPermission(Manifest.permission.READ_SMS) public boolean setMessageStatus(BluetoothDevice device, String handle, int status) { if (DBG) Log.d(TAG, "setMessageStatus(" + device + ", " + handle + ", " + status + ")"); final IBluetoothMapClient service = getService(); if (service != null && isEnabled() && isValidDevice(device) && handle != null && (status == READ || status == UNREAD || status == UNDELETED || status == DELETED)) { try { return service.setMessageStatus(device, handle, status); } catch (RemoteException e) { Log.e(TAG, Log.getStackTraceString(new Throwable())); return false; } } return false; } private boolean isEnabled() { BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) return true; Loading core/res/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -228,6 +228,8 @@ <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_RECEIVED" /> <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_SENT_SUCCESSFULLY" /> <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_DELIVERED_SUCCESSFULLY" /> <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_READ_STATUS_CHANGED" /> <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_DELETED_STATUS_CHANGED" /> <protected-broadcast android:name="com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_SENT" /> <protected-broadcast Loading core/tests/bluetoothtests/AndroidManifest.xml +5 −1 Original line number Diff line number Diff line Loading @@ -15,14 +15,18 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.bluetooth.tests" > package="com.android.bluetooth.tests" android:sharedUserId="android.uid.bluetooth" > <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_SMS"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> Loading core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java +24 −0 Original line number Diff line number Diff line Loading @@ -360,6 +360,30 @@ public class BluetoothStressTest extends InstrumentationTestCase { mTestUtils.unpair(mAdapter, device); } /* Make sure there is at least 1 unread message in the last week on remote device */ public void testMceSetMessageStatus() { int iterations = BluetoothTestRunner.sMceSetMessageStatusIterations; if (iterations == 0) { return; } BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); mTestUtils.enable(mAdapter); mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.MAP_CLIENT, null); mTestUtils.mceGetUnreadMessage(mAdapter, device); for (int i = 0; i < iterations; i++) { mTestUtils.mceSetMessageStatus(mAdapter, device, BluetoothMapClient.READ); mTestUtils.mceSetMessageStatus(mAdapter, device, BluetoothMapClient.UNREAD); } /** * It is hard to find device to support set undeleted status, so just * set deleted in 1 iteration **/ mTestUtils.mceSetMessageStatus(mAdapter, device, BluetoothMapClient.DELETED); } private void sleep(long time) { try { Thread.sleep(time); Loading core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestRunner.java +11 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import android.util.Log; * [-e connect_input_iterations <iterations>] \ * [-e connect_pan_iterations <iterations>] \ * [-e start_stop_sco_iterations <iterations>] \ * [-e mce_set_message_status_iterations <iterations>] \ * [-e pair_address <address>] \ * [-e headset_address <address>] \ * [-e a2dp_address <address>] \ Loading @@ -64,6 +65,7 @@ public class BluetoothTestRunner extends InstrumentationTestRunner { public static int sConnectInputIterations = 100; public static int sConnectPanIterations = 100; public static int sStartStopScoIterations = 100; public static int sMceSetMessageStatusIterations = 100; public static String sDeviceAddress = ""; public static byte[] sDevicePairPin = {'1', '2', '3', '4'}; Loading Loading @@ -173,6 +175,15 @@ public class BluetoothTestRunner extends InstrumentationTestRunner { } } val = arguments.getString("mce_set_message_status_iterations"); if (val != null) { try { sMceSetMessageStatusIterations = Integer.parseInt(val); } catch (NumberFormatException e) { // Invalid argument, fall back to default value } } val = arguments.getString("device_address"); if (val != null) { sDeviceAddress = val; Loading Loading
core/java/android/bluetooth/BluetoothMapClient.java +69 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,18 @@ public final class BluetoothMapClient implements BluetoothProfile { public static final String ACTION_MESSAGE_DELIVERED_SUCCESSFULLY = "android.bluetooth.mapmce.profile.action.MESSAGE_DELIVERED_SUCCESSFULLY"; /** * Action to notify read status changed */ public static final String ACTION_MESSAGE_READ_STATUS_CHANGED = "android.bluetooth.mapmce.profile.action.MESSAGE_READ_STATUS_CHANGED"; /** * Action to notify deleted status changed */ public static final String ACTION_MESSAGE_DELETED_STATUS_CHANGED = "android.bluetooth.mapmce.profile.action.MESSAGE_DELETED_STATUS_CHANGED"; /* Extras used in ACTION_MESSAGE_RECEIVED intent. * NOTE: HANDLE is only valid for a single session with the device. */ public static final String EXTRA_MESSAGE_HANDLE = Loading @@ -65,6 +77,25 @@ public final class BluetoothMapClient implements BluetoothProfile { public static final String EXTRA_SENDER_CONTACT_NAME = "android.bluetooth.mapmce.profile.extra.SENDER_CONTACT_NAME"; /** * Used as a boolean extra in ACTION_MESSAGE_DELETED_STATUS_CHANGED * Contains the MAP message deleted status * Possible values are: * true: deleted * false: undeleted */ public static final String EXTRA_MESSAGE_DELETED_STATUS = "android.bluetooth.mapmce.profile.extra.MESSAGE_DELETED_STATUS"; /** * Extra used in ACTION_MESSAGE_READ_STATUS_CHANGED or ACTION_MESSAGE_DELETED_STATUS_CHANGED * Possible values are: * 0: failure * 1: success */ public static final String EXTRA_RESULT_CODE = "android.bluetooth.device.extra.RESULT_CODE"; /** There was an error trying to obtain the state */ public static final int STATE_ERROR = -1; Loading @@ -75,6 +106,12 @@ public final class BluetoothMapClient implements BluetoothProfile { private static final int UPLOADING_FEATURE_BITMASK = 0x08; /** Parameters in setMessageStatus */ public static final int UNREAD = 0; public static final int READ = 1; public static final int UNDELETED = 2; public static final int DELETED = 3; private BluetoothAdapter mAdapter; private final BluetoothProfileConnector<IBluetoothMapClient> mProfileConnector = new BluetoothProfileConnector(this, BluetoothProfile.MAP_CLIENT, Loading Loading @@ -405,6 +442,38 @@ public final class BluetoothMapClient implements BluetoothProfile { return false; } /** * Set message status of message on MSE * <p> * When read status changed, the result will be published via * {@link #ACTION_MESSAGE_READ_STATUS_CHANGED} * When deleted status changed, the result will be published via * {@link #ACTION_MESSAGE_DELETED_STATUS_CHANGED} * * @param device Bluetooth device * @param handle message handle * @param status <code>UNREAD</code> for "unread", <code>READ</code> for * "read", <code>UNDELETED</code> for "undeleted", <code>DELETED</code> for * "deleted", otherwise return error * @return <code>true</code> if request has been sent, <code>false</code> on error * */ @RequiresPermission(Manifest.permission.READ_SMS) public boolean setMessageStatus(BluetoothDevice device, String handle, int status) { if (DBG) Log.d(TAG, "setMessageStatus(" + device + ", " + handle + ", " + status + ")"); final IBluetoothMapClient service = getService(); if (service != null && isEnabled() && isValidDevice(device) && handle != null && (status == READ || status == UNREAD || status == UNDELETED || status == DELETED)) { try { return service.setMessageStatus(device, handle, status); } catch (RemoteException e) { Log.e(TAG, Log.getStackTraceString(new Throwable())); return false; } } return false; } private boolean isEnabled() { BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) return true; Loading
core/res/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -228,6 +228,8 @@ <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_RECEIVED" /> <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_SENT_SUCCESSFULLY" /> <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_DELIVERED_SUCCESSFULLY" /> <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_READ_STATUS_CHANGED" /> <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_DELETED_STATUS_CHANGED" /> <protected-broadcast android:name="com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_SENT" /> <protected-broadcast Loading
core/tests/bluetoothtests/AndroidManifest.xml +5 −1 Original line number Diff line number Diff line Loading @@ -15,14 +15,18 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.bluetooth.tests" > package="com.android.bluetooth.tests" android:sharedUserId="android.uid.bluetooth" > <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_SMS"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> Loading
core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java +24 −0 Original line number Diff line number Diff line Loading @@ -360,6 +360,30 @@ public class BluetoothStressTest extends InstrumentationTestCase { mTestUtils.unpair(mAdapter, device); } /* Make sure there is at least 1 unread message in the last week on remote device */ public void testMceSetMessageStatus() { int iterations = BluetoothTestRunner.sMceSetMessageStatusIterations; if (iterations == 0) { return; } BluetoothDevice device = mAdapter.getRemoteDevice(BluetoothTestRunner.sDeviceAddress); mTestUtils.enable(mAdapter); mTestUtils.connectProfile(mAdapter, device, BluetoothProfile.MAP_CLIENT, null); mTestUtils.mceGetUnreadMessage(mAdapter, device); for (int i = 0; i < iterations; i++) { mTestUtils.mceSetMessageStatus(mAdapter, device, BluetoothMapClient.READ); mTestUtils.mceSetMessageStatus(mAdapter, device, BluetoothMapClient.UNREAD); } /** * It is hard to find device to support set undeleted status, so just * set deleted in 1 iteration **/ mTestUtils.mceSetMessageStatus(mAdapter, device, BluetoothMapClient.DELETED); } private void sleep(long time) { try { Thread.sleep(time); Loading
core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestRunner.java +11 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import android.util.Log; * [-e connect_input_iterations <iterations>] \ * [-e connect_pan_iterations <iterations>] \ * [-e start_stop_sco_iterations <iterations>] \ * [-e mce_set_message_status_iterations <iterations>] \ * [-e pair_address <address>] \ * [-e headset_address <address>] \ * [-e a2dp_address <address>] \ Loading @@ -64,6 +65,7 @@ public class BluetoothTestRunner extends InstrumentationTestRunner { public static int sConnectInputIterations = 100; public static int sConnectPanIterations = 100; public static int sStartStopScoIterations = 100; public static int sMceSetMessageStatusIterations = 100; public static String sDeviceAddress = ""; public static byte[] sDevicePairPin = {'1', '2', '3', '4'}; Loading Loading @@ -173,6 +175,15 @@ public class BluetoothTestRunner extends InstrumentationTestRunner { } } val = arguments.getString("mce_set_message_status_iterations"); if (val != null) { try { sMceSetMessageStatusIterations = Integer.parseInt(val); } catch (NumberFormatException e) { // Invalid argument, fall back to default value } } val = arguments.getString("device_address"); if (val != null) { sDeviceAddress = val; Loading