安卓源码音量调节服务分析
记一次设置音量调节的源码分析:
调节音量一般在设置里面,于是找到了设置页面的源码:SettingsActivity
@VisibleForTesting void launchSettingFragment(String initialFragmentName, Intent intent) { if (initialFragmentName != null) { setTitleFromIntent(intent); Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS); switchToFragment(initialFragmentName, initialArguments, true, mInitialTitleResId, mInitialTitle); } else { // Show search icon as up affordance if we are displaying the main Dashboard mInitialTitleResId = R.string.dashboard_title; switchToFragment(TopLevelSettings.class.getName(), null /* args */, false, mInitialTitleResId, mInitialTitle); } }
然后进入到TopLevelSettings
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider(R.xml.top_level_settings) { @Override protected boolean isPageSearchEnabled(Context context) { // Never searchable, all entries in this page are already indexed elsewhere. return false; } };
再进入top_level_settings
<Preference android:key="top_level_sound" android:title="@string/sound_settings" android:summary="@string/sound_dashboard_summary" android:icon="@drawable/ic_homepage_sound" android:order="-70" android:fragment="com.android.settings.notification.SoundSettings"/>
进入SoundSettings
@Override protected int getPreferenceScreenResId() { return R.xml.sound_settings; }
进入sound_settings
<!-- Ring volume --> <com.android.settings.notification.VolumeSeekBarPreference android:key="ring_volume" android:icon="@drawable/ic_notifications" android:title="@string/ring_volume_option_title" android:order="-160" settings:controller="com.android.settings.notification.RingVolumePreferenceController"/>
进入RingVolumePreferenceController
private void updateRingerMode() { final int ringerMode = mHelper.getRingerModeInternal(); if (mRingerMode == ringerMode) return; mRingerMode = ringerMode; updatePreferenceIcon(); }
进入AudioHelper
public int getRingerModeInternal() { return mAudioManager.getRingerModeInternal(); }
进入frameworks/base/media/java/android/media/AudioManager
@UnsupportedAppUsage public int getRingerModeInternal() { try { return getService().getRingerModeInternal(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
进入getService方法
@UnsupportedAppUsage private static IAudioService getService() { if (sService != null) { return sService; } IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE); sService = IAudioService.Stub.asInterface(b); return sService; }
进入frameworks/base/media/java/android/media/IAudioService.aidl
int getRingerModeInternal();
进入frameworks/base/services/core/java/com/android/servicer/audio/AudioService
public class AudioService extends IAudioService.Stub implements AccessibilityManager.TouchExplorationStateChangeListener, AccessibilityManager.AccessibilityServicesStateChangeListener {
进入方法getRingerModeInternal
@Override public int getRingerModeInternal() { synchronized(mSettingsLock) { return mRingerMode; } } 可以看到音量的调节是有这个mRingerMode来控制 private void readPersistedSettings() { if (!mSystemServer.isPrivileged()) { return; } final ContentResolver cr = mContentResolver; int ringerModeFromSettings = Settings.Global.getInt( cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL); int ringerMode = ringerModeFromSettings; // sanity check in case the settings are restored from a device with incompatible // ringer modes if (!isValidRingerMode(ringerMode)) { ringerMode = AudioManager.RINGER_MODE_NORMAL; } if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { ringerMode = AudioManager.RINGER_MODE_SILENT; } if (ringerMode != ringerModeFromSettings) { Settings.Global.putInt(cr, Settings.Global.MODE_RINGER, ringerMode); } if (mUseFixedVolume || mIsSingleVolume) { ringerMode = AudioManager.RINGER_MODE_NORMAL; } synchronized(mSettingsLock) { mRingerMode = ringerMode; if (mRingerModeExternal == -1) { mRingerModeExternal = mRingerMode; }
参考网上资料
找到frameworks/media/java/android/media/AudioManager
public void adjustStreamVolume(int streamType, int direction, int flags) { final IAudioService service = getService(); try { service.adjustStreamVolume(streamType, direction, flags, getContext().getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
进入frameworks/base/services/core/java/com/android/servicer/audio/AudioService
protected void adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, boolean hasModifyAudioSettings, int keyEventMode) { 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); if (isMuteAdjust && !isStreamAffectedByMute(streamType)) { return; }