Android之耳机音量加大时警告提示框问题(MTK6739平台)

2022-07-28,,,

37-Android之耳机音量加大时警告提示框问题 MTK6739平台

平台: MTK6739 Android10

之前在
34-Android之耳机音量加大时警告提示框问题(展锐SC9820E平台)里说把MTK该问题的解决方法也发布出来. 结果一直偷懒到现在.

当时GCF测试, 反馈了两个问题:

  1. 设备重启之后, 设备音量没有恢复到安全音量
  2. 当连续播放20个小时候, 音量没有恢复到安全音量
:
frameworks/base/services/core/java/com/android/server/audio/AudioService.java

// 问题1: 
    private void onConfigureSafeVolume(boolean force, String caller) {
        synchronized (mSafeMediaVolumeStateLock) {
            int mcc = mContext.getResources().getConfiguration().mcc;
            if ((mMcc != mcc) || ((mMcc == 0) && force)) {
                mSafeMediaVolumeIndex = mContext.getResources().getInteger(
                        com.android.internal.R.integer.config_safe_media_volume_index) * 10;
                mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
                boolean safeMediaVolumeEnabled =
                        SystemProperties.getBoolean("audio.safemedia.force", false)
                        || mContext.getResources().getBoolean(
                                com.android.internal.R.bool.config_safe_media_volume_enabled);
                boolean safeMediaVolumeBypass =
                        SystemProperties.getBoolean("audio.safemedia.bypass", false);
                        
                // The persisted state is either "disabled" or "active": this is the state applied
                // next time we boot and cannot be "inactive"
                int persistedState;
                if (safeMediaVolumeEnabled && !safeMediaVolumeBypass) {
                    persistedState = SAFE_MEDIA_VOLUME_ACTIVE;
                    // The state can already be "inactive" here if the user has forced it before
                    // the 30 seconds timeout for forced configuration. In this case we don't reset
                    // it to "active".
                    if (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_INACTIVE) {
// 此处修改 begin @{                        
// 在Android10中对mMusicActiveMs进行了持久化存储, mMusicActiveMs 可能不为0, 
// 导致mSafeMediaVolumeState的状态为SAFE_MEDIA_VOLUME_INACTIVE, 因此导致了问题1的出现
//                        if (mMusicActiveMs == 0) {
                            mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
                            enforceSafeMediaVolume(caller);
                            LogUtils.d(TAG,"onConfigureSafeVolume mSafeMediaVolumeState: SAFE_MEDIA_VOLUME_ACTIVE: "+SAFE_MEDIA_VOLUME_ACTIVE);
//                        } else {
                            // We have existing playback time recorded, already confirmed.
//                            mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE;
//                        }
// }@ end
                    }
                } else {
                    persistedState = SAFE_MEDIA_VOLUME_DISABLED;
                    mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED;
                }
                mMcc = mcc;
                sendMsg(mAudioHandler,
                        MSG_PERSIST_SAFE_VOLUME_STATE,
                        SENDMSG_QUEUE,
                        persistedState,
                        0,
                        null,
                        0);
            }
        }
    }

// 问题2: 
// 出现的原因是, 设备系统息屏后, 定时器定时不准导致的
//(设计理想情况是,每隔60秒进行播放时长的检测,但在息屏之后,间隔的检测时长是大于60秒的,可能跟电量优化有关,导致计时器记录时长小于实际播放时长)
// 增加PauseTime相关, 是考虑到超过安全音量的播放过程中,如果中间有暂停,需要将暂停的时间减掉
// 修改此处 begin @{
    private static long mMusicStartTime = 0;
    private static long mMusicPauseTime1 = 0;
    private static List<Long> mCachePauseMusicTimes = new ArrayList<Long>();

    private long getPauseTime(){
        long pauseTime = 0;
        for(Long time : mCachePauseMusicTimes){
            pauseTime +=time;
        }
        return pauseTime;
    }
// }@ end

    private void onCheckMusicActive(String caller) {
        LogUtils.d(TAG,"onCheckMusicActive start caller: "+caller);
        synchronized (mSafeMediaVolumeStateLock) {
            if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {
                int device = getDeviceForStream(AudioSystem.STREAM_MUSIC);
                if ((device & mSafeMediaVolumeDevices) != 0) {
                    sendMsg(mAudioHandler,
                            MSG_CHECK_MUSIC_ACTIVE,
                            SENDMSG_REPLACE,
                            0,
                            0,
                            caller,
                            MUSIC_ACTIVE_POLL_PERIOD_MS);
                    int index = mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(device);
                    if (AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)
                            && (index > safeMediaVolumeIndex(device))) {
                        // Approximate cumulative active music time
// 修改此处, begin @{                        
                        long tempTime = SystemClock.elapsedRealtime();
                        int preMusicActiveMs = mMusicActiveMs;
                        LogUtils.d(TAG,"preMusicActiveMs: " + preMusicActiveMs);
                        mMusicActiveMs += MUSIC_ACTIVE_POLL_PERIOD_MS;
                        // 说明刚开始计时,记录音乐开始播放的时间
                        if(preMusicActiveMs == 1){
                            mMusicStartTime = tempTime - MUSIC_ACTIVE_POLL_PERIOD_MS;
                            mCachePauseMusicTimes.clear();
                        }
                        // 说明播放过程中,有暂停的情况
                        if(mMusicPauseTime1 != 0){
                        	// 收集暂停的时长
                            mCachePauseMusicTimes.add(tempTime - mMusicPauseTime1 - MUSIC_ACTIVE_POLL_PERIOD_MS);
                            mMusicPauseTime1 = 0;
                        }
                        // 当息屏播放音乐,定时器定时不准,会导致计时器记录的时长小于实际播放的时长,因此将实际播放时长赋值给计时器
                        //  (tempTime - mMusicStartTime - getPauseTime()):当前时间 - 音乐开始播放的时间 - 中途暂停的时间 = 实际播放时长
                        if(mMusicActiveMs < (tempTime - mMusicStartTime - getPauseTime())){
                            mMusicActiveMs = (int)(tempTime - mMusicStartTime  - getPauseTime());
                        }
                        // 如果播放时长超过限定的最长播放时厂,开启音量保护,重置计时器
                        if (mMusicActiveMs > UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX) {
                            setSafeMediaVolumeEnabled(true, caller);
                            mMusicActiveMs = 0;
                            mMusicStartTime = 0;
                            mCachePauseMusicTimes.clear();
                        }
                        // 保存播放时长, 持久化存储
                        saveMusicActiveMs();
                    } else {
                        // 记录暂停开始的时间
                        LogUtils.d(TAG,"no music active");
                        if(mMusicStartTime != 0 && mMusicPauseTime1 == 0){
                            LogUtils.d(TAG,"pause active 1");
                            mMusicPauseTime1 = SystemClock.elapsedRealtime();
                        }
                    }
                } else {
                	// 记录暂停开始的时间
                    LogUtils.d(TAG,"no music active");
                    if(mMusicStartTime != 0 && mMusicPauseTime1 == 0){
                        LogUtils.d(TAG,"pause active 1");
                        mMusicPauseTime1 = SystemClock.elapsedRealtime();
                    }
                }
            }else{
            	// 记录暂停开始的时间
                LogUtils.d(TAG,"no music active");
                if(mMusicStartTime != 0 && mMusicPauseTime1 == 0){
                    LogUtils.d(TAG,"pause active 1");
                    mMusicPauseTime1 = SystemClock.elapsedRealtime();
                }
            }
        }
    }
// }@ end 

本文地址:https://blog.csdn.net/liumengluo/article/details/109604702

《Android之耳机音量加大时警告提示框问题(MTK6739平台).doc》

下载本文的Word格式文档,以方便收藏与打印。