| /* |
| * Copyright (C) 2018 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 android.media.audiopolicy; |
| |
| import android.annotation.NonNull; |
| import android.annotation.SystemApi; |
| import android.media.AudioAttributes; |
| import android.media.AudioSystem; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| import android.util.Log; |
| |
| import com.android.internal.annotations.GuardedBy; |
| import com.android.internal.util.Preconditions; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| /** |
| * A class to create the association between different playback attributes |
| * (e.g. media, mapping direction) to a single volume control. |
| * @hide |
| */ |
| @SystemApi |
| public final class AudioVolumeGroup implements Parcelable { |
| private static final String TAG = "AudioVolumeGroup"; |
| /** |
| * Volume group value to use when introspection API fails. |
| */ |
| public static final int DEFAULT_VOLUME_GROUP = -1; |
| |
| /** |
| * Unique identifier of a volume group. |
| */ |
| private int mId; |
| /** |
| * human-readable name of this volume group. |
| */ |
| private final String mName; |
| |
| private final AudioAttributes[] mAudioAttributes; |
| private int[] mLegacyStreamTypes; |
| |
| private static final Object sLock = new Object(); |
| |
| @GuardedBy("sLock") |
| private static List<AudioVolumeGroup> sAudioVolumeGroups; |
| |
| /** |
| * @hide |
| * @return the List of AudioVolumeGroup discovered from platform configuration file. |
| */ |
| @NonNull |
| public static List<AudioVolumeGroup> getAudioVolumeGroups() { |
| if (sAudioVolumeGroups == null) { |
| synchronized (sLock) { |
| if (sAudioVolumeGroups == null) { |
| sAudioVolumeGroups = initializeAudioVolumeGroups(); |
| } |
| } |
| } |
| return sAudioVolumeGroups; |
| } |
| |
| private static List<AudioVolumeGroup> initializeAudioVolumeGroups() { |
| ArrayList<AudioVolumeGroup> avgList = new ArrayList<>(); |
| int status = native_list_audio_volume_groups(avgList); |
| if (status != AudioSystem.SUCCESS) { |
| Log.w(TAG, ": listAudioVolumeGroups failed"); |
| } |
| return avgList; |
| } |
| |
| private static native int native_list_audio_volume_groups( |
| ArrayList<AudioVolumeGroup> groups); |
| |
| /** |
| * @param name of the volume group |
| * @param id of the volume group |
| * @param legacyStreamTypes of volume group |
| */ |
| AudioVolumeGroup(@NonNull String name, int id, |
| @NonNull AudioAttributes[] audioAttributes, |
| @NonNull int[] legacyStreamTypes) { |
| Preconditions.checkNotNull(name, "name must not be null"); |
| Preconditions.checkNotNull(audioAttributes, "audioAttributes must not be null"); |
| Preconditions.checkNotNull(legacyStreamTypes, "legacyStreamTypes must not be null"); |
| mName = name; |
| mId = id; |
| mAudioAttributes = audioAttributes; |
| mLegacyStreamTypes = legacyStreamTypes; |
| } |
| |
| @Override |
| public boolean equals(@NonNull Object o) { |
| if (this == o) return true; |
| if (o == null || getClass() != o.getClass()) return false; |
| |
| AudioVolumeGroup thatAvg = (AudioVolumeGroup) o; |
| |
| return mName == thatAvg.mName && mId == thatAvg.mId |
| && mAudioAttributes.equals(thatAvg.mAudioAttributes); |
| } |
| |
| /** |
| * @return List of {@link AudioAttributes} involved in this {@link AudioVolumeGroup}. |
| */ |
| public @NonNull List<AudioAttributes> getAudioAttributes() { |
| return Arrays.asList(mAudioAttributes); |
| } |
| |
| /** |
| * @return the stream types involved in this {@link AudioVolumeGroup}. |
| */ |
| public @NonNull int[] getLegacyStreamTypes() { |
| return mLegacyStreamTypes; |
| } |
| |
| /** |
| * @return human-readable name of this volume group. |
| */ |
| public @NonNull String name() { |
| return mName; |
| } |
| |
| /** |
| * @return the volume group unique identifier id. |
| */ |
| public int getId() { |
| return mId; |
| } |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| @Override |
| public void writeToParcel(@NonNull Parcel dest, int flags) { |
| dest.writeString(mName); |
| dest.writeInt(mId); |
| dest.writeInt(mAudioAttributes.length); |
| for (AudioAttributes attributes : mAudioAttributes) { |
| attributes.writeToParcel(dest, flags | AudioAttributes.FLATTEN_TAGS/*flags*/); |
| } |
| dest.writeInt(mLegacyStreamTypes.length); |
| for (int streamType : mLegacyStreamTypes) { |
| dest.writeInt(streamType); |
| } |
| } |
| |
| public static final Parcelable.Creator<AudioVolumeGroup> CREATOR = |
| new Parcelable.Creator<AudioVolumeGroup>() { |
| @Override |
| public @NonNull AudioVolumeGroup createFromParcel(@NonNull Parcel in) { |
| Preconditions.checkNotNull(in, "in Parcel must not be null"); |
| String name = in.readString(); |
| int id = in.readInt(); |
| int nbAttributes = in.readInt(); |
| AudioAttributes[] audioAttributes = new AudioAttributes[nbAttributes]; |
| for (int index = 0; index < nbAttributes; index++) { |
| audioAttributes[index] = AudioAttributes.CREATOR.createFromParcel(in); |
| } |
| int nbStreamTypes = in.readInt(); |
| int[] streamTypes = new int[nbStreamTypes]; |
| for (int index = 0; index < nbStreamTypes; index++) { |
| streamTypes[index] = in.readInt(); |
| } |
| return new AudioVolumeGroup(name, id, audioAttributes, streamTypes); |
| } |
| |
| @Override |
| public @NonNull AudioVolumeGroup[] newArray(int size) { |
| return new AudioVolumeGroup[size]; |
| } |
| }; |
| |
| @Override |
| public @NonNull String toString() { |
| StringBuilder s = new StringBuilder(); |
| s.append("\n Name: "); |
| s.append(mName); |
| s.append(" Id: "); |
| s.append(Integer.toString(mId)); |
| |
| s.append("\n Supported Audio Attributes:"); |
| for (AudioAttributes attribute : mAudioAttributes) { |
| s.append("\n -"); |
| s.append(attribute.toString()); |
| } |
| s.append("\n Supported Legacy Stream Types: { "); |
| for (int legacyStreamType : mLegacyStreamTypes) { |
| s.append(Integer.toString(legacyStreamType)); |
| s.append(" "); |
| } |
| s.append("}"); |
| return s.toString(); |
| } |
| } |