Add Volume Groups API to AudioManager

-put in cache collection in AudioService
-add helper function in Strategies and volume groups

Bug: 124767636
Test: dumpsys media.audio_policy
Change-Id: I688abf79ce7dead927fbd021e48bf6460d6cdc85
Signed-off-by: François Gaffie <francois.gaffie@renault.com>
This commit is contained in:
François Gaffie
2018-09-21 17:43:52 +02:00
committed by Hongwei Wang
parent adcd00a7c8
commit 9c36210d29
4 changed files with 178 additions and 1 deletions

View File

@@ -3457,6 +3457,9 @@ package android.media {
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 android.media.audiopolicy.AudioVolumeGroups getAudioVolumeGroups();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method public boolean isAudioServerRunning();
method public boolean isHdmiSystemAudioSupported();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
@@ -3466,6 +3469,7 @@ package android.media {
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int requestAudioFocus(@NonNull android.media.AudioFocusRequest, @Nullable android.media.audiopolicy.AudioPolicy);
method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setVolumeIndexForAttributes(@NonNull android.media.AudioAttributes, int, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicyAsync(@NonNull android.media.audiopolicy.AudioPolicy);
method public void unregisterVolumeGroupCallback(@NonNull android.media.AudioManager.VolumeGroupCallback);
field public static final int AUDIOFOCUS_FLAG_DELAY_OK = 1; // 0x1

View File

@@ -1168,6 +1168,93 @@ public class AudioManager {
}
}
/**
* Sets the volume index for a particular {@link AudioAttributes}.
* @param attr The {@link AudioAttributes} whose volume index should be set.
* @param index The volume index to set. See
* {@link #getMaxVolumeIndexForAttributes(AudioAttributes)} for the largest valid value
* {@link #getMinVolumeIndexForAttributes(AudioAttributes)} for the lowest valid value.
* @param flags One or more flags.
* @see #getMaxVolumeIndexForAttributes(AudioAttributes)
* @see #getMinVolumeIndexForAttributes(AudioAttributes)
* @see #isVolumeFixed()
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags) {
Preconditions.checkNotNull(attr, "attr must not be null");
final IAudioService service = getService();
try {
service.setVolumeIndexForAttributes(attr, index, flags,
getContext().getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the current volume index for a particular {@link AudioAttributes}.
*
* @param attr The {@link AudioAttributes} whose volume index is returned.
* @return The current volume index for the stream.
* @see #getMaxVolumeIndexForAttributes(AudioAttributes)
* @see #getMinVolumeIndexForAttributes(AudioAttributes)
* @see #setVolumeForAttributes(AudioAttributes, int, int)
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
Preconditions.checkNotNull(attr, "attr must not be null");
final IAudioService service = getService();
try {
return service.getVolumeIndexForAttributes(attr);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the maximum volume index for a particular {@link AudioAttributes}.
*
* @param attr The {@link AudioAttributes} whose maximum volume index is returned.
* @return The maximum valid volume index for the {@link AudioAttributes}.
* @see #getVolumeIndexForAttributes(AudioAttributes)
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
Preconditions.checkNotNull(attr, "attr must not be null");
final IAudioService service = getService();
try {
return service.getMaxVolumeIndexForAttributes(attr);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Returns the minimum volume index for a particular {@link AudioAttributes}.
*
* @param attr The {@link AudioAttributes} whose minimum volume index is returned.
* @return The minimum valid volume index for the {@link AudioAttributes}.
* @see #getVolumeIndexForAttributes(AudioAttributes)
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
Preconditions.checkNotNull(attr, "attr must not be null");
final IAudioService service = getService();
try {
return service.getMinVolumeIndexForAttributes(attr);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Solo or unsolo a particular stream.
* <p>
@@ -5262,7 +5349,12 @@ public class AudioManager {
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public @NonNull AudioVolumeGroups getAudioVolumeGroups() {
return new AudioVolumeGroups();
final IAudioService service = getService();
try {
return service.listAudioVolumeGroups();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**

View File

@@ -34,6 +34,7 @@ import android.media.PlayerBase;
import android.media.VolumePolicy;
import android.media.audiopolicy.AudioPolicyConfig;
import android.media.audiopolicy.AudioProductStrategies;
import android.media.audiopolicy.AudioVolumeGroups;
import android.media.audiopolicy.IAudioPolicyCallback;
import android.media.projection.IMediaProjection;
@@ -81,6 +82,16 @@ interface IAudioService {
int getStreamMaxVolume(int streamType);
AudioVolumeGroups listAudioVolumeGroups();
void setVolumeIndexForAttributes(in AudioAttributes aa, int index, int flags, String callingPackage);
int getVolumeIndexForAttributes(in AudioAttributes aa);
int getMaxVolumeIndexForAttributes(in AudioAttributes aa);
int getMinVolumeIndexForAttributes(in AudioAttributes aa);
int getLastAudibleStreamVolume(int streamType);
AudioProductStrategies getAudioProductStrategies();

View File

@@ -89,6 +89,8 @@ import android.media.audiopolicy.AudioMix;
import android.media.audiopolicy.AudioPolicy;
import android.media.audiopolicy.AudioPolicyConfig;
import android.media.audiopolicy.AudioProductStrategies;
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;
@@ -128,6 +130,7 @@ import android.widget.Toast;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
@@ -277,6 +280,8 @@ public class AudioService extends IAudioService.Stub
/** @see AudioProductStrategies */
private static AudioProductStrategies sAudioProductStrategies;
/** @see AudioVolumeGroups */
private static AudioVolumeGroups sAudioVolumeGroups;
private int mMode = AudioSystem.MODE_NORMAL;
// protects mRingerMode
@@ -629,6 +634,7 @@ public class AudioService extends IAudioService.Stub
mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
sAudioProductStrategies = new AudioProductStrategies();
sAudioVolumeGroups = new AudioVolumeGroups();
// Initialize volume
int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
@@ -1002,6 +1008,14 @@ public class AudioService extends IAudioService.Stub
return sAudioProductStrategies;
}
/**
* @return the {@link android.media.audiopolicy.AudioVolumeGroups} discovered from the
* platform configuration file.
*/
public @NonNull AudioVolumeGroups listAudioVolumeGroups() {
return sAudioVolumeGroups;
}
private void checkAllAliasStreamVolumes() {
synchronized (mSettingsLock) {
synchronized (VolumeStreamState.class) {
@@ -1892,6 +1906,62 @@ public class AudioService extends IAudioService.Stub
mStreamStates[stream].mute(index == 0);
}
private void enforceModifyAudioRoutingPermission() {
if (mContext.checkCallingPermission(
android.Manifest.permission.MODIFY_AUDIO_ROUTING)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
}
}
/** @see AudioManager#setVolumeIndexForAttributes(attr, int, int) */
public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags,
String callingPackage) {
enforceModifyAudioRoutingPermission();
Preconditions.checkNotNull(attr, "attr must not be null");
// @todo not hold the caller context, post message
int stream = sAudioProductStrategies.getLegacyStreamTypeForAudioAttributes(attr);
final int device = getDeviceForStream(stream);
int oldIndex = AudioSystem.getVolumeIndexForAttributes(attr, device);
AudioSystem.setVolumeIndexForAttributes(attr, index, device);
final int volumeGroup = sAudioProductStrategies.getVolumeGroupIdForAttributes(attr);
final AudioVolumeGroup avg = sAudioVolumeGroups.getById(volumeGroup);
if (avg == null) {
return;
}
for (final int groupedStream : avg.getLegacyStreamTypes()) {
setStreamVolume(stream, index, flags, callingPackage, callingPackage,
Binder.getCallingUid());
}
}
/** @see AudioManager#getVolumeIndexForAttributes(attr) */
public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
enforceModifyAudioRoutingPermission();
Preconditions.checkNotNull(attr, "attr must not be null");
int stream = sAudioProductStrategies.getLegacyStreamTypeForAudioAttributes(attr);
final int device = getDeviceForStream(stream);
return AudioSystem.getVolumeIndexForAttributes(attr, device);
}
/** @see AudioManager#getMaxVolumeIndexForAttributes(attr) */
public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
enforceModifyAudioRoutingPermission();
Preconditions.checkNotNull(attr, "attr must not be null");
return AudioSystem.getMaxVolumeIndexForAttributes(attr);
}
/** @see AudioManager#getMinVolumeIndexForAttributes(attr) */
public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
enforceModifyAudioRoutingPermission();
Preconditions.checkNotNull(attr, "attr must not be null");
return AudioSystem.getMinVolumeIndexForAttributes(attr);
}
/** @see AudioManager#setStreamVolume(int, int, int) */
public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {