OSDN Git Service

DO NOT MERGE. Grant MMS Uri permissions as the calling UID.
[android-x86/frameworks-base.git] / media / java / android / media / AudioRecordingConfiguration.java
1 /*
2  * Copyright (C) 2016 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.IntDef;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 import android.util.Log;
23
24 import java.lang.annotation.Retention;
25 import java.lang.annotation.RetentionPolicy;
26 import java.util.ArrayList;
27 import java.util.Objects;
28
29 /**
30  * The AudioRecordingConfiguration class collects the information describing an audio recording
31  * session.
32  * <p>Direct polling (see {@link AudioManager#getActiveRecordingConfigurations()}) or callback
33  * (see {@link AudioManager#registerAudioRecordingCallback(android.media.AudioManager.AudioRecordingCallback, android.os.Handler)}
34  * methods are ways to receive information about the current recording configuration of the device.
35  * <p>An audio recording configuration contains information about the recording format as used by
36  * the application ({@link #getClientFormat()}, as well as the recording format actually used by
37  * the device ({@link #getFormat()}). The two recording formats may, for instance, be at different
38  * sampling rates due to hardware limitations (e.g. application recording at 44.1kHz whereas the
39  * device always records at 48kHz, and the Android framework resamples for the application).
40  * <p>The configuration also contains the use case for which audio is recorded
41  * ({@link #getClientAudioSource()}), enabling the ability to distinguish between different
42  * activities such as ongoing voice recognition or camcorder recording.
43  *
44  */
45 public final class AudioRecordingConfiguration implements Parcelable {
46     private final static String TAG = new String("AudioRecordingConfiguration");
47
48     private final int mSessionId;
49
50     private final int mClientSource;
51
52     private final AudioFormat mDeviceFormat;
53     private final AudioFormat mClientFormat;
54
55     private final int mPatchHandle;
56
57     /**
58      * @hide
59      */
60     public AudioRecordingConfiguration(int session, int source, AudioFormat clientFormat,
61             AudioFormat devFormat, int patchHandle) {
62         mSessionId = session;
63         mClientSource = source;
64         mClientFormat = clientFormat;
65         mDeviceFormat = devFormat;
66         mPatchHandle = patchHandle;
67     }
68
69     // matches the sources that return false in MediaRecorder.isSystemOnlyAudioSource(source)
70     /** @hide */
71     @IntDef({
72         MediaRecorder.AudioSource.DEFAULT,
73         MediaRecorder.AudioSource.MIC,
74         MediaRecorder.AudioSource.VOICE_UPLINK,
75         MediaRecorder.AudioSource.VOICE_DOWNLINK,
76         MediaRecorder.AudioSource.VOICE_CALL,
77         MediaRecorder.AudioSource.CAMCORDER,
78         MediaRecorder.AudioSource.VOICE_RECOGNITION,
79         MediaRecorder.AudioSource.VOICE_COMMUNICATION,
80         MediaRecorder.AudioSource.UNPROCESSED
81     })
82     @Retention(RetentionPolicy.SOURCE)
83     public @interface AudioSource {}
84
85     // documented return values match the sources that return false
86     //   in MediaRecorder.isSystemOnlyAudioSource(source)
87     /**
88      * Returns the audio source being used for the recording.
89      * @return one of {@link MediaRecorder.AudioSource#DEFAULT},
90      *       {@link MediaRecorder.AudioSource#MIC},
91      *       {@link MediaRecorder.AudioSource#VOICE_UPLINK},
92      *       {@link MediaRecorder.AudioSource#VOICE_DOWNLINK},
93      *       {@link MediaRecorder.AudioSource#VOICE_CALL},
94      *       {@link MediaRecorder.AudioSource#CAMCORDER},
95      *       {@link MediaRecorder.AudioSource#VOICE_RECOGNITION},
96      *       {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION},
97      *       {@link MediaRecorder.AudioSource#UNPROCESSED}.
98      */
99     public @AudioSource int getClientAudioSource() { return mClientSource; }
100
101     /**
102      * Returns the session number of the recording, see {@link AudioRecord#getAudioSessionId()}.
103      * @return the session number.
104      */
105     public int getClientAudioSessionId() { return mSessionId; }
106
107     /**
108      * Returns the audio format at which audio is recorded on this Android device.
109      * Note that it may differ from the client application recording format
110      * (see {@link #getClientFormat()}).
111      * @return the device recording format
112      */
113     public AudioFormat getFormat() { return mDeviceFormat; }
114
115     /**
116      * Returns the audio format at which the client application is recording audio.
117      * Note that it may differ from the actual recording format (see {@link #getFormat()}).
118      * @return the recording format
119      */
120     public AudioFormat getClientFormat() { return mClientFormat; }
121
122     /**
123      * Returns information about the audio input device used for this recording.
124      * @return the audio recording device or null if this information cannot be retrieved
125      */
126     public AudioDeviceInfo getAudioDevice() {
127         // build the AudioDeviceInfo from the patch handle
128         ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>();
129         if (AudioManager.listAudioPatches(patches) != AudioManager.SUCCESS) {
130             Log.e(TAG, "Error retrieving list of audio patches");
131             return null;
132         }
133         for (int i = 0 ; i < patches.size() ; i++) {
134             final AudioPatch patch = patches.get(i);
135             if (patch.id() == mPatchHandle) {
136                 final AudioPortConfig[] sources = patch.sources();
137                 if ((sources != null) && (sources.length > 0)) {
138                     // not supporting multiple sources, so just look at the first source
139                     final int devId = sources[0].port().id();
140                     final AudioDeviceInfo[] devices =
141                             AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_INPUTS);
142                     for (int j = 0; j < devices.length; j++) {
143                         if (devices[j].getId() == devId) {
144                             return devices[j];
145                         }
146                     }
147                 }
148                 // patch handle is unique, there won't be another with the same handle
149                 break;
150             }
151         }
152         Log.e(TAG, "Couldn't find device for recording, did recording end already?");
153         return null;
154     }
155
156     public static final Parcelable.Creator<AudioRecordingConfiguration> CREATOR
157             = new Parcelable.Creator<AudioRecordingConfiguration>() {
158         /**
159          * Rebuilds an AudioRecordingConfiguration previously stored with writeToParcel().
160          * @param p Parcel object to read the AudioRecordingConfiguration from
161          * @return a new AudioRecordingConfiguration created from the data in the parcel
162          */
163         public AudioRecordingConfiguration createFromParcel(Parcel p) {
164             return new AudioRecordingConfiguration(p);
165         }
166         public AudioRecordingConfiguration[] newArray(int size) {
167             return new AudioRecordingConfiguration[size];
168         }
169     };
170
171     @Override
172     public int hashCode() {
173         return Objects.hash(mSessionId, mClientSource);
174     }
175
176     @Override
177     public int describeContents() {
178         return 0;
179     }
180
181     @Override
182     public void writeToParcel(Parcel dest, int flags) {
183         dest.writeInt(mSessionId);
184         dest.writeInt(mClientSource);
185         mClientFormat.writeToParcel(dest, 0);
186         mDeviceFormat.writeToParcel(dest, 0);
187         dest.writeInt(mPatchHandle);
188     }
189
190     private AudioRecordingConfiguration(Parcel in) {
191         mSessionId = in.readInt();
192         mClientSource = in.readInt();
193         mClientFormat = AudioFormat.CREATOR.createFromParcel(in);
194         mDeviceFormat = AudioFormat.CREATOR.createFromParcel(in);
195         mPatchHandle = in.readInt();
196     }
197
198     @Override
199     public boolean equals(Object o) {
200         if (this == o) return true;
201         if (o == null || !(o instanceof AudioRecordingConfiguration)) return false;
202
203         AudioRecordingConfiguration that = (AudioRecordingConfiguration) o;
204
205         return ((mSessionId == that.mSessionId)
206                 && (mClientSource == that.mClientSource)
207                 && (mPatchHandle == that.mPatchHandle)
208                 && (mClientFormat.equals(that.mClientFormat))
209                 && (mDeviceFormat.equals(that.mDeviceFormat)));
210     }
211 }