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