Replacing AudioProductStrategies with List
- Removed AudioProductStrategies and updated usages to work with List<AudioProductStrategy> - ditributed looping logic to the respective callers Test: built successfully with make and ran on device Bug: 129265140 Change-Id: If95ba9c2418a1fda29590ca1af2d04e7395c2130
This commit is contained in:
@@ -3497,7 +3497,7 @@ package android.media {
|
||||
method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes);
|
||||
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 android.media.audiopolicy.AudioProductStrategies getAudioProductStrategies();
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.audiopolicy.AudioVolumeGroups 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);
|
||||
@@ -3677,22 +3677,6 @@ package android.media.audiopolicy {
|
||||
method @NonNull public android.media.audiopolicy.AudioPolicy.Builder setLooper(@NonNull android.os.Looper) throws java.lang.IllegalArgumentException;
|
||||
}
|
||||
|
||||
public final class AudioProductStrategies implements java.lang.Iterable<android.media.audiopolicy.AudioProductStrategy> android.os.Parcelable {
|
||||
ctor public AudioProductStrategies();
|
||||
method public int describeContents();
|
||||
method @NonNull public android.media.AudioAttributes getAudioAttributesForLegacyStreamType(int);
|
||||
method @NonNull public android.media.AudioAttributes getAudioAttributesForProductStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
|
||||
method @Nullable public android.media.audiopolicy.AudioProductStrategy getById(int);
|
||||
method public int getLegacyStreamTypeForAudioAttributes(@NonNull android.media.AudioAttributes);
|
||||
method @Nullable public android.media.audiopolicy.AudioProductStrategy getProductStrategyForAudioAttributes(@NonNull android.media.AudioAttributes);
|
||||
method public int getVolumeGroupIdForAttributes(@NonNull android.media.AudioAttributes);
|
||||
method public int getVolumeGroupIdForLegacyStreamType(int);
|
||||
method @NonNull public java.util.Iterator<android.media.audiopolicy.AudioProductStrategy> iterator();
|
||||
method public int size();
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioProductStrategies> CREATOR;
|
||||
}
|
||||
|
||||
public final class AudioProductStrategy implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method @NonNull public android.media.AudioAttributes getAudioAttributes();
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.preference;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.UnsupportedAppUsage;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -27,7 +28,7 @@ import android.media.AudioAttributes;
|
||||
import android.media.AudioManager;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.media.audiopolicy.AudioProductStrategies;
|
||||
import android.media.audiopolicy.AudioProductStrategy;
|
||||
import android.media.audiopolicy.AudioVolumeGroups;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
@@ -44,6 +45,7 @@ import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
/**
|
||||
* Turns a {@link SeekBar} into a volume control.
|
||||
@@ -67,7 +69,6 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
|
||||
|
||||
private static final int MSG_GROUP_VOLUME_CHANGED = 1;
|
||||
private final Handler mVolumeHandler = new VolumeHandler();
|
||||
private final AudioProductStrategies mAudioProductStrategies;
|
||||
private AudioAttributes mAttributes;
|
||||
private int mVolumeGroupId;
|
||||
|
||||
@@ -161,11 +162,9 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
|
||||
}
|
||||
mZenMode = mNotificationManager.getZenMode();
|
||||
|
||||
mAudioProductStrategies = mAudioManager.getAudioProductStrategies();
|
||||
if (mAudioProductStrategies.size() > 0) {
|
||||
mVolumeGroupId = mAudioProductStrategies.getVolumeGroupIdForLegacyStreamType(
|
||||
mStreamType);
|
||||
mAttributes = mAudioProductStrategies.getAudioAttributesForLegacyStreamType(
|
||||
if (AudioManager.getAudioProductStrategies().size() > 0) {
|
||||
mVolumeGroupId = getVolumeGroupIdForLegacyStreamType(mStreamType);
|
||||
mAttributes = getAudioAttributesForLegacyStreamType(
|
||||
mStreamType);
|
||||
}
|
||||
|
||||
@@ -190,6 +189,44 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
|
||||
mDefaultUri = defaultUri;
|
||||
}
|
||||
|
||||
private int getVolumeGroupIdForLegacyStreamType(int streamType) {
|
||||
for (final AudioProductStrategy productStrategy :
|
||||
AudioManager.getAudioProductStrategies()) {
|
||||
int volumeGroupId = productStrategy.getVolumeGroupIdForLegacyStreamType(streamType);
|
||||
if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
|
||||
return volumeGroupId;
|
||||
}
|
||||
}
|
||||
// The default volume group is the one hosted by default product strategy, i.e.
|
||||
// supporting Default Attributes
|
||||
return getVolumeGroupIdForAttributesInt(AudioProductStrategy.sDefaultAttributes);
|
||||
}
|
||||
|
||||
private int getVolumeGroupIdForAttributesInt(@NonNull AudioAttributes attributes) {
|
||||
Preconditions.checkNotNull(attributes, "attributes must not be null");
|
||||
for (final AudioProductStrategy productStrategy :
|
||||
AudioManager.getAudioProductStrategies()) {
|
||||
int volumeGroupId = productStrategy.getVolumeGroupIdForAudioAttributes(attributes);
|
||||
if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
|
||||
return volumeGroupId;
|
||||
}
|
||||
}
|
||||
return AudioVolumeGroups.DEFAULT_VOLUME_GROUP;
|
||||
}
|
||||
|
||||
private @NonNull AudioAttributes getAudioAttributesForLegacyStreamType(int streamType) {
|
||||
for (final AudioProductStrategy productStrategy :
|
||||
AudioManager.getAudioProductStrategies()) {
|
||||
AudioAttributes aa = productStrategy.getAudioAttributesForLegacyStreamType(streamType);
|
||||
if (aa != null) {
|
||||
return aa;
|
||||
}
|
||||
}
|
||||
return new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
|
||||
.setUsage(AudioAttributes.USAGE_UNKNOWN).build();
|
||||
}
|
||||
|
||||
private static boolean isNotificationOrRing(int stream) {
|
||||
return stream == AudioManager.STREAM_RING || stream == AudioManager.STREAM_NOTIFICATION;
|
||||
}
|
||||
@@ -329,7 +366,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
|
||||
postStopSample();
|
||||
mContext.getContentResolver().unregisterContentObserver(mVolumeObserver);
|
||||
mReceiver.setListening(false);
|
||||
if (mAudioProductStrategies.size() > 0) {
|
||||
if (AudioManager.getAudioProductStrategies().size() > 0) {
|
||||
unregisterVolumeGroupCb();
|
||||
}
|
||||
mSeekBar.setOnSeekBarChangeListener(null);
|
||||
@@ -349,7 +386,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
|
||||
System.getUriFor(System.VOLUME_SETTINGS_INT[mStreamType]),
|
||||
false, mVolumeObserver);
|
||||
mReceiver.setListening(true);
|
||||
if (mAudioProductStrategies.size() > 0) {
|
||||
if (AudioManager.getAudioProductStrategies().size() > 0) {
|
||||
registerVolumeGroupCb();
|
||||
}
|
||||
}
|
||||
@@ -507,7 +544,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
|
||||
if (AudioManager.VOLUME_CHANGED_ACTION.equals(action)) {
|
||||
int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
|
||||
int streamValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
|
||||
if (mAudioProductStrategies.size() == 0) {
|
||||
if (AudioManager.getAudioProductStrategies().size() == 0) {
|
||||
updateVolumeSlider(streamType, streamValue);
|
||||
}
|
||||
} else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
|
||||
@@ -519,12 +556,11 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
|
||||
}
|
||||
} else if (AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
|
||||
int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
|
||||
if (mAudioProductStrategies.size() == 0) {
|
||||
if (AudioManager.getAudioProductStrategies().size() == 0) {
|
||||
int streamVolume = mAudioManager.getStreamVolume(streamType);
|
||||
updateVolumeSlider(streamType, streamVolume);
|
||||
} else {
|
||||
int volumeGroup = mAudioProductStrategies.getVolumeGroupIdForLegacyStreamType(
|
||||
streamType);
|
||||
int volumeGroup = getVolumeGroupIdForLegacyStreamType(streamType);
|
||||
if (volumeGroup != AudioVolumeGroups.DEFAULT_VOLUME_GROUP
|
||||
&& volumeGroup == mVolumeGroupId) {
|
||||
int streamVolume = mAudioManager.getStreamVolume(streamType);
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
using namespace android;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
static const char* const kClassPathName = "android/media/audiopolicy/AudioProductStrategies";
|
||||
static const char* const kClassPathName = "android/media/audiopolicy/AudioProductStrategy";
|
||||
static const char* const kAudioProductStrategyClassPathName =
|
||||
"android/media/audiopolicy/AudioProductStrategy";
|
||||
|
||||
@@ -194,34 +194,12 @@ exit:
|
||||
return jStatus;
|
||||
}
|
||||
|
||||
static jint
|
||||
android_media_AudioSystem_getProductStrategyFromAudioAttributes(JNIEnv *env, jobject clazz,
|
||||
jobject jAudioAttributes)
|
||||
{
|
||||
JNIAudioAttributeHelper::UniqueAaPtr attributes = JNIAudioAttributeHelper::makeUnique();
|
||||
jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env,
|
||||
jAudioAttributes,
|
||||
attributes.get());
|
||||
if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
|
||||
return jStatus;
|
||||
}
|
||||
product_strategy_t psId;
|
||||
status_t status = AudioSystem::getProductStrategyFromAudioAttributes(
|
||||
AudioAttributes(*attributes.get()), psId);
|
||||
if (status != NO_ERROR) {
|
||||
return nativeToJavaStatus(status);
|
||||
}
|
||||
return psId;
|
||||
}
|
||||
|
||||
/*
|
||||
* JNI registration.
|
||||
*/
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
{"native_list_audio_product_strategies", "(Ljava/util/ArrayList;)I",
|
||||
(void *)android_media_AudioSystem_listAudioProductStrategies},
|
||||
{"native_get_product_strategies_from_audio_attributes", "(Landroid/media/AudioAttributes;)I",
|
||||
(void *)android_media_AudioSystem_getProductStrategyFromAudioAttributes},
|
||||
};
|
||||
|
||||
int register_android_media_AudioProductStrategies(JNIEnv *env)
|
||||
|
||||
@@ -20,7 +20,7 @@ import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.UnsupportedAppUsage;
|
||||
import android.media.audiopolicy.AudioProductStrategies;
|
||||
import android.media.audiopolicy.AudioProductStrategy;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
@@ -783,9 +783,10 @@ public final class AudioAttributes implements Parcelable {
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public Builder setInternalLegacyStreamType(int streamType) {
|
||||
final AudioProductStrategies ps = new AudioProductStrategies();
|
||||
if (ps.size() > 0) {
|
||||
AudioAttributes attributes = ps.getAudioAttributesForLegacyStreamType(streamType);
|
||||
if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
|
||||
AudioAttributes attributes =
|
||||
AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
|
||||
streamType);
|
||||
if (attributes != null) {
|
||||
return new Builder(attributes);
|
||||
}
|
||||
@@ -1165,9 +1166,8 @@ public final class AudioAttributes implements Parcelable {
|
||||
AudioSystem.STREAM_MUSIC : AudioSystem.STREAM_TTS;
|
||||
}
|
||||
|
||||
final AudioProductStrategies ps = new AudioProductStrategies();
|
||||
if (ps.size() > 0) {
|
||||
return ps.getLegacyStreamTypeForAudioAttributes(aa);
|
||||
if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
|
||||
return AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes(aa);
|
||||
}
|
||||
// usage to stream type mapping
|
||||
switch (aa.getUsage()) {
|
||||
|
||||
@@ -37,7 +37,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.audiopolicy.AudioPolicy;
|
||||
import android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener;
|
||||
import android.media.audiopolicy.AudioProductStrategies;
|
||||
import android.media.audiopolicy.AudioProductStrategy;
|
||||
import android.media.audiopolicy.AudioVolumeGroupChangeHandler;
|
||||
import android.media.audiopolicy.AudioVolumeGroups;
|
||||
import android.media.projection.MediaProjection;
|
||||
@@ -5406,8 +5406,9 @@ public class AudioManager {
|
||||
* {@see android.media.audiopolicy.AudioProductStrategy} objects.
|
||||
*/
|
||||
@SystemApi
|
||||
@NonNull
|
||||
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
public @NonNull AudioProductStrategies getAudioProductStrategies() {
|
||||
public static List<AudioProductStrategy> getAudioProductStrategies() {
|
||||
final IAudioService service = getService();
|
||||
try {
|
||||
return service.getAudioProductStrategies();
|
||||
|
||||
@@ -33,7 +33,7 @@ import android.media.IVolumeController;
|
||||
import android.media.PlayerBase;
|
||||
import android.media.VolumePolicy;
|
||||
import android.media.audiopolicy.AudioPolicyConfig;
|
||||
import android.media.audiopolicy.AudioProductStrategies;
|
||||
import android.media.audiopolicy.AudioProductStrategy;
|
||||
import android.media.audiopolicy.AudioVolumeGroups;
|
||||
import android.media.audiopolicy.IAudioPolicyCallback;
|
||||
import android.media.projection.IMediaProjection;
|
||||
@@ -98,7 +98,7 @@ interface IAudioService {
|
||||
|
||||
int getLastAudibleStreamVolume(int streamType);
|
||||
|
||||
AudioProductStrategies getAudioProductStrategies();
|
||||
List<AudioProductStrategy> getAudioProductStrategies();
|
||||
|
||||
void setMicrophoneMute(boolean on, String callingPackage, int userId);
|
||||
|
||||
|
||||
@@ -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 AudioProductStrategies;
|
||||
@@ -1,277 +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.AudioAttributes;
|
||||
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 AudioProductStrategy}.
|
||||
* Provides helper functions to easily retrieve the {@link AudioAttributes} for a given product
|
||||
* strategy or legacy stream type.
|
||||
*/
|
||||
@SystemApi
|
||||
public final class AudioProductStrategies implements Iterable<AudioProductStrategy>, Parcelable {
|
||||
|
||||
private final ArrayList<AudioProductStrategy> mAudioProductStrategyList;
|
||||
|
||||
private static final String TAG = "AudioProductStrategies";
|
||||
|
||||
public AudioProductStrategies() {
|
||||
ArrayList<AudioProductStrategy> apsList = new ArrayList<AudioProductStrategy>();
|
||||
int status = native_list_audio_product_strategies(apsList);
|
||||
if (status != AudioSystem.SUCCESS) {
|
||||
Log.w(TAG, ": createAudioProductStrategies failed");
|
||||
}
|
||||
mAudioProductStrategyList = apsList;
|
||||
}
|
||||
|
||||
private AudioProductStrategies(ArrayList<AudioProductStrategy> audioProductStrategy) {
|
||||
mAudioProductStrategyList = audioProductStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @return number of {@link AudioProductStrategy} objects
|
||||
*/
|
||||
@SystemApi
|
||||
public int size() {
|
||||
return mAudioProductStrategyList.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @return the matching {@link AudioProductStrategy} objects with the given id,
|
||||
* null object if not found.
|
||||
*/
|
||||
@SystemApi
|
||||
public @Nullable AudioProductStrategy getById(int productStrategyId) {
|
||||
for (final AudioProductStrategy avg : this) {
|
||||
if (avg.getId() == productStrategyId) {
|
||||
return avg;
|
||||
}
|
||||
}
|
||||
Log.e(TAG, ": invalid product strategy id: " + productStrategyId + " requested");
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link Iterator}
|
||||
*/
|
||||
@Override
|
||||
public @NonNull Iterator<AudioProductStrategy> iterator() {
|
||||
return mAudioProductStrategyList.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
AudioProductStrategies that = (AudioProductStrategies) o;
|
||||
|
||||
return mAudioProductStrategyList.equals(that.mAudioProductStrategyList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @param aps {@link AudioProductStrategy} (which is the generalisation of Car Audio Usage /
|
||||
* legacy routing_strategy linked to {@link AudioAttributes#getUsage()} )
|
||||
* @return the {@link AudioAttributes} relevant for the given product strategy.
|
||||
* If none is found, it builds the default attributes.
|
||||
* TODO: shall the helper collection be able to identify the platform default?
|
||||
*/
|
||||
@SystemApi
|
||||
@NonNull
|
||||
public AudioAttributes getAudioAttributesForProductStrategy(@NonNull AudioProductStrategy aps) {
|
||||
Preconditions.checkNotNull(aps, "AudioProductStrategy must not be null");
|
||||
for (final AudioProductStrategy audioProductStrategy : this) {
|
||||
if (audioProductStrategy.equals(aps)) {
|
||||
return audioProductStrategy.getAudioAttributes();
|
||||
}
|
||||
}
|
||||
return new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
|
||||
.setUsage(AudioAttributes.USAGE_UNKNOWN).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @param streamType legacy stream type used for volume operation only
|
||||
* @return the {@link AudioAttributes} relevant for the given streamType.
|
||||
* If none is found, it builds the default attributes.
|
||||
*/
|
||||
@SystemApi
|
||||
public @NonNull AudioAttributes getAudioAttributesForLegacyStreamType(int streamType) {
|
||||
for (final AudioProductStrategy productStrategy : this) {
|
||||
AudioAttributes aa = productStrategy.getAudioAttributesForLegacyStreamType(streamType);
|
||||
if (aa != null) {
|
||||
return aa;
|
||||
}
|
||||
}
|
||||
return new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
|
||||
.setUsage(AudioAttributes.USAGE_UNKNOWN).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @param aa the {@link AudioAttributes} for which stream type is requested
|
||||
* @return the legacy stream type relevant for the given {@link AudioAttributes}.
|
||||
* If the product strategy is not associated to any stream, it returns
|
||||
* {@link AudioSystem#STREAM_MUSIC}.
|
||||
* If no product strategy supports the stream type, it returns
|
||||
* {@link AudioSystem#STREAM_MUSIC}.
|
||||
*/
|
||||
@SystemApi
|
||||
public int getLegacyStreamTypeForAudioAttributes(@NonNull AudioAttributes aa) {
|
||||
Preconditions.checkNotNull(aa, "AudioAttributes must not be null");
|
||||
for (final AudioProductStrategy productStrategy : this) {
|
||||
if (productStrategy.supportsAudioAttributes(aa)) {
|
||||
int streamType = productStrategy.getLegacyStreamTypeForAudioAttributes(aa);
|
||||
if (streamType == AudioSystem.STREAM_DEFAULT) {
|
||||
Log.w(TAG, "Attributes " + aa.toString() + " ported by strategy "
|
||||
+ productStrategy.name() + " has no stream type associated, "
|
||||
+ "DO NOT USE STREAM TO CONTROL THE VOLUME");
|
||||
return AudioSystem.STREAM_MUSIC;
|
||||
}
|
||||
return streamType;
|
||||
}
|
||||
}
|
||||
return AudioSystem.STREAM_MUSIC;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @param aa the {@link AudioAttributes} to be considered
|
||||
* @return {@link AudioProductStrategy} supporting the given {@link AudioAttributes}.
|
||||
* null is returned if no match with given attributes.
|
||||
*/
|
||||
@SystemApi
|
||||
@Nullable
|
||||
public AudioProductStrategy getProductStrategyForAudioAttributes(@NonNull AudioAttributes aa) {
|
||||
Preconditions.checkNotNull(aa, "attributes must not be null");
|
||||
int productStrategyId = native_get_product_strategies_from_audio_attributes(aa);
|
||||
if (productStrategyId < 0) {
|
||||
Log.w(TAG, "no strategy found for Attributes " + aa.toString());
|
||||
return null;
|
||||
}
|
||||
return getById(productStrategyId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @param attributes the {@link AudioAttributes} to be considered
|
||||
* @return volume group associated to the given {@link AudioAttributes}.
|
||||
* If no group supports the given {@link AudioAttributes}, it returns the volume group
|
||||
* for the default attributes.
|
||||
* If no group supports the default attributes, it returns {@link #DEFAULT_VOLUME_GROUP}
|
||||
*/
|
||||
@SystemApi
|
||||
public int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
|
||||
Preconditions.checkNotNull(attributes, "attributes must not be null");
|
||||
int volumeGroupId = getVolumeGroupIdForAttributesInt(attributes);
|
||||
if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
|
||||
return volumeGroupId;
|
||||
}
|
||||
// The default volume group is the one hosted by default product strategy, i.e.
|
||||
// supporting Default Attributes
|
||||
return getVolumeGroupIdForAttributesInt(AudioProductStrategy.sDefaultAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @param streamType to be considered
|
||||
* @return volume group associated to the given stream type.
|
||||
*/
|
||||
@SystemApi
|
||||
public int getVolumeGroupIdForLegacyStreamType(int streamType) {
|
||||
for (final AudioProductStrategy productStrategy : this) {
|
||||
int volumeGroupId = productStrategy.getVolumeGroupIdForLegacyStreamType(streamType);
|
||||
if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
|
||||
return volumeGroupId;
|
||||
}
|
||||
}
|
||||
// The default volume group is the one hosted by default product strategy, i.e.
|
||||
// supporting Default Attributes
|
||||
return getVolumeGroupIdForAttributesInt(AudioProductStrategy.sDefaultAttributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeInt(size());
|
||||
for (final AudioProductStrategy productStrategy : this) {
|
||||
productStrategy.writeToParcel(dest, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param attributes to be considered
|
||||
* @return volume group associated to the given {@link AudioAttributes}.
|
||||
*/
|
||||
private int getVolumeGroupIdForAttributesInt(@NonNull AudioAttributes attributes) {
|
||||
Preconditions.checkNotNull(attributes, "attributes must not be null");
|
||||
for (final AudioProductStrategy productStrategy : this) {
|
||||
int volumeGroupId = productStrategy.getVolumeGroupIdForAudioAttributes(attributes);
|
||||
if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
|
||||
return volumeGroupId;
|
||||
}
|
||||
}
|
||||
return AudioVolumeGroups.DEFAULT_VOLUME_GROUP;
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<AudioProductStrategies> CREATOR =
|
||||
new Parcelable.Creator<AudioProductStrategies>() {
|
||||
@Override
|
||||
public AudioProductStrategies createFromParcel(@NonNull Parcel in) {
|
||||
ArrayList<AudioProductStrategy> apsList = new ArrayList<AudioProductStrategy>();
|
||||
int size = in.readInt();
|
||||
for (int index = 0; index < size; index++) {
|
||||
apsList.add(AudioProductStrategy.CREATOR.createFromParcel(in));
|
||||
}
|
||||
return new AudioProductStrategies(apsList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull AudioProductStrategies[] newArray(int size) {
|
||||
return new AudioProductStrategies[size];
|
||||
}
|
||||
};
|
||||
|
||||
private static native int native_list_audio_product_strategies(
|
||||
ArrayList<AudioProductStrategy> strategies);
|
||||
|
||||
private static native int native_get_product_strategies_from_audio_attributes(
|
||||
AudioAttributes attributes);
|
||||
}
|
||||
@@ -25,9 +25,14 @@ import android.media.MediaRecorder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* A class to encapsulate a collection of attributes associated to a given product strategy
|
||||
@@ -41,6 +46,9 @@ public final class AudioProductStrategy implements Parcelable {
|
||||
*/
|
||||
public static final int DEFAULT_GROUP = -1;
|
||||
|
||||
|
||||
private static final String TAG = "AudioProductStrategy";
|
||||
|
||||
private final AudioAttributesGroup[] mAudioAttributesGroups;
|
||||
private final String mName;
|
||||
/**
|
||||
@@ -51,6 +59,86 @@ public final class AudioProductStrategy implements Parcelable {
|
||||
*/
|
||||
private int mId;
|
||||
|
||||
private static final Object sLock = new Object();
|
||||
|
||||
@GuardedBy("sLock")
|
||||
private static List<AudioProductStrategy> sAudioProductStrategies;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @return the list of AudioProductStrategy discovered from platform configuration file.
|
||||
*/
|
||||
@NonNull
|
||||
public static List<AudioProductStrategy> getAudioProductStrategies() {
|
||||
if (sAudioProductStrategies == null) {
|
||||
synchronized (sLock) {
|
||||
if (sAudioProductStrategies == null) {
|
||||
sAudioProductStrategies = initializeAudioProductStrategies();
|
||||
}
|
||||
}
|
||||
}
|
||||
return sAudioProductStrategies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @param streamType to match against AudioProductStrategy
|
||||
* @return the AudioAttributes for the first strategy found with the associated stream type
|
||||
* If no match is found, returns AudioAttributes with unknown content_type and usage
|
||||
*/
|
||||
@NonNull
|
||||
public static AudioAttributes getAudioAttributesForStrategyWithLegacyStreamType(
|
||||
int streamType) {
|
||||
for (final AudioProductStrategy productStrategy :
|
||||
AudioProductStrategy.getAudioProductStrategies()) {
|
||||
AudioAttributes aa = productStrategy.getAudioAttributesForLegacyStreamType(streamType);
|
||||
if (aa != null) {
|
||||
return aa;
|
||||
}
|
||||
}
|
||||
return new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
|
||||
.setUsage(AudioAttributes.USAGE_UNKNOWN).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @param audioAttributes to identify AudioProductStrategy with
|
||||
* @return legacy stream type associated with matched AudioProductStrategy
|
||||
* Defaults to STREAM_MUSIC if no match is found, or if matches is STREAM_DEFAULT
|
||||
*/
|
||||
public static int getLegacyStreamTypeForStrategyWithAudioAttributes(
|
||||
@NonNull AudioAttributes audioAttributes) {
|
||||
Preconditions.checkNotNull(audioAttributes, "AudioAttributes must not be null");
|
||||
for (final AudioProductStrategy productStrategy :
|
||||
AudioProductStrategy.getAudioProductStrategies()) {
|
||||
if (productStrategy.supportsAudioAttributes(audioAttributes)) {
|
||||
int streamType = productStrategy.getLegacyStreamTypeForAudioAttributes(
|
||||
audioAttributes);
|
||||
if (streamType == AudioSystem.STREAM_DEFAULT) {
|
||||
Log.w(TAG, "Attributes " + audioAttributes.toString() + " ported by strategy "
|
||||
+ productStrategy.name() + " has no stream type associated, "
|
||||
+ "DO NOT USE STREAM TO CONTROL THE VOLUME");
|
||||
return AudioSystem.STREAM_MUSIC;
|
||||
}
|
||||
return streamType;
|
||||
}
|
||||
}
|
||||
return AudioSystem.STREAM_MUSIC;
|
||||
}
|
||||
|
||||
private static List<AudioProductStrategy> initializeAudioProductStrategies() {
|
||||
ArrayList<AudioProductStrategy> apsList = new ArrayList<AudioProductStrategy>();
|
||||
int status = native_list_audio_product_strategies(apsList);
|
||||
if (status != AudioSystem.SUCCESS) {
|
||||
Log.w(TAG, ": initializeAudioProductStrategies failed");
|
||||
}
|
||||
return apsList;
|
||||
}
|
||||
|
||||
private static native int native_list_audio_product_strategies(
|
||||
ArrayList<AudioProductStrategy> strategies);
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -200,7 +288,8 @@ public final class AudioProductStrategy implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<AudioProductStrategy> CREATOR =
|
||||
@NonNull
|
||||
public static final Parcelable.Creator<AudioProductStrategy> CREATOR =
|
||||
new Parcelable.Creator<AudioProductStrategy>() {
|
||||
@Override
|
||||
public AudioProductStrategy createFromParcel(@NonNull Parcel in) {
|
||||
|
||||
@@ -49,7 +49,7 @@ public final class AudioVolumeGroup implements Parcelable {
|
||||
/**
|
||||
* @param name of the volume group
|
||||
* @param id of the volume group
|
||||
* @param followers {@link AudioProductStrategies} strategy following this volume group
|
||||
* @param legacyStreamTypes of volume group
|
||||
*/
|
||||
AudioVolumeGroup(@NonNull String name, int id,
|
||||
@NonNull AudioAttributes[] audioAttributes,
|
||||
|
||||
@@ -90,7 +90,7 @@ import android.media.audiofx.AudioEffect;
|
||||
import android.media.audiopolicy.AudioMix;
|
||||
import android.media.audiopolicy.AudioPolicy;
|
||||
import android.media.audiopolicy.AudioPolicyConfig;
|
||||
import android.media.audiopolicy.AudioProductStrategies;
|
||||
import android.media.audiopolicy.AudioProductStrategy;
|
||||
import android.media.audiopolicy.AudioVolumeGroup;
|
||||
import android.media.audiopolicy.AudioVolumeGroups;
|
||||
import android.media.audiopolicy.IAudioPolicyCallback;
|
||||
@@ -281,8 +281,6 @@ public class AudioService extends IAudioService.Stub
|
||||
|
||||
private SettingsObserver mSettingsObserver;
|
||||
|
||||
/** @see AudioProductStrategies */
|
||||
private static AudioProductStrategies sAudioProductStrategies;
|
||||
/** @see AudioVolumeGroups */
|
||||
private static AudioVolumeGroups sAudioVolumeGroups;
|
||||
|
||||
@@ -636,19 +634,19 @@ public class AudioService extends IAudioService.Stub
|
||||
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
|
||||
|
||||
sAudioProductStrategies = new AudioProductStrategies();
|
||||
sAudioVolumeGroups = new AudioVolumeGroups();
|
||||
|
||||
// Initialize volume
|
||||
// Priority 1 - Android Property
|
||||
// Priority 2 - Audio Policy Service
|
||||
// Priority 3 - Default Value
|
||||
if (sAudioProductStrategies.size() > 0) {
|
||||
if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
|
||||
int numStreamTypes = AudioSystem.getNumStreamTypes();
|
||||
|
||||
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
|
||||
AudioAttributes attr =
|
||||
sAudioProductStrategies.getAudioAttributesForLegacyStreamType(streamType);
|
||||
AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
|
||||
streamType);
|
||||
int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr);
|
||||
if (maxVolume != -1) {
|
||||
MAX_STREAM_VOLUME[streamType] = maxVolume;
|
||||
@@ -1023,11 +1021,12 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link android.media.audiopolicy.AudioProductStrategies} discovered from the
|
||||
* @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the
|
||||
* platform configuration file.
|
||||
*/
|
||||
public @NonNull AudioProductStrategies getAudioProductStrategies() {
|
||||
return sAudioProductStrategies;
|
||||
@NonNull
|
||||
public List<AudioProductStrategy> getAudioProductStrategies() {
|
||||
return AudioProductStrategy.getAudioProductStrategies();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1947,14 +1946,14 @@ public class AudioService extends IAudioService.Stub
|
||||
enforceModifyAudioRoutingPermission();
|
||||
Preconditions.checkNotNull(attr, "attr must not be null");
|
||||
// @todo not hold the caller context, post message
|
||||
int stream = sAudioProductStrategies.getLegacyStreamTypeForAudioAttributes(attr);
|
||||
int stream = AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes(attr);
|
||||
final int device = getDeviceForStream(stream);
|
||||
|
||||
int oldIndex = AudioSystem.getVolumeIndexForAttributes(attr, device);
|
||||
|
||||
AudioSystem.setVolumeIndexForAttributes(attr, index, device);
|
||||
|
||||
final int volumeGroup = sAudioProductStrategies.getVolumeGroupIdForAttributes(attr);
|
||||
final int volumeGroup = getVolumeGroupIdForAttributes(attr);
|
||||
final AudioVolumeGroup avg = sAudioVolumeGroups.getById(volumeGroup);
|
||||
if (avg == null) {
|
||||
return;
|
||||
@@ -1969,7 +1968,7 @@ public class AudioService extends IAudioService.Stub
|
||||
public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
|
||||
enforceModifyAudioRoutingPermission();
|
||||
Preconditions.checkNotNull(attr, "attr must not be null");
|
||||
int stream = sAudioProductStrategies.getLegacyStreamTypeForAudioAttributes(attr);
|
||||
int stream = AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes(attr);
|
||||
final int device = getDeviceForStream(stream);
|
||||
|
||||
return AudioSystem.getVolumeIndexForAttributes(attr, device);
|
||||
@@ -2144,6 +2143,32 @@ public class AudioService extends IAudioService.Stub
|
||||
sendVolumeUpdate(streamType, oldIndex, index, flags);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
|
||||
Preconditions.checkNotNull(attributes, "attributes must not be null");
|
||||
int volumeGroupId = getVolumeGroupIdForAttributesInt(attributes);
|
||||
if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
|
||||
return volumeGroupId;
|
||||
}
|
||||
// The default volume group is the one hosted by default product strategy, i.e.
|
||||
// supporting Default Attributes
|
||||
return getVolumeGroupIdForAttributesInt(AudioProductStrategy.sDefaultAttributes);
|
||||
}
|
||||
|
||||
private int getVolumeGroupIdForAttributesInt(@NonNull AudioAttributes attributes) {
|
||||
Preconditions.checkNotNull(attributes, "attributes must not be null");
|
||||
for (final AudioProductStrategy productStrategy :
|
||||
AudioProductStrategy.getAudioProductStrategies()) {
|
||||
int volumeGroupId = productStrategy.getVolumeGroupIdForAudioAttributes(attributes);
|
||||
if (volumeGroupId != AudioVolumeGroups.DEFAULT_VOLUME_GROUP) {
|
||||
return volumeGroupId;
|
||||
}
|
||||
}
|
||||
return AudioVolumeGroups.DEFAULT_VOLUME_GROUP;
|
||||
}
|
||||
|
||||
|
||||
// No ringer or zen muted stream volumes can be changed unless it'll exit dnd
|
||||
private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
|
||||
switch (mNm.getZenMode()) {
|
||||
|
||||
Reference in New Issue
Block a user