From 209bac4c8818978fbbbc1d73aab124d927ad1ff8 Mon Sep 17 00:00:00 2001 From: shenpeixing Date: Tue, 10 Jun 2025 11:18:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4sensor=E6=9C=8D=E5=8A=A1ani?= =?UTF-8?q?=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: shenpeixing --- bundle.json | 1 - frameworks/ets/taihe/idl/ohos.sensor.taihe | 4 + frameworks/ets/taihe/user/main.ets | 56 +- frameworks/js/ani/BUILD.gn | 77 --- frameworks/js/ani/ets/@ohos.sensor.ets | 54 -- frameworks/js/ani/include/ani_utils.h | 413 ------------ frameworks/js/ani/include/sensor_ani.h | 137 ---- frameworks/js/ani/src/sensor_ani.cpp | 708 --------------------- 8 files changed, 31 insertions(+), 1419 deletions(-) delete mode 100644 frameworks/js/ani/BUILD.gn delete mode 100644 frameworks/js/ani/ets/@ohos.sensor.ets delete mode 100644 frameworks/js/ani/include/ani_utils.h delete mode 100644 frameworks/js/ani/include/sensor_ani.h delete mode 100644 frameworks/js/ani/src/sensor_ani.cpp diff --git a/bundle.json b/bundle.json index eb103113..f4b1eac1 100755 --- a/bundle.json +++ b/bundle.json @@ -43,7 +43,6 @@ "base_group": [], "fwk_group": [ "//base/sensors/sensor/frameworks/js/napi:sensor_js_target", - "//base/sensors/sensor/frameworks/js/ani:sensor_ani_target", "//base/sensors/sensor/frameworks/cj:cj_sensor_ffi", "//base/sensors/sensor/frameworks/native:sensor_target", "//base/sensors/sensor/frameworks/native:ohsensor", diff --git a/frameworks/ets/taihe/idl/ohos.sensor.taihe b/frameworks/ets/taihe/idl/ohos.sensor.taihe index becd5ce2..3afbf2a5 100644 --- a/frameworks/ets/taihe/idl/ohos.sensor.taihe +++ b/frameworks/ets/taihe/idl/ohos.sensor.taihe @@ -15,6 +15,10 @@ @!namespace("@ohos.sensor", "sensor") +@!sts_inject(""" + static { loadLibrary("sensor_taihe_native.z") } +""") + /** * Enum for obtain the type of sensor. * @enum { i32 } diff --git a/frameworks/ets/taihe/user/main.ets b/frameworks/ets/taihe/user/main.ets index d2b07cab..f549f695 100644 --- a/frameworks/ets/taihe/user/main.ets +++ b/frameworks/ets/taihe/user/main.ets @@ -13,13 +13,11 @@ * limitations under the License. */ -import sensor from "@ohos.sensor"; -import {BusinessError} from "@ohos.base"; - -loadLibrary("sensor_taihe_native.z"); +import sensor from '@ohos.sensor'; +import {BusinessError} from '@ohos.base'; function testGetRotationMatrix() { - console.log("taihetest testGetRotationMatrix begin"); + console.log('taihetest testGetRotationMatrix begin'); try { let gravity: float[] = [-0.27775216, 0.5351276, 9.788099]; let geomagnetic: float[] = [210.87253, -78.6096, -111.44444]; @@ -28,35 +26,35 @@ function testGetRotationMatrix() { console.error(`Failed to get rotationMatrix. Code: ${err.code}, message: ${err.message}`); return; } - console.info("Succeeded in getting rotationMatrix: " + JSON.stringify(data)); + console.info('Succeeded in getting rotationMatrix: ' + JSON.stringify(data)); }) } catch (error) { let e: BusinessError = error as BusinessError; console.error(`Failed to get rotationMatrix. Code: ${e.code}, message: ${e.message}`); } - console.log("taihetest testGetRotationMatrix end"); + console.log('taihetest testGetRotationMatrix end'); } function testGetOrientation() { - console.log("taihetest testGetOrientation begin"); + console.log('taihetest testGetOrientation begin'); try { - let preRotationMatrix: float[] = [1, 0, 0, 0, 0.87, -0.50, 0 , 0.50, 0.87]; + let preRotationMatrix: float[] = [1, 0, 0, 0, 0.87, -0.50, 0, 0.50, 0.87]; sensor.getOrientation(preRotationMatrix, (err: BusinessError, data: Array) => { if (err.code != 0) { console.error(`Failed to get orientation. Code: ${err.code}, message: ${err.message}`); return; } - console.info("Succeeded in getting data: " + JSON.stringify(data)); + console.info('Succeeded in getting data: ' + JSON.stringify(data)); }) } catch (error) { let e: BusinessError = error as BusinessError; console.error(`Failed to get orientation. Code: ${e.code}, message: ${e.message}`); } - console.log("taihetest testGetOrientation end"); + console.log('taihetest testGetOrientation end'); } function testGetRotationMatrixSync() { - console.log("taihetest testGetRotationMatrixSync begin"); + console.log('taihetest testGetRotationMatrixSync begin'); try { let rotationVector: float[] = [0.20046076, 0.21907, 0.73978853, 0.60376877]; sensor.getRotationMatrix(rotationVector, (err: BusinessError, data: Array) => { @@ -64,34 +62,34 @@ function testGetRotationMatrixSync() { console.error(`Failed to get rotationMatrix. Code: ${err.code}, message: ${err.message}`); return; } - console.info("GetRotationMatrixSync succeeded in getting data: " + JSON.stringify(data)); + console.info('GetRotationMatrixSync succeeded in getting data: ' + JSON.stringify(data)); }) } catch (error) { let e: BusinessError = error as BusinessError; console.error(`Failed to get rotationMatrix. Code: ${e.code}, message: ${e.message}`); } - console.log("taihetest testGetRotationMatrixSync end"); + console.log('taihetest testGetRotationMatrixSync end'); } function testGetSensorList() { - console.log("taihetest testGetSensorList begin"); + console.log('taihetest testGetSensorList begin'); try { sensor.getSensorList((err: BusinessError, data: Array) => { if (err.code != 0) { console.error(`Failed to get sensorList. Code: ${err.code}, message: ${err.message}`); return; } - console.info("GetSensorList succeeded in getting data: " + JSON.stringify(data)); + console.info('GetSensorList succeeded in getting data: ' + JSON.stringify(data)); }); } catch (error) { let e: BusinessError = error as BusinessError; console.error(`Failed to get sensorList. Code: ${e.code}, message: ${e.message}`); } - console.log("taihetest testGetSensorList end"); + console.log('taihetest testGetSensorList end'); } function testOnAccelerometer() { - console.log("taihetest testOnAccelerometer begin"); + console.log('taihetest testOnAccelerometer begin'); try { let intervalData: long = 100000000; let optionTest: sensor.Options = { @@ -104,11 +102,11 @@ function testOnAccelerometer() { let e: BusinessError = error as BusinessError; console.error(`Failed to invoke onAccelerometer. Code: ${e.code}, message: ${e.message}`); } - console.log("taihetest testOnAccelerometer end"); + console.log('taihetest testOnAccelerometer end'); } function testOnceAccelerometer() { - console.log("taihetest testOnceAccelerometer begin"); + console.log('taihetest testOnceAccelerometer begin'); try { sensor.once(sensor.SensorId.ACCELEROMETER, (data: sensor.AccelerometerResponse): void => { console.info('Succeeded in invoking once accelerometer data: ' + JSON.stringify(data)); @@ -117,11 +115,11 @@ function testOnceAccelerometer() { let e: BusinessError = error as BusinessError; console.error(`Failed to invoke onceAccelerometer. Code: ${e.code}, message: ${e.message}`); } - console.log("taihetest testOnceAccelerometer end"); + console.log('taihetest testOnceAccelerometer end'); } function testOffAccelerometer() { - console.log("taihetest testOffAccelerometer begin"); + console.log('taihetest testOffAccelerometer begin'); try { sensor.off(sensor.SensorId.ACCELEROMETER, (data: sensor.AccelerometerResponse): void => { console.info('Succeeded in invoking off accelerometer data: ' + JSON.stringify(data)); @@ -130,11 +128,11 @@ function testOffAccelerometer() { let e: BusinessError = error as BusinessError; console.error(`Failed to invoke offAccelerometer. Code: ${e.code}, message: ${e.message}`); } - console.log("taihetest testOffAccelerometer end"); + console.log('taihetest testOffAccelerometer end'); } function testOnAmbientLight() { - console.log("taihetest testOnAmbientLight begin"); + console.log('taihetest testOnAmbientLight begin'); try { let intervalData: long = 100000000; let optionTest: sensor.Options = { @@ -147,11 +145,11 @@ function testOnAmbientLight() { let e: BusinessError = error as BusinessError; console.error(`Failed to invoke onAmbientLight. Code: ${e.code}, message: ${e.message}`); } - console.log("taihetest testOnAmbientLight end"); + console.log('taihetest testOnAmbientLight end'); } function testOnceAmbientLight() { - console.log("taihetest testOnceAmbientLight begin"); + console.log('taihetest testOnceAmbientLight begin'); try { sensor.once(sensor.SensorId.AMBIENT_LIGHT, (data: sensor.LightResponse): void => { console.info('Succeeded in invoking once onAmbientLight data: ' + JSON.stringify(data)); @@ -160,11 +158,11 @@ function testOnceAmbientLight() { let e: BusinessError = error as BusinessError; console.error(`Failed to invoke onAmbientLight. Code: ${e.code}, message: ${e.message}`); } - console.log("taihetest testOnceAmbientLight end"); + console.log('taihetest testOnceAmbientLight end'); } function testOffAmbientLight() { - console.log("taihetest testOffAmbientLight begin"); + console.log('taihetest testOffAmbientLight begin'); try { sensor.off(sensor.SensorId.AMBIENT_LIGHT, (data: sensor.LightResponse): void => { console.info('Succeeded in invoking off onAmbientLight data: ' + JSON.stringify(data)); @@ -173,7 +171,7 @@ function testOffAmbientLight() { let e: BusinessError = error as BusinessError; console.error(`Failed to invoke onAmbientLight. Code: ${e.code}, message: ${e.message}`); } - console.log("taihetest testOffAmbientLight end"); + console.log('taihetest testOffAmbientLight end'); } function main() { diff --git a/frameworks/js/ani/BUILD.gn b/frameworks/js/ani/BUILD.gn deleted file mode 100644 index c56092f3..00000000 --- a/frameworks/js/ani/BUILD.gn +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (c) 2025 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build/config/components/ets_frontend/ets2abc_config.gni") -import("//build/ohos.gni") -import("./../../../sensor.gni") - -ohos_shared_library("sensor_ani") { - branch_protector_ret = "pac_ret" - sanitize = { - cfi = true - cfi_cross_dso = true - debug = false - } - - sources = [ "src/sensor_ani.cpp" ] - include_dirs = [ - "include", - "$SUBSYSTEM_DIR/frameworks/native/include", - "$SUBSYSTEM_DIR/interfaces/inner_api", - "$SUBSYSTEM_DIR/utils/common/include", - ] - deps = [ - "$SUBSYSTEM_DIR/frameworks/native:sensor_interface_native", - "$SUBSYSTEM_DIR/utils/common:libsensor_utils", - ] - - external_deps = [ - "bundle_framework:appexecfwk_base", - "bundle_framework:appexecfwk_core", - "c_utils:utils", - "eventhandler:libeventhandler", - "hilog:libhilog", - "ipc:ipc_single", - "runtime_core:ani", - "safwk:system_ability_fwk", - "samgr:samgr_proxy", - ] - - subsystem_name = "sensors" - part_name = "sensor" - output_extension = "so" -} - -generate_static_abc("sensor_abc") { - base_url = "./ets" - files = [ "./ets/@ohos.sensor.ets" ] - dst_file = "$target_out_dir/sensor.abc" - out_puts = [ "$target_out_dir/sensor.abc" ] - is_boot_abc = "True" - device_dst_file = "/system/framework/sensor.abc" -} - -ohos_prebuilt_etc("sensor_abc_etc") { - source = "$target_out_dir/sensor.abc" - module_install_dir = "framework" - subsystem_name = "sensors" - part_name = "sensor" - deps = [ ":sensor_abc" ] -} - -group("sensor_ani_target") { - deps = [ - ":sensor_abc_etc", - ":sensor_ani", - ] -} diff --git a/frameworks/js/ani/ets/@ohos.sensor.ets b/frameworks/js/ani/ets/@ohos.sensor.ets deleted file mode 100644 index 31b4c552..00000000 --- a/frameworks/js/ani/ets/@ohos.sensor.ets +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import type { Callback } from '@ohos.base'; -import { BusinessError } from '@ohos.base'; - -export default namespace sensor { - loadLibrary("sensor_ani"); - - export native function on(type: 'ORIENTATION', callback: Callback, options?: Options): void; - export native function off(type: 'ORIENTATION', callback?: Callback): void; - export type SensorFrequency = 'game' | 'ui' | 'normal'; - export interface Options { - interval?: number | SensorFrequency; - } - - export enum SensorAccuracy { - ACCURACY_UNRELIABLE = 0, - ACCURACY_LOW = 1, - ACCURACY_MEDIUM = 2, - ACCURACY_HIGH = 3 - } - - export interface Response { - timestamp: number; - accuracy: SensorAccuracy; - } - - export interface OrientationResponse extends Response { - alpha: number; - beta: number; - gamma: number; - } - - class OrientationResponseImpl implements OrientationResponse { - timestamp: number; - accuracy: SensorAccuracy; - alpha: number; - beta: number; - gamma: number; - } -} \ No newline at end of file diff --git a/frameworks/js/ani/include/ani_utils.h b/frameworks/js/ani/include/ani_utils.h deleted file mode 100644 index 8f2605f0..00000000 --- a/frameworks/js/ani/include/ani_utils.h +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANI_UTILS_H -#define ANI_UTILS_H - -#include - -#include -#include -#include -#include -#include -#include -#include - -template -class NativeObjectWrapper { -public: - static ani_object Create([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_class clazz) - { - T* nativePtr = new T; - return Wrap(env, clazz, nativePtr); - } - - static ani_object Wrap([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_class clazz, T* nativePtr) - { - ani_method ctor; - if (ANI_OK != env->Class_FindMethod(clazz, "", "J:V", &ctor)) { - std::cerr << "Not found ''" << std::endl; - ani_object nullobj = nullptr; - return nullobj; - } - - ani_object obj; - if (ANI_OK != env->Object_New(clazz, ctor, &obj, reinterpret_cast(nativePtr))) { - std::cerr << "Object_New failed" << std::endl; - } - return obj; - } - - static T* Unwrap(ani_env *env, ani_object object, const char* propName = "nativePtr") - { - ani_long nativePtr; - if (ANI_OK != env->Object_GetFieldByName_Long(object, propName, &nativePtr)) { - return nullptr; - } - return reinterpret_cast(nativePtr); - } - - static ani_status Attach(ani_env *env, ani_object object, T* nativePtr, const char* propName = "nativePtr") - { - return env->Object_SetFieldByName_Long(object, propName, reinterpret_cast(nativePtr)); - } -}; - -class AniStringUtils { -public: - static std::string ToStd(ani_env *env, ani_string ani_str) - { - ani_size strSize; - env->String_GetUTF8Size(ani_str, &strSize); - - std::vector buffer(strSize + 1); // +1 for null terminator - char* utf8_buffer = buffer.data(); - - //String_GetUTF8 Supportted by https://gitee.com/openharmony/arkcompiler_runtime_core/pulls/3416 - ani_size bytes_written = 0; - env->String_GetUTF8(ani_str, utf8_buffer, strSize + 1, &bytes_written); - - utf8_buffer[bytes_written] = '\0'; - std::string content = std::string(utf8_buffer); - return content; - } - - static ani_string ToAni(ani_env* env, const std::string& str) - { - ani_string aniStr = nullptr; - if (ANI_OK != env->String_NewUTF8(str.data(), str.size(), &aniStr)) { - std::cerr << "[ANI] Unsupported ANI_VERSION_1" << std::endl; - return nullptr; - } - return aniStr; - } -}; - -class UnionAccessor { -public: - UnionAccessor(ani_env *env, ani_object &obj) : env_(env), obj_(obj) - { - } - - bool IsInstanceOf(const std::string& cls_name) - { - ani_class cls; - env_->FindClass(cls_name.c_str(), &cls); - - ani_boolean ret; - env_->Object_InstanceOf(obj_, cls, &ret); - return ret; - } - - template - bool IsInstanceOfType(); - - template - bool TryConvert(T &value); - - template - bool TryConvertArray(std::vector &value); - -private: - ani_env *env_; - ani_object obj_; -}; - -template<> -bool UnionAccessor::IsInstanceOfType() -{ - return IsInstanceOf("Lstd/core/Boolean;"); -} - -template<> -bool UnionAccessor::IsInstanceOfType() -{ - return IsInstanceOf("Lstd/core/Int;"); -} - -template<> -bool UnionAccessor::IsInstanceOfType() -{ - return IsInstanceOf("Lstd/core/Double;"); -} - -template<> -bool UnionAccessor::IsInstanceOfType() -{ - return IsInstanceOf("Lstd/core/String;"); -} - -template<> -bool UnionAccessor::TryConvert(bool &value) -{ - if (!IsInstanceOfType()) { - return false; - } - - ani_boolean aniValue; - auto ret = env_->Object_CallMethodByName_Boolean(obj_, "unboxed", nullptr, &aniValue); - if (ret != ANI_OK) { - return false; - } - value = static_cast(aniValue); - return true; -} - -template<> -bool UnionAccessor::TryConvert(int &value) -{ - if (!IsInstanceOfType()) { - return false; - } - - ani_int aniValue; - auto ret = env_->Object_CallMethodByName_Int(obj_, "unboxed", nullptr, &aniValue); - if (ret != ANI_OK) { - return false; - } - value = static_cast(aniValue); - return true; -} - -template<> -bool UnionAccessor::TryConvert(double &value) -{ - if (!IsInstanceOfType()) { - return false; - } - - ani_double aniValue; - auto ret = env_->Object_CallMethodByName_Double(obj_, "unboxed", nullptr, &aniValue); - if (ret != ANI_OK) { - return false; - } - value = static_cast(aniValue); - return true; -} - -template<> -bool UnionAccessor::TryConvert(std::string &value) -{ - if (!IsInstanceOfType()) { - return false; - } - - value = AniStringUtils::ToStd(env_, static_cast(obj_)); - return true; -} - -template<> -bool UnionAccessor::TryConvertArray(std::vector &value) -{ - ani_double length; - if (ANI_OK != env_->Object_GetPropertyByName_Double(obj_, "length", &length)) { - std::cerr << "Object_GetPropertyByName_Double length failed" << std::endl; - return false; - } - for (int i = 0; i < int(length); i++) { - ani_ref ref; - if (ANI_OK != env_->Object_CallMethodByName_Ref(obj_, "$_get", "I:Lstd/core/Object;", &ref, (ani_int)i)) { - std::cerr << "Object_GetPropertyByName_Ref failed" << std::endl; - return false; - } - ani_boolean val; - if (ANI_OK != env_->Object_CallMethodByName_Boolean(static_cast(ref), "unboxed", nullptr, &val)) { - std::cerr << "Object_CallMethodByName_Double unbox failed" << std::endl; - return false; - } - value.push_back(static_cast(val)); - } - return true; -} - -template<> -bool UnionAccessor::TryConvertArray(std::vector &value) -{ - ani_double length; - if (ANI_OK != env_->Object_GetPropertyByName_Double(obj_, "length", &length)) { - std::cerr << "Object_GetPropertyByName_Double length failed" << std::endl; - return false; - } - for (int i = 0; i < int(length); i++) { - ani_ref ref; - if (ANI_OK != env_->Object_CallMethodByName_Ref(obj_, "$_get", "I:Lstd/core/Object;", &ref, (ani_int)i)) { - std::cerr << "Object_GetPropertyByName_Ref failed" << std::endl; - return false; - } - ani_int intValue; - if (ANI_OK != env_->Object_CallMethodByName_Int(static_cast(ref), "unboxed", nullptr, &intValue)) { - std::cerr << "Object_CallMethodByName_Double unbox failed" << std::endl; - return false; - } - value.push_back(static_cast(intValue)); - } - return true; -} - -template<> -bool UnionAccessor::TryConvertArray(std::vector &value) -{ - ani_double length; - if (ANI_OK != env_->Object_GetPropertyByName_Double(obj_, "length", &length)) { - std::cerr << "Object_GetPropertyByName_Double length failed" << std::endl; - return false; - } - for (int i = 0; i < int(length); i++) { - ani_ref ref; - if (ANI_OK != env_->Object_CallMethodByName_Ref(obj_, "$_get", "I:Lstd/core/Object;", &ref, (ani_int)i)) { - std::cerr << "Object_GetPropertyByName_Ref failed" << std::endl; - return false; - } - ani_double val; - if (ANI_OK != env_->Object_CallMethodByName_Double(static_cast(ref), "unboxed", nullptr, &val)) { - std::cerr << "Object_CallMethodByName_Double unbox failed" << std::endl; - return false; - } - value.push_back(static_cast(val)); - } - return true; -} - -template<> -bool UnionAccessor::TryConvertArray(std::vector &value) -{ - std::cout << "TryConvertArray std::vector" << std::endl; - ani_ref buffer; - if (ANI_OK != env_->Object_GetFieldByName_Ref(obj_, "buffer", &buffer)) { - std::cout << "Object_GetFieldByName_Ref failed" << std::endl; - return false; - } - void* data; - size_t length; - if (ANI_OK != env_->ArrayBuffer_GetInfo(static_cast(buffer), &data, &length)) { - std::cerr << "ArrayBuffer_GetInfo failed" << std::endl; - return false; - } - std::cout << "Length of buffer is " << length << std::endl; - for (size_t i = 0; i < length; i++) { - value.push_back(static_cast(data)[i]); - } - return true; -} - -template<> -bool UnionAccessor::TryConvertArray(std::vector &value) -{ - ani_double length; - if (ANI_OK != env_->Object_GetPropertyByName_Double(obj_, "length", &length)) { - std::cerr << "Object_GetPropertyByName_Double length failed" << std::endl; - return false; - } - - for (int i = 0; i < int(length); i++) { - ani_ref ref; - if (ANI_OK != env_->Object_CallMethodByName_Ref(obj_, "$_get", "I:Lstd/core/Object;", &ref, (ani_int)i)) { - std::cerr << "Object_GetPropertyByName_Double length failed" << std::endl; - return false; - } - value.push_back(AniStringUtils::ToStd(env_, static_cast(ref))); - } - return true; -} - -class OptionalAccessor { -public: - OptionalAccessor(ani_env *env, ani_object &obj) : env_(env), obj_(obj) - { - } - - bool IsUndefined() - { - ani_boolean isUndefined; - env_->Reference_IsUndefined(obj_, &isUndefined); - return isUndefined; - } - - template - std::optional Convert(); - -private: - ani_env *env_; - ani_object obj_; -}; - -template<> -std::optional OptionalAccessor::Convert() -{ - if (IsUndefined()) { - return std::nullopt; - } - - ani_double aniValue; - auto ret = env_->Object_CallMethodByName_Double(obj_, "doubleValue", nullptr, &aniValue); - if (ret != ANI_OK) { - return std::nullopt; - } - auto value = static_cast(aniValue); - return value; -} - -template<> -std::optional OptionalAccessor::Convert() -{ - if (IsUndefined()) { - return std::nullopt; - } - - ani_size strSize; - env_->String_GetUTF8Size(static_cast(obj_), &strSize); - - std::vector buffer(strSize + 1); - char* utf8_buffer = buffer.data(); - - ani_size bytes_written = 0; - env_->String_GetUTF8(static_cast(obj_), utf8_buffer, strSize + 1, &bytes_written); - - utf8_buffer[bytes_written] = '\0'; - std::string content = std::string(utf8_buffer); - return content; -} - -class AniLocalScopeGuard { -public: - AniLocalScopeGuard(ani_env *env, size_t nrRefs) : env_(env) - { - status_ = env_->CreateLocalScope(nrRefs); - } - - ~AniLocalScopeGuard() - { - if (ANI_OK != status_) { - return; - } - env_->DestroyLocalScope(); - } - - bool IsStatusOK() - { - return ANI_OK == status_; - } - - ani_status GetStatus() - { - return status_; - } - -private: - ani_env *env_ = nullptr; - ani_status status_ = ANI_ERROR; -}; -#endif \ No newline at end of file diff --git a/frameworks/js/ani/include/sensor_ani.h b/frameworks/js/ani/include/sensor_ani.h deleted file mode 100644 index be11ac17..00000000 --- a/frameworks/js/ani/include/sensor_ani.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef SENSOR_ANI_H -#define SENSOR_ANI_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "refbase.h" -#include "sensor_agent_type.h" -#include "sensor_errors.h" -#include "sensor_log.h" - -#undef LOG_TAG -#define LOG_TAG "SensorAniAPI" - -namespace OHOS { -namespace Sensors { -using std::vector; -using std::string; -using namespace OHOS::HiviewDFX; -constexpr int32_t THREE_DIMENSIONAL_MATRIX_LENGTH = 9; -constexpr static int32_t DATA_LENGTH = 16; -constexpr int32_t CALLBACK_NUM = 3; -enum CallbackDataType { - SUBSCRIBE_FAIL = -2, - FAIL = -1, - OFF_CALLBACK = 0, - ON_CALLBACK = 1, - ONCE_CALLBACK = 2, - GET_GEOMAGNETIC_FIELD = 3, - GET_ALTITUDE = 4, - GET_GEOMAGNETIC_DIP = 5, - GET_ANGLE_MODIFY = 6, - CREATE_ROTATION_MATRIX = 7, - TRANSFORM_COORDINATE_SYSTEM = 8, - CREATE_QUATERNION = 9, - GET_DIRECTION = 10, - ROTATION_INCLINATION_MATRIX = 11, - GET_SENSOR_LIST = 12, - GET_SINGLE_SENSOR = 13, - SUBSCRIBE_CALLBACK = 14, - SUBSCRIBE_COMPASS = 15, - GET_BODY_STATE = 16, -}; - -struct GeomagneticData { - float x; - float y; - float z; - float geomagneticDip; - float deflectionAngle; - float levelIntensity; - float totalIntensity; -}; - -struct RationMatrixData { - float rotationMatrix[THREE_DIMENSIONAL_MATRIX_LENGTH]; - float inclinationMatrix[THREE_DIMENSIONAL_MATRIX_LENGTH]; -}; - -struct CallbackSensorData { - int32_t sensorTypeId; - uint32_t dataLength; - float data[DATA_LENGTH]; - int64_t timestamp; - int32_t sensorAccuracy; -}; - -struct ReserveData { - float reserve[DATA_LENGTH]; - int32_t length; -}; - -union CallbackData { - CallbackSensorData sensorData; - GeomagneticData geomagneticData; - RationMatrixData rationMatrixData; - ReserveData reserveData; -}; - -struct BusinessError { - int32_t code { 0 }; - string message; - string name; - string stack; -}; - -class AsyncCallbackInfo : public RefBase { -public: - ani_vm *vm = nullptr; - ani_env *env = nullptr; - ani_ref callback[CALLBACK_NUM] = { 0 }; - CallbackData data; - BusinessError error; - CallbackDataType type; - vector sensorInfos; - AsyncCallbackInfo(ani_vm *vm, ani_env *env, CallbackDataType type) : vm(vm), env(env), type(type) {} - ~AsyncCallbackInfo() - { - CALL_LOG_ENTER; - if (type != ONCE_CALLBACK) { - for (int32_t i = 0; i < CALLBACK_NUM; ++i) { - if (callback[i] != nullptr) { - SEN_HILOGD("Delete reference, i:%{public}d", i); - env->GlobalReference_Delete(callback[i]); - callback[i] = nullptr; - env = nullptr; - vm = nullptr; - } - } - } - } - -private: -}; -} // namespace Sensors -} // namespace OHOS -#endif // SENSOR_ANI_H \ No newline at end of file diff --git a/frameworks/js/ani/src/sensor_ani.cpp b/frameworks/js/ani/src/sensor_ani.cpp deleted file mode 100644 index 361c6e41..00000000 --- a/frameworks/js/ani/src/sensor_ani.cpp +++ /dev/null @@ -1,708 +0,0 @@ -/* - * Copyright (c) 2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "sensor_ani.h" -#include "securec.h" -#include "ani_utils.h" -#include "sensor_agent.h" -#include "event_handler.h" - -#undef LOG_TAG -#define LOG_TAG "SensorAniAPI" - -using namespace OHOS; -using namespace OHOS::Sensors; - -constexpr int32_t REPORTING_INTERVAL = 200000000; -constexpr int32_t INVALID_SENSOR_ID = -1; -constexpr float BODY_STATE_EXCEPT = 1.0f; -constexpr float THRESHOLD = 0.000001f; -constexpr int32_t ANI_SCOPE_SIZE = 16; - -static std::unordered_map g_sensorTypeToClassName = { - {256, "LOrientationResponseImpl;"}, -}; - -std::map> g_sensorAttributeList = { - { 0, { "x" } }, - { SENSOR_TYPE_ID_ACCELEROMETER, { "x", "y", "z" } }, - { SENSOR_TYPE_ID_GYROSCOPE, { "x", "y", "z" } }, - { SENSOR_TYPE_ID_AMBIENT_LIGHT, { "intensity", "colorTemperature", "infraredLuminance" } }, - { SENSOR_TYPE_ID_MAGNETIC_FIELD, { "x", "y", "z" } }, - { SENSOR_TYPE_ID_BAROMETER, { "pressure" } }, - { SENSOR_TYPE_ID_HALL, { "status" } }, - { SENSOR_TYPE_ID_TEMPERATURE, { "temperature" } }, - { SENSOR_TYPE_ID_PROXIMITY, { "distance" } }, - { SENSOR_TYPE_ID_HUMIDITY, { "humidity" } }, - { SENSOR_TYPE_ID_ORIENTATION, { "alpha", "beta", "gamma" } }, - { SENSOR_TYPE_ID_GRAVITY, { "x", "y", "z" } }, - { SENSOR_TYPE_ID_LINEAR_ACCELERATION, { "x", "y", "z" } }, - { SENSOR_TYPE_ID_ROTATION_VECTOR, { "x", "y", "z", "w" } }, - { SENSOR_TYPE_ID_AMBIENT_TEMPERATURE, { "temperature" } }, - { SENSOR_TYPE_ID_MAGNETIC_FIELD_UNCALIBRATED, { "x", "y", "z", "biasX", "biasY", "biasZ" } }, - { SENSOR_TYPE_ID_GYROSCOPE_UNCALIBRATED, { "x", "y", "z", "biasX", "biasY", "biasZ" } }, - { SENSOR_TYPE_ID_SIGNIFICANT_MOTION, { "scalar" } }, - { SENSOR_TYPE_ID_PEDOMETER_DETECTION, { "scalar" } }, - { SENSOR_TYPE_ID_PEDOMETER, { "steps" } }, - { SENSOR_TYPE_ID_HEART_RATE, { "heartRate" } }, - { SENSOR_TYPE_ID_WEAR_DETECTION, { "value" } }, - { SENSOR_TYPE_ID_ACCELEROMETER_UNCALIBRATED, { "x", "y", "z", "biasX", "biasY", "biasZ" } }, - { SENSOR_TYPE_ID_COLOR, { "lightIntensity", "colorTemperature" } }, - { SENSOR_TYPE_ID_SAR, { "absorptionRatio" } } -}; - -std::unordered_map stringToNumberMap = { - {"ORIENTATION", 256}, -}; - -static std::map g_samplingPeriod = { - {"normal", 200000000}, - {"ui", 60000000}, - {"game", 20000000}, -}; - -using ConvertDataFunc = bool(*)(sptr asyncCallbackInfo, std::vector &data); -bool ConvertToSensorData(sptr asyncCallbackInfo, std::vector &data); - -std::map g_convertfuncList = { - {ON_CALLBACK, ConvertToSensorData}, -}; - -static std::mutex mutex_; -static std::mutex bodyMutex_; -static float g_bodyState = -1.0f; -static std::map>> g_subscribeCallbacks; -static std::mutex onMutex_; -static std::map>> g_onCallbackInfos; -static thread_local std::shared_ptr mainHandler = nullptr; - -static void ThrowBusinessError(ani_env *env, int errCode, std::string&& errMsg) -{ - SEN_HILOGD("Begin ThrowBusinessError."); - static const char *errorClsName = "L@ohos/base/BusinessError;"; - ani_class cls {}; - if (ANI_OK != env->FindClass(errorClsName, &cls)) { - SEN_HILOGE("find class BusinessError %{public}s failed", errorClsName); - return; - } - ani_method ctor; - if (ANI_OK != env->Class_FindMethod(cls, "", ":V", &ctor)) { - SEN_HILOGE("find method BusinessError.constructor failed"); - return; - } - ani_object errorObject; - if (ANI_OK != env->Object_New(cls, ctor, &errorObject)) { - SEN_HILOGE("create BusinessError object failed"); - return; - } - ani_double aniErrCode = static_cast(errCode); - ani_string errMsgStr; - if (ANI_OK != env->String_NewUTF8(errMsg.c_str(), errMsg.size(), &errMsgStr)) { - SEN_HILOGE("convert errMsg to ani_string failed"); - return; - } - if (ANI_OK != env->Object_SetFieldByName_Double(errorObject, "code", aniErrCode)) { - SEN_HILOGE("set error code failed"); - return; - } - if (ANI_OK != env->Object_SetPropertyByName_Ref(errorObject, "message", errMsgStr)) { - SEN_HILOGE("set error message failed"); - return; - } - env->ThrowError(static_cast(errorObject)); - return; -} - -static bool CheckSubscribe(int32_t sensorTypeId) -{ - std::lock_guard onCallbackLock(onMutex_); - auto iter = g_onCallbackInfos.find(sensorTypeId); - return iter != g_onCallbackInfos.end(); -} - -static bool CopySensorData(sptr callbackInfo, SensorEvent *event) -{ - CHKPF(callbackInfo); - CHKPF(event); - int32_t sensorTypeId = event->sensorTypeId; - callbackInfo->data.sensorData.sensorTypeId = sensorTypeId; - callbackInfo->data.sensorData.dataLength = event->dataLen; - callbackInfo->data.sensorData.timestamp = event->timestamp; - callbackInfo->data.sensorData.sensorAccuracy = event->option; - CHKPF(event->data); - if (event->dataLen < sizeof(float)) { - SEN_HILOGE("Event dataLen less than float size"); - return false; - } - auto data = reinterpret_cast(event->data); - if (sensorTypeId == SENSOR_TYPE_ID_WEAR_DETECTION && callbackInfo->type == SUBSCRIBE_CALLBACK) { - std::lock_guard onBodyLock(bodyMutex_); - g_bodyState = *data; - callbackInfo->data.sensorData.data[0] = - (fabs(g_bodyState - BODY_STATE_EXCEPT) < THRESHOLD) ? true : false; - return true; - } - if (memcpy_s(callbackInfo->data.sensorData.data, sizeof(callbackInfo->data.sensorData.data), - data, event->dataLen) != EOK) { - SEN_HILOGE("Copy data failed"); - return false; - } - return true; -} - -static bool CheckSystemSubscribe(int32_t sensorTypeId) -{ - std::lock_guard subscribeLock(mutex_); - auto iter = g_subscribeCallbacks.find(sensorTypeId); - if (iter == g_subscribeCallbacks.end()) { - return false; - } - return true; -} - -static ani_boolean IsInstanceOf(ani_env *env, const std::string &cls_name, ani_object obj) -{ - ani_class cls; - if (ANI_OK != env->FindClass(cls_name.c_str(), &cls)) { - SEN_HILOGE("FindClass failed"); - return ANI_FALSE; - } - - ani_boolean ret; - env->Object_InstanceOf(obj, cls, &ret); - return ret; -} - -static bool SendEventToMainThread(const std::function func) -{ - if (func == nullptr) { - SEN_HILOGE("func is nullptr!"); - return false; - } - - if (!mainHandler) { - auto runner = OHOS::AppExecFwk::EventRunner::GetMainEventRunner(); - if (!runner) { - SEN_HILOGE("get main event runner failed!"); - return false; - } - mainHandler = std::make_shared(runner); - } - mainHandler->PostTask(func, "", 0, OHOS::AppExecFwk::EventQueue::Priority::HIGH, {}); - return true; -} - -bool ValidateAndInitialize(sptr asyncCallbackInfo, ani_object &obj) -{ - CHKPF(asyncCallbackInfo); - int32_t sensorTypeId = asyncCallbackInfo->data.sensorData.sensorTypeId; - if (g_sensorAttributeList.find(sensorTypeId) == g_sensorAttributeList.end()) { - SEN_HILOGE("Invalid sensor type"); - return false; - } - if (sensorTypeId == SENSOR_TYPE_ID_WEAR_DETECTION && asyncCallbackInfo->type == SUBSCRIBE_CALLBACK) { - return false; - } - size_t size = g_sensorAttributeList[sensorTypeId].size(); - uint32_t dataLength = asyncCallbackInfo->data.sensorData.dataLength / sizeof(float); - if (size > dataLength) { - SEN_HILOGE("Data length mismatch"); - return false; - } - - if (g_sensorTypeToClassName.find(sensorTypeId) == g_sensorTypeToClassName.end()) { - SEN_HILOGE("Find class by sensorType failed"); - return false; - } - - ani_namespace ns; - static const char *namespaceName = "L@ohos/sensor/sensor;"; - if (ANI_OK != asyncCallbackInfo->env->FindNamespace(namespaceName, &ns)) { - SEN_HILOGE("Not found '%{public}s'", namespaceName); - return false; - } - - ani_class cls; - const char *className = g_sensorTypeToClassName[sensorTypeId].c_str(); - if (ANI_OK != asyncCallbackInfo->env->Namespace_FindClass(ns, className, &cls)) { - SEN_HILOGE("FindClass %{public}s failed", className); - return false; - } - - ani_method ctor; - if (ANI_OK != asyncCallbackInfo->env->Class_FindMethod(cls, "", nullptr, &ctor)) { - SEN_HILOGE("Class_FindMethod 'constructor' failed"); - return false; - } - - if (ANI_OK != asyncCallbackInfo->env->Object_New(cls, ctor, &obj)) { - SEN_HILOGE("Object_New '%{public}s' failed", className); - return false; - } - return true; -} - -ani_enum_item GetEnumItem(ani_env *env, int32_t accuracy) -{ - ani_namespace ns; - static const char *namespaceName = "L@ohos/sensor/sensor;"; - if (ANI_OK != env->FindNamespace(namespaceName, &ns)) { - SEN_HILOGE("Not found '%{public}s'", namespaceName); - return nullptr; - } - - ani_enum aniEnum{}; - const char *enumName = "LSensorAccuracy;"; - if (ANI_OK != env->Namespace_FindEnum(ns, enumName, &aniEnum)) { - SEN_HILOGE("Not found '%{public}s'", enumName); - return nullptr; - } - - constexpr int32_t loopMaxNum = 1000; - for (int32_t index = 0U; index < loopMaxNum; index++) { - ani_enum_item enumItem{}; - if (ANI_OK != env->Enum_GetEnumItemByIndex(aniEnum, index, &enumItem)) { - SEN_HILOGE("Enum_GetEnumItemByIndex failed"); - return nullptr; - } - ani_int intValue = -1; - if (ANI_OK != env->EnumItem_GetValue_Int(enumItem, &intValue)) { - SEN_HILOGE("EnumItem_GetValue_Int FAILD."); - return nullptr; - } - if (intValue == accuracy) { - return enumItem; - } - } - SEN_HILOGE("Get enumItem by %{public}d failed.", accuracy); - return nullptr; -} - -bool SetSensorPropertiesAndPushData(sptr asyncCallbackInfo, ani_object obj, - std::vector &data) -{ - CALL_LOG_ENTER; - int32_t sensorTypeId = asyncCallbackInfo->data.sensorData.sensorTypeId; - size_t size = g_sensorAttributeList[sensorTypeId].size(); - auto sensorAttributes = g_sensorAttributeList[sensorTypeId]; - for (uint32_t i = 0; i < size; ++i) { - if (ANI_OK != asyncCallbackInfo->env->Object_SetPropertyByName_Double(obj, sensorAttributes[i].c_str(), - asyncCallbackInfo->data.sensorData.data[i])) { - SEN_HILOGE("Object_SetPropertyByName_Double failed"); - return false; - } - } - - if (ANI_OK != asyncCallbackInfo->env->Object_SetPropertyByName_Double(obj, "timestamp", - asyncCallbackInfo->data.sensorData.timestamp)) { - SEN_HILOGE("Object_SetPropertyByName_Double timestamp failed"); - return false; - } - - ani_enum_item accuracy = GetEnumItem(asyncCallbackInfo->env, asyncCallbackInfo->data.sensorData.sensorAccuracy); - if (accuracy == nullptr) { - SEN_HILOGE("GetEnumItem failed"); - return false; - } - if (ANI_OK != asyncCallbackInfo->env->Object_SetPropertyByName_Ref(obj, "accuracy", accuracy)) { - SEN_HILOGE("Object_SetPropertyByName_Ref accuracy failed"); - return false; - } - - data.push_back(obj); - return true; -} - -bool ConvertToSensorData(sptr asyncCallbackInfo, std::vector &data) -{ - ani_object obj; - if (!ValidateAndInitialize(asyncCallbackInfo, obj)) { - return false; - } - - if (!SetSensorPropertiesAndPushData(asyncCallbackInfo, obj, data)) { - return false; - } - - return true; -} - -static void EmitUvEventLoop(sptr asyncCallbackInfo) -{ - CHKPV(asyncCallbackInfo); - auto task = [asyncCallbackInfo]() { - SEN_HILOGD("Begin to call task"); - ani_env *env = nullptr; - ani_options aniArgs {0, nullptr}; - if (ANI_ERROR == asyncCallbackInfo->vm->AttachCurrentThread(&aniArgs, ANI_VERSION_1, &env)) { - if (ANI_OK != asyncCallbackInfo->vm->GetEnv(ANI_VERSION_1, &env)) { - SEN_HILOGE("GetEnv failed"); - return; - } - } - asyncCallbackInfo->env = env; - - AniLocalScopeGuard aniLocalScopeGuard(asyncCallbackInfo->env, ANI_SCOPE_SIZE); - if (!aniLocalScopeGuard.IsStatusOK()) { - SEN_HILOGE("CreateLocalScope failed"); - return; - } - - if (!(g_convertfuncList.find(asyncCallbackInfo->type) != g_convertfuncList.end())) { - SEN_HILOGE("asyncCallbackInfo type is invalid"); - ThrowBusinessError(asyncCallbackInfo->env, EINVAL, "asyncCallbackInfo type is invalid"); - return; - } - std::vector args; - g_convertfuncList[asyncCallbackInfo->type](asyncCallbackInfo, args); - - auto fnObj = reinterpret_cast(asyncCallbackInfo->callback[0]); - SEN_HILOGD("Begin to call FunctionalObject_Call"); - if (fnObj == nullptr) { - SEN_HILOGE("fnObj == nullptr"); - ThrowBusinessError(asyncCallbackInfo->env, EINVAL, "fnObj == nullptr"); - return; - } - if (IsInstanceOf(asyncCallbackInfo->env, "Lstd/core/Function1;", fnObj) == 0) { - SEN_HILOGE("fnObj is not instance Of function"); - ThrowBusinessError(asyncCallbackInfo->env, EINVAL, "fnObj is not instance Of function"); - return; - } - - ani_ref result; - if (ANI_OK != asyncCallbackInfo->env->FunctionalObject_Call(fnObj, 1, args.data(), &result)) { - SEN_HILOGE("FunctionalObject_Call failed"); - ThrowBusinessError(asyncCallbackInfo->env, EINVAL, "FunctionalObject_Call failed"); - return; - } - SEN_HILOGD("FunctionalObject_Call success"); - }; - if (!SendEventToMainThread(task)) { - SEN_HILOGE("failed to send event"); - } -} -static void EmitOnCallback(SensorEvent *event) -{ - CHKPV(event); - int32_t sensorTypeId = event->sensorTypeId; - if (!CheckSubscribe(sensorTypeId)) { - return; - } - std::lock_guard onCallbackLock(onMutex_); - auto onCallbackInfos = g_onCallbackInfos[sensorTypeId]; - for (auto &onCallbackInfo : onCallbackInfos) { - if (!CopySensorData(onCallbackInfo, event)) { - SEN_HILOGE("Copy sensor data failed"); - continue; - } - EmitUvEventLoop(onCallbackInfo); - } -} - -void DataCallbackImpl(SensorEvent *event) -{ - CHKPV(event); - EmitOnCallback(event); -} - -const SensorUser user = { - .callback = DataCallbackImpl -}; - -int32_t SubscribeSensor(int32_t sensorTypeId, int64_t interval, RecordSensorCallback callback) -{ - CALL_LOG_ENTER; - int32_t ret = SubscribeSensor(sensorTypeId, &user); - if (ret != ERR_OK) { - SEN_HILOGE("SubscribeSensor failed"); - return ret; - } - ret = SetBatch(sensorTypeId, &user, interval, 0); - if (ret != ERR_OK) { - SEN_HILOGE("SetBatch failed"); - return ret; - } - return ActivateSensor(sensorTypeId, &user); -} - -static bool IsSubscribed(ani_env *env, int32_t sensorTypeId, ani_object callback) -{ - CALL_LOG_ENTER; - if (auto iter = g_onCallbackInfos.find(sensorTypeId); iter == g_onCallbackInfos.end()) { - SEN_HILOGW("No client subscribe, sensorTypeId:%{public}d", sensorTypeId); - return false; - } - std::vector> callbackInfos = g_onCallbackInfos[sensorTypeId]; - for (auto callbackInfo : callbackInfos) { - CHKPC(callbackInfo); - if (callbackInfo->env != env) { - continue; - } - - ani_boolean isEquals = false; - if (ANI_OK != env->Reference_StrictEquals(callback, callbackInfo->callback[0], &isEquals)) { - SEN_HILOGE("StrictEquals failed"); - return false; - } - if (isEquals) { - return true; - } - } - return false; -} - -static void UpdateCallbackInfos(ani_env *env, int32_t sensorTypeId, ani_object callback) -{ - CALL_LOG_ENTER; - std::lock_guard onCallbackLock(onMutex_); - CHKCV((!IsSubscribed(env, sensorTypeId, callback)), "The callback has been subscribed"); - - ani_vm *vm = nullptr; - if (ANI_OK != env->GetVM(&vm)) { - SEN_HILOGE("GetVM failed."); - return; - } - sptr asyncCallbackInfo = new (std::nothrow) AsyncCallbackInfo(vm, env, ON_CALLBACK); - CHKPV(asyncCallbackInfo); - - if (ANI_OK != env->GlobalReference_Create(callback, &asyncCallbackInfo->callback[0])) { - SEN_HILOGE("GlobalReference_Create failed"); - return; - } - - std::vector> callbackInfos = g_onCallbackInfos[sensorTypeId]; - callbackInfos.push_back(asyncCallbackInfo); - g_onCallbackInfos[sensorTypeId] = callbackInfos; -} - -bool GetIntervalValue(ani_env *env, ani_object options, int64_t& interval) -{ - ani_boolean isUndefined; - env->Reference_IsUndefined(options, &isUndefined); - if (isUndefined) { - return true; - } - - ani_ref intervalRef; - ani_boolean isIntervalUndefined; - if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "interval", &intervalRef)) { - SEN_HILOGE("Failed to get property named interval"); - return false; - } - - env->Reference_IsUndefined(intervalRef, &isIntervalUndefined); - if (isIntervalUndefined) { - SEN_HILOGE("interval is undefined"); - return false; - } - - ani_class stringClass; - env->FindClass("Lstd/core/String;", &stringClass); - ani_class doubleClass; - env->FindClass("Lstd/core/Double;", &doubleClass); - - ani_boolean isDouble; - env->Object_InstanceOf(static_cast(intervalRef), doubleClass, &isDouble); - ani_boolean isString; - env->Object_InstanceOf(static_cast(intervalRef), stringClass, &isString); - if (isDouble) { - ani_double doubleValue; - auto ret = env->Object_CallMethodByName_Double(static_cast(intervalRef), "unboxed", - nullptr, &doubleValue); - if (ret != ANI_OK) { - SEN_HILOGE("Failed to get property named doubleValue"); - return false; - } - interval = static_cast(doubleValue); - return true; - } - - if (isString) { - auto mode = AniStringUtils::ToStd(env, static_cast(intervalRef)); - auto iter = g_samplingPeriod.find(mode); - if (iter == g_samplingPeriod.end()) { - SEN_HILOGE("Find interval mode failed"); - return false; - } - interval = iter->second; - SEN_HILOGI("GetIntervalValue mode: %{public}s", mode.c_str()); - return true; - } - - SEN_HILOGE("Invalid interval type"); - return false; -} - -static void On([[maybe_unused]] ani_env *env, ani_string typeId, ani_object callback, ani_object options) -{ - CALL_LOG_ENTER; - if (!IsInstanceOf(env, "Lstd/core/Function1;", callback)) { - SEN_HILOGE("Wrong argument type"); - return; - } - - int32_t sensorTypeId = INVALID_SENSOR_ID; - auto typeIdStr = AniStringUtils::ToStd(env, static_cast(typeId)); - if (stringToNumberMap.find(typeIdStr) == stringToNumberMap.end()) { - SEN_HILOGE("Invalid sensor typeId: %{public}s", typeIdStr.c_str()); - return; - } - sensorTypeId = stringToNumberMap[typeIdStr]; - - int64_t interval = REPORTING_INTERVAL; - if (!GetIntervalValue(env, options, interval)) { - SEN_HILOGW("Get interval failed"); - } - int32_t ret = SubscribeSensor(sensorTypeId, interval, DataCallbackImpl); - if (ret != ERR_OK) { - ThrowBusinessError(env, ret, "SubscribeSensor fail"); - return; - } - UpdateCallbackInfos(env, sensorTypeId, callback); -} - -static int32_t RemoveAllCallback(ani_env *env, int32_t sensorTypeId) -{ - CALL_LOG_ENTER; - std::lock_guard onCallbackLock(onMutex_); - std::vector> callbackInfos = g_onCallbackInfos[sensorTypeId]; - for (auto iter = callbackInfos.begin(); iter != callbackInfos.end();) { - CHKPC(*iter); - if ((*iter)->env != env) { - ++iter; - continue; - } - iter = callbackInfos.erase(iter); - } - if (callbackInfos.empty()) { - SEN_HILOGD("No subscription to change sensor data"); - g_onCallbackInfos.erase(sensorTypeId); - return 0; - } - g_onCallbackInfos[sensorTypeId] = callbackInfos; - return callbackInfos.size(); -} - -static int32_t RemoveCallback(ani_env *env, int32_t sensorTypeId, ani_object callback) -{ - CALL_LOG_ENTER; - std::lock_guard onCallbackLock(onMutex_); - std::vector> callbackInfos = g_onCallbackInfos[sensorTypeId]; - for (auto iter = callbackInfos.begin(); iter != callbackInfos.end();) { - CHKPC(*iter); - if ((*iter)->env != env) { - continue; - } - - ani_boolean isEquals = false; - if (ANI_OK != env->Reference_StrictEquals(callback, (*iter)->callback[0], &isEquals)) { - SEN_HILOGE("Reference_StrictEquals failed"); - return false; - } - if (isEquals) { - iter = callbackInfos.erase(iter); - SEN_HILOGD("Remove callback success"); - break; - } else { - ++iter; - } - } - if (callbackInfos.empty()) { - SEN_HILOGD("No subscription to change sensor data"); - g_onCallbackInfos.erase(sensorTypeId); - return 0; - } - g_onCallbackInfos[sensorTypeId] = callbackInfos; - return callbackInfos.size(); -} - -int32_t UnsubscribeSensor(int32_t sensorTypeId) -{ - int32_t ret = DeactivateSensor(sensorTypeId, &user); - if (ret != ERR_OK) { - SEN_HILOGE("DeactivateSensor failed"); - return ret; - } - return UnsubscribeSensor(sensorTypeId, &user); -} - -static void Off([[maybe_unused]] ani_env *env, ani_string type, ani_object callback) -{ - CALL_LOG_ENTER; - int32_t sensorTypeId = INVALID_SENSOR_ID; - auto typeStr = AniStringUtils::ToStd(env, static_cast(type)); - if (stringToNumberMap.find(typeStr) == stringToNumberMap.end()) { - SEN_HILOGE("Invalid sensor type: %{public}s", typeStr.c_str()); - ThrowBusinessError(env, PARAMETER_ERROR, "Invalid sensor type"); - return; - } - sensorTypeId = stringToNumberMap[typeStr]; - - int32_t subscribeSize = -1; - ani_boolean isUndefined; - env->Reference_IsUndefined(callback, &isUndefined); - if (isUndefined) { - subscribeSize = RemoveAllCallback(env, sensorTypeId); - } else { - ani_boolean result; - if (env->Reference_IsNull(callback, &result) == ANI_OK && result) { - subscribeSize = RemoveAllCallback(env, sensorTypeId); - } else if (IsInstanceOf(env, "Lstd/core/Function1;", callback)) { - subscribeSize = RemoveCallback(env, sensorTypeId, callback); - } else { - ThrowBusinessError(env, PARAMETER_ERROR, "Invalid callback"); - return; - } - } - - if (CheckSystemSubscribe(sensorTypeId) || (subscribeSize > 0)) { - SEN_HILOGW("There are other client subscribe system js api as well, not need unsubscribe"); - return; - } - int32_t ret = UnsubscribeSensor(sensorTypeId); - if (ret == PARAMETER_ERROR || ret == PERMISSION_DENIED) { - ThrowBusinessError(env, ret, "UnsubscribeSensor fail"); - } - return; -} - -ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) -{ - ani_env *env; - if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { - SEN_HILOGE("Unsupported ANI_VERSION_1"); - return ANI_ERROR; - } - - ani_namespace ns; - static const char *spaceName = "L@ohos/sensor/sensor;"; - if (ANI_OK != env->FindNamespace(spaceName, &ns)) { - SEN_HILOGE("Not found space name"); - return ANI_ERROR; - } - - std::array methods = { - ani_native_function {"on", nullptr, reinterpret_cast(On)}, - ani_native_function {"off", nullptr, reinterpret_cast(Off)}, - }; - - if (ANI_OK != env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size())) { - SEN_HILOGE("Cannot bind native methods to %{public}s", spaceName); - return ANI_ERROR; - } - - *result = ANI_VERSION_1; - return ANI_OK; -} \ No newline at end of file -- Gitee