1b3db213eb55acb661e4b9ea40bcc00af4b76fab9Glenn Kasten/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2006, The Android Open Source Project
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License.
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License.
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
183a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent//#define LOG_NDEBUG 0
193a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent
20b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent#define LOG_TAG "AudioSystem-JNI"
21c81d31c3f801ba3d559a22c27b926ace38a7ab49Glenn Kasten#include <utils/Log.h>
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
23737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung#include <sstream>
24c0f494403873435d463c4817066f9c68d57310a7jiabin#include <vector>
25c81d31c3f801ba3d559a22c27b926ace38a7ab49Glenn Kasten#include <jni.h>
262279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/JNIHelp.h>
27ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h"
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <media/AudioSystem.h>
307f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent#include <media/AudioPolicy.h>
31c0f494403873435d463c4817066f9c68d57310a7jiabin#include <media/MicrophoneInfo.h>
32737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung#include <nativehelper/ScopedLocalRef.h>
3334bb419e5946ab28112e9e27a4d1b3928d31e0e2Dima Zavin#include <system/audio.h>
34290029d19a9d314e925b73e19453ab0497602f80Dima Zavin#include <system/audio_policy.h>
35b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent#include "android_media_AudioFormat.h"
36b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent#include "android_media_AudioErrors.h"
37c0f494403873435d463c4817066f9c68d57310a7jiabin#include "android_media_MicrophoneInfo.h"
3824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
43ed0079ddddd4070f3369b13b274222da2e69f4b9Glenn Kastenstatic const char* const kClassPathName = "android/media/AudioSystem";
44ed0079ddddd4070f3369b13b274222da2e69f4b9Glenn Kasten
45b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jclass gArrayListClass;
46b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic struct {
47b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jmethodID    add;
487f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jmethodID    toArray;
49b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent} gArrayListMethods;
50b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
513994075a5b638ecffce5b8782521fce7631e7169jiabinstatic jclass gBooleanClass;
523994075a5b638ecffce5b8782521fce7631e7169jiabinstatic jmethodID gBooleanCstor;
533994075a5b638ecffce5b8782521fce7631e7169jiabin
543994075a5b638ecffce5b8782521fce7631e7169jiabinstatic jclass gIntegerClass;
553994075a5b638ecffce5b8782521fce7631e7169jiabinstatic jmethodID gIntegerCstor;
563994075a5b638ecffce5b8782521fce7631e7169jiabin
573994075a5b638ecffce5b8782521fce7631e7169jiabinstatic jclass gMapClass;
583994075a5b638ecffce5b8782521fce7631e7169jiabinstatic jmethodID gMapPut;
593994075a5b638ecffce5b8782521fce7631e7169jiabin
60b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jclass gAudioHandleClass;
61b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jmethodID gAudioHandleCstor;
62b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic struct {
63b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID    mId;
64b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent} gAudioHandleFields;
65b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
66b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jclass gAudioPortClass;
67b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jmethodID gAudioPortCstor;
68b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic struct {
69b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID    mHandle;
70b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID    mRole;
71b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID    mGains;
72b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID    mActiveConfig;
73b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    // other fields unused by JNI
74b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent} gAudioPortFields;
75b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
76b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jclass gAudioPortConfigClass;
77b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jmethodID gAudioPortConfigCstor;
78b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic struct {
79b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID    mPort;
80b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID    mSamplingRate;
81b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID    mChannelMask;
82b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID    mFormat;
83b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID    mGain;
843a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    jfieldID    mConfigMask;
85b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent} gAudioPortConfigFields;
86b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
87b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jclass gAudioDevicePortClass;
88b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jmethodID gAudioDevicePortCstor;
89b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
90b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jclass gAudioDevicePortConfigClass;
91b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jmethodID gAudioDevicePortConfigCstor;
92b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
93b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jclass gAudioMixPortClass;
94b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jmethodID gAudioMixPortCstor;
95b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
96b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jclass gAudioMixPortConfigClass;
97b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jmethodID gAudioMixPortConfigCstor;
98b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
99b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jclass gAudioGainClass;
100b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jmethodID gAudioGainCstor;
101b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
102b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jclass gAudioGainConfigClass;
103b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jmethodID gAudioGainConfigCstor;
104b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic struct {
105b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID mIndex;
106b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID mMode;
107b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID mChannelMask;
108b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID mValues;
109b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID mRampDurationMs;
110b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    // other fields unused by JNI
111b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent} gAudioGainConfigFields;
112b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
113b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jclass gAudioPatchClass;
114b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jmethodID gAudioPatchCstor;
115b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic struct {
116b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jfieldID    mHandle;
117b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    // other fields unused by JNI
118b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent} gAudioPatchFields;
119b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1207f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurentstatic jclass gAudioMixClass;
1217f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurentstatic struct {
1227f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jfieldID    mRule;
1237f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jfieldID    mFormat;
1247f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jfieldID    mRouteFlags;
1254ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi    jfieldID    mDeviceType;
1264ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi    jfieldID    mDeviceAddress;
1277f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jfieldID    mMixType;
1285a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    jfieldID    mCallbackFlags;
1297f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent} gAudioMixFields;
1307f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
1317f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurentstatic jclass gAudioFormatClass;
1327f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurentstatic struct {
1337f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jfieldID    mEncoding;
1347f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jfieldID    mSampleRate;
1357f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jfieldID    mChannelMask;
1367f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    // other fields unused by JNI
1377f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent} gAudioFormatFields;
1387f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
1397f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurentstatic jclass gAudioMixingRuleClass;
1407f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurentstatic struct {
1417f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jfieldID    mCriteria;
1427f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    // other fields unused by JNI
1437f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent} gAudioMixingRuleFields;
1447f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
145ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivistatic jclass gAudioMixMatchCriterionClass;
1467f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurentstatic struct {
1477f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jfieldID    mAttr;
148ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi    jfieldID    mIntProp;
1497f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jfieldID    mRule;
150ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi} gAudioMixMatchCriterionFields;
1517f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
1527f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurentstatic jclass gAudioAttributesClass;
1537f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurentstatic struct {
1547f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jfieldID    mUsage;
1557f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jfieldID    mSource;
1567f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent} gAudioAttributesFields;
1577f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
158700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentstatic const char* const kEventHandlerClassPathName =
159700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        "android/media/AudioPortEventHandler";
1602615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurentstatic struct {
1612615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    jfieldID    mJniCallback;
1622615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent} gEventHandlerFields;
1632615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurentstatic struct {
1642615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    jmethodID    postEventFromNative;
1652615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent} gAudioPortEventHandlerMethods;
1662615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent
1675a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivistatic struct {
1685a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    jmethodID postDynPolicyEventFromNative;
169d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    jmethodID postRecordConfigEventFromNative;
170d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi} gAudioPolicyEventHandlerMethods;
1715a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi
1722615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurentstatic Mutex gLock;
173b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectenum AudioError {
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    kAudioStatusOk = 0,
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    kAudioStatusError = 1,
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    kAudioStatusMediaServerDied = 100
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
180700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentenum  {
181700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    AUDIOPORT_EVENT_PORT_LIST_UPDATED = 1,
182700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    AUDIOPORT_EVENT_PATCH_LIST_UPDATED = 2,
183700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    AUDIOPORT_EVENT_SERVICE_DIED = 3,
184700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent};
185700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
186b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent#define MAX_PORT_GENERATION_SYNC_ATTEMPTS 5
187b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
188700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent// ----------------------------------------------------------------------------
1895a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi// ref-counted object for audio port callbacks
190700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentclass JNIAudioPortCallback: public AudioSystem::AudioPortCallback
191700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent{
192700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentpublic:
193700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz);
194700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    ~JNIAudioPortCallback();
195700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
196700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    virtual void onAudioPortListUpdate();
197700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    virtual void onAudioPatchListUpdate();
198700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    virtual void onServiceDied();
199700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
200700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentprivate:
201700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    void sendEvent(int event);
202700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
2032615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    jclass      mClass;     // Reference to AudioPortEventHandler class
2042615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    jobject     mObject;    // Weak ref to AudioPortEventHandler Java object to call on
205700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent};
206700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
207700e73471d85348b52ecf213c36bb24b93997ec7Eric LaurentJNIAudioPortCallback::JNIAudioPortCallback(JNIEnv* env, jobject thiz, jobject weak_thiz)
208700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent{
209700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
2102615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    // Hold onto the AudioPortEventHandler class for use in calling the static method
211700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    // that posts events to the application thread.
212700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    jclass clazz = env->GetObjectClass(thiz);
213700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    if (clazz == NULL) {
214700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        ALOGE("Can't find class %s", kEventHandlerClassPathName);
215700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        return;
216700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    }
217700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    mClass = (jclass)env->NewGlobalRef(clazz);
218700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
2192615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    // We use a weak reference so the AudioPortEventHandler object can be garbage collected.
220700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    // The reference is only used as a proxy for callbacks.
221700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    mObject  = env->NewGlobalRef(weak_thiz);
222700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent}
223700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
224700e73471d85348b52ecf213c36bb24b93997ec7Eric LaurentJNIAudioPortCallback::~JNIAudioPortCallback()
225700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent{
226700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    // remove global references
227700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    JNIEnv *env = AndroidRuntime::getJNIEnv();
228449c5887101047d187a55217ced6d8a5c98fb367Eric Laurent    if (env == NULL) {
229449c5887101047d187a55217ced6d8a5c98fb367Eric Laurent        return;
230449c5887101047d187a55217ced6d8a5c98fb367Eric Laurent    }
231700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    env->DeleteGlobalRef(mObject);
232700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    env->DeleteGlobalRef(mClass);
233700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent}
234700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
235700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentvoid JNIAudioPortCallback::sendEvent(int event)
236700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent{
237700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    JNIEnv *env = AndroidRuntime::getJNIEnv();
238449c5887101047d187a55217ced6d8a5c98fb367Eric Laurent    if (env == NULL) {
239449c5887101047d187a55217ced6d8a5c98fb367Eric Laurent        return;
240449c5887101047d187a55217ced6d8a5c98fb367Eric Laurent    }
2412615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    env->CallStaticVoidMethod(mClass, gAudioPortEventHandlerMethods.postEventFromNative, mObject,
242700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent                              event, 0, 0, NULL);
243700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    if (env->ExceptionCheck()) {
244700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        ALOGW("An exception occurred while notifying an event.");
245700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        env->ExceptionClear();
246700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    }
247700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent}
248700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
249700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentvoid JNIAudioPortCallback::onAudioPortListUpdate()
250700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent{
251700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    sendEvent(AUDIOPORT_EVENT_PORT_LIST_UPDATED);
252700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent}
253700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
254700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentvoid JNIAudioPortCallback::onAudioPatchListUpdate()
255700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent{
256700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    sendEvent(AUDIOPORT_EVENT_PATCH_LIST_UPDATED);
257700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent}
258700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
259700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentvoid JNIAudioPortCallback::onServiceDied()
260700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent{
261700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    sendEvent(AUDIOPORT_EVENT_SERVICE_DIED);
262700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent}
263700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
2642615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurentstatic sp<JNIAudioPortCallback> setJniCallback(JNIEnv* env,
2652615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent                                       jobject thiz,
2662615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent                                       const sp<JNIAudioPortCallback>& callback)
2672615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent{
2682615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    Mutex::Autolock l(gLock);
2692615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    sp<JNIAudioPortCallback> old =
2702615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent            (JNIAudioPortCallback*)env->GetLongField(thiz, gEventHandlerFields.mJniCallback);
2712615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    if (callback.get()) {
2722615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent        callback->incStrong((void*)setJniCallback);
2732615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    }
2742615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    if (old != 0) {
2752615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent        old->decStrong((void*)setJniCallback);
2762615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    }
2772615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    env->SetLongField(thiz, gEventHandlerFields.mJniCallback, (jlong)callback.get());
2782615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    return old;
2792615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent}
2802615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int check_AudioSystem_Command(status_t status)
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
283dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent    switch (status) {
284dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent    case DEAD_OBJECT:
285dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent        return kAudioStatusMediaServerDied;
286dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent    case NO_ERROR:
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return kAudioStatusOk;
288dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent    default:
289dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent        break;
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
291dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent    return kAudioStatusError;
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
294075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectandroid_media_AudioSystem_muteMicrophone(JNIEnv *env, jobject thiz, jboolean on)
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
297075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) check_AudioSystem_Command(AudioSystem::muteMicrophone(on));
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectandroid_media_AudioSystem_isMicrophoneMuted(JNIEnv *env, jobject thiz)
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool state = false;
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AudioSystem::isMicrophoneMuted(&state);
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return state;
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean
30925101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurentandroid_media_AudioSystem_isStreamActive(JNIEnv *env, jobject thiz, jint stream, jint inPastMs)
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool state = false;
312bc1d77b6cbce23fbe25f7231651037ae195bc90eGlenn Kasten    AudioSystem::isStreamActive((audio_stream_type_t) stream, &state, inPastMs);
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return state;
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
316d677054ca63f55abaa1c478ea3c50f6be665a979Jean-Michel Trivistatic jboolean
317679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Triviandroid_media_AudioSystem_isStreamActiveRemotely(JNIEnv *env, jobject thiz, jint stream,
318679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi        jint inPastMs)
319679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi{
320679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi    bool state = false;
321679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi    AudioSystem::isStreamActiveRemotely((audio_stream_type_t) stream, &state, inPastMs);
322679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi    return state;
323679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi}
324679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi
325679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivistatic jboolean
326d677054ca63f55abaa1c478ea3c50f6be665a979Jean-Michel Triviandroid_media_AudioSystem_isSourceActive(JNIEnv *env, jobject thiz, jint source)
327d677054ca63f55abaa1c478ea3c50f6be665a979Jean-Michel Trivi{
328d677054ca63f55abaa1c478ea3c50f6be665a979Jean-Michel Trivi    bool state = false;
329d677054ca63f55abaa1c478ea3c50f6be665a979Jean-Michel Trivi    AudioSystem::isSourceActive((audio_source_t) source, &state);
330d677054ca63f55abaa1c478ea3c50f6be665a979Jean-Michel Trivi    return state;
331d677054ca63f55abaa1c478ea3c50f6be665a979Jean-Michel Trivi}
332d677054ca63f55abaa1c478ea3c50f6be665a979Jean-Michel Trivi
333075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint
3348a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Triviandroid_media_AudioSystem_newAudioSessionId(JNIEnv *env, jobject thiz)
3358a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi{
336211d9052f265b4f41b6de74131482a7c77a5e005Glenn Kasten    return AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
3378a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi}
3388a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi
3398a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivistatic jint
340292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Triviandroid_media_AudioSystem_newAudioPlayerId(JNIEnv *env, jobject thiz)
341292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi{
342292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi    return AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_PLAYER);
343292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi}
344292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi
345292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivistatic jint
346a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentandroid_media_AudioSystem_setParameters(JNIEnv *env, jobject thiz, jstring keyValuePairs)
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
348a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    const jchar* c_keyValuePairs = env->GetStringCritical(keyValuePairs, 0);
349a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 c_keyValuePairs8;
350a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (keyValuePairs) {
3516698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert        c_keyValuePairs8 = String8(
3526698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert            reinterpret_cast<const char16_t*>(c_keyValuePairs),
3536698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert            env->GetStringLength(keyValuePairs));
354a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
355a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
356c94752a01a709e9f3914c40ebdd77face2d52cceGlenn Kasten    int status = check_AudioSystem_Command(AudioSystem::setParameters(c_keyValuePairs8));
357075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) status;
358a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
359a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
360a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatic jstring
361a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentandroid_media_AudioSystem_getParameters(JNIEnv *env, jobject thiz, jstring keys)
362a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
363a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    const jchar* c_keys = env->GetStringCritical(keys, 0);
364a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 c_keys8;
365a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (keys) {
3666698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert        c_keys8 = String8(reinterpret_cast<const char16_t*>(c_keys),
3676698749dd4d4d6513b26aa9071af290b956b68a7Dan Albert                          env->GetStringLength(keys));
368a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        env->ReleaseStringCritical(keys, c_keys);
369a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
370c94752a01a709e9f3914c40ebdd77face2d52cceGlenn Kasten    return env->NewStringUTF(AudioSystem::getParameters(c_keys8).string());
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
373ed0079ddddd4070f3369b13b274222da2e69f4b9Glenn Kastenstatic void
374ed0079ddddd4070f3369b13b274222da2e69f4b9Glenn Kastenandroid_media_AudioSystem_error_callback(status_t err)
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
376539719a7af34be96743a4f408aedf6437f441bbfEric Laurent    JNIEnv *env = AndroidRuntime::getJNIEnv();
3770e7a4d9edcee63c6b770db9b6fe792abad5d7b53Eric Laurent    if (env == NULL) {
3780e7a4d9edcee63c6b770db9b6fe792abad5d7b53Eric Laurent        return;
3790e7a4d9edcee63c6b770db9b6fe792abad5d7b53Eric Laurent    }
3800e7a4d9edcee63c6b770db9b6fe792abad5d7b53Eric Laurent
381ed0079ddddd4070f3369b13b274222da2e69f4b9Glenn Kasten    jclass clazz = env->FindClass(kClassPathName);
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
383dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent    env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz,
384dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent                              "errorCallbackFromNative","(I)V"),
385dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent                              check_AudioSystem_Command(err));
386b637ccffd856ba911c1527077cec3abff39035f5Viorel Suman
387b637ccffd856ba911c1527077cec3abff39035f5Viorel Suman    env->DeleteLocalRef(clazz);
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3905a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivistatic void
3915a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Triviandroid_media_AudioSystem_dyn_policy_callback(int event, String8 regId, int val)
3925a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi{
3935a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    JNIEnv *env = AndroidRuntime::getJNIEnv();
3945a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    if (env == NULL) {
3955a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi        return;
3965a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    }
3975a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi
3985a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    jclass clazz = env->FindClass(kClassPathName);
3995a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    const char* zechars = regId.string();
4005a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    jstring zestring = env->NewStringUTF(zechars);
4015a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi
402d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    env->CallStaticVoidMethod(clazz, gAudioPolicyEventHandlerMethods.postDynPolicyEventFromNative,
4035a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi            event, zestring, val);
4045a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi
4055a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    env->ReleaseStringUTFChars(zestring, zechars);
4065a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    env->DeleteLocalRef(clazz);
407d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi}
408d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
409d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivistatic void
41066ffacf42a7dde6fac867605aaa47d555b960ee4Jean-Michel Triviandroid_media_AudioSystem_recording_callback(int event, const record_client_info_t *clientInfo,
4118ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
4128ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi        audio_patch_handle_t patchHandle)
413d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi{
414d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    JNIEnv *env = AndroidRuntime::getJNIEnv();
415d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    if (env == NULL) {
416d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi        return;
417d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    }
41866ffacf42a7dde6fac867605aaa47d555b960ee4Jean-Michel Trivi    if (clientInfo == NULL || clientConfig == NULL || deviceConfig == NULL) {
41966ffacf42a7dde6fac867605aaa47d555b960ee4Jean-Michel Trivi        ALOGE("Unexpected null client/device info or configurations in recording callback");
42033fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi        return;
42133fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    }
4225a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi
42333fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    // create an array for 2*3 integers to store the record configurations (client + device)
4248ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi    //                 plus 1 integer for the patch handle
4258ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi    const int REC_PARAM_SIZE = 7;
4268ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi    jintArray recParamArray = env->NewIntArray(REC_PARAM_SIZE);
42733fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    if (recParamArray == NULL) {
42833fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi        ALOGE("recording callback: Couldn't allocate int array for configuration data");
42933fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi        return;
43033fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    }
4318ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi    jint recParamData[REC_PARAM_SIZE];
43233fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    recParamData[0] = (jint) audioFormatFromNative(clientConfig->format);
43333fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    // FIXME this doesn't support index-based masks
43433fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    recParamData[1] = (jint) inChannelMaskFromNative(clientConfig->channel_mask);
43533fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    recParamData[2] = (jint) clientConfig->sample_rate;
43633fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    recParamData[3] = (jint) audioFormatFromNative(deviceConfig->format);
43733fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    // FIXME this doesn't support index-based masks
43833fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    recParamData[4] = (jint) inChannelMaskFromNative(deviceConfig->channel_mask);
43933fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    recParamData[5] = (jint) deviceConfig->sample_rate;
4408ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi    recParamData[6] = (jint) patchHandle;
4418ab728093eed85c176822d58a0d2ba1f4ebbb362Jean-Michel Trivi    env->SetIntArrayRegion(recParamArray, 0, REC_PARAM_SIZE, recParamData);
44233fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi
44333fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    // callback into java
444d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    jclass clazz = env->FindClass(kClassPathName);
445d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    env->CallStaticVoidMethod(clazz,
446d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative,
44766ffacf42a7dde6fac867605aaa47d555b960ee4Jean-Michel Trivi            event, (jint) clientInfo->uid, clientInfo->session, clientInfo->source, recParamArray);
448d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    env->DeleteLocalRef(clazz);
44933fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi
45033fd8169cdb7e7fa33885b6f892bc4f6df68959bJean-Michel Trivi    env->DeleteLocalRef(recParamArray);
4515a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi}
4525a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi
453075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint
45410804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLeanandroid_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address, jstring device_name)
455a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
456a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    const char *c_address = env->GetStringUTFChars(device_address, NULL);
45710804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    const char *c_name = env->GetStringUTFChars(device_name, NULL);
45824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    int status = check_AudioSystem_Command(AudioSystem::setDeviceConnectionState(static_cast <audio_devices_t>(device),
45924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                          static_cast <audio_policy_dev_state_t>(state),
46010804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean                                          c_address, c_name));
461a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    env->ReleaseStringUTFChars(device_address, c_address);
46210804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    env->ReleaseStringUTFChars(device_name, c_name);
463075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) status;
464a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
465a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
466075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint
467a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentandroid_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jstring device_address)
468a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
469a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    const char *c_address = env->GetStringUTFChars(device_address, NULL);
47024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    int state = static_cast <int>(AudioSystem::getDeviceConnectionState(static_cast <audio_devices_t>(device),
471a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                          c_address));
472a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    env->ReleaseStringUTFChars(device_address, c_address);
473075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) state;
474a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
475a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
476075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint
47744a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavovandroid_media_AudioSystem_handleDeviceConfigChange(JNIEnv *env, jobject thiz, jint device, jstring device_address, jstring device_name)
47844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov{
47944a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov    const char *c_address = env->GetStringUTFChars(device_address, NULL);
48044a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov    const char *c_name = env->GetStringUTFChars(device_name, NULL);
48144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov    int status = check_AudioSystem_Command(AudioSystem::handleDeviceConfigChange(static_cast <audio_devices_t>(device),
48244a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov                                          c_address, c_name));
48344a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov    env->ReleaseStringUTFChars(device_address, c_address);
48444a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov    env->ReleaseStringUTFChars(device_name, c_name);
48544a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov    return (jint) status;
48644a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov}
48744a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov
48844a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavovstatic jint
489a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentandroid_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
490a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
491075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) check_AudioSystem_Command(AudioSystem::setPhoneState((audio_mode_t) state));
492a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
493a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
494075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint
495a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentandroid_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
496a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
497075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) check_AudioSystem_Command(AudioSystem::setForceUse(static_cast <audio_policy_force_use_t>(usage),
49824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                           static_cast <audio_policy_forced_cfg_t>(config)));
499a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
500a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
501075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint
502a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentandroid_media_AudioSystem_getForceUse(JNIEnv *env, jobject thiz, jint usage)
503a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
504075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return static_cast <jint>(AudioSystem::getForceUse(static_cast <audio_policy_force_use_t>(usage)));
505a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
506a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
507075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint
508a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentandroid_media_AudioSystem_initStreamVolume(JNIEnv *env, jobject thiz, jint stream, jint indexMin, jint indexMax)
509a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
510075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) check_AudioSystem_Command(AudioSystem::initStreamVolume(static_cast <audio_stream_type_t>(stream),
511a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                                                   indexMin,
512a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                                                   indexMax));
513a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
514a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
515075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint
5169bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurentandroid_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env,
5179bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent                                               jobject thiz,
5189bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent                                               jint stream,
5199bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent                                               jint index,
5209bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent                                               jint device)
521a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
522075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) check_AudioSystem_Command(
5239bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent            AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
5249bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent                                              index,
5259bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent                                              (audio_devices_t)device));
526a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
527a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
528075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint
5299bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurentandroid_media_AudioSystem_getStreamVolumeIndex(JNIEnv *env,
5309bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent                                               jobject thiz,
5319bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent                                               jint stream,
5329bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent                                               jint device)
533a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
534a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    int index;
5359bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent    if (AudioSystem::getStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
5369bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent                                          &index,
5379bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent                                          (audio_devices_t)device)
5389bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent            != NO_ERROR) {
539a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        index = -1;
540a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
541075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) index;
542a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
543a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
544075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint
545cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwoodandroid_media_AudioSystem_setMasterVolume(JNIEnv *env, jobject thiz, jfloat value)
546cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood{
547075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) check_AudioSystem_Command(AudioSystem::setMasterVolume(value));
548cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood}
549cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood
550cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwoodstatic jfloat
551cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwoodandroid_media_AudioSystem_getMasterVolume(JNIEnv *env, jobject thiz)
552cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood{
553cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    float value;
554cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    if (AudioSystem::getMasterVolume(&value) != NO_ERROR) {
555cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood        value = -1.0;
556cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    }
557cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    return value;
558cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood}
559cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood
560075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint
561cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwoodandroid_media_AudioSystem_setMasterMute(JNIEnv *env, jobject thiz, jboolean mute)
562cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood{
563075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) check_AudioSystem_Command(AudioSystem::setMasterMute(mute));
564cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood}
565cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood
566c1bcdbb75877d99972f1cd13a9c40126822621bcVladimir Markostatic jboolean
567cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwoodandroid_media_AudioSystem_getMasterMute(JNIEnv *env, jobject thiz)
568cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood{
569cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    bool mute;
570cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    if (AudioSystem::getMasterMute(&mute) != NO_ERROR) {
571cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood        mute = false;
572cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    }
573cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    return mute;
574cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood}
575cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood
5768b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kastenstatic jint
577f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hungandroid_media_AudioSystem_setMasterMono(JNIEnv *env, jobject thiz, jboolean mono)
578f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung{
579f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung    return (jint) check_AudioSystem_Command(AudioSystem::setMasterMono(mono));
580f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung}
581f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung
582f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hungstatic jboolean
583f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hungandroid_media_AudioSystem_getMasterMono(JNIEnv *env, jobject thiz)
584f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung{
585f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung    bool mono;
586f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung    if (AudioSystem::getMasterMono(&mono) != NO_ERROR) {
587f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung        mono = false;
588f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung    }
589f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung    return mono;
590f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung}
591f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung
592f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hungstatic jint
5938b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kastenandroid_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
5948b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten{
59524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return (jint) AudioSystem::getDevicesForStream(static_cast <audio_stream_type_t>(stream));
5968b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten}
5978b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten
598c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kastenstatic jint
599c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kastenandroid_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv *env, jobject clazz)
600c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten{
601c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten    return (jint) AudioSystem::getPrimaryOutputSamplingRate();
602c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten}
603c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten
604c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kastenstatic jint
605c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kastenandroid_media_AudioSystem_getPrimaryOutputFrameCount(JNIEnv *env, jobject clazz)
606c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten{
607c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten    return (jint) AudioSystem::getPrimaryOutputFrameCount();
608c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten}
609c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten
61061dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodmanstatic jint
61161dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodmanandroid_media_AudioSystem_getOutputLatency(JNIEnv *env, jobject clazz, jint stream)
61261dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman{
61361dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman    uint32_t afLatency;
61461dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman    if (AudioSystem::getOutputLatency(&afLatency, static_cast <audio_stream_type_t>(stream))
61561dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman            != NO_ERROR) {
61661dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman        afLatency = -1;
61761dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman    }
61861dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman    return (jint) afLatency;
61961dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman}
62061dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman
621fd116ad1ab02f6060a0b2201f018317fa32e28b4Glenn Kastenstatic jint
6227958358ddb34cebe4fdf99fef8d613c0c74ff17aAndy Hungandroid_media_AudioSystem_setLowRamDevice(
6237958358ddb34cebe4fdf99fef8d613c0c74ff17aAndy Hung        JNIEnv *env, jobject clazz, jboolean isLowRamDevice, jlong totalMemory)
624fd116ad1ab02f6060a0b2201f018317fa32e28b4Glenn Kasten{
6257958358ddb34cebe4fdf99fef8d613c0c74ff17aAndy Hung    return (jint) AudioSystem::setLowRamDevice((bool) isLowRamDevice, (int64_t) totalMemory);
626fd116ad1ab02f6060a0b2201f018317fa32e28b4Glenn Kasten}
627fd116ad1ab02f6060a0b2201f018317fa32e28b4Glenn Kasten
628075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhatstatic jint
629dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurentandroid_media_AudioSystem_checkAudioFlinger(JNIEnv *env, jobject clazz)
630dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent{
631075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat    return (jint) check_AudioSystem_Command(AudioSystem::checkAudioFlinger());
632dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent}
633dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent
634b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
635b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic bool useInChannelMask(audio_port_type_t type, audio_port_role_t role)
636b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent{
637b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    return ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) ||
638b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK));
639b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent}
640b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
6413a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurentstatic void convertAudioGainConfigToNative(JNIEnv *env,
6423a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent                                               struct audio_gain_config *nAudioGainConfig,
6433a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent                                               const jobject jAudioGainConfig,
6443a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent                                               bool useInMask)
6453a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent{
6463a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    nAudioGainConfig->index = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mIndex);
6473a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    nAudioGainConfig->mode = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mMode);
6483a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    ALOGV("convertAudioGainConfigToNative got gain index %d", nAudioGainConfig->index);
6493a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    jint jMask = env->GetIntField(jAudioGainConfig, gAudioGainConfigFields.mChannelMask);
6503a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    audio_channel_mask_t nMask;
6513a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    if (useInMask) {
6523a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        nMask = inChannelMaskToNative(jMask);
6533a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        ALOGV("convertAudioGainConfigToNative IN mask java %x native %x", jMask, nMask);
6543a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    } else {
6553a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        nMask = outChannelMaskToNative(jMask);
6563a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        ALOGV("convertAudioGainConfigToNative OUT mask java %x native %x", jMask, nMask);
6573a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    }
6583a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    nAudioGainConfig->channel_mask = nMask;
6593a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    nAudioGainConfig->ramp_duration_ms = env->GetIntField(jAudioGainConfig,
6603a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent                                                       gAudioGainConfigFields.mRampDurationMs);
6613a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    jintArray jValues = (jintArray)env->GetObjectField(jAudioGainConfig,
6623a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent                                                       gAudioGainConfigFields.mValues);
6633a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    int *nValues = env->GetIntArrayElements(jValues, NULL);
6643a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    size_t size = env->GetArrayLength(jValues);
6653a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    memcpy(nAudioGainConfig->values, nValues, size * sizeof(int));
6663a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    env->DeleteLocalRef(jValues);
6673a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent}
6683a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent
6693a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent
670b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jint convertAudioPortConfigToNative(JNIEnv *env,
671b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               struct audio_port_config *nAudioPortConfig,
6726368a7df1884031b6620493e096abe8510c05e24Eric Laurent                                               const jobject jAudioPortConfig,
6736368a7df1884031b6620493e096abe8510c05e24Eric Laurent                                               bool useConfigMask)
674b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent{
675b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jAudioPort = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mPort);
676b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jHandle = env->GetObjectField(jAudioPort, gAudioPortFields.mHandle);
677b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    nAudioPortConfig->id = env->GetIntField(jHandle, gAudioHandleFields.mId);
678b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    nAudioPortConfig->role = (audio_port_role_t)env->GetIntField(jAudioPort,
679b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                                 gAudioPortFields.mRole);
680b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) {
681b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        nAudioPortConfig->type = AUDIO_PORT_TYPE_DEVICE;
682b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) {
683b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        nAudioPortConfig->type = AUDIO_PORT_TYPE_MIX;
684b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    } else {
685b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jAudioPort);
686b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jHandle);
687b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return (jint)AUDIO_JAVA_ERROR;
688b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
689b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    ALOGV("convertAudioPortConfigToNative handle %d role %d type %d",
690b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent          nAudioPortConfig->id, nAudioPortConfig->role, nAudioPortConfig->type);
691b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
6926368a7df1884031b6620493e096abe8510c05e24Eric Laurent    unsigned int configMask = 0;
6936368a7df1884031b6620493e096abe8510c05e24Eric Laurent
694b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    nAudioPortConfig->sample_rate = env->GetIntField(jAudioPortConfig,
695b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                     gAudioPortConfigFields.mSamplingRate);
6966368a7df1884031b6620493e096abe8510c05e24Eric Laurent    if (nAudioPortConfig->sample_rate != 0) {
6976368a7df1884031b6620493e096abe8510c05e24Eric Laurent        configMask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
6986368a7df1884031b6620493e096abe8510c05e24Eric Laurent    }
699b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
700b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role);
701b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    audio_channel_mask_t nMask;
702b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jint jMask = env->GetIntField(jAudioPortConfig,
703b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                   gAudioPortConfigFields.mChannelMask);
704b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (useInMask) {
705b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        nMask = inChannelMaskToNative(jMask);
706b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("convertAudioPortConfigToNative IN mask java %x native %x", jMask, nMask);
707b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    } else {
708b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        nMask = outChannelMaskToNative(jMask);
709b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("convertAudioPortConfigToNative OUT mask java %x native %x", jMask, nMask);
710b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
711b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    nAudioPortConfig->channel_mask = nMask;
7126368a7df1884031b6620493e096abe8510c05e24Eric Laurent    if (nAudioPortConfig->channel_mask != AUDIO_CHANNEL_NONE) {
7136368a7df1884031b6620493e096abe8510c05e24Eric Laurent        configMask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
7146368a7df1884031b6620493e096abe8510c05e24Eric Laurent    }
715b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
716b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jint jFormat = env->GetIntField(jAudioPortConfig, gAudioPortConfigFields.mFormat);
717b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    audio_format_t nFormat = audioFormatToNative(jFormat);
718b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    ALOGV("convertAudioPortConfigToNative format %d native %d", jFormat, nFormat);
719b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    nAudioPortConfig->format = nFormat;
7206368a7df1884031b6620493e096abe8510c05e24Eric Laurent    if (nAudioPortConfig->format != AUDIO_FORMAT_DEFAULT &&
7216368a7df1884031b6620493e096abe8510c05e24Eric Laurent            nAudioPortConfig->format != AUDIO_FORMAT_INVALID) {
7226368a7df1884031b6620493e096abe8510c05e24Eric Laurent        configMask |= AUDIO_PORT_CONFIG_FORMAT;
7236368a7df1884031b6620493e096abe8510c05e24Eric Laurent    }
7246368a7df1884031b6620493e096abe8510c05e24Eric Laurent
725b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jGain = env->GetObjectField(jAudioPortConfig, gAudioPortConfigFields.mGain);
726b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jGain != NULL) {
7273a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        convertAudioGainConfigToNative(env, &nAudioPortConfig->gain, jGain, useInMask);
728b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jGain);
7296368a7df1884031b6620493e096abe8510c05e24Eric Laurent        configMask |= AUDIO_PORT_CONFIG_GAIN;
730b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    } else {
731b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("convertAudioPortConfigToNative no gain");
732b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        nAudioPortConfig->gain.index = -1;
733b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
7346368a7df1884031b6620493e096abe8510c05e24Eric Laurent    if (useConfigMask) {
7356368a7df1884031b6620493e096abe8510c05e24Eric Laurent        nAudioPortConfig->config_mask = env->GetIntField(jAudioPortConfig,
7366368a7df1884031b6620493e096abe8510c05e24Eric Laurent                                                         gAudioPortConfigFields.mConfigMask);
7376368a7df1884031b6620493e096abe8510c05e24Eric Laurent    } else {
7386368a7df1884031b6620493e096abe8510c05e24Eric Laurent        nAudioPortConfig->config_mask = configMask;
7396368a7df1884031b6620493e096abe8510c05e24Eric Laurent    }
740b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    env->DeleteLocalRef(jAudioPort);
741b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    env->DeleteLocalRef(jHandle);
742b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    return (jint)AUDIO_JAVA_SUCCESS;
743b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent}
744b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
745b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jint convertAudioPortConfigFromNative(JNIEnv *env,
746b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 jobject jAudioPort,
747b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 jobject *jAudioPortConfig,
748b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 const struct audio_port_config *nAudioPortConfig)
749b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent{
750b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jint jStatus = AUDIO_JAVA_SUCCESS;
751b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jAudioGainConfig = NULL;
752b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jAudioGain = NULL;
753b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jintArray jGainValues;
754b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    bool audioportCreated = false;
755b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
756b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    ALOGV("convertAudioPortConfigFromNative jAudioPort %p", jAudioPort);
757b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
758b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jAudioPort == NULL) {
759b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jobject jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
760b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 nAudioPortConfig->id);
761b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
762b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("convertAudioPortConfigFromNative handle %d is a %s", nAudioPortConfig->id,
763b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent              nAudioPortConfig->type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix");
764b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
765b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jHandle == NULL) {
766b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            return (jint)AUDIO_JAVA_ERROR;
767b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
768b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        // create dummy port and port config objects with just the correct handle
769b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        // and configuration data. The actual AudioPortConfig objects will be
770b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        // constructed by java code with correct class type (device, mix etc...)
771b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        // and reference to AudioPort instance in this client
772b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jAudioPort = env->NewObject(gAudioPortClass, gAudioPortCstor,
773f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean                                           jHandle, // handle
774f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean                                           0,       // role
775f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean                                           NULL,    // name
776f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean                                           NULL,    // samplingRates
777f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean                                           NULL,    // channelMasks
778f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean                                           NULL,    // channelIndexMasks
779f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean                                           NULL,    // formats
780f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean                                           NULL);   // gains
781b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jHandle);
782b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jAudioPort == NULL) {
783b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            return (jint)AUDIO_JAVA_ERROR;
784b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
785b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("convertAudioPortConfigFromNative jAudioPort created for handle %d",
786b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent              nAudioPortConfig->id);
787b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
788b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        audioportCreated = true;
789b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
790b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
791b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    bool useInMask = useInChannelMask(nAudioPortConfig->type, nAudioPortConfig->role);
792b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
793b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    audio_channel_mask_t nMask;
794b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jint jMask;
795b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
796b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    int gainIndex = nAudioPortConfig->gain.index;
797b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (gainIndex >= 0) {
798b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("convertAudioPortConfigFromNative gain found with index %d mode %x",
799b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent              gainIndex, nAudioPortConfig->gain.mode);
800b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (audioportCreated) {
801b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            ALOGV("convertAudioPortConfigFromNative creating gain");
802b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jAudioGain = env->NewObject(gAudioGainClass, gAudioGainCstor,
803b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               gainIndex,
804b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               0,
805b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               0,
806b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               0,
807b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               0,
808b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               0,
809b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               0,
810b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               0,
811b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               0);
812b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            if (jAudioGain == NULL) {
813b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                ALOGV("convertAudioPortConfigFromNative creating gain FAILED");
814b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                jStatus = (jint)AUDIO_JAVA_ERROR;
815b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                goto exit;
816b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            }
817b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        } else {
818b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            ALOGV("convertAudioPortConfigFromNative reading gain from port");
819b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jobjectArray jGains = (jobjectArray)env->GetObjectField(jAudioPort,
820b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                                      gAudioPortFields.mGains);
821b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            if (jGains == NULL) {
822b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                ALOGV("convertAudioPortConfigFromNative could not get gains from port");
823b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                jStatus = (jint)AUDIO_JAVA_ERROR;
824b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                goto exit;
825b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            }
826b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jAudioGain = env->GetObjectArrayElement(jGains, gainIndex);
827b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            env->DeleteLocalRef(jGains);
828b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            if (jAudioGain == NULL) {
829b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                ALOGV("convertAudioPortConfigFromNative could not get gain at index %d", gainIndex);
830b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                jStatus = (jint)AUDIO_JAVA_ERROR;
831b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                goto exit;
832b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            }
833b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
8340078c7cc59082d32799b9097a81a0341fe98619dEric Laurent        int numValues;
8350078c7cc59082d32799b9097a81a0341fe98619dEric Laurent        if (useInMask) {
8360078c7cc59082d32799b9097a81a0341fe98619dEric Laurent            numValues = audio_channel_count_from_in_mask(nAudioPortConfig->gain.channel_mask);
8370078c7cc59082d32799b9097a81a0341fe98619dEric Laurent        } else {
8380078c7cc59082d32799b9097a81a0341fe98619dEric Laurent            numValues = audio_channel_count_from_out_mask(nAudioPortConfig->gain.channel_mask);
8390078c7cc59082d32799b9097a81a0341fe98619dEric Laurent        }
840b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jGainValues = env->NewIntArray(numValues);
841b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jGainValues == NULL) {
842b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            ALOGV("convertAudioPortConfigFromNative could not create gain values %d", numValues);
843b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = (jint)AUDIO_JAVA_ERROR;
844b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
845b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
846b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->SetIntArrayRegion(jGainValues, 0, numValues,
847b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                               nAudioPortConfig->gain.values);
848b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
849b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        nMask = nAudioPortConfig->gain.channel_mask;
850b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (useInMask) {
851b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jMask = inChannelMaskFromNative(nMask);
852b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
853b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        } else {
854b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jMask = outChannelMaskFromNative(nMask);
855b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
856b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
857b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
858b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jAudioGainConfig = env->NewObject(gAudioGainConfigClass,
859b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                        gAudioGainConfigCstor,
860b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                        gainIndex,
861b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                        jAudioGain,
862b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                        nAudioPortConfig->gain.mode,
863b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                        jMask,
864b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                        jGainValues,
865b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                        nAudioPortConfig->gain.ramp_duration_ms);
866b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jGainValues);
867b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jAudioGainConfig == NULL) {
868b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            ALOGV("convertAudioPortConfigFromNative could not create gain config");
869b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = (jint)AUDIO_JAVA_ERROR;
870b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
871b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
872b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
873b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jclass clazz;
874b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jmethodID methodID;
875b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (audioportCreated) {
876b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        clazz = gAudioPortConfigClass;
877b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        methodID = gAudioPortConfigCstor;
878b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("convertAudioPortConfigFromNative building a generic port config");
879b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    } else {
880b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (env->IsInstanceOf(jAudioPort, gAudioDevicePortClass)) {
881b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            clazz = gAudioDevicePortConfigClass;
882b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            methodID = gAudioDevicePortConfigCstor;
883b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            ALOGV("convertAudioPortConfigFromNative building a device config");
884b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        } else if (env->IsInstanceOf(jAudioPort, gAudioMixPortClass)) {
885b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            clazz = gAudioMixPortConfigClass;
886b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            methodID = gAudioMixPortConfigCstor;
887b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            ALOGV("convertAudioPortConfigFromNative building a mix config");
888b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        } else {
889b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = (jint)AUDIO_JAVA_ERROR;
890b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
891b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
892b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
893b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    nMask = nAudioPortConfig->channel_mask;
894b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (useInMask) {
895b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jMask = inChannelMaskFromNative(nMask);
896b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
897b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    } else {
898b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jMask = outChannelMaskFromNative(nMask);
899b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
900b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
901b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
902b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    *jAudioPortConfig = env->NewObject(clazz, methodID,
903b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                       jAudioPort,
904b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                       nAudioPortConfig->sample_rate,
905b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                       jMask,
906b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                       audioFormatFromNative(nAudioPortConfig->format),
907b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                       jAudioGainConfig);
908b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (*jAudioPortConfig == NULL) {
909b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("convertAudioPortConfigFromNative could not create new port config");
910b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jStatus = (jint)AUDIO_JAVA_ERROR;
911b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    } else {
912b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("convertAudioPortConfigFromNative OK");
913b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
914b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
915b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentexit:
916b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (audioportCreated) {
917b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jAudioPort);
918b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jAudioGain != NULL) {
919b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            env->DeleteLocalRef(jAudioGain);
920b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
921b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
922b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jAudioGainConfig != NULL) {
923b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jAudioGainConfig);
924b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
925b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    return jStatus;
926b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent}
927b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
9284e5e9e9405dc626a03a653161644841102ad89f1Paul McLeanstatic bool hasFormat(int* formats, size_t size, int format) {
9294e5e9e9405dc626a03a653161644841102ad89f1Paul McLean    for (size_t index = 0; index < size; index++) {
9304e5e9e9405dc626a03a653161644841102ad89f1Paul McLean        if (formats[index] == format) {
9314e5e9e9405dc626a03a653161644841102ad89f1Paul McLean            return true; // found
9324e5e9e9405dc626a03a653161644841102ad89f1Paul McLean        }
9334e5e9e9405dc626a03a653161644841102ad89f1Paul McLean    }
9344e5e9e9405dc626a03a653161644841102ad89f1Paul McLean    return false; // not found
9354e5e9e9405dc626a03a653161644841102ad89f1Paul McLean}
9364e5e9e9405dc626a03a653161644841102ad89f1Paul McLean
937737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung// TODO: pull out to separate file
938737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hungtemplate <typename T, size_t N>
939737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hungstatic constexpr size_t array_size(const T (&)[N]) {
940737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung    return N;
941737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung}
942737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung
943b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jint convertAudioPortFromNative(JNIEnv *env,
944b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                           jobject *jAudioPort, const struct audio_port *nAudioPort)
945b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent{
946b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
947b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jintArray jSamplingRates = NULL;
948b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jintArray jChannelMasks = NULL;
949f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    jintArray jChannelIndexMasks = NULL;
9504e5e9e9405dc626a03a653161644841102ad89f1Paul McLean    int* cFormats = NULL;
951b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jintArray jFormats = NULL;
952b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobjectArray jGains = NULL;
953b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jHandle = NULL;
95410804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    jstring jDeviceName = NULL;
955b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    bool useInMask;
956f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    size_t numPositionMasks = 0;
957f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    size_t numIndexMasks = 0;
9582db94372749c4fcc9bd715f41e0b5c4045ee7c84Paul McLean    size_t numUniqueFormats = 0;
9592db94372749c4fcc9bd715f41e0b5c4045ee7c84Paul McLean
96010804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    ALOGV("convertAudioPortFromNative id %d role %d type %d name %s",
96110804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean        nAudioPort->id, nAudioPort->role, nAudioPort->type, nAudioPort->name);
962b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
963737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung    // Verify audio port array count info.
964737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung    if (nAudioPort->num_sample_rates > array_size(nAudioPort->sample_rates)
965737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung            || nAudioPort->num_channel_masks > array_size(nAudioPort->channel_masks)
966737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung            || nAudioPort->num_formats > array_size(nAudioPort->formats)
967737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung            || nAudioPort->num_gains > array_size(nAudioPort->gains)) {
968737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung
969737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung        std::stringstream ss;
970737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung        ss << "convertAudioPortFromNative array count out of bounds:"
971737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung                << " num_sample_rates " << nAudioPort->num_sample_rates
972737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung                << " num_channel_masks " << nAudioPort->num_channel_masks
973737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung                << " num_formats " << nAudioPort->num_formats
974737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung                << " num_gains " << nAudioPort->num_gains
975737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung                ;
976737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung        std::string s = ss.str();
977737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung
978737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung        // Prefer to log through Java wtf instead of native ALOGE.
979737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung        ScopedLocalRef<jclass> jLogClass(env, env->FindClass("android/util/Log"));
980737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung        jmethodID jWtfId = (jLogClass.get() == nullptr)
981737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung                ? nullptr
982737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung                : env->GetStaticMethodID(jLogClass.get(), "wtf",
983737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung                        "(Ljava/lang/String;Ljava/lang/String;)I");
984737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung        if (jWtfId != nullptr) {
985737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung            ScopedLocalRef<jstring> jMessage(env, env->NewStringUTF(s.c_str()));
986737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung            ScopedLocalRef<jstring> jTag(env, env->NewStringUTF(LOG_TAG));
987737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung            (void)env->CallStaticIntMethod(jLogClass.get(), jWtfId, jTag.get(), jMessage.get());
988737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung        } else {
989737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung            ALOGE("%s", s.c_str());
990737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung        }
991737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung        jStatus = (jint)AUDIO_JAVA_ERROR;
992737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung        goto exit;
993737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung    }
994737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung
995b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jSamplingRates = env->NewIntArray(nAudioPort->num_sample_rates);
996b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jSamplingRates == NULL) {
997b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jStatus = (jint)AUDIO_JAVA_ERROR;
998b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        goto exit;
999b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1000b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (nAudioPort->num_sample_rates) {
1001b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->SetIntArrayRegion(jSamplingRates, 0, nAudioPort->num_sample_rates,
1002b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                               (jint *)nAudioPort->sample_rates);
1003b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1004b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1005f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    // count up how many masks are positional and indexed
1006f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    for(size_t index = 0; index < nAudioPort->num_channel_masks; index++) {
1007f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean        const audio_channel_mask_t mask = nAudioPort->channel_masks[index];
1008f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean        if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
1009f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean            numIndexMasks++;
1010f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean        } else {
1011f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean            numPositionMasks++;
1012f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean        }
1013f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    }
1014f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean
1015f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    jChannelMasks = env->NewIntArray(numPositionMasks);
1016b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jChannelMasks == NULL) {
1017b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jStatus = (jint)AUDIO_JAVA_ERROR;
1018b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        goto exit;
1019b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1020f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    jChannelIndexMasks = env->NewIntArray(numIndexMasks);
1021f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    if (jChannelIndexMasks == NULL) {
1022f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean        jStatus = (jint)AUDIO_JAVA_ERROR;
1023f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean        goto exit;
1024f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    }
1025b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    useInMask = useInChannelMask(nAudioPort->type, nAudioPort->role);
1026b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1027f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    // put the masks in the output arrays
1028f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    for (size_t maskIndex = 0, posMaskIndex = 0, indexedMaskIndex = 0;
1029f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean         maskIndex < nAudioPort->num_channel_masks; maskIndex++) {
1030f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean        const audio_channel_mask_t mask = nAudioPort->channel_masks[maskIndex];
1031f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean        if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
1032f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean            jint jMask = audio_channel_mask_get_bits(mask);
1033f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean            env->SetIntArrayRegion(jChannelIndexMasks, indexedMaskIndex++, 1, &jMask);
1034b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        } else {
1035f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean            jint jMask = useInMask ? inChannelMaskFromNative(mask)
1036f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean                                   : outChannelMaskFromNative(mask);
1037f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean            env->SetIntArrayRegion(jChannelMasks, posMaskIndex++, 1, &jMask);
1038b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1039b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1040b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1041f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    // formats
10422db94372749c4fcc9bd715f41e0b5c4045ee7c84Paul McLean    if (nAudioPort->num_formats != 0) {
10432db94372749c4fcc9bd715f41e0b5c4045ee7c84Paul McLean        cFormats = new int[nAudioPort->num_formats];
10442db94372749c4fcc9bd715f41e0b5c4045ee7c84Paul McLean        for (size_t index = 0; index < nAudioPort->num_formats; index++) {
10452db94372749c4fcc9bd715f41e0b5c4045ee7c84Paul McLean            int format = audioFormatFromNative(nAudioPort->formats[index]);
10462db94372749c4fcc9bd715f41e0b5c4045ee7c84Paul McLean            if (!hasFormat(cFormats, numUniqueFormats, format)) {
10472db94372749c4fcc9bd715f41e0b5c4045ee7c84Paul McLean                cFormats[numUniqueFormats++] = format;
10482db94372749c4fcc9bd715f41e0b5c4045ee7c84Paul McLean            }
10494e5e9e9405dc626a03a653161644841102ad89f1Paul McLean        }
10504e5e9e9405dc626a03a653161644841102ad89f1Paul McLean    }
10514e5e9e9405dc626a03a653161644841102ad89f1Paul McLean    jFormats = env->NewIntArray(numUniqueFormats);
1052b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jFormats == NULL) {
1053b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jStatus = (jint)AUDIO_JAVA_ERROR;
1054b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        goto exit;
1055b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
10562db94372749c4fcc9bd715f41e0b5c4045ee7c84Paul McLean    if (numUniqueFormats != 0) {
10572db94372749c4fcc9bd715f41e0b5c4045ee7c84Paul McLean        env->SetIntArrayRegion(jFormats, 0, numUniqueFormats, cFormats);
10582db94372749c4fcc9bd715f41e0b5c4045ee7c84Paul McLean    }
1059b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1060f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean    // gains
1061b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jGains = env->NewObjectArray(nAudioPort->num_gains,
1062b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                          gAudioGainClass, NULL);
1063b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jGains == NULL) {
1064b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jStatus = (jint)AUDIO_JAVA_ERROR;
1065b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        goto exit;
1066b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1067f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean
1068b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    for (size_t j = 0; j < nAudioPort->num_gains; j++) {
1069b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        audio_channel_mask_t nMask = nAudioPort->gains[j].channel_mask;
1070f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean        jint jMask;
1071b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (useInMask) {
1072b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jMask = inChannelMaskFromNative(nMask);
1073b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            ALOGV("convertAudioPortConfigFromNative IN mask java %x native %x", jMask, nMask);
1074b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        } else {
1075b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jMask = outChannelMaskFromNative(nMask);
1076b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            ALOGV("convertAudioPortConfigFromNative OUT mask java %x native %x", jMask, nMask);
1077b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1078b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1079b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jobject jGain = env->NewObject(gAudioGainClass, gAudioGainCstor,
1080b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 j,
1081b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 nAudioPort->gains[j].mode,
1082b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 jMask,
1083b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 nAudioPort->gains[j].min_value,
1084b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 nAudioPort->gains[j].max_value,
1085b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 nAudioPort->gains[j].default_value,
1086b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 nAudioPort->gains[j].step_value,
1087b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 nAudioPort->gains[j].min_ramp_ms,
1088b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 nAudioPort->gains[j].max_ramp_ms);
1089b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jGain == NULL) {
1090b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = (jint)AUDIO_JAVA_ERROR;
1091b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
1092b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1093b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->SetObjectArrayElement(jGains, j, jGain);
1094b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jGain);
1095b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1096b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1097b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1098b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                             nAudioPort->id);
1099b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jHandle == NULL) {
1100b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jStatus = (jint)AUDIO_JAVA_ERROR;
1101b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        goto exit;
1102b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1103b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
110410804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    jDeviceName = env->NewStringUTF(nAudioPort->name);
110510804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean
1106b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (nAudioPort->type == AUDIO_PORT_TYPE_DEVICE) {
1107b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("convertAudioPortFromNative is a device %08x", nAudioPort->ext.device.type);
1108b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jstring jAddress = env->NewStringUTF(nAudioPort->ext.device.address);
1109b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        *jAudioPort = env->NewObject(gAudioDevicePortClass, gAudioDevicePortCstor,
111010804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean                                     jHandle, jDeviceName,
1111f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean                                     jSamplingRates, jChannelMasks, jChannelIndexMasks,
1112f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean                                     jFormats, jGains,
1113b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                     nAudioPort->ext.device.type, jAddress);
1114b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jAddress);
1115b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    } else if (nAudioPort->type == AUDIO_PORT_TYPE_MIX) {
1116b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("convertAudioPortFromNative is a mix");
1117b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        *jAudioPort = env->NewObject(gAudioMixPortClass, gAudioMixPortCstor,
11184bcdba848449b33d7022de527c526943aff1f5fdEric Laurent                                     jHandle, nAudioPort->ext.mix.handle,
11194bcdba848449b33d7022de527c526943aff1f5fdEric Laurent                                     nAudioPort->role, jDeviceName,
1120f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean                                     jSamplingRates, jChannelMasks, jChannelIndexMasks,
1121b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                     jFormats, jGains);
1122b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    } else {
1123b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGE("convertAudioPortFromNative unknown nAudioPort type %d", nAudioPort->type);
1124b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jStatus = (jint)AUDIO_JAVA_ERROR;
1125b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        goto exit;
1126b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1127b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (*jAudioPort == NULL) {
1128b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jStatus = (jint)AUDIO_JAVA_ERROR;
1129b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        goto exit;
1130b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1131b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1132b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jAudioPortConfig;
1133b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jStatus = convertAudioPortConfigFromNative(env,
1134b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                       *jAudioPort,
1135b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                       &jAudioPortConfig,
1136b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                       &nAudioPort->active_config);
1137b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jStatus != AUDIO_JAVA_SUCCESS) {
1138737d9fb181ec12a23934f7de4e3f8ded79486b1eAndy Hung        goto exit;
1139b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1140b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1141b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    env->SetObjectField(*jAudioPort, gAudioPortFields.mActiveConfig, jAudioPortConfig);
1142b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1143b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentexit:
114410804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    if (jDeviceName != NULL) {
114510804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean        env->DeleteLocalRef(jDeviceName);
114610804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    }
1147b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jSamplingRates != NULL) {
1148b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jSamplingRates);
1149b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1150b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jChannelMasks != NULL) {
1151b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jChannelMasks);
1152b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
11534e5e9e9405dc626a03a653161644841102ad89f1Paul McLean    if (jChannelIndexMasks != NULL) {
11544e5e9e9405dc626a03a653161644841102ad89f1Paul McLean        env->DeleteLocalRef(jChannelIndexMasks);
11554e5e9e9405dc626a03a653161644841102ad89f1Paul McLean    }
11564e5e9e9405dc626a03a653161644841102ad89f1Paul McLean    if (cFormats != NULL) {
11574e5e9e9405dc626a03a653161644841102ad89f1Paul McLean        delete[] cFormats;
11584e5e9e9405dc626a03a653161644841102ad89f1Paul McLean    }
1159b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jFormats != NULL) {
1160b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jFormats);
1161b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1162b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jGains != NULL) {
1163b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jGains);
1164b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1165b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jHandle != NULL) {
1166b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jHandle);
1167b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1168b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1169b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    return jStatus;
1170b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent}
1171b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1172b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jint
1173b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentandroid_media_AudioSystem_listAudioPorts(JNIEnv *env, jobject clazz,
1174b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                         jobject jPorts, jintArray jGeneration)
1175b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent{
1176b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    ALOGV("listAudioPorts");
1177b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1178b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jPorts == NULL) {
1179b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGE("listAudioPorts NULL AudioPort ArrayList");
1180b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
1181b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1182b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (!env->IsInstanceOf(jPorts, gArrayListClass)) {
1183b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGE("listAudioPorts not an arraylist");
1184b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
1185b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1186b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1187b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) {
1188b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
1189b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1190b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1191b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    status_t status;
1192b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    unsigned int generation1;
1193b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    unsigned int generation;
1194b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    unsigned int numPorts;
1195b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jint *nGeneration;
1196b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    struct audio_port *nPorts = NULL;
1197b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS;
1198b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent    jint jStatus;
1199b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1200b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    // get the port count and all the ports until they both return the same generation
1201b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    do {
1202b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (attempts-- < 0) {
1203b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            status = TIMED_OUT;
1204b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            break;
1205b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1206b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1207b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        numPorts = 0;
1208b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE,
1209b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                             AUDIO_PORT_TYPE_NONE,
1210b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                      &numPorts,
1211b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                      NULL,
1212b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                      &generation1);
1213b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent        if (status != NO_ERROR) {
1214b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            ALOGE_IF(status != NO_ERROR, "AudioSystem::listAudioPorts error %d", status);
1215b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            break;
1216b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1217b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent        if (numPorts == 0) {
1218b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent            jStatus = (jint)AUDIO_JAVA_SUCCESS;
1219b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent            goto exit;
1220b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent        }
1221b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        nPorts = (struct audio_port *)realloc(nPorts, numPorts * sizeof(struct audio_port));
1222b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1223b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE,
1224b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                             AUDIO_PORT_TYPE_NONE,
1225b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                      &numPorts,
1226b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                      nPorts,
1227b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                      &generation);
1228b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("listAudioPorts AudioSystem::listAudioPorts numPorts %d generation %d generation1 %d",
1229b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent              numPorts, generation, generation1);
1230b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    } while (generation1 != generation && status == NO_ERROR);
1231b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1232b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent    jStatus = nativeToJavaStatus(status);
1233b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jStatus != AUDIO_JAVA_SUCCESS) {
1234b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        goto exit;
1235b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1236b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1237b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    for (size_t i = 0; i < numPorts; i++) {
1238b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jobject jAudioPort;
1239b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jStatus = convertAudioPortFromNative(env, &jAudioPort, &nPorts[i]);
1240b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jStatus != AUDIO_JAVA_SUCCESS) {
1241b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
1242b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1243b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->CallBooleanMethod(jPorts, gArrayListMethods.add, jAudioPort);
1244b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1245b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1246b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentexit:
1247b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent    nGeneration = env->GetIntArrayElements(jGeneration, NULL);
1248b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent    if (nGeneration == NULL) {
1249b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent        jStatus = (jint)AUDIO_JAVA_ERROR;
1250b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent    } else {
1251b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent        nGeneration[0] = generation1;
1252b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent        env->ReleaseIntArrayElements(jGeneration, nGeneration, 0);
1253b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent    }
1254b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    free(nPorts);
1255b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    return jStatus;
1256b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent}
1257b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1258b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic int
1259b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentandroid_media_AudioSystem_createAudioPatch(JNIEnv *env, jobject clazz,
1260b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                 jobjectArray jPatches, jobjectArray jSources, jobjectArray jSinks)
1261b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent{
1262b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    status_t status;
1263b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jint jStatus;
1264b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1265b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    ALOGV("createAudioPatch");
1266b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jPatches == NULL || jSources == NULL || jSinks == NULL) {
1267b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
1268b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1269b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1270b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (env->GetArrayLength(jPatches) != 1) {
1271b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
1272b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1273b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jint numSources = env->GetArrayLength(jSources);
1274b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (numSources == 0 || numSources > AUDIO_PATCH_PORTS_MAX) {
1275b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
1276b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1277b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1278b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jint numSinks = env->GetArrayLength(jSinks);
1279b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (numSinks == 0 || numSinks > AUDIO_PATCH_PORTS_MAX) {
1280b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
1281b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1282b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1283b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    audio_patch_handle_t handle = (audio_patch_handle_t)0;
1284b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jPatch = env->GetObjectArrayElement(jPatches, 0);
1285b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jPatchHandle = NULL;
1286b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jPatch != NULL) {
1287b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) {
1288b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            return (jint)AUDIO_JAVA_BAD_VALUE;
1289b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1290b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle);
1291b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId);
1292b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1293b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1294b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    struct audio_patch nPatch;
1295b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1296b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    nPatch.id = handle;
1297b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    nPatch.num_sources = 0;
1298b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    nPatch.num_sinks = 0;
1299b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jSource = NULL;
1300b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jSink = NULL;
1301b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1302b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    for (jint i = 0; i < numSources; i++) {
1303b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jSource = env->GetObjectArrayElement(jSources, i);
1304b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (!env->IsInstanceOf(jSource, gAudioPortConfigClass)) {
1305b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1306b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
1307b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
13086368a7df1884031b6620493e096abe8510c05e24Eric Laurent        jStatus = convertAudioPortConfigToNative(env, &nPatch.sources[i], jSource, false);
1309b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jSource);
1310b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jSource = NULL;
1311b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jStatus != AUDIO_JAVA_SUCCESS) {
1312b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
1313b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1314b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        nPatch.num_sources++;
1315b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1316b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1317b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    for (jint i = 0; i < numSinks; i++) {
1318b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jSink = env->GetObjectArrayElement(jSinks, i);
1319b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (!env->IsInstanceOf(jSink, gAudioPortConfigClass)) {
1320b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
1321b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
1322b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
13236368a7df1884031b6620493e096abe8510c05e24Eric Laurent        jStatus = convertAudioPortConfigToNative(env, &nPatch.sinks[i], jSink, false);
1324b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jSink);
1325b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jSink = NULL;
1326b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jStatus != AUDIO_JAVA_SUCCESS) {
1327b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
1328b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1329b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        nPatch.num_sinks++;
1330b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1331b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1332b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    ALOGV("AudioSystem::createAudioPatch");
1333b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    status = AudioSystem::createAudioPatch(&nPatch, &handle);
1334b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    ALOGV("AudioSystem::createAudioPatch() returned %d hande %d", status, handle);
1335b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1336b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jStatus = nativeToJavaStatus(status);
1337b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jStatus != AUDIO_JAVA_SUCCESS) {
1338b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        goto exit;
1339b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1340b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1341b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jPatchHandle == NULL) {
1342b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jPatchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1343b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                           handle);
1344b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jPatchHandle == NULL) {
1345b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = (jint)AUDIO_JAVA_ERROR;
1346b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
1347b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1348b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor, jPatchHandle, jSources, jSinks);
1349b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jPatch == NULL) {
1350b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = (jint)AUDIO_JAVA_ERROR;
1351b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
1352b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1353b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->SetObjectArrayElement(jPatches, 0, jPatch);
1354b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    } else {
1355b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->SetIntField(jPatchHandle, gAudioHandleFields.mId, handle);
1356b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1357b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1358b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentexit:
1359b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jPatchHandle != NULL) {
1360b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jPatchHandle);
1361b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1362b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jPatch != NULL) {
1363b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jPatch);
1364b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1365b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jSource != NULL) {
1366b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jSource);
1367b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1368b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jSink != NULL) {
1369b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jSink);
1370b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1371b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    return jStatus;
1372b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent}
1373b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
13740f0b4919667f418b249c497f5ad3e83fdf4437e5Andreas Gampestatic jint
1375b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentandroid_media_AudioSystem_releaseAudioPatch(JNIEnv *env, jobject clazz,
1376b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               jobject jPatch)
1377b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent{
1378b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    ALOGV("releaseAudioPatch");
1379b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jPatch == NULL) {
1380b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
1381b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1382b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1383b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    audio_patch_handle_t handle = (audio_patch_handle_t)0;
1384b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jPatchHandle = NULL;
1385b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (!env->IsInstanceOf(jPatch, gAudioPatchClass)) {
1386b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
1387b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1388b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jPatchHandle = env->GetObjectField(jPatch, gAudioPatchFields.mHandle);
1389b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId);
1390b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    env->DeleteLocalRef(jPatchHandle);
1391b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1392b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    ALOGV("AudioSystem::releaseAudioPatch");
1393b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    status_t status = AudioSystem::releaseAudioPatch(handle);
1394b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    ALOGV("AudioSystem::releaseAudioPatch() returned %d", status);
1395b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jint jStatus = nativeToJavaStatus(status);
13960f0b4919667f418b249c497f5ad3e83fdf4437e5Andreas Gampe    return jStatus;
1397b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent}
1398b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1399b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentstatic jint
1400b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentandroid_media_AudioSystem_listAudioPatches(JNIEnv *env, jobject clazz,
1401b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                           jobject jPatches, jintArray jGeneration)
1402b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent{
1403b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    ALOGV("listAudioPatches");
1404b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jPatches == NULL) {
1405b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGE("listAudioPatches NULL AudioPatch ArrayList");
1406b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
1407b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1408b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (!env->IsInstanceOf(jPatches, gArrayListClass)) {
1409b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGE("listAudioPatches not an arraylist");
1410b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
1411b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1412b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1413b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jGeneration == NULL || env->GetArrayLength(jGeneration) != 1) {
1414b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
1415b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1416b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1417b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    status_t status;
1418b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    unsigned int generation1;
1419b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    unsigned int generation;
1420b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    unsigned int numPatches;
1421b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jint *nGeneration;
1422b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    struct audio_patch *nPatches = NULL;
1423b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobjectArray jSources = NULL;
1424b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jSource = NULL;
1425b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobjectArray jSinks = NULL;
1426b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jSink = NULL;
1427b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    jobject jPatch = NULL;
1428b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    int attempts = MAX_PORT_GENERATION_SYNC_ATTEMPTS;
1429b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent    jint jStatus;
1430b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1431b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    // get the patch count and all the patches until they both return the same generation
1432b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    do {
1433b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (attempts-- < 0) {
1434b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            status = TIMED_OUT;
1435b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            break;
1436b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1437b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1438b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        numPatches = 0;
1439b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        status = AudioSystem::listAudioPatches(&numPatches,
1440b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               NULL,
1441b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               &generation1);
1442b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent        if (status != NO_ERROR) {
1443b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            ALOGE_IF(status != NO_ERROR, "listAudioPatches AudioSystem::listAudioPatches error %d",
1444b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                      status);
1445b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            break;
1446b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1447b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent        if (numPatches == 0) {
1448b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent            jStatus = (jint)AUDIO_JAVA_SUCCESS;
1449b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent            goto exit;
1450b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent        }
1451b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent
1452b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        nPatches = (struct audio_patch *)realloc(nPatches, numPatches * sizeof(struct audio_patch));
1453b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1454b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        status = AudioSystem::listAudioPatches(&numPatches,
1455b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               nPatches,
1456b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               &generation);
1457b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        ALOGV("listAudioPatches AudioSystem::listAudioPatches numPatches %d generation %d generation1 %d",
1458b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent              numPatches, generation, generation1);
1459b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1460b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    } while (generation1 != generation && status == NO_ERROR);
1461b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1462b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent    jStatus = nativeToJavaStatus(status);
1463b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jStatus != AUDIO_JAVA_SUCCESS) {
1464b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        goto exit;
1465b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1466b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1467b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    for (size_t i = 0; i < numPatches; i++) {
1468b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jobject patchHandle = env->NewObject(gAudioHandleClass, gAudioHandleCstor,
1469b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                 nPatches[i].id);
1470b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (patchHandle == NULL) {
1471b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = AUDIO_JAVA_ERROR;
1472b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
1473b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
147446d8444631b4b1253a76bfcc78a29d26014d022fDan Albert        ALOGV("listAudioPatches patch %zu num_sources %d num_sinks %d",
1475b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent              i, nPatches[i].num_sources, nPatches[i].num_sinks);
1476b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1477b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->SetIntField(patchHandle, gAudioHandleFields.mId, nPatches[i].id);
1478b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1479b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        // load sources
1480b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jSources = env->NewObjectArray(nPatches[i].num_sources,
1481b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                       gAudioPortConfigClass, NULL);
1482b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jSources == NULL) {
1483b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = AUDIO_JAVA_ERROR;
1484b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
1485b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1486b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1487b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        for (size_t j = 0; j < nPatches[i].num_sources; j++) {
1488b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = convertAudioPortConfigFromNative(env,
1489b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                      NULL,
1490b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                      &jSource,
1491b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                      &nPatches[i].sources[j]);
1492b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            if (jStatus != AUDIO_JAVA_SUCCESS) {
1493b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                goto exit;
1494b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            }
1495b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            env->SetObjectArrayElement(jSources, j, jSource);
1496b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            env->DeleteLocalRef(jSource);
1497b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jSource = NULL;
149846d8444631b4b1253a76bfcc78a29d26014d022fDan Albert            ALOGV("listAudioPatches patch %zu source %zu is a %s handle %d",
1499b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                  i, j,
1500b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                  nPatches[i].sources[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix",
1501b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                  nPatches[i].sources[j].id);
1502b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1503b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        // load sinks
1504b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jSinks = env->NewObjectArray(nPatches[i].num_sinks,
1505b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                     gAudioPortConfigClass, NULL);
1506b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jSinks == NULL) {
1507b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = AUDIO_JAVA_ERROR;
1508b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
1509b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1510b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1511b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        for (size_t j = 0; j < nPatches[i].num_sinks; j++) {
1512b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = convertAudioPortConfigFromNative(env,
1513b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                      NULL,
1514b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                      &jSink,
1515b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                      &nPatches[i].sinks[j]);
1516b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1517b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            if (jStatus != AUDIO_JAVA_SUCCESS) {
1518b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                goto exit;
1519b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            }
1520b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            env->SetObjectArrayElement(jSinks, j, jSink);
1521b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            env->DeleteLocalRef(jSink);
1522b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jSink = NULL;
152346d8444631b4b1253a76bfcc78a29d26014d022fDan Albert            ALOGV("listAudioPatches patch %zu sink %zu is a %s handle %d",
1524b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                  i, j,
1525b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                  nPatches[i].sinks[j].type == AUDIO_PORT_TYPE_DEVICE ? "device" : "mix",
1526b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                  nPatches[i].sinks[j].id);
1527b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1528b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1529b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jPatch = env->NewObject(gAudioPatchClass, gAudioPatchCstor,
1530b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                       patchHandle, jSources, jSinks);
1531b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jSources);
1532b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jSources = NULL;
1533b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jSinks);
1534b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jSinks = NULL;
1535b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        if (jPatch == NULL) {
1536b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            jStatus = AUDIO_JAVA_ERROR;
1537b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent            goto exit;
1538b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        }
1539b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->CallBooleanMethod(jPatches, gArrayListMethods.add, jPatch);
1540b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jPatch);
1541b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        jPatch = NULL;
1542b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1543b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
1544b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurentexit:
1545b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent
1546b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent    nGeneration = env->GetIntArrayElements(jGeneration, NULL);
1547b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent    if (nGeneration == NULL) {
1548b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent        jStatus = AUDIO_JAVA_ERROR;
1549b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent    } else {
1550b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent        nGeneration[0] = generation1;
1551b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent        env->ReleaseIntArrayElements(jGeneration, nGeneration, 0);
1552b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent    }
1553b36d104b8ffba24417c1b15b763bc8972c6e0d3dEric Laurent
1554b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jSources != NULL) {
1555b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jSources);
1556b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1557b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jSource != NULL) {
1558b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jSource);
1559b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1560b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jSinks != NULL) {
1561b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jSinks);
1562b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1563b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jSink != NULL) {
1564b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jSink);
1565b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1566b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    if (jPatch != NULL) {
1567b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent        env->DeleteLocalRef(jPatch);
1568b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    }
1569b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    free(nPatches);
1570b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    return jStatus;
1571b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent}
1572b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
15733a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurentstatic jint
15743a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurentandroid_media_AudioSystem_setAudioPortConfig(JNIEnv *env, jobject clazz,
15753a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent                                 jobject jAudioPortConfig)
15763a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent{
15773a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    ALOGV("setAudioPortConfig");
15783a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    if (jAudioPortConfig == NULL) {
15793a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        return AUDIO_JAVA_BAD_VALUE;
15803a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    }
15813a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    if (!env->IsInstanceOf(jAudioPortConfig, gAudioPortConfigClass)) {
15823a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        return AUDIO_JAVA_BAD_VALUE;
15833a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    }
15843a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    struct audio_port_config nAudioPortConfig;
15856368a7df1884031b6620493e096abe8510c05e24Eric Laurent    jint jStatus = convertAudioPortConfigToNative(env, &nAudioPortConfig, jAudioPortConfig, true);
15863a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    if (jStatus != AUDIO_JAVA_SUCCESS) {
15873a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent        return jStatus;
15883a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    }
15893a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    status_t status = AudioSystem::setAudioPortConfig(&nAudioPortConfig);
15903a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    ALOGV("AudioSystem::setAudioPortConfig() returned %d", status);
15913a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    jStatus = nativeToJavaStatus(status);
15923a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    return jStatus;
15933a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent}
15943a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent
1595700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentstatic void
1596700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentandroid_media_AudioSystem_eventHandlerSetup(JNIEnv *env, jobject thiz, jobject weak_this)
1597700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent{
1598700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    ALOGV("eventHandlerSetup");
1599700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
1600700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    sp<JNIAudioPortCallback> callback = new JNIAudioPortCallback(env, thiz, weak_this);
1601700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
16022615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    if (AudioSystem::addAudioPortCallback(callback) == NO_ERROR) {
16032615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent        setJniCallback(env, thiz, callback);
16042615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    }
1605700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent}
1606700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
1607700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentstatic void
1608700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurentandroid_media_AudioSystem_eventHandlerFinalize(JNIEnv *env, jobject thiz)
1609700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent{
1610700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    ALOGV("eventHandlerFinalize");
1611700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
16122615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    sp<JNIAudioPortCallback> callback = setJniCallback(env, thiz, 0);
1613700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
16142615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    if (callback != 0) {
16152615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent        AudioSystem::removeAudioPortCallback(callback);
16162615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    }
1617700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent}
1618700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
1619b634e1b6d6bda56128c354b1803b04b537e3799dEric Laurentstatic jint
1620b634e1b6d6bda56128c354b1803b04b537e3799dEric Laurentandroid_media_AudioSystem_getAudioHwSyncForSession(JNIEnv *env, jobject thiz, jint sessionId)
1621b634e1b6d6bda56128c354b1803b04b537e3799dEric Laurent{
162233b840444f5a481dd31e129079d3c0cf3acdf80eGlenn Kasten    return (jint) AudioSystem::getAudioHwSyncForSession((audio_session_t) sessionId);
1623b634e1b6d6bda56128c354b1803b04b537e3799dEric Laurent}
1624b634e1b6d6bda56128c354b1803b04b537e3799dEric Laurent
16255a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivistatic void
16265a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Triviandroid_media_AudioSystem_registerDynPolicyCallback(JNIEnv *env, jobject thiz)
16275a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi{
16285a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    AudioSystem::setDynPolicyCallback(android_media_AudioSystem_dyn_policy_callback);
16295a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi}
16307f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
1631d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivistatic void
1632d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Triviandroid_media_AudioSystem_registerRecordingCallback(JNIEnv *env, jobject thiz)
1633d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi{
1634d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    AudioSystem::setRecordConfigCallback(android_media_AudioSystem_recording_callback);
1635d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi}
1636d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi
16377f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
16387f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurentstatic jint convertAudioMixToNative(JNIEnv *env,
16397f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                    AudioMix *nAudioMix,
16407f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                    const jobject jAudioMix)
16417f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent{
16427f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType);
16437f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags);
16444ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi    nAudioMix->mDeviceType = (audio_devices_t)
16454ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi            env->GetIntField(jAudioMix, gAudioMixFields.mDeviceType);
16467f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
16474ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi    jstring jDeviceAddress = (jstring)env->GetObjectField(jAudioMix,
16484ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi                                                           gAudioMixFields.mDeviceAddress);
16494ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi    const char *nDeviceAddress = env->GetStringUTFChars(jDeviceAddress, NULL);
16504ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi    nAudioMix->mDeviceAddress = String8(nDeviceAddress);
16514ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi    env->ReleaseStringUTFChars(jDeviceAddress, nDeviceAddress);
16524ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi    env->DeleteLocalRef(jDeviceAddress);
16537f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
16545a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    nAudioMix->mCbFlags = env->GetIntField(jAudioMix, gAudioMixFields.mCallbackFlags);
16555a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi
16567f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jobject jFormat = env->GetObjectField(jAudioMix, gAudioMixFields.mFormat);
16577f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    nAudioMix->mFormat.sample_rate = env->GetIntField(jFormat,
16587f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                                     gAudioFormatFields.mSampleRate);
16597f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    nAudioMix->mFormat.channel_mask = outChannelMaskToNative(env->GetIntField(jFormat,
16607f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                                     gAudioFormatFields.mChannelMask));
16617f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    nAudioMix->mFormat.format = audioFormatToNative(env->GetIntField(jFormat,
16627f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                                     gAudioFormatFields.mEncoding));
16637f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    env->DeleteLocalRef(jFormat);
16647f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
16657f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule);
16667f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria);
16677f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    env->DeleteLocalRef(jRule);
16687f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jobjectArray jCriteria = (jobjectArray)env->CallObjectMethod(jRuleCriteria,
16697f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                                                 gArrayListMethods.toArray);
16707f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    env->DeleteLocalRef(jRuleCriteria);
16717f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
16727f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jint numCriteria = env->GetArrayLength(jCriteria);
16737f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    if (numCriteria > MAX_CRITERIA_PER_MIX) {
16747f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        numCriteria = MAX_CRITERIA_PER_MIX;
16757f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    }
16767f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
16777f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    for (jint i = 0; i < numCriteria; i++) {
1678ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi        AudioMixMatchCriterion nCriterion;
16797f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
16807f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        jobject jCriterion = env->GetObjectArrayElement(jCriteria, i);
16817f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
1682ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi        nCriterion.mRule = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mRule);
16837f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
1684ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi        const uint32_t match_rule = nCriterion.mRule & ~RULE_EXCLUSION_MASK;
1685ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi        switch (match_rule) {
1686ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi        case RULE_MATCH_UID:
1687ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi            nCriterion.mValue.mUid = env->GetIntField(jCriterion,
1688ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi                    gAudioMixMatchCriterionFields.mIntProp);
1689ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi            break;
1690ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi        case RULE_MATCH_ATTRIBUTE_USAGE:
1691ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi        case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: {
1692ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi            jobject jAttributes = env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr);
1693ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi            if (match_rule == RULE_MATCH_ATTRIBUTE_USAGE) {
1694ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi                nCriterion.mValue.mUsage = (audio_usage_t)env->GetIntField(jAttributes,
1695ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi                        gAudioAttributesFields.mUsage);
1696ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi            } else {
1697ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi                nCriterion.mValue.mSource = (audio_source_t)env->GetIntField(jAttributes,
1698ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi                        gAudioAttributesFields.mSource);
1699ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi            }
1700ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi            env->DeleteLocalRef(jAttributes);
1701ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi            }
1702ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi            break;
17037f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        }
17047f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
17057f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        nAudioMix->mCriteria.add(nCriterion);
17067f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        env->DeleteLocalRef(jCriterion);
17077f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    }
17087f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
17097f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    env->DeleteLocalRef(jCriteria);
17107f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
17117f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    return (jint)AUDIO_JAVA_SUCCESS;
17127f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent}
17137f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
17147f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurentstatic jint
17157f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurentandroid_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz,
17167f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                              jobject jMixesList, jboolean registration)
17177f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent{
17187f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    ALOGV("registerPolicyMixes");
17197f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
17207f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    if (jMixesList == NULL) {
17217f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
17227f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    }
17237f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    if (!env->IsInstanceOf(jMixesList, gArrayListClass)) {
17247f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        return (jint)AUDIO_JAVA_BAD_VALUE;
17257f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    }
17267f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jobjectArray jMixes = (jobjectArray)env->CallObjectMethod(jMixesList,
17277f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                                              gArrayListMethods.toArray);
17287f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jint numMixes = env->GetArrayLength(jMixes);
17297f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    if (numMixes > MAX_MIXES_PER_POLICY) {
17307f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        numMixes = MAX_MIXES_PER_POLICY;
17317f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    }
17327f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
17337f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    status_t status;
17347f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jint jStatus;
17357f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jobject jAudioMix = NULL;
17367f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    Vector <AudioMix> mixes;
17377f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    for (jint i = 0; i < numMixes; i++) {
17387f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        jAudioMix = env->GetObjectArrayElement(jMixes, i);
17397f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        if (!env->IsInstanceOf(jAudioMix, gAudioMixClass)) {
17407f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent            jStatus = (jint)AUDIO_JAVA_BAD_VALUE;
17417f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent            goto exit;
17427f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        }
17437f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        AudioMix mix;
17447f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        jStatus = convertAudioMixToNative(env, &mix, jAudioMix);
17457f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        env->DeleteLocalRef(jAudioMix);
17467f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        jAudioMix = NULL;
17477f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        if (jStatus != AUDIO_JAVA_SUCCESS) {
17487f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent            goto exit;
17497f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        }
17507f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        mixes.add(mix);
17517f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    }
17527f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
17537f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    ALOGV("AudioSystem::registerPolicyMixes numMixes %d registration %d", numMixes, registration);
17547f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    status = AudioSystem::registerPolicyMixes(mixes, registration);
17557f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    ALOGV("AudioSystem::registerPolicyMixes() returned %d", status);
17567f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
17577f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    jStatus = nativeToJavaStatus(status);
17587f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    if (jStatus != AUDIO_JAVA_SUCCESS) {
17597f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        goto exit;
17607f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    }
17617f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
17627f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurentexit:
17637f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    if (jAudioMix != NULL) {
17647f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent        env->DeleteLocalRef(jAudioMix);
17657f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    }
17667f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    return jStatus;
17677f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent}
17687f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
17690867bed9ddb3bea3d7c252791f8b62ae21ad3de5Eric Laurentstatic jint
17700867bed9ddb3bea3d7c252791f8b62ae21ad3de5Eric Laurentandroid_media_AudioSystem_systemReady(JNIEnv *env, jobject thiz)
17710867bed9ddb3bea3d7c252791f8b62ae21ad3de5Eric Laurent{
17720867bed9ddb3bea3d7c252791f8b62ae21ad3de5Eric Laurent    return nativeToJavaStatus(AudioSystem::systemReady());
17730867bed9ddb3bea3d7c252791f8b62ae21ad3de5Eric Laurent}
17747f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
1775eab40d14a88574e4041504a68012c95a4a8f03c9Eric Laurentstatic jfloat
1776eab40d14a88574e4041504a68012c95a4a8f03c9Eric Laurentandroid_media_AudioSystem_getStreamVolumeDB(JNIEnv *env, jobject thiz,
1777eab40d14a88574e4041504a68012c95a4a8f03c9Eric Laurent                                            jint stream, jint index, jint device)
1778eab40d14a88574e4041504a68012c95a4a8f03c9Eric Laurent{
1779eab40d14a88574e4041504a68012c95a4a8f03c9Eric Laurent    return (jfloat)AudioSystem::getStreamVolumeDB((audio_stream_type_t)stream,
1780eab40d14a88574e4041504a68012c95a4a8f03c9Eric Laurent                                                  (int)index,
1781eab40d14a88574e4041504a68012c95a4a8f03c9Eric Laurent                                                  (audio_devices_t)device);
1782eab40d14a88574e4041504a68012c95a4a8f03c9Eric Laurent}
17837f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
1784980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivistatic jboolean
1785980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Triviandroid_media_AudioSystem_isOffloadSupported(JNIEnv *env, jobject thiz,
1786980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi        jint encoding, jint sampleRate, jint channelMask, jint channelIndexMask)
1787980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi{
1788980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi    audio_offload_info_t format = AUDIO_INFO_INITIALIZER;
1789980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi    format.format = (audio_format_t) audioFormatToNative(encoding);
1790980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi    format.sample_rate = (uint32_t) sampleRate;
1791980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi    format.channel_mask = nativeChannelMaskFromJavaChannelMasks(channelMask, channelIndexMask);
1792980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi    format.stream_type = AUDIO_STREAM_MUSIC;
1793980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi    format.has_video = false;
1794980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi    format.is_streaming = false;
1795980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi    // offload duration unknown at this point:
1796980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi    // client side code cannot access "audio.offload.min.duration.secs" property to make a query
1797980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi    // agnostic of duration, so using acceptable estimate of 2mn
1798980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi    format.duration_us = 120 * 1000000;
1799980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi    return AudioSystem::isOffloadSupported(format);
1800980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi}
1801980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi
1802c0f494403873435d463c4817066f9c68d57310a7jiabinstatic jint
1803c0f494403873435d463c4817066f9c68d57310a7jiabinandroid_media_AudioSystem_getMicrophones(JNIEnv *env, jobject thiz, jobject jMicrophonesInfo)
1804c0f494403873435d463c4817066f9c68d57310a7jiabin{
1805c0f494403873435d463c4817066f9c68d57310a7jiabin    ALOGV("getMicrophones");
1806c0f494403873435d463c4817066f9c68d57310a7jiabin
1807c0f494403873435d463c4817066f9c68d57310a7jiabin    if (jMicrophonesInfo == NULL) {
1808c0f494403873435d463c4817066f9c68d57310a7jiabin        ALOGE("jMicrophonesInfo NULL MicrophoneInfo ArrayList");
1809c0f494403873435d463c4817066f9c68d57310a7jiabin        return (jint)AUDIO_JAVA_BAD_VALUE;
1810c0f494403873435d463c4817066f9c68d57310a7jiabin    }
1811c0f494403873435d463c4817066f9c68d57310a7jiabin    if (!env->IsInstanceOf(jMicrophonesInfo, gArrayListClass)) {
1812c0f494403873435d463c4817066f9c68d57310a7jiabin        ALOGE("getMicrophones not an arraylist");
1813c0f494403873435d463c4817066f9c68d57310a7jiabin        return (jint)AUDIO_JAVA_BAD_VALUE;
1814c0f494403873435d463c4817066f9c68d57310a7jiabin    }
1815c0f494403873435d463c4817066f9c68d57310a7jiabin
1816c0f494403873435d463c4817066f9c68d57310a7jiabin    jint jStatus;
1817c0f494403873435d463c4817066f9c68d57310a7jiabin    std::vector<media::MicrophoneInfo> microphones;
1818c0f494403873435d463c4817066f9c68d57310a7jiabin    status_t status = AudioSystem::getMicrophones(&microphones);
1819c0f494403873435d463c4817066f9c68d57310a7jiabin    if (status != NO_ERROR) {
1820c0f494403873435d463c4817066f9c68d57310a7jiabin        ALOGE_IF(status != NO_ERROR, "AudioSystem::getMicrophones error %d", status);
1821c0f494403873435d463c4817066f9c68d57310a7jiabin        jStatus = nativeToJavaStatus(status);
1822c0f494403873435d463c4817066f9c68d57310a7jiabin        return jStatus;
1823c0f494403873435d463c4817066f9c68d57310a7jiabin    }
1824c0f494403873435d463c4817066f9c68d57310a7jiabin    if (microphones.size() == 0) {
1825c0f494403873435d463c4817066f9c68d57310a7jiabin        jStatus = (jint)AUDIO_JAVA_SUCCESS;
1826c0f494403873435d463c4817066f9c68d57310a7jiabin        return jStatus;
1827c0f494403873435d463c4817066f9c68d57310a7jiabin    }
1828c0f494403873435d463c4817066f9c68d57310a7jiabin    for (size_t i = 0; i < microphones.size(); i++) {
1829c0f494403873435d463c4817066f9c68d57310a7jiabin        jobject jMicrophoneInfo;
1830c0f494403873435d463c4817066f9c68d57310a7jiabin        jStatus = convertMicrophoneInfoFromNative(env, &jMicrophoneInfo, &microphones[i]);
1831c0f494403873435d463c4817066f9c68d57310a7jiabin        if (jStatus != AUDIO_JAVA_SUCCESS) {
1832c0f494403873435d463c4817066f9c68d57310a7jiabin            return jStatus;
1833c0f494403873435d463c4817066f9c68d57310a7jiabin        }
1834c0f494403873435d463c4817066f9c68d57310a7jiabin        env->CallBooleanMethod(jMicrophonesInfo, gArrayListMethods.add, jMicrophoneInfo);
1835c0f494403873435d463c4817066f9c68d57310a7jiabin        env->DeleteLocalRef(jMicrophoneInfo);
1836c0f494403873435d463c4817066f9c68d57310a7jiabin    }
1837c0f494403873435d463c4817066f9c68d57310a7jiabin
1838c0f494403873435d463c4817066f9c68d57310a7jiabin    return jStatus;
1839c0f494403873435d463c4817066f9c68d57310a7jiabin}
1840c0f494403873435d463c4817066f9c68d57310a7jiabin
18413994075a5b638ecffce5b8782521fce7631e7169jiabinstatic jint
18423994075a5b638ecffce5b8782521fce7631e7169jiabinandroid_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject thiz,
18433994075a5b638ecffce5b8782521fce7631e7169jiabin                                             jobject jSurroundFormats, jboolean reported)
18443994075a5b638ecffce5b8782521fce7631e7169jiabin{
18453994075a5b638ecffce5b8782521fce7631e7169jiabin    ALOGV("getSurroundFormats");
18463994075a5b638ecffce5b8782521fce7631e7169jiabin
18473994075a5b638ecffce5b8782521fce7631e7169jiabin    if (jSurroundFormats == NULL) {
18483994075a5b638ecffce5b8782521fce7631e7169jiabin        ALOGE("jSurroundFormats is NULL");
18493994075a5b638ecffce5b8782521fce7631e7169jiabin        return (jint)AUDIO_JAVA_BAD_VALUE;
18503994075a5b638ecffce5b8782521fce7631e7169jiabin    }
18513994075a5b638ecffce5b8782521fce7631e7169jiabin    if (!env->IsInstanceOf(jSurroundFormats, gMapClass)) {
18523994075a5b638ecffce5b8782521fce7631e7169jiabin        ALOGE("getSurroundFormats not a map");
18533994075a5b638ecffce5b8782521fce7631e7169jiabin        return (jint)AUDIO_JAVA_BAD_VALUE;
18543994075a5b638ecffce5b8782521fce7631e7169jiabin    }
18553994075a5b638ecffce5b8782521fce7631e7169jiabin
18563994075a5b638ecffce5b8782521fce7631e7169jiabin    jint jStatus;
18573994075a5b638ecffce5b8782521fce7631e7169jiabin    unsigned int numSurroundFormats = 0;
18583994075a5b638ecffce5b8782521fce7631e7169jiabin    audio_format_t *surroundFormats = NULL;
18593994075a5b638ecffce5b8782521fce7631e7169jiabin    bool *surroundFormatsEnabled = NULL;
18603994075a5b638ecffce5b8782521fce7631e7169jiabin    status_t status = AudioSystem::getSurroundFormats(
18613994075a5b638ecffce5b8782521fce7631e7169jiabin            &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
18623994075a5b638ecffce5b8782521fce7631e7169jiabin    if (status != NO_ERROR) {
18633994075a5b638ecffce5b8782521fce7631e7169jiabin        ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
18643994075a5b638ecffce5b8782521fce7631e7169jiabin        jStatus = nativeToJavaStatus(status);
18653994075a5b638ecffce5b8782521fce7631e7169jiabin        goto exit;
18663994075a5b638ecffce5b8782521fce7631e7169jiabin    }
18673994075a5b638ecffce5b8782521fce7631e7169jiabin    if (numSurroundFormats == 0) {
18683994075a5b638ecffce5b8782521fce7631e7169jiabin        jStatus = (jint)AUDIO_JAVA_SUCCESS;
18693994075a5b638ecffce5b8782521fce7631e7169jiabin        goto exit;
18703994075a5b638ecffce5b8782521fce7631e7169jiabin    }
18713994075a5b638ecffce5b8782521fce7631e7169jiabin    surroundFormats = (audio_format_t *)calloc(numSurroundFormats, sizeof(audio_format_t));
18723994075a5b638ecffce5b8782521fce7631e7169jiabin    surroundFormatsEnabled = (bool *)calloc(numSurroundFormats, sizeof(bool));
18733994075a5b638ecffce5b8782521fce7631e7169jiabin    status = AudioSystem::getSurroundFormats(
18743994075a5b638ecffce5b8782521fce7631e7169jiabin            &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
18753994075a5b638ecffce5b8782521fce7631e7169jiabin    jStatus = nativeToJavaStatus(status);
18763994075a5b638ecffce5b8782521fce7631e7169jiabin    if (status != NO_ERROR) {
18773994075a5b638ecffce5b8782521fce7631e7169jiabin        ALOGE_IF(status != NO_ERROR, "AudioSystem::getSurroundFormats error %d", status);
18783994075a5b638ecffce5b8782521fce7631e7169jiabin        goto exit;
18793994075a5b638ecffce5b8782521fce7631e7169jiabin    }
18803994075a5b638ecffce5b8782521fce7631e7169jiabin    for (size_t i = 0; i < numSurroundFormats; i++) {
18813994075a5b638ecffce5b8782521fce7631e7169jiabin        jobject surroundFormat = env->NewObject(gIntegerClass, gIntegerCstor,
18823994075a5b638ecffce5b8782521fce7631e7169jiabin                                                audioFormatFromNative(surroundFormats[i]));
18833994075a5b638ecffce5b8782521fce7631e7169jiabin        jobject enabled = env->NewObject(gBooleanClass, gBooleanCstor, surroundFormatsEnabled[i]);
18843994075a5b638ecffce5b8782521fce7631e7169jiabin        env->CallObjectMethod(jSurroundFormats, gMapPut, surroundFormat, enabled);
18853994075a5b638ecffce5b8782521fce7631e7169jiabin        env->DeleteLocalRef(surroundFormat);
18863994075a5b638ecffce5b8782521fce7631e7169jiabin        env->DeleteLocalRef(enabled);
18873994075a5b638ecffce5b8782521fce7631e7169jiabin    }
18883994075a5b638ecffce5b8782521fce7631e7169jiabin
18893994075a5b638ecffce5b8782521fce7631e7169jiabinexit:
18903994075a5b638ecffce5b8782521fce7631e7169jiabin    free(surroundFormats);
18913994075a5b638ecffce5b8782521fce7631e7169jiabin    free(surroundFormatsEnabled);
18923994075a5b638ecffce5b8782521fce7631e7169jiabin    return jStatus;
18933994075a5b638ecffce5b8782521fce7631e7169jiabin}
18943994075a5b638ecffce5b8782521fce7631e7169jiabin
18953994075a5b638ecffce5b8782521fce7631e7169jiabinstatic jint
18963994075a5b638ecffce5b8782521fce7631e7169jiabinandroid_media_AudioSystem_setSurroundFormatEnabled(JNIEnv *env, jobject thiz,
18973994075a5b638ecffce5b8782521fce7631e7169jiabin                                                   jint audioFormat, jboolean enabled)
18983994075a5b638ecffce5b8782521fce7631e7169jiabin{
18993994075a5b638ecffce5b8782521fce7631e7169jiabin    status_t status = AudioSystem::setSurroundFormatEnabled(audioFormatToNative(audioFormat),
19003994075a5b638ecffce5b8782521fce7631e7169jiabin                                                            (bool)enabled);
19013994075a5b638ecffce5b8782521fce7631e7169jiabin    if (status != NO_ERROR) {
19023994075a5b638ecffce5b8782521fce7631e7169jiabin        ALOGE_IF(status != NO_ERROR, "AudioSystem::setSurroundFormatEnabled error %d", status);
19033994075a5b638ecffce5b8782521fce7631e7169jiabin    }
19043994075a5b638ecffce5b8782521fce7631e7169jiabin    return (jint)nativeToJavaStatus(status);
19053994075a5b638ecffce5b8782521fce7631e7169jiabin}
19063994075a5b638ecffce5b8782521fce7631e7169jiabin
19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
190976f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethods[] = {
1910a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {"setParameters",        "(Ljava/lang/String;)I", (void *)android_media_AudioSystem_setParameters},
1911a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {"getParameters",        "(Ljava/lang/String;)Ljava/lang/String;", (void *)android_media_AudioSystem_getParameters},
19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"muteMicrophone",      "(Z)I",     (void *)android_media_AudioSystem_muteMicrophone},
19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {"isMicrophoneMuted",   "()Z",      (void *)android_media_AudioSystem_isMicrophoneMuted},
1914d677054ca63f55abaa1c478ea3c50f6be665a979Jean-Michel Trivi    {"isStreamActive",      "(II)Z",    (void *)android_media_AudioSystem_isStreamActive},
1915679d5046f245ea8b39f9b5596195f3468808dd54Jean-Michel Trivi    {"isStreamActiveRemotely","(II)Z",  (void *)android_media_AudioSystem_isStreamActiveRemotely},
1916d677054ca63f55abaa1c478ea3c50f6be665a979Jean-Michel Trivi    {"isSourceActive",      "(I)Z",     (void *)android_media_AudioSystem_isSourceActive},
19178a21f5dd79e93aa4e4b08ab4f33b9255d7c06961Jean-Michel Trivi    {"newAudioSessionId",   "()I",      (void *)android_media_AudioSystem_newAudioSessionId},
1918292a6a4e9934a94eea97b018befde3baed895f7dJean-Michel Trivi    {"newAudioPlayerId",    "()I",      (void *)android_media_AudioSystem_newAudioPlayerId},
191910804eb2818ab59b763a37b4f6151693c2ebba7bPaul McLean    {"setDeviceConnectionState", "(IILjava/lang/String;Ljava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
1920a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {"getDeviceConnectionState", "(ILjava/lang/String;)I",  (void *)android_media_AudioSystem_getDeviceConnectionState},
192144a4ef0aa93ebb2912f36d65af42ffbb1bcdbc0fPavlin Radoslavov    {"handleDeviceConfigChange", "(ILjava/lang/String;Ljava/lang/String;)I", (void *)android_media_AudioSystem_handleDeviceConfigChange},
1922a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {"setPhoneState",       "(I)I",     (void *)android_media_AudioSystem_setPhoneState},
1923a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {"setForceUse",         "(II)I",    (void *)android_media_AudioSystem_setForceUse},
1924a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {"getForceUse",         "(I)I",     (void *)android_media_AudioSystem_getForceUse},
1925a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {"initStreamVolume",    "(III)I",   (void *)android_media_AudioSystem_initStreamVolume},
19269bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent    {"setStreamVolumeIndex","(III)I",   (void *)android_media_AudioSystem_setStreamVolumeIndex},
19279bc8358ddaa01c3490f9709991989633a6a3dd42Eric Laurent    {"getStreamVolumeIndex","(II)I",    (void *)android_media_AudioSystem_getStreamVolumeIndex},
1928cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    {"setMasterVolume",     "(F)I",     (void *)android_media_AudioSystem_setMasterVolume},
1929cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    {"getMasterVolume",     "()F",      (void *)android_media_AudioSystem_getMasterVolume},
1930cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    {"setMasterMute",       "(Z)I",     (void *)android_media_AudioSystem_setMasterMute},
1931cbdb49dc5e1b993a0bc5c68dbfb9486bfa0cd762Mike Lockwood    {"getMasterMute",       "()Z",      (void *)android_media_AudioSystem_getMasterMute},
1932f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung    {"setMasterMono",       "(Z)I",     (void *)android_media_AudioSystem_setMasterMono},
1933f04b84d4c66ea377ec6fe2b36f3a0994f3e94ebaAndy Hung    {"getMasterMono",       "()Z",      (void *)android_media_AudioSystem_getMasterMono},
19348b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    {"getDevicesForStream", "(I)I",     (void *)android_media_AudioSystem_getDevicesForStream},
1935c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten    {"getPrimaryOutputSamplingRate", "()I", (void *)android_media_AudioSystem_getPrimaryOutputSamplingRate},
1936c6c4365ddb0213c548b055f257dc8077389224fbGlenn Kasten    {"getPrimaryOutputFrameCount",   "()I", (void *)android_media_AudioSystem_getPrimaryOutputFrameCount},
193761dcdf3764b614c6f01e77cb4342d192e3101f8aOliver Woodman    {"getOutputLatency",    "(I)I",     (void *)android_media_AudioSystem_getOutputLatency},
19387958358ddb34cebe4fdf99fef8d613c0c74ff17aAndy Hung    {"setLowRamDevice",     "(ZJ)I",    (void *)android_media_AudioSystem_setLowRamDevice},
1939dfb881f96af7898151940a4bbc52e45e6043d38bEric Laurent    {"checkAudioFlinger",    "()I",     (void *)android_media_AudioSystem_checkAudioFlinger},
1940b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    {"listAudioPorts",      "(Ljava/util/ArrayList;[I)I",
1941b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                (void *)android_media_AudioSystem_listAudioPorts},
1942b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    {"createAudioPatch",    "([Landroid/media/AudioPatch;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)I",
1943b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                            (void *)android_media_AudioSystem_createAudioPatch},
1944b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    {"releaseAudioPatch",   "(Landroid/media/AudioPatch;)I",
1945b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                            (void *)android_media_AudioSystem_releaseAudioPatch},
1946b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent    {"listAudioPatches",    "(Ljava/util/ArrayList;[I)I",
1947b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                (void *)android_media_AudioSystem_listAudioPatches},
19483a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent    {"setAudioPortConfig",   "(Landroid/media/AudioPortConfig;)I",
19493a24199a0fe9479802ff6096d82cb3745efa1f1fEric Laurent                                            (void *)android_media_AudioSystem_setAudioPortConfig},
1950b634e1b6d6bda56128c354b1803b04b537e3799dEric Laurent    {"getAudioHwSyncForSession", "(I)I",
1951b634e1b6d6bda56128c354b1803b04b537e3799dEric Laurent                                    (void *)android_media_AudioSystem_getAudioHwSyncForSession},
19527f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent    {"registerPolicyMixes",    "(Ljava/util/ArrayList;Z)I",
19537f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                            (void *)android_media_AudioSystem_registerPolicyMixes},
19545a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    {"native_register_dynamic_policy_callback", "()V",
19555a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi                                    (void *)android_media_AudioSystem_registerDynPolicyCallback},
1956d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    {"native_register_recording_callback", "()V",
1957d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi                                    (void *)android_media_AudioSystem_registerRecordingCallback},
19580867bed9ddb3bea3d7c252791f8b62ae21ad3de5Eric Laurent    {"systemReady", "()I", (void *)android_media_AudioSystem_systemReady},
1959eab40d14a88574e4041504a68012c95a4a8f03c9Eric Laurent    {"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB},
1960980d38ff7743c3f15a9674844d1f9e855b547650Jean-Michel Trivi    {"native_is_offload_supported", "(IIII)Z", (void *)android_media_AudioSystem_isOffloadSupported},
1961c0f494403873435d463c4817066f9c68d57310a7jiabin    {"getMicrophones", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioSystem_getMicrophones},
19623994075a5b638ecffce5b8782521fce7631e7169jiabin    {"getSurroundFormats", "(Ljava/util/Map;Z)I", (void *)android_media_AudioSystem_getSurroundFormats},
19633994075a5b638ecffce5b8782521fce7631e7169jiabin    {"setSurroundFormatEnabled", "(IZ)I", (void *)android_media_AudioSystem_setSurroundFormatEnabled},
19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1966b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
196776f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gEventHandlerMethods[] = {
1968700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    {"native_setup",
1969700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        "(Ljava/lang/Object;)V",
1970700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        (void *)android_media_AudioSystem_eventHandlerSetup},
1971700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent    {"native_finalize",
1972700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        "()V",
1973700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent        (void *)android_media_AudioSystem_eventHandlerFinalize},
1974700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent};
1975700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_media_AudioSystem(JNIEnv *env)
19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1978ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
1979ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
1980ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
1981093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gArrayListMethods.toArray = GetMethodIDOrDie(env, arrayListClass, "toArray", "()[Ljava/lang/Object;");
1982ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe
19833994075a5b638ecffce5b8782521fce7631e7169jiabin    jclass booleanClass = FindClassOrDie(env, "java/lang/Boolean");
19843994075a5b638ecffce5b8782521fce7631e7169jiabin    gBooleanClass = MakeGlobalRefOrDie(env, booleanClass);
19853994075a5b638ecffce5b8782521fce7631e7169jiabin    gBooleanCstor = GetMethodIDOrDie(env, booleanClass, "<init>", "(Z)V");
19863994075a5b638ecffce5b8782521fce7631e7169jiabin
19873994075a5b638ecffce5b8782521fce7631e7169jiabin    jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
19883994075a5b638ecffce5b8782521fce7631e7169jiabin    gIntegerClass = MakeGlobalRefOrDie(env, integerClass);
19893994075a5b638ecffce5b8782521fce7631e7169jiabin    gIntegerCstor = GetMethodIDOrDie(env, integerClass, "<init>", "(I)V");
19903994075a5b638ecffce5b8782521fce7631e7169jiabin
19913994075a5b638ecffce5b8782521fce7631e7169jiabin    jclass mapClass = FindClassOrDie(env, "java/util/Map");
19923994075a5b638ecffce5b8782521fce7631e7169jiabin    gMapClass = MakeGlobalRefOrDie(env, mapClass);
19933994075a5b638ecffce5b8782521fce7631e7169jiabin    gMapPut = GetMethodIDOrDie(env, mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
19943994075a5b638ecffce5b8782521fce7631e7169jiabin
1995ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass audioHandleClass = FindClassOrDie(env, "android/media/AudioHandle");
1996ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioHandleClass = MakeGlobalRefOrDie(env, audioHandleClass);
1997ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioHandleCstor = GetMethodIDOrDie(env, audioHandleClass, "<init>", "(I)V");
1998ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioHandleFields.mId = GetFieldIDOrDie(env, audioHandleClass, "mId", "I");
1999ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe
2000ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass audioPortClass = FindClassOrDie(env, "android/media/AudioPort");
2001ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortClass = MakeGlobalRefOrDie(env, audioPortClass);
2002ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortCstor = GetMethodIDOrDie(env, audioPortClass, "<init>",
2003f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean            "(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V");
2004ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortFields.mHandle = GetFieldIDOrDie(env, audioPortClass, "mHandle",
2005b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                               "Landroid/media/AudioHandle;");
2006ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortFields.mRole = GetFieldIDOrDie(env, audioPortClass, "mRole", "I");
2007ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortFields.mGains = GetFieldIDOrDie(env, audioPortClass, "mGains",
2008b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                              "[Landroid/media/AudioGain;");
2009ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortFields.mActiveConfig = GetFieldIDOrDie(env, audioPortClass, "mActiveConfig",
2010ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe                                                     "Landroid/media/AudioPortConfig;");
2011ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe
2012ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass audioPortConfigClass = FindClassOrDie(env, "android/media/AudioPortConfig");
2013ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortConfigClass = MakeGlobalRefOrDie(env, audioPortConfigClass);
2014ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortConfigCstor = GetMethodIDOrDie(env, audioPortConfigClass, "<init>",
2015ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe            "(Landroid/media/AudioPort;IIILandroid/media/AudioGainConfig;)V");
2016ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortConfigFields.mPort = GetFieldIDOrDie(env, audioPortConfigClass, "mPort",
2017b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                   "Landroid/media/AudioPort;");
2018ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortConfigFields.mSamplingRate = GetFieldIDOrDie(env, audioPortConfigClass,
2019b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                           "mSamplingRate", "I");
2020ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortConfigFields.mChannelMask = GetFieldIDOrDie(env, audioPortConfigClass,
2021b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                          "mChannelMask", "I");
2022ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortConfigFields.mFormat = GetFieldIDOrDie(env, audioPortConfigClass, "mFormat", "I");
2023ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortConfigFields.mGain = GetFieldIDOrDie(env, audioPortConfigClass, "mGain",
2024b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                   "Landroid/media/AudioGainConfig;");
2025ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPortConfigFields.mConfigMask = GetFieldIDOrDie(env, audioPortConfigClass, "mConfigMask",
2026ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe                                                         "I");
2027ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe
2028ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass audioDevicePortConfigClass = FindClassOrDie(env, "android/media/AudioDevicePortConfig");
2029ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioDevicePortConfigClass = MakeGlobalRefOrDie(env, audioDevicePortConfigClass);
2030ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioDevicePortConfigCstor = GetMethodIDOrDie(env, audioDevicePortConfigClass, "<init>",
2031ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe            "(Landroid/media/AudioDevicePort;IIILandroid/media/AudioGainConfig;)V");
2032ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe
2033ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass audioMixPortConfigClass = FindClassOrDie(env, "android/media/AudioMixPortConfig");
2034ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioMixPortConfigClass = MakeGlobalRefOrDie(env, audioMixPortConfigClass);
2035ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioMixPortConfigCstor = GetMethodIDOrDie(env, audioMixPortConfigClass, "<init>",
2036ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe            "(Landroid/media/AudioMixPort;IIILandroid/media/AudioGainConfig;)V");
2037ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe
2038ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass audioDevicePortClass = FindClassOrDie(env, "android/media/AudioDevicePort");
2039ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioDevicePortClass = MakeGlobalRefOrDie(env, audioDevicePortClass);
2040ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioDevicePortCstor = GetMethodIDOrDie(env, audioDevicePortClass, "<init>",
2041f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean            "(Landroid/media/AudioHandle;Ljava/lang/String;[I[I[I[I[Landroid/media/AudioGain;ILjava/lang/String;)V");
2042ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe
2043ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass audioMixPortClass = FindClassOrDie(env, "android/media/AudioMixPort");
2044ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioMixPortClass = MakeGlobalRefOrDie(env, audioMixPortClass);
2045ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioMixPortCstor = GetMethodIDOrDie(env, audioMixPortClass, "<init>",
2046f29e5f34b39a5688925ca4654be0eab11277b1ccPaul McLean            "(Landroid/media/AudioHandle;IILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V");
2047ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe
2048ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass audioGainClass = FindClassOrDie(env, "android/media/AudioGain");
2049ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioGainClass = MakeGlobalRefOrDie(env, audioGainClass);
2050ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioGainCstor = GetMethodIDOrDie(env, audioGainClass, "<init>", "(IIIIIIIII)V");
2051ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe
2052ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass audioGainConfigClass = FindClassOrDie(env, "android/media/AudioGainConfig");
2053ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioGainConfigClass = MakeGlobalRefOrDie(env, audioGainConfigClass);
2054ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioGainConfigCstor = GetMethodIDOrDie(env, audioGainConfigClass, "<init>",
2055b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                             "(ILandroid/media/AudioGain;II[II)V");
2056ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioGainConfigFields.mIndex = GetFieldIDOrDie(env, gAudioGainConfigClass, "mIndex", "I");
2057ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioGainConfigFields.mMode = GetFieldIDOrDie(env, audioGainConfigClass, "mMode", "I");
2058ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioGainConfigFields.mChannelMask = GetFieldIDOrDie(env, audioGainConfigClass, "mChannelMask",
2059b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                          "I");
2060ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioGainConfigFields.mValues = GetFieldIDOrDie(env, audioGainConfigClass, "mValues", "[I");
2061ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioGainConfigFields.mRampDurationMs = GetFieldIDOrDie(env, audioGainConfigClass,
2062b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                             "mRampDurationMs", "I");
2063b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
2064ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass audioPatchClass = FindClassOrDie(env, "android/media/AudioPatch");
2065ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPatchClass = MakeGlobalRefOrDie(env, audioPatchClass);
2066ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPatchCstor = GetMethodIDOrDie(env, audioPatchClass, "<init>",
2067b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent"(Landroid/media/AudioHandle;[Landroid/media/AudioPortConfig;[Landroid/media/AudioPortConfig;)V");
2068ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gAudioPatchFields.mHandle = GetFieldIDOrDie(env, audioPatchClass, "mHandle",
2069b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent                                                "Landroid/media/AudioHandle;");
2070b69681c894c663e84f2826d9b0c832ceb9b45047Eric Laurent
2071ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass eventHandlerClass = FindClassOrDie(env, kEventHandlerClassPathName);
20722615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    gAudioPortEventHandlerMethods.postEventFromNative = GetStaticMethodIDOrDie(
20732615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent                                                    env, eventHandlerClass, "postEventFromNative",
20742615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent                                                    "(Ljava/lang/Object;IIILjava/lang/Object;)V");
20752615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent    gEventHandlerFields.mJniCallback = GetFieldIDOrDie(env,
20762615afb1b0f597f38a07832b33df9bd888a0dce1Eric Laurent                                                    eventHandlerClass, "mJniCallback", "J");
2077700e73471d85348b52ecf213c36bb24b93997ec7Eric Laurent
2078d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    gAudioPolicyEventHandlerMethods.postDynPolicyEventFromNative =
20795a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi            GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
20805a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi                    "dynamicPolicyCallbackFromNative", "(ILjava/lang/String;I)V");
2081d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi    gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative =
2082d3c71f075b139024e2bea39bbd75e3b976bfb7cbJean-Michel Trivi            GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
208366ffacf42a7dde6fac867605aaa47d555b960ee4Jean-Michel Trivi                    "recordingCallbackFromNative", "(IIII[I)V");
20845a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi
2085093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix");
2086093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass);
2087093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioMixFields.mRule = GetFieldIDOrDie(env, audioMixClass, "mRule",
20887f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                                "Landroid/media/audiopolicy/AudioMixingRule;");
2089093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioMixFields.mFormat = GetFieldIDOrDie(env, audioMixClass, "mFormat",
20907f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                                "Landroid/media/AudioFormat;");
2091093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioMixFields.mRouteFlags = GetFieldIDOrDie(env, audioMixClass, "mRouteFlags", "I");
20924ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi    gAudioMixFields.mDeviceType = GetFieldIDOrDie(env, audioMixClass, "mDeviceSystemType", "I");
20934ad39885f2e6e79ae1faaa41ae240eeffcefd368Jean-Michel Trivi    gAudioMixFields.mDeviceAddress = GetFieldIDOrDie(env, audioMixClass, "mDeviceAddress",
20947f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                                      "Ljava/lang/String;");
2095093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioMixFields.mMixType = GetFieldIDOrDie(env, audioMixClass, "mMixType", "I");
20965a56109d1f5c00404c8f0e4281b9ac1392d72886Jean-Michel Trivi    gAudioMixFields.mCallbackFlags = GetFieldIDOrDie(env, audioMixClass, "mCallbackFlags", "I");
20977f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
2098093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    jclass audioFormatClass = FindClassOrDie(env, "android/media/AudioFormat");
2099093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioFormatClass = MakeGlobalRefOrDie(env, audioFormatClass);
2100093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioFormatFields.mEncoding = GetFieldIDOrDie(env, audioFormatClass, "mEncoding", "I");
2101093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioFormatFields.mSampleRate = GetFieldIDOrDie(env, audioFormatClass, "mSampleRate", "I");
2102093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioFormatFields.mChannelMask = GetFieldIDOrDie(env, audioFormatClass, "mChannelMask", "I");
21037f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
2104093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    jclass audioMixingRuleClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule");
2105093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioMixingRuleClass = MakeGlobalRefOrDie(env, audioMixingRuleClass);
2106093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioMixingRuleFields.mCriteria = GetFieldIDOrDie(env, audioMixingRuleClass, "mCriteria",
21077f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                                       "Ljava/util/ArrayList;");
21087f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
2109ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi    jclass audioMixMatchCriterionClass =
2110ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi                FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion");
2111ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi    gAudioMixMatchCriterionClass = MakeGlobalRefOrDie(env,audioMixMatchCriterionClass);
2112ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi    gAudioMixMatchCriterionFields.mAttr = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mAttr",
21137f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                                       "Landroid/media/AudioAttributes;");
2114ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi    gAudioMixMatchCriterionFields.mIntProp = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mIntProp",
2115ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi                                                       "I");
2116ba6b4b400d850ba18fcb9d5bf9789d490f390accJean-Michel Trivi    gAudioMixMatchCriterionFields.mRule = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mRule",
21177f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent                                                       "I");
21187f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
2119093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    jclass audioAttributesClass = FindClassOrDie(env, "android/media/AudioAttributes");
2120093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioAttributesClass = MakeGlobalRefOrDie(env, audioAttributesClass);
2121093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioAttributesFields.mUsage = GetFieldIDOrDie(env, audioAttributesClass, "mUsage", "I");
2122093789755e5549bd8676d268a6f69b1d6db5026bEric Laurent    gAudioAttributesFields.mSource = GetFieldIDOrDie(env, audioAttributesClass, "mSource", "I");
21237f5eb9fe3c10d8d83ff0e2b0fc60a05c2e6d5b02Eric Laurent
21249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);
212518db49a46259020387c40fff36d92edc1087a366Glenn Kasten
2126ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
2127ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    return RegisterMethodsOrDie(env, kEventHandlerClassPathName, gEventHandlerMethods,
2128ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe                                NELEM(gEventHandlerMethods));
21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2130