@@ -501,6 +501,24 @@ private void waitForAudioHandlerCreation() {
501501 }
502502 }
503503
504+ private void checkAllAliasStreamVolumes () {
505+ int numStreamTypes = AudioSystem .getNumStreamTypes ();
506+ for (int streamType = 0 ; streamType < numStreamTypes ; streamType ++) {
507+ if (streamType != mStreamVolumeAlias [streamType ]) {
508+ mStreamStates [streamType ].
509+ setAllIndexes (mStreamStates [mStreamVolumeAlias [streamType ]],
510+ false /*lastAudible*/ );
511+ mStreamStates [streamType ].
512+ setAllIndexes (mStreamStates [mStreamVolumeAlias [streamType ]],
513+ true /*lastAudible*/ );
514+ }
515+ // apply stream volume
516+ if (mStreamStates [streamType ].muteCount () == 0 ) {
517+ mStreamStates [streamType ].applyAllVolumes ();
518+ }
519+ }
520+ }
521+
504522 private void createStreamStates () {
505523 int numStreamTypes = AudioSystem .getNumStreamTypes ();
506524 VolumeStreamState [] streams = mStreamStates = new VolumeStreamState [numStreamTypes ];
@@ -509,23 +527,7 @@ private void createStreamStates() {
509527 streams [i ] = new VolumeStreamState (System .VOLUME_SETTINGS [mStreamVolumeAlias [i ]], i );
510528 }
511529
512- // Correct stream index values for streams with aliases
513- for (int i = 0 ; i < numStreamTypes ; i ++) {
514- int device = getDeviceForStream (i );
515- if (mStreamVolumeAlias [i ] != i ) {
516- int index = rescaleIndex (streams [i ].getIndex (device , false /* lastAudible */ ),
517- mStreamVolumeAlias [i ],
518- i );
519- synchronized (streams [i ]) {
520- streams [i ].mIndex .put (device , streams [i ].getValidIndex (index ));
521- streams [i ].applyDeviceVolume (device );
522- index = rescaleIndex (streams [i ].getIndex (device , true /* lastAudible */ ),
523- mStreamVolumeAlias [i ],
524- i );
525- streams [i ].mLastAudibleIndex .put (device , streams [i ].getValidIndex (index ));
526- }
527- }
528- }
530+ checkAllAliasStreamVolumes ();
529531 }
530532
531533 private void dumpStreamStates (PrintWriter pw ) {
@@ -679,10 +681,13 @@ public void adjustStreamVolume(int streamType, int direction, int flags) {
679681
680682 final int device = getDeviceForStream (streamTypeAlias );
681683 // get last audible index if stream is muted, current index otherwise
682- final int oldIndex = streamState .getIndex (device ,
684+ final int aliasIndex = streamState .getIndex (device ,
683685 (streamState .muteCount () != 0 ) /* lastAudible */ );
684686 boolean adjustVolume = true ;
685687
688+ // convert one UI step (+/-1) into a number of internal units on the stream alias
689+ int step = rescaleIndex (10 , streamType , streamTypeAlias );
690+
686691 // If either the client forces allowing ringer modes for this adjustment,
687692 // or the stream type is one that is affected by ringer modes
688693 if (((flags & AudioManager .FLAG_ALLOW_RINGER_MODES ) != 0 ) ||
@@ -694,35 +699,30 @@ public void adjustStreamVolume(int streamType, int direction, int flags) {
694699 }
695700 // Check if the ringer mode changes with this volume adjustment. If
696701 // it does, it will handle adjusting the volume, so we won't below
697- adjustVolume = checkForRingerModeChange (oldIndex , direction );
702+ adjustVolume = checkForRingerModeChange (aliasIndex , direction , step );
698703 }
699704
700705 // If stream is muted, adjust last audible index only
701706 int index ;
707+ final int oldIndex = mStreamStates [streamType ].getIndex (device ,
708+ (mStreamStates [streamType ].muteCount () != 0 ) /* lastAudible */ );
709+
702710 if (streamState .muteCount () != 0 ) {
703711 if (adjustVolume ) {
704- // adjust volume on all stream types sharing the same alias otherwise a query
705- // on last audible index for an alias would not give the correct value
706- int numStreamTypes = AudioSystem .getNumStreamTypes ();
707- for (int i = numStreamTypes - 1 ; i >= 0 ; i --) {
708- if (mStreamVolumeAlias [i ] == streamTypeAlias ) {
709- VolumeStreamState s = mStreamStates [i ];
710-
711- s .adjustLastAudibleIndex (direction , device );
712- // Post a persist volume msg
713- sendMsg (mAudioHandler ,
714- MSG_PERSIST_VOLUME ,
715- SENDMSG_QUEUE ,
716- PERSIST_LAST_AUDIBLE ,
717- device ,
718- s ,
719- PERSIST_DELAY );
720- }
721- }
712+ // Post a persist volume msg
713+ // no need to persist volume on all streams sharing the same alias
714+ streamState .adjustLastAudibleIndex (direction * step , device );
715+ sendMsg (mAudioHandler ,
716+ MSG_PERSIST_VOLUME ,
717+ SENDMSG_QUEUE ,
718+ PERSIST_LAST_AUDIBLE ,
719+ device ,
720+ streamState ,
721+ PERSIST_DELAY );
722722 }
723- index = streamState .getIndex (device , true /* lastAudible */ );
723+ index = mStreamStates [ streamType ] .getIndex (device , true /* lastAudible */ );
724724 } else {
725- if (adjustVolume && streamState .adjustIndex (direction , device )) {
725+ if (adjustVolume && streamState .adjustIndex (direction * step , device )) {
726726 // Post message to set system volume (it in turn will post a message
727727 // to persist). Do not change volume if stream is muted.
728728 sendMsg (mAudioHandler ,
@@ -733,7 +733,7 @@ public void adjustStreamVolume(int streamType, int direction, int flags) {
733733 streamState ,
734734 0 );
735735 }
736- index = streamState .getIndex (device , false /* lastAudible */ );
736+ index = mStreamStates [ streamType ] .getIndex (device , false /* lastAudible */ );
737737 }
738738
739739 sendVolumeUpdate (streamType , oldIndex , index , flags );
@@ -765,6 +765,8 @@ public void setStreamVolume(int streamType, int index, int flags) {
765765 final int oldIndex = streamState .getIndex (device ,
766766 (streamState .muteCount () != 0 ) /* lastAudible */ );
767767
768+ index = rescaleIndex (index * 10 , streamType , mStreamVolumeAlias [streamType ]);
769+
768770 // setting volume on master stream type also controls silent mode
769771 if (((flags & AudioManager .FLAG_ALLOW_RINGER_MODES ) != 0 ) ||
770772 (mStreamVolumeAlias [streamType ] == getMasterStreamType ())) {
@@ -783,11 +785,10 @@ public void setStreamVolume(int streamType, int index, int flags) {
783785 setRingerMode (newRingerMode );
784786 }
785787
786- index = rescaleIndex (index * 10 , streamType , mStreamVolumeAlias [streamType ]);
787788 setStreamVolumeInt (mStreamVolumeAlias [streamType ], index , device , false , true );
788789 // get last audible index if stream is muted, current index otherwise
789- index = streamState .getIndex (device ,
790- ( streamState .muteCount () != 0 ) /* lastAudible */ );
790+ index = mStreamStates [ streamType ] .getIndex (device ,
791+ ( mStreamStates [ streamType ] .muteCount () != 0 ) /* lastAudible */ );
791792
792793 sendVolumeUpdate (streamType , oldIndex , index , flags );
793794 }
@@ -1089,7 +1090,9 @@ private void ensureValidRingerMode(int ringerMode) {
10891090
10901091 /** @see AudioManager#setRingerMode(int) */
10911092 public void setRingerMode (int ringerMode ) {
1092- ensureValidRingerMode (ringerMode );
1093+ if ((ringerMode == AudioManager .RINGER_MODE_VIBRATE ) && !mHasVibrator ) {
1094+ ringerMode = AudioManager .RINGER_MODE_SILENT ;
1095+ }
10931096 if (ringerMode != getRingerMode ()) {
10941097 setRingerModeInt (ringerMode , true );
10951098 // Send sticky broadcast
@@ -1599,13 +1602,11 @@ public void reloadAudioSettings() {
15991602 streamState .mDeathHandlers .get (i ).mute (false );
16001603 }
16011604 }
1602- // apply stream volume
1603- if (streamState .muteCount () == 0 ) {
1604- streamState .applyAllVolumes ();
1605- }
16061605 }
16071606 }
16081607
1608+ checkAllAliasStreamVolumes ();
1609+
16091610 // apply new ringer mode
16101611 setRingerModeInt (getRingerMode (), false );
16111612 }
@@ -2015,20 +2016,25 @@ public void onServiceDisconnected(int profile) {
20152016 * adjusting volume. If so, this will set the proper ringer mode and volume
20162017 * indices on the stream states.
20172018 */
2018- private boolean checkForRingerModeChange (int oldIndex , int direction ) {
2019+ private boolean checkForRingerModeChange (int oldIndex , int direction , int step ) {
20192020 boolean adjustVolumeIndex = true ;
20202021 int ringerMode = getRingerMode ();
2021- int uiIndex = (oldIndex + 5 ) / 10 ;
20222022
20232023 switch (ringerMode ) {
20242024 case RINGER_MODE_NORMAL :
20252025 if (direction == AudioManager .ADJUST_LOWER ) {
20262026 if (mHasVibrator ) {
2027- if (uiIndex == 1 ) {
2027+ // "step" is the delta in internal index units corresponding to a
2028+ // change of 1 in UI index units.
2029+ // Because of rounding when rescaling from one stream index range to its alias
2030+ // index range, we cannot simply test oldIndex == step:
2031+ // (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1)
2032+ if (step <= oldIndex && oldIndex < 2 * step ) {
20282033 ringerMode = RINGER_MODE_VIBRATE ;
20292034 }
20302035 } else {
2031- if (uiIndex == 0 && mPrevVolDirection != AudioManager .ADJUST_LOWER ) {
2036+ // (oldIndex < step) is equivalent to (old UI index == 0)
2037+ if ((oldIndex < step ) && mPrevVolDirection != AudioManager .ADJUST_LOWER ) {
20322038 ringerMode = RINGER_MODE_SILENT ;
20332039 }
20342040 }
@@ -2257,8 +2263,6 @@ private VolumeStreamState(String settingName, int streamType) {
22572263
22582264 readSettings ();
22592265
2260- applyAllVolumes ();
2261-
22622266 mDeathHandlers = new ArrayList <VolumeDeathHandler >();
22632267 }
22642268
@@ -2369,7 +2373,7 @@ public synchronized void applyAllVolumes() {
23692373
23702374 public boolean adjustIndex (int deltaIndex , int device ) {
23712375 return setIndex (getIndex (device ,
2372- false /* lastAudible */ ) + deltaIndex * 10 ,
2376+ false /* lastAudible */ ) + deltaIndex ,
23732377 device ,
23742378 true /* lastAudible */ );
23752379 }
@@ -2424,12 +2428,28 @@ public synchronized int getIndex(int device, boolean lastAudible) {
24242428 }
24252429
24262430 public synchronized void setLastAudibleIndex (int index , int device ) {
2431+ // Apply change to all streams using this one as alias
2432+ // if changing volume of current device, also change volume of current
2433+ // device on aliased stream
2434+ boolean currentDevice = (device == getDeviceForStream (mStreamType ));
2435+ int numStreamTypes = AudioSystem .getNumStreamTypes ();
2436+ for (int streamType = numStreamTypes - 1 ; streamType >= 0 ; streamType --) {
2437+ if (streamType != mStreamType &&
2438+ mStreamVolumeAlias [streamType ] == mStreamType ) {
2439+ int scaledIndex = rescaleIndex (index , mStreamType , streamType );
2440+ mStreamStates [streamType ].setLastAudibleIndex (scaledIndex , device );
2441+ if (currentDevice ) {
2442+ mStreamStates [streamType ].setLastAudibleIndex (scaledIndex ,
2443+ getDeviceForStream (streamType ));
2444+ }
2445+ }
2446+ }
24272447 mLastAudibleIndex .put (device , getValidIndex (index ));
24282448 }
24292449
24302450 public synchronized void adjustLastAudibleIndex (int deltaIndex , int device ) {
24312451 setLastAudibleIndex (getIndex (device ,
2432- true /* lastAudible */ ) + deltaIndex * 10 ,
2452+ true /* lastAudible */ ) + deltaIndex ,
24332453 device );
24342454 }
24352455
0 commit comments