记录Android 8声音调整过程。

frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java    private void dispatchDirectAudioEvent(KeyEvent event) {        if (event.getAction() != KeyEvent.ACTION_DOWN) {            return;        }        int keyCode = event.getKeyCode();        int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND                | AudioManager.FLAG_FROM_KEY;        String pkgName = mContext.getOpPackageName();        switch (keyCode) {            case KeyEvent.KEYCODE_VOLUME_UP:                try {                    getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE,                            AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG);                } catch (Exception e) {                    Log.e(TAG, "Error dispatching volume up in dispatchTvAudioEvent.", e);                }                break;            case KeyEvent.KEYCODE_VOLUME_DOWN:                try {                    getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER,                            AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG);                } catch (Exception e) {                    Log.e(TAG, "Error dispatching volume down in dispatchTvAudioEvent.", e);                }                break;            case KeyEvent.KEYCODE_VOLUME_MUTE:                try {                    if (event.getRepeatCount() == 0) {                        getAudioService().adjustSuggestedStreamVolume(                                AudioManager.ADJUST_TOGGLE_MUTE,                                AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName, TAG);                    }                } catch (Exception e) {                    Log.e(TAG, "Error dispatching mute in dispatchTvAudioEvent.", e);                }                break;        }    }frameworks\base\services\core\java\com\android\server\audio\AudioService.java       /** @see AudioManager#adjustVolume(int, int) */    public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,            String callingPackage, String caller) {        adjustSuggestedStreamVolume(direction, suggestedStreamType, flags, callingPackage,                caller, Binder.getCallingUid());    }    private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,            String callingPackage, String caller, int uid) {        mVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType,                direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)                        .append("/").append(caller).append(" uid:").append(uid).toString()));        final int streamType;        synchronized (mForceControlStreamLock) {            if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType                    + ", flags=" + flags + ", caller=" + caller                    + ", volControlStream=" + mVolumeControlStream                    + ", userSelect=" + mUserSelectedVolumeControlStream);            if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1                streamType = mVolumeControlStream;            } else {                // 获取当前StreamType类型,传入的是AudioManager.USE_DEFAULT_STREAM_TYPE                // AudioSystem.STREAM_MUSIC                final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType);                final boolean activeForReal;                if (maybeActiveStreamType == AudioSystem.STREAM_MUSIC) {                    // 判断AudioFlinger当前是否是用AudioSystem.STREAM_MUSIC                    activeForReal = isAfMusicActiveRecently(0);                } else {                    activeForReal = AudioSystem.isStreamActive(maybeActiveStreamType, 0);                }                // 获取声音类型, 就是前面getActiveStreamType得到的AudioSystem.STREAM_MUSIC                if (activeForReal || mVolumeControlStream == -1) {                    streamType = maybeActiveStreamType;                } else {                    streamType = mVolumeControlStream;                }            }        }        // 判断是否是MUTE操作        final boolean isMute = isMuteAdjust(direction);        // 判断类型是否合法        ensureValidStreamType(streamType);        final int resolvedStream = mStreamVolumeAlias[streamType];        // RING类型声音处理        // Play sounds on STREAM_RING only.        if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&                resolvedStream != AudioSystem.STREAM_RING) {            flags &= ~AudioManager.FLAG_PLAY_SOUND;        }        // 通知或者电话,显示UI,但是不进行MUTE操作        // For notifications/ring, show the ui before making any adjustments        // Don't suppress mute/unmute requests        if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)) {            direction = 0;            // 将相应的位清零            flags &= ~AudioManager.FLAG_PLAY_SOUND;            flags &= ~AudioManager.FLAG_VIBRATE;            if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");        }        adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid);    }    /** @see AudioManager#adjustStreamVolume(int, int, int) */    public void adjustStreamVolume(int streamType, int direction, int flags,            String callingPackage) {        if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {            Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without"                    + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage);            return;        }        mVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType,                direction/*val1*/, flags/*val2*/, callingPackage));        adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,                Binder.getCallingUid());    }    private void adjustStreamVolume(int streamType, int direction, int flags,            String callingPackage, String caller, int uid) {        if (mUseFixedVolume) {            return;        }        if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction                + ", flags=" + flags + ", caller=" + caller);        // 判断参数是否合法        ensureValidDirection(direction);        ensureValidStreamType(streamType);        boolean isMuteAdjust = isMuteAdjust(direction);        // 判断声音是否受MUTE影响        if (isMuteAdjust && !isStreamAffectedByMute(streamType)) {            return;        }        // use stream type alias here so that streams with same alias have the same behavior,        // including with regard to silent mode control (e.g the use of STREAM_RING below and in        // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)        // 获取声音类型的别名        int streamTypeAlias = mStreamVolumeAlias[streamType];        VolumeStreamState streamState = mStreamStates[streamTypeAlias];        // 获取声音对应的device        final int device = getDeviceForStream(streamTypeAlias);        int aliasIndex = streamState.getIndex(device);        boolean adjustVolume = true;        int step;        // 跳过蓝牙请求,如果对应的设备不是蓝牙        // 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) {            return;        }        // 获取UID        // 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) {            uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));        }        if (mAppOps.noteOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage)                != AppOpsManager.MODE_ALLOWED) {            return;        }        // reset any pending volume command        synchronized (mSafeMediaVolumeState) {            mPendingVolumeCommand = null;        }        flags &= ~AudioManager.FLAG_FIXED_VOLUME;        if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) &&               ((device & mFixedVolumeDevices) != 0)) {            flags |= AudioManager.FLAG_FIXED_VOLUME;            // Always toggle between max safe volume and 0 for fixed volume devices where safe            // volume is enforced, and max and 0 for the others.            // This is simulated by stepping by the full allowed volume range            if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&                    (device & mSafeMediaVolumeDevices) != 0) {                step = safeMediaVolumeIndex(device);            } else {                step = streamState.getMaxIndex();            }            if (aliasIndex != 0) {                aliasIndex = step;            }        } else {            // 更改UI上的显示,增加/减少一格            // convert one UI step (+/-1) into a number of internal units on the stream alias            step = rescaleIndex(10, streamType, streamTypeAlias);        }        // 对与RINGER_MODES有关的声音组处理        // If either the client forces allowing ringer modes for this adjustment,        // or the stream type is one that is affected by ringer modes        if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||                (streamTypeAlias == getUiSoundsStreamType())) {            int ringerMode = getRingerModeInternal();            // do not vibrate if already in vibrate mode            if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {                flags &= ~AudioManager.FLAG_VIBRATE;            }            // Check if the ringer mode handles this adjustment. If it does we don't            // need to adjust the volume further.            final int result = checkForRingerModeChange(aliasIndex, direction, step,                    streamState.mIsMuted, callingPackage, flags);            adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0;            // If suppressing a volume adjustment in silent mode, display the UI hint            if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {                flags |= AudioManager.FLAG_SHOW_SILENT_HINT;            }            // If suppressing a volume down adjustment in vibrate mode, display the UI hint            if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {                flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT;            }        }        // If the ringermode is suppressing media, prevent changes        if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {            adjustVolume = false;        }        int oldIndex = mStreamStates[streamType].getIndex(device);        if (adjustVolume && (direction != AudioManager.ADJUST_SAME)) {            mAudioHandler.removeMessages(MSG_UNMUTE_STREAM);            // 判断是否要更新蓝牙的音量            // Check if volume update should be send to AVRCP            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.adjustAvrcpAbsoluteVolume(direction);                    }                }            }            if (isMuteAdjust) {                boolean state;                if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {                    state = !streamState.mIsMuted;                } else {                    state = direction == AudioManager.ADJUST_MUTE;                }                if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {                    setSystemAudioMute(state);                }                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);                        }                    }                }            } else if ((direction == AudioManager.ADJUST_RAISE) &&                    !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {                Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex);                mVolumeController.postDisplaySafeVolumeWarning(flags);            } else if (streamState.adjustIndex(direction * step, device, caller)                    || streamState.mIsMuted) {                // Post message to set system volume (it in turn will post a                // message to persist).                if (streamState.mIsMuted) {                    // 静音的情况下先unmute设备                    // Unmute the stream if it was previously muted                    if (direction == AudioManager.ADJUST_RAISE) {                        // unmute immediately for volume up                        streamState.mute(false);                    } else if (direction == AudioManager.ADJUST_LOWER) {                        if (mIsSingleVolume) {                            sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE,                                    streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY);                        }                    }                }                // 调整声音大小,并保存声音的数据                sendMsg(mAudioHandler,                        MSG_SET_DEVICE_VOLUME,                        SENDMSG_QUEUE,                        device,                        0,                        streamState,                        0);            }            // Check if volume update should be sent to Hdmi system audio.            int newIndex = mStreamStates[streamType].getIndex(device);            if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {                setSystemAudioVolume(oldIndex, newIndex, getStreamMaxVolume(streamType), flags);            }            if (mHdmiManager != null) {                synchronized (mHdmiManager) {                    // mHdmiCecSink true => mHdmiPlaybackClient != null                    if (mHdmiCecSink &&                            streamTypeAlias == AudioSystem.STREAM_MUSIC &&                            oldIndex != newIndex) {                        synchronized (mHdmiPlaybackClient) {                            int keyCode = (direction == -1) ? KeyEvent.KEYCODE_VOLUME_DOWN :                                    KeyEvent.KEYCODE_VOLUME_UP;                            final long ident = Binder.clearCallingIdentity();                            try {                                mHdmiPlaybackClient.sendKeyEvent(keyCode, true);                                mHdmiPlaybackClient.sendKeyEvent(keyCode, false);                            } finally {                                Binder.restoreCallingIdentity(ident);                            }                        }                    }                }            }        }        int index = mStreamStates[streamType].getIndex(device);        sendVolumeUpdate(streamType, oldIndex, index, flags);       //更新UI显示     }    frameworks\base\services\core\java\com\android\server\audio\AudioService.java     private class AudioHandler extends Handler {                  @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case MSG_SET_DEVICE_VOLUME:                    setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1);                    break;                case MSG_SET_ALL_VOLUMES:                    setAllVolumes((VolumeStreamState) msg.obj);                    break;                case MSG_PERSIST_VOLUME:                    persistVolume((VolumeStreamState) msg.obj, msg.arg1);                    break;                case MSG_PERSIST_RINGER_MODE:                    // 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                    persistRingerMode(getRingerModeInternal());                    break;                           private void setDeviceVolume(VolumeStreamState streamState, int device) {            synchronized (VolumeStreamState.class) {                // Apply volume                streamState.applyDeviceVolume_syncVSS(device);              // 将声音的数据写到底层                // Apply change to all streams using this one as alias                int numStreamTypes = AudioSystem.getNumStreamTypes();                for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {                    if (streamType != streamState.mStreamType &&                            mStreamVolumeAlias[streamType] == streamState.mStreamType) {                        // Make sure volume is also maxed out on A2DP device for aliased stream                        // that may have a different device selected                        int streamDevice = getDeviceForStream(streamType);                        if ((device != streamDevice) && mAvrcpAbsVolSupported &&                                ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) {                            mStreamStates[streamType].applyDeviceVolume_syncVSS(device);                        }                        mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);                    }                }            }            // Post a persist volume msg            sendMsg(mAudioHandler,                    MSG_PERSIST_VOLUME,                    SENDMSG_QUEUE,                    device,                    0,                    streamState,                    PERSIST_DELAY);        }                  private void persistVolume(VolumeStreamState streamState, int device) {            if (mUseFixedVolume) {                return;            }            if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) {                return;            }            if (streamState.hasValidSettingsName()) {                // 将参数保存                System.putIntForUser(mContentResolver,                        streamState.getSettingNameForDevice(device),                        (streamState.getIndex(device) + 5)/ 10,                        UserHandle.USER_CURRENT);            }        }

更多相关文章

  1. Android聊天软件开发(基于网易云IM即时通讯)——注册账号(二)
  2. Android中网络判断
  3. android: content URI的真实路径获取
  4. Android(安卓)- 开发常用工具类Utils
  5. Android(安卓)各种音量的获取和设置
  6. Android(安卓)重新获取验证码 倒计时
  7. Android获取移动设备的IP地址
  8. android 获取sd卡根目录
  9. Android(安卓)搜索不到蓝牙设备

随机推荐

  1. android 4.0 sdk直接下载地址
  2. Android下基于XML的Graphics shape使用方
  3. dev android project from cmd
  4. android技术开发例子,解析以及源码集锦
  5. andoid sys bug 转载
  6. Meteor 的 Android(安卓)支持
  7. Android多媒体应用——ImageSwitcher
  8. Android中自定义属性的使用
  9. Android系列之Android(安卓)命令行手动编
  10. 自定义android RadioPreference组件