Loading android/app/src/com/android/bluetooth/avrcp/Avrcp.java +146 −41 Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ public final class Avrcp { private Context mContext; private final AudioManager mAudioManager; private AvrcpMessageHandler mHandler; private volatile AvrcpMessageHandler mHandler; private Handler mAudioManagerPlaybackHandler; private AudioManagerPlaybackListener mAudioManagerPlaybackCb; private MediaSessionManager mMediaSessionManager; Loading Loading @@ -383,12 +383,12 @@ public final class Avrcp { mAudioManagerPlaybackHandler.removeCallbacksAndMessages(null); mHandler.removeCallbacksAndMessages(null); Looper looper = mHandler.getLooper(); mHandler = null; if (looper != null) { looper.quit(); looper.quitSafely(); } mAudioManagerPlaybackHandler = null; mHandler = null; mContext.unregisterReceiver(mAvrcpReceiver); mContext.unregisterReceiver(mBootReceiver); Loading Loading @@ -466,8 +466,15 @@ public final class Avrcp { return; } Log.v(TAG, "onQueueChanged: NowPlaying list changed, Queue Size = " + queue.size()); mHandler.sendEmptyMessage(MSG_NOW_PLAYING_CHANGED_RSP); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "onQueueChanged: mHandler is already null"); return; } Log.v(TAG, "onQueueChanged: NowPlaying list changed, Queue Size = " + queue.size()); handler.sendEmptyMessage(MSG_NOW_PLAYING_CHANGED_RSP); } } Loading Loading @@ -601,9 +608,9 @@ public final class Avrcp { Log.v(TAG, "remote inital volume too high " + volIndex + ">" + mAbsVolThreshold); } Message msg1 = mHandler.obtainMessage(MSG_SET_ABSOLUTE_VOLUME, Message msg1 = this.obtainMessage(MSG_SET_ABSOLUTE_VOLUME, mAbsVolThreshold, 0); mHandler.sendMessage(msg1); this.sendMessage(msg1); mRemoteVolume = absVol; mLocalVolume = volIndex; break; Loading Loading @@ -1220,15 +1227,27 @@ public final class Avrcp { } private void getRcFeaturesRequestFromNative(byte[] address, int features) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_GET_RC_FEATURES, features, 0, final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "getRcFeaturesRequestFromNative: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_RC_FEATURES, features, 0, Utils.getAddressStringFromByte(address)); mHandler.sendMessage(msg); handler.sendMessage(msg); } private void getPlayStatusRequestFromNative(byte[] address) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_GET_PLAY_STATUS); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "getPlayStatusRequestFromNative: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_PLAY_STATUS); msg.obj = address; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void getElementAttrRequestFromNative(byte[] address, byte numAttr, int[] attrs) { Loading @@ -1240,9 +1259,16 @@ public final class Avrcp { } private void registerNotificationRequestFromNative(byte[] address, int eventId, int param) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_REGISTER_NOTIFICATION, eventId, param); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) { Log.d(TAG, "registerNotificationRequestFromNative: mHandler is already null"); } return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_REGISTER_NOTIFICATION, eventId, param); msg.obj = address; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void processRegisterNotification(byte[] address, int eventId, int param) { Loading Loading @@ -1310,8 +1336,16 @@ public final class Avrcp { } private void handlePassthroughCmdRequestFromNative(byte[] address, int id, int keyState) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_PASS_THROUGH, id, keyState); mHandler.sendMessage(msg); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) { Log.d(TAG, "handlePassthroughCmdRequestFromNative: mHandler is already null"); } return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_PASS_THROUGH, id, keyState); handler.sendMessage(msg); } private void sendTrackChangedRsp(boolean registering) { Loading Loading @@ -1380,6 +1414,12 @@ public final class Avrcp { return; } final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "sendPlayPosNotificationRsp: handler is already null"); return; } long playPositionMs = getPlayPosition(); String debugLine = "sendPlayPosNotificationRsp: "; Loading Loading @@ -1413,10 +1453,10 @@ public final class Avrcp { } } mHandler.removeMessages(MSG_PLAY_INTERVAL_TIMEOUT); handler.removeMessages(MSG_PLAY_INTERVAL_TIMEOUT); if (mPlayPosChangedNT == AvrcpConstants.NOTIFICATION_TYPE_INTERIM && isPlayingState( mCurrentPlayState)) { Message msg = mHandler.obtainMessage(MSG_PLAY_INTERVAL_TIMEOUT); Message msg = handler.obtainMessage(MSG_PLAY_INTERVAL_TIMEOUT); long delay = mPlaybackIntervalMs; if (mNextPosMs != -1) { delay = mNextPosMs - (playPositionMs > 0 ? playPositionMs : 0); Loading @@ -1424,7 +1464,7 @@ public final class Avrcp { if (DEBUG) { debugLine += " Timeout " + delay + "ms"; } mHandler.sendMessageDelayed(msg, delay); handler.sendMessageDelayed(msg, delay); } if (DEBUG) { Log.d(TAG, debugLine); Loading @@ -1444,8 +1484,14 @@ public final class Avrcp { * requesting our handler to call setVolumeNative() */ public void adjustVolume(int direction) { Message msg = mHandler.obtainMessage(MSG_ADJUST_VOLUME, direction, 0); mHandler.sendMessage(msg); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "adjustVolume: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_ADJUST_VOLUME, direction, 0); handler.sendMessage(msg); } public void setAbsoluteVolume(int volume) { Loading @@ -1456,9 +1502,15 @@ public final class Avrcp { return; } mHandler.removeMessages(MSG_ADJUST_VOLUME); Message msg = mHandler.obtainMessage(MSG_SET_ABSOLUTE_VOLUME, volume, 0); mHandler.sendMessage(msg); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "setAbsoluteVolume: mHandler is already null"); return; } handler.removeMessages(MSG_ADJUST_VOLUME); Message msg = handler.obtainMessage(MSG_SET_ABSOLUTE_VOLUME, volume, 0); handler.sendMessage(msg); } /* Called in the native layer as a btrc_callback to return the volume set on the carkit in the Loading @@ -1469,54 +1521,88 @@ public final class Avrcp { * AudioService to update the UI */ private void volumeChangeRequestFromNative(byte[] address, int volume, int ctype) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_VOLUME_CHANGE, volume, ctype); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "volumeChangeRequestFromNative: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_VOLUME_CHANGE, volume, ctype); Bundle data = new Bundle(); data.putByteArray("BdAddress", address); msg.setData(data); mHandler.sendMessage(msg); handler.sendMessage(msg); } private void getFolderItemsRequestFromNative(byte[] address, byte scope, long startItem, long endItem, byte numAttr, int[] attrIds) { final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "getFolderItemsRequestFromNative: mHandler is already null"); return; } AvrcpCmd avrcpCmdobj = new AvrcpCmd(); AvrcpCmd.FolderItemsCmd folderObj = avrcpCmdobj.new FolderItemsCmd(address, scope, startItem, endItem, numAttr, attrIds); Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_GET_FOLDER_ITEMS, 0, 0); Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_FOLDER_ITEMS, 0, 0); msg.obj = folderObj; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void setAddressedPlayerRequestFromNative(byte[] address, int playerId) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_SET_ADDR_PLAYER, playerId, 0); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "setAddressedPlayerRequestFromNative: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_SET_ADDR_PLAYER, playerId, 0); msg.obj = address; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void setBrowsedPlayerRequestFromNative(byte[] address, int playerId) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_SET_BR_PLAYER, playerId, 0); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "setBrowsedPlayerRequestFromNative: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_SET_BR_PLAYER, playerId, 0); msg.obj = address; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void changePathRequestFromNative(byte[] address, byte direction, byte[] folderUid) { final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "changePathRequestFromNative: mHandler is already null"); return; } Bundle data = new Bundle(); Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_CHANGE_PATH); Message msg = handler.obtainMessage(MSG_NATIVE_REQ_CHANGE_PATH); data.putByteArray("BdAddress", address); data.putByteArray("folderUid", folderUid); data.putByte("direction", direction); msg.setData(data); mHandler.sendMessage(msg); handler.sendMessage(msg); } private void getItemAttrRequestFromNative(byte[] address, byte scope, byte[] itemUid, int uidCounter, byte numAttr, int[] attrs) { final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "getItemAttrRequestFromNative: mHandler is already null"); return; } AvrcpCmd avrcpCmdobj = new AvrcpCmd(); AvrcpCmd.ItemAttrCmd itemAttr = avrcpCmdobj.new ItemAttrCmd(address, scope, itemUid, uidCounter, numAttr, attrs); Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_GET_ITEM_ATTR); Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_ITEM_ATTR); msg.obj = itemAttr; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void searchRequestFromNative(byte[] address, int charsetId, byte[] searchStr) { Loading @@ -1526,14 +1612,21 @@ public final class Avrcp { } private void playItemRequestFromNative(byte[] address, byte scope, int uidCounter, byte[] uid) { final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "playItemRequestFromNative: mHandler is already null"); return; } Bundle data = new Bundle(); Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_PLAY_ITEM); Message msg = handler.obtainMessage(MSG_NATIVE_REQ_PLAY_ITEM); data.putByteArray("BdAddress", address); data.putByteArray("uid", uid); data.putInt("uidCounter", uidCounter); data.putByte("scope", scope); msg.setData(data); mHandler.sendMessage(msg); handler.sendMessage(msg); } private void addToPlayListRequestFromNative(byte[] address, byte scope, byte[] uid, Loading @@ -1544,11 +1637,17 @@ public final class Avrcp { } private void getTotalNumOfItemsRequestFromNative(byte[] address, byte scope) { final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "getTotalNumOfItemsRequestFromNative: mHandler is already null"); return; } Bundle data = new Bundle(); Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_GET_TOTAL_NUM_OF_ITEMS); Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_TOTAL_NUM_OF_ITEMS); msg.arg1 = scope; msg.obj = address; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void notifyVolumeChanged(int volume) { Loading Loading @@ -1600,8 +1699,14 @@ public final class Avrcp { * This is called from A2dpStateMachine to set A2dp audio state. */ public void setA2dpAudioState(int state) { Message msg = mHandler.obtainMessage(MSG_SET_A2DP_AUDIO_STATE, state, 0); mHandler.sendMessage(msg); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "setA2dpAudioState: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_SET_A2DP_AUDIO_STATE, state, 0); handler.sendMessage(msg); } private class AvrcpServiceBootReceiver extends BroadcastReceiver { Loading android/app/tests/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := BluetoothInstrumentationTests LOCAL_COMPATIBILITY_SUITE := device-tests LOCAL_INSTRUMENTATION_FOR := Bluetooth include $(BUILD_PACKAGE) android/app/tests/AndroidTest.xml 0 → 100644 +27 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright 2017 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. --> <configuration description="Runs Bluetooth Test Cases."> <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> <option name="test-file-name" value="BluetoothInstrumentationTests.apk" /> </target_preparer> <option name="test-suite-tag" value="apct" /> <option name="test-tag" value="BluetoothInstrumentationTests" /> <test class="com.android.tradefed.testtype.InstrumentationTest" > <option name="package" value="com.android.bluetooth.tests" /> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> </test> </configuration> No newline at end of file android/app/tests/src/com/android/bluetooth/core/FileSystemWriteTest.java→android/app/tests/src/com/android/bluetooth/FileSystemWriteTest.java +67 −0 Original line number Diff line number Diff line /* * Copyright 2017 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; import android.support.test.filters.MediumTest; import android.test.AndroidTestCase; import android.support.test.runner.AndroidJUnit4; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import java.io.File; import java.io.IOException; /** * Test Bluetooth's ability to write to the different directories that it * is supposed to own */ @MediumTest // Test Bluetooth's ability to write to the different directories that it // is supposed to own public class FileSystemWriteTest extends AndroidTestCase { @RunWith(AndroidJUnit4.class) public class FileSystemWriteTest { @Test public void testBluetoothDirWrite() { try { File file = new File("/data/misc/bluetooth/test.file"); assertTrue("File not created", file.createNewFile()); Assert.assertTrue("File not created", file.createNewFile()); file.delete(); } catch (IOException e) { fail("Exception creating file /data/misc/bluetooth/test.file: " + e); Assert.fail("Exception creating file /data/misc/bluetooth/test.file: " + e); } } @Test public void testBluedroidDirWrite() { try { File file = new File("/data/misc/bluedroid/test.file"); assertTrue("File not created", file.createNewFile()); Assert.assertTrue("File not created", file.createNewFile()); file.delete(); } catch (IOException e) { fail("Exception creating file /data/misc/bluedroid/test.file: " + e); Assert.fail("Exception creating file /data/misc/bluedroid/test.file: " + e); } } @Test public void testBluetoothLogsDirWrite() { try { File file = new File("/data/misc/bluetooth/logs/test.file"); assertTrue("File not created", file.createNewFile()); Assert.assertTrue("File not created", file.createNewFile()); file.delete(); } catch (IOException e) { fail("Exception creating file /data/misc/bluetooth/logs/test.file: " + e); Assert.fail("Exception creating file /data/misc/bluetooth/logs/test.file: " + e); } } } android/app/tests/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java +13 −18 Original line number Diff line number Diff line Loading @@ -22,40 +22,37 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; import android.media.AudioManager; import android.media.AudioManager.OnAudioFocusChangeListener; import android.os.HandlerThread; import android.os.Looper; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.MediumTest; import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.mockito.MockitoAnnotations; @MediumTest @RunWith(MockitoJUnitRunner.class) public class A2dpSinkStreamHandlerTest extends AndroidTestCase { static final int DUCK_PERCENT = 75; @RunWith(AndroidJUnit4.class) public class A2dpSinkStreamHandlerTest { private static final int DUCK_PERCENT = 75; private HandlerThread mHandlerThread; A2dpSinkStreamHandler mStreamHandler; ArgumentCaptor<OnAudioFocusChangeListener> mAudioFocusChangeListenerArgumentCaptor; private A2dpSinkStreamHandler mStreamHandler; @Mock Context mMockContext; @Mock private Context mMockContext; @Mock A2dpSinkStateMachine mMockA2dpSink; @Mock private A2dpSinkStateMachine mMockA2dpSink; @Mock AudioManager mMockAudioManager; @Mock private AudioManager mMockAudioManager; @Mock Resources mMockResources; @Mock private Resources mMockResources; @Mock PackageManager mMockPackageManager; @Mock private PackageManager mMockPackageManager; @Override @Before public void setUp() { MockitoAnnotations.initMocks(this); // Mock the looper if (Looper.myLooper() == null) { Looper.prepare(); Loading @@ -64,8 +61,6 @@ public class A2dpSinkStreamHandlerTest extends AndroidTestCase { mHandlerThread = new HandlerThread("A2dpSinkStreamHandlerTest"); mHandlerThread.start(); mAudioFocusChangeListenerArgumentCaptor = ArgumentCaptor.forClass(OnAudioFocusChangeListener.class); when(mMockContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mMockAudioManager); when(mMockContext.getResources()).thenReturn(mMockResources); when(mMockResources.getInteger(anyInt())).thenReturn(DUCK_PERCENT); Loading Loading
android/app/src/com/android/bluetooth/avrcp/Avrcp.java +146 −41 Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ public final class Avrcp { private Context mContext; private final AudioManager mAudioManager; private AvrcpMessageHandler mHandler; private volatile AvrcpMessageHandler mHandler; private Handler mAudioManagerPlaybackHandler; private AudioManagerPlaybackListener mAudioManagerPlaybackCb; private MediaSessionManager mMediaSessionManager; Loading Loading @@ -383,12 +383,12 @@ public final class Avrcp { mAudioManagerPlaybackHandler.removeCallbacksAndMessages(null); mHandler.removeCallbacksAndMessages(null); Looper looper = mHandler.getLooper(); mHandler = null; if (looper != null) { looper.quit(); looper.quitSafely(); } mAudioManagerPlaybackHandler = null; mHandler = null; mContext.unregisterReceiver(mAvrcpReceiver); mContext.unregisterReceiver(mBootReceiver); Loading Loading @@ -466,8 +466,15 @@ public final class Avrcp { return; } Log.v(TAG, "onQueueChanged: NowPlaying list changed, Queue Size = " + queue.size()); mHandler.sendEmptyMessage(MSG_NOW_PLAYING_CHANGED_RSP); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "onQueueChanged: mHandler is already null"); return; } Log.v(TAG, "onQueueChanged: NowPlaying list changed, Queue Size = " + queue.size()); handler.sendEmptyMessage(MSG_NOW_PLAYING_CHANGED_RSP); } } Loading Loading @@ -601,9 +608,9 @@ public final class Avrcp { Log.v(TAG, "remote inital volume too high " + volIndex + ">" + mAbsVolThreshold); } Message msg1 = mHandler.obtainMessage(MSG_SET_ABSOLUTE_VOLUME, Message msg1 = this.obtainMessage(MSG_SET_ABSOLUTE_VOLUME, mAbsVolThreshold, 0); mHandler.sendMessage(msg1); this.sendMessage(msg1); mRemoteVolume = absVol; mLocalVolume = volIndex; break; Loading Loading @@ -1220,15 +1227,27 @@ public final class Avrcp { } private void getRcFeaturesRequestFromNative(byte[] address, int features) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_GET_RC_FEATURES, features, 0, final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "getRcFeaturesRequestFromNative: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_RC_FEATURES, features, 0, Utils.getAddressStringFromByte(address)); mHandler.sendMessage(msg); handler.sendMessage(msg); } private void getPlayStatusRequestFromNative(byte[] address) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_GET_PLAY_STATUS); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "getPlayStatusRequestFromNative: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_PLAY_STATUS); msg.obj = address; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void getElementAttrRequestFromNative(byte[] address, byte numAttr, int[] attrs) { Loading @@ -1240,9 +1259,16 @@ public final class Avrcp { } private void registerNotificationRequestFromNative(byte[] address, int eventId, int param) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_REGISTER_NOTIFICATION, eventId, param); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) { Log.d(TAG, "registerNotificationRequestFromNative: mHandler is already null"); } return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_REGISTER_NOTIFICATION, eventId, param); msg.obj = address; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void processRegisterNotification(byte[] address, int eventId, int param) { Loading Loading @@ -1310,8 +1336,16 @@ public final class Avrcp { } private void handlePassthroughCmdRequestFromNative(byte[] address, int id, int keyState) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_PASS_THROUGH, id, keyState); mHandler.sendMessage(msg); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) { Log.d(TAG, "handlePassthroughCmdRequestFromNative: mHandler is already null"); } return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_PASS_THROUGH, id, keyState); handler.sendMessage(msg); } private void sendTrackChangedRsp(boolean registering) { Loading Loading @@ -1380,6 +1414,12 @@ public final class Avrcp { return; } final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "sendPlayPosNotificationRsp: handler is already null"); return; } long playPositionMs = getPlayPosition(); String debugLine = "sendPlayPosNotificationRsp: "; Loading Loading @@ -1413,10 +1453,10 @@ public final class Avrcp { } } mHandler.removeMessages(MSG_PLAY_INTERVAL_TIMEOUT); handler.removeMessages(MSG_PLAY_INTERVAL_TIMEOUT); if (mPlayPosChangedNT == AvrcpConstants.NOTIFICATION_TYPE_INTERIM && isPlayingState( mCurrentPlayState)) { Message msg = mHandler.obtainMessage(MSG_PLAY_INTERVAL_TIMEOUT); Message msg = handler.obtainMessage(MSG_PLAY_INTERVAL_TIMEOUT); long delay = mPlaybackIntervalMs; if (mNextPosMs != -1) { delay = mNextPosMs - (playPositionMs > 0 ? playPositionMs : 0); Loading @@ -1424,7 +1464,7 @@ public final class Avrcp { if (DEBUG) { debugLine += " Timeout " + delay + "ms"; } mHandler.sendMessageDelayed(msg, delay); handler.sendMessageDelayed(msg, delay); } if (DEBUG) { Log.d(TAG, debugLine); Loading @@ -1444,8 +1484,14 @@ public final class Avrcp { * requesting our handler to call setVolumeNative() */ public void adjustVolume(int direction) { Message msg = mHandler.obtainMessage(MSG_ADJUST_VOLUME, direction, 0); mHandler.sendMessage(msg); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "adjustVolume: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_ADJUST_VOLUME, direction, 0); handler.sendMessage(msg); } public void setAbsoluteVolume(int volume) { Loading @@ -1456,9 +1502,15 @@ public final class Avrcp { return; } mHandler.removeMessages(MSG_ADJUST_VOLUME); Message msg = mHandler.obtainMessage(MSG_SET_ABSOLUTE_VOLUME, volume, 0); mHandler.sendMessage(msg); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "setAbsoluteVolume: mHandler is already null"); return; } handler.removeMessages(MSG_ADJUST_VOLUME); Message msg = handler.obtainMessage(MSG_SET_ABSOLUTE_VOLUME, volume, 0); handler.sendMessage(msg); } /* Called in the native layer as a btrc_callback to return the volume set on the carkit in the Loading @@ -1469,54 +1521,88 @@ public final class Avrcp { * AudioService to update the UI */ private void volumeChangeRequestFromNative(byte[] address, int volume, int ctype) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_VOLUME_CHANGE, volume, ctype); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "volumeChangeRequestFromNative: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_VOLUME_CHANGE, volume, ctype); Bundle data = new Bundle(); data.putByteArray("BdAddress", address); msg.setData(data); mHandler.sendMessage(msg); handler.sendMessage(msg); } private void getFolderItemsRequestFromNative(byte[] address, byte scope, long startItem, long endItem, byte numAttr, int[] attrIds) { final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "getFolderItemsRequestFromNative: mHandler is already null"); return; } AvrcpCmd avrcpCmdobj = new AvrcpCmd(); AvrcpCmd.FolderItemsCmd folderObj = avrcpCmdobj.new FolderItemsCmd(address, scope, startItem, endItem, numAttr, attrIds); Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_GET_FOLDER_ITEMS, 0, 0); Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_FOLDER_ITEMS, 0, 0); msg.obj = folderObj; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void setAddressedPlayerRequestFromNative(byte[] address, int playerId) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_SET_ADDR_PLAYER, playerId, 0); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "setAddressedPlayerRequestFromNative: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_SET_ADDR_PLAYER, playerId, 0); msg.obj = address; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void setBrowsedPlayerRequestFromNative(byte[] address, int playerId) { Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_SET_BR_PLAYER, playerId, 0); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "setBrowsedPlayerRequestFromNative: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_NATIVE_REQ_SET_BR_PLAYER, playerId, 0); msg.obj = address; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void changePathRequestFromNative(byte[] address, byte direction, byte[] folderUid) { final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "changePathRequestFromNative: mHandler is already null"); return; } Bundle data = new Bundle(); Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_CHANGE_PATH); Message msg = handler.obtainMessage(MSG_NATIVE_REQ_CHANGE_PATH); data.putByteArray("BdAddress", address); data.putByteArray("folderUid", folderUid); data.putByte("direction", direction); msg.setData(data); mHandler.sendMessage(msg); handler.sendMessage(msg); } private void getItemAttrRequestFromNative(byte[] address, byte scope, byte[] itemUid, int uidCounter, byte numAttr, int[] attrs) { final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "getItemAttrRequestFromNative: mHandler is already null"); return; } AvrcpCmd avrcpCmdobj = new AvrcpCmd(); AvrcpCmd.ItemAttrCmd itemAttr = avrcpCmdobj.new ItemAttrCmd(address, scope, itemUid, uidCounter, numAttr, attrs); Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_GET_ITEM_ATTR); Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_ITEM_ATTR); msg.obj = itemAttr; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void searchRequestFromNative(byte[] address, int charsetId, byte[] searchStr) { Loading @@ -1526,14 +1612,21 @@ public final class Avrcp { } private void playItemRequestFromNative(byte[] address, byte scope, int uidCounter, byte[] uid) { final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "playItemRequestFromNative: mHandler is already null"); return; } Bundle data = new Bundle(); Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_PLAY_ITEM); Message msg = handler.obtainMessage(MSG_NATIVE_REQ_PLAY_ITEM); data.putByteArray("BdAddress", address); data.putByteArray("uid", uid); data.putInt("uidCounter", uidCounter); data.putByte("scope", scope); msg.setData(data); mHandler.sendMessage(msg); handler.sendMessage(msg); } private void addToPlayListRequestFromNative(byte[] address, byte scope, byte[] uid, Loading @@ -1544,11 +1637,17 @@ public final class Avrcp { } private void getTotalNumOfItemsRequestFromNative(byte[] address, byte scope) { final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "getTotalNumOfItemsRequestFromNative: mHandler is already null"); return; } Bundle data = new Bundle(); Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_GET_TOTAL_NUM_OF_ITEMS); Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_TOTAL_NUM_OF_ITEMS); msg.arg1 = scope; msg.obj = address; mHandler.sendMessage(msg); handler.sendMessage(msg); } private void notifyVolumeChanged(int volume) { Loading Loading @@ -1600,8 +1699,14 @@ public final class Avrcp { * This is called from A2dpStateMachine to set A2dp audio state. */ public void setA2dpAudioState(int state) { Message msg = mHandler.obtainMessage(MSG_SET_A2DP_AUDIO_STATE, state, 0); mHandler.sendMessage(msg); final AvrcpMessageHandler handler = mHandler; if (handler == null) { if (DEBUG) Log.d(TAG, "setA2dpAudioState: mHandler is already null"); return; } Message msg = handler.obtainMessage(MSG_SET_A2DP_AUDIO_STATE, state, 0); handler.sendMessage(msg); } private class AvrcpServiceBootReceiver extends BroadcastReceiver { Loading
android/app/tests/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := BluetoothInstrumentationTests LOCAL_COMPATIBILITY_SUITE := device-tests LOCAL_INSTRUMENTATION_FOR := Bluetooth include $(BUILD_PACKAGE)
android/app/tests/AndroidTest.xml 0 → 100644 +27 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright 2017 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. --> <configuration description="Runs Bluetooth Test Cases."> <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> <option name="test-file-name" value="BluetoothInstrumentationTests.apk" /> </target_preparer> <option name="test-suite-tag" value="apct" /> <option name="test-tag" value="BluetoothInstrumentationTests" /> <test class="com.android.tradefed.testtype.InstrumentationTest" > <option name="package" value="com.android.bluetooth.tests" /> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> </test> </configuration> No newline at end of file
android/app/tests/src/com/android/bluetooth/core/FileSystemWriteTest.java→android/app/tests/src/com/android/bluetooth/FileSystemWriteTest.java +67 −0 Original line number Diff line number Diff line /* * Copyright 2017 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; import android.support.test.filters.MediumTest; import android.test.AndroidTestCase; import android.support.test.runner.AndroidJUnit4; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import java.io.File; import java.io.IOException; /** * Test Bluetooth's ability to write to the different directories that it * is supposed to own */ @MediumTest // Test Bluetooth's ability to write to the different directories that it // is supposed to own public class FileSystemWriteTest extends AndroidTestCase { @RunWith(AndroidJUnit4.class) public class FileSystemWriteTest { @Test public void testBluetoothDirWrite() { try { File file = new File("/data/misc/bluetooth/test.file"); assertTrue("File not created", file.createNewFile()); Assert.assertTrue("File not created", file.createNewFile()); file.delete(); } catch (IOException e) { fail("Exception creating file /data/misc/bluetooth/test.file: " + e); Assert.fail("Exception creating file /data/misc/bluetooth/test.file: " + e); } } @Test public void testBluedroidDirWrite() { try { File file = new File("/data/misc/bluedroid/test.file"); assertTrue("File not created", file.createNewFile()); Assert.assertTrue("File not created", file.createNewFile()); file.delete(); } catch (IOException e) { fail("Exception creating file /data/misc/bluedroid/test.file: " + e); Assert.fail("Exception creating file /data/misc/bluedroid/test.file: " + e); } } @Test public void testBluetoothLogsDirWrite() { try { File file = new File("/data/misc/bluetooth/logs/test.file"); assertTrue("File not created", file.createNewFile()); Assert.assertTrue("File not created", file.createNewFile()); file.delete(); } catch (IOException e) { fail("Exception creating file /data/misc/bluetooth/logs/test.file: " + e); Assert.fail("Exception creating file /data/misc/bluetooth/logs/test.file: " + e); } } }
android/app/tests/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandlerTest.java +13 −18 Original line number Diff line number Diff line Loading @@ -22,40 +22,37 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; import android.media.AudioManager; import android.media.AudioManager.OnAudioFocusChangeListener; import android.os.HandlerThread; import android.os.Looper; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.MediumTest; import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.mockito.MockitoAnnotations; @MediumTest @RunWith(MockitoJUnitRunner.class) public class A2dpSinkStreamHandlerTest extends AndroidTestCase { static final int DUCK_PERCENT = 75; @RunWith(AndroidJUnit4.class) public class A2dpSinkStreamHandlerTest { private static final int DUCK_PERCENT = 75; private HandlerThread mHandlerThread; A2dpSinkStreamHandler mStreamHandler; ArgumentCaptor<OnAudioFocusChangeListener> mAudioFocusChangeListenerArgumentCaptor; private A2dpSinkStreamHandler mStreamHandler; @Mock Context mMockContext; @Mock private Context mMockContext; @Mock A2dpSinkStateMachine mMockA2dpSink; @Mock private A2dpSinkStateMachine mMockA2dpSink; @Mock AudioManager mMockAudioManager; @Mock private AudioManager mMockAudioManager; @Mock Resources mMockResources; @Mock private Resources mMockResources; @Mock PackageManager mMockPackageManager; @Mock private PackageManager mMockPackageManager; @Override @Before public void setUp() { MockitoAnnotations.initMocks(this); // Mock the looper if (Looper.myLooper() == null) { Looper.prepare(); Loading @@ -64,8 +61,6 @@ public class A2dpSinkStreamHandlerTest extends AndroidTestCase { mHandlerThread = new HandlerThread("A2dpSinkStreamHandlerTest"); mHandlerThread.start(); mAudioFocusChangeListenerArgumentCaptor = ArgumentCaptor.forClass(OnAudioFocusChangeListener.class); when(mMockContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mMockAudioManager); when(mMockContext.getResources()).thenReturn(mMockResources); when(mMockResources.getInteger(anyInt())).thenReturn(DUCK_PERCENT); Loading