Loading android/app/res/values-hi/strings.xml +1 −1 Original line number Diff line number Diff line Loading @@ -101,7 +101,7 @@ <string name="status_protocol_error" msgid="3245444473429269539">"अनुरोध को सही तरह से प्रबंधित नहीं किया जा सकता."</string> <string name="status_unknown_error" msgid="8156660554237824912">"अज्ञात गड़बड़ी."</string> <string name="btopp_live_folder" msgid="7967791481444474554">"ब्लूटूथ से मिली फ़ाइलें"</string> <string name="opp_notification_group" msgid="3486303082135789982">"ब्लूटूथ के ज़रिए साझा"</string> <string name="opp_notification_group" msgid="3486303082135789982">"ब्लूटूथ के ज़रिए शेयर"</string> <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> प्राप्ति पूर्ण."</string> <string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> भेजना पूर्ण."</string> <string name="inbound_history_title" msgid="6940914942271327563">"इनबाउंड स्थानांतरण"</string> Loading android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -406,6 +406,20 @@ class ActiveDeviceManager { resetState(); } /** * Get the {@link Looper} for the handler thread. This is used in testing and helper * objects * * @return {@link Looper} for the handler thread */ @VisibleForTesting public Looper getHandlerLooper() { if (mHandlerThread == null) { return null; } return mHandlerThread.getLooper(); } private void setA2dpActiveDevice(BluetoothDevice device) { if (DBG) { Log.d(TAG, "setA2dpActiveDevice(" + device + ")"); Loading android/app/src/com/android/bluetooth/newavrcp/AvrcpVolumeManager.java +39 −17 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.content.SharedPreferences; import android.media.AudioDeviceCallback; import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.util.Log; Loading @@ -29,7 +31,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; class AvrcpVolumeManager { class AvrcpVolumeManager extends AudioDeviceCallback { public static final String TAG = "NewAvrcpVolumeManager"; public static final boolean DEBUG = true; Loading Loading @@ -90,6 +92,8 @@ class AvrcpVolumeManager { mNativeInterface = nativeInterface; sDeviceMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); mAudioManager.registerAudioDeviceCallback(this, null); // Load the stored volume preferences into a hash map since shared preferences are slow // to poll and update. If the device has been unbonded since last start remove it from // the map. Loading Loading @@ -133,6 +137,40 @@ class AvrcpVolumeManager { return mVolumeMap.get(device); } @Override public synchronized void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) { if (mCurrentDevice == null) { d("onAudioDevicesAdded: Not expecting device changed"); return; } boolean foundDevice = false; d("onAudioDevicesAdded: size: " + addedDevices.length); for (int i = 0; i < addedDevices.length; i++) { d("onAudioDevicesAdded: address=" + addedDevices[i].getAddress()); if (addedDevices[i].getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP && Objects.equals(addedDevices[i].getAddress(), mCurrentDevice.getAddress())) { foundDevice = true; break; } } if (!foundDevice) { d("Didn't find deferred device in list: device=" + mCurrentDevice); return; } // A2DP can sometimes connect and set a device to active before AVRCP has determined if the // device supports absolute volume. Defer switching the device until AVRCP returns the // info. if (!mDeviceMap.containsKey(mCurrentDevice)) { Log.w(TAG, "volumeDeviceSwitched: Device isn't connected: " + mCurrentDevice); return; } switchVolumeDevice(mCurrentDevice); } synchronized void deviceConnected(@NonNull BluetoothDevice device, boolean absoluteVolume) { d("deviceConnected: device=" + device + " absoluteVolume=" + absoluteVolume); Loading @@ -154,22 +192,6 @@ class AvrcpVolumeManager { // Wait until AudioManager informs us that the new device is connected mCurrentDevice = device; // If device is null, that means that there is no active Bluetooth device if (device == null) { mCurrentDevice = null; return; } // If the device is connected then switch the device which informs audio manager that // absolute volume is supported and set the volume for the device. Otherwise disable // absolute volume until the new device connects to prevent sending unattenuated audio. if (mDeviceMap.containsKey(device)) { switchVolumeDevice(device); } else { d("volumeDeviceSwitched: Set Absolute Volume support to false until device connects."); mAudioManager.avrcpSupportsAbsoluteVolume(device.getAddress(), false); } } void deviceDisconnected(@NonNull BluetoothDevice device) { Loading android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java +13 −8 Original line number Diff line number Diff line Loading @@ -154,7 +154,8 @@ public class ActiveDeviceManagerTest { a2dpActiveDeviceChanged(mA2dpDevice); // Don't call mA2dpService.setActiveDevice() verify(mA2dpService, after(TIMEOUT_MS).times(1)).setActiveDevice(mA2dpDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mA2dpService, times(1)).setActiveDevice(mA2dpDevice); Assert.assertEquals(mA2dpDevice, mActiveDeviceManager.getA2dpActiveDevice()); } Loading Loading @@ -204,7 +205,8 @@ public class ActiveDeviceManagerTest { headsetActiveDeviceChanged(mHeadsetDevice); // Don't call mHeadsetService.setActiveDevice() verify(mHeadsetService, after(TIMEOUT_MS).times(1)).setActiveDevice(mHeadsetDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mHeadsetService, times(1)).setActiveDevice(mHeadsetDevice); Assert.assertEquals(mHeadsetDevice, mActiveDeviceManager.getHfpActiveDevice()); } Loading Loading @@ -238,8 +240,9 @@ public class ActiveDeviceManagerTest { a2dpConnected(mA2dpHeadsetDevice); headsetConnected(mA2dpHeadsetDevice); verify(mA2dpService, timeout(TIMEOUT_MS).times(0)).setActiveDevice(mA2dpHeadsetDevice); verify(mHeadsetService, timeout(TIMEOUT_MS).times(0)).setActiveDevice(mA2dpHeadsetDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mA2dpService, never()).setActiveDevice(mA2dpHeadsetDevice); verify(mHeadsetService, never()).setActiveDevice(mA2dpHeadsetDevice); } /** Loading @@ -254,9 +257,10 @@ public class ActiveDeviceManagerTest { a2dpConnected(mA2dpHeadsetDevice); a2dpActiveDeviceChanged(mA2dpHeadsetDevice); verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(isNull()); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mHearingAidService).setActiveDevice(isNull()); // Don't call mA2dpService.setActiveDevice() verify(mA2dpService, timeout(TIMEOUT_MS).times(0)).setActiveDevice(mA2dpHeadsetDevice); verify(mA2dpService, never()).setActiveDevice(mA2dpHeadsetDevice); Assert.assertEquals(mA2dpHeadsetDevice, mActiveDeviceManager.getA2dpActiveDevice()); Assert.assertEquals(null, mActiveDeviceManager.getHearingAidActiveDevice()); } Loading @@ -273,9 +277,10 @@ public class ActiveDeviceManagerTest { headsetConnected(mA2dpHeadsetDevice); headsetActiveDeviceChanged(mA2dpHeadsetDevice); verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(isNull()); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mHearingAidService).setActiveDevice(isNull()); // Don't call mHeadsetService.setActiveDevice() verify(mHeadsetService, timeout(TIMEOUT_MS).times(0)).setActiveDevice(mA2dpHeadsetDevice); verify(mHeadsetService, never()).setActiveDevice(mA2dpHeadsetDevice); Assert.assertEquals(mA2dpHeadsetDevice, mActiveDeviceManager.getHfpActiveDevice()); Assert.assertEquals(null, mActiveDeviceManager.getHearingAidActiveDevice()); } Loading android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java +5 −2 Original line number Diff line number Diff line Loading @@ -66,6 +66,9 @@ public class PhonePolicyTest { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); // Stub A2DP and HFP when(mHeadsetService.connect(any(BluetoothDevice.class))).thenReturn(true); when(mA2dpService.connect(any(BluetoothDevice.class))).thenReturn(true); // Prepare the TestUtils TestUtils.setAdapterService(mAdapterService); // Configure the maximum connected audio devices Loading Loading @@ -213,8 +216,8 @@ public class PhonePolicyTest { mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); // This device should be set to auto connect while the first device is reset to ON verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setPriority(bondedDevices[0], BluetoothProfile.PRIORITY_ON); verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).setPriority( bondedDevices[0], BluetoothProfile.PRIORITY_ON); verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setPriority(bondedDevices[1], BluetoothProfile.PRIORITY_AUTO_CONNECT); verify(mHeadsetService, never()).setPriority(eq(bondedDevices[3]), anyInt()); Loading Loading
android/app/res/values-hi/strings.xml +1 −1 Original line number Diff line number Diff line Loading @@ -101,7 +101,7 @@ <string name="status_protocol_error" msgid="3245444473429269539">"अनुरोध को सही तरह से प्रबंधित नहीं किया जा सकता."</string> <string name="status_unknown_error" msgid="8156660554237824912">"अज्ञात गड़बड़ी."</string> <string name="btopp_live_folder" msgid="7967791481444474554">"ब्लूटूथ से मिली फ़ाइलें"</string> <string name="opp_notification_group" msgid="3486303082135789982">"ब्लूटूथ के ज़रिए साझा"</string> <string name="opp_notification_group" msgid="3486303082135789982">"ब्लूटूथ के ज़रिए शेयर"</string> <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> प्राप्ति पूर्ण."</string> <string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> भेजना पूर्ण."</string> <string name="inbound_history_title" msgid="6940914942271327563">"इनबाउंड स्थानांतरण"</string> Loading
android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +14 −0 Original line number Diff line number Diff line Loading @@ -406,6 +406,20 @@ class ActiveDeviceManager { resetState(); } /** * Get the {@link Looper} for the handler thread. This is used in testing and helper * objects * * @return {@link Looper} for the handler thread */ @VisibleForTesting public Looper getHandlerLooper() { if (mHandlerThread == null) { return null; } return mHandlerThread.getLooper(); } private void setA2dpActiveDevice(BluetoothDevice device) { if (DBG) { Log.d(TAG, "setA2dpActiveDevice(" + device + ")"); Loading
android/app/src/com/android/bluetooth/newavrcp/AvrcpVolumeManager.java +39 −17 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.content.SharedPreferences; import android.media.AudioDeviceCallback; import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.util.Log; Loading @@ -29,7 +31,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; class AvrcpVolumeManager { class AvrcpVolumeManager extends AudioDeviceCallback { public static final String TAG = "NewAvrcpVolumeManager"; public static final boolean DEBUG = true; Loading Loading @@ -90,6 +92,8 @@ class AvrcpVolumeManager { mNativeInterface = nativeInterface; sDeviceMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); mAudioManager.registerAudioDeviceCallback(this, null); // Load the stored volume preferences into a hash map since shared preferences are slow // to poll and update. If the device has been unbonded since last start remove it from // the map. Loading Loading @@ -133,6 +137,40 @@ class AvrcpVolumeManager { return mVolumeMap.get(device); } @Override public synchronized void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) { if (mCurrentDevice == null) { d("onAudioDevicesAdded: Not expecting device changed"); return; } boolean foundDevice = false; d("onAudioDevicesAdded: size: " + addedDevices.length); for (int i = 0; i < addedDevices.length; i++) { d("onAudioDevicesAdded: address=" + addedDevices[i].getAddress()); if (addedDevices[i].getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP && Objects.equals(addedDevices[i].getAddress(), mCurrentDevice.getAddress())) { foundDevice = true; break; } } if (!foundDevice) { d("Didn't find deferred device in list: device=" + mCurrentDevice); return; } // A2DP can sometimes connect and set a device to active before AVRCP has determined if the // device supports absolute volume. Defer switching the device until AVRCP returns the // info. if (!mDeviceMap.containsKey(mCurrentDevice)) { Log.w(TAG, "volumeDeviceSwitched: Device isn't connected: " + mCurrentDevice); return; } switchVolumeDevice(mCurrentDevice); } synchronized void deviceConnected(@NonNull BluetoothDevice device, boolean absoluteVolume) { d("deviceConnected: device=" + device + " absoluteVolume=" + absoluteVolume); Loading @@ -154,22 +192,6 @@ class AvrcpVolumeManager { // Wait until AudioManager informs us that the new device is connected mCurrentDevice = device; // If device is null, that means that there is no active Bluetooth device if (device == null) { mCurrentDevice = null; return; } // If the device is connected then switch the device which informs audio manager that // absolute volume is supported and set the volume for the device. Otherwise disable // absolute volume until the new device connects to prevent sending unattenuated audio. if (mDeviceMap.containsKey(device)) { switchVolumeDevice(device); } else { d("volumeDeviceSwitched: Set Absolute Volume support to false until device connects."); mAudioManager.avrcpSupportsAbsoluteVolume(device.getAddress(), false); } } void deviceDisconnected(@NonNull BluetoothDevice device) { Loading
android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java +13 −8 Original line number Diff line number Diff line Loading @@ -154,7 +154,8 @@ public class ActiveDeviceManagerTest { a2dpActiveDeviceChanged(mA2dpDevice); // Don't call mA2dpService.setActiveDevice() verify(mA2dpService, after(TIMEOUT_MS).times(1)).setActiveDevice(mA2dpDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mA2dpService, times(1)).setActiveDevice(mA2dpDevice); Assert.assertEquals(mA2dpDevice, mActiveDeviceManager.getA2dpActiveDevice()); } Loading Loading @@ -204,7 +205,8 @@ public class ActiveDeviceManagerTest { headsetActiveDeviceChanged(mHeadsetDevice); // Don't call mHeadsetService.setActiveDevice() verify(mHeadsetService, after(TIMEOUT_MS).times(1)).setActiveDevice(mHeadsetDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mHeadsetService, times(1)).setActiveDevice(mHeadsetDevice); Assert.assertEquals(mHeadsetDevice, mActiveDeviceManager.getHfpActiveDevice()); } Loading Loading @@ -238,8 +240,9 @@ public class ActiveDeviceManagerTest { a2dpConnected(mA2dpHeadsetDevice); headsetConnected(mA2dpHeadsetDevice); verify(mA2dpService, timeout(TIMEOUT_MS).times(0)).setActiveDevice(mA2dpHeadsetDevice); verify(mHeadsetService, timeout(TIMEOUT_MS).times(0)).setActiveDevice(mA2dpHeadsetDevice); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mA2dpService, never()).setActiveDevice(mA2dpHeadsetDevice); verify(mHeadsetService, never()).setActiveDevice(mA2dpHeadsetDevice); } /** Loading @@ -254,9 +257,10 @@ public class ActiveDeviceManagerTest { a2dpConnected(mA2dpHeadsetDevice); a2dpActiveDeviceChanged(mA2dpHeadsetDevice); verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(isNull()); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mHearingAidService).setActiveDevice(isNull()); // Don't call mA2dpService.setActiveDevice() verify(mA2dpService, timeout(TIMEOUT_MS).times(0)).setActiveDevice(mA2dpHeadsetDevice); verify(mA2dpService, never()).setActiveDevice(mA2dpHeadsetDevice); Assert.assertEquals(mA2dpHeadsetDevice, mActiveDeviceManager.getA2dpActiveDevice()); Assert.assertEquals(null, mActiveDeviceManager.getHearingAidActiveDevice()); } Loading @@ -273,9 +277,10 @@ public class ActiveDeviceManagerTest { headsetConnected(mA2dpHeadsetDevice); headsetActiveDeviceChanged(mA2dpHeadsetDevice); verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(isNull()); TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper()); verify(mHearingAidService).setActiveDevice(isNull()); // Don't call mHeadsetService.setActiveDevice() verify(mHeadsetService, timeout(TIMEOUT_MS).times(0)).setActiveDevice(mA2dpHeadsetDevice); verify(mHeadsetService, never()).setActiveDevice(mA2dpHeadsetDevice); Assert.assertEquals(mA2dpHeadsetDevice, mActiveDeviceManager.getHfpActiveDevice()); Assert.assertEquals(null, mActiveDeviceManager.getHearingAidActiveDevice()); } Loading
android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java +5 −2 Original line number Diff line number Diff line Loading @@ -66,6 +66,9 @@ public class PhonePolicyTest { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); // Stub A2DP and HFP when(mHeadsetService.connect(any(BluetoothDevice.class))).thenReturn(true); when(mA2dpService.connect(any(BluetoothDevice.class))).thenReturn(true); // Prepare the TestUtils TestUtils.setAdapterService(mAdapterService); // Configure the maximum connected audio devices Loading Loading @@ -213,8 +216,8 @@ public class PhonePolicyTest { mPhonePolicy.getBroadcastReceiver().onReceive(null /* context */, intent); // This device should be set to auto connect while the first device is reset to ON verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setPriority(bondedDevices[0], BluetoothProfile.PRIORITY_ON); verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS).times(2)).setPriority( bondedDevices[0], BluetoothProfile.PRIORITY_ON); verify(mHeadsetService, timeout(ASYNC_CALL_TIMEOUT_MILLIS)).setPriority(bondedDevices[1], BluetoothProfile.PRIORITY_AUTO_CONNECT); verify(mHeadsetService, never()).setPriority(eq(bondedDevices[3]), anyInt()); Loading