diff options
| -rw-r--r-- | api/current.txt | 2 | ||||
| -rw-r--r-- | core/jni/android_media_AudioSystem.cpp | 7 | ||||
| -rw-r--r-- | media/java/android/media/AudioManager.java | 63 | ||||
| -rw-r--r-- | media/java/android/media/AudioSystem.java | 9 | ||||
| -rw-r--r-- | media/java/android/media/IAudioService.aidl | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/audio/AudioService.java | 19 |
6 files changed, 94 insertions, 8 deletions
diff --git a/api/current.txt b/api/current.txt index f9a295784248..81cf7cf1f7f7 100644 --- a/api/current.txt +++ b/api/current.txt @@ -23500,6 +23500,7 @@ package android.media { method @Deprecated public boolean isBluetoothA2dpOn(); method public boolean isBluetoothScoAvailableOffCall(); method public boolean isBluetoothScoOn(); + method public boolean isCallScreeningModeSupported(); method public static boolean isHapticPlaybackSupported(); method public boolean isMicrophoneMute(); method public boolean isMusicActive(); @@ -23598,6 +23599,7 @@ package android.media { field public static final int GET_DEVICES_ALL = 3; // 0x3 field public static final int GET_DEVICES_INPUTS = 1; // 0x1 field public static final int GET_DEVICES_OUTPUTS = 2; // 0x2 + field public static final int MODE_CALL_SCREENING = 4; // 0x4 field public static final int MODE_CURRENT = -1; // 0xffffffff field public static final int MODE_INVALID = -2; // 0xfffffffe field public static final int MODE_IN_CALL = 2; // 0x2 diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 541b937860c3..01f9d0b0cde5 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -2264,6 +2264,12 @@ android_media_AudioSystem_setAudioHalPids(JNIEnv *env, jobject clazz, jintArray return jStatus; } +static jboolean +android_media_AudioSystem_isCallScreeningModeSupported(JNIEnv *env, jobject thiz) +{ + return AudioSystem::isCallScreenModeSupported(); +} + // ---------------------------------------------------------------------------- static const JNINativeMethod gMethods[] = { @@ -2343,6 +2349,7 @@ static const JNINativeMethod gMethods[] = { {"setAllowedCapturePolicy", "(II)I", (void *)android_media_AudioSystem_setAllowedCapturePolicy}, {"setRttEnabled", "(Z)I", (void *)android_media_AudioSystem_setRttEnabled}, {"setAudioHalPids", "([I)I", (void *)android_media_AudioSystem_setAudioHalPids}, + {"isCallScreeningModeSupported", "()Z", (void *)android_media_AudioSystem_isCallScreeningModeSupported}, }; static const JNINativeMethod gEventHandlerMethods[] = { diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 9ad7f2a7dcc6..d5524915f423 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -1,4 +1,5 @@ /* +/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -1931,12 +1932,11 @@ public class AudioManager { * application when it places a phone call, as it will cause signals from the radio layer * to feed the platform mixer. * - * @param mode the requested audio mode ({@link #MODE_NORMAL}, {@link #MODE_RINGTONE}, - * {@link #MODE_IN_CALL} or {@link #MODE_IN_COMMUNICATION}). + * @param mode the requested audio mode. * Informs the HAL about the current audio state so that * it can route the audio appropriately. */ - public void setMode(int mode) { + public void setMode(@AudioMode int mode) { final IAudioService service = getService(); try { service.setMode(mode, mICallBack, mApplicationContext.getOpPackageName()); @@ -1948,14 +1948,47 @@ public class AudioManager { /** * Returns the current audio mode. * - * @return the current audio mode ({@link #MODE_NORMAL}, {@link #MODE_RINGTONE}, - * {@link #MODE_IN_CALL} or {@link #MODE_IN_COMMUNICATION}). - * Returns the current current audio state from the HAL. + * @return the current audio mode. */ + @AudioMode public int getMode() { final IAudioService service = getService(); try { - return service.getMode(); + int mode = service.getMode(); + int sdk; + try { + sdk = getContext().getApplicationInfo().targetSdkVersion; + } catch (NullPointerException e) { + // some tests don't have a Context + sdk = Build.VERSION.SDK_INT; + } + if (mode == MODE_CALL_SCREENING && sdk <= Build.VERSION_CODES.Q) { + mode = MODE_IN_CALL; + } + return mode; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Indicates if the platform supports a special call screening and call monitoring mode. + * <p> + * When this mode is supported, it is possible to perform call screening and monitoring + * functions while other use cases like music or movie playback are active. + * <p> + * Use {@link #setMode(int)} with mode {@link #MODE_CALL_SCREENING} to place the platform in + * call screening mode. + * <p> + * If call screening mode is not supported, setting mode to + * MODE_CALL_SCREENING will be ignored and will not change current mode reported by + * {@link #getMode()}. + * @return true if call screening mode is supported, false otherwise. + */ + public boolean isCallScreeningModeSupported() { + final IAudioService service = getService(); + try { + return service.isCallScreeningModeSupported(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1989,6 +2022,22 @@ public class AudioManager { * In communication audio mode. An audio/video chat or VoIP call is established. */ public static final int MODE_IN_COMMUNICATION = AudioSystem.MODE_IN_COMMUNICATION; + /** + * Call screening in progress. Call is connected and audio is accessible to call + * screening applications but other audio use cases are still possible. + */ + public static final int MODE_CALL_SCREENING = AudioSystem.MODE_CALL_SCREENING; + + /** @hide */ + @IntDef(flag = false, prefix = "MODE_", value = { + MODE_NORMAL, + MODE_RINGTONE, + MODE_IN_CALL, + MODE_IN_COMMUNICATION, + MODE_CALL_SCREENING } + ) + @Retention(RetentionPolicy.SOURCE) + public @interface AudioMode {} /* Routing bits for setRouting/getRouting API */ /** diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 900572dabc94..a3a87774483b 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -132,7 +132,8 @@ public class AudioSystem public static final int MODE_RINGTONE = 1; public static final int MODE_IN_CALL = 2; public static final int MODE_IN_COMMUNICATION = 3; - public static final int NUM_MODES = 4; + public static final int MODE_CALL_SCREENING = 4; + public static final int NUM_MODES = 5; public static String modeToString(int mode) { switch (mode) { @@ -142,6 +143,7 @@ public class AudioSystem case MODE_INVALID: return "MODE_INVALID"; case MODE_NORMAL: return "MODE_NORMAL"; case MODE_RINGTONE: return "MODE_RINGTONE"; + case MODE_CALL_SCREENING: return "MODE_CALL_SCREENING"; default: return "unknown mode (" + mode + ")"; } } @@ -1130,6 +1132,11 @@ public class AudioSystem */ public static native int setAudioHalPids(int[] pids); + /** + * @see AudioManager#isCallScreeningModeSupported() + */ + public static native boolean isCallScreeningModeSupported(); + // Items shared with audio service /** diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index fc056109baa4..ef451ce401e6 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -263,6 +263,8 @@ interface IAudioService { boolean hasHapticChannels(in Uri uri); + boolean isCallScreeningModeSupported(); + // WARNING: read warning at top of file, new methods that need to be used by native // code via IAudioManager.h need to be added to the top section. } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index d09139c0589c..b81f5e177e7d 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -772,6 +772,8 @@ public class AudioService extends IAudioService.Stub readAndSetLowRamDevice(); + mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); + // Call setRingerModeInt() to apply correct mute // state on streams affected by ringer mode. mRingerAndZenModeMutedStreams = 0; @@ -965,6 +967,8 @@ public class AudioService extends IAudioService.Stub readAndSetLowRamDevice(); + mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported(); + // Restore device connection states, BT state mDeviceBroker.onAudioServerDied(); @@ -3287,6 +3291,12 @@ public class AudioService extends IAudioService.Stub return; } + if (mode == AudioSystem.MODE_CALL_SCREENING && !mIsCallScreeningModeSupported) { + Log.w(TAG, "setMode(MODE_CALL_SCREENING) not permitted " + + "when call screening is not supported"); + return; + } + if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) { return; } @@ -3417,6 +3427,14 @@ public class AudioService extends IAudioService.Stub return mMode; } + /** cached value read from audiopolicy manager after initialization. */ + private boolean mIsCallScreeningModeSupported = false; + + /** @see AudioManager#isCallScreeningModeSupported() */ + public boolean isCallScreeningModeSupported() { + return mIsCallScreeningModeSupported; + } + //========================================================================================== // Sound Effects //========================================================================================== @@ -6149,6 +6167,7 @@ public class AudioService extends IAudioService.Stub pw.print(" mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient); pw.print(" mHdmiTvClient="); pw.println(mHdmiTvClient); pw.print(" mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported); + pw.print(" mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported); dumpAudioPolicies(pw); mDynPolicyLogger.dump(pw); |