diff options
-rw-r--r-- | Android.bp | 1 | ||||
-rw-r--r-- | OWNERS | 9 | ||||
-rw-r--r-- | api/system-current.txt | 20 | ||||
-rw-r--r-- | java/com/android/libraries/tv/tvsystem/media/AudioDeviceAttributes.java | 179 | ||||
-rw-r--r-- | java/com/android/libraries/tv/tvsystem/media/TvAudioManager.java | 76 |
5 files changed, 285 insertions, 0 deletions
@@ -18,6 +18,7 @@ java_sdk_library { api_packages: [ "com.android.libraries.tv.tvsystem", "com.android.libraries.tv.tvsystem.display", + "com.android.libraries.tv.tvsystem.media", "com.android.libraries.tv.tvsystem.pm", "com.android.libraries.tv.tvsystem.user", "com.android.libraries.tv.tvsystem.wifi" @@ -0,0 +1,9 @@ +# Primary maintainer +robhor@google.com + +# Additional maintainers +galinap@google.com +philipjunker@google.com +rgl@google.com +sergeynv@google.com +valiiftime@google.com diff --git a/api/system-current.txt b/api/system-current.txt index aa0d1db..dbd0cc2 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1,4 +1,24 @@ // Signature format: 2.0 +package com.android.libraries.tv.tvsystem.media { + + public final class AudioDeviceAttributes { + ctor public AudioDeviceAttributes(@NonNull android.media.AudioDeviceInfo); + ctor public AudioDeviceAttributes(int, int, @NonNull String); + method @NonNull public String getAddress(); + method public int getRole(); + method public int getType(); + field public static final int ROLE_INPUT = 1; // 0x1 + field public static final int ROLE_OUTPUT = 2; // 0x2 + } + + public final class TvAudioManager { + ctor public TvAudioManager(@NonNull android.content.Context); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getDeviceVolumeBehavior(@NonNull com.android.libraries.tv.tvsystem.media.AudioDeviceAttributes); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolumeBehavior(@NonNull com.android.libraries.tv.tvsystem.media.AudioDeviceAttributes, int); + } + +} + package com.android.libraries.tv.tvsystem.wifi { public final class SoftApConfiguration implements android.os.Parcelable { diff --git a/java/com/android/libraries/tv/tvsystem/media/AudioDeviceAttributes.java b/java/com/android/libraries/tv/tvsystem/media/AudioDeviceAttributes.java new file mode 100644 index 0000000..581d189 --- /dev/null +++ b/java/com/android/libraries/tv/tvsystem/media/AudioDeviceAttributes.java @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2020 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 + */ + +package com.android.libraries.tv.tvsystem.media; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.media.AudioDeviceInfo; +import android.media.AudioPort; +import android.media.AudioSystem; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +/** + * @hide + * Class to represent the attributes of an audio device: its type (speaker, headset...), address + * (if known) and role (input, output). + * <p>Unlike {@link AudioDeviceInfo}, the device + * doesn't need to be connected to be uniquely identified, it can + * for instance represent a specific A2DP headset even after a + * disconnection, whereas the corresponding <code>AudioDeviceInfo</code> + * would then be invalid. + * <p>While creating / obtaining an instance is not protected by a + * permission, APIs using one rely on MODIFY_AUDIO_ROUTING. + */ +@SystemApi +public final class AudioDeviceAttributes { + + /** + * A role identifying input devices, such as microphones. + */ + public static final int ROLE_INPUT = AudioPort.ROLE_SOURCE; + /** + * A role identifying output devices, such as speakers or headphones. + */ + public static final int ROLE_OUTPUT = AudioPort.ROLE_SINK; + + /** @hide */ + @IntDef(flag = false, prefix = "ROLE_", value = { + ROLE_INPUT, ROLE_OUTPUT } + ) + @Retention(RetentionPolicy.SOURCE) + public @interface Role {} + + /** + * The audio device type, as defined in {@link AudioDeviceInfo} + */ + private final @AudioDeviceInfo.AudioDeviceType int mType; + /** + * The unique address of the device. Some devices don't have addresses, only an empty string. + */ + private final @NonNull String mAddress; + + /** + * Is input or output device + */ + private final @AudioDeviceAttributes.Role + int mRole; + + /** + * @hide + * Constructor from a valid {@link AudioDeviceInfo} + * @param deviceInfo the connected audio device from which to obtain the device-identifying + * type and address. + */ + @SystemApi + public AudioDeviceAttributes(@NonNull AudioDeviceInfo deviceInfo) { + Objects.requireNonNull(deviceInfo); + mRole = deviceInfo.isSink() ? ROLE_OUTPUT : ROLE_INPUT; + mType = deviceInfo.getType(); + mAddress = deviceInfo.getAddress(); + } + + /** + * @hide + * Constructor from role, device type and address + * @param role indicates input or output role + * @param type the device type, as defined in {@link AudioDeviceInfo} + * @param address the address of the device, or an empty string for devices without one + */ + @SystemApi + public AudioDeviceAttributes(@AudioDeviceAttributes.Role int role, + @AudioDeviceInfo.AudioDeviceType int type, + @NonNull String address) { + Objects.requireNonNull(address); + if (role != ROLE_OUTPUT && role != ROLE_INPUT) { + throw new IllegalArgumentException("Invalid role " + role); + } + + mRole = role; + mType = type; + mAddress = address; + } + + /*package*/ AudioDeviceAttributes(int nativeType, @NonNull String address) { + mRole = (nativeType & AudioSystem.DEVICE_BIT_IN) != 0 ? ROLE_INPUT : ROLE_OUTPUT; + mType = AudioDeviceInfo.convertInternalDeviceToDeviceType(nativeType); + mAddress = address; + } + + /** + * @hide + * Returns the role of a device + * @return the role + */ + @SystemApi + public @AudioDeviceAttributes.Role + int getRole() { + return mRole; + } + + /** + * @hide + * Returns the audio device type of a device + * @return the type, as defined in {@link AudioDeviceInfo} + */ + @SystemApi + public @AudioDeviceInfo.AudioDeviceType int getType() { + return mType; + } + + /** + * @hide + * Returns the address of the audio device, or an empty string for devices without one + * @return the device address + */ + @SystemApi + public @NonNull String getAddress() { + return mAddress; + } + + @Override + public int hashCode() { + return Objects.hash(mRole, mType, mAddress); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AudioDeviceAttributes that = (AudioDeviceAttributes) o; + return ((mRole == that.mRole) + && (mType == that.mType) + && mAddress.equals(that.mAddress)); + } + + /** @hide */ + public static String roleToString(@AudioDeviceAttributes.Role int role) { + return (role == ROLE_OUTPUT ? "output" : "input"); + } + + @Override + public String toString() { + return new String("AudioDeviceAttributes:" + + " role:" + roleToString(mRole) + + " type:" + (mRole == ROLE_OUTPUT ? AudioSystem.getOutputDeviceName( + AudioDeviceInfo.convertDeviceTypeToInternalDevice(mType)) + : AudioSystem.getInputDeviceName( + AudioDeviceInfo.convertDeviceTypeToInternalDevice(mType))) + + " addr:" + mAddress); + } +} diff --git a/java/com/android/libraries/tv/tvsystem/media/TvAudioManager.java b/java/com/android/libraries/tv/tvsystem/media/TvAudioManager.java new file mode 100644 index 0000000..7b18200 --- /dev/null +++ b/java/com/android/libraries/tv/tvsystem/media/TvAudioManager.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 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 + */ + +package com.android.libraries.tv.tvsystem.media; + + +import android.annotation.NonNull; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; +import android.content.Context; +import android.media.AudioManager; + +/** + * Provides access to APIs in {@link AudioManager} that are otherwise @hidden. + * + * @hide + */ +@SystemApi +public final class TvAudioManager { + + private final AudioManager mAudioManager; + + public TvAudioManager(@NonNull Context context) { + mAudioManager = context.getSystemService(AudioManager.class); + } + + /** + * @hide + * Sets the volume behavior for an audio output device. + * @see AudioManager#DEVICE_VOLUME_BEHAVIOR_VARIABLE + * @see AudioManager#DEVICE_VOLUME_BEHAVIOR_FULL + * @see AudioManager#DEVICE_VOLUME_BEHAVIOR_FIXED + * @see AudioManager#DEVICE_VOLUME_BEHAVIOR_ABSOLUTE + * @see AudioManager#DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE + * @param device the device to be affected + * @param deviceVolumeBehavior one of the device behaviors + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device, + @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) { + android.media.AudioDeviceAttributes audioDeviceAttributes = + new android.media.AudioDeviceAttributes(device.getRole(), device.getType(), + device.getAddress()); + mAudioManager.setDeviceVolumeBehavior(audioDeviceAttributes, deviceVolumeBehavior); + } + + /** + * @hide + * Returns the volume device behavior for the given audio device + * @param device the audio device + * @return the volume behavior for the device + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + public @AudioManager.DeviceVolumeBehavior + int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) { + android.media.AudioDeviceAttributes audioDeviceAttributes = + new android.media.AudioDeviceAttributes(device.getRole(), device.getType(), + device.getAddress()); + return mAudioManager.getDeviceVolumeBehavior(audioDeviceAttributes); + } +} |