/*
 * Copyright (C) 2017 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 android.media;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.os.Handler;
import android.os.Looper;

/**
 * A class to encapsulate information about an audio focus request.
 * An {@code AudioFocusRequest} instance is built by {@link Builder}, and is used to
 * request and abandon audio focus, respectively
 * with {@link AudioManager#requestAudioFocus(AudioFocusRequest)} and
 * {@link AudioManager#abandonAudioFocusRequest(AudioFocusRequest)}.
 *
 * <h3>What is audio focus?</h3>
 * <p>Audio focus is a concept introduced in API 8. It is used to convey the fact that a user can
 * only focus on a single audio stream at a time, e.g. listening to music or a podcast, but not
 * both at the same time. In some cases, multiple audio streams can be playing at the same time,
 * but there is only one the user would really listen to (focus on), while the other plays in
 * the background. An example of this is driving directions being spoken while music plays at
 * a reduced volume (a.k.a. ducking).
 * <p>When an application requests audio focus, it expresses its intention to “own” audio focus to
 * play audio. Let’s review the different types of focus requests, the return value after a request,
 * and the responses to a loss.
 * <p class="note">Note: applications should not play anything until granted focus.</p>
 *
 * <h3>The different types of focus requests</h3>
 * <p>There are four focus request types. A successful focus request with each will yield different
 * behaviors by the system and the other application that previously held audio focus.
 * <ul>
 * <li>{@link AudioManager#AUDIOFOCUS_GAIN} expresses the fact that your application is now the
 * sole source of audio that the user is listening to. The duration of the audio playback is
 * unknown, and is possibly very long: after the user finishes interacting with your application,
 * (s)he doesn’t expect another audio stream to resume. Examples of uses of this focus gain are
 * for music playback, for a game or a video player.</li>
 *
 * <li>{@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT} is for a situation when you know your
 * application is temporarily grabbing focus from the current owner, but the user expects playback
 * to go back to where it was once your application no longer requires audio focus. An example is
 * for playing an alarm, or during a VoIP call. The playback is known to be finite: the alarm will
 * time-out or be dismissed, the VoIP call has a beginning and an end. When any of those events
 * ends, and if the user was listening to music when it started, the user expects music to resume,
 * but didn’t wish to listen to both at the same time.</li>
 *
 * <li>{@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}: this focus request type is similar
 * to {@code AUDIOFOCUS_GAIN_TRANSIENT} for the temporary aspect of the focus request, but it also
 * expresses the fact during the time you own focus, you allow another application to keep playing
 * at a reduced volume, “ducked”. Examples are when playing driving directions or notifications,
 * it’s ok for music to keep playing, but not loud enough that it would prevent the directions to
 * be hard to understand. A typical attenuation by the “ducked” application is a factor of 0.2f
 * (or -14dB), that can for instance be applied with {@code MediaPlayer.setVolume(0.2f)} when
 * using this class for playback.</li>
 *
 * <li>{@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} is also for a temporary request,
 * but also expresses that your application expects the device to not play anything else. This is
 * typically used if you are doing audio recording or speech recognition, and don’t want for
 * examples notifications to be played by the system during that time.</li>
 * </ul>
 *
 * <p>An {@code AudioFocusRequest} instance always contains one of the four types of requests
 * explained above. It is passed when building an {@code AudioFocusRequest} instance with its
 * builder in the {@link Builder} constructor
 * {@link AudioFocusRequest.Builder#AudioFocusRequest.Builder(int)}, or
 * with {@link AudioFocusRequest.Builder#setFocusGain(int)} after copying an existing instance with
 * {@link AudioFocusRequest.Builder#AudioFocusRequest.Builder(AudioFocusRequest)}.
 *
 * <h3>Qualifying your focus request</h3>
 * <h4>Use case requiring a focus request</h4>
 * <p>Any focus request is qualified by the {@link AudioAttributes}
 * (see {@link Builder#setAudioAttributes(AudioAttributes)}) that describe the audio use case that
 * will follow the request (once it's successful or granted). It is recommended to use the
 * same {@code AudioAttributes} for the request as the attributes you are using for audio/media
 * playback.
 * <br>If no attributes are set, default attributes of {@link AudioAttributes#USAGE_MEDIA} are used.
 *
 * <h4>Delayed focus</h4>
 * <p>Audio focus can be "locked" by the system for a number of reasons: during a phone call, when
 * the car to which the device is connected plays an emergency message... To support these
 * situations, the application can request to be notified when its request is fulfilled, by flagging
 * its request as accepting delayed focus, with {@link Builder#setAcceptsDelayedFocusGain(boolean)}.
 * <br>If focus is requested while being locked by the system,
 * {@link AudioManager#requestAudioFocus(AudioFocusRequest)} will return
 * {@link AudioManager#AUDIOFOCUS_REQUEST_DELAYED}. When focus isn't locked anymore, the focus
 * listener set with {@link Builder#setOnAudioFocusChangeListener(OnAudioFocusChangeListener)}
 * or with {@link Builder#setOnAudioFocusChangeListener(OnAudioFocusChangeListener, Handler)} will
 * be called to notify the application it now owns audio focus.
 *
 * <h4>Pausing vs ducking</h4>
 * <p>When an application requested audio focus with
 * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, the system will duck the current focus
 * owner.
 * <p class="note">Note: this behavior is <b>new for Android O</b>, whereas applications targeting
 * SDK level up to API 25 had to implement the ducking themselves when they received a focus
 * loss of {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}.
 * <p>But ducking is not always the behavior expected by the user. A typical example is when the
 * device plays driving directions while the user is listening to an audio book or podcast, and
 * expects the audio playback to pause, instead of duck, as it is hard to understand a navigation
 * prompt and spoken content at the same time. Therefore the system will not automatically duck
 * when it detects it would be ducking spoken content: such content is detected when the
 * {@code AudioAttributes} of the player are qualified by
 * {@link AudioAttributes#CONTENT_TYPE_SPEECH}. Refer for instance to
 * {@link AudioAttributes.Builder#setContentType(int)} and
 * {@link MediaPlayer#setAudioAttributes(AudioAttributes)} if you are writing a media playback
 * application for audio book, podcasts... Since the system will not automatically duck applications
 * that play speech, it calls their focus listener instead to notify them of
 * {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}, so they can pause instead. Note that
 * this behavior is independent of the use of {@code AudioFocusRequest}, but tied to the use
 * of {@code AudioAttributes}.
 * <p>If your application requires pausing instead of ducking for any other reason than playing
 * speech, you can also declare so with {@link Builder#setWillPauseWhenDucked(boolean)}, which will
 * cause the system to call your focus listener instead of automatically ducking.
 *
 * <h4>Example</h4>
 * <p>The example below covers the following steps to be found in any application that would play
 * audio, and use audio focus. Here we play an audio book, and our application is intended to pause
 * rather than duck when it loses focus. These steps consist in:
 * <ul>
 * <li>Creating {@code AudioAttributes} to be used for the playback and the focus request.</li>
 * <li>Configuring and creating the {@code AudioFocusRequest} instance that defines the intended
 *     focus behaviors.</li>
 * <li>Requesting audio focus and checking the return code to see if playback can happen right
 *     away, or is delayed.</li>
 * <li>Implementing a focus change listener to respond to focus gains and losses.</li>
 * </ul>
 * <p>
 * <pre class="prettyprint">
 * // initialization of the audio attributes and focus request
 * mAudioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE);
 * mPlaybackAttributes = new AudioAttributes.Builder()
 *         .setUsage(AudioAttributes.USAGE_MEDIA)
 *         .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
 *         .build();
 * mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
 *         .setAudioAttributes(mPlaybackAttributes)
 *         .setAcceptsDelayedFocusGain(true)
 *         .setWillPauseWhenDucked(true)
 *         .setOnAudioFocusChangeListener(this, mMyHandler)
 *         .build();
 * mMediaPlayer = new MediaPlayer();
 * mMediaPlayer.setAudioAttributes(mPlaybackAttributes);
 * final Object mFocusLock = new Object();
 *
 * boolean mPlaybackDelayed = false;
 *
 * // requesting audio focus
 * int res = mAudioManager.requestAudioFocus(mFocusRequest);
 * synchronized (mFocusLock) {
 *     if (res == AUDIOFOCUS_REQUEST_FAILED) {
 *         mPlaybackDelayed = false;
 *     } else if (res == AUDIOFOCUS_REQUEST_GRANTED) {
 *         mPlaybackDelayed = false;
 *         playbackNow();
 *     } else if (res == AUDIOFOCUS_REQUEST_DELAYED) {
 *        mPlaybackDelayed = true;
 *     }
 * }
 *
 * // implementation of the OnAudioFocusChangeListener
 * &#64;Override
 * public void onAudioFocusChange(int focusChange) {
 *     switch (focusChange) {
 *         case AudioManager.AUDIOFOCUS_GAIN:
 *             if (mPlaybackDelayed || mResumeOnFocusGain) {
 *                 synchronized (mFocusLock) {
 *                     mPlaybackDelayed = false;
 *                     mResumeOnFocusGain = false;
 *                 }
 *                 playbackNow();
 *             }
 *             break;
 *         case AudioManager.AUDIOFOCUS_LOSS:
 *             synchronized (mFocusLock) {
 *                 // this is not a transient loss, we shouldn't automatically resume for now
 *                 mResumeOnFocusGain = false;
 *                 mPlaybackDelayed = false;
 *             }
 *             pausePlayback();
 *             break;
 *         case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
 *         case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
 *             // we handle all transient losses the same way because we never duck audio books
 *             synchronized (mFocusLock) {
 *                 // we should only resume if playback was interrupted
 *                 mResumeOnFocusGain = mMediaPlayer.isPlaying();
 *                 mPlaybackDelayed = false;
 *             }
 *             pausePlayback();
 *             break;
 *     }
 * }
 *
 * // Important:
 * // Also set "mResumeOnFocusGain" to false when the user pauses or stops playback: this way your
 * // application doesn't automatically restart when it gains focus, even though the user had
 * // stopped it.
 * </pre>
 */

public final class AudioFocusRequest {

    // default attributes for the request when not specified
    private final static AudioAttributes FOCUS_DEFAULT_ATTR = new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_MEDIA).build();

    private final OnAudioFocusChangeListener mFocusListener; // may be null
    private final Handler mListenerHandler;                  // may be null
    private final AudioAttributes mAttr;                     // never null
    private final int mFocusGain;
    private final int mFlags;

    private AudioFocusRequest(OnAudioFocusChangeListener listener, Handler handler,
            AudioAttributes attr, int focusGain, int flags) {
        mFocusListener = listener;
        mListenerHandler = handler;
        mFocusGain = focusGain;
        mAttr = attr;
        mFlags = flags;
    }

    /**
     * @hide
     * Checks whether a focus gain constant is a valid value for an audio focus request.
     * @param focusGain value to check
     * @return true if focusGain is a valid value for an audio focus request.
     */
    final static boolean isValidFocusGain(int focusGain) {
        switch (focusGain) {
            case AudioManager.AUDIOFOCUS_GAIN:
            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
                return true;
            default:
                return false;
        }
    }

    /**
     * @hide
     * Returns the focus change listener set for this {@code AudioFocusRequest}.
     * @return null if no {@link AudioManager.OnAudioFocusChangeListener} was set.
     */
    public @Nullable OnAudioFocusChangeListener getOnAudioFocusChangeListener() {
        return mFocusListener;
    }

    /**
     * @hide
     * Returns the {@link Handler} to be used for the focus change listener.
     * @return the same {@code Handler} set in.
     *   {@link Builder#setOnAudioFocusChangeListener(OnAudioFocusChangeListener, Handler)}, or null
     *   if no listener was set.
     */
    public @Nullable Handler getOnAudioFocusChangeListenerHandler() {
        return mListenerHandler;
    }

    /**
     * Returns the {@link AudioAttributes} set for this {@code AudioFocusRequest}, or the default
     * attributes if none were set.
     * @return non-null {@link AudioAttributes}.
     */
    public @NonNull AudioAttributes getAudioAttributes() {
        return mAttr;
    }

    /**
     * Returns the type of audio focus request configured for this {@code AudioFocusRequest}.
     * @return one of {@link AudioManager#AUDIOFOCUS_GAIN},
     * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT},
     * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and
     * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}.
     */
    public int getFocusGain() {
        return mFocusGain;
    }

    /**
     * Returns whether the application that would use this {@code AudioFocusRequest} would pause
     * when it is requested to duck.
     * @return the duck/pause behavior.
     */
    public boolean willPauseWhenDucked() {
        return (mFlags & AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS)
                == AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS;
    }

    /**
     * Returns whether the application that would use this {@code AudioFocusRequest} supports
     * a focus gain granted after a temporary request failure.
     * @return whether delayed focus gain is supported.
     */
    public boolean acceptsDelayedFocusGain() {
        return (mFlags & AudioManager.AUDIOFOCUS_FLAG_DELAY_OK)
                == AudioManager.AUDIOFOCUS_FLAG_DELAY_OK;
    }

    /**
     * @hide
     * Returns whether audio focus will be locked (i.e. focus cannot change) as a result of this
     * focus request being successful.
     * @return whether this request will lock focus.
     */
    @SystemApi
    public boolean locksFocus() {
        return (mFlags & AudioManager.AUDIOFOCUS_FLAG_LOCK)
                == AudioManager.AUDIOFOCUS_FLAG_LOCK;
    }

    int getFlags() {
        return mFlags;
    }

    /**
     * Builder class for {@link AudioFocusRequest} objects.
     * <p>See {@link AudioFocusRequest} for an example of building an instance with this builder.
     * <br>The default values for the instance to be built are:
     * <table>
     * <tr><td>focus listener and handler</td><td>none</td></tr>
     * <tr><td>{@code AudioAttributes}</td><td>attributes with usage set to
     *     {@link AudioAttributes#USAGE_MEDIA}</td></tr>
     * <tr><td>pauses on duck</td><td>false</td></tr>
     * <tr><td>supports delayed focus grant</td><td>false</td></tr>
     * </table>
     */
    public static final class Builder {
        private OnAudioFocusChangeListener mFocusListener;
        private Handler mListenerHandler;
        private AudioAttributes mAttr = FOCUS_DEFAULT_ATTR;
        private int mFocusGain;
        private boolean mPausesOnDuck = false;
        private boolean mDelayedFocus = false;
        private boolean mFocusLocked = false;

        /**
         * Constructs a new {@code Builder}, and specifies how audio focus
         * will be requested. Valid values for focus requests are
         * {@link AudioManager#AUDIOFOCUS_GAIN}, {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT},
         * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and
         * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}.
         * <p>By default there is no focus change listener, delayed focus is not supported, ducking
         * is suitable for the application, and the <code>AudioAttributes</code>
         * have a usage of {@link AudioAttributes#USAGE_MEDIA}.
         * @param focusGain the type of audio focus gain that will be requested
         * @throws IllegalArgumentException thrown when an invalid focus gain type is used
         */
        public Builder(int focusGain) {
            setFocusGain(focusGain);
        }

        /**
         * Constructs a new {@code Builder} with all the properties of the {@code AudioFocusRequest}
         * passed as parameter.
         * Use this method when you want a new request to differ only by some properties.
         * @param requestToCopy the non-null {@code AudioFocusRequest} to build a duplicate from.
         * @throws IllegalArgumentException thrown when a null {@code AudioFocusRequest} is used.
         */
        public Builder(@NonNull AudioFocusRequest requestToCopy) {
            if (requestToCopy == null) {
                throw new IllegalArgumentException("Illegal null AudioFocusRequest");
            }
            mAttr = requestToCopy.mAttr;
            mFocusListener = requestToCopy.mFocusListener;
            mListenerHandler = requestToCopy.mListenerHandler;
            mFocusGain = requestToCopy.mFocusGain;
            mPausesOnDuck = requestToCopy.willPauseWhenDucked();
            mDelayedFocus = requestToCopy.acceptsDelayedFocusGain();
        }

        /**
         * Sets the type of focus gain that will be requested.
         * Use this method to replace the focus gain when building a request by modifying an
         * existing {@code AudioFocusRequest} instance.
         * @param focusGain the type of audio focus gain that will be requested.
         * @return this {@code Builder} instance
         * @throws IllegalArgumentException thrown when an invalid focus gain type is used
         */
        public @NonNull Builder setFocusGain(int focusGain) {
            if (!isValidFocusGain(focusGain)) {
                throw new IllegalArgumentException("Illegal audio focus gain type " + focusGain);
            }
            mFocusGain = focusGain;
            return this;
        }

        /**
         * Sets the listener called when audio focus changes after being requested with
         *   {@link AudioManager#requestAudioFocus(AudioFocusRequest)}, and until being abandoned
         *   with {@link AudioManager#abandonAudioFocusRequest(AudioFocusRequest)}.
         *   Note that only focus changes (gains and losses) affecting the focus owner are reported,
         *   not gains and losses of other focus requesters in the system.<br>
         *   Notifications are delivered on the main {@link Looper}.
         * @param listener the listener receiving the focus change notifications.
         * @return this {@code Builder} instance.
         * @throws NullPointerException thrown when a null focus listener is used.
         */
        public @NonNull Builder setOnAudioFocusChangeListener(
                @NonNull OnAudioFocusChangeListener listener) {
            if (listener == null) {
                throw new NullPointerException("Illegal null focus listener");
            }
            mFocusListener = listener;
            mListenerHandler = null;
            return this;
        }

        /**
         * @hide
         * Internal listener setter, no null checks on listener nor handler
         * @param listener
         * @param handler
         * @return this {@code Builder} instance.
         */
        @NonNull Builder setOnAudioFocusChangeListenerInt(
                OnAudioFocusChangeListener listener, Handler handler) {
            mFocusListener = listener;
            mListenerHandler = handler;
            return this;
        }

        /**
         * Sets the listener called when audio focus changes after being requested with
         *   {@link AudioManager#requestAudioFocus(AudioFocusRequest)}, and until being abandoned
         *   with {@link AudioManager#abandonAudioFocusRequest(AudioFocusRequest)}.
         *   Note that only focus changes (gains and losses) affecting the focus owner are reported,
         *   not gains and losses of other focus requesters in the system.
         * @param listener the listener receiving the focus change notifications.
         * @param handler the {@link Handler} for the thread on which to execute
         *   the notifications.
         * @return this {@code Builder} instance.
         * @throws NullPointerException thrown when a null focus listener or handler is used.
         */
        public @NonNull Builder setOnAudioFocusChangeListener(
                @NonNull OnAudioFocusChangeListener listener, @NonNull Handler handler) {
            if (listener == null || handler == null) {
                throw new NullPointerException("Illegal null focus listener or handler");
            }
            mFocusListener = listener;
            mListenerHandler = handler;
            return this;
        }

        /**
         * Sets the {@link AudioAttributes} to be associated with the focus request, and which
         * describe the use case for which focus is requested.
         * As the focus requests typically precede audio playback, this information is used on
         * certain platforms to declare the subsequent playback use case. It is therefore good
         * practice to use in this method the same {@code AudioAttributes} as used for
         * playback, see for example {@link MediaPlayer#setAudioAttributes(AudioAttributes)} in
         * {@code MediaPlayer} or {@link AudioTrack.Builder#setAudioAttributes(AudioAttributes)}
         * in {@code AudioTrack}.
         * @param attributes the {@link AudioAttributes} for the focus request.
         * @return this {@code Builder} instance.
         * @throws NullPointerException thrown when using null for the attributes.
         */
        public @NonNull Builder setAudioAttributes(@NonNull AudioAttributes attributes) {
            if (attributes == null) {
                throw new NullPointerException("Illegal null AudioAttributes");
            }
            mAttr = attributes;
            return this;
        }

        /**
         * Declare the intended behavior of the application with regards to audio ducking.
         * See more details in the {@link AudioFocusRequest} class documentation.
         * @param pauseOnDuck use {@code true} if the application intends to pause audio playback
         *    when losing focus with {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}.
         *    If {@code true}, note that you must also set a focus listener to receive such an
         *    event, with
         *    {@link #setOnAudioFocusChangeListener(OnAudioFocusChangeListener, Handler)}.
         * @return this {@code Builder} instance.
         */
        public @NonNull Builder setWillPauseWhenDucked(boolean pauseOnDuck) {
            mPausesOnDuck = pauseOnDuck;
            return this;
        }

        /**
         * Marks this focus request as compatible with delayed focus.
         * See more details about delayed focus in the {@link AudioFocusRequest} class
         * documentation.
         * @param acceptsDelayedFocusGain use {@code true} if the application supports delayed
         *    focus. If {@code true}, note that you must also set a focus listener to be notified
         *    of delayed focus gain, with
         *    {@link #setOnAudioFocusChangeListener(OnAudioFocusChangeListener, Handler)}.
         * @return this {@code Builder} instance
         */
        public @NonNull Builder setAcceptsDelayedFocusGain(boolean acceptsDelayedFocusGain) {
            mDelayedFocus = acceptsDelayedFocusGain;
            return this;
        }

        /**
         * @hide
         * Marks this focus request as locking audio focus so granting is temporarily disabled.
         * This feature can only be used by owners of a registered
         * {@link android.media.audiopolicy.AudioPolicy} in
         * {@link AudioManager#requestAudioFocus(AudioFocusRequest, android.media.audiopolicy.AudioPolicy)}.
         * Setting to false is the same as the default behavior.
         * @param focusLocked true when locking focus
         * @return this {@code Builder} instance
         */
        @SystemApi
        public @NonNull Builder setLocksFocus(boolean focusLocked) {
            mFocusLocked = focusLocked;
            return this;
        }

        /**
         * Builds a new {@code AudioFocusRequest} instance combining all the information gathered
         * by this {@code Builder}'s configuration methods.
         * @return the {@code AudioFocusRequest} instance qualified by all the properties set
         *   on this {@code Builder}.
         * @throws IllegalStateException thrown when attempting to build a focus request that is set
         *    to accept delayed focus, or to pause on duck, but no focus change listener was set.
         */
        public AudioFocusRequest build() {
            if ((mDelayedFocus || mPausesOnDuck) && (mFocusListener == null)) {
                throw new IllegalStateException(
                        "Can't use delayed focus or pause on duck without a listener");
            }
            final int flags = 0
                    | (mDelayedFocus ? AudioManager.AUDIOFOCUS_FLAG_DELAY_OK : 0)
                    | (mPausesOnDuck ? AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS : 0)
                    | (mFocusLocked  ? AudioManager.AUDIOFOCUS_FLAG_LOCK : 0);
            return new AudioFocusRequest(mFocusListener, mListenerHandler,
                    mAttr, mFocusGain, flags);
        }
    }
}
