Merge "Update call log from nuisance report"
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..8ee7754
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,77 @@
+// Build the Telecom service.
+android_app {
+ name: "Telecom",
+ libs: ["telephony-common"],
+ srcs: [
+ "src/**/*.java",
+ "proto/**/*.proto",
+ ],
+ resource_dirs: ["res"],
+ proto: {
+ type: "nano",
+ local_include_dirs: ["proto/"],
+ output_params: ["optional_field_style=accessors"],
+ },
+ platform_apis: true,
+ certificate: "platform",
+ privileged: true,
+ optimize: {
+ proguard_flags_files: ["proguard.flags"],
+ },
+ defaults: ["SettingsLibDefaults"],
+}
+
+android_test {
+ name: "TelecomUnitTests",
+ static_libs: [
+ "android-ex-camera2",
+ "guava",
+ "mockito-target-inline",
+ "android-support-test",
+ "platform-test-annotations",
+ "androidx.legacy_legacy-support-core-ui",
+ "androidx.legacy_legacy-support-core-utils",
+ "androidx.core_core",
+ "androidx.fragment_fragment",
+ ],
+ srcs: [
+ "tests/src/**/*.java",
+ "src/**/*.java",
+ "proto/**/*.proto",
+ ],
+ proto: {
+ type: "nano",
+ local_include_dirs: ["proto/"],
+ output_params: ["optional_field_style=accessors"],
+ },
+ resource_dirs: [
+ "tests/res",
+ "res",
+ ],
+ libs: [
+ "android.test.mock",
+ "android.test.base",
+ "android.test.runner",
+ "telephony-common",
+ ],
+
+ jni_libs: ["libdexmakerjvmtiagent"],
+
+ aaptflags: [
+ "--auto-add-overlay",
+ "--extra-packages",
+ "com.android.server.telecom",
+ ],
+ manifest: "tests/AndroidManifest.xml",
+ optimize: {
+ enabled: false,
+ },
+ platform_apis: true,
+ certificate: "platform",
+ jacoco: {
+ include_filter: ["com.android.server.telecom.*"],
+ exclude_filter: ["com.android.server.telecom.tests.*"],
+ },
+ test_suites: ["device-tests"],
+ defaults: ["SettingsLibDefaults"],
+}
diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index 4e5eeff..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-# Build the Telecom service.
-include $(CLEAR_VARS)
-
-LOCAL_JAVA_LIBRARIES := telephony-common
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-proto-files-under, proto)
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_USE_AAPT2 := true
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := nano
-LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/proto/
-LOCAL_PROTO_JAVA_OUTPUT_PARAMS := optional_field_style=accessors
-
-LOCAL_PACKAGE_NAME := Telecom
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-
-include frameworks/base/packages/SettingsLib/common.mk
-
-include $(BUILD_PACKAGE)
-
-# Build the test package.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 349b789..4545ba2 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -1513,8 +1513,10 @@
false)))) {
Log.d(this, "Outgoing call requesting RTT, rtt setting is %b",
isRttSettingOn());
- if (accountToUse != null
- && accountToUse.hasCapabilities(PhoneAccount.CAPABILITY_RTT)) {
+ if (callToUse.isEmergencyCall() || (accountToUse != null
+ && accountToUse.hasCapabilities(PhoneAccount.CAPABILITY_RTT))) {
+ // If the call requested RTT and it's an emergency call, ignore the
+ // capability and hope that the modem will deal with it somehow.
callToUse.createRttStreams();
}
// Even if the phone account doesn't support RTT yet,
diff --git a/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java b/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
index e53488c..df7896c 100644
--- a/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
+++ b/src/com/android/server/telecom/bluetooth/BluetoothRouteManager.java
@@ -450,6 +450,7 @@
// Tracks the active devices in the BT stack (HFP or hearing aid).
private BluetoothDevice mHfpActiveDeviceCache = null;
private BluetoothDevice mHearingAidActiveDeviceCache = null;
+ private BluetoothDevice mMostRecentlyReportedActiveDevice = null;
public BluetoothRouteManager(Context context, TelecomSystem.SyncRoot lock,
BluetoothDeviceManager deviceManager, Timeouts.Adapter timeoutsAdapter) {
@@ -588,6 +589,9 @@
} else {
mHfpActiveDeviceCache = device;
}
+
+ if (device != null) mMostRecentlyReportedActiveDevice = device;
+
boolean isActiveDevicePresent = mHearingAidActiveDeviceCache != null
|| mHfpActiveDeviceCache != null;
@@ -690,30 +694,38 @@
BluetoothHeadsetProxy bluetoothHeadset = mDeviceManager.getHeadsetService();
BluetoothHearingAid bluetoothHearingAid = mDeviceManager.getHearingAidService();
+ BluetoothDevice hfpActiveDevice = null;
+ BluetoothDevice hearingAidActiveDevice = null;
+
if (bluetoothHeadset == null && bluetoothHearingAid == null) {
Log.i(this, "getBluetoothAudioConnectedDevice: no service available.");
return null;
}
if (bluetoothHeadset != null) {
- for (BluetoothDevice device : bluetoothHeadset.getConnectedDevices()) {
- boolean isAudioOn = bluetoothHeadset.getAudioState(device)
- != BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
- Log.v(this, "isBluetoothAudioConnected: ==> isAudioOn = " + isAudioOn
- + "for headset: " + device);
- if (isAudioOn) {
- return device;
- }
- }
+ hfpActiveDevice = bluetoothHeadset.getActiveDevice();
}
+
if (bluetoothHearingAid != null) {
for (BluetoothDevice device : bluetoothHearingAid.getActiveDevices()) {
if (device != null) {
- return device;
+ hearingAidActiveDevice = device;
+ break;
}
}
}
- return null;
+
+ // Return the active device reported by either HFP or hearing aid. If both are reporting
+ // active devices, go with the most recent one as reported by the receiver.
+ if (hfpActiveDevice != null) {
+ if (hearingAidActiveDevice != null) {
+ Log.i(this, "Both HFP and hearing aid are reporting active devices. Going with"
+ + " the most recently reported active device: %s");
+ return mMostRecentlyReportedActiveDevice;
+ }
+ return hfpActiveDevice;
+ }
+ return hearingAidActiveDevice;
}
/**
diff --git a/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java b/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java
index 0176a43..da2b8f1 100644
--- a/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java
+++ b/src/com/android/server/telecom/bluetooth/BluetoothStateReceiver.java
@@ -136,7 +136,7 @@
boolean isHearingAid =
BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED.equals(intent.getAction());
Log.i(LOG_TAG, "Device %s is now the preferred BT device for %s", device,
- isHearingAid ? "heading aid" : "HFP");
+ isHearingAid ? "hearing aid" : "HFP");
mBluetoothRouteManager.onActiveDeviceChanged(device, isHearingAid);
if (isHearingAid) {
diff --git a/testapps/Android.bp b/testapps/Android.bp
new file mode 100644
index 0000000..c647b1e
--- /dev/null
+++ b/testapps/Android.bp
@@ -0,0 +1,27 @@
+//
+// Copyright (C) 2013 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.
+//
+
+android_test {
+ name: "TelecomTestApps",
+ static_libs: [
+ "android-support-v4",
+ "android-ex-camera2",
+ "guava",
+ ],
+ srcs: ["src/**/*.java"],
+ platform_apis: true,
+ certificate: "platform",
+}
diff --git a/testapps/Android.mk b/testapps/Android.mk
deleted file mode 100644
index b600dca..0000000
--- a/testapps/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright (C) 2013 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-v4 \
- android-ex-camera2 \
- guava
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := TelecomTestApps
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_CERTIFICATE := platform
-
-LOCAL_MODULE_TAGS := tests
-
-include $(BUILD_PACKAGE)
diff --git a/tests/Android.mk b/tests/Android.mk
deleted file mode 100644
index 5abf999..0000000
--- a/tests/Android.mk
+++ /dev/null
@@ -1,75 +0,0 @@
-#
-# Copyright (C) 2013 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- android-ex-camera2 \
- guava \
- mockito-target-inline \
- android-support-test \
- platform-test-annotations
-
-LOCAL_STATIC_ANDROID_LIBRARIES := \
- androidx.legacy_legacy-support-core-ui \
- androidx.legacy_legacy-support-core-utils \
- androidx.core_core \
- androidx.fragment_fragment
-
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, src) \
- $(call all-java-files-under, ../src) \
- $(call all-proto-files-under, ../proto)
-
-LOCAL_PROTOC_OPTIMIZE_TYPE := nano
-LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/../proto/
-LOCAL_PROTO_JAVA_OUTPUT_PARAMS := optional_field_style=accessors
-
-LOCAL_RESOURCE_DIR := \
- $(LOCAL_PATH)/res \
- $(LOCAL_PATH)/../res
-
-LOCAL_JAVA_LIBRARIES := \
- android.test.mock \
- android.test.base \
- android.test.runner \
- telephony-common
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_JNI_SHARED_LIBRARIES := \
- libdexmakerjvmtiagent \
-
-LOCAL_AAPT_FLAGS := \
- --auto-add-overlay \
- --extra-packages com.android.server.telecom
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-LOCAL_PACKAGE_NAME := TelecomUnitTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_CERTIFICATE := platform
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.server.telecom.*
-LOCAL_JACK_COVERAGE_EXCLUDE_FILTER := com.android.server.telecom.tests.*
-
-LOCAL_COMPATIBILITY_SUITE := device-tests
-include frameworks/base/packages/SettingsLib/common.mk
-
-include $(BUILD_PACKAGE)
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java b/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java
index 42626d9..060031d 100644
--- a/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java
+++ b/tests/src/com/android/server/telecom/tests/BluetoothRouteManagerTest.java
@@ -38,7 +38,9 @@
import org.mockito.Mock;
import java.util.Arrays;
-import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
@@ -55,6 +57,7 @@
static final BluetoothDevice DEVICE1 = makeBluetoothDevice("00:00:00:00:00:01");
static final BluetoothDevice DEVICE2 = makeBluetoothDevice("00:00:00:00:00:02");
static final BluetoothDevice DEVICE3 = makeBluetoothDevice("00:00:00:00:00:03");
+ static final BluetoothDevice HEARING_AID_DEVICE = makeBluetoothDevice("00:00:00:00:00:04");
@Mock private BluetoothDeviceManager mDeviceManager;
@Mock private BluetoothHeadsetProxy mHeadsetProxy;
@@ -73,7 +76,7 @@
public void testConnectHfpRetryWhileNotConnected() {
BluetoothRouteManager sm = setupStateMachine(
BluetoothRouteManager.AUDIO_OFF_STATE_NAME, null);
- setupConnectedDevices(new BluetoothDevice[]{DEVICE1}, null);
+ setupConnectedDevices(new BluetoothDevice[]{DEVICE1}, null, null, null);
when(mTimeoutsAdapter.getRetryBluetoothConnectAudioBackoffMillis(
nullable(ContentResolver.class))).thenReturn(0L);
when(mHeadsetProxy.connectAudio()).thenReturn(false);
@@ -92,10 +95,29 @@
@SmallTest
@Test
+ public void testAmbiguousActiveDevice() {
+ BluetoothRouteManager sm = setupStateMachine(
+ BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX, DEVICE1);
+ setupConnectedDevices(new BluetoothDevice[]{DEVICE1},
+ new BluetoothDevice[]{HEARING_AID_DEVICE}, DEVICE1, HEARING_AID_DEVICE);
+ sm.onActiveDeviceChanged(DEVICE1, false);
+ sm.onActiveDeviceChanged(HEARING_AID_DEVICE, true);
+ executeRoutingAction(sm, BluetoothRouteManager.BT_AUDIO_LOST, DEVICE1.getAddress());
+
+ verifyConnectionAttempt(HEARING_AID_DEVICE, 0);
+ verifyConnectionAttempt(DEVICE1, 0);
+ assertEquals(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
+ + ":" + HEARING_AID_DEVICE.getAddress(),
+ sm.getCurrentState().getName());
+ sm.quitNow();
+ }
+
+ @SmallTest
+ @Test
public void testConnectHfpRetryWhileConnectedToAnotherDevice() {
BluetoothRouteManager sm = setupStateMachine(
BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX, DEVICE1);
- setupConnectedDevices(new BluetoothDevice[]{DEVICE1, DEVICE2}, null);
+ setupConnectedDevices(new BluetoothDevice[]{DEVICE1, DEVICE2}, null, null, null);
when(mTimeoutsAdapter.getRetryBluetoothConnectAudioBackoffMillis(
nullable(ContentResolver.class))).thenReturn(0L);
when(mHeadsetProxy.connectAudio()).thenReturn(false);
@@ -127,18 +149,26 @@
return sm;
}
- private void setupConnectedDevices(BluetoothDevice[] devices, BluetoothDevice activeDevice) {
- when(mDeviceManager.getNumConnectedDevices()).thenReturn(devices.length);
- when(mDeviceManager.getConnectedDevices()).thenReturn(Arrays.asList(devices));
- when(mHeadsetProxy.getConnectedDevices()).thenReturn(Arrays.asList(devices));
- when(mHeadsetProxy.getAudioState(any(BluetoothDevice.class)))
- .thenReturn(BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
- when(mBluetoothHearingAid.getConnectedDevices()).thenReturn(Collections.emptyList());
- when(mBluetoothHearingAid.getActiveDevices()).thenReturn(Arrays.asList(null, null));
- if (activeDevice != null) {
- when(mHeadsetProxy.getAudioState(eq(activeDevice)))
- .thenReturn(BluetoothHeadset.STATE_AUDIO_CONNECTED);
- }
+ private void setupConnectedDevices(BluetoothDevice[] hfpDevices,
+ BluetoothDevice[] hearingAidDevices,
+ BluetoothDevice hfpActiveDevice, BluetoothDevice hearingAidActiveDevice) {
+ if (hfpDevices == null) hfpDevices = new BluetoothDevice[]{};
+ if (hearingAidDevices == null) hearingAidDevices = new BluetoothDevice[]{};
+
+ when(mDeviceManager.getNumConnectedDevices()).thenReturn(
+ hfpDevices.length + hearingAidDevices.length);
+ List<BluetoothDevice> allDevices = Stream.concat(
+ Arrays.stream(hfpDevices), Arrays.stream(hearingAidDevices))
+ .collect(Collectors.toList());
+
+ when(mDeviceManager.getConnectedDevices()).thenReturn(allDevices);
+ when(mHeadsetProxy.getConnectedDevices()).thenReturn(Arrays.asList(hfpDevices));
+ when(mHeadsetProxy.getActiveDevice()).thenReturn(hfpActiveDevice);
+
+ when(mBluetoothHearingAid.getConnectedDevices())
+ .thenReturn(Arrays.asList(hearingAidDevices));
+ when(mBluetoothHearingAid.getActiveDevices())
+ .thenReturn(Arrays.asList(hearingAidActiveDevice, null));
}
static void executeRoutingAction(BluetoothRouteManager brm, int message, String
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java b/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java
index f87da3c..2f68ac2 100644
--- a/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java
+++ b/tests/src/com/android/server/telecom/tests/BluetoothRouteTransitionTests.java
@@ -265,9 +265,8 @@
SomeArgs args = SomeArgs.obtain();
args.arg1 = Log.createSubsession();
args.arg2 = mParams.initialDevice.getAddress();
+ when(mHeadsetProxy.getActiveDevice()).thenReturn(null);
sm.sendMessage(BluetoothRouteManager.BT_AUDIO_LOST, args);
- when(mHeadsetProxy.getAudioState(eq(mParams.initialDevice)))
- .thenReturn(BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
return true;
}).when(mDeviceManager).disconnectAudio();
}
@@ -278,9 +277,14 @@
sm.onActiveDeviceChanged(mParams.messageDevice,
mParams.hearingAidBtDevices.contains(mParams.messageDevice));
} else if (mParams.messageType == BluetoothRouteManager.LOST_DEVICE) {
- sm.onDeviceLost(mParams.messageDevice.getAddress());
sm.onActiveDeviceChanged(null,
mParams.hearingAidBtDevices.contains(mParams.messageDevice));
+ if (mParams.hearingAidBtDevices.contains(mParams.messageDevice)) {
+ when(mBluetoothHearingAid.getActiveDevices()).thenReturn(Arrays.asList(null, null));
+ } else {
+ when(mHeadsetProxy.getActiveDevice()).thenReturn(null);
+ }
+ sm.onDeviceLost(mParams.messageDevice.getAddress());
} else {
executeRoutingAction(sm, mParams.messageType,
mParams.messageDevice == null ? null : mParams.messageDevice.getAddress());
@@ -335,11 +339,8 @@
when(mDeviceManager.getConnectedDevices()).thenReturn(Arrays.asList(devices));
when(mHeadsetProxy.getConnectedDevices()).thenReturn(Arrays.asList(devices));
when(mHeadsetProxy.getActiveDevice()).thenReturn(activeDevice);
- when(mHeadsetProxy.getAudioState(any(BluetoothDevice.class)))
- .thenReturn(BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
if (audioOnDevice != null) {
- when(mHeadsetProxy.getAudioState(eq(audioOnDevice)))
- .thenReturn(BluetoothHeadset.STATE_AUDIO_CONNECTED);
+ when(mHeadsetProxy.getActiveDevice()).thenReturn(audioOnDevice);
}
}