• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.car.oem;
18 
19 import android.annotation.NonNull;
20 import android.annotation.SystemApi;
21 import android.media.AudioFocusInfo;
22 import android.os.Parcelable;
23 
24 import com.android.internal.annotations.VisibleForTesting;
25 
26 import java.util.Objects;
27 
28 /**
29  * Class to encapsulate the focus information of evaluation from a car oem audio focus service
30  *
31  * @hide
32  */
33 @SystemApi
34 public final class AudioFocusEntry implements Parcelable {
35 
36     @NonNull
37     private final AudioFocusInfo mAudioFocusInfo;
38     private final int mAudioContextId;
39     private final int mAudioVolumeGroupId;
40     private final int mAudioFocusResult;
41 
AudioFocusEntry( @onNull AudioFocusInfo audioFocusInfo, int audioContextId, int audioVolumeGroupId, int focusResult)42     AudioFocusEntry(
43             @NonNull AudioFocusInfo audioFocusInfo,
44             int audioContextId,
45             int audioVolumeGroupId,
46             int focusResult) {
47         mAudioFocusInfo = Objects.requireNonNull(audioFocusInfo,
48                 "Audio focus info can not be null");
49         mAudioContextId = audioContextId;
50         mAudioVolumeGroupId = audioVolumeGroupId;
51         mAudioFocusResult = focusResult;
52     }
53 
54     /**
55      * Returns the audio focus info
56      */
getAudioFocusInfo()57     public @NonNull AudioFocusInfo getAudioFocusInfo() {
58         return mAudioFocusInfo;
59     }
60 
61     /**
62      * Returns the caudio context as evaluated from the audio attributes
63      */
getAudioContextId()64     public int getAudioContextId() {
65         return mAudioContextId;
66     }
67 
68     /**
69      * Returns the volume group as evaluated from the audio attributes
70      */
getAudioVolumeGroupId()71     public int getAudioVolumeGroupId() {
72         return mAudioVolumeGroupId;
73     }
74 
75     /**
76      * Returns the focus results, must be on of {@link AudioManager.AUDIOFOCUS_GAIN},
77      * {@link AudioManager.AUDIOFOCUS_LOSS}, {@link AudioManager.AUDIOFOCUS_LOSS_TRANSIENT},
78      * {@link AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}
79      **/
getAudioFocusResult()80     public int getAudioFocusResult() {
81         return mAudioFocusResult;
82     }
83 
84     @Override
toString()85     public String toString() {
86         return new StringBuilder().append("AudioFocusEntry { audioFocusInfo = ")
87                 .append(getAudioFocusInfoString()).append(", audioContextId = ")
88                 .append(mAudioContextId).append(", audioVolumeGroupId = ")
89                 .append(mAudioVolumeGroupId).append(", focusResult = ")
90                 .append(mAudioFocusResult).append(" }").toString();
91     }
92 
getAudioFocusInfoString()93     private String getAudioFocusInfoString() {
94         return new StringBuilder().append("{ attributes: ").append(mAudioFocusInfo.getAttributes())
95                 .append(", UID : ").append(mAudioFocusInfo.getClientUid())
96                 .append(", client Id: ").append(mAudioFocusInfo.getClientId())
97                 .append(", pkg: ").append(mAudioFocusInfo.getPackageName())
98                 .append(", gain: ").append(mAudioFocusInfo.getGainRequest())
99                 .append(", loss received: ").append(mAudioFocusInfo.getLossReceived())
100                 .append(", flags: ").append(mAudioFocusInfo.getFlags())
101                 .append("}").toString();
102     }
103 
104     @Override
writeToParcel(@onNull android.os.Parcel dest, int flags)105     public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
106         mAudioFocusInfo.writeToParcel(dest, flags);
107         dest.writeInt(mAudioContextId);
108         dest.writeInt(mAudioVolumeGroupId);
109         dest.writeInt(mAudioFocusResult);
110     }
111 
112     @Override
describeContents()113     public int describeContents() {
114         return 0;
115     }
116 
117     /** @hide */
118     @SuppressWarnings({"unchecked", "RedundantCast"})
119     @VisibleForTesting
AudioFocusEntry(@onNull android.os.Parcel in)120     public AudioFocusEntry(@NonNull android.os.Parcel in) {
121         AudioFocusInfo audioFocusInfo = AudioFocusInfo.CREATOR.createFromParcel(in);
122         int audioContextId = in.readInt();
123         int audioVolumeGroupId = in.readInt();
124         int focusResult = in.readInt();
125 
126         mAudioFocusInfo = audioFocusInfo;
127         mAudioContextId = audioContextId;
128         mAudioVolumeGroupId = audioVolumeGroupId;
129         mAudioFocusResult = focusResult;
130     }
131 
132     @NonNull
133     public static final Parcelable.Creator<AudioFocusEntry> CREATOR =
134             new Parcelable.Creator<>() {
135         @Override
136         public AudioFocusEntry[] newArray(int size) {
137             return new AudioFocusEntry[size];
138         }
139 
140         @Override
141         public AudioFocusEntry createFromParcel(@NonNull android.os.Parcel in) {
142             return new AudioFocusEntry(in);
143         }
144     };
145 
146     @Override
equals(Object o)147     public boolean equals(Object o) {
148         if (this == o) {
149             return true;
150         }
151 
152         if (!(o instanceof AudioFocusEntry)) {
153             return false;
154         }
155 
156         AudioFocusEntry that = (AudioFocusEntry) o;
157 
158         return mAudioContextId == that.mAudioContextId
159                 && mAudioFocusResult == that.mAudioFocusResult
160                 && mAudioVolumeGroupId == that.mAudioVolumeGroupId
161                 && mAudioFocusInfo.equals(that.mAudioFocusInfo);
162     }
163 
164     @Override
hashCode()165     public int hashCode() {
166         return Objects.hash(mAudioFocusInfo.hashCode(), mAudioContextId, mAudioFocusResult,
167                 mAudioVolumeGroupId);
168     }
169 
170     /**
171      * A builder for {@link AudioFocusEntry}
172      */
173     @SuppressWarnings("WeakerAccess")
174     public static final class Builder {
175 
176         private @NonNull AudioFocusInfo mAudioFocusInfo;
177         private int mAudioContextId;
178         private int mAudioVolumeGroupId;
179         private int mAudioFocusResult;
180 
181         private long mBuilderFieldsSet = 0L;
182 
Builder(@onNull AudioFocusEntry entry)183         public Builder(@NonNull AudioFocusEntry entry) {
184             this(Objects.requireNonNull(entry, "Audio focus entry can not be null")
185                             .mAudioFocusInfo, entry.mAudioContextId, entry.mAudioVolumeGroupId,
186                     entry.mAudioFocusResult);
187         }
188 
Builder( @onNull AudioFocusInfo audioFocusInfo, int audioContextId, int audioVolumeGroupId, int focusResult)189         public Builder(
190                 @NonNull AudioFocusInfo audioFocusInfo,
191                 int audioContextId,
192                 int audioVolumeGroupId,
193                 int focusResult) {
194             mAudioFocusInfo = Objects.requireNonNull(audioFocusInfo,
195                     "Audio focus info can not be null");
196             mAudioContextId = audioContextId;
197             mAudioVolumeGroupId = audioVolumeGroupId;
198             mAudioFocusResult = focusResult;
199         }
200 
201         /** see {@link AudioFocusEntry#getAudioFocusInfo()} */
setAudioFocusInfo(@onNull AudioFocusInfo audioFocusInfo)202         public @NonNull Builder setAudioFocusInfo(@NonNull AudioFocusInfo audioFocusInfo) {
203             checkNotUsed();
204             mBuilderFieldsSet |= 0x1;
205             mAudioFocusInfo = Objects.requireNonNull(audioFocusInfo,
206                     "Audio focus info can not be null");
207             return this;
208         }
209 
210         /** see {@link AudioFocusEntry#getAudioContextId()} */
setAudioContextId(int value)211         public @NonNull Builder setAudioContextId(int value) {
212             checkNotUsed();
213             mBuilderFieldsSet |= 0x2;
214             mAudioContextId = value;
215             return this;
216         }
217 
218         /** see {@link AudioFocusEntry#getAudioVolumeGroupId()} */
setAudioVolumeGroupId(int value)219         public @NonNull Builder setAudioVolumeGroupId(int value) {
220             checkNotUsed();
221             mBuilderFieldsSet |= 0x4;
222             mAudioVolumeGroupId = value;
223             return this;
224         }
225 
226         /** see {@link AudioFocusEntry#getAudioFocusResult()} */
setAudioFocusResult(int value)227         public @NonNull Builder setAudioFocusResult(int value) {
228             checkNotUsed();
229             mBuilderFieldsSet |= 0x8;
230             mAudioFocusResult = value;
231             return this;
232         }
233 
234         /** Builds the instance. This builder should not be touched after calling this! */
build()235         public @NonNull AudioFocusEntry build() {
236             checkNotUsed();
237             mBuilderFieldsSet |= 0x10; // Mark builder used
238 
239             AudioFocusEntry o = new AudioFocusEntry(
240                     mAudioFocusInfo,
241                     mAudioContextId,
242                     mAudioVolumeGroupId,
243                     mAudioFocusResult);
244             return o;
245         }
246 
checkNotUsed()247         private void checkNotUsed() {
248             if ((mBuilderFieldsSet & 0x10) != 0) {
249                 throw new IllegalStateException(
250                         "This Builder should not be reused. Use a new Builder instance instead");
251             }
252         }
253     }
254 }
255