AudioAttributes.java revision 6894cd38ebb619a0b7e47831b623655c9c0f6e12
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 17package android.media; 18 19import android.annotation.IntDef; 20import android.annotation.SystemApi; 21import android.os.Parcel; 22import android.os.Parcelable; 23import android.text.TextUtils; 24import android.util.Log; 25 26import java.lang.annotation.Retention; 27import java.lang.annotation.RetentionPolicy; 28import java.util.Collections; 29import java.util.HashSet; 30import java.util.Iterator; 31import java.util.Objects; 32import java.util.Set; 33 34/** 35 * A class to encapsulate a collection of attributes describing information about an audio 36 * player or recorder. 37 */ 38public final class AudioAttributes implements Parcelable { 39 private final static String TAG = "AudioAttributes"; 40 41 /** 42 * Content type value to use when the content type is unknown, or other than the ones defined. 43 */ 44 public final static int CONTENT_TYPE_UNKNOWN = 0; 45 /** 46 * Content type value to use when the content type is speech. 47 */ 48 public final static int CONTENT_TYPE_SPEECH = 1; 49 /** 50 * Content type value to use when the content type is music. 51 */ 52 public final static int CONTENT_TYPE_MUSIC = 2; 53 /** 54 * Content type value to use when the content type is a soundtrack, typically accompanying 55 * a movie or TV program. 56 */ 57 public final static int CONTENT_TYPE_MOVIE = 3; 58 /** 59 * Content type value to use when the content type is a sound used to accompany a user 60 * action, such as a beep or sound effect expressing a key click, or event, such as the 61 * type of a sound for a bonus being received in a game. These sounds are mostly synthesized 62 * or short Foley sounds. 63 */ 64 public final static int CONTENT_TYPE_SONIFICATION = 4; 65 66 /** 67 * Usage value to use when the usage is unknown. 68 */ 69 public final static int USAGE_UNKNOWN = 0; 70 /** 71 * Usage value to use when the usage is media, such as music, or movie 72 * soundtracks. 73 */ 74 public final static int USAGE_MEDIA = 1; 75 /** 76 * Usage value to use when the usage is voice communications, such as telephony 77 * or VoIP. 78 */ 79 public final static int USAGE_VOICE_COMMUNICATION = 2; 80 /** 81 * Usage value to use when the usage is in-call signalling, such as with 82 * a "busy" beep, or DTMF tones. 83 */ 84 public final static int USAGE_VOICE_COMMUNICATION_SIGNALLING = 3; 85 /** 86 * Usage value to use when the usage is an alarm (e.g. wake-up alarm). 87 */ 88 public final static int USAGE_ALARM = 4; 89 /** 90 * Usage value to use when the usage is notification. See other 91 * notification usages for more specialized uses. 92 */ 93 public final static int USAGE_NOTIFICATION = 5; 94 /** 95 * Usage value to use when the usage is telephony ringtone. 96 */ 97 public final static int USAGE_NOTIFICATION_RINGTONE = 6; 98 /** 99 * Usage value to use when the usage is a request to enter/end a 100 * communication, such as a VoIP communication or video-conference. 101 */ 102 public final static int USAGE_NOTIFICATION_COMMUNICATION_REQUEST = 7; 103 /** 104 * Usage value to use when the usage is notification for an "instant" 105 * communication such as a chat, or SMS. 106 */ 107 public final static int USAGE_NOTIFICATION_COMMUNICATION_INSTANT = 8; 108 /** 109 * Usage value to use when the usage is notification for a 110 * non-immediate type of communication such as e-mail. 111 */ 112 public final static int USAGE_NOTIFICATION_COMMUNICATION_DELAYED = 9; 113 /** 114 * Usage value to use when the usage is to attract the user's attention, 115 * such as a reminder or low battery warning. 116 */ 117 public final static int USAGE_NOTIFICATION_EVENT = 10; 118 /** 119 * Usage value to use when the usage is for accessibility, such as with 120 * a screen reader. 121 */ 122 public final static int USAGE_ASSISTANCE_ACCESSIBILITY = 11; 123 /** 124 * Usage value to use when the usage is driving or navigation directions. 125 */ 126 public final static int USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12; 127 /** 128 * Usage value to use when the usage is sonification, such as with user 129 * interface sounds. 130 */ 131 public final static int USAGE_ASSISTANCE_SONIFICATION = 13; 132 /** 133 * Usage value to use when the usage is for game audio. 134 */ 135 public final static int USAGE_GAME = 14; 136 137 /** 138 * Flag defining a behavior where the audibility of the sound will be ensured by the system. 139 */ 140 public final static int FLAG_AUDIBILITY_ENFORCED = 0x1 << 0; 141 /** 142 * @hide 143 * Flag defining a behavior where the playback of the sound is ensured without 144 * degradation only when going to a secure sink. 145 */ 146 // FIXME not guaranteed yet 147 // TODO add in FLAG_ALL_PUBLIC when supported and in public API 148 public final static int FLAG_SECURE = 0x1 << 1; 149 /** 150 * @hide 151 * Flag to enable when the stream is associated with SCO usage. 152 * Internal use only for dealing with legacy STREAM_BLUETOOTH_SCO 153 */ 154 public final static int FLAG_SCO = 0x1 << 2; 155 /** 156 * @hide 157 * Flag defining a behavior where the system ensures that the playback of the sound will 158 * be compatible with its use as a broadcast for surrounding people and/or devices. 159 * Ensures audibility with no or minimal post-processing applied. 160 */ 161 @SystemApi 162 public final static int FLAG_BEACON = 0x1 << 3; 163 164 /** 165 * @hide 166 * CANDIDATE FOR PUBLIC API 167 * Flag requesting the use of an output stream supporting hardware A/V synchronization. 168 */ 169 // TODO add in FLAG_ALL_PUBLIC when in public API 170 public final static int FLAG_HW_AV_SYNC = 0x1 << 4; 171 172 private final static int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO | 173 FLAG_BEACON | FLAG_HW_AV_SYNC; 174 private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED; 175 176 private int mUsage = USAGE_UNKNOWN; 177 private int mContentType = CONTENT_TYPE_UNKNOWN; 178 private int mSource = MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID; 179 private int mFlags = 0x0; 180 private HashSet<String> mTags; 181 private String mFormattedTags; 182 183 private AudioAttributes() { 184 } 185 186 /** 187 * Return the content type. 188 * @return one of the values that can be set in {@link Builder#setContentType(int)} 189 */ 190 public int getContentType() { 191 return mContentType; 192 } 193 194 /** 195 * Return the usage. 196 * @return one of the values that can be set in {@link Builder#setUsage(int)} 197 */ 198 public int getUsage() { 199 return mUsage; 200 } 201 202 /** 203 * @hide 204 * CANDIDATE FOR PUBLIC API 205 * Return the capture preset. 206 * @return one of the values that can be set in {@link Builder#setCapturePreset(int)} or a 207 * negative value if none has been set. 208 */ 209 public int getCapturePreset() { 210 return mSource; 211 } 212 213 /** 214 * Return the flags. 215 * @return a combined mask of all flags 216 */ 217 public int getFlags() { 218 // only return the flags that are public 219 return (mFlags & (FLAG_ALL_PUBLIC)); 220 } 221 222 /** 223 * @hide 224 * Return all the flags, even the non-public ones. 225 * Internal use only 226 * @return a combined mask of all flags 227 */ 228 public int getAllFlags() { 229 return (mFlags & FLAG_ALL); 230 } 231 232 /** 233 * @hide 234 * Return the set of tags. 235 * @return a read-only set of all tags stored as strings. 236 */ 237 public Set<String> getTags() { 238 return Collections.unmodifiableSet(mTags); 239 } 240 241 /** 242 * Builder class for {@link AudioAttributes} objects. 243 */ 244 public static class Builder { 245 private int mUsage = USAGE_UNKNOWN; 246 private int mContentType = CONTENT_TYPE_UNKNOWN; 247 private int mSource = MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID; 248 private int mFlags = 0x0; 249 private HashSet<String> mTags = new HashSet<String>(); 250 251 /** 252 * Constructs a new Builder with the defaults. 253 */ 254 public Builder() { 255 } 256 257 /** 258 * Constructs a new Builder from a given AudioAttributes 259 * @param aa the AudioAttributes object whose data will be reused in the new Builder. 260 */ 261 @SuppressWarnings("unchecked") // for cloning of mTags 262 public Builder(AudioAttributes aa) { 263 mUsage = aa.mUsage; 264 mContentType = aa.mContentType; 265 mFlags = aa.mFlags; 266 mTags = (HashSet<String>) aa.mTags.clone(); 267 } 268 269 /** 270 * Combines all of the attributes that have been set and return a new 271 * {@link AudioAttributes} object. 272 * @return a new {@link AudioAttributes} object 273 */ 274 @SuppressWarnings("unchecked") // for cloning of mTags 275 public AudioAttributes build() { 276 AudioAttributes aa = new AudioAttributes(); 277 aa.mContentType = mContentType; 278 aa.mUsage = mUsage; 279 aa.mSource = mSource; 280 aa.mFlags = mFlags; 281 aa.mTags = (HashSet<String>) mTags.clone(); 282 aa.mFormattedTags = TextUtils.join(";", mTags); 283 return aa; 284 } 285 286 /** 287 * Sets the attribute describing what is the intended use of the the audio signal, 288 * such as alarm or ringtone. 289 * @param usage one of {@link AudioAttributes#USAGE_UNKNOWN}, 290 * {@link AudioAttributes#USAGE_MEDIA}, 291 * {@link AudioAttributes#USAGE_VOICE_COMMUNICATION}, 292 * {@link AudioAttributes#USAGE_VOICE_COMMUNICATION_SIGNALLING}, 293 * {@link AudioAttributes#USAGE_ALARM}, {@link AudioAttributes#USAGE_NOTIFICATION}, 294 * {@link AudioAttributes#USAGE_NOTIFICATION_RINGTONE}, 295 * {@link AudioAttributes#USAGE_NOTIFICATION_COMMUNICATION_REQUEST}, 296 * {@link AudioAttributes#USAGE_NOTIFICATION_COMMUNICATION_INSTANT}, 297 * {@link AudioAttributes#USAGE_NOTIFICATION_COMMUNICATION_DELAYED}, 298 * {@link AudioAttributes#USAGE_NOTIFICATION_EVENT}, 299 * {@link AudioAttributes#USAGE_ASSISTANCE_ACCESSIBILITY}, 300 * {@link AudioAttributes#USAGE_ASSISTANCE_NAVIGATION_GUIDANCE}, 301 * {@link AudioAttributes#USAGE_ASSISTANCE_SONIFICATION}, 302 * {@link AudioAttributes#USAGE_GAME}. 303 * @return the same Builder instance. 304 */ 305 public Builder setUsage(@AttributeUsage int usage) { 306 switch (usage) { 307 case USAGE_UNKNOWN: 308 case USAGE_MEDIA: 309 case USAGE_VOICE_COMMUNICATION: 310 case USAGE_VOICE_COMMUNICATION_SIGNALLING: 311 case USAGE_ALARM: 312 case USAGE_NOTIFICATION: 313 case USAGE_NOTIFICATION_RINGTONE: 314 case USAGE_NOTIFICATION_COMMUNICATION_REQUEST: 315 case USAGE_NOTIFICATION_COMMUNICATION_INSTANT: 316 case USAGE_NOTIFICATION_COMMUNICATION_DELAYED: 317 case USAGE_NOTIFICATION_EVENT: 318 case USAGE_ASSISTANCE_ACCESSIBILITY: 319 case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: 320 case USAGE_ASSISTANCE_SONIFICATION: 321 case USAGE_GAME: 322 mUsage = usage; 323 break; 324 default: 325 mUsage = USAGE_UNKNOWN; 326 } 327 return this; 328 } 329 330 /** 331 * Sets the attribute describing the content type of the audio signal, such as speech, 332 * or music. 333 * @param contentType the content type values, one of 334 * {@link AudioAttributes#CONTENT_TYPE_MOVIE}, 335 * {@link AudioAttributes#CONTENT_TYPE_MUSIC}, 336 * {@link AudioAttributes#CONTENT_TYPE_SONIFICATION}, 337 * {@link AudioAttributes#CONTENT_TYPE_SPEECH}, 338 * {@link AudioAttributes#CONTENT_TYPE_UNKNOWN}. 339 * @return the same Builder instance. 340 */ 341 public Builder setContentType(@AttributeContentType int contentType) { 342 switch (contentType) { 343 case CONTENT_TYPE_UNKNOWN: 344 case CONTENT_TYPE_MOVIE: 345 case CONTENT_TYPE_MUSIC: 346 case CONTENT_TYPE_SONIFICATION: 347 case CONTENT_TYPE_SPEECH: 348 mContentType = contentType; 349 break; 350 default: 351 mUsage = CONTENT_TYPE_UNKNOWN; 352 } 353 return this; 354 } 355 356 /** 357 * Sets the combination of flags. 358 * @param flags the {@link AudioAttributes#FLAG_AUDIBILITY_ENFORCED} flag. 359 * @return the same Builder instance. 360 */ 361 public Builder setFlags(int flags) { 362 flags &= AudioAttributes.FLAG_ALL; 363 mFlags |= flags; 364 return this; 365 } 366 367 /** 368 * @hide 369 * Add a custom tag stored as a string 370 * @param tag 371 * @return the same Builder instance. 372 */ 373 public Builder addTag(String tag) { 374 mTags.add(tag); 375 return this; 376 } 377 378 /** 379 * Adds attributes inferred from the legacy stream types. 380 * @param streamType one of {@link AudioManager#STREAM_VOICE_CALL}, 381 * {@link AudioManager#STREAM_SYSTEM}, {@link AudioManager#STREAM_RING}, 382 * {@link AudioManager#STREAM_MUSIC}, {@link AudioManager#STREAM_ALARM}, 383 * or {@link AudioManager#STREAM_NOTIFICATION}. 384 * @return the same Builder instance. 385 */ 386 public Builder setLegacyStreamType(int streamType) { 387 return setInternalLegacyStreamType(streamType); 388 } 389 390 /** 391 * @hide 392 * For internal framework use only, enables building from hidden stream types. 393 * @param streamType 394 * @return the same Builder instance. 395 */ 396 public Builder setInternalLegacyStreamType(int streamType) { 397 switch(streamType) { 398 case AudioSystem.STREAM_VOICE_CALL: 399 mContentType = CONTENT_TYPE_SPEECH; 400 break; 401 case AudioSystem.STREAM_SYSTEM_ENFORCED: 402 mFlags |= FLAG_AUDIBILITY_ENFORCED; 403 // intended fall through, attributes in common with STREAM_SYSTEM 404 case AudioSystem.STREAM_SYSTEM: 405 mContentType = CONTENT_TYPE_SONIFICATION; 406 break; 407 case AudioSystem.STREAM_RING: 408 mContentType = CONTENT_TYPE_SONIFICATION; 409 break; 410 case AudioSystem.STREAM_MUSIC: 411 mContentType = CONTENT_TYPE_MUSIC; 412 break; 413 case AudioSystem.STREAM_ALARM: 414 mContentType = CONTENT_TYPE_SONIFICATION; 415 break; 416 case AudioSystem.STREAM_NOTIFICATION: 417 mContentType = CONTENT_TYPE_SONIFICATION; 418 break; 419 case AudioSystem.STREAM_BLUETOOTH_SCO: 420 mContentType = CONTENT_TYPE_SPEECH; 421 mFlags |= FLAG_SCO; 422 break; 423 case AudioSystem.STREAM_DTMF: 424 mContentType = CONTENT_TYPE_SONIFICATION; 425 break; 426 case AudioSystem.STREAM_TTS: 427 mContentType = CONTENT_TYPE_SPEECH; 428 break; 429 default: 430 Log.e(TAG, "Invalid stream type " + streamType + " for AudioAttributes"); 431 } 432 mUsage = usageForLegacyStreamType(streamType); 433 return this; 434 } 435 436 /** 437 * @hide 438 * CANDIDATE FOR PUBLIC API 439 * Sets the capture preset. 440 * Use this audio attributes configuration method when building an {@link AudioRecord} 441 * instance with {@link AudioRecord#AudioRecord(AudioAttributes, AudioFormat, int)}. 442 * @param preset one of {@link MediaRecorder.AudioSource#DEFAULT}, 443 * {@link MediaRecorder.AudioSource#MIC}, {@link MediaRecorder.AudioSource#CAMCORDER}, 444 * {@link MediaRecorder.AudioSource#VOICE_RECOGNITION} or 445 * {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION}. 446 * @return the same Builder instance. 447 */ 448 public Builder setCapturePreset(int preset) { 449 switch (preset) { 450 case MediaRecorder.AudioSource.DEFAULT: 451 case MediaRecorder.AudioSource.MIC: 452 case MediaRecorder.AudioSource.CAMCORDER: 453 case MediaRecorder.AudioSource.VOICE_RECOGNITION: 454 case MediaRecorder.AudioSource.VOICE_COMMUNICATION: 455 mSource = preset; 456 break; 457 default: 458 Log.e(TAG, "Invalid capture preset " + preset + " for AudioAttributes"); 459 } 460 return this; 461 } 462 463 /** 464 * @hide 465 * Same as {@link #setCapturePreset(int)} but authorizes the use of HOTWORD and 466 * REMOTE_SUBMIX. 467 * @param preset 468 * @return the same Builder instance. 469 */ 470 public Builder setInternalCapturePreset(int preset) { 471 if ((preset == MediaRecorder.AudioSource.HOTWORD) 472 || (preset == MediaRecorder.AudioSource.REMOTE_SUBMIX)) { 473 mSource = preset; 474 } else { 475 setCapturePreset(preset); 476 } 477 return this; 478 } 479 }; 480 481 @Override 482 public int describeContents() { 483 return 0; 484 } 485 486 /** 487 * @hide 488 * Used to indicate that when parcelling, the tags should be parcelled through the flattened 489 * formatted string, not through the array of strings. 490 * Keep in sync with frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp 491 * see definition of kAudioAttributesMarshallTagFlattenTags 492 */ 493 public final static int FLATTEN_TAGS = 0x1; 494 /** 495 * When adding tags for writeToParcel(Parcel, int), add them in the list of flags (| NEW_FLAG) 496 */ 497 private final static int ALL_PARCEL_FLAGS = FLATTEN_TAGS; 498 @Override 499 public void writeToParcel(Parcel dest, int flags) { 500 dest.writeInt(mUsage); 501 dest.writeInt(mContentType); 502 dest.writeInt(mSource); 503 dest.writeInt(mFlags); 504 dest.writeInt(flags & ALL_PARCEL_FLAGS); 505 if ((flags & FLATTEN_TAGS) == 0) { 506 String[] tagsArray = new String[mTags.size()]; 507 mTags.toArray(tagsArray); 508 dest.writeStringArray(tagsArray); 509 } else if ((flags & FLATTEN_TAGS) == FLATTEN_TAGS) { 510 dest.writeString(mFormattedTags); 511 } 512 } 513 514 private AudioAttributes(Parcel in) { 515 mUsage = in.readInt(); 516 mContentType = in.readInt(); 517 mSource = in.readInt(); 518 mFlags = in.readInt(); 519 boolean hasFlattenedTags = ((in.readInt() & FLATTEN_TAGS) == FLATTEN_TAGS); 520 mTags = new HashSet<String>(); 521 if (hasFlattenedTags) { 522 mFormattedTags = new String(in.readString()); 523 mTags.add(mFormattedTags); 524 } else { 525 String[] tagsArray = in.readStringArray(); 526 for (int i = tagsArray.length - 1 ; i >= 0 ; i--) { 527 mTags.add(tagsArray[i]); 528 } 529 mFormattedTags = TextUtils.join(";", mTags); 530 } 531 } 532 533 /** @hide */ 534 public static final Parcelable.Creator<AudioAttributes> CREATOR 535 = new Parcelable.Creator<AudioAttributes>() { 536 /** 537 * Rebuilds an AudioAttributes previously stored with writeToParcel(). 538 * @param p Parcel object to read the AudioAttributes from 539 * @return a new AudioAttributes created from the data in the parcel 540 */ 541 public AudioAttributes createFromParcel(Parcel p) { 542 return new AudioAttributes(p); 543 } 544 public AudioAttributes[] newArray(int size) { 545 return new AudioAttributes[size]; 546 } 547 }; 548 549 @Override 550 public boolean equals(Object o) { 551 if (this == o) return true; 552 if (o == null || getClass() != o.getClass()) return false; 553 554 AudioAttributes that = (AudioAttributes) o; 555 556 return ((mContentType == that.mContentType) 557 && (mFlags == that.mFlags) 558 && (mSource == that.mSource) 559 && (mUsage == that.mUsage) 560 //mFormattedTags is never null due to assignment in Builder or unmarshalling 561 && (mFormattedTags.equals(that.mFormattedTags))); 562 } 563 564 @Override 565 public int hashCode() { 566 return Objects.hash(mContentType, mFlags, mSource, mUsage, mFormattedTags); 567 } 568 569 @Override 570 public String toString () { 571 return new String("AudioAttributes:" 572 + " usage=" + mUsage 573 + " content=" + mContentType 574 + " flags=0x" + Integer.toHexString(mFlags).toUpperCase() 575 + " tags=" + mFormattedTags); 576 } 577 578 /** @hide */ 579 public String usageToString() { 580 return usageToString(mUsage); 581 } 582 583 /** @hide */ 584 public static String usageToString(int usage) { 585 switch(usage) { 586 case USAGE_UNKNOWN: 587 return new String("USAGE_UNKNOWN"); 588 case USAGE_MEDIA: 589 return new String("USAGE_MEDIA"); 590 case USAGE_VOICE_COMMUNICATION: 591 return new String("USAGE_VOICE_COMMUNICATION"); 592 case USAGE_VOICE_COMMUNICATION_SIGNALLING: 593 return new String("USAGE_VOICE_COMMUNICATION"); 594 case USAGE_ALARM: 595 return new String("USAGE_ALARM"); 596 case USAGE_NOTIFICATION: 597 return new String("USAGE_NOTIFICATION"); 598 case USAGE_NOTIFICATION_RINGTONE: 599 return new String("USAGE_NOTIFICATION"); 600 case USAGE_NOTIFICATION_COMMUNICATION_REQUEST: 601 return new String("USAGE_NOTIFICATION"); 602 case USAGE_NOTIFICATION_COMMUNICATION_INSTANT: 603 return new String("USAGE_NOTIFICATION_COMMUNICATION_INSTANT"); 604 case USAGE_NOTIFICATION_COMMUNICATION_DELAYED: 605 return new String("USAGE_NOTIFICATION_COMMUNICATION_DELAYED"); 606 case USAGE_NOTIFICATION_EVENT: 607 return new String("USAGE_NOTIFICATION_EVENT"); 608 case USAGE_ASSISTANCE_ACCESSIBILITY: 609 return new String("USAGE_ASSISTANCE_ACCESSIBILITY"); 610 case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: 611 return new String("USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"); 612 case USAGE_ASSISTANCE_SONIFICATION: 613 return new String("USAGE_ASSISTANCE_SONIFICATION"); 614 case USAGE_GAME: 615 return new String("USAGE_GAME"); 616 default: 617 return new String("unknown usage " + usage); 618 } 619 } 620 621 /** @hide */ 622 public static int usageForLegacyStreamType(int streamType) { 623 switch(streamType) { 624 case AudioSystem.STREAM_VOICE_CALL: 625 return USAGE_VOICE_COMMUNICATION; 626 case AudioSystem.STREAM_SYSTEM_ENFORCED: 627 case AudioSystem.STREAM_SYSTEM: 628 return USAGE_ASSISTANCE_SONIFICATION; 629 case AudioSystem.STREAM_RING: 630 return USAGE_NOTIFICATION_RINGTONE; 631 case AudioSystem.STREAM_MUSIC: 632 return USAGE_MEDIA; 633 case AudioSystem.STREAM_ALARM: 634 return USAGE_ALARM; 635 case AudioSystem.STREAM_NOTIFICATION: 636 return USAGE_NOTIFICATION; 637 case AudioSystem.STREAM_BLUETOOTH_SCO: 638 return USAGE_VOICE_COMMUNICATION; 639 case AudioSystem.STREAM_DTMF: 640 return USAGE_VOICE_COMMUNICATION_SIGNALLING; 641 case AudioSystem.STREAM_TTS: 642 return USAGE_ASSISTANCE_ACCESSIBILITY; 643 default: 644 return USAGE_UNKNOWN; 645 } 646 } 647 648 /** @hide */ 649 public static int toLegacyStreamType(AudioAttributes aa) { 650 // flags to stream type mapping 651 if ((aa.getFlags() & FLAG_AUDIBILITY_ENFORCED) == FLAG_AUDIBILITY_ENFORCED) { 652 return AudioSystem.STREAM_SYSTEM_ENFORCED; 653 } 654 if ((aa.getFlags() & FLAG_SCO) == FLAG_SCO) { 655 return AudioSystem.STREAM_BLUETOOTH_SCO; 656 } 657 658 // usage to stream type mapping 659 switch (aa.getUsage()) { 660 case USAGE_MEDIA: 661 case USAGE_GAME: 662 case USAGE_ASSISTANCE_ACCESSIBILITY: 663 case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: 664 return AudioSystem.STREAM_MUSIC; 665 case USAGE_ASSISTANCE_SONIFICATION: 666 return AudioSystem.STREAM_SYSTEM; 667 case USAGE_VOICE_COMMUNICATION: 668 return AudioSystem.STREAM_VOICE_CALL; 669 case USAGE_VOICE_COMMUNICATION_SIGNALLING: 670 return AudioSystem.STREAM_DTMF; 671 case USAGE_ALARM: 672 return AudioSystem.STREAM_ALARM; 673 case USAGE_NOTIFICATION_RINGTONE: 674 return AudioSystem.STREAM_RING; 675 case USAGE_NOTIFICATION: 676 case USAGE_NOTIFICATION_COMMUNICATION_REQUEST: 677 case USAGE_NOTIFICATION_COMMUNICATION_INSTANT: 678 case USAGE_NOTIFICATION_COMMUNICATION_DELAYED: 679 case USAGE_NOTIFICATION_EVENT: 680 return AudioSystem.STREAM_NOTIFICATION; 681 case USAGE_UNKNOWN: 682 default: 683 return AudioSystem.STREAM_MUSIC; 684 } 685 } 686 687 /** @hide */ 688 @IntDef({ 689 USAGE_UNKNOWN, 690 USAGE_MEDIA, 691 USAGE_VOICE_COMMUNICATION, 692 USAGE_VOICE_COMMUNICATION_SIGNALLING, 693 USAGE_ALARM, 694 USAGE_NOTIFICATION, 695 USAGE_NOTIFICATION_RINGTONE, 696 USAGE_NOTIFICATION_COMMUNICATION_REQUEST, 697 USAGE_NOTIFICATION_COMMUNICATION_INSTANT, 698 USAGE_NOTIFICATION_COMMUNICATION_DELAYED, 699 USAGE_NOTIFICATION_EVENT, 700 USAGE_ASSISTANCE_ACCESSIBILITY, 701 USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, 702 USAGE_ASSISTANCE_SONIFICATION, 703 USAGE_GAME 704 }) 705 @Retention(RetentionPolicy.SOURCE) 706 public @interface AttributeUsage {} 707 708 /** @hide */ 709 @IntDef({ 710 CONTENT_TYPE_UNKNOWN, 711 CONTENT_TYPE_SPEECH, 712 CONTENT_TYPE_MUSIC, 713 CONTENT_TYPE_MOVIE, 714 CONTENT_TYPE_SONIFICATION 715 }) 716 @Retention(RetentionPolicy.SOURCE) 717 public @interface AttributeContentType {} 718} 719