From ebd6aaa4b0f7b302e9733dd5a801b01bc450af4f Mon Sep 17 00:00:00 2001 From: Hayden Gomes Date: Thu, 4 Apr 2019 13:14:21 -0700 Subject: [PATCH] Replacing AudioVolumeGroups with List Bug: 129262395 Test: Built and ran on device Change-Id: I838296ead584b85be50028c410b9a2d0ba3b0398 --- api/system-current.txt | 12 +- .../android/preference/SeekBarVolumizer.java | 16 +-- core/jni/android_media_AudioVolumeGroups.cpp | 2 +- media/java/android/media/AudioManager.java | 11 +- media/java/android/media/IAudioService.aidl | 4 +- .../audiopolicy/AudioProductStrategy.java | 8 +- .../media/audiopolicy/AudioVolumeGroup.java | 43 ++++++ .../media/audiopolicy/AudioVolumeGroups.aidl | 18 --- .../media/audiopolicy/AudioVolumeGroups.java | 135 ------------------ .../android/server/audio/AudioService.java | 33 +++-- 10 files changed, 85 insertions(+), 197 deletions(-) delete mode 100644 media/java/android/media/audiopolicy/AudioVolumeGroups.aidl delete mode 100644 media/java/android/media/audiopolicy/AudioVolumeGroups.java diff --git a/api/system-current.txt b/api/system-current.txt index d651985b1f0d8..4eef9aaeea865 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3498,7 +3498,7 @@ package android.media { method public void clearAudioServerStateCallback(); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List getAudioProductStrategies(); - method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.audiopolicy.AudioVolumeGroups getAudioVolumeGroups(); + method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List getAudioVolumeGroups(); method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes); method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes); method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes); @@ -3693,16 +3693,6 @@ package android.media.audiopolicy { method @NonNull public String name(); method public void writeToParcel(@NonNull android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; - } - - public final class AudioVolumeGroups implements java.lang.Iterable android.os.Parcelable { - ctor public AudioVolumeGroups(); - method public int describeContents(); - method @Nullable public android.media.audiopolicy.AudioVolumeGroup getById(int); - method @NonNull public java.util.Iterator iterator(); - method public int size(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field public static final android.os.Parcelable.Creator CREATOR; field public static final int DEFAULT_VOLUME_GROUP = -1; // 0xffffffff } diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java index f176dc3485f35..02f99258395c6 100644 --- a/core/java/android/preference/SeekBarVolumizer.java +++ b/core/java/android/preference/SeekBarVolumizer.java @@ -29,7 +29,7 @@ import android.media.AudioManager; import android.media.Ringtone; import android.media.RingtoneManager; import android.media.audiopolicy.AudioProductStrategy; -import android.media.audiopolicy.AudioVolumeGroups; +import android.media.audiopolicy.AudioVolumeGroup; import android.net.Uri; import android.os.Handler; import android.os.HandlerThread; @@ -196,7 +196,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba for (final AudioProductStrategy productStrategy : AudioManager.getAudioProductStrategies()) { int volumeGroupId = productStrategy.getVolumeGroupIdForLegacyStreamType(streamType); - if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) { + if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { return volumeGroupId; } } @@ -204,9 +204,9 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba return AudioManager.getAudioProductStrategies().stream() .map(strategy -> strategy.getVolumeGroupIdForAudioAttributes( AudioProductStrategy.sDefaultAttributes)) - .filter(volumeGroupId -> volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) + .filter(volumeGroupId -> volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) .findFirst() - .orElse(AudioVolumeGroups.DEFAULT_VOLUME_GROUP); + .orElse(AudioVolumeGroup.DEFAULT_VOLUME_GROUP); } private @NonNull AudioAttributes getAudioAttributesForLegacyStreamType(int streamType) { @@ -556,7 +556,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba updateVolumeSlider(streamType, streamVolume); } else { int volumeGroup = getVolumeGroupIdForLegacyStreamType(streamType); - if (volumeGroup != AudioVolumeGroups.DEFAULT_VOLUME_GROUP + if (volumeGroup != AudioVolumeGroup.DEFAULT_VOLUME_GROUP && volumeGroup == mVolumeGroupId) { int streamVolume = mAudioManager.getStreamVolume(streamType); updateVolumeSlider(streamType, streamVolume); @@ -589,14 +589,14 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba } private void registerVolumeGroupCb() { - if (mVolumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) { + if (mVolumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { mAudioManager.registerVolumeGroupCallback(Runnable::run, mVolumeGroupCallback); mLastProgress = mAudioManager.getVolumeIndexForAttributes(mAttributes); } } private void unregisterVolumeGroupCb() { - if (mVolumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) { + if (mVolumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { mAudioManager.unregisterVolumeGroupCallback(mVolumeGroupCallback); } } @@ -609,7 +609,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba case MSG_GROUP_VOLUME_CHANGED: int group = (int) args.arg1; if (mVolumeGroupId != group - || mVolumeGroupId == AudioVolumeGroups.DEFAULT_VOLUME_GROUP) { + || mVolumeGroupId == AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { return; } updateSlider(); diff --git a/core/jni/android_media_AudioVolumeGroups.cpp b/core/jni/android_media_AudioVolumeGroups.cpp index 64f0c1e33e1c3..7098451901c42 100644 --- a/core/jni/android_media_AudioVolumeGroups.cpp +++ b/core/jni/android_media_AudioVolumeGroups.cpp @@ -39,7 +39,7 @@ using namespace android; // ---------------------------------------------------------------------------- -static const char* const kClassPathName = "android/media/audiopolicy/AudioVolumeGroups"; +static const char* const kClassPathName = "android/media/audiopolicy/AudioVolumeGroup"; static const char* const kAudioVolumeGroupClassPathName = "android/media/audiopolicy/AudioVolumeGroup"; diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index f80c8c61cec98..d5eee6308ae09 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -38,8 +38,8 @@ import android.content.Intent; import android.media.audiopolicy.AudioPolicy; import android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener; import android.media.audiopolicy.AudioProductStrategy; +import android.media.audiopolicy.AudioVolumeGroup; import android.media.audiopolicy.AudioVolumeGroupChangeHandler; -import android.media.audiopolicy.AudioVolumeGroups; import android.media.projection.MediaProjection; import android.media.session.MediaController; import android.media.session.MediaSession; @@ -5422,15 +5422,16 @@ public class AudioManager { * Introspection API to retrieve audio volume groups. * When implementing {Car|Oem}AudioManager, use this method to retrieve the collection of * audio volume groups. - * @return a (possibly zero-length) array of - * {@see android.media.audiopolicy.AudioVolumeGroups} objects. + * @return a (possibly zero-length) List of + * {@see android.media.audiopolicy.AudioVolumeGroup} objects. */ @SystemApi + @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) - public @NonNull AudioVolumeGroups getAudioVolumeGroups() { + public static List getAudioVolumeGroups() { final IAudioService service = getService(); try { - return service.listAudioVolumeGroups(); + return service.getAudioVolumeGroups(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 36c9b5a9dbb86..eddbee46252e4 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -34,7 +34,7 @@ import android.media.PlayerBase; import android.media.VolumePolicy; import android.media.audiopolicy.AudioPolicyConfig; import android.media.audiopolicy.AudioProductStrategy; -import android.media.audiopolicy.AudioVolumeGroups; +import android.media.audiopolicy.AudioVolumeGroup; import android.media.audiopolicy.IAudioPolicyCallback; import android.media.projection.IMediaProjection; import android.net.Uri; @@ -86,7 +86,7 @@ interface IAudioService { @UnsupportedAppUsage int getStreamMaxVolume(int streamType); - AudioVolumeGroups listAudioVolumeGroups(); + List getAudioVolumeGroups(); void setVolumeIndexForAttributes(in AudioAttributes aa, int index, int flags, String callingPackage); diff --git a/media/java/android/media/audiopolicy/AudioProductStrategy.java b/media/java/android/media/audiopolicy/AudioProductStrategy.java index eed4502364747..9ac9411370ab2 100644 --- a/media/java/android/media/audiopolicy/AudioProductStrategy.java +++ b/media/java/android/media/audiopolicy/AudioProductStrategy.java @@ -236,7 +236,7 @@ public final class AudioProductStrategy implements Parcelable { * @hide * @param streamType legacy stream type used for volume operation only * @return the volume group id relevant for the given streamType. - * If none is found, {@link AudioVolumeGroups#DEFAULT_VOLUME_GROUP} is returned. + * If none is found, {@link AudioVolumeGroup#DEFAULT_VOLUME_GROUP} is returned. */ public int getVolumeGroupIdForLegacyStreamType(int streamType) { for (final AudioAttributesGroup aag : mAudioAttributesGroups) { @@ -244,14 +244,14 @@ public final class AudioProductStrategy implements Parcelable { return aag.getVolumeGroupId(); } } - return AudioVolumeGroups.DEFAULT_VOLUME_GROUP; + return AudioVolumeGroup.DEFAULT_VOLUME_GROUP; } /** * @hide * @param aa the {@link AudioAttributes} to be considered * @return the volume group id associated with the given audio attributes if found, - * {@link AudioVolumeGroups#DEFAULT_VOLUME_GROUP} otherwise. + * {@link AudioVolumeGroup#DEFAULT_VOLUME_GROUP} otherwise. */ public int getVolumeGroupIdForAudioAttributes(@NonNull AudioAttributes aa) { Preconditions.checkNotNull(aa, "AudioAttributes must not be null"); @@ -260,7 +260,7 @@ public final class AudioProductStrategy implements Parcelable { return aag.getVolumeGroupId(); } } - return AudioVolumeGroups.DEFAULT_VOLUME_GROUP; + return AudioVolumeGroup.DEFAULT_VOLUME_GROUP; } @Override diff --git a/media/java/android/media/audiopolicy/AudioVolumeGroup.java b/media/java/android/media/audiopolicy/AudioVolumeGroup.java index 964de95932c52..79be922144556 100644 --- a/media/java/android/media/audiopolicy/AudioVolumeGroup.java +++ b/media/java/android/media/audiopolicy/AudioVolumeGroup.java @@ -19,11 +19,15 @@ 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; @@ -34,6 +38,12 @@ import java.util.List; */ @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. */ @@ -46,6 +56,39 @@ public final class AudioVolumeGroup implements Parcelable { private final AudioAttributes[] mAudioAttributes; private int[] mLegacyStreamTypes; + private static final Object sLock = new Object(); + + @GuardedBy("sLock") + private static List sAudioVolumeGroups; + + /** + * @hide + * @return the List of AudioVolumeGroup discovered from platform configuration file. + */ + @NonNull + public static List getAudioVolumeGroups() { + if (sAudioVolumeGroups == null) { + synchronized (sLock) { + if (sAudioVolumeGroups == null) { + sAudioVolumeGroups = initializeAudioVolumeGroups(); + } + } + } + return sAudioVolumeGroups; + } + + private static List initializeAudioVolumeGroups() { + ArrayList 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 groups); + /** * @param name of the volume group * @param id of the volume group diff --git a/media/java/android/media/audiopolicy/AudioVolumeGroups.aidl b/media/java/android/media/audiopolicy/AudioVolumeGroups.aidl deleted file mode 100644 index 918cac39f19ac..0000000000000 --- a/media/java/android/media/audiopolicy/AudioVolumeGroups.aidl +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 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; - -parcelable AudioVolumeGroups; diff --git a/media/java/android/media/audiopolicy/AudioVolumeGroups.java b/media/java/android/media/audiopolicy/AudioVolumeGroups.java deleted file mode 100644 index 2e56f846e5748..0000000000000 --- a/media/java/android/media/audiopolicy/AudioVolumeGroups.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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.Nullable; -import android.annotation.SystemApi; -import android.media.AudioSystem; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; - -import com.android.internal.util.Preconditions; - -import java.util.ArrayList; -import java.util.Iterator; - -/** - * @hide - * A class to encapsulate a collection of {@link AudioVolumeGroup}. - */ -@SystemApi -public final class AudioVolumeGroups implements Iterable, Parcelable { - - private final ArrayList mAudioVolumeGroupList; - - private static final String TAG = "AudioVolumeGroups"; - - /** - * Volume group value to use when introspection API fails. - */ - public static final int DEFAULT_VOLUME_GROUP = -1; - - public AudioVolumeGroups() { - ArrayList avgList = new ArrayList(); - int status = native_list_audio_volume_groups(avgList); - if (status != AudioSystem.SUCCESS) { - Log.w(TAG, ": listAudioVolumeGroups failed"); - } - mAudioVolumeGroupList = avgList; - } - - private AudioVolumeGroups(@NonNull ArrayList audioVolumeGroupList) { - Preconditions.checkNotNull(audioVolumeGroupList, "audioVolumeGroupList must not be null"); - mAudioVolumeGroupList = audioVolumeGroupList; - } - - /** - * @return number of {@link AudioProductStrategy} objects - */ - public int size() { - return mAudioVolumeGroupList.size(); - } - - /** - * Returns an {@link Iterator} - */ - @Override - public @NonNull Iterator iterator() { - return mAudioVolumeGroupList.iterator(); - } - - @Override - public boolean equals(@NonNull Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - AudioVolumeGroups that = (AudioVolumeGroups) o; - - return mAudioVolumeGroupList.equals(that.mAudioVolumeGroupList); - } - - /** - * @return the matching {@link AudioVolumeGroup} objects with the given id, - * null object if not found. - */ - public @Nullable AudioVolumeGroup getById(int volumeGroupId) { - for (final AudioVolumeGroup avg : this) { - if (avg.getId() == volumeGroupId) { - return avg; - } - } - Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested"); - return null; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeInt(size()); - for (final AudioVolumeGroup volumeGroup : this) { - volumeGroup.writeToParcel(dest, flags); - } - } - - private static native int native_list_audio_volume_groups( - ArrayList groups); - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public @NonNull AudioVolumeGroups createFromParcel(@NonNull Parcel in) { - Preconditions.checkNotNull(in, "in Parcel must not be null"); - ArrayList avgList = new ArrayList(); - int size = in.readInt(); - for (int index = 0; index < size; index++) { - avgList.add(AudioVolumeGroup.CREATOR.createFromParcel(in)); - } - return new AudioVolumeGroups(avgList); - } - - @Override - public @NonNull AudioVolumeGroups[] newArray(int size) { - return new AudioVolumeGroups[size]; - } - }; -} diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 832cd877d0ade..77472ed288c3a 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -92,7 +92,6 @@ import android.media.audiopolicy.AudioPolicy; import android.media.audiopolicy.AudioPolicyConfig; import android.media.audiopolicy.AudioProductStrategy; import android.media.audiopolicy.AudioVolumeGroup; -import android.media.audiopolicy.AudioVolumeGroups; import android.media.audiopolicy.IAudioPolicyCallback; import android.media.projection.IMediaProjection; import android.media.projection.IMediaProjectionManager; @@ -281,9 +280,6 @@ public class AudioService extends IAudioService.Stub private SettingsObserver mSettingsObserver; - /** @see AudioVolumeGroups */ - private static AudioVolumeGroups sAudioVolumeGroups; - private int mMode = AudioSystem.MODE_NORMAL; // protects mRingerMode private final Object mSettingsLock = new Object(); @@ -634,8 +630,6 @@ public class AudioService extends IAudioService.Stub mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator(); - sAudioVolumeGroups = new AudioVolumeGroups(); - // Initialize volume // Priority 1 - Android Property // Priority 2 - Audio Policy Service @@ -1030,11 +1024,12 @@ public class AudioService extends IAudioService.Stub } /** - * @return the {@link android.media.audiopolicy.AudioVolumeGroups} discovered from the + * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the * platform configuration file. */ - public @NonNull AudioVolumeGroups listAudioVolumeGroups() { - return sAudioVolumeGroups; + @NonNull + public List getAudioVolumeGroups() { + return AudioVolumeGroup.getAudioVolumeGroups(); } private void checkAllAliasStreamVolumes() { @@ -1954,7 +1949,7 @@ public class AudioService extends IAudioService.Stub AudioSystem.setVolumeIndexForAttributes(attr, index, device); final int volumeGroup = getVolumeGroupIdForAttributes(attr); - final AudioVolumeGroup avg = sAudioVolumeGroups.getById(volumeGroup); + final AudioVolumeGroup avg = getAudioVolumeGroupById(volumeGroup); if (avg == null) { return; } @@ -1964,6 +1959,18 @@ public class AudioService extends IAudioService.Stub } } + @Nullable + private AudioVolumeGroup getAudioVolumeGroupById(int volumeGroupId) { + for (final AudioVolumeGroup avg : AudioVolumeGroup.getAudioVolumeGroups()) { + if (avg.getId() == volumeGroupId) { + return avg; + } + } + + Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested"); + return null; + } + /** @see AudioManager#getVolumeIndexForAttributes(attr) */ public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) { enforceModifyAudioRoutingPermission(); @@ -2148,7 +2155,7 @@ public class AudioService extends IAudioService.Stub private int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) { Preconditions.checkNotNull(attributes, "attributes must not be null"); int volumeGroupId = getVolumeGroupIdForAttributesInt(attributes); - if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) { + if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { return volumeGroupId; } // The default volume group is the one hosted by default product strategy, i.e. @@ -2161,11 +2168,11 @@ public class AudioService extends IAudioService.Stub for (final AudioProductStrategy productStrategy : AudioProductStrategy.getAudioProductStrategies()) { int volumeGroupId = productStrategy.getVolumeGroupIdForAudioAttributes(attributes); - if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) { + if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) { return volumeGroupId; } } - return AudioVolumeGroups.DEFAULT_VOLUME_GROUP; + return AudioVolumeGroup.DEFAULT_VOLUME_GROUP; }