Merge "audioservice: fix persistency for volume per attributes" am: 2b6df36401
Change-Id: I98274b101226c1f322f96d0eac3f701eafc5f056
This commit is contained in:
@@ -124,6 +124,7 @@ import android.util.Log;
|
|||||||
import android.util.MathUtils;
|
import android.util.MathUtils;
|
||||||
import android.util.PrintWriterPrinter;
|
import android.util.PrintWriterPrinter;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
import android.util.SparseArray;
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.accessibility.AccessibilityManager;
|
import android.view.accessibility.AccessibilityManager;
|
||||||
@@ -243,6 +244,7 @@ public class AudioService extends IAudioService.Stub
|
|||||||
// AudioHandler messages
|
// AudioHandler messages
|
||||||
private static final int MSG_SET_DEVICE_VOLUME = 0;
|
private static final int MSG_SET_DEVICE_VOLUME = 0;
|
||||||
private static final int MSG_PERSIST_VOLUME = 1;
|
private static final int MSG_PERSIST_VOLUME = 1;
|
||||||
|
private static final int MSG_PERSIST_VOLUME_GROUP = 2;
|
||||||
private static final int MSG_PERSIST_RINGER_MODE = 3;
|
private static final int MSG_PERSIST_RINGER_MODE = 3;
|
||||||
private static final int MSG_AUDIO_SERVER_DIED = 4;
|
private static final int MSG_AUDIO_SERVER_DIED = 4;
|
||||||
private static final int MSG_PLAY_SOUND_EFFECT = 5;
|
private static final int MSG_PLAY_SOUND_EFFECT = 5;
|
||||||
@@ -761,6 +763,10 @@ public class AudioService extends IAudioService.Stub
|
|||||||
mSettingsObserver = new SettingsObserver();
|
mSettingsObserver = new SettingsObserver();
|
||||||
createStreamStates();
|
createStreamStates();
|
||||||
|
|
||||||
|
// must be called after createStreamStates() as it uses MUSIC volume as default if no
|
||||||
|
// persistent data
|
||||||
|
initVolumeGroupStates();
|
||||||
|
|
||||||
// mSafeUsbMediaVolumeIndex must be initialized after createStreamStates() because it
|
// mSafeUsbMediaVolumeIndex must be initialized after createStreamStates() because it
|
||||||
// relies on audio policy having correct ranges for volume indexes.
|
// relies on audio policy having correct ranges for volume indexes.
|
||||||
mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
|
mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
|
||||||
@@ -995,6 +1001,9 @@ public class AudioService extends IAudioService.Stub
|
|||||||
streamState.applyAllVolumes();
|
streamState.applyAllVolumes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore audio volume groups
|
||||||
|
restoreVolumeGroups();
|
||||||
|
|
||||||
// Restore mono mode
|
// Restore mono mode
|
||||||
updateMasterMono(mContentResolver);
|
updateMasterMono(mContentResolver);
|
||||||
|
|
||||||
@@ -2112,20 +2121,20 @@ public class AudioService extends IAudioService.Stub
|
|||||||
String callingPackage) {
|
String callingPackage) {
|
||||||
enforceModifyAudioRoutingPermission();
|
enforceModifyAudioRoutingPermission();
|
||||||
Preconditions.checkNotNull(attr, "attr must not be null");
|
Preconditions.checkNotNull(attr, "attr must not be null");
|
||||||
// @todo not hold the caller context, post message
|
|
||||||
int stream = AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes(attr);
|
|
||||||
final int device = getDeviceForStream(stream);
|
|
||||||
|
|
||||||
int oldIndex = AudioSystem.getVolumeIndexForAttributes(attr, device);
|
|
||||||
|
|
||||||
AudioSystem.setVolumeIndexForAttributes(attr, index, device);
|
|
||||||
|
|
||||||
final int volumeGroup = getVolumeGroupIdForAttributes(attr);
|
final int volumeGroup = getVolumeGroupIdForAttributes(attr);
|
||||||
final AudioVolumeGroup avg = getAudioVolumeGroupById(volumeGroup);
|
if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
|
||||||
if (avg == null) {
|
Log.e(TAG, ": no volume group found for attributes " + attr.toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (final int groupedStream : avg.getLegacyStreamTypes()) {
|
final VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
|
||||||
|
|
||||||
|
sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, attr, vgs.name(),
|
||||||
|
index/*val1*/, flags/*val2*/, callingPackage));
|
||||||
|
|
||||||
|
vgs.setVolumeIndex(index, flags);
|
||||||
|
|
||||||
|
// For legacy reason, propagate to all streams associated to this volume group
|
||||||
|
for (final int groupedStream : vgs.getLegacyStreamTypes()) {
|
||||||
setStreamVolume(groupedStream, index, flags, callingPackage, callingPackage,
|
setStreamVolume(groupedStream, index, flags, callingPackage, callingPackage,
|
||||||
Binder.getCallingUid());
|
Binder.getCallingUid());
|
||||||
}
|
}
|
||||||
@@ -2147,10 +2156,12 @@ public class AudioService extends IAudioService.Stub
|
|||||||
public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
|
public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
|
||||||
enforceModifyAudioRoutingPermission();
|
enforceModifyAudioRoutingPermission();
|
||||||
Preconditions.checkNotNull(attr, "attr must not be null");
|
Preconditions.checkNotNull(attr, "attr must not be null");
|
||||||
int stream = AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes(attr);
|
final int volumeGroup = getVolumeGroupIdForAttributes(attr);
|
||||||
final int device = getDeviceForStream(stream);
|
if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
|
||||||
|
throw new IllegalArgumentException("No volume group for attributes " + attr);
|
||||||
return AudioSystem.getVolumeIndexForAttributes(attr, device);
|
}
|
||||||
|
final VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
|
||||||
|
return vgs.getVolumeIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @see AudioManager#getMaxVolumeIndexForAttributes(attr) */
|
/** @see AudioManager#getMaxVolumeIndexForAttributes(attr) */
|
||||||
@@ -3550,6 +3561,8 @@ public class AudioService extends IAudioService.Stub
|
|||||||
enforceSafeMediaVolume(TAG);
|
enforceSafeMediaVolume(TAG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readVolumeGroupsSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @see AudioManager#setSpeakerphoneOn(boolean) */
|
/** @see AudioManager#setSpeakerphoneOn(boolean) */
|
||||||
@@ -4438,6 +4451,310 @@ public class AudioService extends IAudioService.Stub
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Inner classes
|
// Inner classes
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* Key is the AudioManager VolumeGroupId
|
||||||
|
* Value is the VolumeGroupState
|
||||||
|
*/
|
||||||
|
private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>();
|
||||||
|
|
||||||
|
private void initVolumeGroupStates() {
|
||||||
|
for (final AudioVolumeGroup avg : getAudioVolumeGroups()) {
|
||||||
|
try {
|
||||||
|
// if no valid attributes, this volume group is not controllable, throw exception
|
||||||
|
ensureValidAttributes(avg);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// Volume Groups without attributes are not controllable through set/get volume
|
||||||
|
// using attributes. Do not append them.
|
||||||
|
Log.d(TAG, "volume group " + avg.name() + " for internal policy needs");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sVolumeGroupStates.append(avg.getId(), new VolumeGroupState(avg));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < sVolumeGroupStates.size(); i++) {
|
||||||
|
final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
|
||||||
|
vgs.applyAllVolumes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureValidAttributes(AudioVolumeGroup avg) {
|
||||||
|
boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream()
|
||||||
|
.anyMatch(aa -> !aa.equals(AudioProductStrategy.sDefaultAttributes));
|
||||||
|
if (!hasAtLeastOneValidAudioAttributes) {
|
||||||
|
throw new IllegalArgumentException("Volume Group " + avg.name()
|
||||||
|
+ " has no valid audio attributes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readVolumeGroupsSettings() {
|
||||||
|
Log.v(TAG, "readVolumeGroupsSettings");
|
||||||
|
for (int i = 0; i < sVolumeGroupStates.size(); i++) {
|
||||||
|
final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
|
||||||
|
vgs.readSettings();
|
||||||
|
vgs.applyAllVolumes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called upon crash of AudioServer
|
||||||
|
private void restoreVolumeGroups() {
|
||||||
|
Log.v(TAG, "restoreVolumeGroups");
|
||||||
|
for (int i = 0; i < sVolumeGroupStates.size(); i++) {
|
||||||
|
final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
|
||||||
|
vgs.applyAllVolumes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dumpVolumeGroups(PrintWriter pw) {
|
||||||
|
pw.println("\nVolume Groups (device: index)");
|
||||||
|
for (int i = 0; i < sVolumeGroupStates.size(); i++) {
|
||||||
|
final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
|
||||||
|
vgs.dump(pw);
|
||||||
|
pw.println("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Locking order for synchronized objects related to volume management:
|
||||||
|
// 1 mSettingsLock
|
||||||
|
// 2 VolumeGroupState.class
|
||||||
|
private class VolumeGroupState {
|
||||||
|
private final AudioVolumeGroup mAudioVolumeGroup;
|
||||||
|
private final SparseIntArray mIndexMap = new SparseIntArray(8);
|
||||||
|
private int mIndexMin;
|
||||||
|
private int mIndexMax;
|
||||||
|
private int mLegacyStreamType = AudioSystem.STREAM_DEFAULT;
|
||||||
|
private int mPublicStreamType = AudioSystem.STREAM_MUSIC;
|
||||||
|
private AudioAttributes mAudioAttributes = AudioProductStrategy.sDefaultAttributes;
|
||||||
|
|
||||||
|
// No API in AudioSystem to get a device from strategy or from attributes.
|
||||||
|
// Need a valid public stream type to use current API getDeviceForStream
|
||||||
|
private int getDeviceForVolume() {
|
||||||
|
return getDeviceForStream(mPublicStreamType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private VolumeGroupState(AudioVolumeGroup avg) {
|
||||||
|
mAudioVolumeGroup = avg;
|
||||||
|
Log.v(TAG, "VolumeGroupState for " + avg.toString());
|
||||||
|
for (final AudioAttributes aa : avg.getAudioAttributes()) {
|
||||||
|
if (!aa.equals(AudioProductStrategy.sDefaultAttributes)) {
|
||||||
|
mAudioAttributes = aa;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes();
|
||||||
|
if (streamTypes.length != 0) {
|
||||||
|
// Uses already initialized MIN / MAX if a stream type is attached to group
|
||||||
|
mLegacyStreamType = streamTypes[0];
|
||||||
|
for (final int streamType : streamTypes) {
|
||||||
|
if (streamType != AudioSystem.STREAM_DEFAULT
|
||||||
|
&& streamType < AudioSystem.getNumStreamTypes()) {
|
||||||
|
mPublicStreamType = streamType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType];
|
||||||
|
mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType];
|
||||||
|
} else if (!avg.getAudioAttributes().isEmpty()) {
|
||||||
|
mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes);
|
||||||
|
mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "volume group: " + mAudioVolumeGroup.name()
|
||||||
|
+ " has neither valid attributes nor valid stream types assigned");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Load volume indexes from data base
|
||||||
|
readSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull int[] getLegacyStreamTypes() {
|
||||||
|
return mAudioVolumeGroup.getLegacyStreamTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String name() {
|
||||||
|
return mAudioVolumeGroup.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVolumeIndex() {
|
||||||
|
return getIndex(getDeviceForVolume());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVolumeIndex(int index, int flags) {
|
||||||
|
if (mUseFixedVolume) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setVolumeIndex(index, getDeviceForVolume(), flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setVolumeIndex(int index, int device, int flags) {
|
||||||
|
// Set the volume index
|
||||||
|
setVolumeIndexInt(index, device, flags);
|
||||||
|
|
||||||
|
// Update local cache
|
||||||
|
mIndexMap.put(device, index);
|
||||||
|
|
||||||
|
// update data base - post a persist volume group msg
|
||||||
|
sendMsg(mAudioHandler,
|
||||||
|
MSG_PERSIST_VOLUME_GROUP,
|
||||||
|
SENDMSG_QUEUE,
|
||||||
|
device,
|
||||||
|
0,
|
||||||
|
this,
|
||||||
|
PERSIST_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setVolumeIndexInt(int index, int device, int flags) {
|
||||||
|
// Set the volume index
|
||||||
|
AudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex(int device) {
|
||||||
|
synchronized (VolumeGroupState.class) {
|
||||||
|
int index = mIndexMap.get(device, -1);
|
||||||
|
// there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
|
||||||
|
return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasIndexForDevice(int device) {
|
||||||
|
synchronized (VolumeGroupState.class) {
|
||||||
|
return (mIndexMap.get(device, -1) != -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxIndex() {
|
||||||
|
return mIndexMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinIndex() {
|
||||||
|
return mIndexMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applyAllVolumes() {
|
||||||
|
synchronized (VolumeGroupState.class) {
|
||||||
|
if (mLegacyStreamType != AudioSystem.STREAM_DEFAULT) {
|
||||||
|
// No-op to avoid regression with stream based volume management
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// apply device specific volumes first
|
||||||
|
int index;
|
||||||
|
for (int i = 0; i < mIndexMap.size(); i++) {
|
||||||
|
final int device = mIndexMap.keyAt(i);
|
||||||
|
if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
|
||||||
|
index = mIndexMap.valueAt(i);
|
||||||
|
Log.v(TAG, "applyAllVolumes: restore index " + index + " for group "
|
||||||
|
+ mAudioVolumeGroup.name() + " and device "
|
||||||
|
+ AudioSystem.getOutputDeviceName(device));
|
||||||
|
setVolumeIndexInt(index, device, 0 /*flags*/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// apply default volume last: by convention , default device volume will be used
|
||||||
|
index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
|
||||||
|
Log.v(TAG, "applyAllVolumes: restore default device index " + index + " for group "
|
||||||
|
+ mAudioVolumeGroup.name());
|
||||||
|
setVolumeIndexInt(index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void persistVolumeGroup(int device) {
|
||||||
|
if (mUseFixedVolume) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group "
|
||||||
|
+ mAudioVolumeGroup.name() + " and device "
|
||||||
|
+ AudioSystem.getOutputDeviceName(device));
|
||||||
|
boolean success = Settings.System.putIntForUser(mContentResolver,
|
||||||
|
getSettingNameForDevice(device),
|
||||||
|
getIndex(device),
|
||||||
|
UserHandle.USER_CURRENT);
|
||||||
|
if (!success) {
|
||||||
|
Log.e(TAG, "persistVolumeGroup failed for group " + mAudioVolumeGroup.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readSettings() {
|
||||||
|
synchronized (VolumeGroupState.class) {
|
||||||
|
// First clear previously loaded (previous user?) settings
|
||||||
|
mIndexMap.clear();
|
||||||
|
// force maximum volume on all streams if fixed volume property is set
|
||||||
|
if (mUseFixedVolume) {
|
||||||
|
mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
|
||||||
|
// retrieve current volume for device
|
||||||
|
// if no volume stored for current volume group and device, use default volume
|
||||||
|
// if default device, continue otherwise
|
||||||
|
int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT)
|
||||||
|
? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1;
|
||||||
|
int index;
|
||||||
|
String name = getSettingNameForDevice(device);
|
||||||
|
index = Settings.System.getIntForUser(
|
||||||
|
mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
|
||||||
|
if (index == -1) {
|
||||||
|
Log.e(TAG, "readSettings: No index stored for group "
|
||||||
|
+ mAudioVolumeGroup.name() + ", device " + name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Log.v(TAG, "readSettings: found stored index " + getValidIndex(index)
|
||||||
|
+ " for group " + mAudioVolumeGroup.name() + ", device: " + name);
|
||||||
|
mIndexMap.put(device, getValidIndex(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getValidIndex(int index) {
|
||||||
|
if (index < mIndexMin) {
|
||||||
|
return mIndexMin;
|
||||||
|
} else if (mUseFixedVolume || index > mIndexMax) {
|
||||||
|
return mIndexMax;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull String getSettingNameForDevice(int device) {
|
||||||
|
final String suffix = AudioSystem.getOutputDeviceName(device);
|
||||||
|
if (suffix.isEmpty()) {
|
||||||
|
return mAudioVolumeGroup.name();
|
||||||
|
}
|
||||||
|
return mAudioVolumeGroup.name() + "_" + AudioSystem.getOutputDeviceName(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dump(PrintWriter pw) {
|
||||||
|
pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":");
|
||||||
|
pw.print(" Min: ");
|
||||||
|
pw.println(mIndexMin);
|
||||||
|
pw.print(" Max: ");
|
||||||
|
pw.println(mIndexMax);
|
||||||
|
pw.print(" Current: ");
|
||||||
|
for (int i = 0; i < mIndexMap.size(); i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
pw.print(", ");
|
||||||
|
}
|
||||||
|
final int device = mIndexMap.keyAt(i);
|
||||||
|
pw.print(Integer.toHexString(device));
|
||||||
|
final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
|
||||||
|
: AudioSystem.getOutputDeviceName(device);
|
||||||
|
if (!deviceName.isEmpty()) {
|
||||||
|
pw.print(" (");
|
||||||
|
pw.print(deviceName);
|
||||||
|
pw.print(")");
|
||||||
|
}
|
||||||
|
pw.print(": ");
|
||||||
|
pw.print(mIndexMap.valueAt(i));
|
||||||
|
}
|
||||||
|
pw.println();
|
||||||
|
pw.print(" Devices: ");
|
||||||
|
int n = 0;
|
||||||
|
final int devices = getDeviceForVolume();
|
||||||
|
for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
|
||||||
|
if ((devices & device) == device) {
|
||||||
|
if (n++ > 0) {
|
||||||
|
pw.print(", ");
|
||||||
|
}
|
||||||
|
pw.print(AudioSystem.getOutputDeviceName(device));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// NOTE: Locking order for synchronized objects related to volume or ringer mode management:
|
// NOTE: Locking order for synchronized objects related to volume or ringer mode management:
|
||||||
// 1 mScoclient OR mSafeMediaVolumeState
|
// 1 mScoclient OR mSafeMediaVolumeState
|
||||||
@@ -5082,6 +5399,11 @@ public class AudioService extends IAudioService.Stub
|
|||||||
persistVolume((VolumeStreamState) msg.obj, msg.arg1);
|
persistVolume((VolumeStreamState) msg.obj, msg.arg1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSG_PERSIST_VOLUME_GROUP:
|
||||||
|
final VolumeGroupState vgs = (VolumeGroupState) msg.obj;
|
||||||
|
vgs.persistVolumeGroup(msg.arg1);
|
||||||
|
break;
|
||||||
|
|
||||||
case MSG_PERSIST_RINGER_MODE:
|
case MSG_PERSIST_RINGER_MODE:
|
||||||
// note that the value persisted is the current ringer mode, not the
|
// note that the value persisted is the current ringer mode, not the
|
||||||
// value of ringer mode as of the time the request was made to persist
|
// value of ringer mode as of the time the request was made to persist
|
||||||
@@ -6129,6 +6451,7 @@ public class AudioService extends IAudioService.Stub
|
|||||||
}
|
}
|
||||||
mMediaFocusControl.dump(pw);
|
mMediaFocusControl.dump(pw);
|
||||||
dumpStreamStates(pw);
|
dumpStreamStates(pw);
|
||||||
|
dumpVolumeGroups(pw);
|
||||||
dumpRingerMode(pw);
|
dumpRingerMode(pw);
|
||||||
pw.println("\nAudio routes:");
|
pw.println("\nAudio routes:");
|
||||||
pw.print(" mMainType=0x"); pw.println(Integer.toHexString(
|
pw.print(" mMainType=0x"); pw.println(Integer.toHexString(
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.server.audio;
|
package com.android.server.audio;
|
||||||
|
|
||||||
|
import android.media.AudioAttributes;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.AudioSystem;
|
import android.media.AudioSystem;
|
||||||
|
|
||||||
@@ -97,12 +98,15 @@ public class AudioServiceEvents {
|
|||||||
static final int VOL_ADJUST_VOL_UID = 5;
|
static final int VOL_ADJUST_VOL_UID = 5;
|
||||||
static final int VOL_VOICE_ACTIVITY_HEARING_AID = 6;
|
static final int VOL_VOICE_ACTIVITY_HEARING_AID = 6;
|
||||||
static final int VOL_MODE_CHANGE_HEARING_AID = 7;
|
static final int VOL_MODE_CHANGE_HEARING_AID = 7;
|
||||||
|
static final int VOL_SET_GROUP_VOL = 8;
|
||||||
|
|
||||||
final int mOp;
|
final int mOp;
|
||||||
final int mStream;
|
final int mStream;
|
||||||
final int mVal1;
|
final int mVal1;
|
||||||
final int mVal2;
|
final int mVal2;
|
||||||
final String mCaller;
|
final String mCaller;
|
||||||
|
final String mGroupName;
|
||||||
|
final AudioAttributes mAudioAttributes;
|
||||||
|
|
||||||
/** used for VOL_ADJUST_VOL_UID,
|
/** used for VOL_ADJUST_VOL_UID,
|
||||||
* VOL_ADJUST_SUGG_VOL,
|
* VOL_ADJUST_SUGG_VOL,
|
||||||
@@ -114,6 +118,8 @@ public class AudioServiceEvents {
|
|||||||
mVal1 = val1;
|
mVal1 = val1;
|
||||||
mVal2 = val2;
|
mVal2 = val2;
|
||||||
mCaller = caller;
|
mCaller = caller;
|
||||||
|
mGroupName = null;
|
||||||
|
mAudioAttributes = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** used for VOL_SET_HEARING_AID_VOL*/
|
/** used for VOL_SET_HEARING_AID_VOL*/
|
||||||
@@ -124,6 +130,8 @@ public class AudioServiceEvents {
|
|||||||
// unused
|
// unused
|
||||||
mStream = -1;
|
mStream = -1;
|
||||||
mCaller = null;
|
mCaller = null;
|
||||||
|
mGroupName = null;
|
||||||
|
mAudioAttributes = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** used for VOL_SET_AVRCP_VOL */
|
/** used for VOL_SET_AVRCP_VOL */
|
||||||
@@ -134,6 +142,8 @@ public class AudioServiceEvents {
|
|||||||
mVal2 = 0;
|
mVal2 = 0;
|
||||||
mStream = -1;
|
mStream = -1;
|
||||||
mCaller = null;
|
mCaller = null;
|
||||||
|
mGroupName = null;
|
||||||
|
mAudioAttributes = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** used for VOL_VOICE_ACTIVITY_HEARING_AID */
|
/** used for VOL_VOICE_ACTIVITY_HEARING_AID */
|
||||||
@@ -144,6 +154,8 @@ public class AudioServiceEvents {
|
|||||||
mVal2 = voiceActive ? 1 : 0;
|
mVal2 = voiceActive ? 1 : 0;
|
||||||
// unused
|
// unused
|
||||||
mCaller = null;
|
mCaller = null;
|
||||||
|
mGroupName = null;
|
||||||
|
mAudioAttributes = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** used for VOL_MODE_CHANGE_HEARING_AID */
|
/** used for VOL_MODE_CHANGE_HEARING_AID */
|
||||||
@@ -154,6 +166,19 @@ public class AudioServiceEvents {
|
|||||||
mVal2 = mode;
|
mVal2 = mode;
|
||||||
// unused
|
// unused
|
||||||
mCaller = null;
|
mCaller = null;
|
||||||
|
mGroupName = null;
|
||||||
|
mAudioAttributes = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** used for VOL_SET_GROUP_VOL */
|
||||||
|
VolumeEvent(int op, AudioAttributes aa, String group, int index, int flags, String caller) {
|
||||||
|
mOp = op;
|
||||||
|
mStream = -1;
|
||||||
|
mVal1 = index;
|
||||||
|
mVal2 = flags;
|
||||||
|
mCaller = caller;
|
||||||
|
mGroupName = group;
|
||||||
|
mAudioAttributes = aa;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -208,6 +233,14 @@ public class AudioServiceEvents {
|
|||||||
.append(") causes setting HEARING_AID volume to idx:").append(mVal1)
|
.append(") causes setting HEARING_AID volume to idx:").append(mVal1)
|
||||||
.append(" stream:").append(AudioSystem.streamToString(mStream))
|
.append(" stream:").append(AudioSystem.streamToString(mStream))
|
||||||
.toString();
|
.toString();
|
||||||
|
case VOL_SET_GROUP_VOL:
|
||||||
|
return new StringBuilder("setVolumeIndexForAttributes(attr:")
|
||||||
|
.append(mAudioAttributes.toString())
|
||||||
|
.append(" group: ").append(mGroupName)
|
||||||
|
.append(" index:").append(mVal1)
|
||||||
|
.append(" flags:0x").append(Integer.toHexString(mVal2))
|
||||||
|
.append(") from ").append(mCaller)
|
||||||
|
.toString();
|
||||||
default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
|
default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user