/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.media2.player;

import static androidx.media2.common.SessionPlayer.PLAYER_STATE_PAUSED;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.os.Build;
import android.util.Log;

import androidx.annotation.DoNotInline;
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.media.AudioAttributesCompat;

/**
 * Handles audio focus and noisy intent depending on the {@link AudioAttributesCompat}.
 * <p>
 * This follows our developer's guideline, and does nothing if the audio attribute hasn't set.
 *
 * @see {@docRoot}guide/topics/media-apps/audio-app/mediasession-callbacks.html
 * @see {@docRoot}guide/topics/media-apps/video-app/mediasession-callbacks.html
 * @see {@docRoot}guide/topics/media-apps/audio-focus.html
 * @see {@docRoot}guide/topics/media-apps/volume-and-earphones.html
 */
/* package */ class AudioFocusHandler {
    private static final String TAG = "AudioFocusHandler";
    private static final boolean DEBUG = true;

    interface AudioFocusHandlerImpl {
        boolean onPlay();
        void onPause();
        void onReset();
        void close();
        void sendIntent(Intent intent);
    }

    private final AudioFocusHandlerImpl mImpl;

    AudioFocusHandler(Context context, MediaPlayer player) {
        mImpl = new AudioFocusHandlerImplBase(context, player);
    }

    /**
     * Should be called when the {@link MediaPlayer#play()} is called. Returns whether the play()
     * can be proceed.
     *
     * @return {@code true} if it's OK to start playback because audio focus was successfully
     * granted or audio focus isn't needed for starting playback. {@code false} otherwise.
     * (i.e. Audio focus is needed for starting playback but failed)
     */
    public boolean onPlay() {
        return mImpl.onPlay();
    }

    /**
     * Called when the {@link MediaPlayer#pause()} is called.
     */
    public void onPause() {
        mImpl.onPause();
    }

    /**
     * Called when the {@link MediaPlayer#reset()} is called.
     */
    public void onReset() {
        mImpl.onReset();
    }

    /**
     * Closes this resource, relinquishing any underlying resources.
     */
    public void close() {
        mImpl.close();
    }

    /**
     * Testing purpose.
     *
     * @param intent
     */
    public void sendIntent(Intent intent) {
        mImpl.sendIntent(intent);
    }

    private static class AudioFocusHandlerImplBase implements AudioFocusHandlerImpl {
        // Value is from the {@link AudioFocusRequest} as follows
        // 'A typical attenuation by the “ducked” application is a factor of 0.2f (or -14dB), that
        // can for instance be applied with MediaPlayer.setVolume(0.2f) when using this class for
        // playback.'
        private static final float VOLUME_DUCK_FACTOR = 0.2f;
        private final BroadcastReceiver mBecomingNoisyReceiver = new BecomingNoisyReceiver();
        private final IntentFilter mIntentFilter =
                new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
        private final OnAudioFocusChangeListener mAudioFocusListener = new AudioFocusListener();
        final Object mLock = new Object();
        private final Context mContext;
        final MediaPlayer mPlayer;
        private final AudioManager mAudioManager;

        @GuardedBy("mLock")
        AudioAttributesCompat mAudioAttributes;
        @GuardedBy("mLock")
        private int mCurrentFocusGainType;
        @GuardedBy("mLock")
        boolean mResumeWhenAudioFocusGain;
        @GuardedBy("mLock")
        boolean mBecomingNoisyReceiverRegistered;

        AudioFocusHandlerImplBase(Context context, MediaPlayer player) {
            mContext = context;
            mPlayer = player;

            // Cannot use session.getContext() because session's impl isn't initialized at this
            // moment.
            mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        }

        @Override
        public boolean onPlay() {
            final AudioAttributesCompat attrs = mPlayer.getAudioAttributes();
            boolean result = true;
            synchronized (mLock) {
                mAudioAttributes = attrs;
                // Checks whether the audio attributes is {@code null}, to check indirectly whether
                // the media item has audio track.
                if (attrs == null) {
                    // No sound.
                    abandonAudioFocusLocked();
                    unregisterBecomingNoisyReceiverLocked();
                } else {
                    result = requestAudioFocusLocked();
                    if (result) {
                        registerBecomingNoisyReceiverLocked();
                    }
                }
            }
            return result;
        }

        @Override
        public void onPause() {
            synchronized (mLock) {
                mResumeWhenAudioFocusGain = false;
                unregisterBecomingNoisyReceiverLocked();
            }
        }

        @Override
        public void onReset() {
            synchronized (mLock) {
                abandonAudioFocusLocked();
                unregisterBecomingNoisyReceiverLocked();
            }
        }

        @Override
        public void close() {
            synchronized (mLock) {
                unregisterBecomingNoisyReceiverLocked();
                abandonAudioFocusLocked();
            }
        }

        @Override
        public void sendIntent(Intent intent) {
            mBecomingNoisyReceiver.onReceive(mContext, intent);
        }

        /**
         * Requests audio focus. This may regain audio focus.
         *
         * @return {@code true} if audio focus is granted or isn't needed.
         *         {@code false} only when the attempt to request audio focus was failed.
         */
        @GuardedBy("mLock")
        private boolean requestAudioFocusLocked() {
            int focusGain = convertAudioAttributesToFocusGain(mAudioAttributes);
            if (focusGain == AudioManager.AUDIOFOCUS_NONE) {
                if (mAudioAttributes == null && DEBUG) {
                    // If audio attributes is null, it should be handled outside to set volume
                    // to zero without holding an lock.
                    Log.e(TAG, "requestAudioFocusLocked() shouldn't be called when AudioAttributes"
                            + " is null");
                }
                return true;
            }
            // Note: This API is deprecated from the API level 26, but there's not much reason to
            // use the new API for now.
            int audioFocusRequestResult = mAudioManager.requestAudioFocus(mAudioFocusListener,
                    mAudioAttributes.getVolumeControlStream(), focusGain);
            if (audioFocusRequestResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                mCurrentFocusGainType = focusGain;
            } else {
                Log.w(TAG, "requestAudioFocus(" + focusGain + ") failed (return="
                        + audioFocusRequestResult + ") playback wouldn't start.");
                mCurrentFocusGainType = AudioManager.AUDIOFOCUS_NONE;
            }
            if (DEBUG) {
                Log.d(TAG, "requestAudioFocus(" + focusGain + "), result="
                        + (audioFocusRequestResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED));
            }
            mResumeWhenAudioFocusGain = false;
            return mCurrentFocusGainType != AudioManager.AUDIOFOCUS_NONE;
        }

        /**
         * Abandons audio focus if it has granted.
         */
        @GuardedBy("mLock")
        private void abandonAudioFocusLocked() {
            if (mCurrentFocusGainType == AudioManager.AUDIOFOCUS_NONE) {
                return;
            }
            if (DEBUG) {
                Log.d(TAG, "abandoningAudioFocusLocked, currently=" + mCurrentFocusGainType);
            }
            mAudioManager.abandonAudioFocus(mAudioFocusListener);
            mCurrentFocusGainType = AudioManager.AUDIOFOCUS_NONE;
            mResumeWhenAudioFocusGain = false;
        }

        @GuardedBy("mLock")
        private void registerBecomingNoisyReceiverLocked() {
            if (mBecomingNoisyReceiverRegistered) {
                return;
            }
            if (DEBUG) {
                Log.d(TAG, "registering becoming noisy receiver");
            }
            // Registering the receiver multiple-times may not be allowed for newer platform.
            // Register only when it's not registered.
            if (Build.VERSION.SDK_INT < 33) {
                mContext.registerReceiver(mBecomingNoisyReceiver, mIntentFilter);
            } else {
                Api33.registerReceiver(mContext, mBecomingNoisyReceiver, mIntentFilter,
                        Context.RECEIVER_NOT_EXPORTED);
            }
            mBecomingNoisyReceiverRegistered = true;
        }

        @GuardedBy("mLock")
        private void unregisterBecomingNoisyReceiverLocked() {
            if (!mBecomingNoisyReceiverRegistered) {
                return;
            }
            if (DEBUG) {
                Log.d(TAG, "unregistering becoming noisy receiver");
            }
            mContext.unregisterReceiver(mBecomingNoisyReceiver);
            mBecomingNoisyReceiverRegistered = false;
        }

        // Converts {@link AudioAttributesCompat} to one of the audio focus request. This follows
        // the class Javadoc of {@link AudioFocusRequest}.
        // Note: Any change here should also reflects public Javadoc of {@link MediaSession}.
        private static int convertAudioAttributesToFocusGain(
                final AudioAttributesCompat audioAttributesCompat) {

            if (audioAttributesCompat == null) {
                // Don't handle audio focus. It may be either video only contents or developers
                // want to have more finer grained control. (e.g. adding audio focus listener)
                return AudioManager.AUDIOFOCUS_NONE;
            }
            // Javadoc here means 'The different types of focus requests' written in the
            // {@link AudioFocusRequest}.
            switch (audioAttributesCompat.getUsage()) {
                // USAGE_VOICE_COMMUNICATION_SIGNALLING is for DTMF that may happen multiple times
                // during the phone call when AUDIOFOCUS_GAIN_TRANSIENT is requested for that.
                // Don't request audio focus here.
                case AudioAttributesCompat.USAGE_VOICE_COMMUNICATION_SIGNALLING:
                    return AudioManager.AUDIOFOCUS_NONE;

                // Javadoc says 'AUDIOFOCUS_GAIN: Examples of uses of this focus gain are for music
                // playback, for a game or a video player'
                case AudioAttributesCompat.USAGE_GAME:
                case AudioAttributesCompat.USAGE_MEDIA:
                    return AudioManager.AUDIOFOCUS_GAIN;

                // Special usages: USAGE_UNKNOWN shouldn't be used. Request audio focus to prevent
                // multiple media playback happen at the same time.
                case AudioAttributesCompat.USAGE_UNKNOWN:
                    Log.w(TAG, "Specify a proper usage in the audio attributes for audio focus"
                            + " handling. Using AUDIOFOCUS_GAIN by default.");
                    return AudioManager.AUDIOFOCUS_GAIN;

                // Javadoc says 'AUDIOFOCUS_GAIN_TRANSIENT: An example is for playing an alarm, or
                // during a VoIP call'
                case AudioAttributesCompat.USAGE_ALARM:
                case AudioAttributesCompat.USAGE_VOICE_COMMUNICATION:
                    return AudioManager.AUDIOFOCUS_GAIN_TRANSIENT;

                // Javadoc says 'AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK: Examples are when playing
                // driving directions or notifications'
                case AudioAttributesCompat.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
                case AudioAttributesCompat.USAGE_ASSISTANCE_SONIFICATION:
                case AudioAttributesCompat.USAGE_NOTIFICATION:
                case AudioAttributesCompat.USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
                case AudioAttributesCompat.USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
                case AudioAttributesCompat.USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
                case AudioAttributesCompat.USAGE_NOTIFICATION_EVENT:
                case AudioAttributesCompat.USAGE_NOTIFICATION_RINGTONE:
                    return AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK;

                // Javadoc says 'AUDIOFOCUS_GAIN_EXCLUSIVE: This is typically used if you are doing
                // audio recording or speech recognition'.
                // Assistant is considered as both recording and notifying developer
                case AudioAttributesCompat.USAGE_ASSISTANT:
                    return AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE;

                // Special usages:
                case AudioAttributesCompat.USAGE_ASSISTANCE_ACCESSIBILITY:
                    if (audioAttributesCompat.getContentType()
                            == AudioAttributesCompat.CONTENT_TYPE_SPEECH) {
                        // Voice shouldn't be interrupted by other playback.
                        return AudioManager.AUDIOFOCUS_GAIN_TRANSIENT;
                    }
                    return AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK;
            }
            Log.w(TAG, "Unidentified AudioAttribute " + audioAttributesCompat);
            return AudioManager.AUDIOFOCUS_NONE;
        }

        private class BecomingNoisyReceiver extends BroadcastReceiver {
            BecomingNoisyReceiver() {
            }

            // Note: This is always the main thread, except for the test.
            @SuppressWarnings("FutureReturnValueIgnored")
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
                    return;
                }
                final int usage;
                synchronized (mLock) {
                    if (DEBUG) {
                        Log.d(TAG, "Received noisy intent, intent=" + intent + ", registered="
                                + mBecomingNoisyReceiverRegistered + ", attr=" + mAudioAttributes);
                    }
                    if (!mBecomingNoisyReceiverRegistered || mAudioAttributes == null) {
                        return;
                    }
                    usage = mAudioAttributes.getUsage();
                }
                switch (usage) {
                    case AudioAttributesCompat.USAGE_MEDIA:
                        // Noisy intent guide says 'In the case of music players, users
                        // typically expect the playback to be paused.'
                        mPlayer.pause();
                        break;
                    case AudioAttributesCompat.USAGE_GAME:
                        // Noisy intent guide says 'For gaming apps, you may choose to
                        // significantly lower the volume instead'.
                        mPlayer.setPlayerVolume(mPlayer.getPlayerVolume() * VOLUME_DUCK_FACTOR);
                        break;
                    default:
                        // Noisy intent guide didn't say anything more for this. No-op for now.
                        break;
                }
            }
        }

        private class AudioFocusListener implements OnAudioFocusChangeListener {
            private float mPlayerVolumeBeforeDucking;
            private float mPlayerDuckingVolume;

            AudioFocusListener() {
            }

            // This is the thread where the AudioManager was originally instantiated.
            // see: b/78617702
            @SuppressWarnings("FutureReturnValueIgnored")
            @Override
            public void onAudioFocusChange(int focusGain) {
                switch (focusGain) {
                    case AudioManager.AUDIOFOCUS_GAIN:
                        // Regains focus after the LOSS_TRANSIENT or LOSS_TRANSIENT_CAN_DUCK.
                        if (mPlayer.getPlayerState() == PLAYER_STATE_PAUSED) {
                            // Note: onPlay() will be called again with this.
                            synchronized (mLock) {
                                if (!mResumeWhenAudioFocusGain) {
                                    break;
                                }
                            }
                            mPlayer.play();
                        } else {
                            // Resets the volume if the user didn't change it.
                            final float currentVolume = mPlayer.getPlayerVolume();
                            final float volumeBeforeDucking;
                            synchronized (mLock) {
                                if (currentVolume != mPlayerDuckingVolume) {
                                    // User manually changed the volume meanwhile. Don't reset.
                                    break;
                                }
                                volumeBeforeDucking = mPlayerVolumeBeforeDucking;
                            }
                            mPlayer.setPlayerVolume(volumeBeforeDucking);
                        }
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS:
                        // Audio-focus developer guide says 'Your app should pause playback
                        // immediately, as it won't ever receive an AUDIOFOCUS_GAIN callback'.
                        mPlayer.pause();
                        // Don't resume even after you regain the audio focus.
                        synchronized (mLock) {
                            mResumeWhenAudioFocusGain = false;
                        }
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                        final boolean pause;
                        synchronized (mLock) {
                            if (mAudioAttributes == null) {
                                // This shouldn't happen. Just ignoring for now.
                                break;
                            }
                            pause = (mAudioAttributes.getContentType()
                                    == AudioAttributesCompat.CONTENT_TYPE_SPEECH);
                        }
                        if (pause) {
                            mPlayer.pause();
                        } else {
                            // Lower the volume by the factor
                            final float currentVolume = mPlayer.getPlayerVolume();
                            final float duckingVolume = currentVolume * VOLUME_DUCK_FACTOR;
                            synchronized (mLock) {
                                mPlayerVolumeBeforeDucking = currentVolume;
                                mPlayerDuckingVolume = duckingVolume;
                            }
                            mPlayer.setPlayerVolume(duckingVolume);
                        }
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                        mPlayer.pause();
                        // Resume after regaining the audio focus.
                        synchronized (mLock) {
                            mResumeWhenAudioFocusGain = true;
                        }
                        break;
                }
            }
        }
    }

    @RequiresApi(33)
    private static class Api33 {
        @DoNotInline
        static void registerReceiver(@NonNull Context context, @NonNull BroadcastReceiver receiver,
                @NonNull IntentFilter filter, int flags) {
            context.registerReceiver(receiver, filter, flags);
        }
    }
}
