CarAudioManager.java revision d72b53500006e84b0c69e650878267c693c164a3
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 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 try { 132 return mService.getAudioAttributesForCarUsage(carUsage); 133 } catch (RemoteException e) { 134 return createAudioAttributes(AudioAttributes.CONTENT_TYPE_UNKNOWN, 135 AudioAttributes.USAGE_UNKNOWN); 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 IllegalArgumentException { 152 try { 153 return mService.getAudioAttributesForRadio(radioType); 154 } catch (RemoteException e) { 155 return createAudioAttributes(AudioAttributes.CONTENT_TYPE_UNKNOWN, 156 AudioAttributes.USAGE_UNKNOWN); 157 } 158 } 159 160 /** 161 * Get AudioAttributes for external audio source. 162 * 163 * @param externalSourceType String specifying the desired source type. Should use only what is 164 * listed in {@link #getSupportedExternalSourceTypes()}. 165 * @return 166 * @throws IllegalArgumentException If not supported type is passed. 167 * 168 * @hide 169 */ 170 public AudioAttributes getAudioAttributesForExternalSource(String externalSourceType) 171 throws IllegalArgumentException { 172 try { 173 return mService.getAudioAttributesForExternalSource(externalSourceType); 174 } catch (RemoteException e) { 175 return createAudioAttributes(AudioAttributes.CONTENT_TYPE_UNKNOWN, 176 AudioAttributes.USAGE_UNKNOWN); 177 } 178 } 179 180 /** 181 * List all supported external audio sources. 182 * 183 * @return 184 * 185 * @hide 186 */ 187 public String[] getSupportedExternalSourceTypes() { 188 try { 189 return mService.getSupportedExternalSourceTypes(); 190 } catch (RemoteException e) { 191 return null; 192 } 193 } 194 195 /** 196 * List all supported radio sources. 197 * 198 * @return 199 * 200 * @hide 201 */ 202 public String[] getSupportedRadioTypes() { 203 try { 204 return mService.getSupportedRadioTypes(); 205 } catch (RemoteException e) { 206 return null; 207 } 208 } 209 210 /** 211 * Request audio focus. 212 * Send a request to obtain the audio focus. 213 * @param l 214 * @param requestAttributes 215 * @param durationHint 216 * @param flags 217 */ 218 public int requestAudioFocus(OnAudioFocusChangeListener l, 219 AudioAttributes requestAttributes, 220 int durationHint, 221 int flags) throws IllegalArgumentException { 222 return mAudioManager.requestAudioFocus(l, requestAttributes, durationHint, flags); 223 } 224 225 /** 226 * Abandon audio focus. Causes the previous focus owner, if any, to receive focus. 227 * @param l 228 * @param aa 229 * @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED} 230 */ 231 public int abandonAudioFocus(OnAudioFocusChangeListener l, AudioAttributes aa) { 232 return mAudioManager.abandonAudioFocus(l, aa); 233 } 234 235 /** 236 * Sets the volume index for a particular stream. 237 * 238 * Requires {@link android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME} permission. 239 * 240 * @param streamType The stream whose volume index should be set. 241 * @param index The volume index to set. See 242 * {@link #getStreamMaxVolume(int)} for the largest valid value. 243 * @param flags One or more flags (e.g., {@link android.media.AudioManager#FLAG_SHOW_UI}, 244 * {@link android.media.AudioManager#FLAG_PLAY_SOUND}) 245 */ 246 @SystemApi 247 public void setStreamVolume(int streamType, int index, int flags) 248 throws CarNotConnectedException { 249 try { 250 mService.setStreamVolume(streamType, index, flags); 251 } catch (RemoteException e) { 252 Log.e(CarLibLog.TAG_CAR, "setStreamVolume failed", e); 253 throw new CarNotConnectedException(e); 254 } 255 } 256 257 /** 258 * Registers a global volume controller interface. 259 * 260 * Requires {@link android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME} permission. 261 * 262 * @hide 263 */ 264 @SystemApi 265 public void setVolumeController(IVolumeController controller) 266 throws CarNotConnectedException { 267 try { 268 mService.setVolumeController(controller); 269 } catch (RemoteException e) { 270 Log.e(CarLibLog.TAG_CAR, "setVolumeController failed", e); 271 throw new CarNotConnectedException(e); 272 } 273 } 274 275 /** 276 * Returns the maximum volume index for a particular stream. 277 * 278 * Requires {@link android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME} permission. 279 * 280 * @param stream The stream type whose maximum volume index is returned. 281 * @return The maximum valid volume index for the stream. 282 */ 283 @SystemApi 284 public int getStreamMaxVolume(int stream) throws CarNotConnectedException { 285 try { 286 return mService.getStreamMaxVolume(stream); 287 } catch (RemoteException e) { 288 Log.e(CarLibLog.TAG_CAR, "getStreamMaxVolume failed", e); 289 throw new CarNotConnectedException(e); 290 } 291 } 292 293 /** 294 * Returns the minimum volume index for a particular stream. 295 * 296 * Requires {@link android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME} permission. 297 * 298 * @param stream The stream type whose maximum volume index is returned. 299 * @return The maximum valid volume index for the stream. 300 */ 301 @SystemApi 302 public int getStreamMinVolume(int stream) throws CarNotConnectedException { 303 try { 304 return mService.getStreamMinVolume(stream); 305 } catch (RemoteException e) { 306 Log.e(CarLibLog.TAG_CAR, "getStreamMaxVolume failed", e); 307 throw new CarNotConnectedException(e); 308 } 309 } 310 311 /** 312 * Returns the current volume index for a particular stream. 313 * 314 * Requires {@link android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME} permission. 315 * 316 * @param stream The stream type whose volume index is returned. 317 * @return The current volume index for the stream. 318 * 319 * @see #getStreamMaxVolume(int) 320 * @see #setStreamVolume(int, int, int) 321 */ 322 @SystemApi 323 public int getStreamVolume(int stream) throws CarNotConnectedException { 324 try { 325 return mService.getStreamVolume(stream); 326 } catch (RemoteException e) { 327 Log.e(CarLibLog.TAG_CAR, "getStreamVolume failed", e); 328 throw new CarNotConnectedException(e); 329 } 330 } 331 332 /** 333 * Check if media audio is muted or not. This will include music and radio. Any application 334 * taking audio focus for media stream will get it out of mute state. 335 * 336 * @return true if media is muted. 337 * @throws CarNotConnectedException if the connection to the car service has been lost. 338 * @hide 339 */ 340 @SystemApi 341 public boolean isMediaMuted() throws CarNotConnectedException { 342 try { 343 return mService.isMediaMuted(); 344 } catch (RemoteException e) { 345 Log.e(CarLibLog.TAG_CAR, "isMediaMuted failed", e); 346 throw new CarNotConnectedException(e); 347 } 348 } 349 350 /** 351 * Mute or unmute media stream including radio. This can involve audio focus change to stop 352 * whatever app holding audio focus now. If requester is currently holding audio focus, 353 * it will get LOSS_TRANSIENT focus loss. 354 * This API requires {@link android.car.Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME} permission. 355 * 356 * @param mute 357 * @return Mute state of system after the request. Note that mute request can fail if there 358 * is higher priority audio already being played like phone call. 359 * @throws CarNotConnectedException if the connection to the car service has been lost. 360 * @hide 361 */ 362 @SystemApi 363 public boolean setMediaMute(boolean mute) throws CarNotConnectedException { 364 try { 365 return mService.setMediaMute(mute); 366 } catch (RemoteException e) { 367 Log.e(CarLibLog.TAG_CAR, "setMediaMute failed", e); 368 throw new CarNotConnectedException(e); 369 } 370 } 371 372 @Override 373 public void onCarDisconnected() { 374 } 375 376 /** @hide */ 377 public CarAudioManager(IBinder service, Context context) { 378 mService = ICarAudio.Stub.asInterface(service); 379 mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 380 } 381 382 private AudioAttributes createAudioAttributes(int contentType, int usage) { 383 AudioAttributes.Builder builder = new AudioAttributes.Builder(); 384 return builder.setContentType(contentType).setUsage(usage).build(); 385 } 386} 387