• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #define LOG_TAG "AudioSystem"
19 #include <utils/Log.h>
20 
21 #include <stdio.h>
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <math.h>
25 
26 #include <jni.h>
27 #include <JNIHelp.h>
28 #include <android_runtime/AndroidRuntime.h>
29 
30 #include <media/AudioSystem.h>
31 
32 #include <system/audio.h>
33 #include <system/audio_policy.h>
34 
35 // ----------------------------------------------------------------------------
36 
37 using namespace android;
38 
39 static const char* const kClassPathName = "android/media/AudioSystem";
40 
41 enum AudioError {
42     kAudioStatusOk = 0,
43     kAudioStatusError = 1,
44     kAudioStatusMediaServerDied = 100
45 };
46 
check_AudioSystem_Command(status_t status)47 static int check_AudioSystem_Command(status_t status)
48 {
49     if (status == NO_ERROR) {
50         return kAudioStatusOk;
51     } else {
52         return kAudioStatusError;
53     }
54 }
55 
56 static int
android_media_AudioSystem_muteMicrophone(JNIEnv * env,jobject thiz,jboolean on)57 android_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
58 {
59     return check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
60 }
61 
62 static jboolean
android_media_AudioSystem_isMicrophoneMuted(JNIEnv * env,jobject thiz)63 android_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
64 {
65     bool state = false;
66     AudioSystem::isMicrophoneMuted(&state);
67     return state;
68 }
69 
70 static jboolean
android_media_AudioSystem_isStreamActive(JNIEnv * env,jobject thiz,jint stream,jint inPastMs)71 android_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
72 {
73     bool state = false;
74     AudioSystem::isStreamActive((audio_stream_type_t) stream, &state, inPastMs);
75     return state;
76 }
77 
78 static int
android_media_AudioSystem_setParameters(JNIEnv * env,jobject thiz,jstring keyValuePairs)79 android_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
80 {
81     const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0);
82     String8 c_keyValuePairs8;
83     if (keyValuePairs) {
84         c_keyValuePairs8 = String8(c_keyValuePairs, env->GetStringLength(keyValuePairs));
85         env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
86     }
87     int status = check_AudioSystem_Command(AudioSystem::setParameters(0, c_keyValuePairs8));
88     return status;
89 }
90 
91 static jstring
android_media_AudioSystem_getParameters(JNIEnv * env,jobject thiz,jstring keys)92 android_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys)
93 {
94     const jchar* c_keys = env->GetStringCritical(keys, 0);
95     String8 c_keys8;
96     if (keys) {
97         c_keys8 = String8(c_keys, env->GetStringLength(keys));
98         env->ReleaseStringCritical(keys, c_keys);
99     }
100     return env->NewStringUTF(AudioSystem::getParameters(0, c_keys8).string());
101 }
102 
103 static void
android_media_AudioSystem_error_callback(status_t err)104 android_media_AudioSystem_error_callback(status_t err)
105 {
106     JNIEnv *env = AndroidRuntime::getJNIEnv();
107     if (env == NULL) {
108         return;
109     }
110 
111     jclass clazz = env->FindClass(kClassPathName);
112 
113     int error;
114 
115     switch (err) {
116     case DEAD_OBJECT:
117         error = kAudioStatusMediaServerDied;
118         break;
119     case NO_ERROR:
120         error = kAudioStatusOk;
121         break;
122     default:
123         error = kAudioStatusError;
124         break;
125     }
126 
127     env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz, "errorCallbackFromNative","(I)V"), error);
128 }
129 
130 static int
android_media_AudioSystem_setDeviceConnectionState(JNIEnv * env,jobject thiz,jint device,jint state,jstring device_address)131 android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address)
132 {
133     const char *c_address = env->GetStringUTFChars(device_address, NULL);
134     int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
135                                           static_cast <audio_policy_dev_state_t>(state),
136                                           c_address));
137     env->ReleaseStringUTFChars(device_address, c_address);
138     return status;
139 }
140 
141 static int
android_media_AudioSystem_getDeviceConnectionState(JNIEnv * env,jobject thiz,jint device,jstring device_address)142 android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address)
143 {
144     const char *c_address = env->GetStringUTFChars(device_address, NULL);
145     int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <audio_devices_t>(device),
146                                           c_address));
147     env->ReleaseStringUTFChars(device_address, c_address);
148     return state;
149 }
150 
151 static int
android_media_AudioSystem_setPhoneState(JNIEnv * env,jobject thiz,jint state)152 android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
153 {
154     return check_AudioSystem_Command(AudioSystem::setPhoneState((audio_mode_t) state));
155 }
156 
157 static int
android_media_AudioSystem_setForceUse(JNIEnv * env,jobject thiz,jint usage,jint config)158 android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
159 {
160     return check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <audio_policy_force_use_t>(usage),
161                                                            static_cast <audio_policy_forced_cfg_t>(config)));
162 }
163 
164 static int
android_media_AudioSystem_getForceUse(JNIEnv * env,jobject thiz,jint usage)165 android_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
166 {
167     return static_cast <int>(AudioSystem::getForceUse(static_cast <audio_policy_force_use_t>(usage)));
168 }
169 
170 static int
android_media_AudioSystem_initStreamVolume(JNIEnv * env,jobject thiz,jint stream,jint indexMin,jint indexMax)171 android_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
172 {
173     return check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <audio_stream_type_t>(stream),
174                                                                    indexMin,
175                                                                    indexMax));
176 }
177 
178 static int
android_media_AudioSystem_setStreamVolumeIndex(JNIEnv * env,jobject thiz,jint stream,jint index,jint device)179 android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env,
180                                                jobject thiz,
181                                                jint stream,
182                                                jint index,
183                                                jint device)
184 {
185     return check_AudioSystem_Command(
186             AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
187                                               index,
188                                               (audio_devices_t)device));
189 }
190 
191 static int
android_media_AudioSystem_getStreamVolumeIndex(JNIEnv * env,jobject thiz,jint stream,jint device)192 android_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env,
193                                                jobject thiz,
194                                                jint stream,
195                                                jint device)
196 {
197     int index;
198     if (AudioSystem::getStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
199                                           &index,
200                                           (audio_devices_t)device)
201             != NO_ERROR) {
202         index = -1;
203     }
204     return index;
205 }
206 
207 static int
android_media_AudioSystem_setMasterVolume(JNIEnv * env,jobject thiz,jfloat value)208 android_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value)
209 {
210     return check_AudioSystem_Command(AudioSystem::setMasterVolume(value));
211 }
212 
213 static jfloat
android_media_AudioSystem_getMasterVolume(JNIEnv * env,jobject thiz)214 android_media_AudioSystem_getMasterVolume(JNIEnv *env, jobject thiz)
215 {
216     float value;
217     if (AudioSystem::getMasterVolume(&value) != NO_ERROR) {
218         value = -1.0;
219     }
220     return value;
221 }
222 
223 static int
android_media_AudioSystem_setMasterMute(JNIEnv * env,jobject thiz,jboolean mute)224 android_media_AudioSystem_setMasterMute(JNIEnv *env, jobject thiz, jboolean mute)
225 {
226     return check_AudioSystem_Command(AudioSystem::setMasterMute(mute));
227 }
228 
229 static jfloat
android_media_AudioSystem_getMasterMute(JNIEnv * env,jobject thiz)230 android_media_AudioSystem_getMasterMute(JNIEnv *env, jobject thiz)
231 {
232     bool mute;
233     if (AudioSystem::getMasterMute(&mute) != NO_ERROR) {
234         mute = false;
235     }
236     return mute;
237 }
238 
239 static jint
android_media_AudioSystem_getDevicesForStream(JNIEnv * env,jobject thiz,jint stream)240 android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
241 {
242     return (jint) AudioSystem::getDevicesForStream(static_cast <audio_stream_type_t>(stream));
243 }
244 
245 // ----------------------------------------------------------------------------
246 
247 static JNINativeMethod gMethods[] = {
248     {"setParameters",        "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters},
249     {"getParameters",        "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
250     {"muteMicrophone",      "(Z)I",     (void *)android_media_AudioSystem_muteMicrophone},
251     {"isMicrophoneMuted",   "()Z",      (void *)android_media_AudioSystem_isMicrophoneMuted},
252     {"isStreamActive",      "(II)Z",     (void *)android_media_AudioSystem_isStreamActive},
253     {"setDeviceConnectionState", "(IILjava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
254     {"getDeviceConnectionState", "(ILjava/lang/String;)I",  (void *)android_media_AudioSystem_getDeviceConnectionState},
255     {"setPhoneState",       "(I)I",     (void *)android_media_AudioSystem_setPhoneState},
256     {"setForceUse",         "(II)I",    (void *)android_media_AudioSystem_setForceUse},
257     {"getForceUse",         "(I)I",     (void *)android_media_AudioSystem_getForceUse},
258     {"initStreamVolume",    "(III)I",   (void *)android_media_AudioSystem_initStreamVolume},
259     {"setStreamVolumeIndex","(III)I",   (void *)android_media_AudioSystem_setStreamVolumeIndex},
260     {"getStreamVolumeIndex","(II)I",    (void *)android_media_AudioSystem_getStreamVolumeIndex},
261     {"setMasterVolume",     "(F)I",     (void *)android_media_AudioSystem_setMasterVolume},
262     {"getMasterVolume",     "()F",      (void *)android_media_AudioSystem_getMasterVolume},
263     {"setMasterMute",       "(Z)I",     (void *)android_media_AudioSystem_setMasterMute},
264     {"getMasterMute",       "()Z",      (void *)android_media_AudioSystem_getMasterMute},
265     {"getDevicesForStream", "(I)I",     (void *)android_media_AudioSystem_getDevicesForStream},
266 };
267 
register_android_media_AudioSystem(JNIEnv * env)268 int register_android_media_AudioSystem(JNIEnv *env)
269 {
270     AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);
271 
272     return AndroidRuntime::registerNativeMethods(env,
273                 kClassPathName, gMethods, NELEM(gMethods));
274 }
275