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

Commit 45c90cef authored by Eric Laurent's avatar Eric Laurent
Browse files

Fix AudioManager.forceVolumeControlStream()

AudioManager.forceVolumeControlStream() is used by VolumePanel to temporarily force the
stream type which volume is controlled by volume keys.

Current implementation is not working if the VolumePanel is not executed by the same process
as the one receiving the volume key events.

Issue 6302421.

Change-Id: I2700587a027ffb962429b42083312cd92fe79215
parent 1b8f499a
Loading
Loading
Loading
Loading
+6 −17
Original line number Diff line number Diff line
@@ -47,7 +47,6 @@ public class AudioManager {

    private final Context mContext;
    private long mVolumeKeyUpTime;
    private int  mVolumeControlStream = -1;
    private final boolean mUseMasterVolume;
    private static String TAG = "AudioManager";

@@ -303,13 +302,6 @@ public class AudioManager {
     */
    public static final int FLAG_VIBRATE = 1 << 4;

    /**
     * forces use of specified stream
     * @hide
     */
    public static final int FLAG_FORCE_STREAM = 1 << 5;


    /**
     * Ringer mode that will be silent and will not vibrate. (This overrides the
     * vibrate setting.)
@@ -458,10 +450,6 @@ public class AudioManager {
                                    : ADJUST_LOWER,
                            flags);
                } else {
                    if (mVolumeControlStream != -1) {
                        stream = mVolumeControlStream;
                        flags |= FLAG_FORCE_STREAM;
                    }
                    adjustSuggestedStreamVolume(
                            keyCode == KeyEvent.KEYCODE_VOLUME_UP
                                    ? ADJUST_RAISE
@@ -500,10 +488,6 @@ public class AudioManager {
                    }
                } else {
                    int flags = FLAG_PLAY_SOUND;
                    if (mVolumeControlStream != -1) {
                        stream = mVolumeControlStream;
                        flags |= FLAG_FORCE_STREAM;
                    }
                    adjustSuggestedStreamVolume(
                            ADJUST_SAME,
                            stream,
@@ -943,7 +927,12 @@ public class AudioManager {
     * @hide
     */
    public void forceVolumeControlStream(int streamType) {
        mVolumeControlStream = streamType;
        IAudioService service = getService();
        try {
            service.forceVolumeControlStream(streamType, mICallBack);
        } catch (RemoteException e) {
            Log.e(TAG, "Dead object in forceVolumeControlStream", e);
        }
    }

    /**
+62 −2
Original line number Diff line number Diff line
@@ -149,6 +149,7 @@ public class AudioService extends IAudioService.Stub {
    private int mMode;
    // protects mRingerMode
    private final Object mSettingsLock = new Object();

    private boolean mMediaServerOk;

    private SoundPool mSoundPool;
@@ -343,6 +344,14 @@ public class AudioService extends IAudioService.Stub {
    // Keyguard manager proxy
    private KeyguardManager mKeyguardManager;

    // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume
    // is controlled by Vol keys.
    private int  mVolumeControlStream = -1;
    private final Object mForceControlStreamLock = new Object();
    // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system
    // server process so in theory it is not necessary to monitor the client death.
    // However it is good to be ready for future evolutions.
    private ForceControlStreamClient mForceControlStreamClient = null;

    ///////////////////////////////////////////////////////////////////////////
    // Construction
@@ -538,8 +547,8 @@ public class AudioService extends IAudioService.Stub {
    public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) {

        int streamType;
        if ((flags & AudioManager.FLAG_FORCE_STREAM) != 0) {
            streamType = suggestedStreamType;
        if (mVolumeControlStream != -1) {
            streamType = mVolumeControlStream;
        } else {
            streamType = getActiveStreamType(suggestedStreamType);
        }
@@ -682,6 +691,57 @@ public class AudioService extends IAudioService.Stub {
        sendVolumeUpdate(streamType, oldIndex, index, flags);
    }

    /** @see AudioManager#forceVolumeControlStream(int) */
    public void forceVolumeControlStream(int streamType, IBinder cb) {
        synchronized(mForceControlStreamLock) {
            mVolumeControlStream = streamType;
            if (mVolumeControlStream == -1) {
                if (mForceControlStreamClient != null) {
                    mForceControlStreamClient.release();
                    mForceControlStreamClient = null;
                }
            } else {
                mForceControlStreamClient = new ForceControlStreamClient(cb);
            }
        }
    }

    private class ForceControlStreamClient implements IBinder.DeathRecipient {
        private IBinder mCb; // To be notified of client's death

        ForceControlStreamClient(IBinder cb) {
            if (cb != null) {
                try {
                    cb.linkToDeath(this, 0);
                } catch (RemoteException e) {
                    // Client has died!
                    Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death");
                    cb = null;
                }
            }
            mCb = cb;
        }

        public void binderDied() {
            synchronized(mForceControlStreamLock) {
                Log.w(TAG, "SCO client died");
                if (mForceControlStreamClient != this) {
                    Log.w(TAG, "unregistered control stream client died");
                } else {
                    mForceControlStreamClient = null;
                    mVolumeControlStream = -1;
                }
            }
        }

        public void release() {
            if (mCb != null) {
                mCb.unlinkToDeath(this, 0);
                mCb = null;
            }
        }
    }

    private int findVolumeDelta(int direction, int volume) {
        int delta = 0;
        if (direction == AudioManager.ADJUST_RAISE) {
+2 −0
Original line number Diff line number Diff line
@@ -115,4 +115,6 @@ interface IAudioService {
    void startBluetoothSco(IBinder cb);

    void stopBluetoothSco(IBinder cb);

    void forceVolumeControlStream(int streamType, IBinder cb);
}