1328a0994eba8065571e09c1b3459743b340ce70bDan Sandler/*
2328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * Copyright (C) 2017 The Android Open Source Project
3328a0994eba8065571e09c1b3459743b340ce70bDan Sandler *
4328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * Licensed under the Apache License, Version 2.0 (the "License");
5328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * you may not use this file except in compliance with the License.
6328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * You may obtain a copy of the License at
7328a0994eba8065571e09c1b3459743b340ce70bDan Sandler *
8328a0994eba8065571e09c1b3459743b340ce70bDan Sandler *      http://www.apache.org/licenses/LICENSE-2.0
9328a0994eba8065571e09c1b3459743b340ce70bDan Sandler *
10328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * Unless required by applicable law or agreed to in writing, software
11328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * distributed under the License is distributed on an "AS IS" BASIS,
12328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * See the License for the specific language governing permissions and
14328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * limitations under the License.
15328a0994eba8065571e09c1b3459743b340ce70bDan Sandler */
16328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
17328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerpackage android.support.v4.media;
18328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
19328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerimport static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
20328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
21328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerimport android.media.AudioAttributes;
22328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerimport android.media.AudioManager;
23328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerimport android.os.Build;
24328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerimport android.support.annotation.IntDef;
25328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerimport android.support.annotation.NonNull;
26328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerimport android.support.annotation.Nullable;
27328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerimport android.support.annotation.RestrictTo;
28328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerimport android.util.SparseIntArray;
29328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
30328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerimport java.lang.annotation.Retention;
31328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerimport java.lang.annotation.RetentionPolicy;
32328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerimport java.util.Arrays;
33328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
34328a0994eba8065571e09c1b3459743b340ce70bDan Sandler/**
35328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * A class to encapsulate a collection of attributes describing information about an audio stream.
36328a0994eba8065571e09c1b3459743b340ce70bDan Sandler *
37328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * <p><code>AudioAttributesCompat</code> supersede the notion of stream types (see for instance
38328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * {@link AudioManager#STREAM_MUSIC} or {@link AudioManager#STREAM_ALARM}) for defining the behavior
39328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * of audio playback. Attributes allow an application to specify more information than is conveyed
40328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * in a stream type by allowing the application to define:
41328a0994eba8065571e09c1b3459743b340ce70bDan Sandler *
42328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * <ul>
43328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * <li>usage: "why" you are playing a sound, what is this sound used for. This is achieved with
44328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * the "usage" information. Examples of usage are {@link #USAGE_MEDIA} and {@link
45328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * #USAGE_ALARM}. These two examples are the closest to stream types, but more detailed use
46328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * cases are available. Usage information is more expressive than a stream type, and allows
47328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * certain platforms or routing policies to use this information for more refined volume or
48328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * routing decisions. Usage is the most important information to supply in <code>
49328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * AudioAttributesCompat</code> and it is recommended to build any instance with this
50328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * information supplied, see {@link AudioAttributesCompat.Builder} for exceptions.
51328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * <li>content type: "what" you are playing. The content type expresses the general category of
52328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * the content. This information is optional. But in case it is known (for instance {@link
53328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * #CONTENT_TYPE_MOVIE} for a movie streaming service or {@link #CONTENT_TYPE_MUSIC} for a
54328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * music playback application) this information might be used by the audio framework to
55328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * selectively configure some audio post-processing blocks.
56328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * <li>flags: "how" is playback to be affected, see the flag definitions for the specific playback
57328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * behaviors they control.
58328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * </ul>
59328a0994eba8065571e09c1b3459743b340ce70bDan Sandler *
60328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * <p><code>AudioAttributesCompat</code> instance is built through its builder, {@link
61328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * AudioAttributesCompat.Builder}. Also see {@link android.media.AudioAttributes} for the framework
62328a0994eba8065571e09c1b3459743b340ce70bDan Sandler * implementation of this class.
63328a0994eba8065571e09c1b3459743b340ce70bDan Sandler */
64328a0994eba8065571e09c1b3459743b340ce70bDan Sandlerpublic class AudioAttributesCompat {
65328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final String TAG = "AudioAttributesCompat";
66328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
67328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
68328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Content type value to use when the content type is unknown, or other than the ones defined.
69328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
70328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int CONTENT_TYPE_UNKNOWN = AudioAttributes.CONTENT_TYPE_UNKNOWN;
71328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** Content type value to use when the content type is speech. */
72328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int CONTENT_TYPE_SPEECH = AudioAttributes.CONTENT_TYPE_SPEECH;
73328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** Content type value to use when the content type is music. */
74328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int CONTENT_TYPE_MUSIC = AudioAttributes.CONTENT_TYPE_MUSIC;
75328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
76328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Content type value to use when the content type is a soundtrack, typically accompanying a
77328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * movie or TV program.
78328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
79328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int CONTENT_TYPE_MOVIE = AudioAttributes.CONTENT_TYPE_MOVIE;
80328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
81328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Content type value to use when the content type is a sound used to accompany a user action,
82328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * such as a beep or sound effect expressing a key click, or event, such as the type of a sound
83328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * for a bonus being received in a game. These sounds are mostly synthesized or short Foley
84328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * sounds.
85328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
86328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int CONTENT_TYPE_SONIFICATION = AudioAttributes.CONTENT_TYPE_SONIFICATION;
87328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
88328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** Usage value to use when the usage is unknown. */
89328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_UNKNOWN = AudioAttributes.USAGE_UNKNOWN;
90328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** Usage value to use when the usage is media, such as music, or movie soundtracks. */
91328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_MEDIA = AudioAttributes.USAGE_MEDIA;
92328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** Usage value to use when the usage is voice communications, such as telephony or VoIP. */
93328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_VOICE_COMMUNICATION = AudioAttributes.USAGE_VOICE_COMMUNICATION;
94328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
95328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Usage value to use when the usage is in-call signalling, such as with a "busy" beep, or DTMF
96328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * tones.
97328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
98328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_VOICE_COMMUNICATION_SIGNALLING =
99328a0994eba8065571e09c1b3459743b340ce70bDan Sandler             AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING;
100328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** Usage value to use when the usage is an alarm (e.g. wake-up alarm). */
101328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_ALARM = AudioAttributes.USAGE_ALARM;
102328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
103328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Usage value to use when the usage is notification. See other notification usages for more
104328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * specialized uses.
105328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
106328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_NOTIFICATION = AudioAttributes.USAGE_NOTIFICATION;
107328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** Usage value to use when the usage is telephony ringtone. */
108328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_NOTIFICATION_RINGTONE =
109328a0994eba8065571e09c1b3459743b340ce70bDan Sandler             AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
110328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
111328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Usage value to use when the usage is a request to enter/end a communication, such as a VoIP
112328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * communication or video-conference.
113328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
114328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_NOTIFICATION_COMMUNICATION_REQUEST =
115328a0994eba8065571e09c1b3459743b340ce70bDan Sandler             AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST;
116328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
117328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Usage value to use when the usage is notification for an "instant" communication such as a
118328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * chat, or SMS.
119328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
120328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_NOTIFICATION_COMMUNICATION_INSTANT =
121328a0994eba8065571e09c1b3459743b340ce70bDan Sandler             AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT;
122328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
123328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Usage value to use when the usage is notification for a non-immediate type of communication
124328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * such as e-mail.
125328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
126328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_NOTIFICATION_COMMUNICATION_DELAYED =
127328a0994eba8065571e09c1b3459743b340ce70bDan Sandler             AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED;
128328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
129328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Usage value to use when the usage is to attract the user's attention, such as a reminder or
130328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * low battery warning.
131328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
132328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_NOTIFICATION_EVENT = AudioAttributes.USAGE_NOTIFICATION_EVENT;
133328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** Usage value to use when the usage is for accessibility, such as with a screen reader. */
134328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_ASSISTANCE_ACCESSIBILITY =
135328a0994eba8065571e09c1b3459743b340ce70bDan Sandler             AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY;
136328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** Usage value to use when the usage is driving or navigation directions. */
137328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_ASSISTANCE_NAVIGATION_GUIDANCE =
138328a0994eba8065571e09c1b3459743b340ce70bDan Sandler             AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
139328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** Usage value to use when the usage is sonification, such as with user interface sounds. */
140328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_ASSISTANCE_SONIFICATION =
141328a0994eba8065571e09c1b3459743b340ce70bDan Sandler             AudioAttributes.USAGE_ASSISTANCE_SONIFICATION;
142328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** Usage value to use when the usage is for game audio. */
143328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_GAME = AudioAttributes.USAGE_GAME;
144328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
145328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    // usage not available to clients
146328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int USAGE_VIRTUAL_SOURCE = 15; // AudioAttributes.USAGE_VIRTUAL_SOURCE;
147328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
148328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Usage value to use for audio responses to user queries, audio instructions or help
149328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * utterances.
150328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
151328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int USAGE_ASSISTANT = AudioAttributes.USAGE_ASSISTANT;
152328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
153328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
154328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * IMPORTANT: when adding new usage types, add them to SDK_USAGES and update SUPPRESSIBLE_USAGES
155328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * if applicable.
156328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
157328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
158328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    // private API
159328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int SUPPRESSIBLE_NOTIFICATION = 1;
160328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
161328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int SUPPRESSIBLE_CALL = 2;
162328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final SparseIntArray SUPPRESSIBLE_USAGES;
163328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
164328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    // used by tests
165328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static boolean sForceLegacyBehavior;
166328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
167328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    static {
168328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        SUPPRESSIBLE_USAGES = new SparseIntArray();
169328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION, SUPPRESSIBLE_NOTIFICATION);
170328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_RINGTONE, SUPPRESSIBLE_CALL);
171328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_COMMUNICATION_REQUEST, SUPPRESSIBLE_CALL);
172328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        SUPPRESSIBLE_USAGES.put(
173328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                USAGE_NOTIFICATION_COMMUNICATION_INSTANT, SUPPRESSIBLE_NOTIFICATION);
174328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        SUPPRESSIBLE_USAGES.put(
175328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                USAGE_NOTIFICATION_COMMUNICATION_DELAYED, SUPPRESSIBLE_NOTIFICATION);
176328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_EVENT, SUPPRESSIBLE_NOTIFICATION);
177328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
178328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
179328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int[] SDK_USAGES = {
180328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_UNKNOWN,
181328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_MEDIA,
182328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_VOICE_COMMUNICATION,
183328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_VOICE_COMMUNICATION_SIGNALLING,
184328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_ALARM,
185328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_NOTIFICATION,
186328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_NOTIFICATION_RINGTONE,
187328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_NOTIFICATION_COMMUNICATION_REQUEST,
188328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_NOTIFICATION_COMMUNICATION_INSTANT,
189328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_NOTIFICATION_COMMUNICATION_DELAYED,
190328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_NOTIFICATION_EVENT,
191328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_ASSISTANCE_ACCESSIBILITY,
192328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
193328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_ASSISTANCE_SONIFICATION,
194328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_GAME,
195328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_ASSISTANT,
196328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    };
197328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
198328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** Flag defining a behavior where the audibility of the sound will be ensured by the system. */
199328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int FLAG_AUDIBILITY_ENFORCED = 0x1 << 0;
200328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
201328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    // flags for @hide API so we can create a proper flags mask
202328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int FLAG_SECURE = 0x1 << 1;
203328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int FLAG_SCO = 0x1 << 2;
204328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int FLAG_BEACON = 0x1 << 3;
205328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
206328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** Flag requesting the use of an output stream supporting hardware A/V synchronization. */
207328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static final int FLAG_HW_AV_SYNC = 0x1 << 4;
208328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
209328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    // more @hide flags
210328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int FLAG_HW_HOTWORD = 0x1 << 5;
211328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int FLAG_BYPASS_INTERRUPTION_POLICY = 0x1 << 6;
212328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int FLAG_BYPASS_MUTE = 0x1 << 7;
213328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int FLAG_LOW_LATENCY = 0x1 << 8;
214328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int FLAG_DEEP_BUFFER = 0x1 << 9;
215328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
216328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int FLAG_ALL =
217328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            (FLAG_AUDIBILITY_ENFORCED
218328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    | FLAG_SECURE
219328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    | FLAG_SCO
220328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    | FLAG_BEACON
221328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    | FLAG_HW_AV_SYNC
222328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    | FLAG_HW_HOTWORD
223328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    | FLAG_BYPASS_INTERRUPTION_POLICY
224328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    | FLAG_BYPASS_MUTE
225328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    | FLAG_LOW_LATENCY
226328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    | FLAG_DEEP_BUFFER);
227328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static final int FLAG_ALL_PUBLIC =
228328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            (FLAG_AUDIBILITY_ENFORCED | FLAG_HW_AV_SYNC | FLAG_LOW_LATENCY);
229328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
230328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    int mUsage = USAGE_UNKNOWN;
231328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    int mContentType = CONTENT_TYPE_UNKNOWN;
232328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    int mFlags = 0x0;
233328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    Integer mLegacyStream;
234328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private AudioAttributesCompatApi21.Wrapper mAudioAttributesWrapper;
235328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
236328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private AudioAttributesCompat() {
237328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
238328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
239328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
240328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Returns the stream type matching the given attributes for volume control. Use this method to
241328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * derive the stream type needed to configure the volume control slider in an {@link
242328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * android.app.Activity} with {@link android.app.Activity#setVolumeControlStream(int)}. <br>
243328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Do not use this method to set the stream type on an audio player object (e.g. {@link
244328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * android.media.AudioTrack}, {@link android.media.MediaPlayer}) as this is deprecated;
245328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * use <code>AudioAttributes</code> instead.
246328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     *
247328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * @return a valid stream type for <code>Activity</code> or stream volume control that matches
248328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * the attributes, or {@link AudioManager#USE_DEFAULT_STREAM_TYPE} if there isn't a direct
249328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * match. Note that <code>USE_DEFAULT_STREAM_TYPE</code> is not a valid value for {@link
250328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * AudioManager#setStreamVolume(int, int, int)}.
251328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
252328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public int getVolumeControlStream() {
253328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (this == null) {
254328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            throw new IllegalArgumentException("Invalid null audio attributes");
255328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
256328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (Build.VERSION.SDK_INT >= 26
257328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && !sForceLegacyBehavior
258328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && unwrap() != null) {
259ad06fac657161f49606b1a09cb5d0c4008def2f1Jean-Michel Trivi            return ((AudioAttributes) unwrap()).getVolumeControlStream();
260328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
261328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        return toVolumeStreamType(true, this);
262328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
263328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
264328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    // public API unique to AudioAttributesCompat
265328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
266328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
267328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * If the current SDK level is 21 or higher, return the {@link AudioAttributes} object inside
268328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * this {@link AudioAttributesCompat}. Otherwise <code>null</code>.
269328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     *
270328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * @return the underlying {@link AudioAttributes} object or null
271328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
272328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    @Nullable
273328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public Object unwrap() {
274328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (mAudioAttributesWrapper != null) {
275328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return mAudioAttributesWrapper.unwrap();
276328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
277328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        return null;
278328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
279328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
280328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
281328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Return a stream type passed to {@link Builder#setLegacyStreamType(int)}, or -1 if no legacy
282328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * stream is available
283328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     *
284328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * @return the stream type {@see AudioManager}
285328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
286328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public int getLegacyStreamType() {
287328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        // case 1: developer explicitly set a legacy stream,
288328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        // so just hand that back
289328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (mLegacyStream != null) {
290328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return mLegacyStream;
291328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
292328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
293328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        // case 2: API 21+ and we have a real AudioAttributes
294328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        // the same caveats in AudioAttributes#toLegacyStreamTyoe apply:
295328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        // only use this for volume control
296328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (Build.VERSION.SDK_INT >= 21) {
297328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            if (!sForceLegacyBehavior) {
298328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return AudioAttributesCompatApi21.toLegacyStreamType(mAudioAttributesWrapper);
299328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            }
300328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
301328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
302328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        // case 3: developer set up AudioAttrs using new flags/usage APIs
303328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        // but we are running pre-API21, so use the heuristic below
304328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        return toVolumeStreamType(false, mFlags, mUsage);
305328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
306328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
307328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
308328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Create an {@link AudioAttributesCompat} given an API 21 {@link AudioAttributes} object.
309328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     *
310328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * @param aa an instance of {@link AudioAttributes}
311328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * @return the new <code>AudioAttributesCompat</code>, or <code>null</code> on API &lt; 21
312328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
313328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    @Nullable
314328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static AudioAttributesCompat wrap(@NonNull final Object aa) {
315328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (Build.VERSION.SDK_INT >= 21 && !sForceLegacyBehavior) {
316328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            final AudioAttributesCompat aac = new AudioAttributesCompat();
317328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            aac.mAudioAttributesWrapper =
318328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    AudioAttributesCompatApi21.Wrapper.wrap((AudioAttributes) aa);
319328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return aac;
320328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
321328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        return null;
322328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
323328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
324328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    // The rest of this file implements an approximation to AudioAttributes using old stream types
325328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
326328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
327328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Return the content type.
328328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     *
329328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * @return one of the values that can be set in {@link Builder#setContentType(int)}
330328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
331328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public int getContentType() {
332328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (Build.VERSION.SDK_INT >= 21
333328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && !sForceLegacyBehavior
334328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && mAudioAttributesWrapper != null) {
335328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return mAudioAttributesWrapper.unwrap().getContentType();
336328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        } else {
337328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return mContentType;
338328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
339328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
340328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
341328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
342328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Return the usage.
343328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     *
344328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * @return one of the values that can be set in {@link Builder#setUsage(int)}
345328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
346328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public @AttributeUsage int getUsage() {
347328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (Build.VERSION.SDK_INT >= 21
348328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && !sForceLegacyBehavior
349328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && mAudioAttributesWrapper != null) {
350328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return mAudioAttributesWrapper.unwrap().getUsage();
351328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        } else {
352328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return mUsage;
353328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
354328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
355328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
356328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
357328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Return the flags.
358328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     *
359328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * @return a combined mask of all flags
360328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
361328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public int getFlags() {
362328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (Build.VERSION.SDK_INT >= 21
363328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && !sForceLegacyBehavior
364328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && mAudioAttributesWrapper != null) {
365328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return mAudioAttributesWrapper.unwrap().getFlags();
366328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        } else {
367328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            int flags = mFlags;
368328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            int legacyStream = getLegacyStreamType();
369328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            if (legacyStream == AudioManagerHidden.STREAM_BLUETOOTH_SCO) {
370328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                flags |= FLAG_SCO;
371328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            } else if (legacyStream == AudioManagerHidden.STREAM_SYSTEM_ENFORCED) {
372328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                flags |= FLAG_AUDIBILITY_ENFORCED;
373328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            }
374328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return flags & FLAG_ALL_PUBLIC;
375328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
376328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
377328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
378328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
379328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Builder class for {@link AudioAttributesCompat} objects.
380328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     *
381328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * <p>example:
382328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     *
383328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * <pre class="prettyprint">
384328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * new AudioAttributes.Builder()
385328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * .setUsage(AudioAttributes.USAGE_MEDIA)
386328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
387328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * .build();
388328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * </pre>
389328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     *
390328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * <p>By default all types of information (usage, content type, flags) conveyed by an <code>
391328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * AudioAttributesCompat</code> instance are set to "unknown". Unknown information will be
392328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * interpreted as a default value that is dependent on the context of use, for instance a {@link
393328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * android.media.MediaPlayer} will use a default usage of
394328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * {@link AudioAttributesCompat#USAGE_MEDIA}. See also {@link AudioAttributes.Builder}.
395328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
396328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static class Builder {
397328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        private int mUsage = USAGE_UNKNOWN;
398328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        private int mContentType = CONTENT_TYPE_UNKNOWN;
399328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        private int mFlags = 0x0;
400328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        private Integer mLegacyStream;
401328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        private Object mAAObject;
402328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
403328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        /**
404328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * Constructs a new Builder with the defaults. By default, usage and content type are
405328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * respectively {@link AudioAttributesCompat#USAGE_UNKNOWN} and {@link
406328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * AudioAttributesCompat#CONTENT_TYPE_UNKNOWN}, and flags are 0. It is recommended to
407328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * configure the usage (with {@link #setUsage(int)}) or deriving attributes from a legacy
408328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * stream type (with {@link #setLegacyStreamType(int)}) before calling {@link #build()} to
409328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * override any default playback behavior in terms of routing and volume management.
410328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         */
411328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        public Builder() {
412328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
413328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
414328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        /**
415328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * Constructs a new Builder from a given AudioAttributes
416328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *
417328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * @param aa the AudioAttributesCompat object whose data will be reused in the new Builder.
418328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         */
419328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        public Builder(AudioAttributesCompat aa) {
420328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            mUsage = aa.mUsage;
421328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            mContentType = aa.mContentType;
422328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            mFlags = aa.mFlags;
423328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            mLegacyStream = aa.mLegacyStream;
424328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            mAAObject = aa.unwrap();
425328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
426328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
427328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        /**
428328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * Combines all of the attributes that have been set and return a new {@link
429328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * AudioAttributesCompat} object.
430328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *
431328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * @return a new {@link AudioAttributesCompat} object
432328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         */
433328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        public AudioAttributesCompat build() {
434328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            if (!sForceLegacyBehavior && Build.VERSION.SDK_INT >= 21) {
435328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                // API21
436328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                if (mAAObject != null) {
437328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    // best case: underlying real AudioAttributes
438328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    return wrap(mAAObject);
439328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                } else {
440328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    // set up an API21 builder with whatever we have
441328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    AudioAttributes.Builder api21Builder =
442328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                             new AudioAttributes.Builder()
443328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                                .setContentType(mContentType)
444328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                                .setFlags(mFlags)
445328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                                .setUsage(mUsage);
446328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    if (mLegacyStream != null) {
447328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                        // if a legacy stream was specified, throw that in
448328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                        api21Builder.setLegacyStreamType(mLegacyStream);
449328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    }
450328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    return wrap(api21Builder.build());
451328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                }
452328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            } else {
453328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                // pre-API21
454328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                final AudioAttributesCompat aac = new AudioAttributesCompat();
455328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                aac.mContentType = mContentType;
456328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                aac.mFlags = mFlags;
457328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                aac.mUsage = mUsage;
458328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                aac.mLegacyStream = mLegacyStream;
459328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                aac.mAudioAttributesWrapper = null;
460328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return aac;
461328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            }
462328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
463328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
464328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        /**
465328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * Sets the attribute describing what is the intended use of the the audio signal, such as
466328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * alarm or ringtone.
467328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *
468328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * @param usage one of {@link AudioAttributesCompat#USAGE_UNKNOWN}, {@link
469328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              AudioAttributesCompat#USAGE_MEDIA}, {@link
470328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              AudioAttributesCompat#USAGE_VOICE_COMMUNICATION}, {@link
471328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              AudioAttributesCompat#USAGE_VOICE_COMMUNICATION_SIGNALLING}, {@link
472328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              AudioAttributesCompat#USAGE_ALARM},
473328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              {@link AudioAttributesCompat#USAGE_NOTIFICATION},
474328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              {@link AudioAttributesCompat#USAGE_NOTIFICATION_RINGTONE}, {@link
475328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              AudioAttributesCompat#USAGE_NOTIFICATION_COMMUNICATION_REQUEST}, {@link
476328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              AudioAttributesCompat#USAGE_NOTIFICATION_COMMUNICATION_INSTANT}, {@link
477328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              AudioAttributesCompat#USAGE_NOTIFICATION_COMMUNICATION_DELAYED}, {@link
478328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              AudioAttributesCompat#USAGE_NOTIFICATION_EVENT}, {@link
479328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              AudioAttributesCompat#USAGE_ASSISTANT}, {@link
480328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              AudioAttributesCompat#USAGE_ASSISTANCE_ACCESSIBILITY}, {@link
481328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              AudioAttributesCompat#USAGE_ASSISTANCE_NAVIGATION_GUIDANCE}, {@link
482328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              AudioAttributesCompat#USAGE_ASSISTANCE_SONIFICATION}, {@link
483328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              AudioAttributesCompat#USAGE_GAME}.
484328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * @return the same Builder instance.
485328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         */
486328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        public Builder setUsage(@AttributeUsage int usage) {
487328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            switch (usage) {
488328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_UNKNOWN:
489328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_MEDIA:
490328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_VOICE_COMMUNICATION:
491328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_VOICE_COMMUNICATION_SIGNALLING:
492328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_ALARM:
493328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_NOTIFICATION:
494328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_NOTIFICATION_RINGTONE:
495328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
496328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
497328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
498328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_NOTIFICATION_EVENT:
499328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_ASSISTANCE_ACCESSIBILITY:
500328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
501328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_ASSISTANCE_SONIFICATION:
502328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_GAME:
503328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_VIRTUAL_SOURCE:
504328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    mUsage = usage;
505328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    break;
506328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case USAGE_ASSISTANT:
507328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    if (!sForceLegacyBehavior && Build.VERSION.SDK_INT > 25) {
508328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                        mUsage = usage;
509328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    } else {
510328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                        mUsage = USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
511328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    }
512328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    break;
513328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                default:
514328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    mUsage = USAGE_UNKNOWN;
515328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            }
516328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return this;
517328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
518328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
519328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        /**
520328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * Sets the attribute describing the content type of the audio signal, such as speech, or
521328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * music.
522328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *
523328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * @param contentType the content type values, one of {@link
524328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *                    AudioAttributesCompat#CONTENT_TYPE_MOVIE}, {@link
525328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *                    AudioAttributesCompat#CONTENT_TYPE_MUSIC}, {@link
526328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *                    AudioAttributesCompat#CONTENT_TYPE_SONIFICATION}, {@link
527328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *                    AudioAttributesCompat#CONTENT_TYPE_SPEECH}, {@link
528328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *                    AudioAttributesCompat#CONTENT_TYPE_UNKNOWN}.
529328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * @return the same Builder instance.
530328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         */
531328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        public Builder setContentType(@AttributeContentType int contentType) {
532328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            switch (contentType) {
533328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case CONTENT_TYPE_UNKNOWN:
534328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case CONTENT_TYPE_MOVIE:
535328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case CONTENT_TYPE_MUSIC:
536328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case CONTENT_TYPE_SONIFICATION:
537328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                case CONTENT_TYPE_SPEECH:
538328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    mContentType = contentType;
539328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    break;
540328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                default:
541328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    mUsage = CONTENT_TYPE_UNKNOWN;
542328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            }
543328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return this;
544328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
545328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
546328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        /**
547328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * Sets the combination of flags.
548328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *
549328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * <p>This is a bitwise OR with the existing flags.
550328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *
551328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * @param flags a combination of {@link AudioAttributesCompat#FLAG_AUDIBILITY_ENFORCED},
552328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *              {@link AudioAttributesCompat#FLAG_HW_AV_SYNC}.
553328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * @return the same Builder instance.
554328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         */
555328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        public Builder setFlags(int flags) {
556328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            flags &= AudioAttributesCompat.FLAG_ALL;
557328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            mFlags |= flags;
558328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return this;
559328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
560328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
561328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        /**
562328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * Create an {@link AudioAttributesCompat} that best approximates the specified {@link
563328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * AudioManager} stream type constant.
564328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         *
565328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * @param streamType one of <code>AudioManager.STREAM_*</code>
566328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         * @return this same Builder
567328a0994eba8065571e09c1b3459743b340ce70bDan Sandler         */
568328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        public Builder setLegacyStreamType(int streamType) {
569328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            if (streamType == AudioManagerHidden.STREAM_ACCESSIBILITY) {
570328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                throw new IllegalArgumentException(
571328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                        "STREAM_ACCESSIBILITY is not a legacy stream "
572328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                                + "type that was used for audio playback");
573328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            }
574328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            mLegacyStream = streamType;
575328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            mUsage = usageForStreamType(streamType);
576328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return this;
577328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
578328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
579328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
580328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    @Override
581328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public int hashCode() {
582328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (Build.VERSION.SDK_INT >= 21
583328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && !sForceLegacyBehavior
584328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && mAudioAttributesWrapper != null) {
585328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return mAudioAttributesWrapper.unwrap().hashCode();
586328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
587328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
588328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        return Arrays.hashCode(new Object[] {mContentType, mFlags, mUsage, mLegacyStream});
589328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
590328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
591328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    @Override
592328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public String toString() {
593328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        final StringBuilder sb = new StringBuilder("AudioAttributesCompat:");
594328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (unwrap() != null) {
595328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            sb.append(" audioattributes=").append(unwrap());
596328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        } else {
597328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            if (mLegacyStream != null) {
598328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                sb.append(" stream=").append(mLegacyStream);
599328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                sb.append(" derived");
600328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            }
601328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            sb.append(" usage=")
602328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    .append(usageToString())
603328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    .append(" content=")
604328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    .append(mContentType)
605328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    .append(" flags=0x")
606328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    .append(Integer.toHexString(mFlags).toUpperCase());
607328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
608328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        return sb.toString();
609328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
610328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
611328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    String usageToString() {
612328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        return usageToString(mUsage);
613328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
614328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
615328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    static String usageToString(int usage) {
616328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        switch (usage) {
617328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_UNKNOWN:
618328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_UNKNOWN");
619328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_MEDIA:
620328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_MEDIA");
621328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_VOICE_COMMUNICATION:
622328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_VOICE_COMMUNICATION");
623328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_VOICE_COMMUNICATION_SIGNALLING:
624328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_VOICE_COMMUNICATION_SIGNALLING");
625328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_ALARM:
626328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_ALARM");
627328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_NOTIFICATION:
628328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_NOTIFICATION");
629328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_NOTIFICATION_RINGTONE:
630328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_NOTIFICATION_RINGTONE");
631328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
632328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_NOTIFICATION_COMMUNICATION_REQUEST");
633328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
634328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_NOTIFICATION_COMMUNICATION_INSTANT");
635328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
636328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_NOTIFICATION_COMMUNICATION_DELAYED");
637328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_NOTIFICATION_EVENT:
638328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_NOTIFICATION_EVENT");
639328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_ASSISTANCE_ACCESSIBILITY:
640328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_ASSISTANCE_ACCESSIBILITY");
641328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
642328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_ASSISTANCE_NAVIGATION_GUIDANCE");
643328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_ASSISTANCE_SONIFICATION:
644328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_ASSISTANCE_SONIFICATION");
645328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_GAME:
646328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_GAME");
647328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_ASSISTANT:
648328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("USAGE_ASSISTANT");
649328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            default:
650328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return new String("unknown usage " + usage);
651328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
652328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
653328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
654328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private abstract static class AudioManagerHidden {
655328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        public static final int STREAM_BLUETOOTH_SCO = 6;
656328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        public static final int STREAM_SYSTEM_ENFORCED = 7;
657328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        public static final int STREAM_TTS = 9;
658328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        public static final int STREAM_ACCESSIBILITY = 10;
659328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
660328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
661328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    private static int usageForStreamType(int streamType) {
662328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        switch (streamType) {
663328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case AudioManager.STREAM_VOICE_CALL:
664328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return USAGE_VOICE_COMMUNICATION;
665328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case AudioManagerHidden.STREAM_SYSTEM_ENFORCED:
666328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case AudioManager.STREAM_SYSTEM:
667328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return USAGE_ASSISTANCE_SONIFICATION;
668328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case AudioManager.STREAM_RING:
669328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return USAGE_NOTIFICATION_RINGTONE;
670328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case AudioManager.STREAM_MUSIC:
671328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return USAGE_MEDIA;
672328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case AudioManager.STREAM_ALARM:
673328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return USAGE_ALARM;
674328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case AudioManager.STREAM_NOTIFICATION:
675328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return USAGE_NOTIFICATION;
676328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case AudioManagerHidden.STREAM_BLUETOOTH_SCO:
677328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return USAGE_VOICE_COMMUNICATION;
678328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case AudioManager.STREAM_DTMF:
679328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return USAGE_VOICE_COMMUNICATION_SIGNALLING;
680328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case AudioManagerHidden.STREAM_ACCESSIBILITY:
681328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return USAGE_ASSISTANCE_ACCESSIBILITY;
682328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case AudioManagerHidden.STREAM_TTS:
683328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            default:
684328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return USAGE_UNKNOWN;
685328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
686328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
687328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
688328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /**
689328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * Prevent AudioAttributes from being used even on platforms that support it.
690328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     *
691328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     * @hide For testing only.
692328a0994eba8065571e09c1b3459743b340ce70bDan Sandler     */
693328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    @RestrictTo(LIBRARY_GROUP)
694328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public static void setForceLegacyBehavior(boolean force) {
695328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        sForceLegacyBehavior = force;
696328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
697328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
698328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    static int toVolumeStreamType(boolean fromGetVolumeControlStream, AudioAttributesCompat aa) {
699328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        return toVolumeStreamType(fromGetVolumeControlStream, aa.getFlags(), aa.getUsage());
700328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
701328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
702328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    static int toVolumeStreamType(
703328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            boolean fromGetVolumeControlStream, int flags, @AttributeUsage int usage) {
704328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        // flags to stream type mapping
705328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if ((flags & FLAG_AUDIBILITY_ENFORCED) == FLAG_AUDIBILITY_ENFORCED) {
706328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return fromGetVolumeControlStream
707328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    ? AudioManager.STREAM_SYSTEM
708328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    : AudioManagerHidden.STREAM_SYSTEM_ENFORCED;
709328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
710328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if ((flags & FLAG_SCO) == FLAG_SCO) {
711328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return fromGetVolumeControlStream
712328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    ? AudioManager.STREAM_VOICE_CALL
713328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    : AudioManagerHidden.STREAM_BLUETOOTH_SCO;
714328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
715328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
716328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        // usage to stream type mapping
717328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        switch (usage) {
718328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_MEDIA:
719328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_GAME:
720328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
721328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_ASSISTANT:
722328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return AudioManager.STREAM_MUSIC;
723328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_ASSISTANCE_SONIFICATION:
724328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return AudioManager.STREAM_SYSTEM;
725328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_VOICE_COMMUNICATION:
726328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return AudioManager.STREAM_VOICE_CALL;
727328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_VOICE_COMMUNICATION_SIGNALLING:
728328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return fromGetVolumeControlStream
729328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                        ? AudioManager.STREAM_VOICE_CALL
730328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                        : AudioManager.STREAM_DTMF;
731328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_ALARM:
732328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return AudioManager.STREAM_ALARM;
733328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_NOTIFICATION_RINGTONE:
734328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return AudioManager.STREAM_RING;
735328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_NOTIFICATION:
736328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
737328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
738328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
739328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_NOTIFICATION_EVENT:
740328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return AudioManager.STREAM_NOTIFICATION;
741328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_ASSISTANCE_ACCESSIBILITY:
742328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return AudioManagerHidden.STREAM_ACCESSIBILITY;
743328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            case USAGE_UNKNOWN:
744328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                return fromGetVolumeControlStream
745328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                        ? AudioManager.USE_DEFAULT_STREAM_TYPE
746328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                        : AudioManager.STREAM_MUSIC;
747328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            default:
748328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                if (fromGetVolumeControlStream) {
749328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    throw new IllegalArgumentException(
750328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                            "Unknown usage value " + usage + " in audio attributes");
751328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                } else {
752328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                    return AudioManager.STREAM_MUSIC;
753328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                }
754328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
755328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
756328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
757328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    @Override
758328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public boolean equals(Object o) {
759328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (this == o) return true;
760328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (o == null || getClass() != o.getClass()) return false;
761328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
762328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        final AudioAttributesCompat that = (AudioAttributesCompat) o;
763328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
764328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        if (Build.VERSION.SDK_INT >= 21
765328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && !sForceLegacyBehavior
766328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && mAudioAttributesWrapper != null) {
767328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            return mAudioAttributesWrapper.unwrap().equals(that.unwrap());
768328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        }
769328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
770328a0994eba8065571e09c1b3459743b340ce70bDan Sandler        return ((mContentType == that.getContentType())
771328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && (mFlags == that.getFlags())
772328a0994eba8065571e09c1b3459743b340ce70bDan Sandler                && (mUsage == that.getUsage())
77326444949f9bec919a5fd09772a22d6d9a63ee8edHyundo Moon                && (mLegacyStream != null ? mLegacyStream.equals(that.mLegacyStream)
77426444949f9bec919a5fd09772a22d6d9a63ee8edHyundo Moon                        : that.mLegacyStream == null)); // query the slot directly, don't guess
775328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
776328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
777328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** @hide */
778328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    @IntDef({
779328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_UNKNOWN,
780328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_MEDIA,
781328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_VOICE_COMMUNICATION,
782328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_VOICE_COMMUNICATION_SIGNALLING,
783328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_ALARM,
784328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_NOTIFICATION,
785328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_NOTIFICATION_RINGTONE,
786328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_NOTIFICATION_COMMUNICATION_REQUEST,
787328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_NOTIFICATION_COMMUNICATION_INSTANT,
788328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_NOTIFICATION_COMMUNICATION_DELAYED,
789328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_NOTIFICATION_EVENT,
790328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_ASSISTANCE_ACCESSIBILITY,
791328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
792328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_ASSISTANCE_SONIFICATION,
793328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_GAME,
794328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            USAGE_ASSISTANT,
795328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    })
796328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    @RestrictTo(LIBRARY_GROUP)
797328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    @Retention(RetentionPolicy.SOURCE)
798328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public @interface AttributeUsage {
799328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
800328a0994eba8065571e09c1b3459743b340ce70bDan Sandler
801328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    /** @hide */
802328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    @IntDef({
803328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            CONTENT_TYPE_UNKNOWN,
804328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            CONTENT_TYPE_SPEECH,
805328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            CONTENT_TYPE_MUSIC,
806328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            CONTENT_TYPE_MOVIE,
807328a0994eba8065571e09c1b3459743b340ce70bDan Sandler            CONTENT_TYPE_SONIFICATION
808328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    })
809328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    @Retention(RetentionPolicy.SOURCE)
810328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    @RestrictTo(LIBRARY_GROUP)
811328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    public @interface AttributeContentType {
812328a0994eba8065571e09c1b3459743b340ce70bDan Sandler    }
813328a0994eba8065571e09c1b3459743b340ce70bDan Sandler}
814