CarAudioManager.java revision 150d8de43e71a624106e90bcc04067414c42ef18
1/* 2 * Copyright (C) 2015 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 */ 16package android.car.media; 17 18import android.annotation.IntDef; 19import android.annotation.SystemApi; 20import android.car.CarLibLog; 21import android.car.CarNotConnectedException; 22import android.content.Context; 23import android.media.AudioAttributes; 24import android.media.AudioManager; 25import android.media.AudioManager.OnAudioFocusChangeListener; 26import android.media.IVolumeController; 27import android.os.IBinder; 28import android.os.RemoteException; 29import android.car.CarManagerBase; 30import android.util.Log; 31 32import java.lang.annotation.Retention; 33import java.lang.annotation.RetentionPolicy; 34 35/** 36 * APIs for handling car specific audio stuffs. 37 */ 38public final class CarAudioManager implements CarManagerBase { 39 40 /** 41 * Audio usage for unspecified type. 42 */ 43 public static final int CAR_AUDIO_USAGE_DEFAULT = 0; 44 /** 45 * Audio usage for playing music. 46 */ 47 public static final int CAR_AUDIO_USAGE_MUSIC = 1; 48 /** 49 * Audio usage for H/W radio. 50 */ 51 public static final int CAR_AUDIO_USAGE_RADIO = 2; 52 /** 53 * Audio usage for playing navigation guidance. 54 */ 55 public static final int CAR_AUDIO_USAGE_NAVIGATION_GUIDANCE = 3; 56 /** 57 * Audio usage for voice call 58 */ 59 public static final int CAR_AUDIO_USAGE_VOICE_CALL = 4; 60 /** 61 * Audio usage for voice search or voice command. 62 */ 63 public static final int CAR_AUDIO_USAGE_VOICE_COMMAND = 5; 64 /** 65 * Audio usage for playing alarm. 66 */ 67 public static final int CAR_AUDIO_USAGE_ALARM = 6; 68 /** 69 * Audio usage for notification sound. 70 */ 71 public static final int CAR_AUDIO_USAGE_NOTIFICATION = 7; 72 /** 73 * Audio usage for system sound like UI feedback. 74 */ 75 public static final int CAR_AUDIO_USAGE_SYSTEM_SOUND = 8; 76 /** 77 * Audio usage for playing safety alert. 78 */ 79 public static final int CAR_AUDIO_USAGE_SYSTEM_SAFETY_ALERT = 9; 80 /** 81 * Audio usage for external audio usage. 82 * @hide 83 */ 84 public static final int CAR_AUDIO_USAGE_EXTERNAL_AUDIO_SOURCE = 10; 85 86 /** @hide */ 87 public static final int CAR_AUDIO_USAGE_MAX = CAR_AUDIO_USAGE_EXTERNAL_AUDIO_SOURCE; 88 89 /** @hide */ 90 @IntDef({CAR_AUDIO_USAGE_DEFAULT, CAR_AUDIO_USAGE_MUSIC, CAR_AUDIO_USAGE_RADIO, 91 CAR_AUDIO_USAGE_NAVIGATION_GUIDANCE, CAR_AUDIO_USAGE_VOICE_CALL, 92 CAR_AUDIO_USAGE_VOICE_COMMAND, CAR_AUDIO_USAGE_ALARM, CAR_AUDIO_USAGE_NOTIFICATION, 93 CAR_AUDIO_USAGE_SYSTEM_SOUND, CAR_AUDIO_USAGE_SYSTEM_SAFETY_ALERT, 94 CAR_AUDIO_USAGE_EXTERNAL_AUDIO_SOURCE}) 95 @Retention(RetentionPolicy.SOURCE) 96 public @interface CarAudioUsage {} 97 98 /** @hide */ 99 public static final String CAR_RADIO_TYPE_AM_FM = "RADIO_AM_FM"; 100 /** @hide */ 101 public static final String CAR_RADIO_TYPE_AM_FM_HD = "RADIO_AM_FM_HD"; 102 /** @hide */ 103 public static final String CAR_RADIO_TYPE_DAB = "RADIO_DAB"; 104 /** @hide */ 105 public static final String CAR_RADIO_TYPE_SATELLITE = "RADIO_SATELLITE"; 106 107 /** @hide */ 108 public static final String CAR_EXTERNAL_SOURCE_TYPE_CD_DVD = "CD_DVD"; 109 /** @hide */ 110 public static final String CAR_EXTERNAL_SOURCE_TYPE_AUX_IN0 = "AUX_IN0"; 111 /** @hide */ 112 public static final String CAR_EXTERNAL_SOURCE_TYPE_AUX_IN1 = "AUX_IN1"; 113 /** @hide */ 114 public static final String CAR_EXTERNAL_SOURCE_TYPE_EXT_NAV_GUIDANCE = "EXT_NAV_GUIDANCE"; 115 /** @hide */ 116 public static final String CAR_EXTERNAL_SOURCE_TYPE_EXT_VOICE_CALL = "EXT_VOICE_CALL"; 117 /** @hide */ 118 public static final String CAR_EXTERNAL_SOURCE_TYPE_EXT_VOICE_COMMAND = "EXT_VOICE_COMMAND"; 119 /** @hide */ 120 public static final String CAR_EXTERNAL_SOURCE_TYPE_EXT_SAFETY_ALERT = "EXT_SAFETY_ALERT"; 121 122 private final ICarAudio mService; 123 private final AudioManager mAudioManager; 124 125 /** 126 * Get {@link AudioAttributes} relevant for the given usage in car. 127 * @param carUsage 128 * @return 129 */ 130 public AudioAttributes getAudioAttributesForCarUsage(@CarAudioUsage int carUsage) 131 throws CarNotConnectedException { 132 try { 133 return mService.getAudioAttributesForCarUsage(carUsage); 134 } catch (RemoteException e) { 135 throw new CarNotConnectedException(); 136 } 137 } 138 139 /** 140 * Get AudioAttributes for radio. This is necessary when there are multiple types of radio 141 * in system. 142 * 143 * @param radioType String specifying the desired radio type. Should use only what is listed in 144 * {@link #getSupportedRadioTypes()}. 145 * @return 146 * @throws IllegalArgumentException If not supported type is passed. 147 * 148 * @hide 149 */ 150 public AudioAttributes getAudioAttributesForRadio(String radioType) 151 throws CarNotConnectedException, IllegalArgumentException { 152 try { 153 return mService.getAudioAttributesForRadio(radioType); 154 } catch (RemoteException e) { 155 throw new CarNotConnectedException(); 156 } 157 } 158 159 /** 160 * Get AudioAttributes for external audio source. 161 * 162 * @param externalSourceType String specifying the desired source type. Should use only what is 163 * listed in {@link #getSupportedExternalSourceTypes()}. 164 * @return 165 * @throws IllegalArgumentException If not supported type is passed. 166 * 167 * @hide 168 */ 169 public AudioAttributes getAudioAttributesForExternalSource(String externalSourceType) 170 throws CarNotConnectedException, IllegalArgumentException { 171 try { 172 return mService.getAudioAttributesForExternalSource(externalSourceType); 173 } catch (RemoteException e) { 174 throw new CarNotConnectedException(); 175 } 176 } 177 178 /** 179 * List all supported external audio sources. 180 * 181 * @return 182 * 183 * @hide 184 */ 185 public String[] getSupportedExternalSourceTypes() throws CarNotConnectedException { 186 try { 187 return mService.getSupportedExternalSourceTypes(); 188 } catch (RemoteException e) { 189 throw new CarNotConnectedException(); 190 } 191 } 192 193 /** 194 * List all supported radio sources. 195 * 196 * @return 197 * 198 * @hide 199 */ 200 public String[] getSupportedRadioTypes() throws CarNotConnectedException { 201 try { 202 return mService.getSupportedRadioTypes(); 203 } catch (RemoteException e) { 204 throw new CarNotConnectedException(); 205 } 206 } 207 208 /** 209 * Request audio focus. 210 * Send a request to obtain the audio focus. 211 * @param l 212 * @param requestAttributes 213 * @param durationHint 214 * @param flags 215 */ 216 public int requestAudioFocus(OnAudioFocusChangeListener l, 217 AudioAttributes requestAttributes, 218 int durationHint, 219 int flags) 220 throws CarNotConnectedException, IllegalArgumentException { 221 return mAudioManager.requestAudioFocus(l, requestAttributes, durationHint, flags); 222 } 223 224 /** 225 * Abandon audio focus. Causes the previous focus owner, if any, to receive focus. 226 * @param l 227 * @param aa 228 */ 229 public void abandonAudioFocus(OnAudioFocusChangeListener l, AudioAttributes aa) { 230 mAudioManager.abandonAudioFocus(l, aa); 231 } 232 233 /** 234 * Sets the volume index for a particular stream. 235 * 236 * Requires {@link android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME} permission. 237 * 238 * @param streamType The stream whose volume index should be set. 239 * @param index The volume index to set. See 240 * {@link #getStreamMaxVolume(int)} for the largest valid value. 241 * @param flags One or more flags (e.g., {@link android.media.AudioManager#FLAG_SHOW_UI}, 242 * {@link android.media.AudioManager#FLAG_PLAY_SOUND}) 243 */ 244 @SystemApi 245 public void setStreamVolume(int streamType, int index, int flags) 246 throws CarNotConnectedException { 247 try { 248 mService.setStreamVolume(streamType, index, flags); 249 } catch (RemoteException e) { 250 Log.e(CarLibLog.TAG_CAR, "setStreamVolume failed", e); 251 throw new CarNotConnectedException(e); 252 } 253 } 254 255 /** 256 * Registers a global volume controller interface. 257 * 258 * Requires {@link android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME} permission. 259 * 260 * @hide 261 */ 262 @SystemApi 263 public void setVolumeController(IVolumeController controller) 264 throws CarNotConnectedException { 265 try { 266 mService.setVolumeController(controller); 267 } catch (RemoteException e) { 268 Log.e(CarLibLog.TAG_CAR, "setVolumeController failed", e); 269 throw new CarNotConnectedException(e); 270 } 271 } 272 273 /** 274 * Returns the maximum volume index for a particular stream. 275 * 276 * Requires {@link android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME} permission. 277 * 278 * @param stream The stream type whose maximum volume index is returned. 279 * @return The maximum valid volume index for the stream. 280 */ 281 @SystemApi 282 public int getStreamMaxVolume(int stream) throws CarNotConnectedException { 283 try { 284 return mService.getStreamMaxVolume(stream); 285 } catch (RemoteException e) { 286 Log.e(CarLibLog.TAG_CAR, "getStreamMaxVolume failed", e); 287 throw new CarNotConnectedException(e); 288 } 289 } 290 291 /** 292 * Returns the minimum volume index for a particular stream. 293 * 294 * Requires {@link android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME} permission. 295 * 296 * @param stream The stream type whose maximum volume index is returned. 297 * @return The maximum valid volume index for the stream. 298 */ 299 @SystemApi 300 public int getStreamMinVolume(int stream) throws CarNotConnectedException { 301 try { 302 return mService.getStreamMinVolume(stream); 303 } catch (RemoteException e) { 304 Log.e(CarLibLog.TAG_CAR, "getStreamMaxVolume failed", e); 305 throw new CarNotConnectedException(e); 306 } 307 } 308 309 /** 310 * Returns the current volume index for a particular stream. 311 * 312 * Requires {@link android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME} permission. 313 * 314 * @param stream The stream type whose volume index is returned. 315 * @return The current volume index for the stream. 316 * 317 * @see #getStreamMaxVolume(int) 318 * @see #setStreamVolume(int, int, int) 319 */ 320 @SystemApi 321 public int getStreamVolume(int stream) throws CarNotConnectedException { 322 try { 323 return mService.getStreamVolume(stream); 324 } catch (RemoteException e) { 325 Log.e(CarLibLog.TAG_CAR, "getStreamVolume failed", e); 326 throw new CarNotConnectedException(e); 327 } 328 } 329 330 /** 331 * Check if media audio is muted or not. This will include music and radio. Any application 332 * taking audio focus for media stream will get it out of mute state. 333 * 334 * @return true if media is muted. 335 * @throws CarNotConnectedException if the connection to the car service has been lost. 336 * @hide 337 */ 338 @SystemApi 339 public boolean isMediaMuted() throws CarNotConnectedException { 340 try { 341 return mService.isMediaMuted(); 342 } catch (RemoteException e) { 343 Log.e(CarLibLog.TAG_CAR, "isMediaMuted failed", e); 344 throw new CarNotConnectedException(e); 345 } 346 } 347 348 /** 349 * Mute or unmute media stream including radio. This can involve audio focus change to stop 350 * whatever app holding audio focus now. If requester is currently holding audio focus, 351 * it will get LOSS_TRANSIENT focus loss. 352 * This API requires {@link android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME} permission. 353 * 354 * @param mute 355 * @return Mute state of system after the request. Note that mute request can fail if there 356 * is higher priority audio already being played like phone call. 357 * @throws CarNotConnectedException if the connection to the car service has been lost. 358 * @hide 359 */ 360 @SystemApi 361 public boolean setMediaMute(boolean mute) throws CarNotConnectedException { 362 try { 363 return mService.setMediaMute(mute); 364 } catch (RemoteException e) { 365 Log.e(CarLibLog.TAG_CAR, "setMediaMute failed", e); 366 throw new CarNotConnectedException(e); 367 } 368 } 369 370 /** @hide */ 371 @Override 372 public void onCarDisconnected() { 373 } 374 375 /** @hide */ 376 public CarAudioManager(IBinder service, Context context) { 377 mService = ICarAudio.Stub.asInterface(service); 378 mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 379 } 380 381 private AudioAttributes createAudioAttributes(int contentType, int usage) { 382 AudioAttributes.Builder builder = new AudioAttributes.Builder(); 383 return builder.setContentType(contentType).setUsage(usage).build(); 384 } 385} 386