Android set volume default value

        In car audio development, setting the default volume value is necessary, and customized development is often required. There are also many scenarios where it is necessary to set the maximum and minimum volume values. For example, the call mode is usually prohibited from muting, and when the headset mode is adjusted to a larger volume, it will return to a maximum default value after powering on. And usually, the default values ​​of different models may be different. This article will take a look at how to maintain the default volume of different models in a set of code.

1. System default volume

1.Default volume

Source code location: frameworks/base/media/java/android/media/AudioSystem.java

public static int[] DEFAULT_STREAM_VOLUME = new int[] {
    4,  // STREAM_VOICE_CALL
    7,  // STREAM_SYSTEM
    5,  // STREAM_RING
    5, // STREAM_MUSIC
    6,  // STREAM_ALARM
    5,  // STREAM_NOTIFICATION
    7,  // STREAM_BLUETOOTH_SCO
    7,  // STREAM_SYSTEM_ENFORCED
    5, // STREAM_DTMF
    5, // STREAM_TTS
    5, // STREAM_ACCESSIBILITY
    5, // STREAM_ASSISTANT
};

2. Maximum/minimum volume

Source code location : frameworks/base/services/core/java/com/android/server/audio/AudioService.java

/** 音频流的最大音量索引值 */
protected static int[] MAX_STREAM_VOLUME = new int[] {
    5,  // STREAM_VOICE_CALL
    7,  // STREAM_SYSTEM
    7,  // STREAM_RING
    15, // STREAM_MUSIC
    7,  // STREAM_ALARM
    7,  // STREAM_NOTIFICATION
    15, // STREAM_BLUETOOTH_SCO
    7,  // STREAM_SYSTEM_ENFORCED
    15, // STREAM_DTMF
    15, // STREAM_TTS
    15, // STREAM_ACCESSIBILITY
    15  // STREAM_ASSISTANT
};

/** 音频流的最小音量索引值 */
protected static int[] MIN_STREAM_VOLUME = new int[] {
    1,  // STREAM_VOICE_CALL
    0,  // STREAM_SYSTEM
    0,  // STREAM_RING
    0,  // STREAM_MUSIC
    1,  // STREAM_ALARM
    0,  // STREAM_NOTIFICATION
    0,  // STREAM_BLUETOOTH_SCO
    0,  // STREAM_SYSTEM_ENFORCED
    0,  // STREAM_DTMF
    0,  // STREAM_TTS
    1,  // STREAM_ACCESSIBILITY
    0   // STREAM_ASSISTANT
};

3. Modify the default value

        Although we have found the definition location of the default value, it is best not to modify the default value of the sound attribute here, otherwise the modification may be invalid. Because after these two volume attributes are defined, they will also be initialized in the constructor of AudioService. During this period, the previously defined volume value will be overwritten.

public AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer) {
    ……
    int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
    if (maxCallVolume != -1) {
        MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume;
    }

    int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1);
    if (defaultCallVolume != -1 &&
                defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] &&
                defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume;
    } else {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] =
                    (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4;
    }

    int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
    if (maxMusicVolume != -1) {
        MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume;
    }

    int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
    if (defaultMusicVolume != -1 &&
                defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] &&
                defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
    } else {
        if (isPlatformTelevision()) {
            AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
        } else {
            AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
        }
    }

    int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1);
    if (maxAlarmVolume != -1) {
        MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume;
    }

    int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1);
    if (defaultAlarmVolume != -1 &&
                defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume;
    } else {
        // 默认值是7分中的6分(默认最大值),因此相应地缩放。
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] =
                        6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7;
    }
    
    int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1);
    if (maxSystemVolume != -1) {
        MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume;
    }

    int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1);
    if (defaultSystemVolume != -1 && defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume;
    } else {
        // 默认是使用maximum。
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM];
    }
    ……
}

        Taking the multimedia default volume as an example, we can see that its final setting result is one-third of the maximum volume, that is, 15/3=5 volume levels. 

int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
if (defaultMusicVolume != -1 &&
                defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] &&
                defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
    AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
} else {
    if (isPlatformTelevision()) {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
    } else {
        AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
    }
}

        So, its modification should be like this: 

//多媒体默认音量修改为10格
int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", 10);

        In fact, this is where System 1 is used to record the volume set by the user. First, the volume set by the user is taken out. If the value taken out is between the maximum value and the minimum value, the volume is used directly. Otherwise set one-third of the maximum volume as the default volume.

1. Custom volume value

        For car and machine development, in order to facilitate maintenance, we can also define a set of xml files with custom volume values.

1. Configure default values

        Normally, you need to add relevant default value attributes to the above file.

config.xml

Source code location:/packages/services/Car/service/res/values/config.xml

<integer name="mediaMaxVolume">20</integer>
<integer name="mediaMinVolume">5</integer>
<integer name="alarmMaxVolume">20</integer>
<integer name="alarmMinVolume">5</integer>

        The maximum volume of multimedia is set to 20 and the minimum volume is 10. The minimum volume of the alarm clock is set to 5.

2. Initialization data

CarAudioService

Source code location:/packages/services/Car/service/src/com/android/car/CarAudioService.java

public class CarAudioService extends ICarAudio.Stub implements CarServiceBase, PowerEventProcessingHandler {
    ……
    private static final String MEDIA_MIN_VOLUME  = "vendor.media.min.volume";
    private static final String MEDIA_MAX_VOLUME  = "vendor.media.max.volume";
    private static final String ALARM_MIN_VOLUME  = "vendor.alarm.min.volume";
    private static final String ALARM_MAX_VOLUME  = "vendor.alarm.max.volume";
	
    private int mMediaMinVolume;
    private int mMediaMaxVolume;
    private int mAlarmMinVolume;
    private int mAlarmMaxVolume;

    @Override
    public void init() {
        ……
        synchronized (mImplLock) {
            ……
            Resources res = mContext.getResources();
            mMediaMinVolume = res.getInteger(R.integer.mediaMinVolume);
            mMediaMaxVolume = res.getInteger(R.integer.mediaMaxVolume);
            mAlarmMinVolume = res.getInteger(R.integer.alarmMinVolume);
            mAlarmMaxVolume = res.getInteger(R.integer.alarmMaxVolume);
            SystemProperties.set(MEDIA_MIN_VOLUME, String.valueOf(mMediaMinVolume));
            SystemProperties.set(MEDIA_MAX_VOLUME, String.valueOf(mMediaMaxVolume));
            SystemProperties.set(ALARM_MIN_VOLUME, String.valueOf(mAlarmMinVolume));
            SystemProperties.set(ALARM_MAX_VOLUME, String.valueOf(mAlarmMaxVolume));
            ……
        }
        ……
    }
    ……
}

        This is to take out the data in xml and store it in system variables. Let's take a look at the storage method here.

SystemProperties

Source code location:/frameworks/base/core/java/android/os/SystemProperties.java

/**
 * 提供对系统属性存储的访问权限。系统属性存储包含字符串键值对列表。
 * 该类仅用于本地的系统属性。
 */
public class SystemProperties {
    private static final boolean TRACK_KEY_ACCESS = false;

    public static String get(@NonNull String key) {
        if (TRACK_KEY_ACCESS) onKeyAccess(key);
        return native_get(key);
    }

    public static String get(@NonNull String key, @Nullable String def) {
        if (TRACK_KEY_ACCESS) onKeyAccess(key);
        return native_get(key, def);
    }
}

        You can see that this is equivalent to a tool class used to store system properties.

3. Get data

        In the AudioService above, the data stored here can be used for assignment, so custom data is used.

private static final String MEDIA_MIN_VOLUME  = "vendor.media.min.volume";
private static final String MEDIA_MAX_VOLUME  = "vendor.media.max.volume";
private static final String ALARM_MIN_VOLUME  = "vendor.alarm.min.volume";
private static final String ALARM_MAX_VOLUME  = "vendor.alarm.max.volume";
	
private int mMediaMinVolume;
private int mMediaMaxVolume;
private int mAlarmMinVolume;
private int mAlarmMaxVolume;

mMediaMinVolume = SystemProperties.get(MEDIA_MIN_VOLUME);
mMediaMaxVolume = SystemProperties.get(MEDIA_MAX_VOLUME);
mAlarmMinVolume = SystemProperties.get(ALARM_MIN_VOLUME);
mAlarmMaxVolume = SystemProperties.get(ALARM_MAX_VOLUME);

4. Customized settings

        If you only have one set of settings, just use the code above. However, if there are multiple models currently and the volume boundary settings are not the same, customized settings are required. For example, we have two models, xx01 and xx02, and their customized files are stored under /device/xiaoxu/xx01 and /device/xiaoxu/xx02. The default value configured here needs to override the above configuration information, so an overlay path needs to be added.

xx01

Source code location:/device/xiaoxu/xx01/overlay/packages/services/Car/service/res/values/config.xml

<integer name="mediaMaxVolume">18</integer>
<integer name="mediaMinVolume">3</integer>
<integer name="alarmMaxVolume">18</integer>
<integer name="alarmMinVolume">3</integer>

 xx02

Source code location:/device/xiaoxu/xx02/overlay/packages/services/Car/service/res/values/config.xml

<integer name="mediaMaxVolume">22</integer>
<integer name="mediaMinVolume">7</integer>
<integer name="alarmMaxVolume">22</integer>
<integer name="alarmMinVolume">7</integer>

        In this way, the file will overwrite the above settings, and the initialization and acquisition methods of values ​​​​are the same as above, so they will not be added again here.

Guess you like

Origin blog.csdn.net/c19344881x/article/details/134924790