Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4654f18 authored by Hugh Chen's avatar Hugh Chen
Browse files

Add 0.5 second delay to set stream or play volume ringtone

If get Ring/Alarm/Media stream volume right after stop call volume,
it will return the volume of the earpiece then cause UI incorrect.
It is because the call volume is from the earpiece and the
alarm/ring/media is from the speaker.
This CL adds 0.5 second delay when play volume or set stream
to avoid get wrong volume.

- Add onStartTrackingTouch() callback to stop the ringtone when
  another seek bar is adjusted.
- Add 0.5 second delay to set stream or play volume ringtone.

Bug: 80194851
Test: build, adjust call volume then immediately adjust ring volume
Change-Id: I06c5e84af60f0d77daffabb4a22644f43a9cf54d
parent afd954f3
Loading
Loading
Loading
Loading
+46 −5
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@ import android.widget.SeekBar.OnSeekBarChangeListener;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.SomeArgs;

import java.util.concurrent.TimeUnit;

/**
 * Turns a {@link SeekBar} into a volume control.
 * @hide
@@ -64,9 +66,15 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
        void onSampleStarting(SeekBarVolumizer sbv);
        void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch);
        void onMuted(boolean muted, boolean zenMuted);
        /**
         * Callback reporting that the seek bar is start tracking.
         * @param sbv - The seek bar that start tracking
         */
        void onStartTrackingTouch(SeekBarVolumizer sbv);
    }

    private static final int MSG_GROUP_VOLUME_CHANGED = 1;
    private static long sStopVolumeTime = 0L;
    private final Handler mVolumeHandler = new VolumeHandler();
    private AudioAttributes mAttributes;
    private int mVolumeGroupId;
@@ -126,6 +134,9 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
    private static final int MSG_STOP_SAMPLE = 2;
    private static final int MSG_INIT_SAMPLE = 3;
    private static final int CHECK_RINGTONE_PLAYBACK_DELAY_MS = 1000;
    private static final long SET_STREAM_VOLUME_DELAY_MS = TimeUnit.MILLISECONDS.toMillis(500);
    private static final long START_SAMPLE_DELAY_MS = TimeUnit.MILLISECONDS.toMillis(500);
    private static final long DURATION_TO_START_DELAYING = TimeUnit.MILLISECONDS.toMillis(2000);

    private NotificationManager.Policy mNotificationPolicy;
    private boolean mAllowAlarms;
@@ -314,7 +325,29 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
        if (mHandler == null) return;
        mHandler.removeMessages(MSG_START_SAMPLE);
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_SAMPLE),
                isSamplePlaying() ? CHECK_RINGTONE_PLAYBACK_DELAY_MS : 0);
                isSamplePlaying() ? CHECK_RINGTONE_PLAYBACK_DELAY_MS
                        : isDelay() ? START_SAMPLE_DELAY_MS : 0);
    }

    // After stop volume it needs to add a small delay when playing volume or set stream.
    // It is because the call volume is from the earpiece and the alarm/ring/media
    // is from the speaker. If play the alarm volume or set alarm stream right after stop
    // call volume, the alarm volume on earpiece is returned then cause the volume value incorrect.
    // It needs a small delay after stop call volume to get alarm volume on speaker.
    // e.g. : If the ring volume has adjusted right after call volume stopped in 2 second
    // then delay 0.5 second to set stream or play volume ringtone.
    private boolean isDelay() {
        final long durationTime = java.lang.System.currentTimeMillis() - sStopVolumeTime;
        return durationTime >= 0 && durationTime < DURATION_TO_START_DELAYING;
    }

    private void setStopVolumeTime() {
        // set the time of stop volume
        if ((mStreamType == AudioManager.STREAM_VOICE_CALL
                || mStreamType == AudioManager.STREAM_RING
                || mStreamType == AudioManager.STREAM_ALARM)) {
            sStopVolumeTime = java.lang.System.currentTimeMillis();
        }
    }

    private void onStartSample() {
@@ -341,6 +374,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba

    private void postStopSample() {
        if (mHandler == null) return;
        setStopVolumeTime();
        // remove pending delayed start messages
        mHandler.removeMessages(MSG_START_SAMPLE);
        mHandler.removeMessages(MSG_STOP_SAMPLE);
@@ -404,10 +438,15 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
        // Do the volume changing separately to give responsive UI
        mLastProgress = progress;
        mHandler.removeMessages(MSG_SET_STREAM_VOLUME);
        mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_STREAM_VOLUME));
        mHandler.removeMessages(MSG_START_SAMPLE);
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SET_STREAM_VOLUME),
                isDelay() ? SET_STREAM_VOLUME_DELAY_MS : 0);
    }

    public void onStartTrackingTouch(SeekBar seekBar) {
        if (mCallback != null) {
            mCallback.onStartTrackingTouch(this);
        }
    }

    public void onStopTrackingTouch(SeekBar seekBar) {
@@ -539,7 +578,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
            if (AudioManager.VOLUME_CHANGED_ACTION.equals(action)) {
                int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
                int streamValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
                if (hasAudioProductStrategies()) {
                if (hasAudioProductStrategies() && !isDelay()) {
                    updateVolumeSlider(streamType, streamValue);
                }
            } else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
@@ -551,7 +590,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
                }
            } else if (AudioManager.STREAM_DEVICES_CHANGED_ACTION.equals(action)) {
                int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
                if (hasAudioProductStrategies()) {
                if (hasAudioProductStrategies() && !isDelay()) {
                    int streamVolume = mAudioManager.getStreamVolume(streamType);
                    updateVolumeSlider(streamType, streamVolume);
                } else {
@@ -559,9 +598,11 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
                    if (volumeGroup != AudioVolumeGroup.DEFAULT_VOLUME_GROUP
                            && volumeGroup == mVolumeGroupId) {
                        int streamVolume = mAudioManager.getStreamVolume(streamType);
                        if (!isDelay()) {
                            updateVolumeSlider(streamType, streamVolume);
                        }
                    }
                }
            } else if (NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED.equals(action)) {
                mZenMode = mNotificationManager.getZenMode();
                updateSlider();
+5 −0
Original line number Diff line number Diff line
@@ -175,6 +175,11 @@ public class VolumePreference extends SeekBarDialogPreference implements
        // noop
    }

    @Override
    public void onStartTrackingTouch(SeekBarVolumizer sbv) {
        // noop
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        final Parcelable superState = super.onSaveInstanceState();