diff options
-rw-r--r-- | api/current.txt | 2 | ||||
-rw-r--r-- | api/system-current.txt | 6 | ||||
-rw-r--r-- | api/test-current.txt | 9 | ||||
-rw-r--r-- | telecomm/java/android/telecom/Call.java | 58 | ||||
-rw-r--r-- | telecomm/java/android/telecom/CallScreeningService.java | 42 | ||||
-rw-r--r-- | telecomm/java/android/telecom/InCallAdapter.java | 22 | ||||
-rw-r--r-- | telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl | 2 | ||||
-rw-r--r-- | telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl | 4 |
8 files changed, 142 insertions, 3 deletions
diff --git a/api/current.txt b/api/current.txt index 6177c1a9b861..436ebdc35b6c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -43047,6 +43047,7 @@ package android.telecom { field public static final String EXTRA_SILENT_RINGING_REQUESTED = "android.telecom.extra.SILENT_RINGING_REQUESTED"; field public static final String EXTRA_SUGGESTED_PHONE_ACCOUNTS = "android.telecom.extra.SUGGESTED_PHONE_ACCOUNTS"; field public static final int STATE_ACTIVE = 4; // 0x4 + field public static final int STATE_AUDIO_PROCESSING = 12; // 0xc field public static final int STATE_CONNECTING = 9; // 0x9 field public static final int STATE_DIALING = 1; // 0x1 field public static final int STATE_DISCONNECTED = 7; // 0x7 @@ -43056,6 +43057,7 @@ package android.telecom { field public static final int STATE_PULLING_CALL = 11; // 0xb field public static final int STATE_RINGING = 2; // 0x2 field public static final int STATE_SELECT_PHONE_ACCOUNT = 8; // 0x8 + field public static final int STATE_SIMULATED_RINGING = 13; // 0xd } public abstract static class Call.Callback { diff --git a/api/system-current.txt b/api/system-current.txt index cc3f6a18393e..954ed51d5e02 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -6893,6 +6893,8 @@ package android.telecom { public final class Call { method @Deprecated public void addListener(android.telecom.Call.Listener); + method public void enterBackgroundAudioProcessing(); + method public void exitBackgroundAudioProcessing(boolean); method @Deprecated public void removeListener(android.telecom.Call.Listener); field @Deprecated public static final int STATE_PRE_DIAL_WAIT = 8; // 0x8 } @@ -6901,6 +6903,10 @@ package android.telecom { ctor @Deprecated public Call.Listener(); } + public static class CallScreeningService.CallResponse.Builder { + method public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallFurther(boolean); + } + public abstract class Conference extends android.telecom.Conferenceable { method @Deprecated public final android.telecom.AudioState getAudioState(); method @Deprecated public final long getConnectTimeMillis(); diff --git a/api/test-current.txt b/api/test-current.txt index edd60d91fa33..dab0e7b12deb 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -2733,10 +2733,19 @@ package android.service.quicksettings { package android.telecom { + public final class Call { + method public void enterBackgroundAudioProcessing(); + method public void exitBackgroundAudioProcessing(boolean); + } + public final class CallAudioState implements android.os.Parcelable { ctor public CallAudioState(boolean, int, int, @Nullable android.bluetooth.BluetoothDevice, @NonNull java.util.Collection<android.bluetooth.BluetoothDevice>); } + public static class CallScreeningService.CallResponse.Builder { + method public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallFurther(boolean); + } + public abstract class Conference extends android.telecom.Conferenceable { method public android.telecom.Connection getPrimaryConnection(); } diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index 1822cee89eaa..5e71416a0510 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -19,6 +19,7 @@ package android.telecom; import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.net.Uri; import android.os.Build; @@ -119,6 +120,20 @@ public final class Call { public static final int STATE_PULLING_CALL = 11; /** + * The state of a call that is active with the network, but the audio from the call is + * being intercepted by an app on the local device. Telecom does not hold audio focus in this + * state, and the call will be invisible to the user except for a persistent notification. + */ + public static final int STATE_AUDIO_PROCESSING = 12; + + /** + * The state of a call that is being presented to the user after being in + * {@link #STATE_AUDIO_PROCESSING}. The call is still active with the network in this case, and + * Telecom will hold audio focus and play a ringtone if appropriate. + */ + public static final int STATE_SIMULATED_RINGING = 13; + + /** * The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call * extras. Used to pass the phone accounts to display on the front end to the user in order to * select phone accounts to (for example) place a call. @@ -1479,6 +1494,49 @@ public final class Call { } /** + * Instructs Telecom to put the call into the background audio processing state. + * + * This method can be called either when the call is in {@link #STATE_RINGING} or + * {@link #STATE_ACTIVE}. After Telecom acknowledges the request by setting the call's state to + * {@link #STATE_AUDIO_PROCESSING}, your app may setup the audio paths with the audio stack in + * order to capture and play audio on the call stream. + * + * This method can only be called by the default dialer app. + * @hide + */ + @SystemApi + @TestApi + //@RequiresPermission(android.Manifest.permission.BACKGROUND_CALL_AUDIO) + public void enterBackgroundAudioProcessing() { + if (mState != STATE_ACTIVE && mState != STATE_RINGING) { + throw new IllegalStateException("Call must be active or ringing"); + } + mInCallAdapter.enterBackgroundAudioProcessing(mTelecomCallId); + } + + /** + * Instructs Telecom to come out of the background audio processing state requested by + * {@link #enterBackgroundAudioProcessing()} or from the call screening service. + * + * This method can only be called when the call is in {@link #STATE_AUDIO_PROCESSING}. + * + * @param shouldRing If true, Telecom will put the call into the + * {@link #STATE_SIMULATED_RINGING} state and notify other apps that there is + * a ringing call. Otherwise, the call will go into {@link #STATE_ACTIVE} + * immediately. + * @hide + */ + @SystemApi + @TestApi + //@RequiresPermission(android.Manifest.permission.BACKGROUND_CALL_AUDIO) + public void exitBackgroundAudioProcessing(boolean shouldRing) { + if (mState != STATE_AUDIO_PROCESSING) { + throw new IllegalStateException("Call must in the audio processing state"); + } + mInCallAdapter.exitBackgroundAudioProcessing(mTelecomCallId, shouldRing); + } + + /** * Instructs this {@code Call} to play a dual-tone multi-frequency signaling (DTMF) tone. * * Any other currently playing DTMF tone in the specified call is immediately stopped. diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java index e4f8d118e7df..0d97567ed213 100644 --- a/telecomm/java/android/telecom/CallScreeningService.java +++ b/telecomm/java/android/telecom/CallScreeningService.java @@ -18,6 +18,8 @@ package android.telecom; import android.annotation.NonNull; import android.annotation.SdkConstant; +import android.annotation.SystemApi; +import android.annotation.TestApi; import android.app.Service; import android.content.ComponentName; import android.content.Intent; @@ -136,23 +138,30 @@ public abstract class CallScreeningService extends Service { private final boolean mShouldSilenceCall; private final boolean mShouldSkipCallLog; private final boolean mShouldSkipNotification; + private final boolean mShouldScreenCallFurther; private CallResponse( boolean shouldDisallowCall, boolean shouldRejectCall, boolean shouldSilenceCall, boolean shouldSkipCallLog, - boolean shouldSkipNotification) { + boolean shouldSkipNotification, + boolean shouldScreenCallFurther) { if (!shouldDisallowCall && (shouldRejectCall || shouldSkipCallLog || shouldSkipNotification)) { throw new IllegalStateException("Invalid response state for allowed call."); } + if (shouldDisallowCall && shouldScreenCallFurther) { + throw new IllegalStateException("Invalid response state for allowed call."); + } + mShouldDisallowCall = shouldDisallowCall; mShouldRejectCall = shouldRejectCall; mShouldSkipCallLog = shouldSkipCallLog; mShouldSkipNotification = shouldSkipNotification; mShouldSilenceCall = shouldSilenceCall; + mShouldScreenCallFurther = shouldScreenCallFurther; } /* @@ -191,12 +200,22 @@ public abstract class CallScreeningService extends Service { return mShouldSkipNotification; } + /** + * @return Whether we should enter the {@link Call#STATE_AUDIO_PROCESSING} state to allow + * for further screening of the call. + * @hide + */ + public boolean getShouldScreenCallFurther() { + return mShouldScreenCallFurther; + } + public static class Builder { private boolean mShouldDisallowCall; private boolean mShouldRejectCall; private boolean mShouldSilenceCall; private boolean mShouldSkipCallLog; private boolean mShouldSkipNotification; + private boolean mShouldScreenCallFurther; /** * Sets whether the incoming call should be blocked. @@ -252,13 +271,32 @@ public abstract class CallScreeningService extends Service { return this; } + /** + * Sets whether to request background audio processing so that the in-call service can + * screen the call further. If set to {@code true}, {@link #setDisallowCall} should be + * called with {@code false}, and all other parameters in this builder will be ignored. + * + * This request will only be honored if the {@link CallScreeningService} shares the same + * uid as the default dialer app. Otherwise, the call will go through as usual. + * + * @param shouldScreenCallFurther Whether to request further call screening. + * @hide + */ + @SystemApi + @TestApi + public Builder setShouldScreenCallFurther(boolean shouldScreenCallFurther) { + mShouldScreenCallFurther = shouldScreenCallFurther; + return this; + } + public CallResponse build() { return new CallResponse( mShouldDisallowCall, mShouldRejectCall, mShouldSilenceCall, mShouldSkipCallLog, - mShouldSkipNotification); + mShouldSkipNotification, + mShouldScreenCallFurther); } } } diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java index 8678e33f68b6..261246818f1d 100644 --- a/telecomm/java/android/telecom/InCallAdapter.java +++ b/telecomm/java/android/telecom/InCallAdapter.java @@ -16,8 +16,8 @@ package android.telecom; -import android.net.Uri; import android.bluetooth.BluetoothDevice; +import android.net.Uri; import android.os.Bundle; import android.os.RemoteException; @@ -149,6 +149,26 @@ public final class InCallAdapter { } /** + * @see Call#enterBackgroundAudioProcessing() + */ + public void enterBackgroundAudioProcessing(String callId) { + try { + mAdapter.enterBackgroundAudioProcessing(callId); + } catch (RemoteException e) { + } + } + + /** + * @see Call#exitBackgroundAudioProcessing(boolean) + */ + public void exitBackgroundAudioProcessing(String callId, boolean shouldRing) { + try { + mAdapter.exitBackgroundAudioProcessing(callId, shouldRing); + } catch (RemoteException e) { + } + } + + /** * Request audio routing to a specific bluetooth device. Calling this method may result in * the device routing audio to a different bluetooth device than the one specified. A list of * available devices can be obtained via {@link CallAudioState#getSupportedBluetoothDevices()} diff --git a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl index 3ee3285793c4..83c8f62bb3db 100644 --- a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl +++ b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl @@ -30,6 +30,8 @@ oneway interface ICallScreeningAdapter { void silenceCall(String callId); + void screenCallFurther(String callId); + void disallowCall( String callId, boolean shouldReject, diff --git a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl index 57df5c1e548e..60745e40aa77 100644 --- a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl +++ b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl @@ -44,6 +44,10 @@ oneway interface IInCallAdapter { void setAudioRoute(int route, String bluetoothAddress); + void enterBackgroundAudioProcessing(String callId); + + void exitBackgroundAudioProcessing(String callId, boolean shouldRing); + void playDtmfTone(String callId, char digit); void stopDtmfTone(String callId); |