1 /* 2 * Copyright (C) 2012 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.os.Parcel; 22 import android.os.Parcelable; 23 24 import java.util.Objects; 25 26 /** 27 * The MediaSyncEvent class defines events that can be used to synchronize playback or capture 28 * actions between different players and recorders. 29 * <p>For instance, {@link AudioRecord#startRecording(MediaSyncEvent)} is used to start capture 30 * only when the playback on a particular audio session is complete. 31 * The audio session ID is retrieved from a player (e.g {@link MediaPlayer}, {@link AudioTrack} or 32 * {@link ToneGenerator}) by use of the getAudioSessionId() method. 33 */ 34 public class MediaSyncEvent implements Parcelable { 35 36 /** 37 * No sync event specified. When used with a synchronized playback or capture method, the 38 * behavior is equivalent to calling the corresponding non synchronized method. 39 */ 40 public static final int SYNC_EVENT_NONE = AudioSystem.SYNC_EVENT_NONE; 41 42 /** 43 * The corresponding action is triggered only when the presentation is completed 44 * (meaning the media has been presented to the user) on the specified session. 45 * A synchronization of this type requires a source audio session ID to be set via 46 * {@link #setAudioSessionId(int)} method. 47 */ 48 public static final int SYNC_EVENT_PRESENTATION_COMPLETE = 49 AudioSystem.SYNC_EVENT_PRESENTATION_COMPLETE; 50 51 /** 52 * @hide 53 * Used when sharing audio history between AudioRecord instances. 54 * See {@link AudioRecord.Builder#setSharedAudioEvent(MediaSyncEvent). 55 */ 56 @SystemApi 57 public static final int SYNC_EVENT_SHARE_AUDIO_HISTORY = 58 AudioSystem.SYNC_EVENT_SHARE_AUDIO_HISTORY; 59 60 /** 61 * Creates a synchronization event of the sepcified type. 62 * 63 * <p>The type specifies which kind of event is monitored. 64 * For instance, event {@link #SYNC_EVENT_PRESENTATION_COMPLETE} corresponds to the audio being 65 * presented to the user on a particular audio session. 66 * @param eventType the synchronization event type. 67 * @return the MediaSyncEvent created. 68 * @throws java.lang.IllegalArgumentException 69 */ createEvent(int eventType)70 public static MediaSyncEvent createEvent(int eventType) 71 throws IllegalArgumentException { 72 if (!isValidType(eventType)) { 73 throw (new IllegalArgumentException(eventType 74 + "is not a valid MediaSyncEvent type.")); 75 } else { 76 return new MediaSyncEvent(eventType); 77 } 78 } 79 80 private final int mType; 81 private int mAudioSession = 0; 82 MediaSyncEvent(int eventType)83 private MediaSyncEvent(int eventType) { 84 mType = eventType; 85 } 86 87 /** 88 * Sets the event source audio session ID. 89 * 90 * <p>The audio session ID specifies on which audio session the synchronization event should be 91 * monitored. 92 * It is mandatory for certain event types (e.g. {@link #SYNC_EVENT_PRESENTATION_COMPLETE}). 93 * For instance, the audio session ID can be retrieved via 94 * {@link MediaPlayer#getAudioSessionId()} when monitoring an event on a particular MediaPlayer. 95 * @param audioSessionId the audio session ID of the event source being monitored. 96 * @return the MediaSyncEvent the method is called on. 97 * @throws java.lang.IllegalArgumentException 98 */ setAudioSessionId(int audioSessionId)99 public MediaSyncEvent setAudioSessionId(int audioSessionId) 100 throws IllegalArgumentException { 101 if (audioSessionId > 0) { 102 mAudioSession = audioSessionId; 103 } else { 104 throw (new IllegalArgumentException(audioSessionId + " is not a valid session ID.")); 105 } 106 return this; 107 } 108 109 /** 110 * Gets the synchronization event type. 111 * 112 * @return the synchronization event type. 113 */ getType()114 public int getType() { 115 return mType; 116 } 117 118 /** 119 * Gets the synchronization event audio session ID. 120 * 121 * @return the synchronization audio session ID. The returned audio session ID is 0 if it has 122 * not been set. 123 */ getAudioSessionId()124 public int getAudioSessionId() { 125 return mAudioSession; 126 } 127 isValidType(int type)128 private static boolean isValidType(int type) { 129 switch (type) { 130 case SYNC_EVENT_NONE: 131 case SYNC_EVENT_PRESENTATION_COMPLETE: 132 case SYNC_EVENT_SHARE_AUDIO_HISTORY: 133 return true; 134 default: 135 return false; 136 } 137 } 138 139 // Parcelable implementation 140 @Override describeContents()141 public int describeContents() { 142 return 0; 143 } 144 145 @Override writeToParcel(@onNull Parcel dest, int flags)146 public void writeToParcel(@NonNull Parcel dest, int flags) { 147 Objects.requireNonNull(dest); 148 dest.writeInt(mType); 149 dest.writeInt(mAudioSession); 150 } 151 MediaSyncEvent(Parcel in)152 private MediaSyncEvent(Parcel in) { 153 mType = in.readInt(); 154 mAudioSession = in.readInt(); 155 } 156 157 public static final @NonNull Parcelable.Creator<MediaSyncEvent> CREATOR = 158 new Parcelable.Creator<MediaSyncEvent>() { 159 /** 160 * Rebuilds an MediaSyncEvent previously stored with writeToParcel(). 161 * @param p Parcel object to read the MediaSyncEvent from 162 * @return a new MediaSyncEvent created from the data in the parcel 163 */ 164 public MediaSyncEvent createFromParcel(Parcel p) { 165 return new MediaSyncEvent(p); 166 } 167 public MediaSyncEvent[] newArray(int size) { 168 return new MediaSyncEvent[size]; 169 } 170 }; 171 172 @Override equals(Object o)173 public boolean equals(Object o) { 174 if (this == o) return true; 175 if (o == null || getClass() != o.getClass()) return false; 176 177 MediaSyncEvent that = (MediaSyncEvent) o; 178 return ((mType == that.mType) 179 && (mAudioSession == that.mAudioSession)); 180 } 181 182 @Override hashCode()183 public int hashCode() { 184 return Objects.hash(mType, mAudioSession); 185 } 186 187 @Override toString()188 public String toString() { 189 return new String("MediaSyncEvent:" 190 + " type=" + typeToString(mType) 191 + " session=" + mAudioSession); 192 } 193 194 /** 195 * Returns the string representation for the type. 196 * @param type one of the {@link MediaSyncEvent} type constants 197 * @hide 198 */ typeToString(int type)199 public static @NonNull String typeToString(int type) { 200 switch (type) { 201 case SYNC_EVENT_NONE: 202 return "SYNC_EVENT_NONE"; 203 case SYNC_EVENT_PRESENTATION_COMPLETE: 204 return "SYNC_EVENT_PRESENTATION_COMPLETE"; 205 case SYNC_EVENT_SHARE_AUDIO_HISTORY: 206 return "SYNC_EVENT_SHARE_AUDIO_HISTORY"; 207 default: 208 return "unknown event type " + type; 209 } 210 } 211 212 } 213