DO NOT MERGE ANYWHERE
Handle audio route restrictions set on calls.
When a call restricts audio routes, it will move the audio route to a
supported route if available. The supported routes are determined initially
and re-evaluated when the call becomes the foreground call.
Bug: 25485578
Change-Id: I54b9bf17495eb2b0dc73b822ad16485a4673a779
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 714e7fd..0cf2373 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -296,6 +296,8 @@
private int mConnectionCapabilities;
+ private int mSupportedAudioRoutes;
+
private boolean mIsConference = false;
private Call mParentCall = null;
@@ -808,6 +810,16 @@
}
}
+ int getSupportedAudioRoutes() {
+ return mSupportedAudioRoutes;
+ }
+
+ void setSupportedAudioRoutes(int audioRoutes) {
+ if (mSupportedAudioRoutes != audioRoutes) {
+ mSupportedAudioRoutes = audioRoutes;
+ }
+ }
+
Call getParentCall() {
return mParentCall;
}
@@ -911,6 +923,7 @@
setCallerDisplayName(
connection.getCallerDisplayName(), connection.getCallerDisplayNamePresentation());
setConnectionCapabilities(connection.getConnectionCapabilities());
+ setSupportedAudioRoutes(connection.getSupportedAudioRoutes());
setVideoProvider(connection.getVideoProvider());
setVideoState(connection.getVideoState());
setRingbackRequested(connection.isRingbackRequested());
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index 23284e3..af6f98c 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -253,6 +253,12 @@
@Override
public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
onCallUpdated(newForegroundCall);
+
+ // Set the system audio state again in case the current route is not permitted by the new
+ // foreground call.
+ setSystemAudioState(mCallAudioState.isMuted(), mCallAudioState.getRoute(),
+ calculateSupportedRoutes(newForegroundCall));
+
// Ensure that the foreground call knows about the latest audio state.
updateAudioForForegroundCall();
}
@@ -472,6 +478,20 @@
}
CallAudioState oldAudioState = mCallAudioState;
+
+ // If the currently selected route is not supported, switch to another supported route
+ if ((route & supportedRouteMask) == 0) {
+ if ((CallAudioState.ROUTE_EARPIECE & supportedRouteMask) != 0) {
+ route = CallAudioState.ROUTE_EARPIECE;
+ } else if ((CallAudioState.ROUTE_WIRED_HEADSET & supportedRouteMask) != 0) {
+ route = CallAudioState.ROUTE_WIRED_HEADSET;
+ } else if ((CallAudioState.ROUTE_SPEAKER & supportedRouteMask) != 0) {
+ route = CallAudioState.ROUTE_SPEAKER;
+ } else if ((CallAudioState.ROUTE_BLUETOOTH & supportedRouteMask) != 0) {
+ route = CallAudioState.ROUTE_BLUETOOTH;
+ }
+ }
+
saveAudioState(new CallAudioState(isMuted, route, supportedRouteMask));
if (!force && Objects.equals(oldAudioState, mCallAudioState)) {
return;
@@ -645,6 +665,10 @@
}
private int calculateSupportedRoutes() {
+ return calculateSupportedRoutes(getForegroundCall());
+ }
+
+ private int calculateSupportedRoutes(Call call) {
int routeMask = CallAudioState.ROUTE_SPEAKER;
if (mWiredHeadsetManager.isPluggedIn()) {
@@ -657,11 +681,11 @@
routeMask |= CallAudioState.ROUTE_BLUETOOTH;
}
- return routeMask;
+ return call != null ? routeMask & call.getSupportedAudioRoutes() : routeMask;
}
private CallAudioState getInitialAudioState(Call call) {
- int supportedRouteMask = calculateSupportedRoutes();
+ int supportedRouteMask = calculateSupportedRoutes(call);
int route = selectWiredOrEarpiece(
CallAudioState.ROUTE_WIRED_OR_EARPIECE, supportedRouteMask);
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index 9562ea7..1011910 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -590,6 +590,8 @@
int state = getParcelableState(call);
int capabilities = convertConnectionToCallCapabilities(call.getConnectionCapabilities());
int properties = convertConnectionToCallProperties(call.getConnectionCapabilities());
+ int supportedAudioRoutes = call.getSupportedAudioRoutes();
+
if (call.isConference()) {
properties |= android.telecom.Call.Details.PROPERTY_CONFERENCE;
}
@@ -659,6 +661,7 @@
call.getCannedSmsResponses(),
capabilities,
properties,
+ supportedAudioRoutes,
connectTimeMillis,
handle,
call.getHandlePresentation(),
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index aab193e..a4b8992 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -35,6 +35,7 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.telecom.CallAudioState;
import android.telecom.ConnectionService;
import android.telecom.DefaultDialerManager;
import android.telecom.PhoneAccount;
@@ -121,7 +122,7 @@
private static final String FILE_NAME = "phone-account-registrar-state.xml";
@VisibleForTesting
- public static final int EXPECTED_STATE_VERSION = 8;
+ public static final int EXPECTED_STATE_VERSION = 9;
/** Keep in sync with the same in SipSettings.java */
private static final String SIP_SHARED_PREFERENCES = "SIP_PREFERENCES";
@@ -1147,6 +1148,7 @@
private static final String ADDRESS = "handle";
private static final String SUBSCRIPTION_ADDRESS = "subscription_number";
private static final String CAPABILITIES = "capabilities";
+ private static final String SUPPORTED_AUDIO_ROUTES = "supported_audio_routes";
private static final String ICON_RES_ID = "icon_res_id";
private static final String ICON_PACKAGE_NAME = "icon_package_name";
private static final String ICON_BITMAP = "icon_bitmap";
@@ -1179,7 +1181,9 @@
writeTextIfNonNull(LABEL, o.getLabel(), serializer);
writeTextIfNonNull(SHORT_DESCRIPTION, o.getShortDescription(), serializer);
writeStringList(SUPPORTED_URI_SCHEMES, o.getSupportedUriSchemes(), serializer);
- writeTextIfNonNull(ENABLED, o.isEnabled() ? "true" : "false" , serializer);
+ writeTextIfNonNull(ENABLED, o.isEnabled() ? "true" : "false", serializer);
+ writeTextIfNonNull(SUPPORTED_AUDIO_ROUTES, Integer.toString(
+ o.getSupportedAudioRoutes()), serializer);
serializer.endTag(null, CLASS_PHONE_ACCOUNT);
}
@@ -1193,6 +1197,7 @@
Uri address = null;
Uri subscriptionAddress = null;
int capabilities = 0;
+ int supportedAudioRoutes = 0;
int iconResId = PhoneAccount.NO_RESOURCE_ID;
String iconPackageName = null;
Bitmap iconBitmap = null;
@@ -1248,6 +1253,9 @@
} else if (parser.getName().equals(ENABLED)) {
parser.next();
enabled = "true".equalsIgnoreCase(parser.getText());
+ } else if (parser.getName().equals(SUPPORTED_AUDIO_ROUTES)) {
+ parser.next();
+ supportedAudioRoutes = Integer.parseInt(parser.getText());
}
}
@@ -1306,10 +1314,16 @@
}
}
+ if (version < 9) {
+ // Set supported audio routes to all by default
+ supportedAudioRoutes = CallAudioState.ROUTE_ALL;
+ }
+
PhoneAccount.Builder builder = PhoneAccount.builder(accountHandle, label)
.setAddress(address)
.setSubscriptionAddress(subscriptionAddress)
.setCapabilities(capabilities)
+ .setSupportedAudioRoutes(supportedAudioRoutes)
.setShortDescription(shortDescription)
.setSupportedUriSchemes(supportedUriSchemes)
.setHighlightColor(highlightColor)
diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
index bdcfb5b..c108d21 100644
--- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
@@ -171,6 +171,7 @@
int state;
int addressPresentation;
int capabilities;
+ int supportedAudioRoutes;
StatusHints statusHints;
DisconnectCause disconnectCause;
String conferenceId;
@@ -395,6 +396,7 @@
c.request.getAccountHandle(),
c.state,
c.capabilities,
+ c.supportedAudioRoutes,
c.request.getAddress(),
c.addressPresentation,
c.callerDisplayName,