blob: 630ce6221eaf34b8c1eae49142cc1bd02a7bdacd [file] [log] [blame]
Kiran Kelagerid81255d2013-12-09 17:12:30 -08001/*
2 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * * Neither the name of The Linux Foundation nor
12 * the names of its contributors may be used to endorse or promote
13 * products derived from this software without specific prior written
14 * permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#define LOG_TAG "wipower"
30
31#include "jni.h"
32#include "JNIHelp.h"
33#include "android_runtime/AndroidRuntime.h"
34#include "utils/Log.h"
35#include "utils/misc.h"
36#include <cutils/properties.h>
37#include <fcntl.h>
38#include <sys/ioctl.h>
39#include "android_hardware_wipower.h"
40#include "com_android_bluetooth.h"
41
42#define CHECK_CALLBACK_ENV \
43 if (!checkCallbackThread()) { \
44 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
45 return; \
46 }
47
48#define ALOGV ALOGE
49
50namespace android {
51
52static jmethodID method_wipowerstateChangeCallback;
53static jmethodID method_wipowerAlertNotify;
54static jmethodID method_wipowerDataNotify;
Kiran Kelageri72ddbae2014-01-23 18:35:20 -080055static jmethodID method_wipowerPowerNotify;
Kiran Kelagerid81255d2013-12-09 17:12:30 -080056
57static const wipower_interface_t *sWipowerInterface = NULL;
58static jobject sCallbacksObj;
59static JNIEnv *sCallbackEnv = NULL;
60
61static bool checkCallbackThread() {
62 sCallbackEnv = getCallbackEnv();
63
64 JNIEnv* env = AndroidRuntime::getJNIEnv();
65 if (sCallbackEnv != env || sCallbackEnv == NULL) {
66 ALOGE("Callback env check fail: env: %p, callback: %p", env, sCallbackEnv);
67 return false;
68 }
69 return true;
70}
71
72
73static void wipower_state_changed_cb(wipower_state_t state) {
74 ALOGV("%s: State is: %d", __FUNCTION__, state);
75 CHECK_CALLBACK_ENV
76 sCallbackEnv->CallVoidMethod(sCallbacksObj, method_wipowerstateChangeCallback, (jint) state);
77}
78
79static void wipower_alerts_cb(unsigned char alert_data) {
80 ALOGV("%s: alert_data is: %d", __FUNCTION__, alert_data);
81 CHECK_CALLBACK_ENV
82 sCallbackEnv->CallVoidMethod(sCallbacksObj, method_wipowerAlertNotify, (jint) alert_data);
83}
84
85static void wipower_data_cb(wipower_dyn_data_t *alert_data) {
Kiran Kelageri72ddbae2014-01-23 18:35:20 -080086 ALOGV("%s: wp data is: %x", __FUNCTION__, (unsigned int)alert_data);
Kiran Kelagerid81255d2013-12-09 17:12:30 -080087 jbyteArray wp_data = NULL;
88
89 CHECK_CALLBACK_ENV
Kiran Kelageri72ddbae2014-01-23 18:35:20 -080090 wp_data = sCallbackEnv->NewByteArray(sizeof(wipower_dyn_data_t));
Kiran Kelagerid81255d2013-12-09 17:12:30 -080091 if (wp_data == NULL) {
92 ALOGV("%s: alloc failure", __FUNCTION__);
93 return;
94 }
95
96 sCallbackEnv->SetByteArrayRegion(wp_data, 0, sizeof(wipower_dyn_data_t),
97 (jbyte*)alert_data);
98
Kiran Kelageri72ddbae2014-01-23 18:35:20 -080099
Kiran Kelagerid81255d2013-12-09 17:12:30 -0800100 ALOGV("set value to byte array");
101
102 sCallbackEnv->CallVoidMethod(sCallbacksObj, method_wipowerDataNotify, wp_data);
103
Kiran Kelageri72ddbae2014-01-23 18:35:20 -0800104 sCallbackEnv->DeleteLocalRef(wp_data);
105}
106
107static void wipower_power_cb(unsigned char alert_data) {
108 ALOGV("%s: alert_data is: %d", __FUNCTION__, alert_data);
109 CHECK_CALLBACK_ENV
110 sCallbackEnv->CallVoidMethod(sCallbacksObj, method_wipowerPowerNotify, (jint) alert_data);
Kiran Kelagerid81255d2013-12-09 17:12:30 -0800111}
112
113wipower_callbacks_t sWipowerCallbacks = {
114 sizeof(sWipowerCallbacks),
115 wipower_state_changed_cb,
116 wipower_alerts_cb,
Kiran Kelageri72ddbae2014-01-23 18:35:20 -0800117 wipower_data_cb,
118 wipower_power_cb
Kiran Kelagerid81255d2013-12-09 17:12:30 -0800119};
120
121
122static void android_wipower_wipowerJNI_classInitNative(JNIEnv* env, jclass clazz) {
123
124 ALOGV("%s:",__FUNCTION__);
125 method_wipowerstateChangeCallback = env->GetMethodID(clazz, "stateChangeCallback", "(I)V");
126
127 method_wipowerAlertNotify = env->GetMethodID(clazz, "wipowerAlertNotify", "(I)V");
128
129 method_wipowerDataNotify = env->GetMethodID(clazz, "wipowerDataNotify",
130 "([B)V");
Kiran Kelageri72ddbae2014-01-23 18:35:20 -0800131
132 method_wipowerPowerNotify = env->GetMethodID(clazz, "wipowerPowerNotify",
133 "(B)V");
Kiran Kelagerid81255d2013-12-09 17:12:30 -0800134}
135
136static void android_wipower_wipowerJNI_initNative (JNIEnv* env, jobject obj) {
137 ALOGE("%s:",__FUNCTION__);
138
139 const bt_interface_t* btInf;
140
141 if ( (btInf = getBluetoothInterface()) == NULL) {
142 ALOGE("Bluetooth module is not loaded");
143 return;
144 }
145
146 //Get WiPower Interface
147 sWipowerInterface = (const wipower_interface_t*)btInf->get_profile_interface(WIPOWER_PROFILE_ID);
148
Kiran Kelageri72ddbae2014-01-23 18:35:20 -0800149 ALOGE("%s: Get wipower interface: %x",__FUNCTION__, (unsigned int)sWipowerInterface);
150 //Initialize wipower interface
151 int ret = sWipowerInterface->init(&sWipowerCallbacks);
152
153 if (ret != 0)
154 ALOGE("wipower init failed");
Kiran Kelagerid81255d2013-12-09 17:12:30 -0800155
156 sCallbacksObj = env->NewGlobalRef(obj);
157}
158
159/* native interface */
160static jint android_wipower_wipowerJNI_enableNative
161 (JNIEnv* env, jobject thiz, jboolean enable)
162{
163
164 ALOGD("%s->", __func__);
165
166 if (sWipowerInterface == NULL) {
167 ALOGE("No Interface initialized");
168 return JNI_FALSE;
169 }
170
Kiran Kelageri72ddbae2014-01-23 18:35:20 -0800171 int ret = sWipowerInterface->enable(enable);
Kiran Kelagerid81255d2013-12-09 17:12:30 -0800172
173 if (ret != 0) {
174 ALOGE("wipower enable failed");
175 return JNI_FALSE;
176 } else {
177 ALOGE("wipower enabled successfully");
178 }
179 return 0;
180}
181
182/* native interface */
183static jint android_wipower_wipowerJNI_setCurrentLimitNative
184 (JNIEnv* env, jobject thiz, jbyte value)
185{
186 ALOGD("%s->", __func__);
187
188 if (sWipowerInterface == NULL) {
189 ALOGE("No Interface initialized");
190 return JNI_FALSE;
191 }
192
193 int ret = sWipowerInterface->set_current_limit(value);
194
195 if (ret != 0) {
196 ALOGE("wipower set current limit failed");
197 return JNI_FALSE;
198 } else {
199 ALOGD("%s:success", __func__);
200 }
201
202 return 0;
203}
204
205/* native interface */
206static jbyte android_wipower_wipowerJNI_getCurrentLimitNative
207 (JNIEnv* env, jobject thiz)
208{
209 ALOGD("%s->", __func__);
210
211 if (sWipowerInterface == NULL) {
212 ALOGE("No Interface initialized");
213 return JNI_FALSE;
214 }
215
216 unsigned char val = sWipowerInterface->get_current_limit();
217
218 ALOGE("%s: %d", __func__, val);
219
220 return val;
221}
222
223/* native interface */
224static jint android_wipower_wipowerJNI_getStateNative
225 (JNIEnv* env, jobject thiz)
226{
227 ALOGD("%s->", __func__);
228
229 if (sWipowerInterface == NULL) {
230 ALOGE("No Interface initialized");
231 return JNI_FALSE;
232 }
233
234 int val = sWipowerInterface->get_state();
235
236 ALOGE("%s: %d", __func__, val);
237
238 return val;
239}
240
241/* native interface */
242static jint android_wipower_wipowerJNI_enableAlertNative
243 (JNIEnv* env, jobject thiz, jboolean enable)
244{
245 ALOGD("%s->", __func__);
246
247 if (sWipowerInterface == NULL) {
248 ALOGE("No Interface initialized");
249 return JNI_FALSE;
250 }
251
252 int ret = sWipowerInterface->enable_alerts(enable);
253
254 if (ret != 0) {
255 ALOGE("%s: Failure", __func__);
256 return JNI_FALSE;
257 } else {
258 ALOGE("%s: Success", __func__);
259 }
260 return 0;
261}
262
263/* native interface */
264static jint android_wipower_wipowerJNI_enableDataNative
265 (JNIEnv* env, jobject thiz, jboolean enable)
266{
267
268 ALOGD("%s->", __func__);
269
270 if (sWipowerInterface == NULL) {
271 ALOGE("No Interface initialized");
272 return JNI_FALSE;
273 }
274
275 int ret = sWipowerInterface->enable_data_notify(enable);
276
277 if (ret != 0) {
278 ALOGE("%s: Failure", __func__);
279 return JNI_FALSE;
280 } else {
281 ALOGE("%s: Success", __func__);
282 }
283
284 return 0;
285}
286
287/*
288 * JNI registration.
289 */
290static JNINativeMethod gMethods[] = {
291 /* name, signature, funcPtr */
292 { "classInitNative", "()V",
293 (void*)android_wipower_wipowerJNI_classInitNative},
294
295 { "initNative", "()V",
296 (void*)android_wipower_wipowerJNI_initNative},
297
298 { "enableNative", "(Z)I",
299 (void*)android_wipower_wipowerJNI_enableNative},
300
301 { "setCurrentLimitNative", "(B)I",
302 (void*)android_wipower_wipowerJNI_setCurrentLimitNative},
303
304 { "getCurrentLimitNative", "()B",
305 (void*)android_wipower_wipowerJNI_getCurrentLimitNative},
306
307 { "getStateNative", "()I",
308 (void*)android_wipower_wipowerJNI_getStateNative},
309
310 { "enableAlertNative", "(Z)I",
311 (void*)android_wipower_wipowerJNI_enableAlertNative},
312
313 { "enableDataNative", "(Z)I",
314 (void*)android_wipower_wipowerJNI_enableDataNative},
315
316};
317int register_android_hardware_wipower(JNIEnv* env)
318{
319
320 ALOGE("%s: >\n", __func__);
321 return jniRegisterNativeMethods(env, "com/android/bluetooth/wipower/WipowerService", gMethods, NELEM(gMethods));
322}
323}