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