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

Commit 5f061b52 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "APC-stop-projection" into qt-dev

* changes:
  Unregister policy on projection stop
  Do not ignore audio policy register errors
parents 803c0528 724b0263
Loading
Loading
Loading
Loading
+67 −17
Original line number Original line Diff line number Diff line
@@ -96,6 +96,7 @@ import android.media.audiopolicy.AudioProductStrategy;
import android.media.audiopolicy.AudioVolumeGroup;
import android.media.audiopolicy.AudioVolumeGroup;
import android.media.audiopolicy.IAudioPolicyCallback;
import android.media.audiopolicy.IAudioPolicyCallback;
import android.media.projection.IMediaProjection;
import android.media.projection.IMediaProjection;
import android.media.projection.IMediaProjectionCallback;
import android.media.projection.IMediaProjectionManager;
import android.media.projection.IMediaProjectionManager;
import android.net.Uri;
import android.net.Uri;
import android.os.Binder;
import android.os.Binder;
@@ -6705,13 +6706,13 @@ public class AudioService extends IAudioService.Stub


        String regId = null;
        String regId = null;
        synchronized (mAudioPolicies) {
        synchronized (mAudioPolicies) {
            try {
            if (mAudioPolicies.containsKey(pcb.asBinder())) {
            if (mAudioPolicies.containsKey(pcb.asBinder())) {
                Slog.e(TAG, "Cannot re-register policy");
                Slog.e(TAG, "Cannot re-register policy");
                return null;
                return null;
            }
            }
            try {
                AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener,
                AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener,
                        isFocusPolicy, isTestFocusPolicy, isVolumeController);
                        isFocusPolicy, isTestFocusPolicy, isVolumeController, projection);
                pcb.asBinder().linkToDeath(app, 0/*flags*/);
                pcb.asBinder().linkToDeath(app, 0/*flags*/);
                regId = app.getRegistrationId();
                regId = app.getRegistrationId();
                mAudioPolicies.put(pcb.asBinder(), app);
                mAudioPolicies.put(pcb.asBinder(), app);
@@ -6720,6 +6721,9 @@ public class AudioService extends IAudioService.Stub
                Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb +
                Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb +
                        " binder death", e);
                        " binder death", e);
                return null;
                return null;
            } catch (IllegalStateException e) {
                Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e);
                return null;
            }
            }
        }
        }
        return regId;
        return regId;
@@ -6884,9 +6888,9 @@ public class AudioService extends IAudioService.Stub
            if (app == null){
            if (app == null){
                return AudioManager.ERROR;
                return AudioManager.ERROR;
            }
            }
            app.addMixes(policyConfig.getMixes());
            return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
                ? AudioManager.SUCCESS : AudioManager.ERROR;
        }
        }
        return AudioManager.SUCCESS;
    }
    }


    public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
    public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
@@ -6898,9 +6902,9 @@ public class AudioService extends IAudioService.Stub
            if (app == null) {
            if (app == null) {
                return AudioManager.ERROR;
                return AudioManager.ERROR;
            }
            }
            app.removeMixes(policyConfig.getMixes());
            return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
                ? AudioManager.SUCCESS : AudioManager.ERROR;
        }
        }
        return AudioManager.SUCCESS;
    }
    }


    /** see AudioPolicy.setUidDeviceAffinity() */
    /** see AudioPolicy.setUidDeviceAffinity() */
@@ -7165,6 +7169,15 @@ public class AudioService extends IAudioService.Stub
        final boolean mIsVolumeController;
        final boolean mIsVolumeController;
        final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities =
        final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities =
                new HashMap<Integer, AudioDeviceArray>();
                new HashMap<Integer, AudioDeviceArray>();

        final IMediaProjection mProjection;
        private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub {
            public void onStop() {
                unregisterAudioPolicyAsync(mPolicyCallback);
            }
        };
        UnregisterOnStopCallback mProjectionCallback;

        /**
        /**
         * Audio focus ducking behavior for an audio policy.
         * Audio focus ducking behavior for an audio policy.
         * This variable reflects the value that was successfully set in
         * This variable reflects the value that was successfully set in
@@ -7178,12 +7191,13 @@ public class AudioService extends IAudioService.Stub


        AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token,
        AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token,
                boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
                boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
                boolean isVolumeController) {
                boolean isVolumeController, IMediaProjection projection) {
            super(config);
            super(config);
            setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++));
            setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++));
            mPolicyCallback = token;
            mPolicyCallback = token;
            mHasFocusListener = hasFocusListener;
            mHasFocusListener = hasFocusListener;
            mIsVolumeController = isVolumeController;
            mIsVolumeController = isVolumeController;
            mProjection = projection;
            if (mHasFocusListener) {
            if (mHasFocusListener) {
                mMediaFocusControl.addFocusFollower(mPolicyCallback);
                mMediaFocusControl.addFocusFollower(mPolicyCallback);
                // can only ever be true if there is a focus listener
                // can only ever be true if there is a focus listener
@@ -7196,7 +7210,21 @@ public class AudioService extends IAudioService.Stub
            if (mIsVolumeController) {
            if (mIsVolumeController) {
                setExtVolumeController(mPolicyCallback);
                setExtVolumeController(mPolicyCallback);
            }
            }
            connectMixes();
            if (mProjection != null) {
                mProjectionCallback = new UnregisterOnStopCallback();
                try {
                    mProjection.registerCallback(mProjectionCallback);
                } catch (RemoteException e) {
                    release();
                    throw new IllegalStateException("MediaProjection callback registration failed, "
                            + "could not link to " + projection + " binder death", e);
                }
            }
            int status = connectMixes();
            if (status != AudioSystem.SUCCESS) {
                release();
                throw new IllegalStateException("Could not connect mix, error: " + status);
            }
        }
        }


        public void binderDied() {
        public void binderDied() {
@@ -7226,6 +7254,13 @@ public class AudioService extends IAudioService.Stub
            if (mHasFocusListener) {
            if (mHasFocusListener) {
                mMediaFocusControl.removeFocusFollower(mPolicyCallback);
                mMediaFocusControl.removeFocusFollower(mPolicyCallback);
            }
            }
            if (mProjectionCallback != null) {
                try {
                    mProjection.unregisterCallback(mProjectionCallback);
                } catch (RemoteException e) {
                    Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection");
                }
            }
            final long identity = Binder.clearCallingIdentity();
            final long identity = Binder.clearCallingIdentity();
            AudioSystem.registerPolicyMixes(mMixes, false);
            AudioSystem.registerPolicyMixes(mMixes, false);
            Binder.restoreCallingIdentity(identity);
            Binder.restoreCallingIdentity(identity);
@@ -7260,28 +7295,29 @@ public class AudioService extends IAudioService.Stub
            return true;
            return true;
        }
        }


        void addMixes(@NonNull ArrayList<AudioMix> mixes) {
        int addMixes(@NonNull ArrayList<AudioMix> mixes) {
            // TODO optimize to not have to unregister the mixes already in place
            // TODO optimize to not have to unregister the mixes already in place
            synchronized (mMixes) {
            synchronized (mMixes) {
                AudioSystem.registerPolicyMixes(mMixes, false);
                AudioSystem.registerPolicyMixes(mMixes, false);
                this.add(mixes);
                this.add(mixes);
                AudioSystem.registerPolicyMixes(mMixes, true);
                return AudioSystem.registerPolicyMixes(mMixes, true);
            }
            }
        }
        }


        void removeMixes(@NonNull ArrayList<AudioMix> mixes) {
        int removeMixes(@NonNull ArrayList<AudioMix> mixes) {
            // TODO optimize to not have to unregister the mixes already in place
            // TODO optimize to not have to unregister the mixes already in place
            synchronized (mMixes) {
            synchronized (mMixes) {
                AudioSystem.registerPolicyMixes(mMixes, false);
                AudioSystem.registerPolicyMixes(mMixes, false);
                this.remove(mixes);
                this.remove(mixes);
                AudioSystem.registerPolicyMixes(mMixes, true);
                return AudioSystem.registerPolicyMixes(mMixes, true);
            }
            }
        }
        }


        void connectMixes() {
        int connectMixes() {
            final long identity = Binder.clearCallingIdentity();
            final long identity = Binder.clearCallingIdentity();
            AudioSystem.registerPolicyMixes(mMixes, true);
            int status = AudioSystem.registerPolicyMixes(mMixes, true);
            Binder.restoreCallingIdentity(identity);
            Binder.restoreCallingIdentity(identity);
            return status;
        }
        }


        int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) {
        int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) {
@@ -7320,6 +7356,20 @@ public class AudioService extends IAudioService.Stub
            Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed");
            Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed");
            return AudioManager.ERROR;
            return AudioManager.ERROR;
        }
        }

        /** @return human readable debug informations summarizing the state of the object. */
        public String toLogFriendlyString() {
            String textDump = super.toLogFriendlyString();
            textDump += " Proxy:\n";
            textDump += "   is focus policy= " + mIsFocusPolicy + "\n";
            if (mIsFocusPolicy) {
                textDump += "     focus duck behaviour= " + mFocusDuckBehavior + "\n";
                textDump += "     is test focus policy= " + mIsTestFocusPolicy + "\n";
                textDump += "     has focus listener= " + mHasFocusListener  + "\n";
            }
            textDump += "   media projection= " + mProjection + "\n";
            return textDump;
        }
    };
    };


    //======================
    //======================