1 /*
2  * Copyright (C) 2014 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.media;
18 
19 import android.annotation.SystemApi;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 
23 import java.util.Objects;
24 
25 /**
26  * @hide
27  * A class to encapsulate information about an audio focus owner or request.
28  */
29 @SystemApi
30 public final class AudioFocusInfo implements Parcelable {
31 
32     private final AudioAttributes mAttributes;
33     private final int mClientUid;
34     private final String mClientId;
35     private final String mPackageName;
36     private final int mSdkTarget;
37     private int mGainRequest;
38     private int mLossReceived;
39     private int mFlags;
40 
41     // generation count for the validity of a request/response async exchange between
42     // external focus policy and MediaFocusControl
43     private long mGenCount = -1;
44 
45 
46     /**
47      * Class constructor
48      * @param aa
49      * @param clientId
50      * @param packageName
51      * @param gainRequest
52      * @param lossReceived
53      * @param flags
54      * @hide
55      */
AudioFocusInfo(AudioAttributes aa, int clientUid, String clientId, String packageName, int gainRequest, int lossReceived, int flags, int sdk)56     public AudioFocusInfo(AudioAttributes aa, int clientUid, String clientId, String packageName,
57             int gainRequest, int lossReceived, int flags, int sdk) {
58         mAttributes = aa == null ? new AudioAttributes.Builder().build() : aa;
59         mClientUid = clientUid;
60         mClientId = clientId == null ? "" : clientId;
61         mPackageName = packageName == null ? "" : packageName;
62         mGainRequest = gainRequest;
63         mLossReceived = lossReceived;
64         mFlags = flags;
65         mSdkTarget = sdk;
66     }
67 
68     /** @hide */
setGen(long g)69     public void setGen(long g) {
70         mGenCount = g;
71     }
72 
73     /** @hide */
getGen()74     public long getGen() {
75         return mGenCount;
76     }
77 
78 
79     /**
80      * The audio attributes for the audio focus request.
81      * @return non-null {@link AudioAttributes}.
82      */
83     @SystemApi
getAttributes()84     public AudioAttributes getAttributes() { return mAttributes; }
85 
86     @SystemApi
getClientUid()87     public int getClientUid() { return mClientUid; }
88 
89     @SystemApi
getClientId()90     public String getClientId() { return mClientId; }
91 
92     @SystemApi
getPackageName()93     public String getPackageName() { return mPackageName; }
94 
95     /**
96      * The type of audio focus gain request.
97      * @return one of {@link AudioManager#AUDIOFOCUS_GAIN},
98      *     {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT},
99      *     {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK},
100      *     {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}.
101      */
102     @SystemApi
getGainRequest()103     public int getGainRequest() { return mGainRequest; }
104 
105     /**
106      * The type of audio focus loss that was received by the
107      * {@link AudioManager.OnAudioFocusChangeListener} if one was set.
108      * @return 0 if focus wasn't lost, or one of {@link AudioManager#AUDIOFOCUS_LOSS},
109      *   {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT} or
110      *   {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}.
111      */
112     @SystemApi
getLossReceived()113     public int getLossReceived() { return mLossReceived; }
114 
115     /** @hide */
getSdkTarget()116     public int getSdkTarget() { return mSdkTarget; }
117 
118     /** @hide */
clearLossReceived()119     public void clearLossReceived() { mLossReceived = 0; }
120 
121     /**
122      * The flags set in the audio focus request.
123      * @return 0 or a combination of {link AudioManager#AUDIOFOCUS_FLAG_DELAY_OK},
124      *     {@link AudioManager#AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS}, and
125      *     {@link AudioManager#AUDIOFOCUS_FLAG_LOCK}.
126      */
127     @SystemApi
getFlags()128     public int getFlags() { return mFlags; }
129 
130     @Override
describeContents()131     public int describeContents() {
132         return 0;
133     }
134 
135     @Override
writeToParcel(Parcel dest, int flags)136     public void writeToParcel(Parcel dest, int flags) {
137         mAttributes.writeToParcel(dest, flags);
138         dest.writeInt(mClientUid);
139         dest.writeString(mClientId);
140         dest.writeString(mPackageName);
141         dest.writeInt(mGainRequest);
142         dest.writeInt(mLossReceived);
143         dest.writeInt(mFlags);
144         dest.writeInt(mSdkTarget);
145         dest.writeLong(mGenCount);
146     }
147 
148     @Override
hashCode()149     public int hashCode() {
150         return Objects.hash(mAttributes, mClientUid, mClientId, mPackageName, mGainRequest, mFlags);
151     }
152 
153     @Override
equals(Object obj)154     public boolean equals(Object obj) {
155         if (this == obj)
156             return true;
157         if (obj == null)
158             return false;
159         if (getClass() != obj.getClass())
160             return false;
161         AudioFocusInfo other = (AudioFocusInfo) obj;
162         if (!mAttributes.equals(other.mAttributes)) {
163             return false;
164         }
165         if (mClientUid != other.mClientUid) {
166             return false;
167         }
168         if (!mClientId.equals(other.mClientId)) {
169             return false;
170         }
171         if (!mPackageName.equals(other.mPackageName)) {
172             return false;
173         }
174         if (mGainRequest != other.mGainRequest) {
175             return false;
176         }
177         if (mLossReceived != other.mLossReceived) {
178             return false;
179         }
180         if (mFlags != other.mFlags) {
181             return false;
182         }
183         if (mSdkTarget != other.mSdkTarget) {
184             return false;
185         }
186         // mGenCount is not used to verify equality between two focus holds as multiple requests
187         // (hence of different generations) could correspond to the same hold
188         return true;
189     }
190 
191     public static final Parcelable.Creator<AudioFocusInfo> CREATOR
192             = new Parcelable.Creator<AudioFocusInfo>() {
193 
194         public AudioFocusInfo createFromParcel(Parcel in) {
195             final AudioFocusInfo afi = new AudioFocusInfo(
196                     AudioAttributes.CREATOR.createFromParcel(in), //AudioAttributes aa
197                     in.readInt(), // int clientUid
198                     in.readString(), //String clientId
199                     in.readString(), //String packageName
200                     in.readInt(), //int gainRequest
201                     in.readInt(), //int lossReceived
202                     in.readInt(), //int flags
203                     in.readInt()  //int sdkTarget
204                     );
205             afi.setGen(in.readLong());
206             return afi;
207         }
208 
209         public AudioFocusInfo[] newArray(int size) {
210             return new AudioFocusInfo[size];
211         }
212     };
213 }
214