Merge changes from topic "volume_group_apis"
* changes: [IMPR] AudioProductStrategy: add getName system hidden API fixup '[IMPR] AudioManager: add adjustAttributesVolume API' [IMPR] AudioService: improve bijectivity between VSS / VGS [BUG] AudioService: fix mute/umute of aliased streams. [IMPR] AudioManager: add adjustAttributesVolume API
This commit is contained in:
@@ -20908,6 +20908,7 @@ package android.media {
|
||||
method public void adjustStreamVolume(int, int, int);
|
||||
method public void adjustSuggestedStreamVolume(int, int, int);
|
||||
method public void adjustVolume(int, int);
|
||||
method public void adjustVolumeGroupVolume(int, int, int);
|
||||
method public void clearCommunicationDevice();
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS) public boolean clearPreferredMixerAttributes(@NonNull android.media.AudioAttributes, @NonNull android.media.AudioDeviceInfo);
|
||||
method public void dispatchMediaKeyEvent(android.view.KeyEvent);
|
||||
@@ -20938,6 +20939,7 @@ package android.media {
|
||||
method public float getStreamVolumeDb(int, int, int);
|
||||
method @NonNull public java.util.List<android.media.AudioMixerAttributes> getSupportedMixerAttributes(@NonNull android.media.AudioDeviceInfo);
|
||||
method @Deprecated public int getVibrateSetting(int);
|
||||
method public int getVolumeGroupIdForAttributes(@NonNull android.media.AudioAttributes);
|
||||
method @Deprecated public boolean isBluetoothA2dpOn();
|
||||
method public boolean isBluetoothScoAvailableOffCall();
|
||||
method @Deprecated public boolean isBluetoothScoOn();
|
||||
@@ -20951,6 +20953,7 @@ package android.media {
|
||||
method public boolean isStreamMute(int);
|
||||
method public boolean isSurroundFormatEnabled(int);
|
||||
method public boolean isVolumeFixed();
|
||||
method public boolean isVolumeGroupMuted(int);
|
||||
method @Deprecated public boolean isWiredHeadsetOn();
|
||||
method public void loadSoundEffects();
|
||||
method public void playSoundEffect(int);
|
||||
|
||||
@@ -6680,6 +6680,7 @@ package android.media {
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE"}) public int getDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes);
|
||||
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE"}) public java.util.List<android.media.AudioDeviceAttributes> getDevicesForAttributes(@NonNull android.media.AudioAttributes);
|
||||
method @RequiresPermission("android.permission.QUERY_AUDIO_STATE") public int getLastAudibleStreamVolume(int);
|
||||
method @IntRange(from=0) @RequiresPermission("android.permission.QUERY_AUDIO_STATE") public int getLastAudibleVolumeGroupVolume(int);
|
||||
method @IntRange(from=0) public long getMaxAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
|
||||
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);
|
||||
@@ -6689,6 +6690,9 @@ package android.media {
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getSupportedSystemUsages();
|
||||
method @IntRange(from=0) @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public int getVolumeGroupMaxVolumeIndex(int);
|
||||
method @IntRange(from=0) @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public int getVolumeGroupMinVolumeIndex(int);
|
||||
method @IntRange(from=0) @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public int getVolumeGroupVolumeIndex(int);
|
||||
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
|
||||
method public boolean isAudioServerRunning();
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean isBluetoothVariableLatencyEnabled();
|
||||
@@ -6722,6 +6726,7 @@ package android.media {
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public void setVolumeGroupVolumeIndex(int, int, int);
|
||||
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 boolean supportsBluetoothVariableLatency();
|
||||
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
|
||||
@@ -7128,6 +7133,7 @@ package android.media.audiopolicy {
|
||||
method public int describeContents();
|
||||
method @NonNull public android.media.AudioAttributes getAudioAttributes();
|
||||
method public int getId();
|
||||
method @NonNull public String getName();
|
||||
method public boolean supportsAudioAttributes(@NonNull android.media.AudioAttributes);
|
||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioProductStrategy> CREATOR;
|
||||
|
||||
@@ -1350,12 +1350,8 @@ public class AudioManager {
|
||||
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(), getContext().getAttributionTag());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
int groupId = getVolumeGroupIdForAttributes(attr);
|
||||
setVolumeGroupVolumeIndex(groupId, index, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1374,11 +1370,8 @@ public class AudioManager {
|
||||
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();
|
||||
}
|
||||
int groupId = getVolumeGroupIdForAttributes(attr);
|
||||
return getVolumeGroupVolumeIndex(groupId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1395,11 +1388,8 @@ public class AudioManager {
|
||||
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();
|
||||
}
|
||||
int groupId = getVolumeGroupIdForAttributes(attr);
|
||||
return getVolumeGroupMaxVolumeIndex(groupId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1415,9 +1405,183 @@ public class AudioManager {
|
||||
@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();
|
||||
int groupId = getVolumeGroupIdForAttributes(attr);
|
||||
return getVolumeGroupMinVolumeIndex(groupId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the volume group id associated to the given {@link AudioAttributes}.
|
||||
*
|
||||
* @param attributes The {@link AudioAttributes} to consider.
|
||||
* @return {@link android.media.audiopolicy.AudioVolumeGroup} id supporting the given
|
||||
* {@link AudioAttributes} if found,
|
||||
* {@code android.media.audiopolicy.AudioVolumeGroup.DEFAULT_VOLUME_GROUP} otherwise.
|
||||
*/
|
||||
public int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
|
||||
Preconditions.checkNotNull(attributes, "Audio Attributes must not be null");
|
||||
return AudioProductStrategy.getVolumeGroupIdForAudioAttributes(attributes,
|
||||
/* fallbackOnDefault= */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the volume index for a particular group associated to given id.
|
||||
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)}
|
||||
* to retrieve the volume group id supporting the given {@link AudioAttributes}.
|
||||
*
|
||||
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
|
||||
* @param index The volume index to set. See
|
||||
* {@link #getVolumeGroupMaxVolumeIndex(id)} for the largest valid value
|
||||
* {@link #getVolumeGroupMinVolumeIndex(id)} for the lowest valid value.
|
||||
* @param flags One or more flags.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(anyOf = {
|
||||
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
|
||||
android.Manifest.permission.MODIFY_AUDIO_ROUTING
|
||||
})
|
||||
public void setVolumeGroupVolumeIndex(int groupId, int index, int flags) {
|
||||
final IAudioService service = getService();
|
||||
try {
|
||||
return service.getMinVolumeIndexForAttributes(attr);
|
||||
service.setVolumeGroupVolumeIndex(groupId, index, flags,
|
||||
getContext().getOpPackageName(), getContext().getAttributionTag());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current volume index for a particular group associated to given id.
|
||||
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)}
|
||||
* to retrieve the volume group id supporting the given {@link AudioAttributes}.
|
||||
*
|
||||
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
|
||||
* @return The current volume index for the stream.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@IntRange(from = 0)
|
||||
@RequiresPermission(anyOf = {
|
||||
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
|
||||
android.Manifest.permission.MODIFY_AUDIO_ROUTING
|
||||
})
|
||||
public int getVolumeGroupVolumeIndex(int groupId) {
|
||||
final IAudioService service = getService();
|
||||
try {
|
||||
return service.getVolumeGroupVolumeIndex(groupId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum volume index for a particular group associated to given id.
|
||||
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)}
|
||||
* to retrieve the volume group id supporting the given {@link AudioAttributes}.
|
||||
*
|
||||
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
|
||||
* @return The maximum valid volume index for the {@link AudioAttributes}.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@IntRange(from = 0)
|
||||
@RequiresPermission(anyOf = {
|
||||
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
|
||||
android.Manifest.permission.MODIFY_AUDIO_ROUTING
|
||||
})
|
||||
public int getVolumeGroupMaxVolumeIndex(int groupId) {
|
||||
final IAudioService service = getService();
|
||||
try {
|
||||
return service.getVolumeGroupMaxVolumeIndex(groupId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum volume index for a particular group associated to given id.
|
||||
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)}
|
||||
* to retrieve the volume group id supporting the given {@link AudioAttributes}.
|
||||
*
|
||||
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
|
||||
* @return The minimum valid volume index for the {@link AudioAttributes}.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@IntRange(from = 0)
|
||||
@RequiresPermission(anyOf = {
|
||||
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
|
||||
android.Manifest.permission.MODIFY_AUDIO_ROUTING
|
||||
})
|
||||
public int getVolumeGroupMinVolumeIndex(int groupId) {
|
||||
final IAudioService service = getService();
|
||||
try {
|
||||
return service.getVolumeGroupMinVolumeIndex(groupId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the volume of a particular group associated to given id by one step in a direction.
|
||||
* <p> If the volume group is associated to a stream type, it fallbacks on
|
||||
* {@link #adjustStreamVolume(int, int, int)} for compatibility reason.
|
||||
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)} to retrieve
|
||||
* the volume group id supporting the given {@link AudioAttributes}.
|
||||
*
|
||||
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
|
||||
* @param direction The direction to adjust the volume. One of
|
||||
* {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
|
||||
* {@link #ADJUST_SAME}.
|
||||
* @param flags One or more flags.
|
||||
* @throws SecurityException if the adjustment triggers a Do Not Disturb change and the caller
|
||||
* is not granted notification policy access.
|
||||
*/
|
||||
public void adjustVolumeGroupVolume(int groupId, int direction, int flags) {
|
||||
IAudioService service = getService();
|
||||
try {
|
||||
service.adjustVolumeGroupVolume(groupId, direction, flags,
|
||||
getContext().getOpPackageName());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last audible volume of the group associated to given id before it was muted.
|
||||
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)} to retrieve
|
||||
* the volume group id supporting the given {@link AudioAttributes}.
|
||||
*
|
||||
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
|
||||
* @return current volume if not muted, volume before muted otherwise.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission("android.permission.QUERY_AUDIO_STATE")
|
||||
@IntRange(from = 0)
|
||||
public int getLastAudibleVolumeGroupVolume(int groupId) {
|
||||
IAudioService service = getService();
|
||||
try {
|
||||
return service.getLastAudibleVolumeGroupVolume(groupId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current mute state for a particular volume group associated to the given id.
|
||||
* <p> Call first in prior {@link #getVolumeGroupIdForAttributes(AudioAttributes)} to retrieve
|
||||
* the volume group id supporting the given {@link AudioAttributes}.
|
||||
*
|
||||
* @param groupId of the {@link android.media.audiopolicy.AudioVolumeGroup} to consider.
|
||||
* @return The mute state for the given {@link android.media.audiopolicy.AudioVolumeGroup} id.
|
||||
* @see #adjustVolumeGroupVolume(int, int, int)
|
||||
*/
|
||||
public boolean isVolumeGroupMuted(int groupId) {
|
||||
IAudioService service = getService();
|
||||
try {
|
||||
return service.isVolumeGroupMuted(groupId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -138,18 +138,25 @@ interface IAudioService {
|
||||
@EnforcePermission("MODIFY_AUDIO_ROUTING")
|
||||
List<AudioVolumeGroup> getAudioVolumeGroups();
|
||||
|
||||
@EnforcePermission("MODIFY_AUDIO_ROUTING")
|
||||
void setVolumeIndexForAttributes(in AudioAttributes aa, int index, int flags,
|
||||
String callingPackage, in String attributionTag);
|
||||
@EnforcePermission(anyOf={"MODIFY_AUDIO_SYSTEM_SETTINGS", "MODIFY_AUDIO_ROUTING"})
|
||||
void setVolumeGroupVolumeIndex(int groupId, int index, int flags, String callingPackage,
|
||||
in String attributionTag);
|
||||
|
||||
@EnforcePermission("MODIFY_AUDIO_ROUTING")
|
||||
int getVolumeIndexForAttributes(in AudioAttributes aa);
|
||||
@EnforcePermission(anyOf={"MODIFY_AUDIO_SYSTEM_SETTINGS", "MODIFY_AUDIO_ROUTING"})
|
||||
int getVolumeGroupVolumeIndex(int groupId);
|
||||
|
||||
@EnforcePermission("MODIFY_AUDIO_ROUTING")
|
||||
int getMaxVolumeIndexForAttributes(in AudioAttributes aa);
|
||||
@EnforcePermission(anyOf={"MODIFY_AUDIO_SYSTEM_SETTINGS", "MODIFY_AUDIO_ROUTING"})
|
||||
int getVolumeGroupMaxVolumeIndex(int groupId);
|
||||
|
||||
@EnforcePermission("MODIFY_AUDIO_ROUTING")
|
||||
int getMinVolumeIndexForAttributes(in AudioAttributes aa);
|
||||
@EnforcePermission(anyOf={"MODIFY_AUDIO_SYSTEM_SETTINGS", "MODIFY_AUDIO_ROUTING"})
|
||||
int getVolumeGroupMinVolumeIndex(int groupId);
|
||||
|
||||
@EnforcePermission("QUERY_AUDIO_STATE")
|
||||
int getLastAudibleVolumeGroupVolume(int groupId);
|
||||
|
||||
boolean isVolumeGroupMuted(int groupId);
|
||||
|
||||
void adjustVolumeGroupVolume(int groupId, int direction, int flags, String callingPackage);
|
||||
|
||||
@EnforcePermission("QUERY_AUDIO_STATE")
|
||||
int getLastAudibleStreamVolume(int streamType);
|
||||
|
||||
@@ -231,6 +231,16 @@ public final class AudioProductStrategy implements Parcelable {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @return the product strategy ID (which is the generalisation of Car Audio Usage / legacy
|
||||
* routing_strategy linked to {@link AudioAttributes#getUsage()}).
|
||||
*/
|
||||
@SystemApi
|
||||
@NonNull public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* @return first {@link AudioAttributes} associated to this product strategy.
|
||||
|
||||
@@ -1265,6 +1265,20 @@ public class AudioService extends IAudioService.Stub
|
||||
0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
|
||||
}
|
||||
|
||||
private void initVolumeStreamStates() {
|
||||
int numStreamTypes = AudioSystem.getNumStreamTypes();
|
||||
synchronized (VolumeStreamState.class) {
|
||||
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
|
||||
VolumeStreamState streamState = mStreamStates[streamType];
|
||||
int groupId = getVolumeGroupForStreamType(streamType);
|
||||
if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP
|
||||
&& sVolumeGroupStates.indexOfKey(groupId) >= 0) {
|
||||
streamState.setVolumeGroupState(sVolumeGroupStates.get(groupId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Separating notification volume from ring is NOT of aliasing the corresponding streams
|
||||
* @param properties
|
||||
@@ -1292,6 +1306,8 @@ public class AudioService extends IAudioService.Stub
|
||||
initVolumeGroupStates();
|
||||
|
||||
mSoundDoseHelper.initSafeUsbMediaVolumeIndex();
|
||||
// Link VGS on VSS
|
||||
initVolumeStreamStates();
|
||||
|
||||
// Call setRingerModeInt() to apply correct mute
|
||||
// state on streams affected by ringer mode.
|
||||
@@ -2610,13 +2626,11 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
if (!TextUtils.isEmpty(packageName)) {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
ActivityManager am =
|
||||
(ActivityManager) mContext.getSystemService(mContext.ACTIVITY_SERVICE);
|
||||
|
||||
if (pm.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
try {
|
||||
assistantUid = pm.getPackageUidAsUser(packageName, am.getCurrentUser());
|
||||
assistantUid = pm.getPackageUidAsUser(packageName, getCurrentUserId());
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(TAG,
|
||||
"updateAssistantUId() could not find UID for package: " + packageName);
|
||||
@@ -3482,15 +3496,7 @@ public class AudioService extends IAudioService.Stub
|
||||
} else {
|
||||
state = direction == AudioManager.ADJUST_MUTE;
|
||||
}
|
||||
for (int stream = 0; stream < mStreamStates.length; stream++) {
|
||||
if (streamTypeAlias == mStreamVolumeAlias[stream]) {
|
||||
if (!(readCameraSoundForced()
|
||||
&& (mStreamStates[stream].getStreamType()
|
||||
== AudioSystem.STREAM_SYSTEM_ENFORCED))) {
|
||||
mStreamStates[stream].mute(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
muteAliasStreams(streamTypeAlias, state);
|
||||
} else if ((direction == AudioManager.ADJUST_RAISE)
|
||||
&& mSoundDoseHelper.raiseVolumeDisplaySafeMediaVolume(streamTypeAlias,
|
||||
aliasIndex + step, device, flags)) {
|
||||
@@ -3505,7 +3511,7 @@ public class AudioService extends IAudioService.Stub
|
||||
// Unmute the stream if it was previously muted
|
||||
if (direction == AudioManager.ADJUST_RAISE) {
|
||||
// unmute immediately for volume up
|
||||
streamState.mute(false);
|
||||
muteAliasStreams(streamTypeAlias, false);
|
||||
} else if (direction == AudioManager.ADJUST_LOWER) {
|
||||
if (mIsSingleVolume) {
|
||||
sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE,
|
||||
@@ -3631,6 +3637,42 @@ public class AudioService extends IAudioService.Stub
|
||||
sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops on aliasted stream, update the mute cache attribute of each
|
||||
* {@see AudioService#VolumeStreamState}, and then apply the change.
|
||||
* It prevents to unnecessary {@see AudioSystem#setStreamVolume} done for each stream
|
||||
* and aliases before mute change changed and after.
|
||||
*/
|
||||
private void muteAliasStreams(int streamAlias, boolean state) {
|
||||
synchronized (VolumeStreamState.class) {
|
||||
List<Integer> streamsToMute = new ArrayList<>();
|
||||
for (int stream = 0; stream < mStreamStates.length; stream++) {
|
||||
if (streamAlias == mStreamVolumeAlias[stream]) {
|
||||
if (!(readCameraSoundForced()
|
||||
&& (mStreamStates[stream].getStreamType()
|
||||
== AudioSystem.STREAM_SYSTEM_ENFORCED))) {
|
||||
boolean changed = mStreamStates[stream].mute(state, /* apply= */ false);
|
||||
if (changed) {
|
||||
streamsToMute.add(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
streamsToMute.forEach(streamToMute -> {
|
||||
mStreamStates[streamToMute].doMute();
|
||||
broadcastMuteSetting(streamToMute, state);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcastMuteSetting(int streamType, boolean isMuted) {
|
||||
// Stream mute changed, fire the intent.
|
||||
Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
|
||||
intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType);
|
||||
intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, isMuted);
|
||||
sendBroadcastToAll(intent, null /* options */);
|
||||
}
|
||||
|
||||
// Called after a delay when volume down is pressed while muted
|
||||
private void onUnmuteStream(int stream, int flags) {
|
||||
boolean wasMuted;
|
||||
@@ -3730,7 +3772,8 @@ public class AudioService extends IAudioService.Stub
|
||||
// except for BT SCO stream where only explicit mute is allowed to comply to BT requirements
|
||||
if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO)
|
||||
&& (getDeviceForStream(stream) == device)) {
|
||||
mStreamStates[stream].mute(index == 0);
|
||||
// As adjustStreamVolume with muteAdjust flags mute/unmutes stream and aliased streams.
|
||||
muteAliasStreams(stream, index == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3774,23 +3817,23 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
|
||||
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
/** @see AudioManager#setVolumeIndexForAttributes(attr, int, int) */
|
||||
public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags,
|
||||
@Override
|
||||
@android.annotation.EnforcePermission(anyOf = {
|
||||
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
|
||||
android.Manifest.permission.MODIFY_AUDIO_ROUTING
|
||||
})
|
||||
/** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */
|
||||
public void setVolumeGroupVolumeIndex(int groupId, int index, int flags,
|
||||
String callingPackage, String attributionTag) {
|
||||
super.setVolumeIndexForAttributes_enforcePermission();
|
||||
|
||||
Objects.requireNonNull(attr, "attr must not be null");
|
||||
int volumeGroup = AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
|
||||
attr, /* fallbackOnDefault= */false);
|
||||
if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
|
||||
Log.e(TAG, ": no volume group found for attributes " + attr.toString());
|
||||
super.setVolumeGroupVolumeIndex_enforcePermission();
|
||||
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
|
||||
Log.e(TAG, ": no volume group found for id " + groupId);
|
||||
return;
|
||||
}
|
||||
VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
|
||||
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
|
||||
|
||||
sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, attr, vgs.name(),
|
||||
index, flags, callingPackage + ", user " + ActivityManager.getCurrentUser()));
|
||||
sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, vgs.name(),
|
||||
index, flags, callingPackage + ", user " + getCurrentUserId()));
|
||||
|
||||
vgs.setVolumeIndex(index, flags);
|
||||
|
||||
@@ -3799,7 +3842,7 @@ public class AudioService extends IAudioService.Stub
|
||||
try {
|
||||
ensureValidStreamType(groupedStream);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.d(TAG, "volume group " + volumeGroup + " has internal streams (" + groupedStream
|
||||
Log.d(TAG, "volume group " + groupId + " has internal streams (" + groupedStream
|
||||
+ "), do not change associated stream volume");
|
||||
continue;
|
||||
}
|
||||
@@ -3821,39 +3864,55 @@ public class AudioService extends IAudioService.Stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
/** @see AudioManager#getVolumeIndexForAttributes(attr) */
|
||||
public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
|
||||
super.getVolumeIndexForAttributes_enforcePermission();
|
||||
|
||||
Objects.requireNonNull(attr, "attr must not be null");
|
||||
@Override
|
||||
@android.annotation.EnforcePermission(anyOf = {
|
||||
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
|
||||
android.Manifest.permission.MODIFY_AUDIO_ROUTING
|
||||
})
|
||||
/** @see AudioManager#getVolumeGroupVolumeIndex(int) */
|
||||
public int getVolumeGroupVolumeIndex(int groupId) {
|
||||
super.getVolumeGroupVolumeIndex_enforcePermission();
|
||||
synchronized (VolumeStreamState.class) {
|
||||
int volumeGroup = AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
|
||||
attr, /* fallbackOnDefault= */false);
|
||||
if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
|
||||
throw new IllegalArgumentException("No volume group for attributes " + attr);
|
||||
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
|
||||
throw new IllegalArgumentException("No volume group for id " + groupId);
|
||||
}
|
||||
VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
|
||||
return vgs.isMuted() ? vgs.getMinIndex() : vgs.getVolumeIndex();
|
||||
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
|
||||
// Return 0 when muted, not min index since for e.g. Voice Call, it has a non zero
|
||||
// min but it mutable on permission condition.
|
||||
return vgs.isMuted() ? 0 : vgs.getVolumeIndex();
|
||||
}
|
||||
}
|
||||
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
/** @see AudioManager#getMaxVolumeIndexForAttributes(attr) */
|
||||
public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
|
||||
super.getMaxVolumeIndexForAttributes_enforcePermission();
|
||||
|
||||
Objects.requireNonNull(attr, "attr must not be null");
|
||||
return AudioSystem.getMaxVolumeIndexForAttributes(attr);
|
||||
/** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */
|
||||
@android.annotation.EnforcePermission(anyOf = {
|
||||
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
|
||||
android.Manifest.permission.MODIFY_AUDIO_ROUTING
|
||||
})
|
||||
public int getVolumeGroupMaxVolumeIndex(int groupId) {
|
||||
super.getVolumeGroupMaxVolumeIndex_enforcePermission();
|
||||
synchronized (VolumeStreamState.class) {
|
||||
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
|
||||
throw new IllegalArgumentException("No volume group for id " + groupId);
|
||||
}
|
||||
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
|
||||
return vgs.getMaxIndex();
|
||||
}
|
||||
}
|
||||
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
|
||||
/** @see AudioManager#getMinVolumeIndexForAttributes(attr) */
|
||||
public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
|
||||
super.getMinVolumeIndexForAttributes_enforcePermission();
|
||||
|
||||
Objects.requireNonNull(attr, "attr must not be null");
|
||||
return AudioSystem.getMinVolumeIndexForAttributes(attr);
|
||||
/** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */
|
||||
@android.annotation.EnforcePermission(anyOf = {
|
||||
android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS,
|
||||
android.Manifest.permission.MODIFY_AUDIO_ROUTING
|
||||
})
|
||||
public int getVolumeGroupMinVolumeIndex(int groupId) {
|
||||
super.getVolumeGroupMinVolumeIndex_enforcePermission();
|
||||
synchronized (VolumeStreamState.class) {
|
||||
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
|
||||
throw new IllegalArgumentException("No volume group for id " + groupId);
|
||||
}
|
||||
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
|
||||
return vgs.getMinIndex();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3922,6 +3981,71 @@ public class AudioService extends IAudioService.Stub
|
||||
callingPackage, /*attributionTag*/ null);
|
||||
}
|
||||
|
||||
/** @see AudioManager#adjustVolumeGroupVolume(int, int, int) */
|
||||
public void adjustVolumeGroupVolume(int groupId, int direction, int flags,
|
||||
String callingPackage) {
|
||||
ensureValidDirection(direction);
|
||||
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
|
||||
Log.e(TAG, ": no volume group found for id " + groupId);
|
||||
return;
|
||||
}
|
||||
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
|
||||
// For compatibility reason, use stream API if group linked to a valid stream
|
||||
boolean fallbackOnStream = false;
|
||||
for (int stream : vgs.getLegacyStreamTypes()) {
|
||||
try {
|
||||
ensureValidStreamType(stream);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.d(TAG, "volume group " + groupId + " has internal streams (" + stream
|
||||
+ "), do not change associated stream volume");
|
||||
continue;
|
||||
}
|
||||
// Note: Group and Stream does not share same convention, 0 is mute for stream,
|
||||
// min index is acting as mute for Groups
|
||||
if (vgs.isVssMuteBijective(stream)) {
|
||||
adjustStreamVolume(stream, direction, flags, callingPackage);
|
||||
if (isMuteAdjust(direction)) {
|
||||
// will be propagated to all aliased streams
|
||||
return;
|
||||
}
|
||||
fallbackOnStream = true;
|
||||
}
|
||||
}
|
||||
if (fallbackOnStream) {
|
||||
// Handled by at least one stream, will be propagated to group, bailing out.
|
||||
return;
|
||||
}
|
||||
sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(),
|
||||
direction, flags, callingPackage));
|
||||
vgs.adjustVolume(direction, flags);
|
||||
}
|
||||
|
||||
/** @see AudioManager#getLastAudibleVolumeGroupVolume(int) */
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.QUERY_AUDIO_STATE)
|
||||
public int getLastAudibleVolumeGroupVolume(int groupId) {
|
||||
super.getLastAudibleVolumeGroupVolume_enforcePermission();
|
||||
synchronized (VolumeStreamState.class) {
|
||||
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
|
||||
Log.e(TAG, ": no volume group found for id " + groupId);
|
||||
return 0;
|
||||
}
|
||||
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
|
||||
return vgs.getVolumeIndex();
|
||||
}
|
||||
}
|
||||
|
||||
/** @see AudioManager#isVolumeGroupMuted(int) */
|
||||
public boolean isVolumeGroupMuted(int groupId) {
|
||||
synchronized (VolumeStreamState.class) {
|
||||
if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
|
||||
Log.e(TAG, ": no volume group found for id " + groupId);
|
||||
return false;
|
||||
}
|
||||
VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
|
||||
return vgs.isMuted();
|
||||
}
|
||||
}
|
||||
|
||||
/** @see AudioManager#setStreamVolume(int, int, int)
|
||||
* Part of service interface, check permissions here */
|
||||
public void setStreamVolumeWithAttribution(int streamType, int index, int flags,
|
||||
@@ -5110,7 +5234,7 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
|
||||
private void setRingerMode(int ringerMode, String caller, boolean external) {
|
||||
if (mUseFixedVolume || mIsSingleVolume) {
|
||||
if (mUseFixedVolume || mIsSingleVolume || mUseVolumeGroupAliases) {
|
||||
return;
|
||||
}
|
||||
if (caller == null || caller.length() == 0) {
|
||||
@@ -7413,6 +7537,16 @@ public class AudioService extends IAudioService.Stub
|
||||
|| stream == AudioSystem.STREAM_BLUETOOTH_SCO;
|
||||
}
|
||||
|
||||
private static int getVolumeGroupForStreamType(int stream) {
|
||||
AudioAttributes attributes =
|
||||
AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
|
||||
if (attributes.equals(new AudioAttributes.Builder().build())) {
|
||||
return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
|
||||
}
|
||||
return AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
|
||||
attributes, /* fallbackOnDefault= */ false);
|
||||
}
|
||||
|
||||
// NOTE: Locking order for synchronized objects related to volume management:
|
||||
// 1 mSettingsLock
|
||||
// 2 VolumeStreamState.class
|
||||
@@ -7521,14 +7655,62 @@ public class AudioService extends IAudioService.Stub
|
||||
return mIsMuted;
|
||||
}
|
||||
|
||||
public void adjustVolume(int direction, int flags) {
|
||||
synchronized (AudioService.VolumeStreamState.class) {
|
||||
int device = getDeviceForVolume();
|
||||
int previousIndex = getIndex(device);
|
||||
if (isMuteAdjust(direction) && !isMutable()) {
|
||||
// Non mutable volume group
|
||||
if (DEBUG_VOL) {
|
||||
Log.d(TAG, "invalid mute on unmutable volume group " + name());
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (direction) {
|
||||
case AudioManager.ADJUST_TOGGLE_MUTE: {
|
||||
// Note: If muted by volume 0, unmute will restore volume 0.
|
||||
mute(!mIsMuted);
|
||||
break;
|
||||
}
|
||||
case AudioManager.ADJUST_UNMUTE:
|
||||
// Note: If muted by volume 0, unmute will restore volume 0.
|
||||
mute(false);
|
||||
break;
|
||||
case AudioManager.ADJUST_MUTE:
|
||||
// May be already muted by setvolume 0, prevent from setting same value
|
||||
if (previousIndex != 0) {
|
||||
// bypass persist
|
||||
mute(true);
|
||||
}
|
||||
mIsMuted = true;
|
||||
break;
|
||||
case AudioManager.ADJUST_RAISE:
|
||||
// As for stream, RAISE during mute will increment the index
|
||||
setVolumeIndex(Math.min(previousIndex + 1, mIndexMax), device, flags);
|
||||
break;
|
||||
case AudioManager.ADJUST_LOWER:
|
||||
// For stream, ADJUST_LOWER on a muted VSS is a no-op
|
||||
// If we decide to unmute on ADJUST_LOWER, cannot fallback on
|
||||
// adjustStreamVolume for group associated to legacy stream type
|
||||
if (isMuted() && previousIndex != 0) {
|
||||
mute(false);
|
||||
} else {
|
||||
int newIndex = Math.max(previousIndex - 1, mIndexMin);
|
||||
setVolumeIndex(newIndex, device, flags);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getVolumeIndex() {
|
||||
synchronized (VolumeStreamState.class) {
|
||||
synchronized (AudioService.VolumeStreamState.class) {
|
||||
return getIndex(getDeviceForVolume());
|
||||
}
|
||||
}
|
||||
|
||||
public void setVolumeIndex(int index, int flags) {
|
||||
synchronized (VolumeStreamState.class) {
|
||||
synchronized (AudioService.VolumeStreamState.class) {
|
||||
if (mUseFixedVolume) {
|
||||
return;
|
||||
}
|
||||
@@ -7613,7 +7795,7 @@ public class AudioService extends IAudioService.Stub
|
||||
|
||||
public void applyAllVolumes(boolean userSwitch) {
|
||||
String caller = "from vgs";
|
||||
synchronized (VolumeStreamState.class) {
|
||||
synchronized (AudioService.VolumeStreamState.class) {
|
||||
// apply device specific volumes first
|
||||
for (int i = 0; i < mIndexMap.size(); i++) {
|
||||
int device = mIndexMap.keyAt(i);
|
||||
@@ -7713,7 +7895,7 @@ public class AudioService extends IAudioService.Stub
|
||||
Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group "
|
||||
+ mAudioVolumeGroup.name()
|
||||
+ ", device " + AudioSystem.getOutputDeviceName(device)
|
||||
+ " and User=" + ActivityManager.getCurrentUser());
|
||||
+ " and User=" + getCurrentUserId());
|
||||
}
|
||||
boolean success = mSettings.putSystemIntForUser(mContentResolver,
|
||||
getSettingNameForDevice(device),
|
||||
@@ -7725,7 +7907,7 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
|
||||
public void readSettings() {
|
||||
synchronized (VolumeStreamState.class) {
|
||||
synchronized (AudioService.VolumeStreamState.class) {
|
||||
// force maximum volume on all streams if fixed volume property is set
|
||||
if (mUseFixedVolume) {
|
||||
mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
|
||||
@@ -7752,7 +7934,7 @@ public class AudioService extends IAudioService.Stub
|
||||
if (DEBUG_VOL) {
|
||||
Log.v(TAG, "readSettings: found stored index " + getValidIndex(index)
|
||||
+ " for group " + mAudioVolumeGroup.name() + ", device: " + name
|
||||
+ ", User=" + ActivityManager.getCurrentUser());
|
||||
+ ", User=" + getCurrentUserId());
|
||||
}
|
||||
mIndexMap.put(device, getValidIndex(index));
|
||||
}
|
||||
@@ -7829,13 +8011,14 @@ public class AudioService extends IAudioService.Stub
|
||||
// 4 VolumeStreamState.class
|
||||
/*package*/ class VolumeStreamState {
|
||||
private final int mStreamType;
|
||||
private VolumeGroupState mVolumeGroupState = null;
|
||||
private int mIndexMin;
|
||||
// min index when user doesn't have permission to change audio settings
|
||||
private int mIndexMinNoPerm;
|
||||
private int mIndexMax;
|
||||
|
||||
private boolean mIsMuted;
|
||||
private boolean mIsMutedInternally;
|
||||
private boolean mIsMuted = false;
|
||||
private boolean mIsMutedInternally = false;
|
||||
private String mVolumeIndexSettingName;
|
||||
@NonNull private Set<Integer> mObservedDeviceSet = new TreeSet<>();
|
||||
|
||||
@@ -7907,6 +8090,15 @@ public class AudioService extends IAudioService.Stub
|
||||
mStreamDevicesChangedOptions = streamDevicesChangedOptions.toBundle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a {@link volumeGroupState} on the {@link VolumeStreamState}.
|
||||
* <p> It helps to synchronize the index, mute attributes on the maching
|
||||
* {@link volumeGroupState}
|
||||
* @param volumeGroupState matching the {@link VolumeStreamState}
|
||||
*/
|
||||
public void setVolumeGroupState(VolumeGroupState volumeGroupState) {
|
||||
mVolumeGroupState = volumeGroupState;
|
||||
}
|
||||
/**
|
||||
* Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission
|
||||
* @param index minimum index expressed in "UI units", i.e. no 10x factor
|
||||
@@ -8168,6 +8360,9 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
// If associated to volume group, update group cache
|
||||
updateVolumeGroupIndex(device, /* forceMuteState= */ false);
|
||||
|
||||
oldIndex = (oldIndex + 5) / 10;
|
||||
index = (index + 5) / 10;
|
||||
// log base stream changes to the event log
|
||||
@@ -8285,6 +8480,28 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
// If associated to volume group, update group cache
|
||||
private void updateVolumeGroupIndex(int device, boolean forceMuteState) {
|
||||
synchronized (VolumeStreamState.class) {
|
||||
if (mVolumeGroupState != null) {
|
||||
int groupIndex = (getIndex(device) + 5) / 10;
|
||||
if (DEBUG_VOL) {
|
||||
Log.d(TAG, "updateVolumeGroupIndex for stream " + mStreamType
|
||||
+ ", muted=" + mIsMuted + ", device=" + device + ", index="
|
||||
+ getIndex(device) + ", group " + mVolumeGroupState.name()
|
||||
+ " Muted=" + mVolumeGroupState.isMuted() + ", Index=" + groupIndex
|
||||
+ ", forceMuteState=" + forceMuteState);
|
||||
}
|
||||
mVolumeGroupState.updateVolumeIndex(groupIndex, device);
|
||||
// Only propage mute of stream when applicable
|
||||
if (mIndexMin == 0 || isCallStream(mStreamType)) {
|
||||
// For call stream, align mute only when muted, not when index is set to 0
|
||||
mVolumeGroupState.mute(forceMuteState ? mIsMuted : groupIndex == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mute/unmute the stream
|
||||
* @param state the new mute state
|
||||
@@ -8293,27 +8510,10 @@ public class AudioService extends IAudioService.Stub
|
||||
public boolean mute(boolean state) {
|
||||
boolean changed = false;
|
||||
synchronized (VolumeStreamState.class) {
|
||||
if (state != mIsMuted) {
|
||||
changed = true;
|
||||
mIsMuted = state;
|
||||
|
||||
// Set the new mute volume. This propagates the values to
|
||||
// the audio system, otherwise the volume won't be changed
|
||||
// at the lower level.
|
||||
sendMsg(mAudioHandler,
|
||||
MSG_SET_ALL_VOLUMES,
|
||||
SENDMSG_QUEUE,
|
||||
0,
|
||||
0,
|
||||
this, 0);
|
||||
}
|
||||
changed = mute(state, true);
|
||||
}
|
||||
if (changed) {
|
||||
// Stream mute changed, fire the intent.
|
||||
Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
|
||||
intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
|
||||
intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, state);
|
||||
sendBroadcastToAll(intent, null /* options */);
|
||||
broadcastMuteSetting(mStreamType, state);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
@@ -8345,6 +8545,44 @@ public class AudioService extends IAudioService.Stub
|
||||
return mIsMuted || mIsMutedInternally;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mute/unmute the stream
|
||||
* @param state the new mute state
|
||||
* @param apply true to propagate to HW, or false just to update the cache. May be needed
|
||||
* to mute a stream and its aliases as applyAllVolume will force settings to aliases.
|
||||
* It prevents unnecessary calls to {@see AudioSystem#setStreamVolume}
|
||||
* @return true if the mute state was changed
|
||||
*/
|
||||
public boolean mute(boolean state, boolean apply) {
|
||||
synchronized (VolumeStreamState.class) {
|
||||
boolean changed = state != mIsMuted;
|
||||
if (changed) {
|
||||
mIsMuted = state;
|
||||
if (apply) {
|
||||
doMute();
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
|
||||
public void doMute() {
|
||||
synchronized (VolumeStreamState.class) {
|
||||
// If associated to volume group, update group cache
|
||||
updateVolumeGroupIndex(getDeviceForStream(mStreamType), /* forceMuteState= */ true);
|
||||
|
||||
// Set the new mute volume. This propagates the values to
|
||||
// the audio system, otherwise the volume won't be changed
|
||||
// at the lower level.
|
||||
sendMsg(mAudioHandler,
|
||||
MSG_SET_ALL_VOLUMES,
|
||||
SENDMSG_QUEUE,
|
||||
0,
|
||||
0,
|
||||
this, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public int getStreamType() {
|
||||
return mStreamType;
|
||||
}
|
||||
@@ -8414,6 +8652,9 @@ public class AudioService extends IAudioService.Stub
|
||||
pw.println();
|
||||
pw.print(" Devices: ");
|
||||
pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType)));
|
||||
pw.println();
|
||||
pw.print(" Volume Group: ");
|
||||
pw.println(mVolumeGroupState != null ? mVolumeGroupState.name() : "n/a");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.server.audio;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.AudioDeviceAttributes;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioSystem;
|
||||
@@ -197,6 +196,7 @@ public class AudioServiceEvents {
|
||||
static final int VOL_SET_GROUP_VOL = 8;
|
||||
static final int VOL_MUTE_STREAM_INT = 9;
|
||||
static final int VOL_SET_LE_AUDIO_VOL = 10;
|
||||
static final int VOL_ADJUST_GROUP_VOL = 11;
|
||||
|
||||
final int mOp;
|
||||
final int mStream;
|
||||
@@ -204,7 +204,6 @@ public class AudioServiceEvents {
|
||||
final int mVal2;
|
||||
final String mCaller;
|
||||
final String mGroupName;
|
||||
final AudioAttributes mAudioAttributes;
|
||||
|
||||
/** used for VOL_ADJUST_VOL_UID,
|
||||
* VOL_ADJUST_SUGG_VOL,
|
||||
@@ -217,7 +216,6 @@ public class AudioServiceEvents {
|
||||
mVal2 = val2;
|
||||
mCaller = caller;
|
||||
mGroupName = null;
|
||||
mAudioAttributes = null;
|
||||
logMetricEvent();
|
||||
}
|
||||
|
||||
@@ -230,7 +228,6 @@ public class AudioServiceEvents {
|
||||
mStream = -1;
|
||||
mCaller = null;
|
||||
mGroupName = null;
|
||||
mAudioAttributes = null;
|
||||
logMetricEvent();
|
||||
}
|
||||
|
||||
@@ -243,7 +240,6 @@ public class AudioServiceEvents {
|
||||
mStream = -1;
|
||||
mCaller = null;
|
||||
mGroupName = null;
|
||||
mAudioAttributes = null;
|
||||
logMetricEvent();
|
||||
}
|
||||
|
||||
@@ -256,7 +252,6 @@ public class AudioServiceEvents {
|
||||
// unused
|
||||
mCaller = null;
|
||||
mGroupName = null;
|
||||
mAudioAttributes = null;
|
||||
logMetricEvent();
|
||||
}
|
||||
|
||||
@@ -269,19 +264,18 @@ public class AudioServiceEvents {
|
||||
// unused
|
||||
mCaller = null;
|
||||
mGroupName = null;
|
||||
mAudioAttributes = null;
|
||||
logMetricEvent();
|
||||
}
|
||||
|
||||
/** used for VOL_SET_GROUP_VOL */
|
||||
VolumeEvent(int op, AudioAttributes aa, String group, int index, int flags, String caller) {
|
||||
/** used for VOL_SET_GROUP_VOL,
|
||||
* VOL_ADJUST_GROUP_VOL */
|
||||
VolumeEvent(int op, String group, int index, int flags, String caller) {
|
||||
mOp = op;
|
||||
mStream = -1;
|
||||
mVal1 = index;
|
||||
mVal2 = flags;
|
||||
mCaller = caller;
|
||||
mGroupName = group;
|
||||
mAudioAttributes = aa;
|
||||
logMetricEvent();
|
||||
}
|
||||
|
||||
@@ -293,7 +287,6 @@ public class AudioServiceEvents {
|
||||
mVal2 = 0;
|
||||
mCaller = null;
|
||||
mGroupName = null;
|
||||
mAudioAttributes = null;
|
||||
logMetricEvent();
|
||||
}
|
||||
|
||||
@@ -335,6 +328,15 @@ public class AudioServiceEvents {
|
||||
.record();
|
||||
return;
|
||||
}
|
||||
case VOL_ADJUST_GROUP_VOL:
|
||||
new MediaMetrics.Item(mMetricsId)
|
||||
.set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
|
||||
.set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down")
|
||||
.set(MediaMetrics.Property.EVENT, "adjustVolumeGroupVolume")
|
||||
.set(MediaMetrics.Property.FLAGS, mVal2)
|
||||
.set(MediaMetrics.Property.GROUP, mGroupName)
|
||||
.record();
|
||||
return;
|
||||
case VOL_SET_STREAM_VOL:
|
||||
new MediaMetrics.Item(mMetricsId)
|
||||
.set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
|
||||
@@ -386,7 +388,6 @@ public class AudioServiceEvents {
|
||||
return;
|
||||
case VOL_SET_GROUP_VOL:
|
||||
new MediaMetrics.Item(mMetricsId)
|
||||
.set(MediaMetrics.Property.ATTRIBUTES, mAudioAttributes.toString())
|
||||
.set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
|
||||
.set(MediaMetrics.Property.EVENT, "setVolumeIndexForAttributes")
|
||||
.set(MediaMetrics.Property.FLAGS, mVal2)
|
||||
@@ -412,6 +413,13 @@ public class AudioServiceEvents {
|
||||
.append(" flags:0x").append(Integer.toHexString(mVal2))
|
||||
.append(") from ").append(mCaller)
|
||||
.toString();
|
||||
case VOL_ADJUST_GROUP_VOL:
|
||||
return new StringBuilder("adjustVolumeGroupVolume(group:")
|
||||
.append(mGroupName)
|
||||
.append(" dir:").append(AudioManager.adjustToString(mVal1))
|
||||
.append(" flags:0x").append(Integer.toHexString(mVal2))
|
||||
.append(") from ").append(mCaller)
|
||||
.toString();
|
||||
case VOL_ADJUST_STREAM_VOL:
|
||||
return new StringBuilder("adjustStreamVolume(stream:")
|
||||
.append(AudioSystem.streamToString(mStream))
|
||||
@@ -460,8 +468,7 @@ public class AudioServiceEvents {
|
||||
.append(" stream:").append(AudioSystem.streamToString(mStream))
|
||||
.toString();
|
||||
case VOL_SET_GROUP_VOL:
|
||||
return new StringBuilder("setVolumeIndexForAttributes(attr:")
|
||||
.append(mAudioAttributes.toString())
|
||||
return new StringBuilder("setVolumeIndexForAttributes(group:")
|
||||
.append(" group: ").append(mGroupName)
|
||||
.append(" index:").append(mVal1)
|
||||
.append(" flags:0x").append(Integer.toHexString(mVal2))
|
||||
|
||||
Reference in New Issue
Block a user