整个需要添加的类均在frameworks\base\media\java\android\media 包下
1.AudioManager.java中添加两个方法,设置音频流设备的音量和得到相关音量
Index: AudioManager.java
===================================================================
--- AudioManager.java (revision 3929)
+++ AudioManager.java (revision 3930)
@@ -984,6 +984,16 @@
}
}
+ public int getStreamDeviceVolume(int streamType, int device) {
+ Slog.d(TAG,"getStreamDeviceVolume streamType:"+streamType+" device:"+device);
+ final IAudioService service = getService();
+ try {
+ return service.getStreamDeviceVolume(streamType,device);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
// keep in sync with frameworks/av/services/audiopolicy/common/include/Volume.h
private static final float VOLUME_MIN_DB = -758.0f;
@@ -1131,6 +1141,15 @@
}
}
+ public void setStreamDeviceVolume(int streamType, int device, int index, int flags) {
+ Slog.d(TAG,"setStreamDeviceVolume streamType:"+streamType+" device:"+device+" index:"+index+" flags:"+flags);
+ final IAudioService service = getService();
+ try {
+ service.setStreamDeviceVolume(streamType, device, index, flags, getContext().getOpPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
/**
* Solo or unsolo a particular stream.
* <p>
2.IAudioService.aidl中添加2个新的接口
Index: IAudioService.aidl
===================================================================
--- IAudioService.aidl (revision 3929)
+++ IAudioService.aidl (revision 3930)
@@ -64,6 +64,8 @@
void adjustStreamVolume(int streamType, int direction, int flags, String callingPackage);
void setStreamVolume(int streamType, int index, int flags, String callingPackage);
+
+ void setStreamDeviceVolume(int streamType, int device, int index, int flags, String callingPackage);
boolean isStreamMute(int streamType);
@@ -74,6 +76,8 @@
void setMasterMute(boolean mute, int flags, String callingPackage, int userId);
int getStreamVolume(int streamType);
+
+ int getStreamDeviceVolume(int streamType, int device);
int getStreamMinVolume(int streamType);
3.AudioService中添加接口的实现
Index: AudioService.java
===================================================================
--- AudioService.java (revision 3929)
+++ AudioService.java (revision 3930)
@@ -1956,7 +1956,7 @@
Slog.d(TAG,"---yums--- onSetStreamVolume streamType:" + streamType + ",index:" + index + ",oldIndex:" + oldIndex + ",device:" + device + ",caller:" + caller);
final int stream = mStreamVolumeAlias[streamType];
Slog.d(TAG,"-zhangshuai--setStreamVolumeInt ---setStreamVolume----Bluetooth--A2DP---- ");
- // setStreamVolumeInt(stream, index, device, false, caller);// shuai4.zhang@tcl.com
+ // setStreamVolumeInt(stream, index, device, false, caller);// shuai4.zhang@tcl.com
// setting volume on ui sounds stream type also controls silent mode
if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
(stream == getUiSoundsStreamType())) {
@@ -1982,6 +1982,39 @@
}
+ private void onSetStreamDeviceVolume(int streamType, int index, int flags, int device,
+ String caller) {
+
+ int oldIndex;
+ oldIndex = mStreamStates[streamType].getIndex(device);
+ final int stream = mStreamVolumeAlias[streamType];
+ Slog.d(TAG,"-zhangshuai---setStreamDeviceVolume------- ");
+ setStreamVolumeInt(stream, index, device, false, caller);// shuai4.zhang@tcl.com
+ // setting volume on ui sounds stream type also controls silent mode
+ if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
+ (stream == getUiSoundsStreamType())) {
+ setRingerMode(getNewRingerMode(stream, index, flags),
+ TAG + ".onSetStreamVolume", false /*external*/);
+ }
+ // setting non-zero volume for a muted stream unmutes the stream and vice versa
+ //mStreamStates[stream].mute(false);//google original logical
+
+ //start add by yums@tcl.com for mantis bug 0214756:after press bluetooth device's volume decrease button when blueto oth device is //muted,Bluetooth speaker will also unmute.
+ if(mStreamStates[streamType].mIsMuted)
+ {
+ if(index > oldIndex)
+ {
+ mStreamStates[stream].mute(false);
+ }
+ }//end add by yums@tcl 2018-12-25
+ else
+ {
+ // setting non-zero volume for a muted stream unmutes the stream and vice versa
+ mStreamStates[stream].mute(index == 0);;//google original logical
+ }
+
+ }
+
/** @see AudioManager#setStreamVolume(int, int, int) */
public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
@@ -2004,6 +2037,34 @@
Binder.getCallingUid());
}
+ /** @see AudioManager#setStreamDeviceVolume(int, int, int, int) */
+ public void setStreamDeviceVolume(int streamType, int device, int index, int flags, String callingPackage) {
+ Slog.d(TAG,"setStreamDeviceVolume streamType:"+streamType+" device:"+device+" index:"+index+" flags:"+flags+" callingPackage:"+callingPackage);
+ if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
+ Log.w(TAG, "Trying to call setStreamVolume() for a11y without"
+ + " CHANGE_ACCESSIBILITY_VOLUME callingPackage=" + callingPackage);
+ return;
+ }
+ if ((streamType == AudioManager.STREAM_VOICE_CALL) &&
+ (index == 0) &&
+ (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MODIFY_PHONE_STATE)
+ != PackageManager.PERMISSION_GRANTED)) {
+ Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without"
+ + " MODIFY_PHONE_STATE callingPackage=" + callingPackage);
+ return;
+ }
+ mVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
+ index/*val1*/, flags/*val2*/, callingPackage));
+ setStreamDeviceVolume(streamType, device, index, flags, callingPackage, callingPackage,
+ Binder.getCallingUid());
+ /*VolumeStreamState streamState = mStreamStates[streamTypeAlias];
+ System.putIntForUser(mContentResolver,
+ streamState.getSettingNameForDevice(device),
+ index,
+ UserHandle.USER_CURRENT);*/
+ }
+
private boolean canChangeAccessibilityVolume() {
synchronized (mAccessibilityServiceUidsLock) {
if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
@@ -2119,6 +2180,116 @@
sendVolumeUpdate(streamType, oldIndex, index, flags);
}
+ private void setStreamDeviceVolume(int streamType, int device, int index, int flags, String callingPackage,
+ String caller, int uid) {
+ Slog.d(TAG, "setStreamVolume(stream=" + streamType+", device="+device+", index=" + index
+ + ", calling=" + callingPackage + ")");
+
+ if (mUseFixedVolume) {
+ Slog.d(TAG,"--zhangshuai--50505050505050- index: "+index);
+ return;
+ }
+
+ ensureValidStreamType(streamType);
+ int streamTypeAlias = mStreamVolumeAlias[streamType];
+ VolumeStreamState streamState = mStreamStates[streamTypeAlias];
+
+ int oldIndex;
+ // System.putIntForUser(mContentResolver,streamState.getSettingNameForDevice(device),(streamState.getIndex(device) + 5)/ 10,UserHandle.USER_CURRENT);
+ // skip a2dp absolute volume control request when the device
+ // is not an a2dp device
+ if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) == 0 &&
+ (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
+ Slog.d(TAG,"--zhangshuai--404040404004- index: "+index);
+ return;
+ }
+ // If we are being called by the system (e.g. hardware keys) check for current user
+ // so we handle user restrictions correctly.
+ if (uid == android.os.Process.SYSTEM_UID) {
+ Slog.d(TAG,"--zhangshuai--3030303030- index: "+index);
+ uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
+ }
+ if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage)
+ != AppOpsManager.MODE_ALLOWED) {
+ Slog.d(TAG,"--zhangshuai--20202020- index: "+index);
+ return;
+ }
+
+ if (isAndroidNPlus(callingPackage)
+ && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags))
+ && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) {
+ Slog.d(TAG,"--zhangshuai--101010100101- index: "+index);
+ throw new SecurityException("Not allowed to change Do Not Disturb state");
+ }
+
+ if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
+ Slog.d(TAG,"--zhangshuai--999- index: "+index);
+ return;
+ }
+
+ synchronized (mSafeMediaVolumeState) {
+ // reset any pending volume command
+ mPendingVolumeCommand = null;
+
+ oldIndex = streamState.getIndex(device);
+ Slog.d(TAG,"--zhangshuai--888- oldIndex: "+oldIndex);
+
+ index = rescaleIndex(index * 10, streamType, streamTypeAlias);
+
+ if (streamTypeAlias == AudioSystem.STREAM_MUSIC &&
+ (device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&
+ (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
+ synchronized (mA2dpAvrcpLock) {
+ if (mA2dp != null && mAvrcpAbsVolSupported) {
+ mA2dp.setAvrcpAbsoluteVolume(index / 10);
+ Slog.d(TAG,"--zhangshuai--777- index: "+index);
+ }
+ }
+ }
+
+ if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0) {
+ setHearingAidVolume(index, streamType);
+ Slog.d(TAG,"--zhangshuai--666- index: "+index);
+ }
+
+ if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
+ setSystemAudioVolume(oldIndex, index, getStreamMaxVolume(streamType), flags);
+ Slog.d(TAG,"--zhangshuai--555- index: "+index);
+ }
+
+ flags &= ~AudioManager.FLAG_FIXED_VOLUME;
+ if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) &&
+ ((device & mFixedVolumeDevices) != 0)) {
+ flags |= AudioManager.FLAG_FIXED_VOLUME;
+
+ // volume is either 0 or max allowed for fixed volume devices
+ if (index != 0) {
+ if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
+ (device & mSafeMediaVolumeDevices) != 0) {
+ index = safeMediaVolumeIndex(device);
+ Slog.d(TAG,"--zhangshuai--444- index: "+index);
+ } else {
+ index = streamState.getMaxIndex();
+ }
+ }
+ }
+
+ if (!checkSafeMediaVolume(streamTypeAlias, index, device)) {
+ Slog.d(TAG,"--zhangshuai--333--- index: "+index);
+ mVolumeController.postDisplaySafeVolumeWarning(flags);
+ mPendingVolumeCommand = new StreamVolumeCommand(
+ streamType, index, flags, device);
+ } else {
+ Slog.d(TAG,"--zhangshuai--222----222--- index: "+index);
+ onSetStreamDeviceVolume(streamType, index, flags, device, caller);
+ index = mStreamStates[streamType].getIndex(device);
+ Slog.d(TAG,"--zhangshuai--222- index: "+index);
+ }
+ }
+ Slog.d(TAG,"--zhangshuai-111-- index: "+index);
+ //sendVolumeUpdate(streamType, oldIndex, index, flags);
+ }
+
// 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()) {
@@ -2516,6 +2687,26 @@
}
}
+ /** @see AudioManager#getStreamDeviceVolume(int,int) */
+ public int getStreamDeviceVolume(int streamType,int device) {
+ Slog.d(TAG,"getStreamDeviceVolume streamType:"+streamType+" device:"+device);
+ ensureValidStreamType(streamType);
+ synchronized (VolumeStreamState.class) {
+ int index = mStreamStates[streamType].getIndex(device);
+ Slog.d(TAG,"getStreamDeviceVolume index: "+index);
+ // by convention getStreamVolume() returns 0 when a stream is muted.
+ if (mStreamStates[streamType].mIsMuted) {
+ //index = 0;//caojun1@tcl.com modify
+ }
+ if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
+ (device & mFixedVolumeDevices) != 0) {
+ index = mStreamStates[streamType].getMaxIndex();
+ Slog.d(TAG,"getStreamDeviceVolume ---2--index: "+index);
+ }
+ return (index + 5) / 10;
+ }
+ }
+
/** @see AudioManager#getStreamMaxVolume(int) */
public int getStreamMaxVolume(int streamType) {
ensureValidStreamType(streamType);
第三方应用调用:
// 第一种反射方式
try {
method = AudioManager.class.getDeclaredMethod("setStreamDeviceVolume",
new Class[] { boolean.class });
method.invoke(audioManager, new Object[] { new Boolean(true) });
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
Log.i("gao", e.toString());
}
}