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