Loading media/java/android/media/AudioManager.java +86 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_AUDIO; import static android.content.Context.DEVICE_ID_DEFAULT; import static android.media.audio.Flags.autoPublicVolumeApiHardening; import static android.media.audio.Flags.automaticBtDeviceType; import static android.media.audio.Flags.cacheGetStreamMinMaxVolume; import static android.media.audio.Flags.FLAG_DEPRECATE_STREAM_BT_SCO; import static android.media.audio.Flags.FLAG_FOCUS_EXCLUSIVE_WITH_RECORDING; import static android.media.audio.Flags.FLAG_FOCUS_FREEZE_TEST_API; Loading Loading @@ -58,7 +59,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.media.AudioAttributes.AttributeSystemUsage; import android.media.AudioDeviceInfo; import android.media.CallbackUtil.ListenerInfo; import android.media.audiopolicy.AudioPolicy; import android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener; Loading @@ -75,6 +75,7 @@ import android.os.Binder; import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.IpcDataCache; import android.os.Looper; import android.os.Message; import android.os.RemoteException; Loading Loading @@ -1230,6 +1231,84 @@ public class AudioManager { } } /** * API string for caching the min volume for each stream * @hide **/ public static final String VOLUME_MIN_CACHING_API = "getStreamMinVolume"; /** * API string for caching the max volume for each stream * @hide **/ public static final String VOLUME_MAX_CACHING_API = "getStreamMaxVolume"; private static final int VOLUME_MIN_MAX_CACHING_SIZE = 16; private final IpcDataCache.QueryHandler<VolumeCacheQuery, Integer> mVolQuery = new IpcDataCache.QueryHandler<>() { @Override public Integer apply(VolumeCacheQuery query) { final IAudioService service = getService(); try { return switch (query.queryCommand) { case QUERY_VOL_MIN -> service.getStreamMinVolume(query.stream); case QUERY_VOL_MAX -> service.getStreamMaxVolume(query.stream); default -> { Log.w(TAG, "Not a valid volume cache query: " + query); yield null; } }; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } }; private final IpcDataCache<VolumeCacheQuery, Integer> mVolMinCache = new IpcDataCache<>(VOLUME_MIN_MAX_CACHING_SIZE, IpcDataCache.MODULE_SYSTEM, VOLUME_MIN_CACHING_API, VOLUME_MIN_CACHING_API, mVolQuery); private final IpcDataCache<VolumeCacheQuery, Integer> mVolMaxCache = new IpcDataCache<>(VOLUME_MIN_MAX_CACHING_SIZE, IpcDataCache.MODULE_SYSTEM, VOLUME_MAX_CACHING_API, VOLUME_MAX_CACHING_API, mVolQuery); /** * Used to invalidate the cache for the given API * @hide **/ public static void clearVolumeCache(String api) { if (cacheGetStreamMinMaxVolume()) { IpcDataCache.invalidateCache(IpcDataCache.MODULE_SYSTEM, api); } } private static final int QUERY_VOL_MIN = 1; private static final int QUERY_VOL_MAX = 2; /** @hide */ @IntDef(prefix = "QUERY_VOL", value = { QUERY_VOL_MIN, QUERY_VOL_MAX} ) @Retention(RetentionPolicy.SOURCE) private @interface QueryVolCommand {} private record VolumeCacheQuery(int stream, @QueryVolCommand int queryCommand) { private String queryVolCommandToString() { return switch (queryCommand) { case QUERY_VOL_MIN -> "getStreamMinVolume"; case QUERY_VOL_MAX -> "getStreamMaxVolume"; default -> "invalid command"; }; } @NonNull @Override public String toString() { return TextUtils.formatSimple("VolumeCacheQuery(stream=%d, queryCommand=%s)", stream, queryVolCommandToString()); } } /** * Returns the maximum volume index for a particular stream. * Loading @@ -1238,6 +1317,9 @@ public class AudioManager { * @see #getStreamVolume(int) */ public int getStreamMaxVolume(int streamType) { if (cacheGetStreamMinMaxVolume()) { return mVolMaxCache.query(new VolumeCacheQuery(streamType, QUERY_VOL_MAX)); } final IAudioService service = getService(); try { return service.getStreamMaxVolume(streamType); Loading Loading @@ -1271,6 +1353,9 @@ public class AudioManager { */ @TestApi public int getStreamMinVolumeInt(int streamType) { if (cacheGetStreamMinMaxVolume()) { return mVolMinCache.query(new VolumeCacheQuery(streamType, QUERY_VOL_MIN)); } final IAudioService service = getService(); try { return service.getStreamMinVolume(streamType); Loading media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioManagerTest.java +39 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,15 @@ package com.android.audiopolicytest; import static android.media.AudioManager.STREAM_ACCESSIBILITY; import static android.media.AudioManager.STREAM_ALARM; import static android.media.AudioManager.STREAM_DTMF; import static android.media.AudioManager.STREAM_MUSIC; import static android.media.AudioManager.STREAM_NOTIFICATION; import static android.media.AudioManager.STREAM_RING; import static android.media.AudioManager.STREAM_SYSTEM; import static android.media.AudioManager.STREAM_VOICE_CALL; import static androidx.test.core.app.ApplicationProvider.getApplicationContext; import static com.android.audiopolicytest.AudioVolumeTestUtil.DEFAULT_ATTRIBUTES; Loading @@ -28,11 +37,15 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import android.content.Context; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.AudioSystem; import android.media.IAudioService; import android.media.audiopolicy.AudioProductStrategy; import android.media.audiopolicy.AudioVolumeGroup; import android.os.IBinder; import android.os.ServiceManager; import android.platform.test.annotations.Presubmit; import android.util.Log; Loading Loading @@ -206,6 +219,32 @@ public class AudioManagerTest { } } //----------------------------------------------------------------- // Test getStreamVolume consistency with AudioService //----------------------------------------------------------------- @Test public void getStreamMinMaxVolume_consistentWithAs() throws Exception { IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE); IAudioService service = IAudioService.Stub.asInterface(b); final int[] streamTypes = { STREAM_VOICE_CALL, STREAM_SYSTEM, STREAM_RING, STREAM_MUSIC, STREAM_ALARM, STREAM_NOTIFICATION, STREAM_DTMF, STREAM_ACCESSIBILITY, }; for (int streamType : streamTypes) { assertEquals(service.getStreamMinVolume(streamType), mAudioManager.getStreamMinVolume(streamType)); assertEquals(service.getStreamMaxVolume(streamType), mAudioManager.getStreamMaxVolume(streamType)); } } //----------------------------------------------------------------- // Test Volume per Attributes setter/getters //----------------------------------------------------------------- Loading services/core/java/com/android/server/audio/AudioManagerShellCommand.java +26 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,10 @@ class AudioManagerShellCommand extends ShellCommand { return setRingerMode(); case "set-volume": return setVolume(); case "get-min-volume": return getMinVolume(); case "get-max-volume": return getMaxVolume(); case "set-device-volume": return setDeviceVolume(); case "adj-mute": Loading Loading @@ -106,6 +110,10 @@ class AudioManagerShellCommand extends ShellCommand { pw.println(" Sets the Ringer mode to one of NORMAL|SILENT|VIBRATE"); pw.println(" set-volume STREAM_TYPE VOLUME_INDEX"); pw.println(" Sets the volume for STREAM_TYPE to VOLUME_INDEX"); pw.println(" get-min-volume STREAM_TYPE"); pw.println(" Gets the min volume for STREAM_TYPE"); pw.println(" get-max-volume STREAM_TYPE"); pw.println(" Gets the max volume for STREAM_TYPE"); pw.println(" set-device-volume STREAM_TYPE VOLUME_INDEX NATIVE_DEVICE_TYPE"); pw.println(" Sets for NATIVE_DEVICE_TYPE the STREAM_TYPE volume to VOLUME_INDEX"); pw.println(" adj-mute STREAM_TYPE"); Loading Loading @@ -296,6 +304,24 @@ class AudioManagerShellCommand extends ShellCommand { return 0; } private int getMinVolume() { final Context context = mService.mContext; final AudioManager am = context.getSystemService(AudioManager.class); final int stream = readIntArg(); final int result = am.getStreamMinVolume(stream); getOutPrintWriter().println("AudioManager.getStreamMinVolume(" + stream + ") -> " + result); return 0; } private int getMaxVolume() { final Context context = mService.mContext; final AudioManager am = context.getSystemService(AudioManager.class); final int stream = readIntArg(); final int result = am.getStreamMaxVolume(stream); getOutPrintWriter().println("AudioManager.getStreamMaxVolume(" + stream + ") -> " + result); return 0; } private int setDeviceVolume() { final Context context = mService.mContext; final AudioDeviceVolumeManager advm = (AudioDeviceVolumeManager) context.getSystemService( Loading services/core/java/com/android/server/audio/AudioService.java +17 −1 Original line number Diff line number Diff line Loading @@ -47,9 +47,9 @@ import static android.media.AudioManager.RINGER_MODE_NORMAL; import static android.media.AudioManager.RINGER_MODE_SILENT; import static android.media.AudioManager.RINGER_MODE_VIBRATE; import static android.media.AudioManager.STREAM_SYSTEM; import static android.media.IAudioManagerNative.HardeningType; import static android.media.audio.Flags.autoPublicVolumeApiHardening; import static android.media.audio.Flags.automaticBtDeviceType; import static android.media.audio.Flags.cacheGetStreamMinMaxVolume; import static android.media.audio.Flags.concurrentAudioRecordBypassPermission; import static android.media.audio.Flags.featureSpatialAudioHeadtrackingLowLatency; import static android.media.audio.Flags.focusFreezeTestApi; Loading Loading @@ -4976,6 +4976,8 @@ public class AudioService extends IAudioService.Stub + ringMyCar()); pw.println("\tandroid.media.audio.Flags.concurrentAudioRecordBypassPermission:" + concurrentAudioRecordBypassPermission()); pw.println("\tandroid.media.audio.Flags.cacheGetStreamMinMaxVolume:" + cacheGetStreamMinMaxVolume()); } private void dumpAudioMode(PrintWriter pw) { Loading Loading @@ -9366,6 +9368,12 @@ public class AudioService extends IAudioService.Stub mIndexMinNoPerm = mIndexMin; } } if (cacheGetStreamMinMaxVolume() && mStreamType == AudioSystem.STREAM_VOICE_CALL) { if (DEBUG_VOL) { Log.d(TAG, "Clear min volume cache from updateIndexFactors"); } AudioManager.clearVolumeCache(AudioManager.VOLUME_MIN_CACHING_API); } final int status = AudioSystem.initStreamVolume( mStreamType, indexMinVolCurve, indexMaxVolCurve); Loading Loading @@ -9403,11 +9411,19 @@ public class AudioService extends IAudioService.Stub * @param index minimum index expressed in "UI units", i.e. no 10x factor */ public void updateNoPermMinIndex(int index) { boolean changedNoPermMinIndex = cacheGetStreamMinMaxVolume() && (index * 10) != mIndexMinNoPerm; mIndexMinNoPerm = index * 10; if (mIndexMinNoPerm < mIndexMin) { Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType); mIndexMinNoPerm = mIndexMin; } if (changedNoPermMinIndex) { if (DEBUG_VOL) { Log.d(TAG, "Clear min volume cache from updateNoPermMinIndex"); } AudioManager.clearVolumeCache(AudioManager.VOLUME_MIN_CACHING_API); } } /** Loading services/tests/servicestests/src/com/android/server/audio/AbsoluteVolumeBehaviorTest.java +2 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.media.AudioManager; import android.media.AudioSystem; import android.media.IAudioDeviceVolumeDispatcher; import android.media.VolumeInfo; import android.os.IpcDataCache; import android.os.PermissionEnforcer; import android.os.RemoteException; import android.os.test.TestLooper; Loading Loading @@ -83,6 +84,7 @@ public class AbsoluteVolumeBehaviorTest { @Before public void setUp() throws Exception { IpcDataCache.disableForTestMode(); mTestLooper = new TestLooper(); mContext = spy(ApplicationProvider.getApplicationContext()); Loading Loading
media/java/android/media/AudioManager.java +86 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_AUDIO; import static android.content.Context.DEVICE_ID_DEFAULT; import static android.media.audio.Flags.autoPublicVolumeApiHardening; import static android.media.audio.Flags.automaticBtDeviceType; import static android.media.audio.Flags.cacheGetStreamMinMaxVolume; import static android.media.audio.Flags.FLAG_DEPRECATE_STREAM_BT_SCO; import static android.media.audio.Flags.FLAG_FOCUS_EXCLUSIVE_WITH_RECORDING; import static android.media.audio.Flags.FLAG_FOCUS_FREEZE_TEST_API; Loading Loading @@ -58,7 +59,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.media.AudioAttributes.AttributeSystemUsage; import android.media.AudioDeviceInfo; import android.media.CallbackUtil.ListenerInfo; import android.media.audiopolicy.AudioPolicy; import android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener; Loading @@ -75,6 +75,7 @@ import android.os.Binder; import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.IpcDataCache; import android.os.Looper; import android.os.Message; import android.os.RemoteException; Loading Loading @@ -1230,6 +1231,84 @@ public class AudioManager { } } /** * API string for caching the min volume for each stream * @hide **/ public static final String VOLUME_MIN_CACHING_API = "getStreamMinVolume"; /** * API string for caching the max volume for each stream * @hide **/ public static final String VOLUME_MAX_CACHING_API = "getStreamMaxVolume"; private static final int VOLUME_MIN_MAX_CACHING_SIZE = 16; private final IpcDataCache.QueryHandler<VolumeCacheQuery, Integer> mVolQuery = new IpcDataCache.QueryHandler<>() { @Override public Integer apply(VolumeCacheQuery query) { final IAudioService service = getService(); try { return switch (query.queryCommand) { case QUERY_VOL_MIN -> service.getStreamMinVolume(query.stream); case QUERY_VOL_MAX -> service.getStreamMaxVolume(query.stream); default -> { Log.w(TAG, "Not a valid volume cache query: " + query); yield null; } }; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } }; private final IpcDataCache<VolumeCacheQuery, Integer> mVolMinCache = new IpcDataCache<>(VOLUME_MIN_MAX_CACHING_SIZE, IpcDataCache.MODULE_SYSTEM, VOLUME_MIN_CACHING_API, VOLUME_MIN_CACHING_API, mVolQuery); private final IpcDataCache<VolumeCacheQuery, Integer> mVolMaxCache = new IpcDataCache<>(VOLUME_MIN_MAX_CACHING_SIZE, IpcDataCache.MODULE_SYSTEM, VOLUME_MAX_CACHING_API, VOLUME_MAX_CACHING_API, mVolQuery); /** * Used to invalidate the cache for the given API * @hide **/ public static void clearVolumeCache(String api) { if (cacheGetStreamMinMaxVolume()) { IpcDataCache.invalidateCache(IpcDataCache.MODULE_SYSTEM, api); } } private static final int QUERY_VOL_MIN = 1; private static final int QUERY_VOL_MAX = 2; /** @hide */ @IntDef(prefix = "QUERY_VOL", value = { QUERY_VOL_MIN, QUERY_VOL_MAX} ) @Retention(RetentionPolicy.SOURCE) private @interface QueryVolCommand {} private record VolumeCacheQuery(int stream, @QueryVolCommand int queryCommand) { private String queryVolCommandToString() { return switch (queryCommand) { case QUERY_VOL_MIN -> "getStreamMinVolume"; case QUERY_VOL_MAX -> "getStreamMaxVolume"; default -> "invalid command"; }; } @NonNull @Override public String toString() { return TextUtils.formatSimple("VolumeCacheQuery(stream=%d, queryCommand=%s)", stream, queryVolCommandToString()); } } /** * Returns the maximum volume index for a particular stream. * Loading @@ -1238,6 +1317,9 @@ public class AudioManager { * @see #getStreamVolume(int) */ public int getStreamMaxVolume(int streamType) { if (cacheGetStreamMinMaxVolume()) { return mVolMaxCache.query(new VolumeCacheQuery(streamType, QUERY_VOL_MAX)); } final IAudioService service = getService(); try { return service.getStreamMaxVolume(streamType); Loading Loading @@ -1271,6 +1353,9 @@ public class AudioManager { */ @TestApi public int getStreamMinVolumeInt(int streamType) { if (cacheGetStreamMinMaxVolume()) { return mVolMinCache.query(new VolumeCacheQuery(streamType, QUERY_VOL_MIN)); } final IAudioService service = getService(); try { return service.getStreamMinVolume(streamType); Loading
media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioManagerTest.java +39 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,15 @@ package com.android.audiopolicytest; import static android.media.AudioManager.STREAM_ACCESSIBILITY; import static android.media.AudioManager.STREAM_ALARM; import static android.media.AudioManager.STREAM_DTMF; import static android.media.AudioManager.STREAM_MUSIC; import static android.media.AudioManager.STREAM_NOTIFICATION; import static android.media.AudioManager.STREAM_RING; import static android.media.AudioManager.STREAM_SYSTEM; import static android.media.AudioManager.STREAM_VOICE_CALL; import static androidx.test.core.app.ApplicationProvider.getApplicationContext; import static com.android.audiopolicytest.AudioVolumeTestUtil.DEFAULT_ATTRIBUTES; Loading @@ -28,11 +37,15 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import android.content.Context; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.AudioSystem; import android.media.IAudioService; import android.media.audiopolicy.AudioProductStrategy; import android.media.audiopolicy.AudioVolumeGroup; import android.os.IBinder; import android.os.ServiceManager; import android.platform.test.annotations.Presubmit; import android.util.Log; Loading Loading @@ -206,6 +219,32 @@ public class AudioManagerTest { } } //----------------------------------------------------------------- // Test getStreamVolume consistency with AudioService //----------------------------------------------------------------- @Test public void getStreamMinMaxVolume_consistentWithAs() throws Exception { IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE); IAudioService service = IAudioService.Stub.asInterface(b); final int[] streamTypes = { STREAM_VOICE_CALL, STREAM_SYSTEM, STREAM_RING, STREAM_MUSIC, STREAM_ALARM, STREAM_NOTIFICATION, STREAM_DTMF, STREAM_ACCESSIBILITY, }; for (int streamType : streamTypes) { assertEquals(service.getStreamMinVolume(streamType), mAudioManager.getStreamMinVolume(streamType)); assertEquals(service.getStreamMaxVolume(streamType), mAudioManager.getStreamMaxVolume(streamType)); } } //----------------------------------------------------------------- // Test Volume per Attributes setter/getters //----------------------------------------------------------------- Loading
services/core/java/com/android/server/audio/AudioManagerShellCommand.java +26 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,10 @@ class AudioManagerShellCommand extends ShellCommand { return setRingerMode(); case "set-volume": return setVolume(); case "get-min-volume": return getMinVolume(); case "get-max-volume": return getMaxVolume(); case "set-device-volume": return setDeviceVolume(); case "adj-mute": Loading Loading @@ -106,6 +110,10 @@ class AudioManagerShellCommand extends ShellCommand { pw.println(" Sets the Ringer mode to one of NORMAL|SILENT|VIBRATE"); pw.println(" set-volume STREAM_TYPE VOLUME_INDEX"); pw.println(" Sets the volume for STREAM_TYPE to VOLUME_INDEX"); pw.println(" get-min-volume STREAM_TYPE"); pw.println(" Gets the min volume for STREAM_TYPE"); pw.println(" get-max-volume STREAM_TYPE"); pw.println(" Gets the max volume for STREAM_TYPE"); pw.println(" set-device-volume STREAM_TYPE VOLUME_INDEX NATIVE_DEVICE_TYPE"); pw.println(" Sets for NATIVE_DEVICE_TYPE the STREAM_TYPE volume to VOLUME_INDEX"); pw.println(" adj-mute STREAM_TYPE"); Loading Loading @@ -296,6 +304,24 @@ class AudioManagerShellCommand extends ShellCommand { return 0; } private int getMinVolume() { final Context context = mService.mContext; final AudioManager am = context.getSystemService(AudioManager.class); final int stream = readIntArg(); final int result = am.getStreamMinVolume(stream); getOutPrintWriter().println("AudioManager.getStreamMinVolume(" + stream + ") -> " + result); return 0; } private int getMaxVolume() { final Context context = mService.mContext; final AudioManager am = context.getSystemService(AudioManager.class); final int stream = readIntArg(); final int result = am.getStreamMaxVolume(stream); getOutPrintWriter().println("AudioManager.getStreamMaxVolume(" + stream + ") -> " + result); return 0; } private int setDeviceVolume() { final Context context = mService.mContext; final AudioDeviceVolumeManager advm = (AudioDeviceVolumeManager) context.getSystemService( Loading
services/core/java/com/android/server/audio/AudioService.java +17 −1 Original line number Diff line number Diff line Loading @@ -47,9 +47,9 @@ import static android.media.AudioManager.RINGER_MODE_NORMAL; import static android.media.AudioManager.RINGER_MODE_SILENT; import static android.media.AudioManager.RINGER_MODE_VIBRATE; import static android.media.AudioManager.STREAM_SYSTEM; import static android.media.IAudioManagerNative.HardeningType; import static android.media.audio.Flags.autoPublicVolumeApiHardening; import static android.media.audio.Flags.automaticBtDeviceType; import static android.media.audio.Flags.cacheGetStreamMinMaxVolume; import static android.media.audio.Flags.concurrentAudioRecordBypassPermission; import static android.media.audio.Flags.featureSpatialAudioHeadtrackingLowLatency; import static android.media.audio.Flags.focusFreezeTestApi; Loading Loading @@ -4976,6 +4976,8 @@ public class AudioService extends IAudioService.Stub + ringMyCar()); pw.println("\tandroid.media.audio.Flags.concurrentAudioRecordBypassPermission:" + concurrentAudioRecordBypassPermission()); pw.println("\tandroid.media.audio.Flags.cacheGetStreamMinMaxVolume:" + cacheGetStreamMinMaxVolume()); } private void dumpAudioMode(PrintWriter pw) { Loading Loading @@ -9366,6 +9368,12 @@ public class AudioService extends IAudioService.Stub mIndexMinNoPerm = mIndexMin; } } if (cacheGetStreamMinMaxVolume() && mStreamType == AudioSystem.STREAM_VOICE_CALL) { if (DEBUG_VOL) { Log.d(TAG, "Clear min volume cache from updateIndexFactors"); } AudioManager.clearVolumeCache(AudioManager.VOLUME_MIN_CACHING_API); } final int status = AudioSystem.initStreamVolume( mStreamType, indexMinVolCurve, indexMaxVolCurve); Loading Loading @@ -9403,11 +9411,19 @@ public class AudioService extends IAudioService.Stub * @param index minimum index expressed in "UI units", i.e. no 10x factor */ public void updateNoPermMinIndex(int index) { boolean changedNoPermMinIndex = cacheGetStreamMinMaxVolume() && (index * 10) != mIndexMinNoPerm; mIndexMinNoPerm = index * 10; if (mIndexMinNoPerm < mIndexMin) { Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType); mIndexMinNoPerm = mIndexMin; } if (changedNoPermMinIndex) { if (DEBUG_VOL) { Log.d(TAG, "Clear min volume cache from updateNoPermMinIndex"); } AudioManager.clearVolumeCache(AudioManager.VOLUME_MIN_CACHING_API); } } /** Loading
services/tests/servicestests/src/com/android/server/audio/AbsoluteVolumeBehaviorTest.java +2 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.media.AudioManager; import android.media.AudioSystem; import android.media.IAudioDeviceVolumeDispatcher; import android.media.VolumeInfo; import android.os.IpcDataCache; import android.os.PermissionEnforcer; import android.os.RemoteException; import android.os.test.TestLooper; Loading Loading @@ -83,6 +84,7 @@ public class AbsoluteVolumeBehaviorTest { @Before public void setUp() throws Exception { IpcDataCache.disableForTestMode(); mTestLooper = new TestLooper(); mContext = spy(ApplicationProvider.getApplicationContext()); Loading