1a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/* 2a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Copyright 2014, The Android Open Source Project 3a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * 4a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Licensed under the Apache License, Version 2.0 (the "License"); 5a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * you may not use this file except in compliance with the License. 6a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * You may obtain a copy of the License at 7a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * 8a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * http://www.apache.org/licenses/LICENSE-2.0 9a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * 10a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Unless required by applicable law or agreed to in writing, software 11a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * distributed under the License is distributed on an "AS IS" BASIS, 12a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * See the License for the specific language governing permissions and 14a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * limitations under the License. 15a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 16a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 17a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa#define LOG_TAG "ActivityRecognitionHardware" 18a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 19a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa#include <jni.h> 20a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa#include <JNIHelp.h> 21a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 22a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa#include <android_runtime/AndroidRuntime.h> 23a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa#include <android_runtime/Log.h> 24a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 25a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa#include "activity_recognition.h" 26a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 27a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 28a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa// keep base connection data from the HAL 29a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic activity_recognition_module_t* sModule = NULL; 30a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic activity_recognition_device_t* sDevice = NULL; 31a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 32a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic jobject sCallbacksObject = NULL; 33a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic jmethodID sOnActivityChanged = NULL; 34a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 35a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 36a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic void check_and_clear_exceptions(JNIEnv* env, const char* method_name) { 37a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (!env->ExceptionCheck()) { 38a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 39a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 40a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 41a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("An exception was thrown by '%s'.", method_name); 42a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa LOGE_EX(env); 43a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->ExceptionClear(); 44a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 45a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 46a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic jint attach_thread(JNIEnv** env) { 47a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa JavaVM* java_vm = android::AndroidRuntime::getJavaVM(); 48a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa assert(java_vm != NULL); 49a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 50a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa JavaVMAttachArgs args = { 51a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa JNI_VERSION_1_6, 52a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa "ActivityRecognition HAL callback.", 53a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa NULL /* group */ 54a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa }; 55a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 56a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jint result = java_vm->AttachCurrentThread(env, &args); 57a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (result != JNI_OK) { 58a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Attach to callback thread failed: %d", result); 59a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 60a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 61a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return result; 62a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 63a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 64a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic jint detach_thread() { 65a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa JavaVM* java_vm = android::AndroidRuntime::getJavaVM(); 66a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa assert(java_vm != NULL); 67a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 68a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jint result = java_vm->DetachCurrentThread(); 69a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (result != JNI_OK) { 70a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Detach of callback thread failed: %d", result); 71a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 72a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 73a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return result; 74a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 75a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 76a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 77a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 78a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Handle activity recognition events from HAL. 79a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 80a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic void activity_callback( 81a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa const activity_recognition_callback_procs_t* procs, 82a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa const activity_event_t* events, 83a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int count) { 84a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sOnActivityChanged == NULL) { 85a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Dropping activity_callback because onActivityChanged handler is null."); 86a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 87a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 88a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 89a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (events == NULL || count <= 0) { 90a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Invalid activity_callback. Count: %d, Events: %p", count, events); 91a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 92a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 93a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 94a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa JNIEnv* env = NULL; 95a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int result = attach_thread(&env); 96a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (result != JNI_OK) { 973b0224dc3c2e7ffb93dc56970395003d0e387545destradaa ALOGE("Unable to attach thread with JNI."); 98a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 99a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 100a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 101a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jclass event_class = 102a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->FindClass("android/hardware/location/ActivityRecognitionHardware$Event"); 103a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jmethodID event_ctor = env->GetMethodID(event_class, "<init>", "()V"); 104a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jfieldID activity_field = env->GetFieldID(event_class, "activity", "I"); 105a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jfieldID type_field = env->GetFieldID(event_class, "type", "I"); 106a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jfieldID timestamp_field = env->GetFieldID(event_class, "timestamp", "J"); 107a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 108a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jobjectArray events_array = env->NewObjectArray(count, event_class, NULL); 109a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa for (int i = 0; i < count; ++i) { 110a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa const activity_event_t* event = &events[i]; 111a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jobject event_object = env->NewObject(event_class, event_ctor); 112a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->SetIntField(event_object, activity_field, event->activity); 113a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->SetIntField(event_object, type_field, event->event_type); 114a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->SetLongField(event_object, timestamp_field, event->timestamp); 115a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->SetObjectArrayElement(events_array, i, event_object); 116a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->DeleteLocalRef(event_object); 117a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 118a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 119a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->CallVoidMethod(sCallbacksObject, sOnActivityChanged, events_array); 120a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa check_and_clear_exceptions(env, __FUNCTION__); 121a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 122a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa // TODO: ideally we'd let the HAL register the callback thread only once 123a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa detach_thread(); 124a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 125a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 1260f0b4919667f418b249c497f5ad3e83fdf4437e5Andreas Gampeactivity_recognition_callback_procs_t sCallbacks = { 127a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa activity_callback, 128a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa}; 129a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 130a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 131a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Initializes the ActivityRecognitionHardware class from the native side. 132a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 133a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic void class_init(JNIEnv* env, jclass clazz) { 134a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa // open the hardware module 135a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int error = hw_get_module( 136a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ACTIVITY_RECOGNITION_HARDWARE_MODULE_ID, 137a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa (const hw_module_t**) &sModule); 138a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (error != 0) { 139a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Error hw_get_module: %d", error); 140a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 141a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 142a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 143a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa error = activity_recognition_open(&sModule->common, &sDevice); 144a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (error != 0) { 145a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Error opening device: %d", error); 146a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 147a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 148a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 149a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa // get references to the Java provided methods 150a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sOnActivityChanged = env->GetMethodID( 151a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa clazz, 152a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa "onActivityChanged", 153a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa "([Landroid/hardware/location/ActivityRecognitionHardware$Event;)V"); 154a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sOnActivityChanged == NULL) { 155a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Error obtaining ActivityChanged callback."); 156a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 157a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 158a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 159a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa // register callbacks 160a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sDevice->register_activity_callback(sDevice, &sCallbacks); 161a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 162a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 163a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 164a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Initializes and connect the callbacks handlers in the HAL. 165a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 166a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic void initialize(JNIEnv* env, jobject obj) { 167a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sCallbacksObject == NULL) { 168a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sCallbacksObject = env->NewGlobalRef(obj); 169a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } else { 170a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGD("Callbacks Object was already initialized."); 171a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 172a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 173a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sDevice != NULL) { 174a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sDevice->register_activity_callback(sDevice, &sCallbacks); 175a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } else { 176a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGD("ActivityRecognition device not found during initialization."); 177a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 178a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 179a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 180a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 181a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * De-initializes the ActivityRecognitionHardware from the native side. 182a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 183a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic void release(JNIEnv* env, jobject obj) { 184a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sDevice == NULL) { 185a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 186a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 187a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 188a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int error = activity_recognition_close(sDevice); 189a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (error != 0) { 190a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Error closing device: %d", error); 191a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 192a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 193a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 194a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 195a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 196a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Returns true if ActivityRecognition HAL is supported, false otherwise. 197a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 198a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic jboolean is_supported(JNIEnv* env, jclass clazz) { 199a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sModule != NULL && sDevice != NULL ) { 200a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return JNI_TRUE; 201a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 202a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return JNI_FALSE; 203a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 204a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 205a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 206a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Gets an array representing the supported activities. 207a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 208a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic jobjectArray get_supported_activities(JNIEnv* env, jobject obj) { 209a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sModule == NULL) { 210a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return NULL; 211a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 212a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 213a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa char const* const* list = NULL; 214a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int list_size = sModule->get_supported_activities_list(sModule, &list); 215a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (list_size <= 0 || list == NULL) { 216a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return NULL; 217a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 218a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 2193b0224dc3c2e7ffb93dc56970395003d0e387545destradaa jclass string_class = env->FindClass("java/lang/String"); 220a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (string_class == NULL) { 221a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Unable to find String class for supported activities."); 222a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return NULL; 223a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 224a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 225a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jobjectArray string_array = env->NewObjectArray(list_size, string_class, NULL); 226a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (string_array == NULL) { 227a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Unable to create string array for supported activities."); 228a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return NULL; 229a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 230a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 231a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa for (int i = 0; i < list_size; ++i) { 232a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa const char* string_ptr = const_cast<const char*>(list[i]); 2333b0224dc3c2e7ffb93dc56970395003d0e387545destradaa jstring string = env->NewStringUTF(string_ptr); 234a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->SetObjectArrayElement(string_array, i, string); 235a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 236a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 237a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return string_array; 238a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 239a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 240a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 241a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Enables a given activity event to be actively monitored. 242a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 243a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic int enable_activity_event( 244a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa JNIEnv* env, 245a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jobject obj, 246a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jint activity_handle, 247a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jint event_type, 248a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jlong report_latency_ns) { 249a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return sDevice->enable_activity_event( 250a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sDevice, 251a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa (uint32_t) activity_handle, 252a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa (uint32_t) event_type, 253a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa report_latency_ns); 254a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 255a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 256a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 257a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Disables a given activity event from being actively monitored. 258a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 259a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic int disable_activity_event( 260a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa JNIEnv* env, 261a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jobject obj, 262a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jint activity_handle, 263a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jint event_type) { 264a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return sDevice->disable_activity_event( 265a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sDevice, 266a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa (uint32_t) activity_handle, 267a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa (uint32_t) event_type); 268a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 269a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 270a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 271a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Request flush for al batch buffers. 272a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 273a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic int flush(JNIEnv* env, jobject obj) { 274a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return sDevice->flush(sDevice); 275a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 276a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 277a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 27876f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod sMethods[] = { 279a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa // {"name", "signature", (void*) functionPointer }, 280a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeClassInit", "()V", (void*) class_init }, 281a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeInitialize", "()V", (void*) initialize }, 282a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeRelease", "()V", (void*) release }, 283a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeIsSupported", "()Z", (void*) is_supported }, 284a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeGetSupportedActivities", "()[Ljava/lang/String;", (void*) get_supported_activities }, 285a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeEnableActivityEvent", "(IIJ)I", (void*) enable_activity_event }, 286a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeDisableActivityEvent", "(II)I", (void*) disable_activity_event }, 287a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeFlush", "()I", (void*) flush }, 288a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa}; 289a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 290a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 291a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Registration method invoked in JNI load. 292a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 293a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaaint register_android_hardware_location_ActivityRecognitionHardware(JNIEnv* env) { 294a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return jniRegisterNativeMethods( 295a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env, 296a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa "android/hardware/location/ActivityRecognitionHardware", 297a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sMethods, 298a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa NELEM(sMethods)); 299a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 300