android_hardware_location_ActivityRecognitionHardware.cpp revision a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26
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) { 97a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 98a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 99a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 100a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jclass event_class = 101a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->FindClass("android/hardware/location/ActivityRecognitionHardware$Event"); 102a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jmethodID event_ctor = env->GetMethodID(event_class, "<init>", "()V"); 103a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jfieldID activity_field = env->GetFieldID(event_class, "activity", "I"); 104a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jfieldID type_field = env->GetFieldID(event_class, "type", "I"); 105a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jfieldID timestamp_field = env->GetFieldID(event_class, "timestamp", "J"); 106a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 107a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jobjectArray events_array = env->NewObjectArray(count, event_class, NULL); 108a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa for (int i = 0; i < count; ++i) { 109a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa const activity_event_t* event = &events[i]; 110a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jobject event_object = env->NewObject(event_class, event_ctor); 111a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->SetIntField(event_object, activity_field, event->activity); 112a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->SetIntField(event_object, type_field, event->event_type); 113a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->SetLongField(event_object, timestamp_field, event->timestamp); 114a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->SetObjectArrayElement(events_array, i, event_object); 115a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->DeleteLocalRef(event_object); 116a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 117a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 118a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->CallVoidMethod(sCallbacksObject, sOnActivityChanged, events_array); 119a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa check_and_clear_exceptions(env, __FUNCTION__); 120a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 121a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa // TODO: ideally we'd let the HAL register the callback thread only once 122a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa detach_thread(); 123a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 124a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 125a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaaactivity_recognition_callback_procs_t sCallbacks { 126a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa activity_callback, 127a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa}; 128a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 129a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 130a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Initializes the ActivityRecognitionHardware class from the native side. 131a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 132a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic void class_init(JNIEnv* env, jclass clazz) { 133a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa // open the hardware module 134a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int error = hw_get_module( 135a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ACTIVITY_RECOGNITION_HARDWARE_MODULE_ID, 136a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa (const hw_module_t**) &sModule); 137a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (error != 0) { 138a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Error hw_get_module: %d", error); 139a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 140a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 141a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 142a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa error = activity_recognition_open(&sModule->common, &sDevice); 143a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (error != 0) { 144a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Error opening device: %d", error); 145a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 146a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 147a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 148a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa // get references to the Java provided methods 149a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sOnActivityChanged = env->GetMethodID( 150a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa clazz, 151a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa "onActivityChanged", 152a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa "([Landroid/hardware/location/ActivityRecognitionHardware$Event;)V"); 153a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sOnActivityChanged == NULL) { 154a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Error obtaining ActivityChanged callback."); 155a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 156a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 157a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 158a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa // register callbacks 159a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sDevice->register_activity_callback(sDevice, &sCallbacks); 160a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 161a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 162a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 163a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Initializes and connect the callbacks handlers in the HAL. 164a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 165a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic void initialize(JNIEnv* env, jobject obj) { 166a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sCallbacksObject == NULL) { 167a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sCallbacksObject = env->NewGlobalRef(obj); 168a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } else { 169a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGD("Callbacks Object was already initialized."); 170a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 171a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 172a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sDevice != NULL) { 173a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sDevice->register_activity_callback(sDevice, &sCallbacks); 174a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } else { 175a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGD("ActivityRecognition device not found during initialization."); 176a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 177a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 178a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 179a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 180a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * De-initializes the ActivityRecognitionHardware from the native side. 181a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 182a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic void release(JNIEnv* env, jobject obj) { 183a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sDevice == NULL) { 184a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 185a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 186a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 187a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int error = activity_recognition_close(sDevice); 188a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (error != 0) { 189a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Error closing device: %d", error); 190a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return; 191a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 192a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 193a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 194a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 195a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Returns true if ActivityRecognition HAL is supported, false otherwise. 196a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 197a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic jboolean is_supported(JNIEnv* env, jclass clazz) { 198a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sModule != NULL && sDevice != NULL ) { 199a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return JNI_TRUE; 200a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 201a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return JNI_FALSE; 202a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 203a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 204a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 205a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Gets an array representing the supported activities. 206a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 207a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic jobjectArray get_supported_activities(JNIEnv* env, jobject obj) { 208a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (sModule == NULL) { 209a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return NULL; 210a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 211a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 212a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa char const* const* list = NULL; 213a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa int list_size = sModule->get_supported_activities_list(sModule, &list); 214a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (list_size <= 0 || list == NULL) { 215a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return NULL; 216a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 217a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 218a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jclass string_class = env->FindClass("java/lang/String;"); 219a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (string_class == NULL) { 220a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Unable to find String class for supported activities."); 221a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return NULL; 222a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 223a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 224a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jobjectArray string_array = env->NewObjectArray(list_size, string_class, NULL); 225a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (string_array == NULL) { 226a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGE("Unable to create string array for supported activities."); 227a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return NULL; 228a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 229a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 230a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa for (int i = 0; i < list_size; ++i) { 231a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa const char* string_ptr = const_cast<const char*>(list[i]); 232a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jsize string_length = strlen(string_ptr); 233a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jstring string = env->NewString((const jchar*) string_ptr, string_length); 234a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env->SetObjectArrayElement(string_array, i, string); 235a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 236a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa // log debugging information in case we need to try to trace issues with the strings 237a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa if (string_length) { 238a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa ALOGD("Invalid activity (index=%d) name size: %d", i, string_length); 239a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 240a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa } 241a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 242a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return string_array; 243a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 244a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 245a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 246a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Enables a given activity event to be actively monitored. 247a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 248a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic int enable_activity_event( 249a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa JNIEnv* env, 250a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jobject obj, 251a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jint activity_handle, 252a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jint event_type, 253a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jlong report_latency_ns) { 254a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return sDevice->enable_activity_event( 255a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sDevice, 256a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa (uint32_t) activity_handle, 257a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa (uint32_t) event_type, 258a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa report_latency_ns); 259a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 260a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 261a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 262a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Disables a given activity event from being actively monitored. 263a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 264a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic int disable_activity_event( 265a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa JNIEnv* env, 266a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jobject obj, 267a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jint activity_handle, 268a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa jint event_type) { 269a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return sDevice->disable_activity_event( 270a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sDevice, 271a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa (uint32_t) activity_handle, 272a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa (uint32_t) event_type); 273a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 274a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 275a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 276a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Request flush for al batch buffers. 277a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 278a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic int flush(JNIEnv* env, jobject obj) { 279a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return sDevice->flush(sDevice); 280a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 281a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 282a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 283a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaastatic JNINativeMethod sMethods[] = { 284a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa // {"name", "signature", (void*) functionPointer }, 285a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeClassInit", "()V", (void*) class_init }, 286a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeInitialize", "()V", (void*) initialize }, 287a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeRelease", "()V", (void*) release }, 288a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeIsSupported", "()Z", (void*) is_supported }, 289a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeGetSupportedActivities", "()[Ljava/lang/String;", (void*) get_supported_activities }, 290a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeEnableActivityEvent", "(IIJ)I", (void*) enable_activity_event }, 291a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeDisableActivityEvent", "(II)I", (void*) disable_activity_event }, 292a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa { "nativeFlush", "()I", (void*) flush }, 293a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa}; 294a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa 295a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa/** 296a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa * Registration method invoked in JNI load. 297a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa */ 298a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaaint register_android_hardware_location_ActivityRecognitionHardware(JNIEnv* env) { 299a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa return jniRegisterNativeMethods( 300a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa env, 301a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa "android/hardware/location/ActivityRecognitionHardware", 302a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa sMethods, 303a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa NELEM(sMethods)); 304a4fa3b5aa53cf677b623fe346c585cb8a0c1ce26destradaa} 305