add medical_sensor framework

Signed-off-by: 371931794 <wuhb30061@chipsea.com>

Signed-off-by: wuhb <wuhb30061@chipsea.com>
This commit is contained in:
wuhb
2022-01-05 11:38:09 +08:00
parent 6eed9347ce
commit c7574a8b11
86 changed files with 10446 additions and 0 deletions
Executable
+177
View File
@@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Executable
+82
View File
@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (c) 2021 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.
This is the configuration file template for OpenHarmony OSS Audit Tool, please copy it to your project root dir and modify it refer to OpenHarmony/tools_oat/README.
-->
<configuration>
<oatconfig>
<licensefile>LICENSE</licensefile>
<policylist>
<policy name="defaultPolicy" desc="" >
<policyitem type="compatibility" name="Apache" path="frameworks/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter" desc=""/>
<policyitem type="compatibility" name="Apache" path="interfaces/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter" desc=""/>
<policyitem type="compatibility" name="Apache" path="sa_profile/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter" desc=""/>
<policyitem type="compatibility" name="Apache" path="services/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter" desc=""/>
<policyitem type="compatibility" name="Apache" path="utils/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter" desc=""/>
</policy>
</policylist>
<filefilterlist>
<filefilter name="defaultPolicyFilter" desc="Files not to check">
<filteritem type="filepath" name="interfaces/plugin/vibrate/test/vibrate_js_test_hap/entry/src/ohosTest/resources/base/media/icon.png" desc="png文件"/>
<filteritem type="filepath" name="interfaces/plugin/vibrate/test/vibrate_js_test_hap/entry/src/main/resources/base/media/icon.png" desc="png文件"/>
<filteritem type="filepath" name="interfaces/plugin/vibrate/test/vibrate_js_test_hap/entry/src/main/resources/base/media/icon_small.png" desc="png文件"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/ohosTest/js/default/app.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/main/js/default/app.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/ohosTest/js/default/pages/index/index.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/main/js/test/List.test.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/ohosTest/js/test/ExampleJsunit.test.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/main/js/test/SensorJsunit.test.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/ohosTest/js/test/List.test.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/main/js/default/pages/index/index.js" desc="js文件,不参与打包不影响兼容性"/>
</filefilter>
<filefilter name="copyrightPolicyFilter" desc="Filters for copyright header policies">
<filteritem type="filepath" name="interfaces/plugin/vibrate/test/vibrate_js_test_hap/entry/src/ohosTest/resources/base/media/icon.png" desc="png文件"/>
<filteritem type="filepath" name="interfaces/plugin/vibrate/test/vibrate_js_test_hap/entry/src/main/resources/base/media/icon.png" desc="png文件"/>
<filteritem type="filepath" name="interfaces/plugin/vibrate/test/vibrate_js_test_hap/entry/src/main/resources/base/media/icon_small.png" desc="png文件"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/ohosTest/js/default/app.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/main/js/default/app.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/ohosTest/js/default/pages/index/index.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/main/js/test/List.test.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/ohosTest/js/test/ExampleJsunit.test.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/main/js/test/SensorJsunit.test.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/ohosTest/js/test/List.test.js" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/main/js/default/pages/index/index.js" desc="js文件,不参与打包不影响兼容性"/>
</filefilter>
<filefilter name="licenseFileNamePolicyFilter" desc="Filters for LICENSE file policies">
</filefilter>
<filefilter name="readmeFileNamePolicyFilter" desc="Filters for README file policies">
</filefilter>
<filefilter name="readmeOpenSourcefileNamePolicyFilter" desc="Filters for README.OpenSource file policies">
</filefilter>
<filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies">
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/main/resources/base/media/icon_small.png" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/ohosTest/resources/base/media/icon.png" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/entry/src/main/resources/base/media/icon.png" desc="js文件,不参与打包不影响兼容性"/>
<filteritem type="filepath" name="interfaces/plugin/test/sensor_js_test_hap/gradle/wrapper/gradle-wrapper.jar" desc="js文件,不参与打包不影响兼容性"/>
</filefilter>
</filefilterlist>
<licensematcherlist>
<licensematcher name="uvwxyz License" desc="If the scanning result is InvalidLicense, you can define matching rules here. Note that quotation marks must be escaped.">
<licensetext name="
uvwxyz license text xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
" desc=""/>
</licensematcher>
</licensematcherlist>
</oatconfig>
</configuration>
+67
View File
@@ -0,0 +1,67 @@
# Copyright (c) 2021 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/ohos.gni")
import("//foundation/appexecfwk/standard/appexecfwk.gni")
import(
"//foundation/appexecfwk/standard/libs/libeventhandler/lib_event_handler_sources.gni")
SUBSYSTEM_DIR = "//base/sensors/medical_sensor"
##############################################
ohos_shared_library("libmedical_native") {
sources = [
"src/my_event_handler.cpp",
"src/my_file_descriptor_listener.cpp",
"src/medical_data_channel.cpp",
"src/medical_service_client.cpp",
"src/medical_service_proxy.cpp",
"src/medical_client_stub.cpp",
]
include_dirs = [
"include",
"//utils/native/base/include",
"//utils/system/safwk/native/include",
"$SUBSYSTEM_DIR/utils/include",
"$SUBSYSTEM_DIR/services/medical_sensor/include",
"$SUBSYSTEM_DIR/interfaces/native/include",
"//drivers/peripheral/sensor/interfaces/include",
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include",
"//foundation/appexecfwk/standard/libs/test/moduletest/common/event_handler",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include",
]
deps = [
"$SUBSYSTEM_DIR/services/medical_sensor:libmedical_service",
"$SUBSYSTEM_DIR/utils:libmedical_utils",
"//drivers/peripheral/sensor/hal:hdi_sensor",
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler",
"//foundation/appexecfwk/standard/libs/libeventhandler:libeventhandler_target",
"//utils/native/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_standard:samgr_proxy",
]
part_name = "medical_sensor"
subsystem_name = "sensors"
}
##############################################
group("medical_native_target") {
deps = [ ":libmedical_native" ]
}
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2021 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 I_SENSOR_CLIENT_H
#define I_SENSOR_CLIENT_H
#include "iremote_broker.h"
namespace OHOS {
namespace Sensors {
class IMedicalSensorClient : public IRemoteBroker {
public:
IMedicalSensorClient() = default;
virtual ~IMedicalSensorClient() = default;
DECLARE_INTERFACE_DESCRIPTOR(u"IMedicalSensorClient");
};
} // namespace Sensors
} // namespace OHOS
#endif // I_SENSOR_CLIENT_H
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2021 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 I_SENSOR_SERVICE_H
#define I_SENSOR_SERVICE_H
#include <vector>
#include "errors.h"
#include "i_medical_client.h"
#include "iremote_broker.h"
#include "medical.h"
#include "medical_basic_data_channel.h"
namespace OHOS {
namespace Sensors {
class IMedicalSensorService : public IRemoteBroker {
public:
IMedicalSensorService() = default;
virtual ~IMedicalSensorService() = default;
DECLARE_INTERFACE_DESCRIPTOR(u"IMedicalSensorService");
virtual ErrCode EnableSensor(uint32_t sensorId, int64_t samplingPeriodNs,
int64_t maxReportDelayNs) = 0;
virtual ErrCode DisableSensor(uint32_t sensorId) = 0;
virtual ErrCode SetOption(uint32_t sensorId, uint32_t opt) = 0;
virtual int32_t GetSensorState(uint32_t sensorId) = 0;
virtual ErrCode RunCommand(uint32_t sensorId, uint32_t cmdType, uint32_t params) = 0;
virtual std::vector<MedicalSensor> GetSensorList() = 0;
virtual ErrCode TransferDataChannel(const sptr<MedicalSensorBasicDataChannel> &sensorBasicDataChannel,
const sptr<IRemoteObject> &sensorClient) = 0;
virtual ErrCode DestroySensorChannel(sptr<IRemoteObject> sensorClient) = 0;
enum {
ENABLE_SENSOR = 0,
DISABLE_SENSOR,
GET_SENSOR_STATE,
RUN_COMMAND,
GET_SENSOR_LIST,
TRANSFER_DATA_CHANNEL,
DESTROY_SENSOR_CHANNEL,
SET_OPTION,
};
};
} // namespace Sensors
} // namespace OHOS
#endif // I_SENSOR_SERVICE_H
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2021 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_CLIENT_STUB_H
#define SENSOR_CLIENT_STUB_H
#include "i_medical_client.h"
#include "iremote_stub.h"
#include "message_parcel.h"
namespace OHOS {
namespace Sensors {
class MedicalSensorClientStub : public IRemoteStub<IMedicalSensorClient> {
public:
MedicalSensorClientStub() = default;
virtual ~MedicalSensorClientStub() = default;
virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option) override;
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSOR_CLIENT_STUB_H
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2021 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_DATA_CHANNEL_H
#define SENSOR_DATA_CHANNEL_H
#include <memory>
#include <thread>
#include "medical_basic_data_channel.h"
#include "medical_native_type.h"
#include "my_event_handler.h"
namespace OHOS {
namespace Sensors {
typedef void (*DataChannelCB)(struct SensorEvent *events, int32_t num, void *data);
class MedicalSensorDataChannel : public MedicalSensorBasicDataChannel {
public:
MedicalSensorDataChannel();
~MedicalSensorDataChannel();
static int32_t HandleEvent(int32_t fd, int32_t events, void *data);
int32_t CreateSensorDataChannel(DataChannelCB callBack, void *data);
int32_t DestroySensorDataChannel();
bool IsThreadExit();
bool IsThreadStart();
int32_t RestoreSensorDataChannel();
int32_t test = 10;
DataChannelCB dataCB_;
void *privateData_ = nullptr;
private:
static void threadProcessTask(MedicalSensorDataChannel *afeChannel);
int32_t InnerSensorDataChannel();
std::mutex eventRunnerMutex_;
static std::shared_ptr<MyEventHandler> eventHandler_;
static std::shared_ptr<AppExecFwk::EventRunner> eventRunner_;
static int32_t receiveFd_;
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSOR_DATA_CHANNEL_H
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2021 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_SERVICE_CLIENT_H
#define SENSOR_SERVICE_CLIENT_H
#include <map>
#include <vector>
#include "iservice_registry.h"
#include "medical.h"
#include "medical_basic_data_channel.h"
#include "medical_basic_info.h"
#include "medical_client_stub.h"
#include "medical_data_channel.h"
#include "medical_service_proxy.h"
#include "singleton.h"
#include "medical_native_type.h"
namespace OHOS {
namespace Sensors {
class MedicalSensorServiceClient : public Singleton<MedicalSensorServiceClient> {
public:
std::vector<MedicalSensor> GetSensorList();
int32_t EnableSensor(uint32_t sensorId, int64_t samplingPeroid, int64_t maxReportDelay);
int32_t DisableSensor(uint32_t sensorId);
int32_t RunCommand(uint32_t sensorId, int32_t cmdType, int32_t parms);
int32_t TransferDataChannel(sptr<MedicalSensorDataChannel> sensorDataChannel);
int32_t DestroyDataChannel();
void ProcessDeathObserver(const wptr<IRemoteObject> &object);
int32_t SetOption(uint32_t sensorId, uint32_t opt);
private:
int32_t InitServiceClient();
void UpdateSensorInfoMap(uint32_t sensorId, int64_t samplingPeroid, int64_t maxReportDelay);
void DeleteSensorInfoItem(uint32_t sensorId);
bool IsValidSensorId(uint32_t sensorId);
std::mutex clientMutex_;
sptr<IRemoteObject::DeathRecipient> serviceDeathObserver_;
sptr<IMedicalSensorService> afeServer_;
std::vector<MedicalSensor> afeList_;
sptr<MedicalSensorDataChannel> dataChannel_;
sptr<MedicalSensorClientStub> afeClientStub_;
std::mutex mapMutex_;
std::map<uint32_t, MedicalSensorBasicInfo> sensorInfoMap_;
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSOR_SERVICE_CLIENT_H
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 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_SERVICE_PROXY_H
#define SENSOR_SERVICE_PROXY_H
#include "errors.h"
#include "i_medical_service.h"
#include "iremote_proxy.h"
#include "nocopyable.h"
#include "medical_native_type.h"
namespace OHOS {
namespace Sensors {
class MedicalSensorServiceProxy : public IRemoteProxy<IMedicalSensorService> {
public:
explicit MedicalSensorServiceProxy(const sptr<IRemoteObject> &impl);
virtual ~MedicalSensorServiceProxy() = default;
ErrCode EnableSensor(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) override;
ErrCode DisableSensor(uint32_t sensorId) override;
ErrCode SetOption(uint32_t sensorId, uint32_t opt) override;
int32_t GetSensorState(uint32_t sensorId) override;
ErrCode RunCommand(uint32_t sensorId, uint32_t cmdType, uint32_t params) override;
std::vector<MedicalSensor> GetSensorList() override;
ErrCode TransferDataChannel(const sptr<MedicalSensorBasicDataChannel> &sensorBasicDataChannel,
const sptr<IRemoteObject> &sensorClient) override;
ErrCode DestroySensorChannel(sptr<IRemoteObject> sensorClient) override;
private:
DISALLOW_COPY_AND_MOVE(MedicalSensorServiceProxy);
static inline BrokerDelegator<MedicalSensorServiceProxy> delegator_;
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSOR_SERVICE_PROXY_H
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2021 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 MY_EVENT_HANDLER_H
#define MY_EVENT_HANDLER_H
#include "event_handler.h"
#include "event_runner.h"
namespace OHOS {
namespace Sensors {
class MyEventHandler : public AppExecFwk::EventHandler {
public:
explicit MyEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> &runner);
~MyEventHandler() = default;
/**
* Function: Process the event. Override the method of base class.
* @param event The event need to be processed.
*/
void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override;
};
} // namespace Sensors
} // namespace OHOS
#endif // MY_EVENT_HANDLER_H
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2021 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 MY_FILE_DESCRIPTOR_LISTENER_H
#define MY_FILE_DESCRIPTOR_LISTENER_H
#include <atomic>
#include <fcntl.h>
#include <sys/socket.h>
#include "event_handler.h"
#include "event_runner.h"
#include "file_descriptor_listener.h"
#include "medical_native_type.h"
#include "medical_data_channel.h"
namespace OHOS {
namespace Sensors {
class MyFileDescriptorListener : public AppExecFwk::FileDescriptorListener {
public:
explicit MyFileDescriptorListener();
~MyFileDescriptorListener() = default;
void OnReadable(int32_t fileDescriptor) override;
void OnWritable(int32_t fileDescriptor) override;
void OnShutdown(int32_t fileDescriptor) override;
void OnException(int32_t fileDescriptor) override;
void SetChannel(MedicalSensorDataChannel* channel);
private:
MedicalSensorDataChannel* channel_;
struct TransferMedicalSensorEvents *receiveDataBuff_ = nullptr;
};
} // namespace Sensors
} // namespace OHOS
#endif // MY_FILE_DESCRIPTOR_LISTENER_H
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2021 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 "medical_client_stub.h"
#include "message_parcel.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_SERVICE, "MedicalSensorClientStub" };
}
int32_t MedicalSensorClientStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
HiLog::Debug(LABEL, "%{public}s begin, cmd : %{public}u", __func__, code);
return NO_ERROR;
}
} // namespace Sensors
} // namespace OHOS
@@ -0,0 +1,142 @@
/*
* Copyright (c) 2021 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 "medical_data_channel.h"
#include <cerrno>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include "my_file_descriptor_listener.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
#include "string_ex.h"
#ifndef O_NONBLOCK
# define O_NONBLOCK 04000
#endif
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
using namespace OHOS::AppExecFwk;
std::shared_ptr<MyEventHandler> MedicalSensorDataChannel::eventHandler_;
std::shared_ptr<AppExecFwk::EventRunner> MedicalSensorDataChannel::eventRunner_;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_NATIVE, "MedicalSensorDataChannel" };
// max 100 data in cache buffer
constexpr int32_t SENSOR_READ_DATA_SIZE = sizeof(struct SensorEvent) * 100;
const uint32_t STOP_EVENT_ID = 0;
} // namespace
MedicalSensorDataChannel::MedicalSensorDataChannel()
: dataCB_(nullptr),
privateData_(nullptr)
{}
int32_t MedicalSensorDataChannel::CreateSensorDataChannel(DataChannelCB callBack, void *data)
{
if (callBack == nullptr) {
HiLog::Error(LABEL, "%{public}s callBack cannot be null", __func__);
return SENSOR_NATIVE_REGSITER_CB_ERR;
}
dataCB_ = callBack;
privateData_ = data;
return InnerSensorDataChannel();
}
int32_t MedicalSensorDataChannel::RestoreSensorDataChannel()
{
if (dataCB_ == nullptr) {
HiLog::Error(LABEL, "%{public}s dataCB_ cannot be null", __func__);
return SENSOR_CHANNEL_RESTORE_CB_ERR;
}
if (GetReceiveDataFd() != INVALID_FD) {
HiLog::Error(LABEL, "%{public}s fd not close", __func__);
return SENSOR_CHANNEL_RESTORE_FD_ERR;
}
return InnerSensorDataChannel();
}
int32_t MedicalSensorDataChannel::InnerSensorDataChannel()
{
std::lock_guard<std::mutex> eventRunnerLock(eventRunnerMutex_);
// create basic data channel
int32_t ret = CreateSensorBasicChannel(SENSOR_READ_DATA_SIZE, SENSOR_READ_DATA_SIZE);
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s create basic channel failed, ret : %{public}d", __func__, ret);
return ret;
}
auto listener = std::make_shared<MyFileDescriptorListener>();
listener->SetChannel(this);
auto myRunner = AppExecFwk::EventRunner::Create(true);
if (myRunner == nullptr) {
HiLog::Error(LABEL, "%{public}s myRunner is null", __func__);
return -1;
}
auto handler = std::make_shared<MyEventHandler>(myRunner);
if (handler == nullptr) {
HiLog::Error(LABEL, "%{public}s handler is null", __func__);
return -1;
}
int32_t receiveFd = GetReceiveDataFd();
auto inResult = handler->AddFileDescriptorListener(receiveFd, AppExecFwk::FILE_DESCRIPTOR_INPUT_EVENT, listener);
if (inResult != 0) {
HiLog::Error(LABEL, "%{public}s AddFileDescriptorListener fail", __func__);
return -1;
}
eventHandler_ = handler;
eventRunner_ = myRunner;
int64_t delayTime = 100;
int64_t param = 0;
bool sendEventResult = eventHandler_->SendEvent(STOP_EVENT_ID, param, delayTime);
if (!sendEventResult) {
HiLog::Error(LABEL, "%{public}s EventHandler SendEvent fail", __func__);
return -1;
}
int32_t runResult = eventRunner_->Run();
if (!runResult) {
HiLog::Error(LABEL, "%{public}s EventRunner run fail", __func__);
return -1;
}
return ERR_OK;
}
int32_t MedicalSensorDataChannel::DestroySensorDataChannel()
{
std::lock_guard<std::mutex> eventRunnerLock(eventRunnerMutex_);
if (eventHandler_ == nullptr || eventRunner_ == nullptr) {
HiLog::Error(LABEL, "%{public}s handler or eventRunner is null", __func__);
return -1;
}
int32_t receiveFd = GetReceiveDataFd();
eventHandler_->RemoveFileDescriptorListener(receiveFd);
eventHandler_ = nullptr;
eventRunner_->Stop();
eventRunner_ = nullptr;
// destroy sensor basic channelx
return DestroySensorBasicChannel();
}
MedicalSensorDataChannel::~MedicalSensorDataChannel()
{
DestroySensorDataChannel();
}
} // namespace Sensors
} // namespace OHOS
@@ -0,0 +1,263 @@
/*
* Copyright (c) 2021 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 "medical_service_client.h"
#include <sys/socket.h>
#include <thread>
#include <unistd.h>
#include <vector>
#include "death_recipient_template.h"
#include "dmd_report.h"
#include "ipc_skeleton.h"
#include "medical_service_proxy.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
#include "system_ability_definition.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_NATIVE, "MedicalSensorServiceClient" };
constexpr int32_t GET_SERVICE_MAX_COUNT = 30;
constexpr uint32_t WAIT_MS = 200;
} // namespace
int32_t MedicalSensorServiceClient::InitServiceClient()
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
std::lock_guard<std::mutex> clientLock(clientMutex_);
if (afeServer_ != nullptr) {
HiLog::Debug(LABEL, "%{public}s already init", __func__);
return ERR_OK;
}
if (afeClientStub_ == nullptr) {
afeClientStub_ = new (std::nothrow) MedicalSensorClientStub();
}
auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (systemAbilityManager == nullptr) {
HiLog::Error(LABEL, "%{public}s systemAbilityManager cannot be null", __func__);
return SENSOR_NATIVE_SAM_ERR;
}
int32_t retry = 0;
while (retry < GET_SERVICE_MAX_COUNT) {
afeServer_ = iface_cast<IMedicalSensorService>(systemAbilityManager->GetSystemAbility(MEDICAL_SENSOR_SERVICE_ABILITY_ID));
if (afeServer_ != nullptr) {
HiLog::Debug(LABEL, "%{public}s get service success, retry : %{public}d", __func__, retry);
serviceDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<MedicalSensorServiceClient *>(this));
if (serviceDeathObserver_ != nullptr) {
afeServer_->AsObject()->AddDeathRecipient(serviceDeathObserver_);
}
afeList_ = afeServer_->GetSensorList();
return ERR_OK;
}
HiLog::Warn(LABEL, "%{public}s get service failed, retry : %{public}d", __func__, retry);
std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS));
retry++;
}
DmdReport::ReportException(SENSOR_SERVICE_EXCEPTION, "InitServiceClient", SENSOR_NATIVE_GET_SERVICE_ERR);
HiLog::Error(LABEL, "%{public}s get service failed", __func__);
return SENSOR_NATIVE_GET_SERVICE_ERR;
}
bool MedicalSensorServiceClient::IsValidSensorId(uint32_t sensorId)
{
if (afeList_.empty()) {
HiLog::Error(LABEL, "%{public}s afeList_ cannot be empty", __func__);
return false;
}
for (auto &sensor : afeList_) {
if (sensor.GetSensorId() == sensorId) {
return true;
}
}
return false;
}
int32_t MedicalSensorServiceClient::EnableSensor(uint32_t sensorId, int64_t samplingPeriod, int64_t maxReportDelay)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (!IsValidSensorId(sensorId)) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
return SENSOR_NATIVE_SAM_ERR;
}
int32_t ret = InitServiceClient();
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
return ret;
}
ret = afeServer_->EnableSensor(sensorId, samplingPeriod, maxReportDelay);
if (ret == ERR_OK) {
UpdateSensorInfoMap(sensorId, samplingPeriod, maxReportDelay);
}
return ret;
}
int32_t MedicalSensorServiceClient::DisableSensor(uint32_t sensorId)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (!IsValidSensorId(sensorId)) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
return SENSOR_NATIVE_SAM_ERR;
}
int32_t ret = InitServiceClient();
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
return ret;
}
ret = afeServer_->DisableSensor(sensorId);
if (ret == ERR_OK) {
DeleteSensorInfoItem(sensorId);
}
return ret;
}
int32_t MedicalSensorServiceClient::RunCommand(uint32_t sensorId, int32_t cmdType, int32_t params)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (!IsValidSensorId(sensorId)) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
return SENSOR_NATIVE_SAM_ERR;
}
int32_t ret = InitServiceClient();
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
return ret;
}
ret = afeServer_->RunCommand(sensorId, cmdType, params);
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s RunCommand failed", __func__);
return ret;
}
return ret;
}
std::vector<MedicalSensor> MedicalSensorServiceClient::GetSensorList()
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
int32_t ret = InitServiceClient();
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
return {};
}
if (afeList_.empty()) {
HiLog::Error(LABEL, "%{public}s afeList_ cannot be empty", __func__);
}
return afeList_;
}
int32_t MedicalSensorServiceClient::TransferDataChannel(sptr<MedicalSensorDataChannel> afeDataChannel)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
dataChannel_ = afeDataChannel;
int32_t ret = InitServiceClient();
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
return ret;
}
return afeServer_->TransferDataChannel(afeDataChannel, afeClientStub_);
}
int32_t MedicalSensorServiceClient::DestroyDataChannel()
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
int32_t ret = InitServiceClient();
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
return ret;
}
return afeServer_->DestroySensorChannel(afeClientStub_);
}
void MedicalSensorServiceClient::ProcessDeathObserver(const wptr<IRemoteObject> &object)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
(void)object;
if (dataChannel_ == nullptr) {
HiLog::Error(LABEL, "%{public}s dataChannel_ cannot be null", __func__);
return;
}
// STEP1 : Destroy revious data channel
dataChannel_->DestroySensorDataChannel();
// STEP2 : Restore data channel
dataChannel_->RestoreSensorDataChannel();
// STEP3 : Clear sensorlist and afeServer_
afeList_.clear();
afeServer_ = nullptr;
// STEP4 : ReGet hsensors 3601 service
int32_t ret = InitServiceClient();
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
dataChannel_->DestroySensorDataChannel();
return;
}
// STEP5 : Retransfer new channel to hsensors
afeServer_->TransferDataChannel(dataChannel_, afeClientStub_);
// STEP6 : Restore MedicalSensor status
std::lock_guard<std::mutex> mapLock(mapMutex_);
for (const auto &it : sensorInfoMap_) {
afeServer_->EnableSensor(it.first, it.second.GetSamplingPeriodNs(), it.second.GetMaxReportDelayNs());
}
HiLog::Debug(LABEL, "%{public}s end", __func__);
}
void MedicalSensorServiceClient::UpdateSensorInfoMap(uint32_t sensorId, int64_t samplingPeriod, int64_t maxReportDelay)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
std::lock_guard<std::mutex> mapLock(mapMutex_);
MedicalSensorBasicInfo sensorInfo;
sensorInfo.SetSamplingPeriodNs(samplingPeriod);
sensorInfo.SetMaxReportDelayNs(maxReportDelay);
sensorInfo.SetSensorState(MedicalSensorState::SENSOR_ENABLED);
sensorInfoMap_[sensorId] = sensorInfo;
return;
}
void MedicalSensorServiceClient::DeleteSensorInfoItem(uint32_t sensorId)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
std::lock_guard<std::mutex> mapLock(mapMutex_);
auto it = sensorInfoMap_.find(sensorId);
if (it != sensorInfoMap_.end()) {
sensorInfoMap_.erase(it);
}
return;
}
int32_t MedicalSensorServiceClient::SetOption(uint32_t sensorId, uint32_t opt)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (!IsValidSensorId(sensorId)) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
return SENSOR_NATIVE_SAM_ERR;
}
int32_t ret = InitServiceClient();
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s InitServiceClient failed, ret : %{public}d", __func__, ret);
return ret;
}
return afeServer_->SetOption(sensorId, opt);
}
} // namespace Sensors
} // namespace OHOS
@@ -0,0 +1,260 @@
/*
* Copyright (c) 2021 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 "medical_service_proxy.h"
#include <vector>
#include "dmd_report.h"
#include "message_parcel.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_SERVICE, "MedicalSensorServiceProxy" };
constexpr int32_t MAX_SENSOR_COUNT = 200;
enum {
FLUSH = 0,
SET_MODE,
RESERVED,
};
} // namespace
MedicalSensorServiceProxy::MedicalSensorServiceProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<IMedicalSensorService>(impl)
{}
ErrCode MedicalSensorServiceProxy::EnableSensor(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(MedicalSensorServiceProxy::GetDescriptor())) {
HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__);
return WRITE_MSG_ERR;
}
if (!data.WriteUint32(sensorId)) {
HiLog::Error(LABEL, "%{public}s write sensorId failed", __func__);
return WRITE_MSG_ERR;
}
if (!data.WriteInt64(samplingPeriodNs)) {
HiLog::Error(LABEL, "%{public}s write samplingPeriodNs failed", __func__);
return WRITE_MSG_ERR;
}
if (!data.WriteInt64(maxReportDelayNs)) {
HiLog::Error(LABEL, "%{public}s write maxReportDelayNs failed", __func__);
return WRITE_MSG_ERR;
}
int32_t ret = Remote()->SendRequest(IMedicalSensorService::ENABLE_SENSOR, data, reply, option);
if (ret != NO_ERROR) {
DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "EnableSensor", ret);
HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret);
}
return static_cast<ErrCode>(ret);
}
ErrCode MedicalSensorServiceProxy::DisableSensor(uint32_t sensorId)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(MedicalSensorServiceProxy::GetDescriptor())) {
HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__);
return WRITE_MSG_ERR;
}
if (!data.WriteUint32(sensorId)) {
HiLog::Error(LABEL, "%{public}s write sensorId failed", __func__);
return WRITE_MSG_ERR;
}
int32_t ret = Remote()->SendRequest(IMedicalSensorService::DISABLE_SENSOR, data, reply, option);
if (ret != NO_ERROR) {
DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "DisableSensor", ret);
HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret);
}
return static_cast<ErrCode>(ret);
}
ErrCode MedicalSensorServiceProxy::SetOption(uint32_t sensorId, uint32_t opt)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(MedicalSensorServiceProxy::GetDescriptor())) {
HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__);
return WRITE_MSG_ERR;
}
if (!data.WriteUint32(sensorId)) {
HiLog::Error(LABEL, "%{public}s write sensorId failed", __func__);
return WRITE_MSG_ERR;
}
if (!data.WriteUint32(opt)) {
HiLog::Error(LABEL, "%{public}s write sensorId failed", __func__);
return WRITE_MSG_ERR;
}
int32_t ret = Remote()->SendRequest(IMedicalSensorService::SET_OPTION, data, reply, option);
if (ret != NO_ERROR) {
DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "DisableSensor", ret);
HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret);
}
return static_cast<ErrCode>(ret);
}
int32_t MedicalSensorServiceProxy::GetSensorState(uint32_t sensorId)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(MedicalSensorServiceProxy::GetDescriptor())) {
HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__);
return WRITE_MSG_ERR;
}
if (!data.WriteUint32(sensorId)) {
HiLog::Error(LABEL, "%{public}s write sensorId failed", __func__);
return WRITE_MSG_ERR;
}
int32_t ret = Remote()->SendRequest(IMedicalSensorService::GET_SENSOR_STATE, data, reply, option);
if (ret != NO_ERROR) {
DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "GetSensorState", ret);
HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret);
}
return static_cast<ErrCode>(ret);
}
ErrCode MedicalSensorServiceProxy::RunCommand(uint32_t sensorId, uint32_t cmdType, uint32_t params)
{
if (cmdType > RESERVED) {
HiLog::Error(LABEL, "%{public}s failed, cmdType : %{public}u", __func__, cmdType);
return CMD_TYPE_ERR;
}
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(MedicalSensorServiceProxy::GetDescriptor())) {
HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__);
return WRITE_MSG_ERR;
}
if (!data.WriteUint32(sensorId)) {
HiLog::Error(LABEL, "%{public}s write sensorId failed", __func__);
return WRITE_MSG_ERR;
}
if (!data.WriteUint32(cmdType)) {
HiLog::Error(LABEL, "%{public}s write cmdType failed", __func__);
return WRITE_MSG_ERR;
}
if (!data.WriteUint32(params)) {
HiLog::Error(LABEL, "%{public}s write params failed", __func__);
return WRITE_MSG_ERR;
}
int32_t ret = Remote()->SendRequest(IMedicalSensorService::RUN_COMMAND, data, reply, option);
if (ret != NO_ERROR) {
DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "RunCommand", ret);
HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret);
}
return static_cast<ErrCode>(ret);
}
std::vector<MedicalSensor> MedicalSensorServiceProxy::GetSensorList()
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
std::vector<MedicalSensor> sensors;
if (!data.WriteInterfaceToken(MedicalSensorServiceProxy::GetDescriptor())) {
HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__);
return sensors;
}
int32_t ret = Remote()->SendRequest(IMedicalSensorService::GET_SENSOR_LIST, data, reply, option);
if (ret != NO_ERROR) {
DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "GetSensorList", ret);
HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret);
return sensors;
}
int32_t sensorCount = reply.ReadInt32();
HiLog::Debug(LABEL, "%{public}s sensorCount : %{public}d", __func__, sensorCount);
if (sensorCount > MAX_SENSOR_COUNT) {
sensorCount = MAX_SENSOR_COUNT;
}
MedicalSensor sensor;
for (int32_t i = 0; i < sensorCount; i++) {
auto tmpSensor = sensor.Unmarshalling(reply);
if (tmpSensor == nullptr) {
continue;
}
sensors.push_back(*tmpSensor);
}
return sensors;
}
ErrCode MedicalSensorServiceProxy::TransferDataChannel(const sptr<MedicalSensorBasicDataChannel> &sensorBasicDataChannel,
const sptr<IRemoteObject> &afeClient)
{
HiLog::Debug(LABEL, "%{public}s sendFd: %{public}d", __func__, sensorBasicDataChannel->GetSendDataFd());
if (sensorBasicDataChannel == nullptr || afeClient == nullptr) {
HiLog::Error(LABEL, "%{public}s sensorBasicDataChannel or afeClient cannot be null", __func__);
return OBJECT_NULL;
}
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(MedicalSensorServiceProxy::GetDescriptor())) {
HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__);
return WRITE_MSG_ERR;
}
sensorBasicDataChannel->SendToBinder(data);
if (!data.WriteRemoteObject(afeClient)) {
HiLog::Error(LABEL, "%{public}s write afeClient failed", __func__);
return WRITE_MSG_ERR;
}
int32_t ret = Remote()->SendRequest(IMedicalSensorService::TRANSFER_DATA_CHANNEL, data, reply, option);
if (ret != NO_ERROR) {
DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "TransferDataChannel", ret);
HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret);
}
sensorBasicDataChannel->CloseSendFd();
return static_cast<ErrCode>(ret);
}
ErrCode MedicalSensorServiceProxy::DestroySensorChannel(sptr<IRemoteObject> afeClient)
{
if (afeClient == nullptr) {
HiLog::Error(LABEL, "%{public}s afeClient cannot be null", __func__);
return OBJECT_NULL;
}
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(MedicalSensorServiceProxy::GetDescriptor())) {
HiLog::Error(LABEL, "%{public}s write descriptor failed", __func__);
return WRITE_MSG_ERR;
}
if (!data.WriteRemoteObject(afeClient)) {
HiLog::Error(LABEL, "%{public}s write afeClient failed", __func__);
return WRITE_MSG_ERR;
}
int32_t ret = Remote()->SendRequest(IMedicalSensorService::DESTROY_SENSOR_CHANNEL, data, reply, option);
if (ret != NO_ERROR) {
DmdReport::ReportException(SENSOR_SERVICE_IPC_EXCEPTION, "DestroySensorChannel", ret);
HiLog::Error(LABEL, "%{public}s failed, ret : %{public}d", __func__, ret);
}
return static_cast<ErrCode>(ret);
}
} // namespace Sensors
} // namespace OHOS
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2021 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 "my_event_handler.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
using namespace OHOS::AppExecFwk;
namespace {
} // namespace
MyEventHandler::MyEventHandler(const std::shared_ptr<EventRunner> &runner):EventHandler(runner){}
/**
* Function: Process the event. Override the method of base class.
* @param event The event need to be processed.
*/
void MyEventHandler::ProcessEvent(const InnerEvent::Pointer &event){}
} // namespace Sensors
} // namespace OHOS
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2021 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 "my_file_descriptor_listener.h"
#include <cstring>
#include <sstream>
#include <unistd.h>
#include <vector>
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
using namespace OHOS::AppExecFwk;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_SERVICE, "MyFileDescriptorListener" };
constexpr int32_t RECEIVE_DATA_SIZE = 100;
} // namespace
MyFileDescriptorListener::MyFileDescriptorListener()
:channel_(nullptr),
receiveDataBuff_(
new (std::nothrow) TransferMedicalSensorEvents[sizeof(struct TransferMedicalSensorEvents) * RECEIVE_DATA_SIZE])
{}
void MyFileDescriptorListener::OnReadable(int32_t fileDescriptor)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (fileDescriptor < 0) {
HiLog::Error(LABEL, "%{public}s fileDescriptor: %{public}d", __func__, fileDescriptor);
return;
}
FileDescriptorListener::OnReadable(fileDescriptor);
if (receiveDataBuff_ == nullptr) {
receiveDataBuff_ =
new (std::nothrow) TransferMedicalSensorEvents[sizeof(struct TransferMedicalSensorEvents) * RECEIVE_DATA_SIZE];
}
int32_t len =
recv(fileDescriptor, receiveDataBuff_, sizeof(struct TransferMedicalSensorEvents) * RECEIVE_DATA_SIZE, NULL);
int32_t eventSize = sizeof(struct TransferMedicalSensorEvents);
while (len > 0) {
int32_t num = len / eventSize;
for (int i = 0; i < num; i++) {
SensorEvent event = {
.sensorTypeId = receiveDataBuff_[i].sensorTypeId,
.timestamp = receiveDataBuff_[i].timestamp,
.option = receiveDataBuff_[i].option,
.mode = receiveDataBuff_[i].mode,
.dataLen = receiveDataBuff_[i].dataLen,
.data = receiveDataBuff_[i].data
};
channel_->dataCB_(&event, 1, channel_->privateData_);
}
len = recv(fileDescriptor, receiveDataBuff_, sizeof(struct TransferMedicalSensorEvents) * RECEIVE_DATA_SIZE, NULL);
}
}
void MyFileDescriptorListener::OnWritable(int32_t fileDescriptor){}
void MyFileDescriptorListener::SetChannel(MedicalSensorDataChannel* channel)
{
channel_ = channel;
}
void MyFileDescriptorListener::OnShutdown(int32_t fileDescriptor)
{
if (fileDescriptor < 0) {
HiLog::Error(LABEL, "%{public}s param is error: %{public}d", __func__, fileDescriptor);
return;
}
FileDescriptorListener::OnShutdown(fileDescriptor);
if (receiveDataBuff_ != nullptr) {
delete[] receiveDataBuff_;
}
}
void MyFileDescriptorListener::OnException(int32_t fileDescriptor)
{
if (fileDescriptor < 0) {
HiLog::Error(LABEL, "%{public}s param is error: %{public}d", __func__, fileDescriptor);
return;
}
FileDescriptorListener::OnException(fileDescriptor);
if (receiveDataBuff_ != nullptr) {
delete[] receiveDataBuff_;
}
}
} // namespace Sensors
} // namespace OHOS
+25
View File
@@ -0,0 +1,25 @@
# Copyright (c) 2021 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/test.gni")
###############################################################################
group("unittest") {
testonly = true
if (is_phone_product || is_wearable_product) {
deps = [ "unittest/common:unittest" ]
}
if (is_phone_product) {
deps += [ "unittest/phone:unittest" ]
}
}
@@ -0,0 +1,96 @@
# Copyright (c) 2021 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/test.gni")
SUBSYSTEM_DIR = "//base/sensors/medical_sensor"
module_output_path = "sensors/medical_sensor/frameworks/medical_sensor"
#######################################################
ohos_unittest("MedicalNativeCommonTest") {
module_out_path = module_output_path
sources = [ "./medical_native_test.cpp" ]
include_dirs = [
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include",
"$SUBSYSTEM_DIR/interfaces/native/include",
"$SUBSYSTEM_DIR/utils/include",
"$SUBSYSTEM_DIR/services/medical_sensor/include",
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor/include",
"$SUBSYSTEM_DIR/frameworks/native/common/include",
"//utils/native/base/include",
]
deps = [
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor:libmedical_native",
"$SUBSYSTEM_DIR/services/medical_sensor:libmedical_service",
"$SUBSYSTEM_DIR/utils:libmedical_utils",
"//third_party/googletest:gmock_main",
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_standard:samgr_proxy",
]
}
#######################################################
ohos_unittest("MedicalDfxTest") {
module_out_path = module_output_path
sources = [ "./medical_dfx_test.cpp" ]
include_dirs = [
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include",
"$SUBSYSTEM_DIR/interfaces/native/include",
"$SUBSYSTEM_DIR/utils/include",
"$SUBSYSTEM_DIR/services/medical_sensor/include",
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor/include",
"//utils/native/base/include",
]
deps = [
#"$SUBSYSTEM_DIR/sensor/adapter/frameworks:libsensor_fwk_adapter",
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor:libmedical_native",
"$SUBSYSTEM_DIR/services/medical_sensor:libmedical_service",
"$SUBSYSTEM_DIR/utils:libmedical_utils",
"//third_party/googletest:gmock_main",
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
#"communication_L2:ipc_core",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_standard:samgr_proxy",
]
}
###########################################################################
group("unittest") {
testonly = true
if (is_phone_product || is_wearable_product) {
deps = [
":MedicalDfxTest",
":MedicalNativeCommonTest",
]
}
}
@@ -0,0 +1,130 @@
/*
* Copyright (c) 2021 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 <cstdint>
#include <memory>
#include <thread>
#include <unistd.h>
#include <fcntl.h>
#include <gtest/gtest.h>
#include "medical_data_channel.h"
#include "medical_service_client.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
#include "string_ex.h"
namespace OHOS {
namespace Sensors {
using namespace testing::ext;
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_TEST, "AfeDFXTest" };
const std::string CMD_LINE = "ps -ef | grep 'hhealth' | grep -v grep | awk '{print $2}'";
constexpr int32_t BUFFER_SIZE = 8;
constexpr pid_t INVALID_PID = -1;
} // namespace
class AfeDFXTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
pid_t GetSensorServicePid();
static void HandleEvent(struct SensorEvent *events, int32_t num, void *data);
static std::vector<MedicalSensor> g_afesList;
static sptr<MedicalSensorDataChannel> g_afeDataChannel;
static std::unique_ptr<MedicalSensorServiceClient> g_afeServiceClient;
static bool g_dataReport;
};
std::vector<MedicalSensor> AfeDFXTest::g_afesList;
sptr<MedicalSensorDataChannel> AfeDFXTest::g_afeDataChannel = nullptr;
bool AfeDFXTest::g_dataReport = false;
std::unique_ptr<MedicalSensorServiceClient> AfeDFXTest::g_afeServiceClient = nullptr;
pid_t AfeDFXTest::GetSensorServicePid()
{
pid_t pid = INVALID_PID;
char buf[BUFFER_SIZE] = { 0 };
FILE *fp = popen(CMD_LINE.c_str(), "r");
if (fp == nullptr) {
HiLog::Error(LABEL, "get error when getting afe service process id");
return pid;
}
fgets(buf, sizeof(buf) - 1, fp);
pclose(fp);
fp = nullptr;
HiLog::Info(LABEL, "process is : %{public}s", buf);
std::string pidStr(buf);
pidStr = TrimStr(pidStr, '\n');
HiLog::Info(LABEL, "pidStr is : %{public}s", pidStr.c_str());
if (pidStr.empty()) {
return pid;
}
if (IsNumericStr(pidStr)) {
pid = std::stoi(pidStr);
}
return pid;
}
void AfeDFXTest::HandleEvent(struct SensorEvent *events, int32_t num, void *data)
{
HiLog::Info(LABEL, "%{public}s HandleEvent", __func__);
for (int32_t i = 0; i < num; i++) {
g_dataReport = true;
}
return;
}
void AfeDFXTest::SetUpTestCase()
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
g_afeDataChannel = new (std::nothrow) MedicalSensorDataChannel();
ASSERT_NE(g_afeDataChannel, nullptr);
g_afeServiceClient = std::make_unique<MedicalSensorServiceClient>();
ASSERT_NE(g_afeServiceClient, nullptr);
g_afesList = g_afeServiceClient->GetSensorList();
ASSERT_NE(g_afesList.size(), 0UL);
auto ret = g_afeDataChannel->CreateSensorDataChannel(HandleEvent, nullptr);
HiLog::Info(LABEL, "CreateSensorDataChannel ret is : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
ret = g_afeServiceClient->TransferDataChannel(g_afeDataChannel);
HiLog::Info(LABEL, "TransferDataChannel ret is : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
g_dataReport = false;
}
void AfeDFXTest::TearDownTestCase()
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
g_afeServiceClient->DestroyDataChannel();
g_afeDataChannel->DestroySensorDataChannel();
}
void AfeDFXTest::SetUp()
{}
void AfeDFXTest::TearDown()
{}
} // namespace Sensors
} // namespace OHOS
@@ -0,0 +1,190 @@
/*
* Copyright (c) 2021 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 <cstdint>
#include <gtest/gtest.h>
#include <memory>
#include <thread>
#include "medical_native_type.h"
#include "medical_data_channel.h"
#include "medical_service_client.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace testing::ext;
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_TEST, "AfeNativeTest" };
}
class AfeNativeTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
static void HandleEvent(struct SensorEvent *events, int32_t num, void *data);
std::vector<MedicalSensor> afesList_;
uint32_t afeId_;
sptr<MedicalSensorDataChannel> afeDataChannel_;
std::unique_ptr<MedicalSensorServiceClient> afeServiceClient_;
bool dataReport_;
};
void AfeNativeTest::HandleEvent(struct SensorEvent *events, int32_t num, void *data)
{
ASSERT_NE(events, nullptr);
HiLog::Info(LABEL, "%{public}s start,num : %{public}d", __func__, num);
AfeNativeTest *test = reinterpret_cast<AfeNativeTest *>(data);
ASSERT_NE(test, nullptr);
for (int32_t i = 0; i < num; i++) {
if (events[i].sensorTypeId == (int32_t)test->afeId_) {
test->dataReport_ = true;
}
}
return;
}
void AfeNativeTest::SetUpTestCase()
{}
void AfeNativeTest::TearDownTestCase()
{}
void AfeNativeTest::SetUp()
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
afeDataChannel_ = new (std::nothrow) MedicalSensorDataChannel();
ASSERT_NE(afeDataChannel_, nullptr);
afeServiceClient_ = std::make_unique<MedicalSensorServiceClient>();
ASSERT_NE(afeServiceClient_, nullptr);
afesList_ = afeServiceClient_->GetSensorList();
ASSERT_NE(afesList_.size(), 0UL);
afeId_ = afesList_[0].GetSensorId();
int32_t ret = afeDataChannel_->CreateSensorDataChannel(HandleEvent, this);
HiLog::Info(LABEL, "CreateSensorDataChannel ret is : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
afeServiceClient_->TransferDataChannel(afeDataChannel_);
dataReport_ = false;
}
void AfeNativeTest::TearDown()
{
afeServiceClient_->DestroyDataChannel();
afeDataChannel_->DestroySensorDataChannel();
}
/*
* @tc.name: GetSensorList_001
* @tc.desc: get afe list
* @tc.type: FUNC
*/
HWTEST_F(AfeNativeTest, GetSensorList_001, TestSize.Level0)
{
bool ret = afesList_.empty();
HiLog::Info(LABEL, "GetSensorList_001,count : %{public}d!", int{ afesList_.size() });
ASSERT_EQ(ret, false);
}
/*
* @tc.name: GetSensorList_002
* @tc.desc: Judge afe info
* @tc.type: FUNC
*/
HWTEST_F(AfeNativeTest, GetSensorList_002, TestSize.Level0)
{
for (const auto &it : afesList_) {
ASSERT_EQ(it.GetSensorId() == 0, true);
ASSERT_EQ(it.GetName().empty(), false);
ASSERT_EQ(it.GetVendor().empty(), false);
}
HiLog::Info(LABEL, "GetSensorList_002");
}
/*
* @tc.name: SensorOperation_001
* @tc.desc: disable afe
* @tc.type: FUNC
*/
HWTEST_F(AfeNativeTest, SensorOperation_001, TestSize.Level1)
{
HiLog::Info(LABEL, "SensorOperation_001 begin");
uint64_t samplingPeriodNs = 10000000;
uint64_t maxReportDelayNs = 0;
auto afeId = afesList_[0].GetSensorId();
auto ret = afeServiceClient_->EnableSensor(afeId, samplingPeriodNs, maxReportDelayNs);
HiLog::Info(LABEL, "EnableSensor ret is : %{public}d, afeId: %{public}d", ret, afeId);
ASSERT_EQ(ret, ERR_OK);
dataReport_ = false;
// wait evennt: need about 5s from afe enable to data report
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
ASSERT_EQ(dataReport_, true);
ret = afeServiceClient_->DisableSensor(afeId);
HiLog::Info(LABEL, "DisableSensor ret is : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
}
/*
* @tc.name: ClientAfeDataChannel_001
* @tc.desc: do client afe send data channel close
* @tc.type: FUNC
*/
HWTEST_F(AfeNativeTest, ClientAfeDataChannel_001, TestSize.Level0)
{
int32_t ret = afeDataChannel_->GetSendDataFd();
HiLog::Info(LABEL, "ClientAfeDataChannel_001,ret : %{public}d!", ret);
ASSERT_EQ(ret, -1);
}
/*
* @tc.name: ClientAfeDataChannel_002
* @tc.desc: judge channel fd when create channel
* @tc.type: FUNC
*/
HWTEST_F(AfeNativeTest, ClientAfeDataChannel_002, TestSize.Level0)
{
int32_t ret = afeDataChannel_->GetReceiveDataFd();
ASSERT_EQ((ret >= 0), true);
}
/*
* @tc.name: ClientAfeDataChannel_003
* @tc.desc: Judge read thread status when Destroy Channel
* @tc.type: FUNC
*/
HWTEST_F(AfeNativeTest, ClientAfeDataChannel_003, TestSize.Level0)
{
int32_t ret = afeDataChannel_->DestroySensorDataChannel();
ASSERT_EQ(ret, ERR_OK);
}
/*
* @tc.name: ClientAfeDataChannel_004
* @tc.desc: Destroy ClientAfeDataChannel
* @tc.type: FUNC
*/
HWTEST_F(AfeNativeTest, ClientAfeDataChannel_004, TestSize.Level0)
{
int32_t ret = afeDataChannel_->DestroySensorDataChannel();
ASSERT_EQ(ret, ERR_OK);
ret = afeDataChannel_->GetSendDataFd();
ASSERT_EQ(ret, -1);
ret = afeDataChannel_->GetReceiveDataFd();
ASSERT_EQ(ret, -1);
}
} // namespace Sensors
} // namespace OHOS
@@ -0,0 +1,56 @@
# Copyright (c) 2021 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/test.gni")
SUBSYSTEM_DIR = "//base/sensors/medical_sensor"
module_output_path = "sensors/medical_sensor/frameworks/medical_sensor"
#######################################################
ohos_unittest("MedicalNativeTest") {
module_out_path = module_output_path
sources = [ "./medical_native_test.cpp" ]
include_dirs = [
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include",
"$SUBSYSTEM_DIR/interfaces/native/include",
"$SUBSYSTEM_DIR/utils/include",
"$SUBSYSTEM_DIR/services/medical_sensor/include",
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor/include",
"$SUBSYSTEM_DIR/frameworks/native/common/include",
"//utils/native/base/include",
]
deps = [
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor:libmedical_native",
"$SUBSYSTEM_DIR/services/medical_sensor:libmedical_service",
"$SUBSYSTEM_DIR/utils:libmedical_utils",
"//third_party/googletest:gmock_main",
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_standard:samgr_proxy",
]
}
###########################################################################
group("unittest") {
testonly = true
deps = [ ":MedicalNativeTest" ]
}
@@ -0,0 +1,115 @@
/*
* Copyright (c) 2021 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 <cstdint>
#include <gtest/gtest.h>
#include <memory>
#include <thread>
#include "medical_native_type.h"
#include "medical_data_channel.h"
#include "medical_service_client.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace testing::ext;
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_TEST, "AfeNativeTest" };
}
class AfeNativeTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
static void HandleEvent(struct SensorEvent *events, int32_t num, void *data);
std::vector<MedicalSensor> afesList_;
uint32_t afeId_;
sptr<MedicalSensorDataChannel> afeDataChannel_;
std::unique_ptr<MedicalSensorServiceClient> afeServiceClient_;
bool dataReport_;
};
void AfeNativeTest::HandleEvent(struct SensorEvent *events, int32_t num, void *data)
{
ASSERT_NE(events, nullptr);
HiLog::Info(LABEL, "%{public}s start,num : %{public}d", __func__, num);
AfeNativeTest *test = reinterpret_cast<AfeNativeTest *>(data);
ASSERT_NE(test, nullptr);
for (int32_t i = 0; i < num; i++) {
HiLog::Info(LABEL, "%{public}s: sensorId : %{public}d, afeid: %{public}d", __func__, events[i].sensorTypeId, test->afeId_);
if (events[i].sensorTypeId == (int32_t)test->afeId_) {
test->dataReport_ = true;
}
}
return;
}
void AfeNativeTest::SetUpTestCase()
{}
void AfeNativeTest::TearDownTestCase()
{}
void AfeNativeTest::SetUp()
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
afeDataChannel_ = new (std::nothrow) MedicalSensorDataChannel();
ASSERT_NE(afeDataChannel_, nullptr);
afeServiceClient_ = std::make_unique<MedicalSensorServiceClient>();
ASSERT_NE(afeServiceClient_, nullptr);
afesList_ = afeServiceClient_->GetSensorList();
ASSERT_NE(afesList_.size(), 0UL);
afeId_ = afesList_[0].GetSensorId();
auto ret = afeDataChannel_->CreateSensorDataChannel(HandleEvent, this);
HiLog::Info(LABEL, "CreateSensorDataChannel ret is : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
afeServiceClient_->TransferDataChannel(afeDataChannel_);
dataReport_ = false;
}
void AfeNativeTest::TearDown()
{
afeServiceClient_->DestroyDataChannel();
afeDataChannel_->DestroySensorDataChannel();
}
/*
* @tc.name: SensorOperation_001
* @tc.desc: enable afe
* @tc.type: FUNC
*/
HWTEST_F(AfeNativeTest, SensorOperation_001, TestSize.Level1)
{
HiLog::Info(LABEL, "SensorOperation_001 begin");
uint64_t samplingPeriodNs = 10000000;
uint64_t maxReportDelayNs = 0;
auto afeId = afesList_[0].GetSensorId();
auto ret = afeServiceClient_->EnableSensor(afeId, samplingPeriodNs, maxReportDelayNs);
HiLog::Info(LABEL, "EnableSensor ret is : %{public}d, afeId: %{public}d", ret, afeId);
ASSERT_EQ(ret, ERR_OK);
dataReport_ = false;
// wait evennt: need about 5s from afe enable to data report
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
ASSERT_EQ(dataReport_, true);
ret = afeServiceClient_->DisableSensor(afeId);
HiLog::Info(LABEL, "DisableSensor ret is : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
}
} // namespace Sensors
} // namespace OHOS
+58
View File
@@ -0,0 +1,58 @@
# Copyright (c) 2021 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/ohos.gni")
SUBSYSTEM_DIR = "//base/sensors/medical_sensor"
##############################################
ohos_ndk_library("libmedical_ndk") {
output_name = "medical"
ndk_description_file = "./libmedical.json"
min_compact_version = "6"
}
ohos_shared_library("medical_interface_native") {
output_name = "medical_agent"
sources = [ "src/medical_native_impl.cpp" ]
include_dirs = [
"include",
"//utils/native/base/include",
"//utils/system/safwk/native/include",
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor/include",
"$SUBSYSTEM_DIR/utils/include",
"$SUBSYSTEM_DIR/interfaces/native/include",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core/include",
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy/include",
]
deps = [
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor:libmedical_native",
"$SUBSYSTEM_DIR/interfaces/native:libmedical_ndk",
"$SUBSYSTEM_DIR/utils:libmedical_utils",
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler",
"//utils/native/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
]
part_name = "medical_sensor"
subsystem_name = "sensors"
}
##############################################
group("medical_ndk_target") {
deps = [ ":medical_interface_native" ]
}
+139
View File
@@ -0,0 +1,139 @@
/*
* Copyright (c) 2021 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.
*/
/**
* @addtogroup PanSensor
* @{
*
* @brief Provides standard open APIs for you to use common capabilities of sensors.
*
* For example, you can call these APIs to obtain sensor information,
* subscribe to or unsubscribe from sensor data, enable or disable a sensor,
* and set the sensor data reporting mode.
*
* @since 5
*/
/**
* @file sensor_agent.h
*
* @brief Declares common APIs for sensor management, such as APIs for subscribing to
* and obtaining sensor data, enabling a sensor, and setting the sensor data reporting mode.
*
* @since 5
*/
#ifndef SENSOR_AGENT_H
#define SENSOR_AGENT_H
#include "medical_native_type.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
/**
* @brief Obtains information about all sensors in the system.
*
* @param sensorInfo Indicates the double pointer to the information about all sensors in the system.
* For details, see {@link MedicalSensorInfo}.
* @param count Indicates the pointer to the total number of sensors in the system.
* @return Returns <b>0</b> if the information is obtained; returns a non-zero value otherwise.
*
* @since 5
*/
int32_t GetAllSensors(MedicalSensorInfo **sensorInfo, int32_t *count);
/**
* @brief Subscribes to sensor data. The system will report the obtained sensor data to the subscriber.
*
* @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}.
* @param user Indicates the pointer to the sensor subscriber that requests sensor data. For details,
* see {@link MedicalSensorUser}. A subscriber can obtain data from only one sensor.
* @return Returns <b>0</b> if the subscription is successful; returns a non-zero value otherwise.
*
* @since 5
*/
int32_t SubscribeSensor(int32_t sensorTypeId, const MedicalSensorUser *user);
/**
* @brief Unsubscribes from sensor data.
*
* @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}.
* @param user Indicates the pointer to the sensor subscriber that requests sensor data.
* For details, see {@link MedicalSensorUser}. A subscriber can obtain data from only one sensor.
* @return Returns <b>0</b> if the unsubscription is successful; returns a non-zero value otherwise.
*
* @since 5
*/
int32_t UnsubscribeSensor(int32_t sensorTypeId, const MedicalSensorUser *user);
/**
* @brief Sets the data sampling interval and data reporting interval for the specified sensor.
*
* @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}.
* @param user Indicates the pointer to the sensor subscriber that requests sensor data.
* For details, see {@link MedicalSensorUser}. A subscriber can obtain data from only one sensor.
* @param samplingInterval Indicates the sensor data sampling interval to set, in nanoseconds.
* @param reportInterval Indicates the sensor data reporting interval, in nanoseconds.
* @return Returns <b>0</b> if the setting is successful; returns a non-zero value otherwise.
*
* @since 5
*/
int32_t SetBatch(int32_t sensorTypeId, const MedicalSensorUser *user, int64_t samplingInterval, int64_t reportInterval);
/**
* @brief Enables the sensor that has been subscribed to. The subscriber can obtain the sensor data
* only after the sensor is enabled.
*
* @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}.
* @param user Indicates the pointer to the sensor subscriber that requests sensor data.
* For details, see {@link MedicalSensorUser}. A subscriber can obtain data from only one sensor.
* @return Returns <b>0</b> if the sensor is successfully enabled; returns a non-zero value otherwise.
*
* @since 5
*/
int32_t ActivateSensor(int32_t sensorTypeId, const MedicalSensorUser *user);
/**
* @brief Disables an enabled sensor.
*
* @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}.
* @param user Indicates the pointer to the sensor subscriber that requests sensor data.
* For details, see {@link MedicalSensorUser}. A subscriber can obtain data from only one sensor.
* @return Returns <b>0</b> if the sensor is successfully disabled; returns a non-zero value otherwise.
*
* @since 5
*/
int32_t DeactivateSensor(int32_t sensorTypeId, const MedicalSensorUser *user);
/**
* @brief Sets the data reporting mode for the specified sensor.
*
* @param sensorTypeId Indicates the ID of a sensor type. For details, see {@link SensorTypeId}.
* @param user Indicates the pointer to the sensor subscriber that requests sensor data.
* For details, see {@link MedicalSensorUser}. A subscriber can obtain data from only one sensor.
* @param mode Indicates the data reporting mode to set. For details, see {@link SensorMode}.
* @return Returns <b>0</b> if the sensor data reporting mode is successfully set; returns a non-zero value otherwise.
*
* @since 5
*/
int32_t SetMode(int32_t sensorTypeId, const MedicalSensorUser *user, int32_t mode);
int32_t SetOption(int32_t sensorTypeId, const MedicalSensorUser *user, int32_t option);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif /* SENSOR_AGENT_H */
/** @} */
+190
View File
@@ -0,0 +1,190 @@
/*
* Copyright (c) 2021 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.
*/
/**
* @addtogroup PanSensor
* @{
*
* @brief Provides standard open APIs for you to use common capabilities of sensors.
*
* For example, you can call these APIs to obtain sensor information,
* subscribe to or unsubscribe from sensor data, enable or disable a sensor,
* and set the sensor data reporting mode.
*
* @since 5
*/
/**
* @file sensor_agent_type.h
*
* @brief Defines the basic data used by the sensor agent to manage sensors.
*
* @since 5
*/
#ifndef SENSOR_AGENT_TYPE_H
#define SENSOR_AGENT_TYPE_H
#include <stdint.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
/** Maximum length of the sensor name */
#ifndef AFE_NAME_MAX_LEN2
#define AFE_NAME_MAX_LEN2 48
#endif /* SENSOR_NAME_MAX_LEN */
/** Size of sensor data */
#ifndef AFE_USER_DATA_SIZE
#define AFE_USER_DATA_SIZE 512
#endif /* AFE_USER_DATA_SIZE */
/** Maximum length of the sensor version */
#ifndef VERSION_MAX_LEN
#define VERSION_MAX_LEN 16
#endif /* VERSION_MAX_LEN */
/**
* @brief Enumerates sensor types.
*
* @since 5
*/
typedef enum {
AFE_TYPE_ID_NONE = 0, /**< None, for testing only */
AFE_TYPE_ID_PHOTOPLETHYSMOGRAPH = 129, /**< Photoplethysmography sensor */
AFE_TYPE_ID_ELECTROCARDIOGRAPH = 130, /**< Electrocardiogram (ECG) sensor */
AFE_TYPE_ID_HEART_RATE = 278, /**< Heart rate sensor */
AFE_TYPE_ID_WEAR_DETECTION = 280, /**< Wear detection sensor */
AFE_TYPE_ID_MAX = 0xFFF, /**< Maximum number of sensor type IDs */
} MedicalSensorTypeId;
/**
* @brief Defines sensor information.
*
* @since 5
*/
typedef struct MedicalSensorInfo {
char sensorName[AFE_NAME_MAX_LEN2]; /**< Sensor name */
char vendorName[AFE_NAME_MAX_LEN2]; /**< Sensor vendor */
char firmwareVersion[VERSION_MAX_LEN]; /**< Sensor firmware version */
char hardwareVersion[VERSION_MAX_LEN]; /**< Sensor hardware version */
int32_t sensorTypeId; /**< Sensor type ID */
int32_t sensorId; /**< Sensor ID */
float maxRange; /**< Maximum measurement range of the sensor */
float precision; /**< Sensor accuracy */
float power; /**< Sensor power */
} MedicalSensorInfo;
/**
* @brief Defines the data reported by the sensor.
*
* @since 5
*/
typedef struct SensorEvent {
int32_t sensorTypeId; /**< Sensor type ID */
int32_t version; /**< Sensor algorithm version */
int64_t timestamp; /**< Time when sensor data was reported */
uint32_t option; /**< Sensor data options, including the measurement range and accuracy */
int32_t mode; /**< Sensor data reporting mode (described in {@link SensorMode}) */
uint8_t *data; /**< Sensor data */
uint32_t dataLen; /**< Sensor data length */
} SensorEvent;
struct Test {
char ip[30];
char name[30];
int32_t *data;
};
/**
* @brief Defines the callback for data reporting by the sensor agent.
*
* @since 5
*/
typedef void (*RecordSensorCallback)(SensorEvent *event);
/**
* @brief Defines a reserved field for the sensor data subscriber.
*
* @since 5
*/
typedef struct UserData {
uint8_t userData[AFE_USER_DATA_SIZE]; /**< Reserved for the sensor data subscriber */
} UserData;
/**
* @brief Defines information about the sensor data subscriber.
*
* @since 5
*/
typedef struct MedicalSensorUser {
char name[AFE_NAME_MAX_LEN2]; /**< Name of the sensor data subscriber */
RecordSensorCallback callback; /**< Callback for reporting sensor data */
UserData *userData; /**< Reserved field for the sensor data subscriber */
} MedicalSensorUser;
/**
* @brief Enumerates data reporting modes of sensors.
*
* @since 5
*/
typedef enum SensorMode {
SENSOR_DEFAULT_MODE = 0, /**< Default data reporting mode */
SENSOR_REALTIME_MODE = 1, /**< Real-time data reporting mode to report a group of data each time */
SENSOR_ON_CHANGE = 2, /**< Real-time data reporting mode to report data upon status changes */
SENSOR_ONE_SHOT = 3, /**< Real-time data reporting mode to report data only once */
SENSOR_FIFO_MODE = 4, /**< FIFO-based data reporting mode to report data based on the <b>BatchCnt</b> setting */
SENSOR_MODE_MAX2, /**< Maximum sensor data reporting mode */
} SensorMode;
/**
* @brief ppg传感器的数据结构
*/
typedef struct PpgData {
uint32_t reserve : 2;
uint32_t adc_data : 22;
uint32_t tl : 2;
uint32_t rx : 2;
uint32_t phase_group : 4;
} PpgData;
/**
* @brief 心率传感器的数据结构
*/
typedef struct HeartRateData {
/**< 心率值,单位bpm */
int32_t heartRateBpm;
/**< 心率状态 */
int32_t temperatureStatus;
} HeartRateData;
/**
* @brief 佩戴检测传感器的数据结构
*/
typedef struct WearDetectionData {
/**< 标量 */
int32_t scalar;
} WearDetectionData;
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif /* SENSOR_AGENT_TYPE_H */
/**< @} */
+24
View File
@@ -0,0 +1,24 @@
[
{
"first_introduced": "6",
"name": "GetAllSensors"
},
{
"name": "SubscribeSensor"
},
{
"name": "UnsubscribeSensor"
},
{
"name": "SetBatch"
},
{
"name": "ActivateSensor"
},
{
"name": "DeactivateSensor"
},
{
"name": "SetMode"
}
]
+301
View File
@@ -0,0 +1,301 @@
/*
* Copyright (c) 2021 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 "medical_native_impl.h"
#include "securec.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
#include "medical_service_client.h"
#include "medical_data_channel.h"
using OHOS::HiviewDFX::HiLog;
using OHOS::HiviewDFX::HiLogLabel;
using OHOS::Sensors::MedicalSensorDataChannel;
using OHOS::Sensors::MedicalSensorServiceClient;
using OHOS::Sensors::INVALID_POINTER;
using OHOS::Sensors::SUCCESS;
static const HiLogLabel LABEL = {LOG_CORE, OHOS::MedicalSensorLogDomain::SENSORS_INTERFACE, "AfeNativeAPI"};
static bool g_isChannelCreated;
static int64_t g_samplingInterval;
static int64_t g_reportInterval;
static std::mutex subscribeMutex_;
static std::mutex chanelMutex_;
static std::map<int32_t, const MedicalSensorUser *> g_subscribeMap;
static std::map<int32_t, const MedicalSensorUser *> g_unsubscribeMap;
static OHOS::sptr<MedicalSensorDataChannel> g_dataChannel;
static void HandleSensorData(struct SensorEvent *events, int32_t num, void *data)
{
if (events == nullptr || num <= 0) {
HiLog::Error(LABEL, "%{public}s events is null or num is invalid", __func__);
return;
}
struct SensorEvent eventStream;
for (int32_t i = 0; i < num; ++i) {
eventStream = events[i];
if (eventStream.data == nullptr || g_subscribeMap[eventStream.sensorTypeId] == nullptr) {
HiLog::Error(LABEL, "%{public}s data or sensorUser is nullptr", __func__);
return;
}
if (g_subscribeMap.find(eventStream.sensorTypeId) == g_subscribeMap.end()) {
HiLog::Error(LABEL, "%{public}s sensorTypeId not in g_subscribeMap", __func__);
return;
}
g_subscribeMap[eventStream.sensorTypeId]->callback(&eventStream);
}
}
static int32_t CreateSensorDataChannel()
{
HiLog::Debug(LABEL, "%{public}s", __func__);
std::lock_guard<std::mutex> chanelLock(chanelMutex_);
if (g_isChannelCreated) {
HiLog::Info(LABEL, "%{public}s the channel has already been created", __func__);
return SUCCESS;
}
if (g_dataChannel == nullptr) {
g_dataChannel = new (std::nothrow) MedicalSensorDataChannel();
}
auto ret = g_dataChannel->CreateSensorDataChannel(HandleSensorData, nullptr);
if (ret != SUCCESS) {
HiLog::Error(LABEL, "%{public}s create data channel failed, ret : %{public}d", __func__, ret);
return ret;
}
auto &client = MedicalSensorServiceClient::GetInstance();
ret = client.TransferDataChannel(g_dataChannel);
if (ret != SUCCESS) {
auto destoryRet = g_dataChannel->DestroySensorDataChannel();
HiLog::Error(LABEL, "%{public}s transfer data channel failed, ret : %{public}d, destoryRet : %{public}d",
__func__, ret, destoryRet);
return ret;
}
g_isChannelCreated = true;
return SUCCESS;
}
static int32_t DestroyAfeDataChannel()
{
HiLog::Debug(LABEL, "%{public}s", __func__);
std::lock_guard<std::mutex> chanelLock(chanelMutex_);
if (!g_isChannelCreated) {
HiLog::Info(LABEL, "%{public}s channel has been destroyed", __func__);
return SUCCESS;
}
if (g_dataChannel == nullptr) {
HiLog::Error(LABEL, "%{public}s data channel cannot be null", __func__);
return INVALID_POINTER;
}
int32_t ret = g_dataChannel->DestroySensorDataChannel();
if (ret != SUCCESS) {
HiLog::Error(LABEL, "%{public}s destory data channel failed, ret : %{public}d", __func__, ret);
return ret;
}
MedicalSensorServiceClient &client = MedicalSensorServiceClient::GetInstance();
ret = client.DestroyDataChannel();
if (ret != SUCCESS) {
HiLog::Error(LABEL, "%{public}s destory service data channel fail, ret : %{public}d", __func__, ret);
return ret;
}
g_isChannelCreated = false;
delete g_dataChannel;
return SUCCESS;
}
int32_t GetAllSensors(MedicalSensorInfo **sensorInfo, int32_t *count)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (sensorInfo == nullptr || count == nullptr) {
HiLog::Error(LABEL, "%{public}s sensorInfo or count is null", __func__);
return OHOS::Sensors::ERROR;
}
MedicalSensorServiceClient &client = MedicalSensorServiceClient::GetInstance();
std::vector<OHOS::Sensors::MedicalSensor> sensorList_ = client.GetSensorList();
if (sensorList_.empty()) {
HiLog::Error(LABEL, "%{public}s get sensor lists failed", __func__);
return OHOS::Sensors::ERROR;
}
*count = sensorList_.size();
*sensorInfo = (MedicalSensorInfo *)malloc(sizeof(MedicalSensorInfo) * (*count));
if (*sensorInfo == nullptr) {
HiLog::Error(LABEL, "%{public}s malloc sensorInfo failed", __func__);
return OHOS::Sensors::ERROR;
}
for (int32_t index = 0; index < *count; index++) {
errno_t ret = strcpy_s((*sensorInfo + index)->sensorName, AFE_NAME_MAX_LEN2,
sensorList_[index].GetName().c_str());
if (ret != EOK) {
HiLog::Error(LABEL, "%{public}s strcpy sensorName failed", __func__);
return OHOS::Sensors::ERROR;
}
ret = strcpy_s((*sensorInfo + index)->vendorName, AFE_NAME_MAX_LEN2, sensorList_[index].GetVendor().c_str());
if (ret != EOK) {
HiLog::Error(LABEL, "%{public}s strcpy vendorName failed", __func__);
return OHOS::Sensors::ERROR;
}
const char *version = std::to_string(sensorList_[index].GetVersion()).c_str();
ret = strcpy_s((*sensorInfo + index)->hardwareVersion, AFE_NAME_MAX_LEN2, version);
if (ret != EOK) {
HiLog::Error(LABEL, "%{public}s strcpy hardwareVersion failed", __func__);
return OHOS::Sensors::ERROR;
}
(*sensorInfo + index)->sensorId = sensorList_[index].GetSensorId();
(*sensorInfo + index)->sensorTypeId = sensorList_[index].GetSensorId();
}
return OHOS::Sensors::SUCCESS;
}
int32_t ActivateSensor(int32_t sensorId, const MedicalSensorUser *user)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
return OHOS::Sensors::ERROR;
}
if (g_samplingInterval < 0 || g_reportInterval < 0) {
HiLog::Error(LABEL, "%{public}s samplingPeroid or g_reportInterval is invalid", __func__);
return OHOS::Sensors::ERROR;
}
std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) {
HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
return OHOS::Sensors::ERROR;
}
MedicalSensorServiceClient &client = MedicalSensorServiceClient::GetInstance();
int32_t ret = client.EnableSensor(sensorId, g_samplingInterval, g_reportInterval);
g_samplingInterval = -1;
g_reportInterval = -1;
if (ret != 0) {
HiLog::Error(LABEL, "%{public}s enable sensor failed, ret: %{public}d", __func__, ret);
g_subscribeMap.erase(sensorId);
return OHOS::Sensors::ERROR;
}
return OHOS::Sensors::SUCCESS;
}
int32_t DeactivateSensor(int32_t sensorId, const MedicalSensorUser *user)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
return OHOS::Sensors::ERROR;
}
std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap[sensorId] != user)) {
HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
return OHOS::Sensors::ERROR;
}
g_subscribeMap.erase(sensorId);
g_unsubscribeMap[sensorId] = user;
MedicalSensorServiceClient &client = MedicalSensorServiceClient::GetInstance();
int32_t ret = client.DisableSensor(sensorId);
if (ret != 0) {
HiLog::Error(LABEL, "%{public}s disable sensor failed, ret: %{public}d", __func__, ret);
return OHOS::Sensors::ERROR;
}
return OHOS::Sensors::SUCCESS;
}
int32_t SetBatch(int32_t sensorId, const MedicalSensorUser *user, int64_t samplingInterval, int64_t reportInterval)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (user == nullptr || sensorId < 0) {
HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
return OHOS::Sensors::ERROR;
}
if (samplingInterval < 0 || reportInterval < 0) {
HiLog::Error(LABEL, "%{public}s samplingInterval or reportInterval is invalid", __func__);
return OHOS::Sensors::ERROR;
}
std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) {
HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
return OHOS::Sensors::ERROR;
}
g_samplingInterval = samplingInterval;
g_reportInterval = reportInterval;
return OHOS::Sensors::SUCCESS;
}
int32_t SubscribeSensor(int32_t sensorId, const MedicalSensorUser *user)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
HiLog::Error(LABEL, "%{public}s user or sensorId is invalid", __func__);
return OHOS::Sensors::ERROR;
}
int32_t ret = CreateSensorDataChannel();
if (ret != SUCCESS) {
HiLog::Error(LABEL, "%{public}s create sensor data chanel failed", __func__);
return OHOS::Sensors::ERROR;
}
std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
g_subscribeMap[sensorId] = user;
return OHOS::Sensors::SUCCESS;
}
int32_t UnsubscribeSensor(int32_t sensorId, const MedicalSensorUser *user)
{
HiLog::Info(LABEL, "%{public}s in, sensorId: %{public}d", __func__, sensorId);
if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
return OHOS::Sensors::ERROR;
}
std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
if (g_unsubscribeMap.find(sensorId) == g_unsubscribeMap.end() || g_unsubscribeMap[sensorId] != user) {
HiLog::Error(LABEL, "%{public}s deactivate sensorId first", __func__);
return OHOS::Sensors::ERROR;
}
if (g_subscribeMap.empty()) {
int32_t ret = DestroyAfeDataChannel();
if (ret != SUCCESS) {
HiLog::Error(LABEL, "%{public}s destory data channel fail, ret : %{public}d", __func__, ret);
return ret;
}
}
g_unsubscribeMap.erase(sensorId);
return OHOS::Sensors::SUCCESS;
}
int32_t SetMode(int32_t sensorId, const MedicalSensorUser *user, int32_t mode)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
return OHOS::Sensors::ERROR;
}
std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) {
HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
return OHOS::Sensors::ERROR;
}
return OHOS::Sensors::SUCCESS;
}
int32_t SetOption(int32_t sensorId, const MedicalSensorUser *user, int32_t option)
{
HiLog::Info(LABEL, "%{public}s begin, sensorId: %{public}d, opt: %{public}d", __func__, sensorId, option);
if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
return OHOS::Sensors::ERROR;
}
std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) {
HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
return OHOS::Sensors::ERROR;
}
return OHOS::Sensors::SUCCESS;
}
+50
View File
@@ -0,0 +1,50 @@
# Copyright (c) 2021 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/test.gni")
SUBSYSTEM_DIR = "//base/sensors/medical_sensor"
module_output_path = "sensors/medical_sensor/interfaces"
###########################MedicalNativeTest###########################
ohos_unittest("MedicalNativeTest") {
module_out_path = module_output_path
sources = [ "unittest/medical_native_test.cpp" ]
include_dirs = [
"//utils/native/base/include",
"$SUBSYSTEM_DIR/utils/include",
"$SUBSYSTEM_DIR/interfaces/native/include",
]
deps = [
"$SUBSYSTEM_DIR/interfaces/native:medical_ndk_target",
"$SUBSYSTEM_DIR/utils:libmedical_utils",
"//third_party/googletest:gmock_main",
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
#"communication_L2:ipc_core",
"ipc:ipc_core",
]
}
###########################end###########################
group("unittest") {
testonly = true
deps = [ ":MedicalNativeTest" ]
}
+97
View File
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2021 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 <gtest/gtest.h>
#include <thread>
#include "medical_native_impl.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace testing::ext;
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_TEST, "AfeNativeTest" };
} // namespace
class AfeNativeTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
};
void AfeNativeTest::SetUpTestCase()
{}
void AfeNativeTest::TearDownTestCase()
{}
void AfeNativeTest::SetUp()
{}
void AfeNativeTest::TearDown()
{}
void AfeDataCallbackImpl(SensorEvent *event)
{
if (event == nullptr) {
HiLog::Error(LABEL, "AfeDataCallbackImpl event is null");
return;
}
uint32_t *sensorData = (uint32_t *)(event[0].data);
HiLog::Info(LABEL, "AfeDataCallbackImpl sensorTypeId: %{public}d, dataLen: %{public}d, data[0]: %{public}d\n",
event[0].sensorTypeId, event[0].dataLen, *(sensorData));
}
/*
* @tc.name: AfeNativeApiTest_001
* @tc.desc: afe native api test
* @tc.type: FUNC
* @tc.author: wuzhihui
*/
HWTEST_F(AfeNativeTest, AfeNativeApiTest_001, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
int32_t sensorTypeId = 0;
MedicalSensorUser user;
user.callback = AfeDataCallbackImpl;
int32_t ret = SubscribeSensor(sensorTypeId, &user);
ASSERT_EQ(ret, 0);
ret = SetBatch(sensorTypeId, &user, 100000000, 100000000);
ASSERT_EQ(ret, 0);
ret = ActivateSensor(sensorTypeId, &user);
ASSERT_EQ(ret, 0);
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
ASSERT_EQ(ret, 0);
ret = DeactivateSensor(sensorTypeId, &user);
ASSERT_EQ(ret, 0);
ret = UnsubscribeSensor(sensorTypeId, &user);
ASSERT_EQ(ret, 0);
}
} // namespace Sensors
} // namespace OHOS
+46
View File
@@ -0,0 +1,46 @@
# Copyright (c) 2021 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/ohos/rules.gni")
import("//build/ohos.gni")
ohos_shared_library("medical") {
include_dirs = [
"//third_party/node/src",
"//native_engine",
"../native/include",
"//third_party/libuv/include",
"//utils/native/base/include",
"./include",
]
defines = [
"APP_LOG_TAG = \"medicalJs\"",
"LOG_DOMAIN = 0xD002701",
]
sources = [
"./src/medical_js.cpp",
"./src/medical_napi_utils.cpp",
]
deps = [
"../native:medical_interface_native",
"//foundation/ace/napi:ace_napi",
"//utils/native/base:utils",
]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
relative_install_dir = "module"
part_name = "medical_sensor"
subsystem_name = "sensors"
}
group("medical_js_target") {
deps = [ ":medical" ]
}
+19
View File
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2021 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 "medical_native_impl.h"
static int32_t UnsubscribeSensor(int32_t sensorTypeId);
static void DataCallbackImpl(SensorEvent *event);
static int32_t SubscribeSensor(int32_t sensorTypeId, int64_t interval, const MedicalSensorUser *user);
+44
View File
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2021 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 "napi/native_api.h"
#include "napi/native_node_api.h"
#include <uv.h>
#include "medical_native_impl.h"
#include <iostream>
#define EVENT_INVALID_PARAMETER (-1);
#define EVENT_OK 0;
#define PPG_MAX_DATA_LEN 128
struct AsyncCallbackInfo {
napi_env env;
napi_async_work asyncWork;
napi_deferred deferred;
napi_ref callback[1] = { 0 };
int32_t sensorTypeId;
int32_t sensorDataLength;
uint32_t sensorData[PPG_MAX_DATA_LEN];
int32_t status;
};
bool IsMatchType(napi_value value, napi_valuetype type, napi_env env);
napi_value GetNapiInt32(int32_t number, napi_env env);
int32_t GetCppInt32(napi_value value, napi_env env);
bool GetCppBool(napi_value value, napi_env env);
void EmitAsyncCallbackWork(AsyncCallbackInfo *async_callback_info);
void EmitUvEventLoop(AsyncCallbackInfo *async_callback_info);
int64_t GetCppInt64(napi_value value, napi_env env);
napi_value NapiGetNamedProperty(napi_value jsonObject, std::string name, napi_env env);
napi_value GetUndefined(napi_env env);
+266
View File
@@ -0,0 +1,266 @@
/*
* Copyright (c) 2021 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 "medical_js.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <pthread.h>
#include <string>
#include <thread>
#include <unistd.h>
#include "hilog/log.h"
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "medical_native_impl.h"
#include "medical_napi_utils.h"
#include "refbase.h"
#include "securec.h"
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0xD002708, "AfeJsAPI"};
static std::map<int32_t, struct AsyncCallbackInfo*> g_onCallbackInfos;
static void DataCallbackImpl(SensorEvent *event)
{
HiLog::Info(LABEL, "%{public}s in", __func__);
if (event == nullptr) {
HiLog::Error(LABEL, "%{public}s event is null!", __func__);
return;
}
int32_t sensorTypeId = event->sensorTypeId;
uint32_t *data = (uint32_t *)(event->data);
uint32_t maxDataLen = PPG_MAX_DATA_LEN * sizeof(uint32_t);
uint32_t dataLen = (event->dataLen > maxDataLen) ? maxDataLen : event->dataLen;
// check sensorType
if (g_onCallbackInfos.find(sensorTypeId) == g_onCallbackInfos.end()) {
HiLog::Debug(LABEL, "%{public}s no subscribe to the sensor data on", __func__);
return;
}
struct AsyncCallbackInfo *onCallbackInfo = g_onCallbackInfos[sensorTypeId];
onCallbackInfo->sensorTypeId = sensorTypeId;
onCallbackInfo->sensorDataLength = dataLen / sizeof(uint32_t);
if (memcpy_s(onCallbackInfo->sensorData, dataLen, data, dataLen) != EOK) {
HiLog::Error(LABEL, "%{public}s copy data failed", __func__);
return;
}
onCallbackInfo->status = 1;
EmitUvEventLoop((struct AsyncCallbackInfo *)(onCallbackInfo));
HiLog::Info(LABEL, "%{public}s end", __func__);
}
static const MedicalSensorUser user = {
.callback = DataCallbackImpl
};
static int32_t UnsubscribeSensor(int32_t sensorTypeId)
{
HiLog::Info(LABEL, "%{public}s in", __func__);
int32_t ret = DeactivateSensor(sensorTypeId, &user);
if (ret < 0) {
HiLog::Error(LABEL, "%{public}s DeactivateSensor failed", __func__);
return ret;
}
ret = UnsubscribeSensor(sensorTypeId, &user);
if (ret < 0) {
HiLog::Error(LABEL, "%{public}s UnsubscribeSensor failed", __func__);
return ret;
}
HiLog::Info(LABEL, "%{public}s left", __func__);
return 0;
}
static int32_t SubscribeSensor(int32_t sensorTypeId, int64_t interval, const MedicalSensorUser *user)
{
HiLog::Info(LABEL, "%{public}s in, sensorTypeId: %{public}d", __func__, sensorTypeId);
int32_t ret = SubscribeSensor(sensorTypeId, user);
if (ret < 0) {
HiLog::Error(LABEL, "%{public}s subscribeSensor failed", __func__);
return ret;
}
ret = SetBatch(sensorTypeId, user, interval, 0);
if (ret < 0) {
HiLog::Error(LABEL, "%{public}s set batch failed", __func__);
return ret;
}
ret = ActivateSensor(sensorTypeId, user);
if (ret < 0) {
HiLog::Error(LABEL, "%{public}s activateSensor failed", __func__);
return ret;
}
return 0;
}
static napi_value On(napi_env env, napi_callback_info info)
{
HiLog::Info(LABEL, "%{public}s in", __func__);
size_t argc = 3;
napi_value args[3];
napi_value thisVar;
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, NULL));
if (argc <= 1 || argc > 3) {
HiLog::Error(LABEL, "%{public}s the number of input parameters does not match", __func__);
return nullptr;
}
if (!IsMatchType(args[0], napi_number, env)) {
HiLog::Error(LABEL, "%{public}s the first parameter should be napi_number type", __func__);
return nullptr;
}
int32_t sensorTypeId = GetCppInt32(args[0], env);
if (!IsMatchType(args[1], napi_function, env)) {
HiLog::Error(LABEL, "%{public}s the second parameter should be napi_function type!", __func__);
return nullptr;
}
int64_t interval = 200000000;
if (argc == 3) {
HiLog::Info(LABEL, "%{public}s argc = 3!", __func__);
napi_value value = NapiGetNamedProperty(args[2], "interval", env);
if (!IsMatchType(value, napi_number, env)) {
HiLog::Error(LABEL, "%{public}s argument should be napi_number type!", __func__);
return nullptr;
}
interval = GetCppInt64(value, env);
}
AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo {
.env = env,
.asyncWork = nullptr,
.deferred = nullptr,
};
napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]);
g_onCallbackInfos[sensorTypeId] = asyncCallbackInfo;
int32_t ret = SubscribeSensor(sensorTypeId, interval, &user);
if (ret < 0) {
HiLog::Error(LABEL, "%{public}s subscribeSensor failed", __func__);
asyncCallbackInfo->status = -1;
EmitAsyncCallbackWork(asyncCallbackInfo);
g_onCallbackInfos.erase(sensorTypeId);
return nullptr;
}
HiLog::Info(LABEL, "%{public}s out", __func__);
return nullptr;
}
static napi_value Off(napi_env env, napi_callback_info info)
{
HiLog::Info(LABEL, "%{public}s in", __func__);
size_t argc = 2;
napi_value args[2];
napi_value thisVar;
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, NULL));
if (argc < 1) {
HiLog::Error(LABEL, "%{public}s Invalid input.", __func__);
return nullptr;
}
if (!IsMatchType(args[0], napi_number, env)) {
HiLog::Error(LABEL, "%{public}s argument should be number type!", __func__);
return nullptr;
}
int32_t sensorTypeId = GetCppInt32(args[0], env);
if (!IsMatchType(args[1], napi_function, env)) {
HiLog::Error(LABEL, "%{public}s argument should be function type!", __func__);
return nullptr;
}
AsyncCallbackInfo *asyncCallbackInfo = new AsyncCallbackInfo {
.env = env,
.asyncWork = nullptr,
.deferred = nullptr,
};
napi_create_reference(env, args[1], 1, &asyncCallbackInfo->callback[0]);
int32_t ret = UnsubscribeSensor(sensorTypeId);
if (ret < 0) {
asyncCallbackInfo->status = -1;
HiLog::Error(LABEL, "%{public}s UnsubscribeSensor failed", __func__);
} else {
HiLog::Error(LABEL, "%{public}s UnsubscribeSensor success", __func__);
asyncCallbackInfo->status = 0;
if (g_onCallbackInfos.find(sensorTypeId) != g_onCallbackInfos.end()) {
napi_delete_reference(env, g_onCallbackInfos[sensorTypeId]->callback[0]);
delete g_onCallbackInfos[sensorTypeId];
g_onCallbackInfos[sensorTypeId] = nullptr;
g_onCallbackInfos.erase(sensorTypeId);
}
}
EmitAsyncCallbackWork(asyncCallbackInfo);
HiLog::Info(LABEL, "%{public}s left", __func__);
return nullptr;
}
static napi_value SetOpt(napi_env env, napi_callback_info info)
{
HiLog::Info(LABEL, "%{public}s in", __func__);
size_t argc = 2;
napi_value args[2];
napi_value thisVar;
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, NULL));
if (argc < 1) {
HiLog::Error(LABEL, "%{public}s Invalid input.", __func__);
return nullptr;
}
if (!IsMatchType(args[0], napi_number, env)) {
HiLog::Error(LABEL, "%{public}s argument should be number type!", __func__);
return nullptr;
}
int32_t sensorTypeId = GetCppInt32(args[0], env);
if (!IsMatchType(args[1], napi_number, env)) {
HiLog::Error(LABEL, "%{public}s argument should be function type!", __func__);
return nullptr;
}
int32_t opt = GetCppInt32(args[1], env);
int32_t ret = SetOption(sensorTypeId, &user, opt);
if (ret < 0) {
HiLog::Error(LABEL, "%{public}s SetOption failed", __func__);
} else {
HiLog::Error(LABEL, "%{public}s SetOption success", __func__);
}
HiLog::Info(LABEL, "%{public}s left", __func__);
return nullptr;
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("on", On),
DECLARE_NAPI_FUNCTION("setOpt", SetOpt),
DECLARE_NAPI_FUNCTION("off", Off)
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc));
return exports;
}
EXTERN_C_END
static napi_module _module = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = NULL,
.nm_register_func = Init,
.nm_modname = "medical",
.nm_priv = ((void *)0),
.reserved = {0}
};
extern "C" __attribute__((constructor)) void RegisterModule(void)
{
napi_module_register(&_module);
}
+204
View File
@@ -0,0 +1,204 @@
/*
* Copyright (c) 2021 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 "medical_napi_utils.h"
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include "hilog/log.h"
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0xD002708, "AfeJsAPI"};
bool IsMatchType(napi_value value, napi_valuetype type, napi_env env)
{
napi_valuetype paramType;
napi_typeof(env, value, &paramType);
if (paramType != type) {
HiLog::Error(LABEL, "%{public}s failed!", __func__);
return false;
}
return true;
}
napi_value GetNapiInt32(int32_t number, napi_env env)
{
napi_value value;
napi_create_int32(env, number, &value);
return value;
}
napi_value NapiGetNamedProperty(napi_value jsonObject, std::string name, napi_env env)
{
napi_value value;
napi_get_named_property(env, jsonObject, name.c_str(), &value);
return value;
}
int32_t GetCppInt32(napi_value value, napi_env env)
{
int32_t number;
napi_get_value_int32(env, value, &number);
return number;
}
int64_t GetCppInt64(napi_value value, napi_env env)
{
int64_t number;
napi_get_value_int64(env, value, &number);
return number;
}
bool GetCppBool(napi_value value, napi_env env)
{
bool number;
napi_get_value_bool(env, value, &number);
return number;
}
napi_value GetUndefined(napi_env env)
{
napi_value value;
napi_get_undefined(env, &value);
return value;
}
std::map<int32_t, std::vector<std::string>> g_sensorAttributeList = {
{ AFE_TYPE_ID_NONE, { "dataArray" } },
{ AFE_TYPE_ID_PHOTOPLETHYSMOGRAPH, { "dataArray" } },
};
void EmitAsyncCallbackWork(AsyncCallbackInfo *asyncCallbackInfo)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (asyncCallbackInfo == nullptr) {
HiLog::Error(LABEL, "%{public}s asyncCallbackInfo is null!", __func__);
return;
}
napi_value resourceName;
if (napi_create_string_utf8(asyncCallbackInfo->env, "AsyncCallback", NAPI_AUTO_LENGTH, &resourceName) != napi_ok) {
HiLog::Error(LABEL, "%{public}s create string utf8 failed", __func__);
return;
}
napi_create_async_work(
asyncCallbackInfo->env, nullptr, resourceName,
[](napi_env env, void* data) {},
[](napi_env env, napi_status status, void* data) {
HiLog::Debug(LABEL, "%{public}s napi_create_async_work in", __func__);
AsyncCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncCallbackInfo *>(data);
napi_value callback;
napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback);
napi_value callResult = nullptr;
napi_value result[2] = {0};
if (asyncCallbackInfo->status < 0) {
HiLog::Debug(LABEL, "%{public}s napi_create_async_work < 0 in", __func__);
napi_value code = nullptr;
napi_value message = nullptr;
napi_create_string_utf8(env, "-1", NAPI_AUTO_LENGTH, &code);
napi_create_string_utf8(env, "failed", NAPI_AUTO_LENGTH, &message);
napi_create_error(env, code, message, &result[0]);
napi_get_undefined(env, &result[1]);
} else if (asyncCallbackInfo->status == 0) {
napi_get_undefined(env, &result[1]);
napi_get_undefined(env, &result[0]);
}
napi_call_function(env, nullptr, callback, 2, result, &callResult);
napi_delete_reference(env, asyncCallbackInfo->callback[0]);
napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
delete asyncCallbackInfo;
asyncCallbackInfo = nullptr;
HiLog::Debug(LABEL, "%{public}s napi_create_async_work left", __func__);
},
asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
napi_queue_async_work(asyncCallbackInfo->env, asyncCallbackInfo->asyncWork);
HiLog::Debug(LABEL, "%{public}s end", __func__);
}
void EmitUvEventLoop(AsyncCallbackInfo *asyncCallbackInfo)
{
uv_loop_s *loop(nullptr);
HiLog::Debug(LABEL, "%{public}s env: %{public}p", __func__, asyncCallbackInfo->env);
napi_get_uv_event_loop(asyncCallbackInfo->env, &loop);
if (loop == nullptr) {
HiLog::Error(LABEL, "%{public}s loop is null", __func__);
return;
}
uv_work_t *work = new(std::nothrow) uv_work_t;
if (work == nullptr) {
HiLog::Error(LABEL, "%{public}s work is null", __func__);
return;
}
work->data = reinterpret_cast<void *>(asyncCallbackInfo);
uv_queue_work(loop, work, [] (uv_work_t *work) {}, [] (uv_work_t *work, int status) {
AsyncCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncCallbackInfo *>(work->data);
if (asyncCallbackInfo == nullptr) {
HiLog::Error(LABEL, "%{public}s asyncCallbackInfo is null", __func__);
return;
}
napi_env env = asyncCallbackInfo->env;
napi_value undefined;
napi_get_undefined(env, &undefined);
if (asyncCallbackInfo->callback[0] == nullptr) {
HiLog::Error(LABEL, "%{public}s callback is null", __func__);
return;
}
napi_value callback;
napi_get_reference_value(env, asyncCallbackInfo->callback[0], &callback);
napi_value callResult = nullptr;
napi_value result[2] = {0};
if (asyncCallbackInfo->status < 0) {
HiLog::Debug(LABEL, "%{public}s status < 0 in", __func__);
napi_value code = nullptr;
napi_value message = nullptr;
napi_create_string_utf8(env, "-1", NAPI_AUTO_LENGTH, &code);
napi_create_string_utf8(env, "failed", NAPI_AUTO_LENGTH, &message);
napi_create_error(env, code, message, &result[0]);
napi_get_undefined(env, &result[1]);
} else {
int32_t sensorTypeId = asyncCallbackInfo->sensorTypeId;
if (g_sensorAttributeList.count(sensorTypeId) == 0) {
HiLog::Error(LABEL, "%{public}s count of sensorTypeId is zero", __func__);
return;
}
std::vector<std::string> sensorAttribute = g_sensorAttributeList[sensorTypeId];
napi_create_object(env, &result[1]);
for (size_t i = 0; i < sensorAttribute.size(); i++) {
napi_value message = nullptr;
napi_create_array(env, &message);
for (size_t j = 0; j < asyncCallbackInfo->sensorDataLength; j++) {
napi_value num;
napi_create_uint32(env, asyncCallbackInfo->sensorData[j], &num);
napi_set_element(env, message, j, num);
}
napi_set_named_property(env, result[1], sensorAttribute[i].c_str(), message);
HiLog::Error(LABEL, "%{public}s sensorData[0]=%{public}d", __func__, *(uint32_t *)message);
}
napi_get_undefined(env, &result[0]);
}
napi_call_function(env, undefined, callback, 2, result, &callResult);
if (asyncCallbackInfo->status != 1) {
napi_delete_reference(env, asyncCallbackInfo->callback[0]);
delete asyncCallbackInfo;
asyncCallbackInfo = nullptr;
}
delete work;
work = nullptr;
});
}
+59
View File
@@ -0,0 +1,59 @@
# Copyright (c) 2021 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/ohos/rules.gni")
import("//build/ohos.gni")
import("//build/test.gni")
SUBSYSTEM_DIR = "//base/sensors/medical_sensor"
module_output_path = "sensors/medical_sensor/interfaces"
ohos_unittest("MedicalJsTest") {
module_out_path = module_output_path
include_dirs = [
"//third_party/node/src",
"//native_engine",
"$SUBSYSTEM_DIR/interfaces/native/include",
"$SUBSYSTEM_DIR/interfaces/plugin/include",
"//utils/native/base/include",
"./include",
"//third_party/libuv/include",
"//foundation/ace/napi",
"//foundation/ace/napi/interfaces/kits",
"//foundation/ace/napi/native_engine",
"//foundation/ace/napi/native_engine/impl/quickjs",
]
defines = [
"APP_LOG_TAG = \"medicalJs\"",
"LOG_DOMAIN = 0xD002700",
]
sources = [ "medical_js_test.cpp" ]
deps = [
"$SUBSYSTEM_DIR/interfaces/native:medical_interface_native",
"$SUBSYSTEM_DIR/interfaces/plugin:medical",
"//foundation/ace/napi:ace_napi",
"//foundation/ace/napi/:ace_napi_quickjs",
"//third_party/googletest:gtest",
"//third_party/googletest:gtest_main",
"//third_party/libuv:uv_static",
"//third_party/quickjs:qjs",
"//utils/native/base:utils",
]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
relative_install_dir = "module"
part_name = "medical_sensor"
subsystem_name = "sensors"
}
group("unittest") {
testonly = true
deps = [ ":MedicalJsTest" ]
}
+595
View File
@@ -0,0 +1,595 @@
/*
* Copyright (c) 2021 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 <gtest/gtest.h>
#include <thread>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "medical_napi_utils.h"
#include "medical_native_impl.h"
#include "native_engine.h"
#include "quickjs_native_engine.h"
#include "hilog/log.h"
namespace OHOS {
namespace Sensors {
using namespace testing::ext;
using namespace OHOS::HiviewDFX;
static NativeEngine* g_nativeEngine = nullptr;
namespace {
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0xD002708, "AfeJsTest"};
}
class AfeJsTest : public testing::Test {
public:
void SetUp();
void TearDown();
AfeJsTest();
virtual ~AfeJsTest();
protected:
NativeEngine* engine_;
};
void AfeJsTest::SetUp()
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
}
void AfeJsTest::TearDown()
{
HiLog::Info(LABEL, "%{public}s end", __func__);
}
AfeJsTest::AfeJsTest()
{
JSRuntime* rt = JS_NewRuntime();
if (rt == nullptr) {
return ;
}
JSContext* ctx = JS_NewContext(rt);
if (ctx == nullptr) {
return ;
}
js_std_add_helpers(ctx, 0, nullptr);
g_nativeEngine = new QuickJSNativeEngine(rt, ctx, 0); // default instance id 0
engine_ = g_nativeEngine;
}
AfeJsTest::~AfeJsTest() {
delete g_nativeEngine;
g_nativeEngine = nullptr;
}
/*
* @tc.name: IsMatchType_001
* @tc.desc: Match napi_number
* @tc.type: FUNC
* @tc.require:SR000G54IU
*/
HWTEST_F(AfeJsTest, IsMatchType_001, TestSize.Level1)
{
napi_env env = (napi_env)engine_;
uint32_t cppValue = UINT32_MAX;
napi_value napiValue = nullptr;
napi_create_uint32(env, cppValue, &napiValue);
bool ret = IsMatchType(napiValue, napi_number, env);
ASSERT_EQ(ret, true);
}
/*
* @tc.name: IsMatchType_002
* @tc.desc: Match napi_string
* @tc.type: FUNC
* @tc.require:AR000G54IV
*/
HWTEST_F(AfeJsTest, IsMatchType_002, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
const char cppValue[] = "中文,English,123456,!@#";
size_t cppValueStrLength = strlen(cppValue);
napi_value napiValue = nullptr;
napi_create_string_utf8(env, cppValue, cppValueStrLength, &napiValue);
// call function
bool ret = IsMatchType(napiValue, napi_string, env);
ASSERT_EQ(ret, true);
}
/*
* @tc.name: IsMatchType_003
* @tc.desc: Match napi_symbol
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, IsMatchType_003, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
const char testStr[] = "testSymbol";
napi_value result = nullptr;
napi_create_string_latin1(env, testStr, strlen(testStr), &result);
napi_value symbolVal = nullptr;
napi_create_symbol(env, result, &symbolVal);
// call function
bool ret = IsMatchType(symbolVal, napi_symbol, env);
ASSERT_EQ(ret, true);
}
/*
* @tc.name: IsMatchType_004
* @tc.desc: Match napi_function
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, IsMatchType_004, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
const char* tetScriptStr = "new Date();";
napi_value testScript = nullptr;
napi_create_string_utf8(env, tetScriptStr, strlen(tetScriptStr), &testScript);
napi_value date = nullptr;
napi_run_script(env, testScript, &date);
napi_value getTimeFunc = nullptr;
napi_get_named_property(env, date, "getTime", &getTimeFunc);
// call function
bool ret = IsMatchType(getTimeFunc, napi_function, env);
ASSERT_EQ(ret, true);
}
/*
* @tc.name: IsMatchType_005
* @tc.desc: Match napi_boolean
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, IsMatchType_005, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
napi_value result = nullptr;
napi_get_boolean(env, true, &result);
// call function
bool ret = IsMatchType(result, napi_boolean, env);
ASSERT_EQ(ret, true);
}
/*
* @tc.name: GetNapiInt32_001
* @tc.desc: change int32_t[INT32_MAX] to napi_value
* @tc.type: FUNC
* @tc.require: SR000FU58Q
*/
HWTEST_F(AfeJsTest, GetNapiInt32_001, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int32_t number = INT32_MAX;
// call function
napi_value value = GetNapiInt32(number, env);
napi_valuetype ret;
napi_typeof(env, value, &ret);
ASSERT_EQ(ret, napi_number);
}
/*
* @tc.name: GetNapiInt32_002
* @tc.desc: change int32_t[INT32_MIN] to napi_value
* @tc.type: FUNC
* @tc.require: AR000FU73V
*/
HWTEST_F(AfeJsTest, GetNapiInt32_002, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int32_t number = INT32_MIN;
// call function
napi_value value = GetNapiInt32(number, env);
napi_valuetype ret;
napi_typeof(env, value, &ret);
ASSERT_EQ(ret, napi_number);
}
/*
* @tc.name: GetNapiInt32_003
* @tc.desc: change int32_t[true] to napi_value
* @tc.type: FUNC
* @tc.require: AR000FU73V
*/
HWTEST_F(AfeJsTest, GetNapiInt32_003, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int32_t number = (int32_t)true;
// call function
napi_value value = GetNapiInt32(number, env);
napi_valuetype ret;
napi_typeof(env, value, &ret);
ASSERT_EQ(ret, napi_number);
}
/*
* @tc.name: GetNapiInt32_004
* @tc.desc: change int32_t[true] to napi_value
* @tc.type: FUNC
* @tc.require: AR000FU73V
*/
HWTEST_F(AfeJsTest, GetNapiInt32_004, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int32_t number = (int32_t)false;
// call function
napi_value value = GetNapiInt32(number, env);
napi_valuetype ret;
napi_typeof(env, value, &ret);
ASSERT_EQ(ret, napi_number);
}
/*
* @tc.name: GetNapiInt32_005
* @tc.desc: change int32_t[char] to napi_value
* @tc.type: FUNC
* @tc.require: AR000FU73V
*/
HWTEST_F(AfeJsTest, GetNapiInt32_005, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int32_t number = (int32_t)'a';
// call function
napi_value value = GetNapiInt32(number, env);
napi_valuetype ret;
napi_typeof(env, value, &ret);
ASSERT_EQ(ret, napi_number);
}
/*
* @tc.name: NapiGetNamedProperty_001
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000FU73V
*/
HWTEST_F(AfeJsTest, NapiGetNamedProperty_001, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
const char* tetScriptStr = "new Date();";
napi_value testScript = nullptr;
napi_create_string_utf8(env, tetScriptStr, strlen(tetScriptStr), &testScript);
napi_value date = nullptr;
napi_run_script(env, testScript, &date);
// call function
napi_value value = NapiGetNamedProperty(date, "getTime", env);
napi_valuetype ret;
napi_typeof(env, value, &ret);
ASSERT_EQ(ret, napi_function);
}
/*
* @tc.name: NapiGetNamedProperty_002
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000FU73V
*/
HWTEST_F(AfeJsTest, NapiGetNamedProperty_002, TestSize.Level1)
{
// 定义变量 赋值
napi_env env = (napi_env)engine_;
int32_t status=101;
napi_value message;
napi_create_int32(env, status, &message);
// 定义变量为对象
napi_value result;
napi_create_object(env, &result);
// 赋值给object
napi_set_named_property(env, result, "code", message);
napi_value value = NapiGetNamedProperty(result, "code", env);
napi_valuetype ret;
napi_typeof(env, value, &ret);
ASSERT_EQ(ret, napi_number);
}
/*
* @tc.name: NapiGetNamedProperty_003
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000FU73V
*/
HWTEST_F(AfeJsTest, NapiGetNamedProperty_003, TestSize.Level1)
{
// 定义变量 赋值
napi_env env = (napi_env)engine_;
const char status[] = "type001";
napi_value message;
napi_create_string_utf8(env, status, strlen(status), &message);
// 定义变量为对象
napi_value result;
napi_create_object(env, &result);
// 赋值给object
napi_set_named_property(env, result, "code", message);
napi_value value = NapiGetNamedProperty(result, "code", env);
napi_valuetype ret;
napi_typeof(env, value, &ret);
ASSERT_EQ(ret, napi_string);
}
/*
* @tc.name: NapiGetNamedProperty_004
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, NapiGetNamedProperty_004, TestSize.Level1)
{
// 定义变量 赋值
napi_env env = (napi_env)engine_;
napi_value message;
napi_get_boolean(env, true, &message);
// 定义变量为对象
napi_value result;
napi_create_object(env, &result);
// 赋值给object
napi_set_named_property(env, result, "code", message);
napi_value value = NapiGetNamedProperty(result, "code", env);
napi_valuetype ret;
napi_typeof(env, value, &ret);
ASSERT_EQ(ret, napi_boolean);
}
/*
* @tc.name: NapiGetNamedProperty_005
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, NapiGetNamedProperty_005, TestSize.Level1)
{
// 定义变量 赋值
napi_env env = (napi_env)engine_;
const char testStr[] = "testSymbol";
napi_value resultSymbol = nullptr;
napi_create_string_latin1(env, testStr, strlen(testStr), &resultSymbol);
napi_value message = nullptr;
napi_create_symbol(env, resultSymbol, &message);
// 定义变量为对象
napi_value result;
napi_create_object(env, &result);
// 赋值给object
napi_set_named_property(env, result, "code", message);
napi_value value = NapiGetNamedProperty(result, "code", env);
napi_valuetype ret;
napi_typeof(env, value, &ret);
ASSERT_EQ(ret, napi_symbol);
}
/*
* @tc.name: GetCppInt32_001
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, GetCppInt32_001, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int32_t number = INT32_MAX;
napi_value value;
napi_create_int32(env, number, &value);
// call function
int32_t ret = GetCppInt32(value, env);
ASSERT_EQ(ret, (int32_t)INT32_MAX);
}
/*
* @tc.name: GetCppInt32_002
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, GetCppInt32_002, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int32_t number = INT32_MIN;
napi_value value;
napi_create_int32(env, number, &value);
// call function
int32_t ret = GetCppInt32(value, env);
ASSERT_EQ(ret, (int32_t)INT32_MIN);
}
/*
* @tc.name: GetCppInt32_003
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, GetCppInt32_003, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int32_t number = (int32_t)true;
napi_value value;
napi_create_int32(env, number, &value);
// call function
int32_t ret = GetCppInt32(value, env);
ASSERT_EQ(ret, (int32_t)true);
}
/*
* @tc.name: GetCppInt32_004
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, GetCppInt32_004, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int32_t number = (int32_t)false;
napi_value value;
napi_create_int32(env, number, &value);
// call function
int32_t ret = GetCppInt32(value, env);
ASSERT_EQ(ret, (int32_t)false);
}
/*
* @tc.name: GetCppInt32_005
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, GetCppInt32_005, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int32_t number = (int32_t)'b';
napi_value value;
napi_create_int32(env, number, &value);
// call function
int32_t ret = GetCppInt32(value, env);
ASSERT_EQ(ret, (int32_t)'b');
}
/*
* @tc.name: GetCppInt64_001
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, GetCppInt64_001, TestSize.Level1)
{
// Construction parameters
int64_t tmpInt64Max = 9007199254740991;//9223372036854775807;9007199254740992
napi_env env = (napi_env)engine_;
int64_t number = tmpInt64Max;//(int64_t)INT64_MAX;
napi_value value;
napi_create_int64(env, number, &value);
// call function
int64_t ret = GetCppInt64(value, env);
ASSERT_EQ(ret, tmpInt64Max);
}
/*
* @tc.name: GetCppInt64_002
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, GetCppInt64_002, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int64_t number = (int64_t)INT64_MIN;
napi_value value;
napi_create_int64(env, number, &value);
// call function
int64_t ret = GetCppInt64(value, env);
ASSERT_EQ(ret, (int64_t)INT64_MIN);
}
/*
* @tc.name: GetCppInt64_003
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, GetCppInt64_003, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int64_t number = (int64_t)true;
napi_value value;
napi_create_int64(env, number, &value);
// call function
int64_t ret = GetCppInt64(value, env);
ASSERT_EQ(ret, (int64_t)true);
}
/*
* @tc.name: GetCppInt64_004
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, GetCppInt64_004, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int64_t number = (int64_t)false;
napi_value value;
napi_create_int64(env, number, &value);
// call function
int64_t ret = GetCppInt64(value, env);
ASSERT_EQ(ret, (int64_t)false);
}
/*
* @tc.name: GetCppInt64_005
* @tc.desc: Parse function in Json
* @tc.type: FUNC
* @tc.require: AR000G54IV
*/
HWTEST_F(AfeJsTest, GetCppInt64_005, TestSize.Level1)
{
// Construction parameters
napi_env env = (napi_env)engine_;
int64_t number = (int64_t)'c';
napi_value value;
napi_create_int64(env, number, &value);
// call function
int64_t ret = GetCppInt64(value, env);
ASSERT_EQ(ret, (int64_t)'c');
}
} // namespace Sensors
} // namespace OHOS
Executable
+37
View File
@@ -0,0 +1,37 @@
{
"subsystem": "sensors",
"parts": {
"medical_sensor": {
"variants": [
"phone",
"wearable"
],
"module_list": [
"//base/sensors/medical_sensor/interfaces/native:medical_ndk_target",
"//base/sensors/medical_sensor/interfaces/plugin:medical_js_target",
"//base/sensors/medical_sensor/frameworks/native/medical_sensor:medical_native_target",
"//base/sensors/medical_sensor/services/medical_sensor:medical_service_target",
"//base/sensors/medical_sensor/utils:medical_utils_target",
"//base/sensors/medical_sensor/sa_profile:medical_sa_profiles"
],
"inner_kits": [
{
"header": {
"header_files": [
"medical_native_type.h",
"medical_native_impl.h"
],
"header_base": "//base/sensors/medical_sensor/interfaces/native/include"
},
"name": "//base/sensors/medical_sensor/interfaces/native:medical_interface_native"
}
],
"test_list": [
"//base/sensors/medical_sensor/frameworks/native/medical_sensor/test:unittest",
"//base/sensors/medical_sensor/interfaces/native/test:unittest",
"//base/sensors/medical_sensor/interfaces/plugin/test/unittest:unittest",
"//base/sensors/medical_sensor/services/medical_sensor/test:unittest"
]
}
}
}
Executable
View File
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2021 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.
-->
<info>
<process>hsensors</process>
<systemability>
<name>3605</name>
<libpath>libmedical_service.z.so</libpath>
<run-on-create>true</run-on-create>
<distributed>false</distributed>
<dump-level>1</dump-level>
</systemability>
</info>
+19
View File
@@ -0,0 +1,19 @@
# Copyright (c) 2021 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/ohos/sa_profile/sa_profile.gni")
ohos_sa_profile("medical_sa_profiles") {
sources = [ "3605.xml" ]
part_name = "medical_sensor"
}
+67
View File
@@ -0,0 +1,67 @@
# Copyright (c) 2021 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/ohos.gni")
SUBSYSTEM_DIR = "//base/sensors/medical_sensor"
ohos_shared_library("libmedical_service") {
sources = [
"src/client_info.cpp",
"src/fifo_cache_data.cpp",
"src/flush_info_record.cpp",
"src/medical_data_processer.cpp",
"src/medical_dump.cpp",
"src/medical_manager.cpp",
"src/medical_service.cpp",
"src/medical_service_impl.cpp",
"src/medical_service_stub.cpp",
]
include_dirs = [
"include",
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor/include",
"$SUBSYSTEM_DIR/interfaces/native/include",
"//utils/native/base/include",
"//utils/system/safwk/native/include",
"$SUBSYSTEM_DIR/utils/include",
"$SUBSYSTEM_DIR/services/medical_sensor/include",
"//drivers/peripheral/sensor/interfaces/include",
]
cflags = [ "-Wno-error=inconsistent-missing-override" ]
deps = [
"$SUBSYSTEM_DIR/utils:libmedical_utils",
"//drivers/peripheral/sensor/hal:hdi_sensor",
"//utils/native/base:utils",
]
external_deps = [
"aafwk_standard:base",
"aafwk_standard:intent",
"appexecfwk_standard:appexecfwk_base",
"appexecfwk_standard:appexecfwk_core",
"hisysevent_native:libhisysevent",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"permission_standard:libpermissionsdk_standard",
"safwk:system_ability_fwk",
"samgr_standard:samgr_proxy",
]
part_name = "medical_sensor"
subsystem_name = "sensors"
}
group("medical_service_target") {
deps = [ ":libmedical_service" ]
}
+95
View File
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2021 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 CLIENT_INFO_H
#define CLIENT_INFO_H
#include <map>
#include <queue>
#include <unordered_map>
#include <vector>
#include "refbase.h"
#include "singleton.h"
#include "permission_util.h"
#include "iremote_object.h"
#include "nocopyable.h"
#include "medical_basic_data_channel.h"
#include "medical_basic_info.h"
#include "medical_channel_info.h"
#include "medical_native_type.h"
namespace OHOS {
namespace Sensors {
class ClientInfo : public Singleton<ClientInfo> {
public:
ClientInfo() = default;
virtual ~ClientInfo() = default;
MedicalSensorState GetSensorState(uint32_t sensorId);
MedicalSensorBasicInfo GetBestSensorInfo(uint32_t sensorId);
bool OnlyCurPidSensorEnabled(uint32_t sensorId, int32_t pid);
std::vector<sptr<MedicalSensorBasicDataChannel>> GetSensorChannel(uint32_t sensorId);
std::vector<sptr<MedicalSensorBasicDataChannel>> GetSensorChannelByUid(int32_t uid);
sptr<MedicalSensorBasicDataChannel> GetSensorChannelByPid(int32_t pid);
bool UpdateSensorInfo(uint32_t sensorId, int32_t pid, const MedicalSensorBasicInfo &sensorInfo);
void RemoveSubscriber(uint32_t sensorId, uint32_t pid);
bool UpdateSensorChannel(int32_t pid, const sptr<MedicalSensorBasicDataChannel> &channel);
bool UpdateUid(int32_t pid, int32_t uid);
bool ClearSensorInfo(uint32_t sensorId);
void ClearCurPidSensorInfo(uint32_t sensorId, int32_t pid);
bool DestroySensorChannel(int32_t pid);
bool DestroyUid(int32_t pid);
MedicalSensorBasicInfo GetCurPidSensorInfo(uint32_t sensorId, int32_t pid);
uint64_t ComputeBestPeriodCount(uint32_t sensorId, sptr<MedicalSensorBasicDataChannel> &channel);
uint64_t ComputeBestFifoCount(uint32_t sensorId, sptr<MedicalSensorBasicDataChannel> &channel);
int32_t GetStoreEvent(int32_t sensorId, struct SensorEvent &event);
void StoreEvent(const struct SensorEvent &event);
void ClearEvent();
MedicalThreadInfo GetAppInfoByChannel(const sptr<MedicalSensorBasicDataChannel> &channel);
bool SaveClientPid(const sptr<IRemoteObject> &sensorClient, int32_t pid);
int32_t FindClientPid(const sptr<IRemoteObject> &sensorClient);
void DestroyClientPid(const sptr<IRemoteObject> &sensorClient);
std::vector<uint32_t> GetSensorIdByPid(int32_t pid);
void GetSensorChannelInfo(std::vector<MedicalSensorChannelInfo> &channelInfo);
void UpdateCmd(uint32_t sensorId, int32_t uid, int32_t cmdType);
void DestroyCmd(int32_t uid);
void UpdateDataQueue(int32_t sensorId, struct SensorEvent &event);
std::unordered_map<uint32_t, std::queue<struct SensorEvent>> GetDataQueue();
void ClearDataQueue(int32_t sensorId);
private:
DISALLOW_COPY_AND_MOVE(ClientInfo);
int32_t GetUidByPid(int32_t pid);
std::vector<int32_t> GetCmdList(uint32_t sensorId, int32_t uid);
std::mutex clientMutex_;
std::mutex channelMutex_;
std::mutex eventMutex_;
std::mutex uidMutex_;
std::mutex clientPidMutex_;
std::mutex cmdMutex_;
std::mutex dataQueueMutex_;
std::unordered_map<uint32_t, std::unordered_map<int32_t, MedicalSensorBasicInfo>> clientMap_;
std::unordered_map<int32_t, sptr<MedicalSensorBasicDataChannel>> channelMap_;
std::unordered_map<int32_t, struct SensorEvent> storedEvent_;
std::unordered_map<int32_t, int32_t> uidMap_;
std::map<sptr<IRemoteObject>, int32_t> clientPidMap_;
std::unordered_map<uint32_t, std::unordered_map<int32_t, std::vector<int32_t>>> cmdMap_;
std::unordered_map<uint32_t, std::queue<struct SensorEvent>> dataQueue_;
};
} // namespace Sensors
} // namespace OHOS
#endif // CLIENT_INFO_H
+49
View File
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2021 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 FIFO_CACHE_DATA_H
#define FIFO_CACHE_DATA_H
#include <vector>
#include "refbase.h"
#include "medical_native_type.h"
#include "medical_basic_data_channel.h"
#include "nocopyable.h"
namespace OHOS {
namespace Sensors {
class FifoCacheData : public RefBase {
public:
FifoCacheData();
virtual ~FifoCacheData();
void SetPeriodCount(uint64_t periodCount);
uint64_t GetPeriodCount() const;
void SetFifoCacheData(const std::vector<struct SensorEvent> &fifoCacheData);
std::vector<struct SensorEvent> GetFifoCacheData() const;
void SetChannel(const sptr<MedicalSensorBasicDataChannel> &channel);
sptr<MedicalSensorBasicDataChannel> GetChannel() const;
void InitFifoCache();
private:
DISALLOW_COPY_AND_MOVE(FifoCacheData);
uint64_t periodCount_;
sptr<MedicalSensorBasicDataChannel> channel_;
std::vector<struct SensorEvent> fifoCacheData_;
};
} // namespace Sensors
} // namespace OHOS
#endif // FIFO_CACHE_DATA_H
+69
View File
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2021 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 FLUSH_INFO_RECORD_H
#define FLUSH_INFO_RECORD_H
#include <mutex>
#include <unordered_map>
#include <vector>
#include "client_info.h"
#include "refbase.h"
#include "medical_basic_data_channel.h"
#include "medical_service_impl.h"
#include "medical_errors.h"
#include "singleton.h"
#include "nocopyable.h"
#include "medical_native_type.h"
namespace OHOS {
namespace Sensors {
struct FlushInfo {
sptr<MedicalSensorBasicDataChannel> flushChannel;
bool flushFromEnable;
FlushInfo(const sptr<MedicalSensorBasicDataChannel> &channel, bool enableFlush)
: flushChannel(channel), flushFromEnable(enableFlush){};
};
class FlushInfoRecord : public Singleton<FlushInfoRecord> {
public:
FlushInfoRecord() = default;
~FlushInfoRecord()
{
flushInfo_.clear();
}
std::unordered_map<uint32_t, std::vector<struct FlushInfo>> GetFlushInfo();
void ClearFlushInfoItem(uint32_t sensorId);
ErrCode SetFlushInfo(uint32_t sensorId, const sptr<MedicalSensorBasicDataChannel> &channel, bool isFirstFlush);
bool IsFlushChannelValid(const std::vector<sptr<MedicalSensorBasicDataChannel>> &currChannelList,
const sptr<MedicalSensorBasicDataChannel> &flushChannel);
int32_t GetFlushChannelIndex(const std::vector<struct FlushInfo> &flushInfoList,
const sptr<MedicalSensorBasicDataChannel> &channel);
ErrCode FlushProcess(const uint32_t sensorId, const uint32_t flag, const int32_t pid, const bool isEnableFlush);
private:
DISALLOW_COPY_AND_MOVE(FlushInfoRecord);
MedicalSensorServiceImpl &sensorServiceImpl_ = MedicalSensorServiceImpl::GetInstance();
ClientInfo &clientInfo_ = ClientInfo::GetInstance();
// sensorId, channel pointer for pending flush.
std::unordered_map<uint32_t, std::vector<struct FlushInfo>> flushInfo_;
std::mutex flushInfoMutex_;
};
} // namespace Sensors
} // namespace OHOS
#endif // FLUSH_INFO_RECORD_H
+68
View File
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2021 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 SENSORS_DATA_PROCESSER_H
#define SENSORS_DATA_PROCESSER_H
#include <unordered_map>
#include <vector>
#include "refbase.h"
#include "client_info.h"
#include "fifo_cache_data.h"
#include "flush_info_record.h"
#include "nocopyable.h"
#include "report_data_cache.h"
#include "medical.h"
#include "medical_log_domain.h"
#include "medical_service_impl.h"
#include "medical_native_type.h"
namespace OHOS {
namespace Sensors {
class MedicalSensorDataProcesser : public RefBase {
public:
explicit MedicalSensorDataProcesser(const std::unordered_map<uint32_t, MedicalSensor> &sensorMap);
virtual ~MedicalSensorDataProcesser();
int32_t ProcessEvents(sptr<ReportDataCache> dataCallback);
int32_t SendEvents(sptr<MedicalSensorBasicDataChannel> &channel, struct SensorEvent &event);
static int DataThread(sptr<MedicalSensorDataProcesser> dataProcesser, sptr<ReportDataCache> dataCache);
int32_t CacheSensorEvent(const struct SensorEvent &event, sptr<MedicalSensorBasicDataChannel> &channel);
private:
DISALLOW_COPY_AND_MOVE(MedicalSensorDataProcesser);
void ReportData(sptr<MedicalSensorBasicDataChannel> &channel, struct SensorEvent &event);
bool ReportNotContinuousData(std::unordered_map<uint32_t, struct SensorEvent> &cacheBuf,
sptr<MedicalSensorBasicDataChannel> &channel, struct SensorEvent &event);
void SendNoneFifoCacheData(std::unordered_map<uint32_t, struct SensorEvent> &cacheBuf,
sptr<MedicalSensorBasicDataChannel> &channel, struct SensorEvent &event, uint64_t periodCount);
void SendFifoCacheData(std::unordered_map<uint32_t, struct SensorEvent> &cacheBuf,
sptr<MedicalSensorBasicDataChannel> &channel, struct SensorEvent &event, uint64_t periodCount,
uint64_t fifoCount);
void SendRawData(std::unordered_map<uint32_t, struct SensorEvent> &cacheBuf, sptr<MedicalSensorBasicDataChannel> channel,
std::vector<struct SensorEvent> event);
void EventFilter(struct CircularEventBuf &eventsBuf);
bool CheckSendDataPermission(sptr<MedicalSensorBasicDataChannel> channel, uint32_t sensorId);
ClientInfo &clientInfo_ = ClientInfo::GetInstance();
FlushInfoRecord &flushInfo_ = FlushInfoRecord::GetInstance();
std::mutex dataCountMutex_;
std::unordered_map<uint32_t, std::vector<sptr<FifoCacheData>>> dataCountMap_;
std::mutex sensorMutex_;
std::unordered_map<uint32_t, MedicalSensor> sensorMap_;
};
} // namespace Sensors
} // namespace OHOS
#endif // endif SENSORS_DATA_PROCESSER_H
+53
View File
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2021 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_DUMP_H
#define SENSOR_DUMP_H
#include <vector>
#include "singleton.h"
#include "client_info.h"
#include "medical.h"
#include "nocopyable.h"
#include "medical_native_type.h"
namespace OHOS {
namespace Sensors {
class MedicalSensorDump : public Singleton<MedicalSensorDump> {
public:
MedicalSensorDump() = default;
virtual ~MedicalSensorDump() = default;
void DumpHelp(int32_t fd);
bool DumpSensorHelp(int32_t fd, const std::vector<std::u16string> &args);
bool DumpSensorList(int32_t fd, const std::vector<MedicalSensor> &sensors, const std::vector<std::u16string> &args);
bool DumpSensorChannel(int32_t fd, ClientInfo &clientInfo, const std::vector<std::u16string> &args);
bool DumpOpeningSensor(int32_t fd, const std::vector<MedicalSensor> &sensors, ClientInfo &clientInfo,
const std::vector<std::u16string> &args);
bool DumpSensorData(int32_t fd, ClientInfo &clientInfo, const std::vector<std::u16string> &args);
int32_t Dump(int32_t fd, const std::vector<std::u16string> &args,
std::vector<MedicalSensor> &sensors, ClientInfo &clientInfo);
private:
DISALLOW_COPY_AND_MOVE(MedicalSensorDump);
void DumpCurrentTime(int32_t fd);
int32_t DataSizeBySensorId(uint32_t sensorId);
std::string GetDataBySensorId(uint32_t sensorId, struct SensorEvent &sensorData);
static std::unordered_map<uint32_t, std::string> sensorMap_;
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSOR_DUMP_H
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 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_MANAGER_H
#define SENSOR_MANAGER_H
#include <mutex>
#include <thread>
#include <unordered_map>
#include "client_info.h"
#include "flush_info_record.h"
#include "medical_data_processer.h"
#include "medical_service_impl.h"
#include "medical_native_type.h"
namespace OHOS {
namespace Sensors {
class MedicalSensorManager : public Singleton<MedicalSensorManager> {
public:
bool SetBestSensorParams(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs);
bool ResetBestSensorParams(uint32_t sensorId);
ErrCode SaveSubscriber(uint32_t sensorId, uint32_t pid, int64_t samplingPeriodNs, int64_t maxReportDelayNs);
void StartDataReportThread();
MedicalSensorBasicInfo GetSensorInfo(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs);
bool IsOtherClientUsingSensor(uint32_t sensorId, int32_t clientPid);
ErrCode AfterDisableSensor(uint32_t sensorId);
void InitSensorMap(std::unordered_map<uint32_t, MedicalSensor> &sensorMap, sptr<MedicalSensorDataProcesser> dataProcesser,
sptr<ReportDataCache> dataCache);
uint32_t GetSensorFlag(uint32_t sensorId);
void GetPackageNameFromUid(int32_t uid, std::string &packageName);
private:
MedicalSensorServiceImpl &sensorServiceImpl_ = MedicalSensorServiceImpl::GetInstance();
ClientInfo &clientInfo_ = ClientInfo::GetInstance();
std::thread dataThread_;
sptr<MedicalSensorDataProcesser> sensorDataProcesser_;
sptr<ReportDataCache> reportDataCache_;
std::unordered_map<uint32_t, MedicalSensor> sensorMap_;
std::mutex sensorMapMutex_;
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSOR_MANAGER_H
+102
View File
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2021 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_SERVICE_H
#define SENSOR_SERVICE_H
#include <mutex>
#include <thread>
#include <unordered_map>
#include "client_info.h"
#include "medical_service_impl.h"
#include "death_recipient_template.h"
#include "nocopyable.h"
#include "medical_manager.h"
#include "medical_service_stub.h"
#include "system_ability.h"
#include "medical_native_type.h"
namespace OHOS {
namespace Sensors {
enum class MedicalSensorServiceState {
STATE_STOPPED,
STATE_RUNNING,
};
class MedicalSensorService : public SystemAbility, public MedicalSensorServiceStub {
DECLARE_SYSTEM_ABILITY(MedicalSensorService)
public:
explicit MedicalSensorService(int32_t systemAbilityId, bool runOnCreate = false);
virtual ~MedicalSensorService() = default;
void OnDump() override;
void OnStart() override;
void OnStop() override;
int Dump(int fd, const std::vector<std::u16string> &args) override;
ErrCode EnableSensor(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) override;
ErrCode DisableSensor(uint32_t sensorId) override;
ErrCode SetOption(uint32_t sensorId, uint32_t opt) override;
int32_t GetSensorState(uint32_t sensorId) override;
ErrCode RunCommand(uint32_t sensorId, uint32_t cmdType, uint32_t params) override;
std::vector<MedicalSensor> GetSensorList() override;
ErrCode TransferDataChannel(const sptr<MedicalSensorBasicDataChannel> &sensorBasicDataChannel,
const sptr<IRemoteObject> &sensorClient) override;
ErrCode DestroySensorChannel(sptr<IRemoteObject> sensorClient) override;
void ProcessDeathObserver(const wptr<IRemoteObject> &object);
private:
DISALLOW_COPY_AND_MOVE(MedicalSensorService);
void RegisterClientDeathRecipient(sptr<IRemoteObject> sensorClient, int32_t pid);
void UnregisterClientDeathRecipient(sptr<IRemoteObject> sensorClient);
bool InitInterface();
bool InitDataCache();
bool InitSensorList();
void ReportOnChangeData(uint32_t sensorId);
void ReportSensorUsedInfo(uint32_t sensorId, bool enable);
MedicalSensorServiceState state_;
std::mutex serviceLock_;
std::mutex sensorsMutex_;
std::mutex sensorMapMutex_;
std::vector<MedicalSensor> sensors_;
std::unordered_map<uint32_t, MedicalSensor> sensorMap_;
MedicalSensorServiceImpl &sensorServiceImpl_ = MedicalSensorServiceImpl::GetInstance();
ClientInfo &clientInfo_ = ClientInfo::GetInstance();
MedicalSensorManager &sensorManager_ = MedicalSensorManager::GetInstance();
FlushInfoRecord &flushInfo_ = FlushInfoRecord::GetInstance();
sptr<MedicalSensorDataProcesser> sensorDataProcesser_;
sptr<ReportDataCache> reportDataCache_;
std::mutex uidLock_;
// death recipient of sensor client
sptr<IRemoteObject::DeathRecipient> clientDeathObserver_;
ErrCode SaveSubscriber(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs);
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSOR_SERVICE_H
+65
View File
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2021 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_INTERFACE_H
#define SENSOR_INTERFACE_H
#include "report_data_cache.h"
#include "errors.h"
#include "refbase.h"
#include "singleton.h"
#include "medical.h"
#include "sensor_if.h"
#include "sensor_type.h"
#include "nocopyable.h"
namespace OHOS {
namespace Sensors {
class MedicalSensorServiceImpl : public Singleton<MedicalSensorServiceImpl> {
public:
MedicalSensorServiceImpl() = default;
virtual ~MedicalSensorServiceImpl() = default;
std::vector<MedicalSensor> GetSensorList() const;
ErrCode EnableSensor(uint32_t sensorId) const;
ErrCode DisableSensor(uint32_t sensorId) const;
ErrCode SetOption(uint32_t sensorId, uint32_t opt) const;
ErrCode RunCommand(uint32_t sensorId, int32_t cmd, int32_t params) const;
ErrCode SetSensorConfig(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) const;
ErrCode InitSensorServiceImpl();
ErrCode RegisteDataReport(DataCacheFunc cacheData, sptr<ReportDataCache> reportDataCache);
ErrCode Unregister(void) const;
static int32_t AfeDataCallback(const struct SensorEvents *event);
static std::mutex dataMutex_;
static std::condition_variable dataCondition_;
private:
DISALLOW_COPY_AND_MOVE(MedicalSensorServiceImpl);
const struct SensorInterface *sensorInterface_ = nullptr;
ErrCode Register(RecordDataCallback cb) const;
static DataCacheFunc cacheData_;
static sptr<ReportDataCache> reportDataCache_;
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSOR_INTERFACE_H
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2021 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_SERVICE_STUB_H
#define SENSOR_SERVICE_STUB_H
#include "iremote_stub.h"
#include "message_parcel.h"
#include "nocopyable.h"
#include "i_medical_service.h"
namespace OHOS {
namespace Sensors {
class MedicalSensorServiceStub : public IRemoteStub<IMedicalSensorService> {
public:
MedicalSensorServiceStub();
virtual ~MedicalSensorServiceStub();
virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option) override;
private:
DISALLOW_COPY_AND_MOVE(MedicalSensorServiceStub);
using AfeBaseFunc = ErrCode (MedicalSensorServiceStub::*)(MessageParcel &data, MessageParcel &reply);
ErrCode AfeEnableInner(MessageParcel &data, MessageParcel &reply);
ErrCode AfeDisableInner(MessageParcel &data, MessageParcel &reply);
ErrCode AfeSetOptionInner(MessageParcel &data, MessageParcel &reply);
ErrCode GetAfeStateInner(MessageParcel &data, MessageParcel &reply);
ErrCode RunCommandInner(MessageParcel &data, MessageParcel &reply);
ErrCode GetAllSensorsInner(MessageParcel &data, MessageParcel &reply);
ErrCode CreateDataChannelInner(MessageParcel &data, MessageParcel &reply);
ErrCode DestroyDataChannelInner(MessageParcel &data, MessageParcel &reply);
std::unordered_map<uint32_t, AfeBaseFunc> baseFuncs_;
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSOR_SERVICE_STUB_H
+717
View File
@@ -0,0 +1,717 @@
/*
* Copyright (c) 2021 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 "client_info.h"
#include <mutex>
#include "securec.h"
#include "medical_service_impl.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_SERVICE, "ClientInfo" };
constexpr uint32_t INVALID_SENSOR_ID = -1;
constexpr int32_t INVALID_PID = -1;
constexpr int32_t INVALID_UID = -1;
constexpr int32_t MIN_MAP_SIZE = 0;
constexpr uint32_t NO_STROE_EVENT = -2;
constexpr uint32_t MAX_SUPPORT_CHANNEL = 200;
constexpr uint32_t MAX_DUMP_DATA_SIZE = 10;
constexpr uint32_t HEART_RATE_SENSOR_ID = 83886336;
} // namespace
MedicalSensorState ClientInfo::GetSensorState(uint32_t sensorId)
{
HiLog::Debug(LABEL, "%{public}s begin, sensorId : %{public}u", __func__, sensorId);
if (sensorId == INVALID_SENSOR_ID) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
return SENSOR_DISABLED;
}
std::lock_guard<std::mutex> clientLock(clientMutex_);
auto it = clientMap_.find(sensorId);
if (it == clientMap_.end()) {
HiLog::Error(LABEL, "%{public}s cannot find sensorId : %{public}u", __func__, sensorId);
return SENSOR_DISABLED;
}
for (const auto &pidIt : it->second) {
if (pidIt.second.GetSensorState() == SENSOR_ENABLED) {
return SENSOR_ENABLED;
}
}
HiLog::Error(LABEL, "%{public}s cannot find sensorinfo, sensorId : %{public}u", __func__, sensorId);
return SENSOR_DISABLED;
}
MedicalSensorBasicInfo ClientInfo::GetBestSensorInfo(uint32_t sensorId)
{
HiLog::Debug(LABEL, "%{public}s begin, sensorId : %{public}u", __func__, sensorId);
int64_t minSamplingPeriodNs = LLONG_MAX;
int64_t minReportDelayNs = LLONG_MAX;
MedicalSensorBasicInfo sensorInfo;
sensorInfo.SetSamplingPeriodNs(minSamplingPeriodNs);
sensorInfo.SetMaxReportDelayNs(minReportDelayNs);
if (sensorId == INVALID_SENSOR_ID) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
return sensorInfo;
}
std::lock_guard<std::mutex> clientLock(clientMutex_);
auto it = clientMap_.find(sensorId);
if (it == clientMap_.end()) {
HiLog::Error(LABEL, "%{public}s cannot find sensorId : %{public}u", __func__, sensorId);
return sensorInfo;
}
for (const auto &pidIt : it->second) {
int64_t curSamplingPeriodNs = pidIt.second.GetSamplingPeriodNs();
int64_t curReportDelayNs = pidIt.second.GetMaxReportDelayNs();
minSamplingPeriodNs = (curSamplingPeriodNs < minSamplingPeriodNs) ? curSamplingPeriodNs : minSamplingPeriodNs;
minReportDelayNs = (curReportDelayNs < minReportDelayNs) ? curReportDelayNs : minReportDelayNs;
}
sensorInfo.SetSamplingPeriodNs(minSamplingPeriodNs);
sensorInfo.SetMaxReportDelayNs(minReportDelayNs);
return sensorInfo;
}
bool ClientInfo::OnlyCurPidSensorEnabled(uint32_t sensorId, int32_t pid)
{
HiLog::Debug(LABEL, "%{public}s begin, sensorId : %{public}u, pid : %{public}d", __func__, sensorId, pid);
if ((sensorId == INVALID_SENSOR_ID) || (pid <= INVALID_PID)) {
HiLog::Error(LABEL, "%{public}s sensorId or pid is invalid", __func__);
return false;
}
std::lock_guard<std::mutex> clientLock(clientMutex_);
auto it = clientMap_.find(sensorId);
if (it == clientMap_.end()) {
HiLog::Error(LABEL, "%{public}s cannot find sensorId : %{public}u", __func__, sensorId);
return false;
}
bool ret = false;
for (const auto &pidIt : it->second) {
if (pidIt.second.GetSensorState() != SENSOR_ENABLED) {
continue;
}
if (pidIt.first != pid) {
return false;
}
ret = true;
}
HiLog::Debug(LABEL, "%{public}s end", __func__);
return ret;
}
bool ClientInfo::UpdateUid(int32_t pid, int32_t uid)
{
HiLog::Debug(LABEL, "%{public}s begin, pid : %{public}d, uid : %{public}d", __func__, pid, uid);
if ((uid == INVALID_UID) || (pid <= INVALID_PID)) {
HiLog::Error(LABEL, "%{public}s uid or pid is invalid", __func__);
return false;
}
std::lock_guard<std::mutex> uidLock(uidMutex_);
auto uidIt = uidMap_.find(pid);
if (uidIt == uidMap_.end()) {
if (uidMap_.size() == MAX_SUPPORT_CHANNEL) {
HiLog::Error(LABEL, "%{public}s max support channel size is %{public}u", __func__, MAX_SUPPORT_CHANNEL);
return false;
}
auto ret = uidMap_.insert(std::make_pair(pid, uid));
HiLog::Debug(LABEL, "%{public}s insert uid ret.second : %{public}d", __func__, ret.second);
return ret.second;
}
uidMap_[pid] = uid;
HiLog::Debug(LABEL, "%{public}s end", __func__);
return true;
}
bool ClientInfo::DestroyUid(int32_t pid)
{
HiLog::Debug(LABEL, "%{public}s begin, pid : %{public}d", __func__, pid);
if (pid == INVALID_PID) {
HiLog::Error(LABEL, "%{public}s pid is invalid", __func__);
return false;
}
std::lock_guard<std::mutex> uidLock(uidMutex_);
auto uidIt = uidMap_.find(pid);
if (uidIt == uidMap_.end()) {
HiLog::Debug(LABEL, "%{public}s uid not exist, no need to destroy it", __func__);
return true;
}
int32_t uid = uidIt->second;
uidMap_.erase(uidIt);
for (const auto &it : uidMap_) {
if (it.second == uid) {
return true;
}
}
MedicalThreadInfo appThreadInfo;
appThreadInfo.uid = uid;
appThreadInfo.pid = 0;
PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
permissionUtil.UnregistPermissionChanged(appThreadInfo);
HiLog::Debug(LABEL, "%{public}s end", __func__);
return true;
}
std::vector<sptr<MedicalSensorBasicDataChannel>> ClientInfo::GetSensorChannelByUid(int32_t uid)
{
HiLog::Debug(LABEL, "%{public}s begin, uid : %{public}d", __func__, uid);
if (uid == INVALID_UID) {
HiLog::Error(LABEL, "%{public}s uid is invalid", __func__);
return {};
}
std::vector<sptr<MedicalSensorBasicDataChannel>> afeChannel;
std::lock_guard<std::mutex> uidLock(uidMutex_);
for (const auto &uidIt : uidMap_) {
if (uid != uidIt.second) {
continue;
}
std::lock_guard<std::mutex> channelLock(channelMutex_);
auto channelIt = channelMap_.find(uidIt.first);
if (channelIt == channelMap_.end()) {
continue;
}
afeChannel.push_back(channelIt->second);
}
HiLog::Debug(LABEL, "%{public}s end", __func__);
return afeChannel;
}
sptr<MedicalSensorBasicDataChannel> ClientInfo::GetSensorChannelByPid(int32_t pid)
{
HiLog::Debug(LABEL, "%{public}s begin, pid : %{public}d", __func__, pid);
if (pid == INVALID_PID) {
HiLog::Error(LABEL, "%{public}s pid is invalid", __func__);
return nullptr;
}
std::lock_guard<std::mutex> channelLock(channelMutex_);
auto channelIt = channelMap_.find(pid);
if (channelIt == channelMap_.end()) {
HiLog::Error(LABEL, "%{public}s there is no channel belong to the pid", __func__);
return nullptr;
}
HiLog::Debug(LABEL, "%{public}s end", __func__);
return channelIt->second;
}
std::vector<sptr<MedicalSensorBasicDataChannel>> ClientInfo::GetSensorChannel(uint32_t sensorId)
{
if (sensorId == INVALID_SENSOR_ID) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
return {};
}
std::lock_guard<std::mutex> clientLock(clientMutex_);
auto clientIt = clientMap_.find(sensorId);
if (clientIt == clientMap_.end()) {
HiLog::Debug(LABEL, "%{public}s there is no channel belong to sensorId : %{public}u", __func__, sensorId);
return {};
}
std::vector<sptr<MedicalSensorBasicDataChannel>> afeChannel;
for (const auto &sensorInfoIt : clientIt->second) {
std::lock_guard<std::mutex> channelLock(channelMutex_);
auto channelIt = channelMap_.find(sensorInfoIt.first);
if (channelIt == channelMap_.end()) {
continue;
}
afeChannel.push_back(channelIt->second);
}
return afeChannel;
}
bool ClientInfo::UpdateSensorInfo(uint32_t sensorId, int32_t pid, const MedicalSensorBasicInfo &sensorInfo)
{
HiLog::Debug(LABEL, "%{public}s begin, sensorId : %{public}u, pid : %{public}d", __func__, sensorId, pid);
if ((sensorId == INVALID_SENSOR_ID) || (pid <= INVALID_PID) || (sensorInfo.GetSensorState() != SENSOR_ENABLED)) {
HiLog::Error(LABEL, "%{public}s params are invalid", __func__);
return false;
}
std::lock_guard<std::mutex> clientLock(clientMutex_);
auto it = clientMap_.find(sensorId);
if (it == clientMap_.end()) {
std::unordered_map<int32_t, MedicalSensorBasicInfo> pidMap;
auto pidRet = pidMap.insert(std::make_pair(pid, sensorInfo));
auto clientRet = clientMap_.insert(std::make_pair(sensorId, pidMap));
return pidRet.second && clientRet.second;
}
auto pidIt = it->second.find(pid);
if (pidIt == it->second.end()) {
auto ret = it->second.insert(std::make_pair(pid, sensorInfo));
return ret.second;
}
it->second[pid] = sensorInfo;
return true;
}
void ClientInfo::RemoveSubscriber(uint32_t sensorId, uint32_t pid)
{
std::lock_guard<std::mutex> clientLock(clientMutex_);
auto it = clientMap_.find(sensorId);
if (it == clientMap_.end()) {
HiLog::Warn(LABEL, "%{public}s sensorId not exist", __func__);
return;
}
auto pidIt = it->second.find(pid);
if (pidIt != it->second.end()) {
it->second.erase(pidIt);
}
}
bool ClientInfo::UpdateSensorChannel(int32_t pid, const sptr<MedicalSensorBasicDataChannel> &channel)
{
HiLog::Debug(LABEL, "%{public}s begin, pid : %{public}d", __func__, pid);
if (pid <= INVALID_PID || channel == nullptr) {
HiLog::Error(LABEL, "%{public}s pid or channel is invalid or channel cannot be null", __func__);
return false;
}
std::lock_guard<std::mutex> channelLock(channelMutex_);
auto it = channelMap_.find(pid);
if (it == channelMap_.end()) {
if (channelMap_.size() == MAX_SUPPORT_CHANNEL) {
HiLog::Error(LABEL, "%{public}s max support channel size : %{public}u", __func__, MAX_SUPPORT_CHANNEL);
return false;
}
auto ret = channelMap_.insert(std::make_pair(pid, channel));
HiLog::Debug(LABEL, "%{public}s ret.second : %{public}d", __func__, ret.second);
return ret.second;
}
channelMap_[pid] = channel;
HiLog::Debug(LABEL, "%{public}s end", __func__);
return true;
}
bool ClientInfo::ClearSensorInfo(uint32_t sensorId)
{
HiLog::Debug(LABEL, "%{public}s begin, sensorId : %{public}d", __func__, sensorId);
if (sensorId == INVALID_SENSOR_ID) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
return false;
}
std::lock_guard<std::mutex> clientLock(clientMutex_);
auto it = clientMap_.find(sensorId);
if (it == clientMap_.end()) {
HiLog::Debug(LABEL, "%{public}s sensorId not exist, no need to clear it", __func__);
return true;
}
clientMap_.erase(it);
return true;
}
void ClientInfo::ClearCurPidSensorInfo(uint32_t sensorId, int32_t pid)
{
HiLog::Debug(LABEL, "%{public}s begin, sensorId : %{public}d", __func__, sensorId);
if ((sensorId == INVALID_SENSOR_ID) || (pid <= INVALID_PID)) {
HiLog::Error(LABEL, "%{public}s sensorId or pid is invalid", __func__);
return;
}
std::lock_guard<std::mutex> clientLock(clientMutex_);
auto it = clientMap_.find(sensorId);
if (it == clientMap_.end()) {
HiLog::Debug(LABEL, "%{public}s sensorId not exist, no need to clear it", __func__);
return;
}
auto pidIt = it->second.find(pid);
if (pidIt == it->second.end()) {
HiLog::Debug(LABEL, "%{public}s pid not exist, no need to clear it", __func__);
return;
}
pidIt = it->second.erase(pidIt);
if (it->second.size() == MIN_MAP_SIZE) {
it = clientMap_.erase(it);
}
}
bool ClientInfo::DestroySensorChannel(int32_t pid)
{
HiLog::Debug(LABEL, "%{public}s start, pid : %{public}d", __func__, pid);
if (pid <= INVALID_PID) {
HiLog::Error(LABEL, "%{public}s pid is invalid", __func__);
return false;
}
std::lock_guard<std::mutex> clientLock(clientMutex_);
for (auto it = clientMap_.begin(); it != clientMap_.end();) {
auto pidIt = it->second.find(pid);
if (pidIt == it->second.end()) {
it++;
continue;
}
pidIt = it->second.erase(pidIt);
if (it->second.size() != MIN_MAP_SIZE) {
it++;
continue;
}
it = clientMap_.erase(it);
}
DestroyUid(pid);
std::lock_guard<std::mutex> channelLock(channelMutex_);
auto it = channelMap_.find(pid);
if (it == channelMap_.end()) {
HiLog::Debug(LABEL, "%{public}s there is no channel belong to pid, no need to destroy", __func__);
return true;
}
it = channelMap_.erase(it);
HiLog::Debug(LABEL, "%{public}s end", __func__);
return true;
}
MedicalSensorBasicInfo ClientInfo::GetCurPidSensorInfo(uint32_t sensorId, int32_t pid)
{
HiLog::Debug(LABEL, "%{public}s begin, sensorId : %{public}u", __func__, sensorId);
int64_t minSamplingPeriodNs = LLONG_MAX;
int64_t minReportDelayNs = LLONG_MAX;
MedicalSensorBasicInfo sensorInfo;
sensorInfo.SetSamplingPeriodNs(minSamplingPeriodNs);
sensorInfo.SetMaxReportDelayNs(minReportDelayNs);
if ((sensorId == INVALID_SENSOR_ID) || (pid <= INVALID_PID)) {
HiLog::Error(LABEL, "%{public}s sensorId or channel is invalid", __func__);
return sensorInfo;
}
std::lock_guard<std::mutex> clientLock(clientMutex_);
auto it = clientMap_.find(sensorId);
if (it == clientMap_.end()) {
HiLog::Error(LABEL, "%{public}s cannot find sensorId : %{public}u", __func__, sensorId);
return sensorInfo;
}
auto pidIt = it->second.find(pid);
if (pidIt == it->second.end()) {
HiLog::Error(LABEL, "%{public}s cannot find pid : %{public}d", __func__, pid);
return sensorInfo;
}
sensorInfo.SetSamplingPeriodNs(pidIt->second.GetSamplingPeriodNs());
sensorInfo.SetMaxReportDelayNs(pidIt->second.GetMaxReportDelayNs());
HiLog::Debug(LABEL, "%{public}s end", __func__);
return sensorInfo;
}
uint64_t ClientInfo::ComputeBestPeriodCount(uint32_t sensorId, sptr<MedicalSensorBasicDataChannel> &channel)
{
if (sensorId == INVALID_SENSOR_ID || channel == nullptr) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid or channel cannot be null", __func__);
return 0UL;
}
int32_t pid = INVALID_PID;
{
std::lock_guard<std::mutex> channelLock(channelMutex_);
for (const auto &channelIt : channelMap_) {
if (channelIt.second == channel) {
pid = channelIt.first;
}
}
}
int64_t bestSamplingPeriod = GetBestSensorInfo(sensorId).GetSamplingPeriodNs();
int64_t curSamplingPeriod = GetCurPidSensorInfo(sensorId, pid).GetSamplingPeriodNs();
if (bestSamplingPeriod == 0L) {
HiLog::Error(LABEL, "%{public}s best MedicalSensor Sampling Period is 0", __func__);
return 0UL;
}
int64_t ret = curSamplingPeriod / bestSamplingPeriod;
return (ret <= 0L) ? 0UL : ret;
}
uint64_t ClientInfo::ComputeBestFifoCount(uint32_t sensorId, sptr<MedicalSensorBasicDataChannel> &channel)
{
if (channel == nullptr || sensorId == INVALID_SENSOR_ID) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid or channel cannot be null", __func__);
return 0UL;
}
int32_t pid = INVALID_PID;
{
std::lock_guard<std::mutex> channelLock(channelMutex_);
for (const auto &channelIt : channelMap_) {
if (channelIt.second == channel) {
pid = channelIt.first;
}
}
}
int64_t curReportDelay = GetCurPidSensorInfo(sensorId, pid).GetMaxReportDelayNs();
int64_t curSamplingPeriod = GetCurPidSensorInfo(sensorId, pid).GetSamplingPeriodNs();
if (curSamplingPeriod == 0L) {
HiLog::Error(LABEL, "%{public}s best sensor fifo count is 0", __func__);
return 0UL;
}
int64_t ret = curReportDelay / curSamplingPeriod;
return (ret <= 0L) ? 0UL : ret;
}
int32_t ClientInfo::GetStoreEvent(int32_t sensorId, struct SensorEvent &event)
{
std::lock_guard<std::mutex> lock(eventMutex_);
auto storedEvent = storedEvent_.find(sensorId);
if (storedEvent != storedEvent_.end()) {
errno_t ret = memcpy_s(&event, sizeof(struct SensorEvent), &storedEvent->second, sizeof(struct SensorEvent));
if (ret != EOK) {
HiLog::Error(LABEL, "%{public}s memcpy_s failed, sensorId : %{public}d", __func__, sensorId);
return ret;
}
return ERR_OK;
}
HiLog::Error(LABEL, "%{public}s can't get store event, sensorId : %{public}u", __func__, sensorId);
return NO_STROE_EVENT;
}
void ClientInfo::StoreEvent(const struct SensorEvent &event)
{
bool foundSensor = false;
struct SensorEvent storedEvent;
auto sensorServiceImpl = &MedicalSensorServiceImpl::GetInstance();
if (sensorServiceImpl == nullptr) {
HiLog::Error(LABEL, "%{public}s sensorServiceImpl cannot be null", __func__);
return;
}
auto sensors = sensorServiceImpl->GetSensorList();
size_t len = sensors.size();
if (len == 0) {
HiLog::Error(LABEL, "%{public}s GetSensorList failed", __func__);
return;
}
errno_t ret = memcpy_s(&storedEvent, sizeof(storedEvent), &event, sizeof(event));
if (ret != EOK) {
HiLog::Error(LABEL, "%{public}s memcpy_s failed", __func__);
return;
}
for (size_t i = 0; i < len; i++) {
if ((int32_t)(sensors[i].GetSensorId()) == storedEvent.sensorTypeId) {
HiLog::Debug(LABEL, "%{public}s sensorFlags : %{public}u", __func__, sensors[i].GetFlags());
foundSensor = true;
break;
}
}
if (foundSensor) {
std::lock_guard<std::mutex> lock(eventMutex_);
storedEvent_[storedEvent.sensorTypeId] = storedEvent;
}
}
bool ClientInfo::SaveClientPid(const sptr<IRemoteObject> &sensorClient, int32_t pid)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (sensorClient == nullptr) {
HiLog::Error(LABEL, "%{public}s sensorClient cannot be null", __func__);
return false;
}
std::lock_guard<std::mutex> lock(clientPidMutex_);
auto it = clientPidMap_.find(sensorClient);
if (it == clientPidMap_.end()) {
clientPidMap_.insert(std::make_pair(sensorClient, pid));
HiLog::Debug(LABEL, "%{public}s end", __func__);
return true;
}
clientPidMap_.insert(std::make_pair(sensorClient, pid));
HiLog::Debug(LABEL, "%{public}s end", __func__);
return true;
}
int32_t ClientInfo::FindClientPid(const sptr<IRemoteObject> &sensorClient)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (sensorClient == nullptr) {
HiLog::Error(LABEL, "%{public}s sensorClient cannot be null", __func__);
return INVALID_PID;
}
std::lock_guard<std::mutex> lock(clientPidMutex_);
auto it = clientPidMap_.find(sensorClient);
if (it == clientPidMap_.end()) {
HiLog::Error(LABEL, "%{public}s cannot find client pid", __func__);
return INVALID_PID;
}
HiLog::Debug(LABEL, "%{public}s end, pid : %{public}d", __func__, it->second);
return it->second;
}
void ClientInfo::DestroyClientPid(const sptr<IRemoteObject> &sensorClient)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (sensorClient == nullptr) {
HiLog::Error(LABEL, "%{public}s sensorClient cannot be null", __func__);
return;
}
std::lock_guard<std::mutex> lock(clientPidMutex_);
auto it = clientPidMap_.find(sensorClient);
if (it == clientPidMap_.end()) {
HiLog::Error(LABEL, "%{public}s cannot find client pid", __func__);
return;
}
HiLog::Debug(LABEL, "%{public}s end, pid : %{public}d", __func__, it->second);
clientPidMap_.erase(it);
}
void ClientInfo::ClearEvent()
{
std::lock_guard<std::mutex> lock(eventMutex_);
storedEvent_.clear();
}
std::vector<uint32_t> ClientInfo::GetSensorIdByPid(int32_t pid)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
std::vector<uint32_t> sensorIdVec;
std::lock_guard<std::mutex> clientLock(clientMutex_);
for (const auto &itClientMap : clientMap_) {
auto it = itClientMap.second.find(pid);
if (it != itClientMap.second.end()) {
sensorIdVec.push_back(itClientMap.first);
}
}
return sensorIdVec;
}
MedicalThreadInfo ClientInfo::GetAppInfoByChannel(const sptr<MedicalSensorBasicDataChannel> &channel)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
MedicalThreadInfo appThreadInfo;
{
std::lock_guard<std::mutex> channelLock(channelMutex_);
for (auto channelIt = channelMap_.begin(); channelIt != channelMap_.end(); channelIt++) {
if (channelIt->second == channel) {
appThreadInfo.pid = channelIt->first;
}
}
}
{
std::lock_guard<std::mutex> uidLock(uidMutex_);
auto it = uidMap_.find(appThreadInfo.pid);
if (it != uidMap_.end()) {
appThreadInfo.uid = it->second;
}
}
return appThreadInfo;
}
void ClientInfo::GetSensorChannelInfo(std::vector<MedicalSensorChannelInfo> &channelInfo)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
std::lock_guard<std::mutex> clientLock(clientMutex_);
for (const auto &sensorIt : clientMap_) {
for (const auto &pidIt : sensorIt.second) {
MedicalSensorChannelInfo channel;
int32_t uid = GetUidByPid(pidIt.first);
if (uid == INVALID_UID) {
continue;
}
channel.SetUid(uid);
// BundleManager bundleManager_;
std::string packageName("");
channel.SetSensorId(sensorIt.first);
channel.SetPackageName(packageName);
int64_t samplingPeriodNs = pidIt.second.GetSamplingPeriodNs();
int64_t maxReportDelayNs = pidIt.second.GetMaxReportDelayNs();
channel.SetSamplingPeriodNs(samplingPeriodNs);
uint32_t fifoCount = (samplingPeriodNs == 0) ? 0 : (uint32_t)(maxReportDelayNs / samplingPeriodNs);
channel.SetFifoCount(fifoCount);
channel.SetCmdType(GetCmdList(sensorIt.first, uid));
channelInfo.push_back(channel);
}
}
}
int32_t ClientInfo::GetUidByPid(int32_t pid)
{
std::lock_guard<std::mutex> uidLock(uidMutex_);
auto uidIt = uidMap_.find(pid);
if (uidIt == uidMap_.end()) {
return INVALID_UID;
}
return uidIt->second;
}
void ClientInfo::UpdateCmd(uint32_t sensorId, int32_t uid, int32_t cmdType)
{
std::lock_guard<std::mutex> cmdLock(cmdMutex_);
auto cmdIt = cmdMap_.find(sensorId);
if (cmdIt == cmdMap_.end()) {
std::unordered_map<int32_t, std::vector<int32_t>> cmds;
std::vector<int32_t> tmp;
tmp.push_back(cmdType);
cmds.insert(std::make_pair(uid, tmp));
cmdMap_.insert(std::make_pair(sensorId, cmds));
return;
}
auto tmpIt = cmdIt->second.find(uid);
if (tmpIt == cmdIt->second.end()) {
std::vector<int32_t> tmp;
tmp.push_back(cmdType);
cmdIt->second.insert(std::make_pair(uid, tmp));
return;
}
auto tmp = tmpIt->second;
tmp.push_back(cmdType);
cmdIt->second.insert(std::make_pair(uid, tmp));
}
void ClientInfo::DestroyCmd(int32_t uid)
{
std::lock_guard<std::mutex> cmdLock(cmdMutex_);
cmdMap_.erase(uid);
}
std::vector<int32_t> ClientInfo::GetCmdList(uint32_t sensorId, int32_t uid)
{
std::lock_guard<std::mutex> cmdLock(cmdMutex_);
auto cmdIt = cmdMap_.find(sensorId);
if (cmdIt == cmdMap_.end()) {
return {};
}
auto uidIt = cmdIt->second.find(uid);
if (uidIt == cmdIt->second.end()) {
return {};
}
return uidIt->second;
}
void ClientInfo::UpdateDataQueue(int32_t sensorId, struct SensorEvent &event)
{
if (sensorId == HEART_RATE_SENSOR_ID) {
return;
}
std::lock_guard<std::mutex> queueLock(dataQueueMutex_);
auto it = dataQueue_.find(sensorId);
if (it == dataQueue_.end()) {
std::queue<struct SensorEvent> q;
q.push(event);
dataQueue_.insert(std::make_pair(sensorId, q));
return;
}
it->second.push(event);
if (it->second.size() > MAX_DUMP_DATA_SIZE) {
it->second.pop();
}
}
std::unordered_map<uint32_t, std::queue<struct SensorEvent>> ClientInfo::GetDataQueue()
{
return dataQueue_;
}
void ClientInfo::ClearDataQueue(int32_t sensorId)
{
std::lock_guard<std::mutex> queueLock(dataQueueMutex_);
auto it = dataQueue_.find(sensorId);
if (it != dataQueue_.end()) {
dataQueue_.erase(it);
}
}
} // namespace Sensors
} // namespace OHOS
+63
View File
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2021 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 "fifo_cache_data.h"
namespace OHOS {
namespace Sensors {
FifoCacheData::FifoCacheData() : periodCount_(0), channel_(nullptr)
{}
FifoCacheData::~FifoCacheData()
{
fifoCacheData_.clear();
}
void FifoCacheData::InitFifoCache()
{
periodCount_ = 0;
fifoCacheData_.clear();
}
void FifoCacheData::SetPeriodCount(uint64_t periodCount)
{
periodCount_ = periodCount;
}
uint64_t FifoCacheData::GetPeriodCount() const
{
return periodCount_;
}
void FifoCacheData::SetFifoCacheData(const std::vector<struct SensorEvent> &fifoCacheData)
{
fifoCacheData_ = fifoCacheData;
}
std::vector<struct SensorEvent> FifoCacheData::GetFifoCacheData() const
{
return fifoCacheData_;
}
void FifoCacheData::SetChannel(const sptr<MedicalSensorBasicDataChannel> &channel)
{
channel_ = channel;
}
sptr<MedicalSensorBasicDataChannel> FifoCacheData::GetChannel() const
{
return channel_;
}
} // namespace Sensors
} // namespace OHOS
+120
View File
@@ -0,0 +1,120 @@
/*
* Copyright (c) 2021 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 "flush_info_record.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_SERVICE, "FlushInfoRecord" };
constexpr int32_t CHANNEL_NO_FLUSH = -1;
enum {
FLUSH = 0,
SET_MODE,
RESERVED,
};
} // namespace
std::unordered_map<uint32_t, std::vector<struct FlushInfo>> FlushInfoRecord::GetFlushInfo()
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
std::lock_guard<std::mutex> flushLock(flushInfoMutex_);
return flushInfo_;
}
void FlushInfoRecord::ClearFlushInfoItem(uint32_t sensorId)
{
std::lock_guard<std::mutex> flushLock(flushInfoMutex_);
auto it = flushInfo_.find(sensorId);
if (it != flushInfo_.end()) {
it->second.erase(it->second.begin());
}
}
ErrCode FlushInfoRecord::SetFlushInfo(uint32_t sensorId, const sptr<MedicalSensorBasicDataChannel> &channel, bool isFirstFlush)
{
HiLog::Debug(LABEL, "%{public}s, sensorId : %{public}u", __func__, sensorId);
if (channel == nullptr) {
HiLog::Error(LABEL, "%{public}s failed, channel cannot be null", __func__);
return INVALID_POINTER;
}
struct FlushInfo flush(channel, isFirstFlush);
std::lock_guard<std::mutex> flushLock(flushInfoMutex_);
/* If the sensorId can be found, it indicates that other processes have flushed on this sensor,
so need to insert this flush command to the end of the vector */
auto it = flushInfo_.find(sensorId);
if (it != flushInfo_.end()) {
it->second.push_back(flush);
} else {
std::vector<struct FlushInfo> vec { flush };
flushInfo_.insert(std::make_pair(sensorId, vec));
}
return ERR_OK;
}
bool FlushInfoRecord::IsFlushChannelValid(const std::vector<sptr<MedicalSensorBasicDataChannel>> &currChannelList,
const sptr<MedicalSensorBasicDataChannel> &flushChannel)
{
HiLog::Debug(LABEL, "%{public}s channel list size : %{public}u", __func__,
static_cast<uint32_t>(currChannelList.size()));
for (const auto &channel : currChannelList) {
HiLog::Debug(LABEL, "%{public}s channel : %{public}p, flushchannel : %{public}p", __func__, channel.GetRefPtr(),
flushChannel.GetRefPtr());
if (channel == flushChannel) {
return true;
}
}
return false;
}
int32_t FlushInfoRecord::GetFlushChannelIndex(const std::vector<struct FlushInfo> &flushInfoList,
const sptr<MedicalSensorBasicDataChannel> &channel)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
for (size_t i = 0; i < flushInfoList.size(); i++) {
if (flushInfoList[i].flushChannel == channel) {
return i;
}
}
return CHANNEL_NO_FLUSH;
}
ErrCode FlushInfoRecord::FlushProcess(const uint32_t sensorId, const uint32_t flag, const int32_t pid,
const bool isEnableFlush)
{
auto ret = sensorServiceImpl_.RunCommand(sensorId, FLUSH, 0);
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s flush command failed", __func__);
return ret;
}
sptr<MedicalSensorBasicDataChannel> channel = clientInfo_.GetSensorChannelByPid(pid);
if (channel == nullptr) {
HiLog::Error(LABEL, "%{public}s channel cannot be null", __func__);
return ERROR;
}
ret = SetFlushInfo(sensorId, channel, false);
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s set flush info failed", __func__);
return ret;
}
return ERR_OK;
}
} // namespace Sensors
} // namespace OHOS
+414
View File
@@ -0,0 +1,414 @@
/*
* Copyright (c) 2021 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 "medical_data_processer.h"
#include <sys/socket.h>
#include <thread>
#include "permission_util.h"
#include "securec.h"
#include "medical_basic_data_channel.h"
#include "medical_catalog.h"
#include "medical_errors.h"
#include "system_ability_definition.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_UTILS, "MedicalSensorDataProcesser" };
enum {
FIRST_INDEX = 1,
SECOND_INDEX = 2,
THIRD_INDEX = 3,
};
constexpr uint32_t SENSOR_INDEX_SHIFT = 8;
constexpr uint32_t SENSOR_TYPE_SHIFT = 16;
constexpr uint32_t SENSOR_CATAGORY_SHIFT = 24;
constexpr uint32_t FLUSH_COMPLETE_ID = ((uint32_t)OTHER << SENSOR_CATAGORY_SHIFT) |
((uint32_t)SENSOR_TYPE_FLUSH << SENSOR_TYPE_SHIFT) |
((uint32_t)FIRST_INDEX << SENSOR_INDEX_SHIFT);
} // namespace
MedicalSensorDataProcesser::MedicalSensorDataProcesser(const std::unordered_map<uint32_t, MedicalSensor> &sensorMap)
{
sensorMap_.insert(sensorMap.begin(), sensorMap.end());
HiLog::Debug(LABEL, "%{public}s sensorMap_.size : %{public}d", __func__, int32_t { sensorMap_.size() });
}
MedicalSensorDataProcesser::~MedicalSensorDataProcesser()
{
dataCountMap_.clear();
sensorMap_.clear();
}
void MedicalSensorDataProcesser::SendNoneFifoCacheData(std::unordered_map<uint32_t, struct SensorEvent> &cacheBuf,
sptr<MedicalSensorBasicDataChannel> &channel, struct SensorEvent &event,
uint64_t periodCount)
{
std::vector<struct SensorEvent> sendEvents;
std::lock_guard<std::mutex> dataCountLock(dataCountMutex_);
sendEvents.push_back(event);
uint32_t sensorId = event.sensorTypeId;
if (sensorId == FLUSH_COMPLETE_ID) {
sensorId = event.sensorTypeId;
}
auto dataCountIt = dataCountMap_.find(sensorId);
if (dataCountIt == dataCountMap_.end()) {
std::vector<sptr<FifoCacheData>> channelFifoList;
sptr<FifoCacheData> fifoCacheData = new (std::nothrow) FifoCacheData();
if (fifoCacheData == nullptr) {
HiLog::Error(LABEL, "%{public}s fifoCacheData cannot be null", __func__);
return;
}
fifoCacheData->SetChannel(channel);
channelFifoList.push_back(fifoCacheData);
dataCountMap_.insert(std::make_pair(sensorId, channelFifoList));
SendRawData(cacheBuf, channel, sendEvents);
return;
}
bool channelExist = false;
for (const auto &fifoCacheData : dataCountIt->second) {
if (fifoCacheData->GetChannel() != channel) {
continue;
}
channelExist = true;
uint64_t curCount = fifoCacheData->GetPeriodCount();
curCount++;
fifoCacheData->SetPeriodCount(curCount);
if (periodCount != 0 && fifoCacheData->GetPeriodCount() % periodCount != 0UL) {
continue;
}
SendRawData(cacheBuf, channel, sendEvents);
fifoCacheData->SetPeriodCount(0);
return;
}
if (!channelExist) {
sptr<FifoCacheData> fifoCacheData = new (std::nothrow) FifoCacheData();
if (fifoCacheData == nullptr) {
HiLog::Error(LABEL, "%{public}s failed, fifoCacheData cannot be null", __func__);
return;
}
fifoCacheData->SetChannel(channel);
dataCountIt->second.push_back(fifoCacheData);
SendRawData(cacheBuf, channel, sendEvents);
}
}
void MedicalSensorDataProcesser::SendFifoCacheData(std::unordered_map<uint32_t, struct SensorEvent> &cacheBuf,
sptr<MedicalSensorBasicDataChannel> &channel, struct SensorEvent &event,
uint64_t periodCount, uint64_t fifoCount)
{
uint32_t sensorId = event.sensorTypeId;
if (sensorId == FLUSH_COMPLETE_ID) {
sensorId = event.sensorTypeId;
}
std::lock_guard<std::mutex> dataCountLock(dataCountMutex_);
auto dataCountIt = dataCountMap_.find(sensorId);
// there is no channelFifoList
if (dataCountIt == dataCountMap_.end()) {
std::vector<sptr<FifoCacheData>> channelFifoList;
sptr<FifoCacheData> fifoCacheData = new (std::nothrow) FifoCacheData();
if (fifoCacheData == nullptr) {
HiLog::Error(LABEL, "%{public}s fifoCacheData cannot be null", __func__);
return;
}
fifoCacheData->SetChannel(channel);
channelFifoList.push_back(fifoCacheData);
dataCountMap_.insert(std::make_pair(sensorId, channelFifoList));
return;
}
// find channel in channelFifoList
bool channelExist = false;
for (auto &fifoData : dataCountIt->second) {
if (fifoData->GetChannel() != channel) {
continue;
}
channelExist = true;
uint64_t curCount = fifoData->GetPeriodCount();
curCount++;
fifoData->SetPeriodCount(curCount);
if (fifoData->GetPeriodCount() % periodCount != 0UL) {
continue;
}
fifoData->SetPeriodCount(0);
std::vector<struct SensorEvent> fifoDataList = fifoData->GetFifoCacheData();
fifoDataList.push_back(event);
fifoData->SetFifoCacheData(fifoDataList);
if ((fifoData->GetFifoCacheData()).size() != fifoCount) {
continue;
}
SendRawData(cacheBuf, channel, fifoData->GetFifoCacheData());
fifoData->InitFifoCache();
return;
}
// cannot find channel in channelFifoList
if (!channelExist) {
sptr<FifoCacheData> fifoCacheData = new (std::nothrow) FifoCacheData();
if (fifoCacheData == nullptr) {
HiLog::Error(LABEL, "%{public}s failed, fifoCacheData cannot be null", __func__);
return;
}
fifoCacheData->SetChannel(channel);
dataCountIt->second.push_back(fifoCacheData);
}
}
void MedicalSensorDataProcesser::ReportData(sptr<MedicalSensorBasicDataChannel> &channel, struct SensorEvent &event)
{
if (channel == nullptr) {
HiLog::Error(LABEL, "%{public}s channel cannot be null", __func__);
return;
}
uint32_t sensorId = event.sensorTypeId;
if (sensorId == FLUSH_COMPLETE_ID) {
sensorId = event.sensorTypeId;
}
auto &cacheBuf = const_cast<std::unordered_map<uint32_t, struct SensorEvent> &>(channel->GetDataCacheBuf());
if (ReportNotContinuousData(cacheBuf, channel, event)) {
return;
}
uint64_t periodCount = clientInfo_.ComputeBestPeriodCount(sensorId, channel);
if (periodCount == 0UL) {
return;
}
auto fifoCount = clientInfo_.ComputeBestFifoCount(sensorId, channel);
if (fifoCount <= 0) {
SendNoneFifoCacheData(cacheBuf, channel, event, periodCount);
return;
}
SendFifoCacheData(cacheBuf, channel, event, periodCount, fifoCount);
}
bool MedicalSensorDataProcesser::ReportNotContinuousData(std::unordered_map<uint32_t, struct SensorEvent> &cacheBuf,
sptr<MedicalSensorBasicDataChannel> &channel, struct SensorEvent &event)
{
uint32_t sensorId = event.sensorTypeId;
if (sensorId == FLUSH_COMPLETE_ID) {
sensorId = event.sensorTypeId;
}
std::lock_guard<std::mutex> sensorLock(sensorMutex_);
auto sensor = sensorMap_.find(sensorId);
sensor->second.SetFlags(event.mode);
if (sensor == sensorMap_.end()) {
HiLog::Error(LABEL, "%{public}s data's sensorId is not supported", __func__);
return false;
}
if (((SENSOR_ON_CHANGE & sensor->second.GetFlags()) == SENSOR_ON_CHANGE) ||
((SENSOR_ONE_SHOT & sensor->second.GetFlags()) == SENSOR_ONE_SHOT)) {
std::vector<struct SensorEvent> sendEvents;
sendEvents.push_back(event);
SendRawData(cacheBuf, channel, sendEvents);
return true;
}
return false;
}
bool MedicalSensorDataProcesser::CheckSendDataPermission(sptr<MedicalSensorBasicDataChannel> channel, uint32_t sensorId)
{
return true;
}
void MedicalSensorDataProcesser::SendRawData(std::unordered_map<uint32_t, struct SensorEvent> &cacheBuf,
sptr<MedicalSensorBasicDataChannel> channel, std::vector<struct SensorEvent> event)
{
if (channel == nullptr || event.empty()) {
HiLog::Error(LABEL, "%{public}s channel cannot be null or event cannot be empty", __func__);
return;
}
if (!CheckSendDataPermission(channel, event[0].sensorTypeId)) {
HiLog::Error(LABEL, "%{public}s permission denied", __func__);
return;
}
size_t eventSize = event.size();
std::vector<struct TransferMedicalSensorEvents> transferEvents;
for (int32_t i = 0; i < (int32_t)eventSize; i++) {
struct TransferMedicalSensorEvents transferEvent = {
.sensorTypeId = event[i].sensorTypeId,
.version = event[i].version,
.timestamp = event[i].timestamp,
.option = event[i].option,
.mode = event[i].mode,
.dataLen = event[i].dataLen
};
if (memcpy_s(transferEvent.data, SENSOR_MAX_LENGTH, event[i].data, event[i].dataLen) != EOK) {
HiLog::Error(LABEL, "%{public}s copy data failed", __func__);
return;
}
transferEvents.push_back(transferEvent);
}
auto ret = channel->SendData(transferEvents.data(), eventSize * sizeof(struct TransferMedicalSensorEvents));
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s send data failed, ret : %{public}d", __func__, ret);
uint32_t sensorId = event[eventSize - 1].sensorTypeId;
if (sensorId == FLUSH_COMPLETE_ID) {
sensorId = event[eventSize - 1].sensorTypeId;
}
cacheBuf[sensorId] = event[eventSize - 1];
}
}
int32_t MedicalSensorDataProcesser::CacheSensorEvent(const struct SensorEvent &event, sptr<MedicalSensorBasicDataChannel> &channel)
{
if (channel == nullptr) {
HiLog::Error(LABEL, "%{public}s channel cannot be null", __func__);
return INVALID_POINTER;
}
uint32_t ret = ERR_OK;
auto &cacheBuf = const_cast<std::unordered_map<uint32_t, struct SensorEvent> &>(channel->GetDataCacheBuf());
uint32_t sensorId = event.sensorTypeId;
if (sensorId == FLUSH_COMPLETE_ID) {
sensorId = event.sensorTypeId;
}
auto cacheEvent = cacheBuf.find(sensorId);
if (cacheEvent != cacheBuf.end()) {
// Try to send the last failed value, if it still fails, replace the previous cache directly
ret = channel->SendData(&cacheEvent->second, sizeof(struct SensorEvent));
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s ret : %{public}d", __func__, ret);
}
ret = channel->SendData(&event, sizeof(struct SensorEvent));
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s ret : %{public}d", __func__, ret);
cacheBuf[sensorId] = event;
} else {
cacheBuf.erase(cacheEvent);
}
} else {
ret = channel->SendData(&event, sizeof(struct SensorEvent));
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s ret : %{public}d", __func__, ret);
cacheBuf[sensorId] = event;
}
}
return ret;
}
void MedicalSensorDataProcesser::EventFilter(struct CircularEventBuf &eventsBuf)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
uint32_t realSensorId = 0;
uint32_t sensorId = eventsBuf.circularBuf[eventsBuf.readPosition].sensorTypeId;
HiLog::Debug(LABEL, "%{public}s sensorId = %{public}d, FLUSH_COMPLETE_ID=%{public}d", __func__, sensorId, FLUSH_COMPLETE_ID);
std::vector<sptr<MedicalSensorBasicDataChannel>> channelList;
if (sensorId == FLUSH_COMPLETE_ID) {
realSensorId = eventsBuf.circularBuf[eventsBuf.readPosition].sensorTypeId;
channelList = clientInfo_.GetSensorChannel(realSensorId);
} else {
channelList = clientInfo_.GetSensorChannel(sensorId);
}
auto flushInfo = flushInfo_.GetFlushInfo();
std::vector<struct FlushInfo> flushVec;
if (sensorId == FLUSH_COMPLETE_ID) {
HiLog::Debug(LABEL, "%{public}s sensorId : %{public}u", __func__, sensorId);
auto it = flushInfo.find(realSensorId);
if (it != flushInfo.end()) {
flushVec = it->second;
for (auto &channel : flushVec) {
if (flushInfo_.IsFlushChannelValid(channelList, channel.flushChannel)) {
SendEvents(channel.flushChannel, eventsBuf.circularBuf[eventsBuf.readPosition]);
flushInfo_.ClearFlushInfoItem(realSensorId);
break;
} else {
// The channel that store in the flushVec has invalid, so erase this channel directly
HiLog::Debug(LABEL, "%{public}s clear flush info", __func__);
flushInfo_.ClearFlushInfoItem(realSensorId);
}
}
}
} else {
if (channelList.empty() || channelList.size() == 0) {
HiLog::Error(LABEL, "%{public}s channelList is empty", __func__);
}
for (auto &channel : channelList) {
int32_t index = flushInfo_.GetFlushChannelIndex(flushVec, channel);
if (index >= 0) {
if (flushVec[index].flushFromEnable) {
HiLog::Info(LABEL, "%{public}s flushFromEnable", __func__);
continue;
}
}
/* if has some suspend flush, but this flush come from the flush function rather than enable,
so we need to calling GetSensorStatus to decided whether send this event. */
if (channel->GetSensorStatus()) {
SendEvents(channel, eventsBuf.circularBuf[eventsBuf.readPosition]);
}
}
}
}
int32_t MedicalSensorDataProcesser::ProcessEvents(sptr<ReportDataCache> dataCache)
{
if (dataCache == nullptr) {
HiLog::Error(LABEL, "%{public}s dataCallback cannot be null", __func__);
return INVALID_POINTER;
}
std::unique_lock<std::mutex> lk(MedicalSensorServiceImpl::dataMutex_);
MedicalSensorServiceImpl::dataCondition_.wait(lk);
auto &eventsBuf = dataCache->GetEventData();
if (eventsBuf.eventNum <= 0) {
HiLog::Error(LABEL, "%{public}s data cannot be empty", __func__);
return NO_EVENT;
}
int32_t eventNum = eventsBuf.eventNum;
HiLog::Debug(LABEL, "%{public}s data eventNum = %{public}d", __func__, eventNum);
for (int32_t i = 0; i < eventNum; i++) {
EventFilter(eventsBuf);
delete eventsBuf.circularBuf[eventsBuf.readPosition].data;
eventsBuf.circularBuf[eventsBuf.readPosition].data = nullptr;
eventsBuf.readPosition++;
if (eventsBuf.readPosition == CIRCULAR_BUF_LEN) {
eventsBuf.readPosition = 0;
}
eventsBuf.eventNum--;
}
return SUCCESS;
}
int32_t MedicalSensorDataProcesser::SendEvents(sptr<MedicalSensorBasicDataChannel> &channel, struct SensorEvent &event)
{
if (channel == nullptr) {
HiLog::Error(LABEL, "%{public}s channel cannot be null", __func__);
return INVALID_POINTER;
}
clientInfo_.UpdateDataQueue(event.sensorTypeId, event);
auto &cacheBuf = channel->GetDataCacheBuf();
if (cacheBuf.empty()) {
ReportData(channel, event);
} else {
CacheSensorEvent(event, channel);
}
clientInfo_.StoreEvent(event);
return SUCCESS;
}
int32_t MedicalSensorDataProcesser::DataThread(sptr<MedicalSensorDataProcesser> dataProcesser, sptr<ReportDataCache> dataCache)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
do {
if (dataProcesser->ProcessEvents(dataCache) == INVALID_POINTER) {
HiLog::Error(LABEL, "%{public}s callback cannot be null", __func__);
return INVALID_POINTER;
}
} while (1);
}
} // namespace Sensors
} // namespace OHOS
+219
View File
@@ -0,0 +1,219 @@
/*
* Copyright (c) 2021 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 "medical_dump.h"
#include <cinttypes>
#include <ctime>
#include <queue>
#include "medical_log_domain.h"
#include "medical_errors.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_SERVICE, "MedicalSensorDump" };
constexpr uint32_t MAX_DUMP_DATA_SIZE = 10;
constexpr uint32_t MS_NS = 1000000;
constexpr uint32_t PPG = 256;
constexpr int32_t MAX_DMUP_PARAM = 2;
enum {
PPG_DATA_SIZE = 400,
COMMON_DATA_SIZE = 1,
};
} // namespace
std::unordered_map<uint32_t, std::string> MedicalSensorDump::sensorMap_ = {
{ PPG, "PPG" },
};
bool MedicalSensorDump::DumpSensorHelp(int32_t fd, const std::vector<std::u16string> &args)
{
if ((args.empty()) || (args[0].compare(u"-h") != 0)) {
HiLog::Error(LABEL, "%{public}s args cannot be empty or invalid", __func__);
return false;
}
DumpHelp(fd);
return true;
}
void MedicalSensorDump::DumpHelp(int32_t fd)
{
dprintf(fd, "Usage:\n");
dprintf(fd, " -h: dump help\n");
dprintf(fd, " -l: dump the sensor list\n");
dprintf(fd, " -c: dump the sensor data channel info\n");
dprintf(fd, " -o: dump the opening sensors\n");
dprintf(fd, " -d: dump the last 10 packages sensor data\n");
}
bool MedicalSensorDump::DumpSensorList(int32_t fd, const std::vector<MedicalSensor> &sensors, const std::vector<std::u16string> &args)
{
if ((args.empty()) || (args[0].compare(u"-l") != 0)) {
HiLog::Error(LABEL, "%{public}s args cannot be empty or invalid", __func__);
return false;
}
DumpCurrentTime(fd);
dprintf(fd, "Total sensor:%d, MedicalSensor list:\n", int32_t { sensors.size() });
for (const auto &sensor : sensors) {
auto sensorId = sensor.GetSensorId();
dprintf(fd,
"sensorId:%8u | sensorType:%s | name:%s | vendor:%s | maxRange:%f | fifoMaxEventCount:%d "
"| minSamplePeriodNs:%lld | maxSamplePeriodNs:%lld\n",
sensorId, sensorMap_[sensorId].c_str(), sensor.GetName().c_str(), sensor.GetVendor().c_str(),
sensor.GetMaxRange(), sensor.GetFifoMaxEventCount(), (long long) { sensor.GetMinSamplePeriodNs() },
(long long) { sensor.GetMaxSamplePeriodNs() });
}
return true;
}
bool MedicalSensorDump::DumpSensorChannel(int32_t fd, ClientInfo &clientInfo, const std::vector<std::u16string> &args)
{
if ((args.empty()) || (args[0].compare(u"-c") != 0)) {
HiLog::Error(LABEL, "%{public}s args cannot be empty or invalid", __func__);
return false;
}
DumpCurrentTime(fd);
dprintf(fd, "MedicalSensor channel info:\n");
std::vector<MedicalSensorChannelInfo> channelInfo;
clientInfo.GetSensorChannelInfo(channelInfo);
for (const auto &channel : channelInfo) {
auto sensorId = channel.GetSensorId();
std::string cmds("");
auto cmdList = channel.GetCmdType();
for (auto cmd : cmdList) {
cmds += (std::to_string(cmd) + " ");
}
dprintf(fd,
"uid:%d | packageName:%s | sensorId:%8u | sensorType:%s | samplingPeriodNs:%d "
"| fifoCount:%u | cmdType:%s\n",
channel.GetUid(), channel.GetPackageName().c_str(), sensorId, sensorMap_[sensorId].c_str(),
int32_t { channel.GetSamplingPeriodNs() }, channel.GetFifoCount(), cmds.c_str());
}
return true;
}
bool MedicalSensorDump::DumpOpeningSensor(int32_t fd, const std::vector<MedicalSensor> &sensors, ClientInfo &clientInfo,
const std::vector<std::u16string> &args)
{
if ((args.empty()) || (args[0].compare(u"-o") != 0)) {
HiLog::Error(LABEL, "%{public}s args cannot be empty or invalid", __func__);
return false;
}
DumpCurrentTime(fd);
dprintf(fd, "Opening sensors:\n");
for (const auto &sensor : sensors) {
uint32_t sensorId = sensor.GetSensorId();
if (clientInfo.GetSensorState(sensorId) == SENSOR_ENABLED) {
dprintf(fd, "sensorId: %8u | sensorType: %s\n", sensorId, sensorMap_[sensorId].c_str());
}
}
return true;
}
bool MedicalSensorDump::DumpSensorData(int32_t fd, ClientInfo &clientInfo, const std::vector<std::u16string> &args)
{
if ((args.empty()) || (args[0].compare(u"-d") != 0)) {
HiLog::Error(LABEL, "%{public}s args cannot be empty or invalid", __func__);
return false;
}
dprintf(fd, "Last 10 packages sensor data:\n");
auto dataMap = clientInfo.GetDataQueue();
int32_t j = 0;
for (auto &sensorData : dataMap) {
uint32_t sensorId = sensorData.first;
dprintf(fd, "sensorId: %8u | sensorType: %s:\n", sensorId, sensorMap_[sensorId].c_str());
for (uint32_t i = 0; i < MAX_DUMP_DATA_SIZE && (!sensorData.second.empty()); i++) {
auto data = sensorData.second.front();
sensorData.second.pop();
timespec time = { 0, 0 };
struct tm *timeinfo = localtime(&(time.tv_sec));
if (timeinfo == nullptr) {
HiLog::Error(LABEL, "%{public}s timeinfo cannot be null", __func__);
return false;
}
dprintf(fd, " %2d (ts=%.9f, time=%02d:%02d:%02d.%03d) | data:%s", ++j, data.timestamp / 1e9,
timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, int32_t { (time.tv_nsec / MS_NS) },
GetDataBySensorId(sensorId, data).c_str());
}
}
return true;
}
void MedicalSensorDump::DumpCurrentTime(int32_t fd)
{
timespec curTime = { 0, 0 };
clock_gettime(CLOCK_REALTIME, &curTime);
struct tm *timeinfo = localtime(&(curTime.tv_sec));
if (timeinfo == nullptr) {
HiLog::Error(LABEL, "%{public}s timeinfo cannot be null", __func__);
return;
}
dprintf(fd, "Current time: %02d:%02d:%02d.%03d\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec,
int32_t { (curTime.tv_nsec / MS_NS) });
}
int32_t MedicalSensorDump::DataSizeBySensorId(uint32_t sensorId)
{
switch (sensorId) {
case PPG:
return PPG_DATA_SIZE;
default:
return COMMON_DATA_SIZE;
}
}
std::string MedicalSensorDump::GetDataBySensorId(uint32_t sensorId, struct SensorEvent &sensorData)
{
HiLog::Debug(LABEL, "%{public}s sensorId: %{public}u", __func__, sensorId);
std::string buffer;
int32_t dataLen = DataSizeBySensorId(sensorId);
for (int32_t i = 0; i < dataLen; ++i) {
buffer.append(std::to_string(sensorData.data[i])).append(",");
}
buffer.append("\n");
return buffer;
}
int32_t MedicalSensorDump::Dump(int32_t fd, const std::vector<std::u16string> &args,
std::vector<MedicalSensor> &sensors, ClientInfo &clientInfo)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if ((args.empty()) || (args[0].size() != MAX_DMUP_PARAM)) {
HiLog::Error(LABEL, "%{public}s param cannot be empty or the length is not 2", __func__);
dprintf(fd, "cmd param number is not equal to 2\n");
DumpHelp(fd);
return DUMP_PARAM_ERR;
}
bool helpRet = DumpSensorHelp(fd, args);
bool listRet = DumpSensorList(fd, sensors, args);
bool channelRet = DumpSensorChannel(fd, clientInfo, args);
bool openRet = DumpOpeningSensor(fd, sensors, clientInfo, args);
bool dataRet = DumpSensorData(fd, clientInfo, args);
bool total = helpRet + listRet + channelRet + openRet + dataRet;
if (!total) {
dprintf(fd, "cmd param is error\n");
DumpHelp(fd);
return DUMP_PARAM_ERR;
}
HiLog::Info(LABEL, "%{public}s end", __func__);
return ERR_OK;
}
} // namespace Sensors
} // namespace OHOS
+196
View File
@@ -0,0 +1,196 @@
/*
* Copyright (c) 2021 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 "medical_manager.h"
#include "medical.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_SERVICE, "MedicalSensorManager" };
constexpr uint32_t INVALID_SENSOR_ID = -1;
constexpr uint32_t PROXIMITY_SENSOR_ID = 50331904;
constexpr float PROXIMITY_FAR = 5.0;
} // namespace
void MedicalSensorManager::InitSensorMap(std::unordered_map<uint32_t, MedicalSensor> &sensorMap,
sptr<MedicalSensorDataProcesser> dataProcesser, sptr<ReportDataCache> dataCache)
{
std::lock_guard<std::mutex> sensorLock(sensorMapMutex_);
sensorMap_.insert(sensorMap.begin(), sensorMap.end());
sensorDataProcesser_ = dataProcesser;
reportDataCache_ = dataCache;
HiLog::Debug(LABEL, "%{public}s begin sensorMap_.size : %{public}d", __func__, int32_t { sensorMap_.size() });
return;
}
uint32_t MedicalSensorManager::GetSensorFlag(uint32_t sensorId)
{
uint32_t flag = SENSOR_ONE_SHOT;
auto sensor = sensorMap_.find(sensorId);
if (sensor != sensorMap_.end()) {
flag = sensor->second.GetFlags();
}
return flag;
}
bool MedicalSensorManager::SetBestSensorParams(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs)
{
HiLog::Debug(LABEL, "%{public}s begin, sensorId : %{public}u, samplingPeriodNs : %{public}d", __func__, sensorId,
int32_t { samplingPeriodNs });
if (sensorId == INVALID_SENSOR_ID) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
return false;
}
MedicalSensorBasicInfo sensorInfo = clientInfo_.GetBestSensorInfo(sensorId);
int64_t bestSamplingPeriodNs = sensorInfo.GetSamplingPeriodNs();
int64_t bestReportDelayNs = sensorInfo.GetMaxReportDelayNs();
if ((samplingPeriodNs > bestSamplingPeriodNs) && (maxReportDelayNs > bestReportDelayNs)) {
HiLog::Debug(LABEL, "%{public}s no need to reset sensor params", __func__);
return true;
}
bestSamplingPeriodNs = (samplingPeriodNs < bestSamplingPeriodNs) ? samplingPeriodNs : bestSamplingPeriodNs;
bestReportDelayNs = (maxReportDelayNs < bestReportDelayNs) ? maxReportDelayNs : bestReportDelayNs;
HiLog::Debug(LABEL, "%{public}s bestSamplingPeriodNs : %{public}d", __func__, int32_t { bestSamplingPeriodNs });
auto ret = sensorServiceImpl_.SetSensorConfig(sensorId, bestSamplingPeriodNs, bestReportDelayNs);
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s SetSensorConfig failed", __func__);
return false;
}
HiLog::Debug(LABEL, "%{public}s end", __func__);
return true;
}
bool MedicalSensorManager::ResetBestSensorParams(uint32_t sensorId)
{
HiLog::Debug(LABEL, "%{public}s begin, sensorId : %{public}u", __func__, sensorId);
if (sensorId == INVALID_SENSOR_ID) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
return false;
}
MedicalSensorBasicInfo sensorInfo = clientInfo_.GetBestSensorInfo(sensorId);
auto ret = sensorServiceImpl_.SetSensorConfig(sensorId, sensorInfo.GetSamplingPeriodNs(),
sensorInfo.GetMaxReportDelayNs());
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s SetSensorConfig failed", __func__);
return false;
}
HiLog::Debug(LABEL, "%{public}s end", __func__);
return true;
}
MedicalSensorBasicInfo MedicalSensorManager::GetSensorInfo(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs)
{
HiLog::Debug(LABEL, "%{public}s begin, sensorId : %{public}u", __func__, sensorId);
MedicalSensorBasicInfo sensorInfo;
std::lock_guard<std::mutex> sensorMapLock(sensorMapMutex_);
auto it = sensorMap_.find(sensorId);
if (it == sensorMap_.end()) {
sensorInfo.SetSamplingPeriodNs(samplingPeriodNs);
sensorInfo.SetMaxReportDelayNs(maxReportDelayNs);
sensorInfo.SetSensorState(SENSOR_ENABLED);
HiLog::Error(LABEL, "%{public}s sensorId invalid", __func__);
return sensorInfo;
}
int64_t curSamplingPeriodNs =
(samplingPeriodNs < it->second.GetMinSamplePeriodNs()) ? it->second.GetMinSamplePeriodNs() : samplingPeriodNs;
if (it->second.GetMaxSamplePeriodNs() != 0) {
curSamplingPeriodNs = (samplingPeriodNs > it->second.GetMaxSamplePeriodNs()) ? it->second.GetMaxSamplePeriodNs()
: curSamplingPeriodNs;
}
int32_t maxEventCount = it->second.GetFifoMaxEventCount();
if ((samplingPeriodNs == 0) || (maxEventCount > (INT64_MAX / samplingPeriodNs))) {
HiLog::Error(LABEL, "%{public}s failed, samplingPeriodNs overflow", __func__);
return sensorInfo;
}
int64_t supportDelay = samplingPeriodNs * maxEventCount;
int64_t curReportDelayNs = (maxReportDelayNs > supportDelay) ? supportDelay : maxReportDelayNs;
sensorInfo.SetSamplingPeriodNs(curSamplingPeriodNs);
sensorInfo.SetMaxReportDelayNs(curReportDelayNs);
sensorInfo.SetSensorState(SENSOR_ENABLED);
HiLog::Debug(LABEL, "%{public}s end", __func__);
return sensorInfo;
}
ErrCode MedicalSensorManager::SaveSubscriber(uint32_t sensorId, uint32_t pid, int64_t samplingPeriodNs,
int64_t maxReportDelayNs)
{
MedicalSensorBasicInfo sensorInfo = GetSensorInfo(sensorId, samplingPeriodNs, maxReportDelayNs);
auto updateRet = clientInfo_.UpdateSensorInfo(sensorId, pid, sensorInfo);
if (!updateRet) {
HiLog::Error(LABEL, "%{public}s UpdateSensorInfo failed", __func__);
return UPDATE_SENSOR_INFO_ERR;
}
return ERR_OK;
}
void MedicalSensorManager::StartDataReportThread()
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (!dataThread_.joinable()) {
HiLog::Warn(LABEL, "%{public}s dataThread_ started", __func__);
std::thread senocdDataThread(MedicalSensorDataProcesser::DataThread, sensorDataProcesser_, reportDataCache_);
dataThread_ = std::move(senocdDataThread);
}
HiLog::Debug(LABEL, "%{public}s end", __func__);
}
bool MedicalSensorManager::IsOtherClientUsingSensor(uint32_t sensorId, int32_t clientPid)
{
HiLog::Debug(LABEL, "%{public}s begin, sensorId : %{public}u", __func__, sensorId);
if (clientInfo_.OnlyCurPidSensorEnabled(sensorId, clientPid)) {
HiLog::Warn(LABEL, "%{public}s Only current client using this sensor", __func__);
return false;
}
clientInfo_.ClearCurPidSensorInfo(sensorId, clientPid);
if (!ResetBestSensorParams(sensorId)) {
HiLog::Warn(LABEL, "%{public}s ResetBestSensorParams failed", __func__);
}
HiLog::Debug(LABEL, "%{public}s other client is using this sensor", __func__);
return true;
}
ErrCode MedicalSensorManager::AfterDisableSensor(uint32_t sensorId)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (!clientInfo_.ClearSensorInfo(sensorId)) {
HiLog::Error(LABEL, "%{public}s ClearSensorInfo failed", __func__);
return CLEAR_SENSOR_INFO_ERR;
}
if (sensorId == PROXIMITY_SENSOR_ID) {
struct SensorEvent event;
auto ret = clientInfo_.GetStoreEvent(sensorId, event);
if (ret == ERR_OK) {
HiLog::Debug(LABEL, "%{public}s change the default state is far", __func__);
// event.light.data[0] = PROXIMITY_FAR;
event.data[0] = PROXIMITY_FAR;
clientInfo_.StoreEvent(event);
}
}
HiLog::Debug(LABEL, "%{public}s end", __func__);
return ERR_OK;
}
void MedicalSensorManager::GetPackageNameFromUid(int32_t uid, std::string &packageName)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
}
} // namespace Sensors
} // namespace OHOS
+472
View File
@@ -0,0 +1,472 @@
/*
* Copyright (c) 2021 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 "medical_service.h"
#include <cinttypes>
#include <sys/socket.h>
#include <unistd.h>
#include "hisysevent.h"
#include "iservice_registry.h"
#include "permission_util.h"
#include "securec.h"
#include "medical.h"
#include "medical_dump.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
#include "system_ability_definition.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_SERVICE, "PpgService" };
constexpr uint32_t INVALID_SENSOR_ID = -1;
constexpr int32_t INVALID_PID = -1;
constexpr int64_t MAX_EVENT_COUNT = 1000;
constexpr uint32_t REPORT_STATUS_LEN = 20;
int32_t g_sendFd = 0;
enum {
FLUSH = 0,
SET_MODE,
RESERVED,
};
} // namespace
REGISTER_SYSTEM_ABILITY_BY_ID(MedicalSensorService, MEDICAL_SENSOR_SERVICE_ABILITY_ID, true);
MedicalSensorService::MedicalSensorService(int32_t systemAbilityId, bool runOnCreate)
: SystemAbility(systemAbilityId, runOnCreate), state_(MedicalSensorServiceState::STATE_STOPPED)
{}
void MedicalSensorService::OnDump()
{
HiLog::Info(LABEL, "OnDump");
}
void MedicalSensorService::OnStart()
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (state_ == MedicalSensorServiceState::STATE_RUNNING) {
HiLog::Warn(LABEL, "%{public}s MedicalSensorService has already started", __func__);
return;
}
if (!InitInterface()) {
HiLog::Error(LABEL, "%{public}s Init interface error", __func__);
return;
}
if (!InitDataCache()) {
HiLog::Error(LABEL, "%{public}s Init data callback error", __func__);
return;
}
if (!InitSensorList()) {
HiLog::Error(LABEL, "%{public}s Init sensor list error", __func__);
return;
}
sensorDataProcesser_ = new (std::nothrow) MedicalSensorDataProcesser(sensorMap_);
if (sensorDataProcesser_ == nullptr) {
HiLog::Error(LABEL, "%{public}s failed, sensorDataProcesser_ cannot be null", __func__);
return;
}
bool isPublished = SystemAbility::Publish(this);
if (!isPublished) {
HiLog::Error(LABEL, "%{public}s publish MedicalSensorService error", __func__);
return;
}
sensorManager_.InitSensorMap(sensorMap_, sensorDataProcesser_, reportDataCache_);
state_ = MedicalSensorServiceState::STATE_RUNNING;
}
bool MedicalSensorService::InitInterface()
{
auto ret = sensorServiceImpl_.InitSensorServiceImpl();
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s InitSensorServiceImpl failed", __func__);
return false;
}
return true;
}
bool MedicalSensorService::InitDataCache()
{
HiLog::Error(LABEL, "===%{public}s in", __func__);
reportDataCache_ = new (std::nothrow) ReportDataCache();
if (reportDataCache_ == nullptr) {
HiLog::Error(LABEL, "%{public}s failed, reportDataCache_ cannot be null", __func__);
return false;
}
DataCacheFunc cacheData = &ReportDataCache::CacheData;
auto ret = sensorServiceImpl_.RegisteDataReport(cacheData, reportDataCache_);
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s RegisterDataReport failed", __func__);
return false;
}
return true;
}
bool MedicalSensorService::InitSensorList()
{
std::lock_guard<std::mutex> sensorLock(sensorsMutex_);
sensors_ = sensorServiceImpl_.GetSensorList();
{
std::lock_guard<std::mutex> sensorMapLock(sensorMapMutex_);
for (const auto &it : sensors_) {
sensorMap_.insert(std::make_pair(it.GetSensorId(), it));
}
}
return true;
}
void MedicalSensorService::OnStop()
{
if (state_ == MedicalSensorServiceState::STATE_STOPPED) {
HiLog::Warn(LABEL, "%{public}s already stopped", __func__);
return;
}
state_ = MedicalSensorServiceState::STATE_STOPPED;
}
void MedicalSensorService::ReportSensorUsedInfo(uint32_t sensorId, bool enable)
{
char uidChar[REPORT_STATUS_LEN];
int32_t uid = this->GetCallingUid();
std::string packageName("");
sensorManager_.GetPackageNameFromUid(uid, packageName);
int32_t ret = sprintf_s(uidChar, sizeof(uidChar), "%d", uid);
if (ret < 0) {
HiLog::Error(LABEL, "%{public}s sprintf uidChar failed", __func__);
return;
}
const int logLevel = 4;
std::string message;
if (enable) {
// define in LogPower.java, 500 stand for enable sensor
message.append("uid : ").append(std::to_string(uid)).append(" pkgName : ").append(packageName)
.append(" type : ");
HiSysEvent::Write(HiSysEvent::Domain::SENSORS, "EnableAfe", HiSysEvent::EventType::BEHAVIOR,
"LEVEL", logLevel, "TAG", "DUBAI_TAG_HHEALTH_ENABLE", "MESSAGE", message);
} else {
// define in LogPower.java, 501 stand for disable sensor
message.append("uid : ").append(std::to_string(uid)).append(" pkgName : ").append(packageName)
.append(" type : ");
HiSysEvent::Write(HiSysEvent::Domain::SENSORS, "DisableAfe", HiSysEvent::EventType::BEHAVIOR,
"LEVEL", logLevel, "TAG", "DUBAI_TAG_HHEALTH_DISABLE", "MESSAGE", message);
}
HiLog::Info(LABEL, "%{public}s end, packageName : %{public}s", __func__, packageName.c_str());
}
void MedicalSensorService::ReportOnChangeData(uint32_t sensorId)
{
std::lock_guard<std::mutex> sensorMapLock(sensorMapMutex_);
auto it = sensorMap_.find(sensorId);
if (it == sensorMap_.end()) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
return;
}
if ((SENSOR_ON_CHANGE & it->second.GetFlags()) != SENSOR_ON_CHANGE) {
HiLog::Warn(LABEL, "%{public}s it is not onchange data, no need to report", __func__);
return;
}
struct SensorEvent event;
auto ret = clientInfo_.GetStoreEvent(sensorId, event);
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s there is no data to be reported", __func__);
return;
}
sptr<MedicalSensorBasicDataChannel> channel = clientInfo_.GetSensorChannelByPid(this->GetCallingPid());
if (channel == nullptr) {
HiLog::Error(LABEL, "%{public}s there is no channel to be reported", __func__);
return;
}
auto sendRet = channel->SendData(&event, sizeof(event));
if (sendRet != ERR_OK) {
HiLog::Error(LABEL, "%{public}s send data failed", __func__);
return;
}
}
ErrCode MedicalSensorService::SaveSubscriber(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs)
{
auto ret = sensorManager_.SaveSubscriber(sensorId, this->GetCallingPid(), samplingPeriodNs, maxReportDelayNs);
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s SaveSubscriber failed", __func__);
return ret;
}
sensorManager_.StartDataReportThread();
if (!sensorManager_.SetBestSensorParams(sensorId, samplingPeriodNs, maxReportDelayNs)) {
HiLog::Error(LABEL, "%{public}s SetBestSensorParams failed", __func__);
clientInfo_.RemoveSubscriber(sensorId, this->GetCallingPid());
return ENABLE_SENSOR_ERR;
}
return ret;
}
ErrCode MedicalSensorService::EnableSensor(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs)
{
HiLog::Debug(LABEL, "%{public}s begin, sensorId : %{public}u, samplingPeriodNs : %{public}"
PRId64, __func__, sensorId, samplingPeriodNs);
if ((sensorId == INVALID_SENSOR_ID) ||
((samplingPeriodNs != 0L) && ((maxReportDelayNs / samplingPeriodNs) > MAX_EVENT_COUNT))) {
HiLog::Error(LABEL, "%{public}s sensorId is 0 or maxReportDelayNs exceeded the maximum value", __func__);
return ERR_NO_INIT;
}
ReportSensorUsedInfo(sensorId, SENSOR_ENABLED);
std::lock_guard<std::mutex> serviceLock(serviceLock_);
if (clientInfo_.GetSensorState(sensorId) == SENSOR_ENABLED) {
HiLog::Warn(LABEL, "%{public}s afe.has been enabled already", __func__);
auto ret = SaveSubscriber(sensorId, samplingPeriodNs, maxReportDelayNs);
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s SaveSubscriber failed", __func__);
return ret;
}
uint32_t flag = sensorManager_.GetSensorFlag(sensorId);
int32_t pid = this->GetCallingPid();
ret = flushInfo_.FlushProcess(sensorId, flag, pid, true);
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s ret : %{public}d", __func__, ret);
}
ReportOnChangeData(sensorId);
return ERR_OK;
}
auto ret = SaveSubscriber(sensorId, samplingPeriodNs, maxReportDelayNs);
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s SaveSubscriber failed", __func__);
clientInfo_.RemoveSubscriber(sensorId, this->GetCallingPid());
return ret;
}
ret = sensorServiceImpl_.EnableSensor(sensorId);
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s EnableSensor failed", __func__);
clientInfo_.RemoveSubscriber(sensorId, this->GetCallingPid());
return ENABLE_SENSOR_ERR;
}
return ret;
}
ErrCode MedicalSensorService::DisableSensor(uint32_t sensorId)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (sensorId == INVALID_SENSOR_ID) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
return ERR_NO_INIT;
}
ReportSensorUsedInfo(sensorId, SENSOR_DISABLED);
std::lock_guard<std::mutex> serviceLock(serviceLock_);
const int32_t clientPid = this->GetCallingPid();
if (clientPid < 0) {
HiLog::Error(LABEL, "%{public}s clientPid is invalid, clientPid : %{public}d", __func__, clientPid);
return CLIENT_PID_INVALID_ERR;
}
if (clientInfo_.GetSensorState(sensorId) != SENSOR_ENABLED) {
HiLog::Error(LABEL, "%{public}s sensor should be enabled first", __func__);
return DISABLE_SENSOR_ERR;
}
if (sensorManager_.IsOtherClientUsingSensor(sensorId, clientPid)) {
HiLog::Warn(LABEL, "%{public}s other client is using this sensor now, cannot disable", __func__);
return ERR_OK;
}
if (sensorServiceImpl_.DisableSensor(sensorId) != ERR_OK) {
HiLog::Error(LABEL, "%{public}s DisableSensor failed", __func__);
return DISABLE_SENSOR_ERR;
}
clientInfo_.DestroyCmd(this->GetCallingUid());
clientInfo_.ClearDataQueue(sensorId);
return sensorManager_.AfterDisableSensor(sensorId);
}
ErrCode MedicalSensorService::SetOption(uint32_t sensorId, uint32_t opt)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (sensorId == INVALID_SENSOR_ID) {
HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__);
return ERR_NO_INIT;
}
if (sensorServiceImpl_.SetOption(sensorId, opt) != ERR_OK) {
HiLog::Error(LABEL, "%{public}s SetOption failed", __func__);
return DISABLE_SENSOR_ERR;
}
HiLog::Debug(LABEL, "%{public}s end", __func__);
return ERR_OK;
}
int32_t MedicalSensorService::GetSensorState(uint32_t sensorId)
{
if (sensorId == INVALID_SENSOR_ID) {
HiLog::Error(LABEL, "%{public}s sensorId is 0", __func__);
return ERR_NO_INIT;
}
auto state = clientInfo_.GetSensorState(sensorId);
return static_cast<int32_t>(state);
}
ErrCode MedicalSensorService::RunCommand(uint32_t sensorId, uint32_t cmdType, uint32_t params)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (sensorId == INVALID_SENSOR_ID || ((cmdType != FLUSH) && (cmdType != SET_MODE))) {
HiLog::Error(LABEL, "%{public}s sensorId or cmd is invalid", __func__);
return ERR_NO_INIT;
}
std::lock_guard<std::mutex> serviceLock(serviceLock_);
uint32_t flag = sensorManager_.GetSensorFlag(sensorId);
if (cmdType == FLUSH) {
int32_t pid = this->GetCallingPid();
HiLog::Info(LABEL, "%{public}s sensorId : %{public}u, flag : %{public}u", __func__, sensorId, flag);
auto retFlush = flushInfo_.FlushProcess(sensorId, flag, pid, false);
if (retFlush != ERR_OK) {
HiLog::Error(LABEL, "%{public}s ret : %{public}d", __func__, retFlush);
}
return retFlush;
}
if (sensorServiceImpl_.RunCommand(sensorId, cmdType, params) != ERR_OK) {
HiLog::Error(LABEL, "%{public}s RunCommand failed", __func__);
return RUN_COMMAND_ERR;
}
auto uid = this->GetCallingUid();
clientInfo_.UpdateCmd(sensorId, uid, cmdType);
return ERR_OK;
}
std::vector<MedicalSensor> MedicalSensorService::GetSensorList()
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
std::lock_guard<std::mutex> sensorLock(sensorsMutex_);
sensors_ = sensorServiceImpl_.GetSensorList();
for (const auto &it : sensors_) {
std::lock_guard<std::mutex> sensorMapLock(sensorMapMutex_);
sensorMap_.insert(std::make_pair(it.GetSensorId(), it));
}
HiLog::Debug(LABEL, "%{public}s end", __func__);
return sensors_;
}
ErrCode MedicalSensorService::TransferDataChannel(const sptr<MedicalSensorBasicDataChannel> &sensorBasicDataChannel,
const sptr<IRemoteObject> &afeClient)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
g_sendFd = sensorBasicDataChannel->GetSendDataFd();
if ((sensorBasicDataChannel == nullptr)) {
HiLog::Error(LABEL, "%{public}s sensorBasicDataChannel cannot be null", __func__);
return ERR_NO_INIT;
}
auto pid = this->GetCallingPid();
auto uid = this->GetCallingUid();
if (!clientInfo_.UpdateUid(pid, uid)) {
HiLog::Error(LABEL, "%{public}s UpdateUid failed", __func__);
return UPDATE_UID_ERR;
}
if (!clientInfo_.UpdateSensorChannel(pid, sensorBasicDataChannel)) {
HiLog::Error(LABEL, "%{public}s UpdateSensorChannel failed", __func__);
return UPDATE_SENSOR_CHANNEL_ERR;
}
sensorBasicDataChannel->SetSensorStatus(true);
RegisterClientDeathRecipient(afeClient, pid);
HiLog::Debug(LABEL, "%{public}s end", __func__);
return ERR_OK;
}
ErrCode MedicalSensorService::DestroySensorChannel(sptr<IRemoteObject> afeClient)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
const int32_t clientPid = this->GetCallingPid();
if (clientPid < 0) {
HiLog::Error(LABEL, "%{public}s clientPid is invalid, clientPid : %{public}d", __func__, clientPid);
return CLIENT_PID_INVALID_ERR;
}
std::lock_guard<std::mutex> serviceLock(serviceLock_);
bool destoryRet = clientInfo_.DestroySensorChannel(clientPid);
if (!destoryRet) {
HiLog::Error(LABEL, "%{public}s DestroySensorChannel failed", __func__);
return DESTROY_SENSOR_CHANNEL_ERR;
}
clientInfo_.DestroyCmd(this->GetCallingUid());
UnregisterClientDeathRecipient(afeClient);
HiLog::Info(LABEL, "%{public}s end", __func__);
return ERR_OK;
}
void MedicalSensorService::ProcessDeathObserver(const wptr<IRemoteObject> &object)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
sptr<IRemoteObject> client = object.promote();
if (client == nullptr) {
HiLog::Error(LABEL, "%{public}s client cannot be null", __func__);
return;
}
int32_t pid = clientInfo_.FindClientPid(client);
if (pid == INVALID_PID) {
HiLog::Error(LABEL, "%{public}s pid is -1", __func__);
return;
}
HiLog::Info(LABEL, "%{public}s pid is %d", __func__, pid);
clientInfo_.DestroySensorChannel(pid);
clientInfo_.DestroyClientPid(client);
clientInfo_.DestroyCmd(this->GetCallingUid());
HiLog::Info(LABEL, "%{public}s end", __func__);
}
void MedicalSensorService::RegisterClientDeathRecipient(sptr<IRemoteObject> afeClient, int32_t pid)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
sptr<IMedicalSensorClient> client = iface_cast<IMedicalSensorClient>(afeClient);
clientDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<MedicalSensorService *>(this));
if (clientDeathObserver_ == nullptr) {
HiLog::Error(LABEL, "%{public}s clientDeathObserver_ cannot be null", __func__);
return;
}
afeClient->AddDeathRecipient(clientDeathObserver_);
// client->AsObject()->AddDeathRecipient(clientDeathObserver_);
HiLog::Info(LABEL, "%{public}s add clientDeathObserver_", __func__);
clientInfo_.SaveClientPid(afeClient, pid);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
void MedicalSensorService::UnregisterClientDeathRecipient(sptr<IRemoteObject> afeClient)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
sptr<IMedicalSensorClient> client = iface_cast<IMedicalSensorClient>(afeClient);
clientDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<MedicalSensorService *>(this));
if (clientDeathObserver_ == nullptr) {
HiLog::Error(LABEL, "%{public}s clientDeathObserver_ cannot be null", __func__);
return;
}
afeClient->RemoveDeathRecipient(clientDeathObserver_);
// client->AsObject()->RemoveDeathRecipient(clientDeathObserver_);
clientInfo_.DestroyClientPid(afeClient);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
int32_t MedicalSensorService::Dump(int32_t fd, const std::vector<std::u16string> &args)
{
MedicalSensorDump &sensorDump = MedicalSensorDump::GetInstance();
return sensorDump.Dump(fd, args, sensors_, clientInfo_);
}
} // namespace Sensors
} // namespace OHOS
+226
View File
@@ -0,0 +1,226 @@
/*
* Copyright (c) 2021 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 "medical_service_impl.h"
#include <cmath>
#include <cstring>
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_SERVICE, "MedicalSensorServiceImpl" };
}
DataCacheFunc MedicalSensorServiceImpl::cacheData_ = nullptr;
sptr<ReportDataCache> MedicalSensorServiceImpl::reportDataCache_ = nullptr;
std::mutex MedicalSensorServiceImpl::dataMutex_;
std::condition_variable MedicalSensorServiceImpl::dataCondition_;
ErrCode MedicalSensorServiceImpl::InitSensorServiceImpl()
{
HiLog::Info(LABEL, "%{public}s begin", "InitSensorServiceImpl");
sensorInterface_ = NewSensorInterfaceInstance();
if (sensorInterface_ == nullptr) {
HiLog::Error(LABEL, " %{public}s,", "test sensorHdi get Module instance failed\n\r");
return ERR_INVALID_VALUE;
}
HiLog::Info(LABEL, "%{public}s end", "InitSensorServiceImpl");
return ERR_OK;
}
std::vector<MedicalSensor> MedicalSensorServiceImpl::GetSensorList() const
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (sensorInterface_ == nullptr) {
HiLog::Error(LABEL, " %{public}s,", "test sensorHdi get Module instance failed\n\r");
return std::vector<MedicalSensor>();
}
struct SensorInformation *sensorInfo = nullptr;
int32_t count = 0;
int32_t ret = sensorInterface_->GetAllSensors(&sensorInfo, &count);
if (ret != 0) {
HiLog::Error(LABEL, "Get sensor list failed!");
return std::vector<MedicalSensor>();
}
HiLog::Info(LABEL, "GetAllSensors success, sensor counts: %{public}d", count);
std::vector<MedicalSensor> list;
for (int i = 0; i < count; i++) {
const std::string sensorName(sensorInfo->sensorName);
const std::string vendorName(sensorInfo->vendorName);
const int32_t sensorId = sensorInfo->sensorId;
HiLog::Info(LABEL, " %{public}d, %{public}s, %{public}s", sensorId, sensorName.c_str(),
vendorName.c_str());
MedicalSensor sensor;
sensor.SetSensorId(sensorId);
sensor.SetName(sensorName.c_str());
sensor.SetVendor(vendorName.c_str());
list.push_back(sensor);
sensorInfo++;
}
HiLog::Info(LABEL, "%{public}s end", __func__);
return list;
}
ErrCode MedicalSensorServiceImpl::EnableSensor(uint32_t sensorId) const
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (sensorInterface_ == nullptr) {
HiLog::Error(LABEL, " %{public}s,", "test sensorHdi get Module instance failed\n\r");
return ERR_INVALID_VALUE;
}
int32_t ret = sensorInterface_->Enable(sensorId);
if (ret < 0) {
HiLog::Error(LABEL, "%{public}s is failed", __func__);
return -1;
}
HiLog::Info(LABEL, "%{public}s end", __func__);
return ERR_OK;
}
ErrCode MedicalSensorServiceImpl::DisableSensor(uint32_t sensorId) const
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (sensorInterface_ == nullptr) {
HiLog::Error(LABEL, " %{public}s,", "test sensorHdi get Module instance failed\n\r");
return ERR_INVALID_VALUE;
}
int32_t ret = sensorInterface_->Disable(sensorId);
if (ret < 0) {
HiLog::Error(LABEL, "%{public}s is failed", __func__);
return -1;
}
HiLog::Info(LABEL, "%{public}s end", __func__);
return ERR_OK;
}
ErrCode MedicalSensorServiceImpl::SetOption(uint32_t sensorId, uint32_t opt) const
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (sensorInterface_ == nullptr) {
HiLog::Error(LABEL, " %{public}s,", "test sensorHdi get Module instance failed\n\r");
return ERR_INVALID_VALUE;
}
int32_t ret = sensorInterface_->SetOption(sensorId, opt);
if (ret < 0) {
HiLog::Error(LABEL, "%{public}s is failed", __func__);
return -1;
}
HiLog::Info(LABEL, "%{public}s end", __func__);
return ERR_OK;
}
ErrCode MedicalSensorServiceImpl::RunCommand(uint32_t sensorId, int32_t cmd, int32_t params) const
{
return ERR_OK;
}
ErrCode MedicalSensorServiceImpl::SetSensorConfig(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) const
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if (sensorInterface_ == nullptr) {
HiLog::Error(LABEL, " %{public}s,", "test sensorHdi get Module instance failed\n\r");
return ERR_INVALID_VALUE;
}
HiLog::Debug(LABEL, "%{public}s end", __func__);
return ERR_OK;
}
int32_t MedicalSensorServiceImpl::AfeDataCallback(const struct SensorEvents *event)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if ((event == nullptr) || (event->dataLen == 0)) {
HiLog::Error(LABEL, "%{public}s event is NULL", __func__);
return ERR_INVALID_VALUE;
}
if ((reportDataCache_ == nullptr) || (cacheData_ == nullptr)) {
HiLog::Error(LABEL, "%{public}s reportDataCache_ and cacheData_ cannot be null", __func__);
return ERR_INVALID_VALUE;
}
(void)(reportDataCache_->*cacheData_)(reinterpret_cast<const struct SensorEvent*>(event),
reportDataCache_);
dataCondition_.notify_one();
return ERR_OK;
}
ErrCode MedicalSensorServiceImpl::Register(RecordDataCallback cb) const
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (sensorInterface_ == nullptr) {
HiLog::Error(LABEL, " %{public}s,", "test sensorHdi get Module instance failed\n\r");
return ERR_INVALID_VALUE;
}
int32_t ret = sensorInterface_->Register(SENSORS_HEALTH, cb);
//int32_t ret = sensorInterface_->Register(HEALTH_TYPE_MAXID, cb);
if (ret < 0) {
HiLog::Error(LABEL, "%{public}s failed", __func__);
return ERR_INVALID_VALUE;
}
HiLog::Info(LABEL, "%{public}s end", __func__);
return ERR_OK;
}
ErrCode MedicalSensorServiceImpl::RegisteDataReport(DataCacheFunc cacheData, sptr<ReportDataCache> reportDataCallback)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (reportDataCallback == nullptr) {
HiLog::Error(LABEL, "%{public}s failed, reportDataCallback cannot be null", __func__);
return ERR_NO_INIT;
}
Register(AfeDataCallback);
cacheData_ = cacheData;
reportDataCache_ = reportDataCallback;
HiLog::Info(LABEL, "%{public}s end", __func__);
return ERR_OK;
}
ErrCode MedicalSensorServiceImpl::Unregister(void) const
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
if (sensorInterface_ == nullptr) {
HiLog::Error(LABEL, " %{public}s,", "test sensorHdi get Module instance failed\n\r");
return ERR_INVALID_VALUE;
}
int32_t ret = sensorInterface_->Unregister(SENSORS_HEALTH);
//int32_t ret = sensorInterface_->Unregister(HEALTH_TYPE_MAXID);
if (ret < 0) {
HiLog::Error(LABEL, "%{public}s failed", __func__);
return ERR_INVALID_VALUE;
}
HiLog::Info(LABEL, "%{public}s end", __func__);
return ERR_OK;
}
} // namespace Sensors
} // namespace OHOS
+189
View File
@@ -0,0 +1,189 @@
/*
* Copyright (c) 2021 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 "medical_service_stub.h"
#include <string>
#include <sys/socket.h>
#include <unistd.h>
#include <vector>
#include "ipc_skeleton.h"
#include "message_parcel.h"
#include "permission_util.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_SERVICE, "MedicalSensorServiceStub" };
} // namespace
MedicalSensorServiceStub::MedicalSensorServiceStub()
{
HiLog::Info(LABEL, "%{public}s begin, %{public}p", __func__, this);
baseFuncs_[ENABLE_SENSOR] = &MedicalSensorServiceStub::AfeEnableInner;
baseFuncs_[DISABLE_SENSOR] = &MedicalSensorServiceStub::AfeDisableInner;
baseFuncs_[GET_SENSOR_STATE] = &MedicalSensorServiceStub::GetAfeStateInner;
baseFuncs_[RUN_COMMAND] = &MedicalSensorServiceStub::RunCommandInner;
baseFuncs_[GET_SENSOR_LIST] = &MedicalSensorServiceStub::GetAllSensorsInner;
baseFuncs_[TRANSFER_DATA_CHANNEL] = &MedicalSensorServiceStub::CreateDataChannelInner;
baseFuncs_[DESTROY_SENSOR_CHANNEL] = &MedicalSensorServiceStub::DestroyDataChannelInner;
baseFuncs_[SET_OPTION] = &MedicalSensorServiceStub::AfeSetOptionInner;
}
MedicalSensorServiceStub::~MedicalSensorServiceStub()
{
HiLog::Info(LABEL, "%{public}s begin, yigou %{public}p", __func__, this);
baseFuncs_.clear();
}
int32_t MedicalSensorServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
HiLog::Debug(LABEL, "%{public}s begin, cmd : %{public}u", __func__, code);
std::u16string descriptor = MedicalSensorServiceStub::GetDescriptor();
std::u16string remoteDescriptor = data.ReadInterfaceToken();
if (descriptor != remoteDescriptor) {
HiLog::Error(LABEL, "%{public}s client and service descriptors are inconsistent", __func__);
return OBJECT_NULL;
}
auto itFunc = baseFuncs_.find(code);
if (itFunc != baseFuncs_.end()) {
auto memberFunc = itFunc->second;
if (memberFunc != nullptr) {
return (this->*memberFunc)(data, reply);
}
}
HiLog::Debug(LABEL, "%{public}s no member func supporting, applying default process", __func__);
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
ErrCode MedicalSensorServiceStub::AfeEnableInner(MessageParcel &data, MessageParcel &reply)
{
(void)reply;
uint32_t sensorId = data.ReadUint32();
PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
if (!permissionUtil.CheckCallingPermission(sensorId)) {
HiLog::Error(LABEL, "%{public}s permission denied", __func__);
return ERR_PERMISSION_DENIED;
}
return EnableSensor(sensorId, data.ReadInt64(), data.ReadInt64());
}
ErrCode MedicalSensorServiceStub::AfeDisableInner(MessageParcel &data, MessageParcel &reply)
{
(void)reply;
uint32_t sensorId = data.ReadUint32();
PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
if (!permissionUtil.CheckCallingPermission(sensorId)) {
HiLog::Error(LABEL, "%{public}s permission denied", __func__);
return ERR_PERMISSION_DENIED;
}
return DisableSensor(sensorId);
}
ErrCode MedicalSensorServiceStub::AfeSetOptionInner(MessageParcel &data, MessageParcel &reply)
{
(void)reply;
uint32_t sensorId = data.ReadUint32();
uint32_t opt = data.ReadUint32();
PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
if (!permissionUtil.CheckCallingPermission(sensorId)) {
HiLog::Error(LABEL, "%{public}s permission denied", __func__);
return ERR_PERMISSION_DENIED;
}
return SetOption(sensorId, opt);
}
ErrCode MedicalSensorServiceStub::GetAfeStateInner(MessageParcel &data, MessageParcel &reply)
{
(void)reply;
uint32_t sensorId = data.ReadUint32();
PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
if (!permissionUtil.CheckCallingPermission(sensorId)) {
HiLog::Error(LABEL, "%{public}s permission denied", __func__);
return ERR_PERMISSION_DENIED;
}
return GetSensorState(sensorId);
}
ErrCode MedicalSensorServiceStub::RunCommandInner(MessageParcel &data, MessageParcel &reply)
{
(void)reply;
uint32_t sensorId = data.ReadUint32();
PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
if (!permissionUtil.CheckCallingPermission(sensorId)) {
HiLog::Error(LABEL, "%{public}s permission denied", __func__);
return ERR_PERMISSION_DENIED;
}
return RunCommand(sensorId, data.ReadUint32(), data.ReadUint32());
}
ErrCode MedicalSensorServiceStub::GetAllSensorsInner(MessageParcel &data, MessageParcel &reply)
{
(void)data;
std::vector<MedicalSensor> sensors(GetSensorList());
int32_t sensorCount = int32_t { sensors.size() };
HiLog::Debug(LABEL, "%{public}s sensorCount : %{public}d", __func__, sensorCount);
reply.WriteInt32(sensorCount);
for (int32_t i = 0; i < sensorCount; i++) {
bool flag = sensors[i].Marshalling(reply);
if (!flag) {
HiLog::Error(LABEL, "Marshalling sensor %{public}d failed", i);
return GET_SENSOR_LIST_ERR;
}
}
return NO_ERROR;
}
ErrCode MedicalSensorServiceStub::CreateDataChannelInner(MessageParcel &data, MessageParcel &reply)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
(void)reply;
sptr<MedicalSensorBasicDataChannel> afeChannel = new (std::nothrow) MedicalSensorBasicDataChannel();
if (afeChannel == nullptr) {
HiLog::Error(LABEL, "%{public}s afe.hannel cannot be null", __func__);
return OBJECT_NULL;
}
auto ret = afeChannel->CreateSensorBasicChannel(data);
if (ret != ERR_OK) {
HiLog::Error(LABEL, "%{public}s CreateSensorBasicChannel ret : %{public}d", __func__, ret);
return OBJECT_NULL;
}
sptr<IRemoteObject> afeClient = data.ReadRemoteObject();
if (afeClient == nullptr) {
HiLog::Error(LABEL, "%{public}s afeClient cannot be null", __func__);
return OBJECT_NULL;
}
return TransferDataChannel(afeChannel, afeClient);
}
ErrCode MedicalSensorServiceStub::DestroyDataChannelInner(MessageParcel &data, MessageParcel &reply)
{
sptr<IRemoteObject> afeClient = data.ReadRemoteObject();
if (afeClient == nullptr) {
HiLog::Error(LABEL, "%{public}s afeClient cannot be null", __func__);
return OBJECT_NULL;
}
return DestroySensorChannel(afeClient);
}
} // namespace Sensors
} // namespace OHOS
+23
View File
@@ -0,0 +1,23 @@
# Copyright (c) 2021 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/test.gni")
########################################################
group("unittest") {
testonly = true
deps = [ "unittest/common:unittest" ]
if (is_phone_product) {
deps += [ "unittest/phone:unittest" ]
}
}
+49
View File
@@ -0,0 +1,49 @@
# Copyright (c) 2021 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/test.gni")
SUBSYSTEM_DIR = "//base/sensors/medical_sensor"
module_output_path = "sensors/medical_sensor/services/medical_sensor"
###########################ClientInfoTest###########################
ohos_unittest("ClientInfoCommonTest") {
module_out_path = module_output_path
sources = [ "./client_info_test.cpp" ]
include_dirs = [
"//utils/native/base/include",
"$SUBSYSTEM_DIR/utils/include",
"$SUBSYSTEM_DIR/services/medical_sensor/include",
"$SUBSYSTEM_DIR/interfaces/native/include",
]
deps = [
"$SUBSYSTEM_DIR/services/medical_sensor:libmedical_service",
"$SUBSYSTEM_DIR/utils:libmedical_utils",
"//third_party/googletest:gmock_main",
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
]
}
###########################end###########################
group("unittest") {
testonly = true
deps = [ ":ClientInfoCommonTest" ]
}
@@ -0,0 +1,380 @@
/*
* Copyright (c) 2021 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 <gtest/gtest.h>
#include "client_info.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace testing::ext;
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_TEST, "ClientInfoTest" };
const uint32_t INVALID_SENSOR_ID = -1;
const uint32_t ACC_SENSOR_ID = (1 << 16) | (1 << 8);
const uint32_t MAG_SENSOR_ID = (1 << 24) | (1 << 16) | (1 << 8);
} // namespace
class ClientInfoTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
ClientInfo &clientInfo_ = ClientInfo::GetInstance();
};
void ClientInfoTest::SetUpTestCase()
{}
void ClientInfoTest::TearDownTestCase()
{}
void ClientInfoTest::SetUp()
{}
void ClientInfoTest::TearDown()
{}
/*
* @tc.name: UpdateSensorInfo_001
* @tc.desc: update sensor info
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, UpdateSensorInfo_001, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
int32_t pid = 1000;
int64_t samplingPeriodNs = 100000000;
int64_t maxReportDelayNs = 0;
MedicalSensorBasicInfo sensorInfo;
sensorInfo.SetSamplingPeriodNs(samplingPeriodNs);
sensorInfo.SetMaxReportDelayNs(maxReportDelayNs);
sensorInfo.SetSensorState(SENSOR_ENABLED);
bool ret = clientInfo_.UpdateSensorInfo(ACC_SENSOR_ID, pid, sensorInfo);
ASSERT_TRUE(ret);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: UpdateSensorInfo_002
* @tc.desc: update sensor info
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, UpdateSensorInfo_002, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
int32_t pid = 1067;
int64_t samplingPeriodNs = 100000000L;
int64_t maxReportDelayNs = 0;
MedicalSensorBasicInfo sensorInfo;
sensorInfo.SetSamplingPeriodNs(samplingPeriodNs);
sensorInfo.SetMaxReportDelayNs(maxReportDelayNs);
sensorInfo.SetSensorState(SENSOR_ENABLED);
bool ret = clientInfo_.UpdateSensorInfo(ACC_SENSOR_ID, pid, sensorInfo);
ASSERT_TRUE(ret);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: UpdateSensorInfo_003
* @tc.desc: update sensor info
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, UpdateSensorInfo_003, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
int32_t pid = 1000;
int64_t samplingPeriodNs = 100000000;
int64_t maxReportDelayNs = 0;
MedicalSensorBasicInfo sensorInfo;
sensorInfo.SetSamplingPeriodNs(samplingPeriodNs);
sensorInfo.SetMaxReportDelayNs(maxReportDelayNs);
sensorInfo.SetSensorState(SENSOR_ENABLED);
bool ret = clientInfo_.UpdateSensorInfo(MAG_SENSOR_ID, pid, sensorInfo);
ASSERT_TRUE(ret);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: UpdateSensorInfo_004
* @tc.desc: update sensor info
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, UpdateSensorInfo_004, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
int32_t pid = 1000;
int64_t samplingPeriodNs = 100000000;
int64_t maxReportDelayNs = 0;
MedicalSensorBasicInfo sensorInfo;
sensorInfo.SetSamplingPeriodNs(samplingPeriodNs);
sensorInfo.SetMaxReportDelayNs(maxReportDelayNs);
sensorInfo.SetSensorState(SENSOR_ENABLED);
bool ret = clientInfo_.UpdateSensorInfo(INVALID_SENSOR_ID, pid, sensorInfo);
ASSERT_FALSE(ret);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: UpdateSensorInfo_005
* @tc.desc: update sensor info
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, UpdateSensorInfo_005, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
int32_t pid = -1;
int64_t samplingPeriodNs = 100000000;
int64_t maxReportDelayNs = 0;
MedicalSensorBasicInfo sensorInfo;
sensorInfo.SetSamplingPeriodNs(samplingPeriodNs);
sensorInfo.SetMaxReportDelayNs(maxReportDelayNs);
sensorInfo.SetSensorState(SENSOR_DISABLED);
bool ret = clientInfo_.UpdateSensorInfo(MAG_SENSOR_ID, pid, sensorInfo);
ASSERT_FALSE(ret);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: UpdateSensorInfo_006
* @tc.desc: update sensor info
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, UpdateSensorInfo_006, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
int32_t pid = 1067;
int64_t samplingPeriodNs = 50000000;
int64_t maxReportDelayNs = 0;
MedicalSensorBasicInfo sensorInfo;
sensorInfo.SetSamplingPeriodNs(samplingPeriodNs);
sensorInfo.SetMaxReportDelayNs(maxReportDelayNs);
sensorInfo.SetSensorState(SENSOR_ENABLED);
bool ret = clientInfo_.UpdateSensorInfo(ACC_SENSOR_ID, pid, sensorInfo);
ASSERT_TRUE(ret);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: GetSensorState_001
* @tc.desc: get sensor state
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, GetSensorState_001, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
MedicalSensorState ret = clientInfo_.GetSensorState(ACC_SENSOR_ID);
ASSERT_EQ(ret, SENSOR_ENABLED);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: GetSensorState_002
* @tc.desc: get sensor state
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, GetSensorState_002, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
MedicalSensorState ret = clientInfo_.GetSensorState(MAG_SENSOR_ID);
ASSERT_EQ(ret, SENSOR_ENABLED);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: UpdateSensorChannel_001
* @tc.desc: update sensor channel
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, UpdateSensorChannel_001, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
int32_t pid = 1067;
sptr<MedicalSensorBasicDataChannel> sensorChannel = new (std::nothrow) MedicalSensorBasicDataChannel();
ASSERT_NE(sensorChannel, nullptr);
auto ret = clientInfo_.UpdateSensorChannel(pid, sensorChannel);
ASSERT_TRUE(ret);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: UpdateSensorChannel_002
* @tc.desc: update sensor channel
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, UpdateSensorChannel_002, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
int32_t pid = -1;
sptr<MedicalSensorBasicDataChannel> sensorChannel = new (std::nothrow) MedicalSensorBasicDataChannel();
ASSERT_NE(sensorChannel, nullptr);
auto ret = clientInfo_.UpdateSensorChannel(pid, sensorChannel);
ASSERT_FALSE(ret);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: UpdateSensorChannel_003
* @tc.desc: update sensor channel
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, UpdateSensorChannel_003, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
int32_t pid = 1000;
sptr<MedicalSensorBasicDataChannel> sensorChannel = nullptr;
auto ret = clientInfo_.UpdateSensorChannel(pid, sensorChannel);
ASSERT_FALSE(ret);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: UpdateSensorChannel_004
* @tc.desc: update sensor channel
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, UpdateSensorChannel_004, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
int32_t pid = -1;
sptr<MedicalSensorBasicDataChannel> sensorChannel = nullptr;
auto ret = clientInfo_.UpdateSensorChannel(pid, sensorChannel);
ASSERT_FALSE(ret);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: UpdateSensorChannel_005
* @tc.desc: update sensor channel
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, UpdateSensorChannel_005, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
int32_t pid = 1000;
sptr<MedicalSensorBasicDataChannel> sensorChannel = new (std::nothrow) MedicalSensorBasicDataChannel();
ASSERT_NE(sensorChannel, nullptr);
auto ret = clientInfo_.UpdateSensorChannel(pid, sensorChannel);
ASSERT_TRUE(ret);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: GetSensorChannel_001
* @tc.desc: get sensor channel
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, GetSensorChannel_001, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
auto ret = clientInfo_.GetSensorChannel(ACC_SENSOR_ID);
ASSERT_EQ(ret.size(), 2UL);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: GetSensorChannel_002
* @tc.desc: get sensor channel
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, GetSensorChannel_002, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
auto ret = clientInfo_.GetSensorChannel(INVALID_SENSOR_ID);
ASSERT_EQ(ret.size(), 0UL);
HiLog::Info(LABEL, "%{public}s end ret.size() : %{public}d", __func__, int32_t{ ret.size() });
}
/*
* @tc.name: GetSensorChannel_003
* @tc.desc: get sensor channel
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, GetSensorChannel_003, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
auto ret = clientInfo_.GetSensorChannel(INVALID_SENSOR_ID);
ASSERT_EQ(ret.size(), 0UL);
HiLog::Info(LABEL, "%{public}s end ret.size() : %{public}d", __func__, int32_t{ ret.size() });
}
/*
* @tc.name: GetSensorChannel_001
* @tc.desc: get sensor channel
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, GetSensorChannel_004, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
auto ret = clientInfo_.GetSensorChannel(MAG_SENSOR_ID);
ASSERT_EQ(ret.size(), 1UL);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
/*
* @tc.name: DestroySensorChannel_001
* @tc.desc: destroy sensor channel
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, DestroySensorChannel_001, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
int32_t pid = 1067;
MedicalSensorState ret = clientInfo_.GetSensorState(ACC_SENSOR_ID);
ASSERT_EQ(ret, SENSOR_ENABLED);
auto channelList = clientInfo_.GetSensorChannel(ACC_SENSOR_ID);
ASSERT_EQ(channelList.size(), 2UL);
auto flag = clientInfo_.DestroySensorChannel(pid);
ASSERT_TRUE(flag);
ret = clientInfo_.GetSensorState(ACC_SENSOR_ID);
ASSERT_EQ(ret, SENSOR_ENABLED);
channelList = clientInfo_.GetSensorChannel(ACC_SENSOR_ID);
ASSERT_EQ(channelList.size(), 1UL);
HiLog::Info(LABEL, "%{public}s end ret.size() : %{public}d", __func__, int32_t{ channelList.size() });
}
/*
* @tc.name: ClearSensorInfo_001
* @tc.desc: clear sensor info
* @tc.type: FUNC
*/
HWTEST_F(ClientInfoTest, ClearSensorInfo_001, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
MedicalSensorState ret = clientInfo_.GetSensorState(ACC_SENSOR_ID);
ASSERT_EQ(ret, SENSOR_ENABLED);
auto flag = clientInfo_.ClearSensorInfo(ACC_SENSOR_ID);
ASSERT_TRUE(flag);
ret = clientInfo_.GetSensorState(ACC_SENSOR_ID);
ASSERT_NE(ret, SENSOR_ENABLED);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
} // namespace Sensors
} // namespace OHOS
+123
View File
@@ -0,0 +1,123 @@
# Copyright (c) 2021 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/test.gni")
SUBSYSTEM_DIR = "//base/sensors/medical_sensor"
module_output_path = "sensors/medical_sensor/services/medical_sensor"
###########################MedicalDataProcesserTest###########################
ohos_unittest("MedicalDataProcesserTest") {
module_out_path = module_output_path
sources = [ "./medical_data_processer_test.cpp" ]
include_dirs = [
"//utils/native/base/include",
"$SUBSYSTEM_DIR/utils/include",
"$SUBSYSTEM_DIR/services/medical_sensor/include",
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor/include",
"//drivers/peripheral/sensor/interfaces/include",
"$SUBSYSTEM_DIR/interfaces/native/include",
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include",
]
deps = [
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor:libmedical_native",
"$SUBSYSTEM_DIR/services/medical_sensor:libmedical_service",
"$SUBSYSTEM_DIR/utils:libmedical_utils",
"//drivers/peripheral/sensor/hal:hdi_sensor",
"//third_party/googletest:gmock_main",
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"samgr_standard:samgr_proxy",
]
}
###########################MedicalProxyTest###########################
ohos_unittest("MedicalProxyTest") {
module_out_path = module_output_path
sources = [ "./medical_proxy_test.cpp" ]
include_dirs = [
"//utils/native/base/include",
"//utils/system/safwk/native/include",
"$SUBSYSTEM_DIR/utils/include",
"$SUBSYSTEM_DIR/services/medical_sensor/include",
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor/include",
"$SUBSYSTEM_DIR/interfaces/native/include",
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include",
]
deps = [
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor:libmedical_native",
"$SUBSYSTEM_DIR/services/medical_sensor:libmedical_service",
"$SUBSYSTEM_DIR/utils:libmedical_utils",
"//third_party/googletest:gmock_main",
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_standard:samgr_proxy",
]
}
###########################MedicalServiceImplTest###########################
ohos_unittest("MedicalServiceImplTest") {
module_out_path = module_output_path
sources = [ "./medical_service_impl_test.cpp" ]
include_dirs = [
"//utils/native/base/include",
"//utils/system/safwk/native/include",
"$SUBSYSTEM_DIR/utils/include",
"$SUBSYSTEM_DIR/services/medical_sensor/include",
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor/include",
"//drivers/peripheral/sensor/interfaces/include",
"$SUBSYSTEM_DIR/interfaces/native/include",
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include",
]
deps = [
"$SUBSYSTEM_DIR/frameworks/native/medical_sensor:libmedical_native",
"$SUBSYSTEM_DIR/services/medical_sensor:libmedical_service",
"$SUBSYSTEM_DIR/utils:libmedical_utils",
"//drivers/peripheral/sensor/hal:hdi_sensor",
"//utils/native/base:utils",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_standard:samgr_proxy",
]
}
###########################end###########################
group("unittest") {
testonly = true
deps = [
":MedicalDataProcesserTest",
":MedicalProxyTest",
":MedicalServiceImplTest",
]
}
@@ -0,0 +1,222 @@
/*
* Copyright (c) 2021 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 <cstdint>
#include <gtest/gtest.h>
#include <memory>
#include <thread>
#include "report_data_cache.h"
#include "medical_data_channel.h"
#include "medical_service_client.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace testing::ext;
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_TEST, "AfeDataProcesserTest" };
constexpr uint32_t ACC_SENSOR_ID = 0;
constexpr uint32_t WAIT_TIME = 3000;
constexpr uint64_t SAMPLING_PEROID_NS = 200000000;
constexpr uint64_t MAX_REPORT_DELAY_NS = 0;
constexpr uint32_t STEP_COUNTER_SENSORID = 0;
constexpr uint32_t STEP_DETECTOR_SENSORID = 0;
constexpr uint32_t OTHER = 4;
constexpr uint32_t SENSOR_TYPE_FLUSH = 4;
constexpr uint32_t FIRST_INDEX = 1;
constexpr uint32_t SENSOR_INDEX_SHIFT = 8;
constexpr uint32_t SENSOR_TYPE_SHIFT = 16;
constexpr uint32_t SENSOR_CATAGORY_SHIFT = 24;
constexpr uint32_t FLUSH_COMPLETE_ID = (static_cast<uint32_t>(OTHER) << SENSOR_CATAGORY_SHIFT) |
(static_cast<uint32_t>(SENSOR_TYPE_FLUSH) << SENSOR_TYPE_SHIFT) |
(static_cast<uint32_t>(FIRST_INDEX) << SENSOR_INDEX_SHIFT);
class AfeDataProcesserTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
static void HandleEvent(struct SensorEvent *events, int32_t num, void *data);
static std::vector<MedicalSensor> g_afesList;
static sptr<MedicalSensorDataChannel> g_dataChannel;
static sptr<ReportDataCache> g_dataCache;
static std::vector<struct SensorEvent> g_eventsBuf;
static std::unique_ptr<MedicalSensorServiceClient> g_serviceClient;
static int32_t g_dataCount;
static bool g_getFlushComplete;
};
struct SensorEvent g_event;
int32_t AfeDataProcesserTest::g_dataCount = 0;
bool AfeDataProcesserTest::g_getFlushComplete = false;
std::vector<MedicalSensor> AfeDataProcesserTest::g_afesList;
sptr<MedicalSensorDataChannel> AfeDataProcesserTest::g_dataChannel;
sptr<ReportDataCache> AfeDataProcesserTest::g_dataCache;
std::vector<struct SensorEvent> AfeDataProcesserTest::g_eventsBuf;
std::unique_ptr<MedicalSensorServiceClient> AfeDataProcesserTest::g_serviceClient;
} // namespace
void AfeDataProcesserTest::HandleEvent(struct SensorEvent *events, int32_t num, void *data)
{
HiLog::Info(LABEL, "HandleEvent begin");
if (num <= 0) {
HiLog::Error(LABEL, "%{public}s failed, num : %{public}d", __func__, num);
return;
}
g_event.sensorTypeId = events[0].sensorTypeId;
for (int32_t i = 0; i < num; i++) {
if (events[i].sensorTypeId == ACC_SENSOR_ID) {
g_dataCount++;
}
if (events[i].sensorTypeId == FLUSH_COMPLETE_ID) {
g_getFlushComplete = true;
}
}
}
void AfeDataProcesserTest::SetUpTestCase()
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
g_dataChannel = new (std::nothrow) MedicalSensorDataChannel();
ASSERT_NE(g_dataChannel, nullptr);
g_serviceClient = std::make_unique<MedicalSensorServiceClient>();
ASSERT_NE(g_serviceClient, nullptr);
g_dataCache = new (std::nothrow) ReportDataCache();
ASSERT_NE(g_dataCache, nullptr);
g_afesList = g_serviceClient->GetSensorList();
auto ret = g_dataChannel->CreateSensorDataChannel(HandleEvent, nullptr);
HiLog::Info(LABEL, "CreateSensorDataChannel ret : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
g_serviceClient->TransferDataChannel(g_dataChannel);
}
void AfeDataProcesserTest::TearDownTestCase()
{
g_dataChannel->DestroySensorDataChannel();
g_serviceClient->DestroyDataChannel();
}
void AfeDataProcesserTest::SetUp()
{}
void AfeDataProcesserTest::TearDown()
{}
/*
* @tc.name: EnableSensor_001
* @tc.desc: enable afe
* @tc.type: FUNC
*/
HWTEST_F(AfeDataProcesserTest, EnableSensor_001, TestSize.Level1)
{
HiLog::Info(LABEL, "EnableSensor_001 begin");
uint64_t samplingPeroidNs = SAMPLING_PEROID_NS;
uint64_t maxReportDelayNs = MAX_REPORT_DELAY_NS;
uint32_t afeId = ACC_SENSOR_ID;
auto ret = g_serviceClient->EnableSensor(afeId, samplingPeroidNs, maxReportDelayNs);
HiLog::Info(LABEL, "EnableSensor ret : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
HiLog::Info(LABEL, "EnableSensor_001 end");
}
/*
* @tc.name: ReadSensorData_001
* @tc.desc: read afe data
* @tc.type: FUNC
*/
HWTEST_F(AfeDataProcesserTest, ReadSensorData_001, TestSize.Level1)
{
HiLog::Info(LABEL, "ReadSensorData_001 begin");
g_dataCount = 0;
std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
HiLog::Info(LABEL, "ReadSensorData_001 end");
}
/*
* @tc.name: ReportData_001
* @tc.desc: judge whether the data is valid
* @tc.type: FUNC
*/
HWTEST_F(AfeDataProcesserTest, ReportData_001, TestSize.Level1)
{
HiLog::Info(LABEL, "ReportData_001 begin");
ASSERT_EQ(g_event.sensorTypeId, 0);
HiLog::Info(LABEL, "ReportData_001 end, %{public}d", g_event.sensorTypeId);
}
/*
* @tc.name: EnableStepCounter_001
* @tc.desc: enable step counter afe
* @tc.type: FUNC
*/
HWTEST_F(AfeDataProcesserTest, EnableStepCounter_001, TestSize.Level1)
{
HiLog::Info(LABEL, "EnableStepCounter begin");
ASSERT_NE(g_serviceClient, nullptr);
const int64_t samplingPeriodNs = 50000000;
const int64_t maxReportDelayNs = 0;
auto ret = g_serviceClient->EnableSensor(STEP_COUNTER_SENSORID, samplingPeriodNs, maxReportDelayNs);
HiLog::Info(LABEL, "Enable step counter, ret : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
}
/*
* @tc.name: DisableStepCounter_001
* @tc.desc: disable step counter afe
* @tc.type: FUNC
*/
HWTEST_F(AfeDataProcesserTest, DisableStepCounter_001, TestSize.Level1)
{
ASSERT_NE(g_serviceClient, nullptr);
auto ret = g_serviceClient->DisableSensor(STEP_COUNTER_SENSORID);
HiLog::Info(LABEL, "Disable step counter, ret : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
}
/*
* @tc.name: EnableStepCounter_002
* @tc.desc: enable step counter afe
* @tc.type: FUNC
*/
HWTEST_F(AfeDataProcesserTest, EnableStepCounter_002, TestSize.Level1)
{
HiLog::Info(LABEL, "EnableStepCounter begin");
ASSERT_NE(g_serviceClient, nullptr);
const int64_t samplingPeriodNs = 50000000;
const int64_t maxReportDelayNs = 0;
auto ret = g_serviceClient->EnableSensor(STEP_COUNTER_SENSORID, samplingPeriodNs, maxReportDelayNs);
HiLog::Info(LABEL, "Enable step counter, ret : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
}
/*
* @tc.name: DisableStepDetector_001
* @tc.desc: disable step detector afe
* @tc.type: FUNC
*/
HWTEST_F(AfeDataProcesserTest, DisableStepDetector_001, TestSize.Level1)
{
ASSERT_NE(g_serviceClient, nullptr);
auto ret = g_serviceClient->DisableSensor(STEP_DETECTOR_SENSORID);
HiLog::Info(LABEL, "Disable step detector ret : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
}
} // namespace Sensors
} // namespace OHOS
@@ -0,0 +1,260 @@
/*
* Copyright (c) 2021 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 <cstdint>
#include <thread>
#include <unistd.h>
#include <vector>
#include <fcntl.h>
#include <gtest/gtest.h>
#include "ipc_skeleton.h"
#include "iservice_registry.h"
#include "medical_service_proxy.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
#include "string_ex.h"
#include "system_ability_definition.h"
namespace OHOS {
namespace Sensors {
using namespace testing::ext;
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_TEST, "AfeProxyTest" };
const uint32_t INVALID_SENSOR_ID = -1;
const std::string CMD_LINE = "ps -ef | grep 'hardware.afe' | grep -v grep | awk '{print $2}'";
constexpr int32_t BUFFER_SIZE = 8;
constexpr pid_t INVALID_PID = -1;
class AfeProxyTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
pid_t GetSensorServicePid();
sptr<IMedicalSensorService> afeProxy_;
std::vector<MedicalSensor> afes_;
uint32_t afeId_;
};
} // namespace
void AfeProxyTest::SetUpTestCase()
{}
void AfeProxyTest::TearDownTestCase()
{}
void AfeProxyTest::SetUp()
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
ASSERT_NE(systemAbilityManager, nullptr);
afeProxy_ = iface_cast<IMedicalSensorService>(systemAbilityManager->GetSystemAbility(AFE_SERVICE_ABILITY_ID));
ASSERT_NE(afeProxy_, nullptr);
afes_ = afeProxy_->GetSensorList();
ASSERT_NE(afes_.size(), 0UL);
afeId_ = afes_[0].GetSensorId();
ASSERT_NE(afeId_, INVALID_SENSOR_ID);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
void AfeProxyTest::TearDown()
{}
pid_t AfeProxyTest::GetSensorServicePid()
{
pid_t pid = INVALID_PID;
char buf[BUFFER_SIZE] = { 0 };
FILE *fp = popen(CMD_LINE.c_str(), "r");
if (fp == nullptr) {
HiLog::Error(LABEL, "get error when getting afe service process id");
return pid;
}
fgets(buf, sizeof(buf) - 1, fp);
pclose(fp);
fp = nullptr;
HiLog::Info(LABEL, "process is : %{public}s", buf);
std::string pidStr(buf);
pidStr = TrimStr(pidStr, '\n');
HiLog::Info(LABEL, "pidStr is : %{public}s", pidStr.c_str());
if (pidStr.empty()) {
return pid;
}
if (IsNumericStr(pidStr)) {
pid = std::stoi(pidStr);
}
return pid;
}
/*
* @tc.name: EnableSensor_001
* @tc.desc: enable afe
* @tc.type: FUNC
*/
HWTEST_F(AfeProxyTest, EnableSensor_001, TestSize.Level1)
{
HiLog::Info(LABEL, "EnableSensor begin");
ASSERT_NE(afeProxy_, nullptr);
int64_t samplingPeriodNs = 100000000L;
int64_t maxReportDelayNs = 0L;
auto ret = afeProxy_->EnableSensor(afeId_, samplingPeriodNs, maxReportDelayNs);
HiLog::Info(LABEL, "EnableSensor ret is : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
samplingPeriodNs = 50000000L;
maxReportDelayNs = 0L;
ret = afeProxy_->EnableSensor(afeId_, samplingPeriodNs, maxReportDelayNs);
ASSERT_EQ(ret, ERR_OK);
samplingPeriodNs = 20000000L;
maxReportDelayNs = 0L;
ret = afeProxy_->EnableSensor(afeId_, samplingPeriodNs, maxReportDelayNs);
ASSERT_EQ(ret, ERR_OK);
samplingPeriodNs = 10000000L;
maxReportDelayNs = 0L;
ret = afeProxy_->EnableSensor(afeId_, samplingPeriodNs, maxReportDelayNs);
ASSERT_EQ(ret, ERR_OK);
samplingPeriodNs = 20000000L;
maxReportDelayNs = 0L;
ret = afeProxy_->EnableSensor(afeId_, samplingPeriodNs, maxReportDelayNs);
ASSERT_EQ(ret, ERR_OK);
}
/*
* @tc.name: EnableSensor_002
* @tc.desc: enable afe
* @tc.type: FUNC
*/
HWTEST_F(AfeProxyTest, EnableSensor_002, TestSize.Level1)
{
HiLog::Info(LABEL, "EnableSensor begin");
ASSERT_NE(afeProxy_, nullptr);
const int64_t samplingPeriodNs = 50000000;
const int64_t maxReportDelayNs = 0;
auto ret = afeProxy_->EnableSensor(afeId_, samplingPeriodNs, maxReportDelayNs);
HiLog::Info(LABEL, "EnableSensor ret is : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
}
/*
* @tc.name: EnableSensor_003
* @tc.desc: enable afe
* @tc.type: FUNC
*/
HWTEST_F(AfeProxyTest, EnableSensor_003, TestSize.Level1)
{
HiLog::Info(LABEL, "EnableSensor begin");
ASSERT_NE(afeProxy_, nullptr);
const int64_t samplingPeriodNs = 50000000;
const int64_t maxReportDelayNs = 0;
auto ret = afeProxy_->EnableSensor(INVALID_SENSOR_ID, samplingPeriodNs, maxReportDelayNs);
HiLog::Info(LABEL, "EnableSensor ret is : %{public}d", ret);
ASSERT_NE(ret, ERR_OK);
}
/*
* @tc.name: RunCommand_001
* @tc.desc: run command flush
* @tc.type: FUNC
*/
HWTEST_F(AfeProxyTest, RunCommand_001, TestSize.Level1)
{
ASSERT_NE(afeProxy_, nullptr);
uint32_t cmdType = 0; // flush cmd
uint32_t params = 1; // flush cmd doesn't need this param, just give a value
auto ret = afeProxy_->RunCommand(afeId_, cmdType, params);
HiLog::Info(LABEL, "RunCommand_001 ret is : %{public}d", ret);
// because the AfeProxyTest haven't calling TransferDataChannel, so RunCommand should return fail.
ASSERT_NE(ret, ERR_OK);
}
/*
* @tc.name: RunCommand_002
* @tc.desc: run command unknown
* @tc.type: FUNC
*/
HWTEST_F(AfeProxyTest, RunCommand_002, TestSize.Level1)
{
ASSERT_NE(afeProxy_, nullptr);
uint32_t cmdType = 4; // unknown cmd
uint32_t params = 1;
auto ret = afeProxy_->RunCommand(afeId_, cmdType, params);
ASSERT_NE(ret, ERR_OK);
}
/*
* @tc.name: RunCommand_003
* @tc.desc: run command unknown
* @tc.type: FUNC
*/
HWTEST_F(AfeProxyTest, RunCommand_003, TestSize.Level1)
{
ASSERT_NE(afeProxy_, nullptr);
uint32_t cmdType = 4; // unknown cmd
uint32_t params = 1;
auto ret = afeProxy_->RunCommand(INVALID_SENSOR_ID, cmdType, params);
ASSERT_NE(ret, ERR_OK);
}
/*
* @tc.name: RunCommand_004
* @tc.desc: run command unknown
* @tc.type: FUNC
*/
HWTEST_F(AfeProxyTest, RunCommand_004, TestSize.Level1)
{
ASSERT_NE(afeProxy_, nullptr);
uint32_t cmdType = 0; // flush cmd
uint32_t params = 1;
auto ret = afeProxy_->RunCommand(INVALID_SENSOR_ID, cmdType, params);
ASSERT_NE(ret, ERR_OK);
}
/*
* @tc.name: DisableSensor_001
* @tc.desc: disable afe
* @tc.type: FUNC
*/
HWTEST_F(AfeProxyTest, DisableSensor_001, TestSize.Level1)
{
ASSERT_NE(afeProxy_, nullptr);
auto ret = afeProxy_->DisableSensor(afeId_);
HiLog::Info(LABEL, "DisableSensor ret is : %{public}d", ret);
ASSERT_EQ(ret, ERR_OK);
}
/*
* @tc.name: DisableSensor_002
* @tc.desc: disable afe
* @tc.type: FUNC
*/
HWTEST_F(AfeProxyTest, DisableSensor_002, TestSize.Level1)
{
ASSERT_NE(afeProxy_, nullptr);
auto ret = afeProxy_->DisableSensor(INVALID_SENSOR_ID);
HiLog::Info(LABEL, "DisableSensor ret is : %{public}d", ret);
ASSERT_NE(ret, ERR_OK);
}
} // namespace Sensors
} // namespace OHOS
@@ -0,0 +1,112 @@
/*
* Copyright (c) 2021 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 <cstdint>
#include <gtest/gtest.h>
#include <memory>
#include <thread>
#include "report_data_cache.h"
#include "medical_native_type.h"
#include "medical_data_channel.h"
#include "sensor_if.h"
#include "medical_service_client.h"
#include "medical_service_impl.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace testing::ext;
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_TEST, "AfeServiceImplTest" };
} // namespace
class AfeServiceImplTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp();
void TearDown();
MedicalSensorServiceImpl &afeServiceImpl_ = MedicalSensorServiceImpl::GetInstance();
};
void AfeServiceImplTest::SetUpTestCase()
{}
void AfeServiceImplTest::TearDownTestCase()
{}
void AfeServiceImplTest::SetUp()
{}
void AfeServiceImplTest::TearDown()
{}
/*
* @tc.name: RegisteDataReport_001
* @tc.desc: register data report.
* @tc.type: FUNC
* @tc.require: SR000F5A2Q AR000F8QO2
* @tc.author: wuzhihui
*/
HWTEST_F(AfeServiceImplTest, RegisteDataReport_001, TestSize.Level1)
{
HiLog::Info(LABEL, "%{public}s begin", __func__);
// 获取afe列表
afeServiceImpl_.InitSensorServiceImpl();
std::vector<MedicalSensor> list = afeServiceImpl_.GetSensorList();
for (size_t i=0; i<list.size(); i++) {
MedicalSensor afe = list[i];
printf("get afeiId[%d], afeName[%s], vendorNmae[%s]\n\r", afe.GetSensorId(),
afe.GetName().c_str(), afe.GetVendor().c_str());
}
ASSERT_NE(list.size(), 0UL);
// SetBatch
const int32_t afeId = 0;
const int32_t afeInterval = 1000000000;
const int32_t afePollTime = 5;
int32_t ret = afeServiceImpl_.SetSensorConfig(afeId, afeInterval, afePollTime);
EXPECT_EQ(0, ret);
// 注册
DataCacheFunc cb;
sptr<ReportDataCache> reportDataCache_;
reportDataCache_ = new (std::nothrow) ReportDataCache();
ASSERT_NE(reportDataCache_, nullptr);
cb = &ReportDataCache::CacheData;
ret = afeServiceImpl_.RegisteDataReport(cb, reportDataCache_);
ASSERT_EQ(ret, 0);
// 激活
ret = afeServiceImpl_.EnableSensor(afeId);
EXPECT_EQ(0, ret);
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
HiLog::Info(LABEL, "%{public}s begin", "--->Unregister1111");
// 去注册
ret = afeServiceImpl_.Unregister();
ASSERT_EQ(ret, 0);
HiLog::Info(LABEL, "%{public}s begin", "--->Unregister222");
// 去激活
ret = afeServiceImpl_.DisableSensor(afeId);
ASSERT_EQ(ret, 0);
HiLog::Info(LABEL, "%{public}s end", __func__);
}
} // namespace Sensors
} // namespace OHOS
Executable
+58
View File
@@ -0,0 +1,58 @@
# Copyright (c) 2021 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/ohos.gni")
SUBSYSTEM_DIR = "//base/sensors/medical_sensor"
ohos_shared_library("libmedical_utils") {
sources = [
"src/dmd_report.cpp",
"src/permission_util.cpp",
"src/report_data_cache.cpp",
"src/medical.cpp",
"src/medical_basic_data_channel.cpp",
"src/medical_basic_info.cpp",
"src/medical_channel_info.cpp",
]
include_dirs = [
"include",
"//utils/native/base/include",
"//utils/system/safwk/native/include",
"//drivers/peripheral/sensor/interfaces/include",
"$SUBSYSTEM_DIR/interfaces/native/include",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core/include/message_parcel.h",
]
deps = [
"//drivers/peripheral/sensor/hal:hdi_sensor",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//utils/native/base:utils",
]
external_deps = [
"aafwk_standard:base",
"aafwk_standard:intent",
"appexecfwk_standard:appexecfwk_base",
"appexecfwk_standard:appexecfwk_core",
"hisysevent_native:libhisysevent",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_standard:samgr_proxy",
]
part_name = "medical_sensor"
subsystem_name = "sensors"
}
group("medical_utils_target") {
deps = [ ":libmedical_utils" ]
}
+38
View File
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2021 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 DEATH_RECIPIENT_TEMPLATE_H
#define DEATH_RECIPIENT_TEMPLATE_H
#include "iremote_object.h"
namespace OHOS {
namespace Sensors {
template<typename T>
class DeathRecipientTemplate : public IRemoteObject::DeathRecipient {
public:
explicit DeathRecipientTemplate(T &privateData) : privateData_(privateData){};
virtual ~DeathRecipientTemplate() = default;
virtual void OnRemoteDied(const wptr<IRemoteObject> &object)
{
privateData_.ProcessDeathObserver(object);
};
private:
T &privateData_;
};
} // namespace Sensors
} // namespace OHOS
#endif // DEATH_RECIPIENT_TEMPLATE_H
+52
View File
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2021 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 DMD_REPORT_H
#define DMD_REPORT_H
#include <map>
#include <mutex>
#include <string>
namespace OHOS {
namespace Sensors {
enum SensorEventId {
JNI_ENV_VAR_EXCEPTION = 951000106,
CLASS_NOT_FOUND = 951000107,
NATIVE_METHOD_REGISTER_EXCEPTION = 951000108,
JAVA_VM_THREAD_ATTACH_EXCEPTION = 951000109,
SENSOR_SERVICE_EXCEPTION = 951000110,
MISC_SERVICE_EXCEPTION = 951000111,
SENSOR_SERVICE_IPC_EXCEPTION = 951000112,
MISC_SERVICE_IPC_EXCEPTION = 951000113,
SENSOR_HIDL_SERVICE_EXCEPTION = 951000114,
LIGHT_HIDL_SERVICE_EXCEPTION = 951000115,
VIBRATOR_HIDL_SERVICE_EXCEPTION = 951000116,
SENSOR_DATA_CHANNEL_EXCEPTION = 951000117,
};
class DmdReport {
public:
DmdReport() = default;
virtual ~DmdReport() = default;
static void ReportException(int32_t eventId, const std::string &interfaceName, int32_t error);
private:
static std::mutex eventMutex_;
static std::map<int32_t, int64_t> eventMap_;
};
} // namespace Sensors
} // namespace OHOS
#endif // DMD_REPORT_H
+71
View File
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2021 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 MEDICAL_SENSOR_H
#define MEDICAL_SENSOR_H
#include <string>
#include <vector>
#include "parcel.h"
namespace OHOS {
namespace Sensors {
class MedicalSensor : public Parcelable {
public:
MedicalSensor();
virtual ~MedicalSensor() = default;
uint32_t GetSensorId() const;
void SetSensorId(uint32_t sensorId);
std::string GetName() const;
void SetName(const std::string &name);
std::string GetVendor() const;
void SetVendor(const std::string &vendor);
uint32_t GetVersion() const;
void SetVersion(uint32_t version);
float GetMaxRange() const;
void SetMaxRange(float maxRange);
float GetResolution() const;
void SetResolution(float resolution);
uint32_t GetFlags() const;
void SetFlags(uint32_t flags);
int32_t GetFifoMaxEventCount() const;
void SetFifoMaxEventCount(int32_t fifoMaxEventCount);
int64_t GetMinSamplePeriodNs() const;
void SetMinSamplePeriodNs(int64_t minSamplePeriodNs);
int64_t GetMaxSamplePeriodNs() const;
void SetMaxSamplePeriodNs(int64_t maxSamplePeriodNs);
std::vector<uint32_t> GetReserved() const;
void SetReserved(const std::vector<uint32_t> &reserved);
bool ReadFromParcel(Parcel &parcel);
static std::unique_ptr<MedicalSensor> Unmarshalling(Parcel &parcel);
virtual bool Marshalling(Parcel &parcel) const override;
private:
uint32_t sensorId_;
std::string name_;
std::string vendor_;
uint32_t version_;
float maxRange_;
float resolution_;
uint32_t flags_;
int32_t fifoMaxEventCount_;
int64_t minSamplePeriodNs_;
int64_t maxSamplePeriodNs_;
std::vector<uint32_t> reserved_;
};
} // namespace Sensors
} // namespace OHOS
#endif // MEDICAL_SENSOR_H
+65
View File
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2021 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_BASIC_DATA_CHANNEL_H
#define SENSOR_BASIC_DATA_CHANNEL_H
#include <mutex>
#include <unordered_map>
#include "message_parcel.h"
#include "refbase.h"
#include "medical_native_type.h"
namespace OHOS {
namespace Sensors {
constexpr int32_t INVALID_FD = -1;
constexpr int32_t SENSOR_MAX_LENGTH = 512;
struct TransferMedicalSensorEvents {
uint32_t sensorTypeId; /**< Sensor type ID */
int32_t version; /**< Sensor algorithm version */
int64_t timestamp; /**< Time when sensor data was reported */
int32_t option; /**< Sensor data options, including the measurement range and accuracy */
int32_t mode; /**< Sensor data reporting mode (described in {@link SensorMode}) */
uint32_t dataLen; /**< Sensor data length */
uint8_t data[SENSOR_MAX_LENGTH];
};
class MedicalSensorBasicDataChannel : public RefBase {
public:
MedicalSensorBasicDataChannel();
virtual ~MedicalSensorBasicDataChannel();
int32_t CreateSensorBasicChannel(size_t sendSize, size_t receiveSize);
int32_t CreateSensorBasicChannel(MessageParcel &data);
int32_t DestroySensorBasicChannel();
int32_t GetSendDataFd() const;
int32_t GetReceiveDataFd() const;
int32_t SendToBinder(MessageParcel &data);
void CloseSendFd();
int32_t SendData(const void *vaddr, size_t size);
int32_t ReceiveData(void *vaddr, size_t size);
bool GetSensorStatus() const;
void SetSensorStatus(bool isActive);
const std::unordered_map<uint32_t, struct SensorEvent> &GetDataCacheBuf() const;
private:
int32_t sendFd_;
int32_t receiveFd_;
bool isActive_;
std::mutex statusLock_;
std::unordered_map<uint32_t, struct SensorEvent> dataCacheBuf_;
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSOR_H
+47
View File
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 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_BASIC_INFO_H
#define SENSOR_BASIC_INFO_H
#include <cstdint>
namespace OHOS {
namespace Sensors {
enum MedicalSensorState {
SENSOR_DISABLED = 0,
SENSOR_ENABLED = 1,
SENSOR_UNKNOWN_STATE = 2,
};
class MedicalSensorBasicInfo {
public:
MedicalSensorBasicInfo();
virtual ~MedicalSensorBasicInfo() = default;
int64_t GetSamplingPeriodNs() const;
void SetSamplingPeriodNs(int64_t samplingPeriodNs);
int64_t GetMaxReportDelayNs() const;
void SetMaxReportDelayNs(int64_t maxReportDelayNs);
MedicalSensorState GetSensorState() const;
void SetSensorState(MedicalSensorState sensorState);
private:
int64_t samplingPeriodNs_;
int64_t maxReportDelayNs_;
MedicalSensorState sensorState_;
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSOR_BASIC_INFO_H
+91
View File
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2021 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_CATALOG_H
#define SENSOR_CATALOG_H
namespace OHOS {
namespace Sensors {
enum SensorGroup {
DEVICE_MOTION = 0,
ENVIRONMENT = 1,
ORIENTATION = 2,
LIGHT = 3,
OTHER = 4,
BODY = 5,
};
enum GroupMotion {
SENSOR_TYPE_ACCELEROMETER = 0,
SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED = 1,
SENSOR_TYPE_LINEAR_ACCELERATION = 2,
SENSOR_TYPE_GRAVITY = 3,
SENSOR_TYPE_GYROSCOPE = 4,
SENSOR_TYPE_GYROSCOPE_UNCALIBRATED = 5,
SENSOR_TYPE_SIGNIFICANT_MOTION = 6,
SENSOR_TYPE_DROP_DETECTION = 7,
SENSOR_TYPE_STEP_DETECTOR = 8,
SENSOR_TYPE_STEP_COUNTER = 9,
};
enum GroupEnvironment {
SENSOR_TYPE_AMBIENT_TEMPERATURE = 0,
SENSOR_TYPE_MAGNETIC_FIELD = 1,
SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED = 2,
SENSOR_TYPE_HUMIDITY = 3,
SENSOR_TYPE_BAROMETER = 4,
SENSOR_TYPE_SAR = 5,
};
enum GroupOrientation {
SENSOR_TYPE_6DOF_ATTITUDE = 0,
SENSOR_TYPE_SCREEN_ROTATION = 1,
SENSOR_TYPE_DEVICE_ORIENTATION = 2,
SENSOR_TYPE_ORIENTATION = 3,
SENSOR_TYPE_ROTATION_VECTOR = 4,
SENSOR_TYPE_GAME_ROTATION_VECTOR = 5,
SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR = 6,
};
enum GroupLight {
SENSOR_TYPE_PROXIMITY = 0,
SENSOR_TYPE_TOF = 1,
SENSOR_TYPE_AMBIENT_LIGHT = 2,
SENSOR_TYPE_COLOR_TEMPERATURE = 3,
SENSOR_TYPE_COLOR_RGB = 4,
SENSOR_TYPE_COLOR_XYZ = 5,
};
enum GroupOther {
SENSOR_TYPE_HALL = 0,
SENSOR_TYPE_GRIP_DETECTOR = 1,
SENSOR_TYPE_MAGNET_BRACKET = 2,
SENSOR_TYPE_PRESSURE_DETECTOR = 3,
SENSOR_TYPE_FLUSH = 4,
};
enum GroupBody {
SENSOR_TYPE_HEART_RATE_DETECTOR = 0,
SENSOR_TYPE_WEAR_DETECTOR = 1,
};
struct SensorCombination {
SensorGroup sensorCatagory;
uint8_t sensorType;
uint8_t sensorIndex;
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSOR_CATALOG_H
+52
View File
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2021 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_CHANNEL_INFO_H
#define SENSOR_CHANNEL_INFO_H
#include <cstdint>
#include <string>
#include <vector>
namespace OHOS {
namespace Sensors {
class MedicalSensorChannelInfo {
public:
MedicalSensorChannelInfo();
virtual ~MedicalSensorChannelInfo() = default;
int32_t GetUid() const;
void SetUid(int32_t uid);
std::string GetPackageName() const;
void SetPackageName(const std::string &packageName);
uint32_t GetSensorId() const;
void SetSensorId(uint32_t sensorId);
int64_t GetSamplingPeriodNs() const;
void SetSamplingPeriodNs(int64_t samplingPeriodNs);
int32_t GetFifoCount() const;
void SetFifoCount(int32_t fifoCount);
std::vector<int32_t> GetCmdType() const;
void SetCmdType(const std::vector<int32_t> &cmdType);
private:
int32_t uid_;
std::string packageName_;
uint32_t sensorId_;
int64_t samplingPeriodNs_;
uint32_t fifoCount_;
std::vector<int32_t> cmdType_;
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSOR_CHANNEL_INFO_H
+127
View File
@@ -0,0 +1,127 @@
/*
* Copyright (c) 2021 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 SENSORS_ERRORS_H
#define SENSORS_ERRORS_H
#include <errors.h>
namespace OHOS {
namespace Sensors {
enum {
MODULE_COMMON = 0x00,
MODULE_SENSORS_ADAPTER = 0x01,
MODULE_SENSOR_SERVICE = 0x02,
MODULE_SENSORS_UTILS = 0x03,
MODULE_MISCDEVICE_SERVICE = 0x04,
MODULE_SENSORS_NATIVE = 0X05,
};
// Error code for common
constexpr ErrCode COMMON_ERR_OFFSET = ErrCodeOffset(SUBSYS_SENSORS, MODULE_COMMON);
enum {
ERROR = -1,
SUCCESS = 0,
COMMON_ERR = COMMON_ERR_OFFSET,
};
// Error code for adapter
constexpr ErrCode ADAPTER_ERR_OFFSET = ErrCodeOffset(SUBSYS_SENSORS, MODULE_SENSORS_ADAPTER);
enum {
ADAPTER_ERR = ADAPTER_ERR_OFFSET,
ADAPTER_ENABLE_SENSOR_ERR = ADAPTER_ERR_OFFSET + 1,
ADAPTER_DISABLE_SENSOR_ERR = ADAPTER_ENABLE_SENSOR_ERR + 1,
ADAPTER_RUN_COMMAND_ERR = ADAPTER_DISABLE_SENSOR_ERR + 1,
ADAPTER_SET_SENSOR_CONFIG_ERR = ADAPTER_RUN_COMMAND_ERR + 1,
ADAPTER_NOT_SUPPORT_CMD_ERR = ADAPTER_SET_SENSOR_CONFIG_ERR + 1,
};
// Error code for sensor service
constexpr ErrCode SENSOR_SERVICE_ERR_OFFSET = ErrCodeOffset(SUBSYS_SENSORS, MODULE_SENSOR_SERVICE);
enum {
SENSOR_SERVICE_ERR = SENSOR_SERVICE_ERR_OFFSET,
CMD_TYPE_ERR = SENSOR_SERVICE_ERR + 1,
SENSOR_DEVICE_INIT_ERR = CMD_TYPE_ERR + 1,
CONNECT_SENSOR_HIDL_ERR = SENSOR_DEVICE_INIT_ERR + 1,
SET_SENSOR_CONFIG_ERR = CONNECT_SENSOR_HIDL_ERR + 1,
ENABLE_SENSOR_ERR = SET_SENSOR_CONFIG_ERR + 1,
DISABLE_SENSOR_ERR = ENABLE_SENSOR_ERR + 1,
RUN_COMMAND_ERR = DISABLE_SENSOR_ERR + 1,
GET_SENSOR_LIST_ERR = RUN_COMMAND_ERR + 1,
SENSOR_ENABLED_ERR = GET_SENSOR_LIST_ERR + 1,
UPDATE_SENSOR_CHANNEL_ERR = SENSOR_ENABLED_ERR + 1,
CLEAR_SENSOR_CHANNEL_ERR = UPDATE_SENSOR_CHANNEL_ERR + 1,
CLEAR_SENSOR_INFO_ERR = CLEAR_SENSOR_CHANNEL_ERR + 1,
UPDATE_SENSOR_INFO_ERR = CLEAR_SENSOR_INFO_ERR + 1,
CLIENT_PID_INVALID_ERR = UPDATE_SENSOR_INFO_ERR + 1,
DESTROY_SENSOR_CHANNEL_ERR = CLIENT_PID_INVALID_ERR + 1,
UPDATE_UID_ERR = DESTROY_SENSOR_CHANNEL_ERR + 1,
INVALID_POINTER = UPDATE_UID_ERR + 1,
NO_EVENT = INVALID_POINTER + 1,
COPY_ERR = NO_EVENT + 1,
REGIST_PERMISSION_CHANGED_ERR = COPY_ERR + 1,
DUMP_PARAM_ERR = REGIST_PERMISSION_CHANGED_ERR + 1,
WRITE_MSG_ERR = DUMP_PARAM_ERR + 1,
};
// Error code for miscdevice service
constexpr ErrCode MISCDEVICE_SERVICE_ERR_OFFSET = ErrCodeOffset(SUBSYS_SENSORS, MODULE_MISCDEVICE_SERVICE);
enum {
LIGHT_HIDL_CONNECT_ERR = MISCDEVICE_SERVICE_ERR_OFFSET,
LIGHT_ID_NOT_SUPPORT = LIGHT_HIDL_CONNECT_ERR + 1,
LIGHT_ERR = LIGHT_ID_NOT_SUPPORT + 1,
LIGHT_PLAY_EFFECT_ERROR = LIGHT_ERR + 1,
LIGHT_STOP_EFFECT_ERROR = LIGHT_PLAY_EFFECT_ERROR + 1,
LIGHT_END_ERROR = LIGHT_STOP_EFFECT_ERROR,
VIBRATOR_HIDL_CONNECT_ERR = LIGHT_END_ERROR + 1,
VIBRATOR_ON_ERR = VIBRATOR_HIDL_CONNECT_ERR + 1,
VIBRATOR_OFF_ERR = VIBRATOR_ON_ERR + 1,
VIBRATOR_PLAY_EFFECT_ERR = VIBRATOR_OFF_ERR + 1,
VIBRATOR_STOP_EFFECT_ERR = VIBRATOR_PLAY_EFFECT_ERR + 1,
VIBRATOR_SET_PARA_ERR = VIBRATOR_STOP_EFFECT_ERR + 1,
};
// Error code for Sensor uitls
constexpr ErrCode SENSOR_UTILS_ERR_OFFSET = ErrCodeOffset(SUBSYS_SENSORS, MODULE_SENSORS_UTILS);
enum {
SENSOR_CHANNEL_SOCKET_CREATE_ERR = SENSOR_UTILS_ERR_OFFSET,
SENSOR_CHANNEL_SENDFD_ERR = SENSOR_CHANNEL_SOCKET_CREATE_ERR + 1,
SENSOR_CHANNEL_WRITE_DESCRIPTOR_ERR = SENSOR_CHANNEL_SENDFD_ERR + 1,
SENSOR_CHANNEL_DUP_ERR = SENSOR_CHANNEL_WRITE_DESCRIPTOR_ERR + 1,
SENSOR_CHANNEL_BASIC_CHANNEL_NOT_INIT = SENSOR_CHANNEL_DUP_ERR + 1,
SENSOR_CHANNEL_SEND_ADDR_ERR = SENSOR_CHANNEL_BASIC_CHANNEL_NOT_INIT + 1,
SENSOR_CHANNEL_SEND_DATA_ERR = SENSOR_CHANNEL_SEND_ADDR_ERR + 1,
SENSOR_CHANNEL_RECEIVE_DATA_ERR = SENSOR_CHANNEL_SEND_DATA_ERR + 1,
SENSOR_CHANNEL_RECEIVE_ADDR_ERR = SENSOR_CHANNEL_RECEIVE_DATA_ERR + 1,
SENSOR_CHANNEL_RESTORE_CB_ERR = SENSOR_CHANNEL_RECEIVE_ADDR_ERR + 1,
SENSOR_CHANNEL_RESTORE_FD_ERR = SENSOR_CHANNEL_RESTORE_CB_ERR + 1,
SENSOR_CHANNEL_RESTORE_THREAD_ERR = SENSOR_CHANNEL_RESTORE_FD_ERR + 1,
};
// Error code for Sensor native
constexpr ErrCode SENSOR_NATIVE_ERR_OFFSET = ErrCodeOffset(SUBSYS_SENSORS, MODULE_SENSORS_NATIVE);
enum {
SENSOR_NATIVE_SAM_ERR = SENSOR_NATIVE_ERR_OFFSET,
SENSOR_NATIVE_GET_SERVICE_ERR = SENSOR_NATIVE_SAM_ERR + 1,
SENSOR_NATIVE_REGSITER_CB_ERR = SENSOR_NATIVE_GET_SERVICE_ERR + 1,
MISC_NATIVE_GET_SERVICE_ERR = SENSOR_NATIVE_REGSITER_CB_ERR + 1,
MISC_NATIVE_SAM_ERR = MISC_NATIVE_GET_SERVICE_ERR + 1,
};
} // namespace Sensors
} // namespace OHOS
#endif // SENSORS_ERRORS_H
+34
View File
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2021 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 SENSORS_LOG_DOMAIN_H
#define SENSORS_LOG_DOMAIN_H
#include "hilog/log.h"
namespace OHOS {
namespace MedicalSensorLogDomain {
constexpr uint32_t COMMON = 0xD002700;
constexpr uint32_t SENSOR_ADAPTER = 0xD002701;
constexpr uint32_t SENSOR_SERVICE = 0xD002702;
constexpr uint32_t SENSOR_UTILS = 0xD002703;
constexpr uint32_t SENSOR_TEST = 0xD002704;
constexpr uint32_t SENSOR_NATIVE = 0xD002705;
constexpr uint32_t SENSOR_JNI = 0xD002706;
constexpr uint32_t SENSORS_IMPLEMENT = 0xD002707;
constexpr uint32_t SENSORS_INTERFACE = 0xD002708;
} // namespace MedicalSensorLogDomain
} // namespace OHOS
#endif // SENSORS_LOG_DOMAIN_H
+57
View File
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2021 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 PERMISSION_UTIL_H
#define PERMISSION_UTIL_H
#include <mutex>
#include <set>
#include <string>
#include <unordered_map>
#include "refbase.h"
#include "singleton.h"
namespace OHOS {
namespace Sensors {
struct MedicalThreadInfo {
int32_t pid;
int32_t uid;
MedicalThreadInfo() : pid(0), uid(0) {};
MedicalThreadInfo(int32_t pid, int32_t uid) : pid(pid), uid(uid) {};
};
class PermissionUtil : public Singleton<PermissionUtil> {
public:
PermissionUtil() = default;
virtual ~PermissionUtil();
/* check local caller's permission by permission name */
bool CheckCallingPermission(const std::string &permissionName);
bool CheckCallingPermission(const int32_t afeId);
bool RegistPermissionChanged(const MedicalThreadInfo &appThreadInfo);
void UnregistPermissionChanged(const MedicalThreadInfo &appThreadInfo);
void UpdatePermissionStatus(int32_t uid, const std::string &permissionName, bool permissionStatus);
private:
bool IsPermissionRegisted(int32_t uid);
std::mutex permissionStatusMutex_;
std::unordered_map<int, std::unordered_map<std::string, bool>> appPermissionStatus_;
static std::unordered_map<uint32_t, std::string> sensorPermissions_;
};
} // namespace Sensors
} // namespace OHOS
#endif // PERMISSION_UTIL_H
+48
View File
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2021 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 REPORT_DATA_CALLBACK_H
#define REPORT_DATA_CALLBACK_H
#include <vector>
#include "refbase.h"
#include "medical_native_type.h"
namespace OHOS {
namespace Sensors {
constexpr int32_t CIRCULAR_BUF_LEN = 1024;
constexpr int32_t SENSOR_DATA_LENGHT = 1024;
struct CircularEventBuf {
struct SensorEvent *circularBuf;
int32_t readPosition;
int32_t writePosition;
int32_t eventNum;
};
class ReportDataCache : public RefBase {
public:
ReportDataCache();
~ReportDataCache();
int32_t CacheData(const struct SensorEvent *event, sptr<ReportDataCache> cache);
struct CircularEventBuf &GetEventData();
struct CircularEventBuf eventsBuf_;
};
using DataCacheFunc = int32_t (ReportDataCache::*)(const struct SensorEvent *event, sptr<ReportDataCache> cb);
} // namespace Sensors
} // namespace OHOS
#endif // REPORT_DATA_CALLBACK_H
+103
View File
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2021 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 "dmd_report.h"
#include "datetime_ex.h"
#include "hisysevent.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_UTILS, "DmdReport" };
constexpr int32_t SECONDS_HALF_HOUR = 1800;
} // namespace
std::map<int32_t, int64_t> DmdReport::eventMap_ = {
{ JNI_ENV_VAR_EXCEPTION, 0 },
{ CLASS_NOT_FOUND, 0 },
{ NATIVE_METHOD_REGISTER_EXCEPTION, 0 },
{ JAVA_VM_THREAD_ATTACH_EXCEPTION, 0 },
{ SENSOR_SERVICE_EXCEPTION, 0 },
{ MISC_SERVICE_EXCEPTION, 0 },
{ SENSOR_SERVICE_IPC_EXCEPTION, 0 },
{ MISC_SERVICE_IPC_EXCEPTION, 0 },
{ SENSOR_HIDL_SERVICE_EXCEPTION, 0 },
{ LIGHT_HIDL_SERVICE_EXCEPTION, 0 },
{ VIBRATOR_HIDL_SERVICE_EXCEPTION, 0 },
{ SENSOR_DATA_CHANNEL_EXCEPTION, 0 },
};
std::mutex DmdReport::eventMutex_;
static std::string GetEventName(int32_t eventId)
{
switch (eventId) {
case JNI_ENV_VAR_EXCEPTION:
return "JniEnvVarException";
case CLASS_NOT_FOUND:
return "ClassNotFound";
case NATIVE_METHOD_REGISTER_EXCEPTION:
return "NativeMethodRegisterException";
case JAVA_VM_THREAD_ATTACH_EXCEPTION:
return "JavaVmThreadAttachException";
case SENSOR_SERVICE_EXCEPTION:
return "SensorServiceException";
case MISC_SERVICE_EXCEPTION:
return "MiscServiceException";
case SENSOR_SERVICE_IPC_EXCEPTION:
return "SensorServiceIpcException";
case MISC_SERVICE_IPC_EXCEPTION:
return "MiscServiceIpcException";
case SENSOR_HIDL_SERVICE_EXCEPTION:
return "SensorHidlServiceException";
case LIGHT_HIDL_SERVICE_EXCEPTION:
return "LightHidlServiceException";
case VIBRATOR_HIDL_SERVICE_EXCEPTION:
return "VibratorHidlServiceException";
case SENSOR_DATA_CHANNEL_EXCEPTION:
return "SensorDataChannelException";
default:
return "";
}
}
void DmdReport::ReportException(int32_t eventId, const std::string &interfaceName, int32_t error)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
std::lock_guard<std::mutex> eventLock(eventMutex_);
auto eventIt = eventMap_.find(eventId);
if (eventIt == eventMap_.end()) {
HiLog::Error(LABEL, "%{public}s eventId : %{public}d is not supported", __func__, eventId);
return;
}
int64_t curTime = GetSecondsSince1970ToNow();
if ((curTime - eventIt->second) > SECONDS_HALF_HOUR) {
HiviewDFX::HiSysEvent::Write(HiviewDFX::HiSysEvent::Domain::SENSORS, GetEventName(eventId),
HiviewDFX::HiSysEvent::EventType::FAULT, interfaceName, error);
HiLog::Error(LABEL, "%{public}s eventId : %{public}d, interfaceName=%{public}s, error=%{public}d", __func__, eventId, interfaceName.c_str(), error);
eventMap_[eventId] = curTime;
HiLog::Debug(LABEL, "%{public}s end", __func__);
return;
}
HiLog::Warn(LABEL, "%{public}s eventId is reported every half an hour", __func__);
}
} // namespace Sensors
} // namespace OHOS
+232
View File
@@ -0,0 +1,232 @@
/*
* Copyright (c) 2021 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 "medical.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_UTILS, "MedicalSensor" };
}
MedicalSensor::MedicalSensor()
: sensorId_(0),
version_(0),
maxRange_(0.0),
resolution_(0.0),
flags_(0),
fifoMaxEventCount_(0),
minSamplePeriodNs_(0),
maxSamplePeriodNs_(0)
{}
uint32_t MedicalSensor::GetSensorId() const
{
return sensorId_;
}
void MedicalSensor::SetSensorId(uint32_t sensorId)
{
sensorId_ = sensorId;
}
std::string MedicalSensor::GetName() const
{
return name_;
}
void MedicalSensor::SetName(const std::string &name)
{
name_ = name;
}
std::string MedicalSensor::GetVendor() const
{
return vendor_;
}
void MedicalSensor::SetVendor(const std::string &vendor)
{
vendor_ = vendor;
}
uint32_t MedicalSensor::GetVersion() const
{
return version_;
}
void MedicalSensor::SetVersion(uint32_t version)
{
version_ = version;
}
float MedicalSensor::GetMaxRange() const
{
return maxRange_;
}
void MedicalSensor::SetMaxRange(float maxRange)
{
maxRange_ = maxRange;
}
float MedicalSensor::GetResolution() const
{
return resolution_;
}
void MedicalSensor::SetResolution(float resolution)
{
resolution_ = resolution;
}
uint32_t MedicalSensor::GetFlags() const
{
return flags_;
}
void MedicalSensor::SetFlags(uint32_t flags)
{
flags_ = flags;
}
int32_t MedicalSensor::GetFifoMaxEventCount() const
{
return fifoMaxEventCount_;
}
void MedicalSensor::SetFifoMaxEventCount(int32_t fifoMaxEventCount)
{
fifoMaxEventCount_ = fifoMaxEventCount;
}
int64_t MedicalSensor::GetMinSamplePeriodNs() const
{
return minSamplePeriodNs_;
}
void MedicalSensor::SetMinSamplePeriodNs(int64_t minSamplePeriodNs)
{
minSamplePeriodNs_ = minSamplePeriodNs;
}
int64_t MedicalSensor::GetMaxSamplePeriodNs() const
{
return maxSamplePeriodNs_;
}
void MedicalSensor::SetMaxSamplePeriodNs(int64_t maxSamplePeriodNs)
{
maxSamplePeriodNs_ = maxSamplePeriodNs;
}
std::vector<uint32_t> MedicalSensor::GetReserved() const
{
return reserved_;
}
void MedicalSensor::SetReserved(const std::vector<uint32_t> &reserved)
{
auto reservedCount = reserved.size();
for (size_t i = 0; i < reservedCount; i++) {
reserved_[i] = reserved[i];
}
}
bool MedicalSensor::Marshalling(Parcel &parcel) const
{
if (!parcel.WriteUint32(sensorId_)) {
HiLog::Error(LABEL, "%{public}s failed, write sensorId failed", __func__);
return false;
}
if (!parcel.WriteString(name_)) {
HiLog::Error(LABEL, "%{public}s failed, write name_ failed", __func__);
return false;
}
if (!parcel.WriteString(vendor_)) {
HiLog::Error(LABEL, "%{public}s failed, write vendor_ failed", __func__);
return false;
}
if (!parcel.WriteUint32(version_)) {
HiLog::Error(LABEL, "%{public}s failed, write version_ failed", __func__);
return false;
}
if (!parcel.WriteFloat(maxRange_)) {
HiLog::Error(LABEL, "%{public}s failed, write maxRange_ failed", __func__);
return false;
}
if (!parcel.WriteFloat(resolution_)) {
HiLog::Error(LABEL, "%{public}s failed, write resolution_ failed", __func__);
return false;
}
if (!parcel.WriteUint32(flags_)) {
HiLog::Error(LABEL, "%{public}s failed, write flags_ failed", __func__);
return false;
}
if (!parcel.WriteInt32(fifoMaxEventCount_)) {
HiLog::Error(LABEL, "%{public}s failed, write fifoMaxEventCount_ failed", __func__);
return false;
}
if (!parcel.WriteInt64(minSamplePeriodNs_)) {
HiLog::Error(LABEL, "%{public}s failed, write minSamplePeriodNs_ failed", __func__);
return false;
}
if (!parcel.WriteInt64(maxSamplePeriodNs_)) {
HiLog::Error(LABEL, "%{public}s failed, write maxSamplePeriodNs_ failed", __func__);
return false;
}
if (!parcel.WriteUInt32Vector(reserved_)) {
HiLog::Error(LABEL, "%{public}s failed, write reserved_ failed", __func__);
return false;
}
return true;
}
std::unique_ptr<MedicalSensor> MedicalSensor::Unmarshalling(Parcel &parcel)
{
auto sensor = std::make_unique<MedicalSensor>();
if (sensor == nullptr) {
HiLog::Error(LABEL, "%{public}s sensor cannot be null", __func__);
return nullptr;
}
if (!sensor->ReadFromParcel(parcel)) {
HiLog::Error(LABEL, "%{public}s ReadFromParcel failed", __func__);
return nullptr;
}
return sensor;
}
bool MedicalSensor::ReadFromParcel(Parcel &parcel)
{
sensorId_ = parcel.ReadUint32();
name_ = parcel.ReadString();
vendor_ = parcel.ReadString();
version_ = parcel.ReadUint32();
maxRange_ = parcel.ReadFloat();
resolution_ = parcel.ReadFloat();
flags_ = parcel.ReadUint32();
fifoMaxEventCount_ = parcel.ReadInt32();
minSamplePeriodNs_ = parcel.ReadInt64();
maxSamplePeriodNs_ = parcel.ReadInt64();
return parcel.ReadUInt32Vector(&reserved_);
}
} // namespace Sensors
} // namespace OHOS
+216
View File
@@ -0,0 +1,216 @@
/*
* Copyright (c) 2021 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 "medical_basic_data_channel.h"
#include <fcntl.h>
#include <sys/socket.h>
#include <unistd.h>
#include "dmd_report.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_UTILS, "SensorBasicChannel" };
constexpr int32_t DEFAULT_CHANNEL_SIZE = 2 * 1024;
constexpr int32_t SOCKET_PAIR_SIZE = 2;
} // namespace
MedicalSensorBasicDataChannel::MedicalSensorBasicDataChannel() : sendFd_(INVALID_FD), receiveFd_(INVALID_FD), isActive_(false)
{
HiLog::Debug(LABEL, "%{public}s isActive_ : %{public}d, sendFd: %{public}d", __func__, isActive_, sendFd_);
}
int32_t MedicalSensorBasicDataChannel::CreateSensorBasicChannel(size_t sendSize, size_t receiveSize)
{
if ((sendFd_ != INVALID_FD) || (receiveFd_ != INVALID_FD)) {
HiLog::Debug(LABEL, "%{public}s already create socketpair", __func__);
return ERR_OK;
}
int32_t socketPair[SOCKET_PAIR_SIZE] = { 0 };
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socketPair) != 0) {
DmdReport::ReportException(SENSOR_DATA_CHANNEL_EXCEPTION, "CreateSensorBasicChannel",
SENSOR_CHANNEL_SOCKET_CREATE_ERR);
HiLog::Error(LABEL, "%{public}s create socketpair failed", __func__);
sendFd_ = INVALID_FD;
receiveFd_ = INVALID_FD;
return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
}
// set socket attr
setsockopt(socketPair[0], SOL_SOCKET, SO_SNDBUF, &sendSize, sizeof(sendSize));
setsockopt(socketPair[1], SOL_SOCKET, SO_RCVBUF, &receiveSize, sizeof(receiveSize));
int32_t bufferSize = DEFAULT_CHANNEL_SIZE;
int32_t ret = setsockopt(socketPair[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
if (ret != 0) {
HiLog::Error(LABEL, "%{public}s setsockopt socketpair 0 failed", __func__);
return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
}
ret = setsockopt(socketPair[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
if (ret != 0) {
HiLog::Error(LABEL, "%{public}s setsockopt socketpair 1 failed", __func__);
return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
}
ret = fcntl(socketPair[0], F_SETFL, O_NONBLOCK);
if (ret != 0) {
HiLog::Error(LABEL, "%{public}s fcntl socketpair 0 failed", __func__);
return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
}
ret = fcntl(socketPair[1], F_SETFL, O_NONBLOCK);
if (ret != 0) {
HiLog::Error(LABEL, "%{public}s fcntl socketpair 1 failed", __func__);
return SENSOR_CHANNEL_SOCKET_CREATE_ERR;
}
sendFd_ = socketPair[0];
receiveFd_ = socketPair[1];
HiLog::Debug(LABEL, "%{public}s create socketpair success, receiveFd_ : %{public}d, sendFd_ : %{public}d", __func__,
receiveFd_, sendFd_);
return ERR_OK;
}
int32_t MedicalSensorBasicDataChannel::CreateSensorBasicChannel(MessageParcel &data)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
if ((sendFd_ != INVALID_FD) || (receiveFd_ != INVALID_FD)) {
HiLog::Debug(LABEL, "%{public}s already create socketpair", __func__);
return ERR_OK;
}
int32_t tmpFd = data.ReadFileDescriptor();
if (tmpFd < 0) {
HiLog::Error(LABEL, "%{public}s ReadFileDescriptor failed", __func__);
sendFd_ = INVALID_FD;
return SENSOR_CHANNEL_DUP_ERR;
}
sendFd_ = dup(tmpFd);
if (sendFd_ < 0) {
HiLog::Error(LABEL, "%{public}s dup FileDescriptor failed", __func__);
sendFd_ = INVALID_FD;
return SENSOR_CHANNEL_DUP_ERR;
}
return ERR_OK;
}
MedicalSensorBasicDataChannel::~MedicalSensorBasicDataChannel()
{
DestroySensorBasicChannel();
}
int32_t MedicalSensorBasicDataChannel::SendToBinder(MessageParcel &data)
{
HiLog::Debug(LABEL, "%{public}s sendFd: %{public}d", __func__, sendFd_);
if (sendFd_ < 0) {
HiLog::Error(LABEL, "%{public}s sendFd FileDescriptor error", __func__);
return SENSOR_CHANNEL_SENDFD_ERR;
}
bool result = data.WriteFileDescriptor(sendFd_);
if (!result) {
HiLog::Error(LABEL, "%{public}s send sendFd_ failed", __func__);
CloseSendFd();
return SENSOR_CHANNEL_WRITE_DESCRIPTOR_ERR;
}
return ERR_OK;
}
void MedicalSensorBasicDataChannel::CloseSendFd()
{
if (sendFd_ != INVALID_FD) {
close(sendFd_);
sendFd_ = INVALID_FD;
HiLog::Debug(LABEL, "%{public}s close sendFd_", __func__);
}
}
int32_t MedicalSensorBasicDataChannel::SendData(const void *vaddr, size_t size)
{
if (vaddr == nullptr || sendFd_ < 0) {
HiLog::Error(LABEL, "%{public}s failed, param is invalid", __func__);
return SENSOR_CHANNEL_SEND_ADDR_ERR;
}
ssize_t length;
do {
length = send(sendFd_, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
} while (errno == EINTR);
if (length < 0) {
HiLog::Error(LABEL, "%{public}s send fail : %{public}d, length = %{public}d", __func__, errno, (int32_t)length);
return SENSOR_CHANNEL_SEND_DATA_ERR;
}
return ERR_OK;
}
int32_t MedicalSensorBasicDataChannel::ReceiveData(void *vaddr, size_t size)
{
if (vaddr == nullptr || (receiveFd_ == INVALID_FD)) {
HiLog::Error(LABEL, "%{public}s failed, vaddr is null or receiveFd_ invalid", __func__);
return SENSOR_CHANNEL_RECEIVE_ADDR_ERR;
}
ssize_t length;
do {
length = recv(receiveFd_, vaddr, size, MSG_DONTWAIT);
} while (errno == EINTR);
if (length < 0) {
return 0;
}
return length;
}
int32_t MedicalSensorBasicDataChannel::GetSendDataFd() const
{
return sendFd_;
}
int32_t MedicalSensorBasicDataChannel::GetReceiveDataFd() const
{
return receiveFd_;
}
int32_t MedicalSensorBasicDataChannel::DestroySensorBasicChannel()
{
if (sendFd_ >= 0) {
close(sendFd_);
sendFd_ = INVALID_FD;
HiLog::Debug(LABEL, "%{public}s close sendFd_ success", __func__);
}
if (receiveFd_ >= 0) {
close(receiveFd_);
receiveFd_ = INVALID_FD;
HiLog::Debug(LABEL, "%{public}s close receiveFd_ success", __func__);
}
return ERR_OK;
}
const std::unordered_map<uint32_t, struct SensorEvent> &MedicalSensorBasicDataChannel::GetDataCacheBuf() const
{
return dataCacheBuf_;
}
bool MedicalSensorBasicDataChannel::GetSensorStatus() const
{
return isActive_;
}
void MedicalSensorBasicDataChannel::SetSensorStatus(bool isActive)
{
HiLog::Debug(LABEL, "%{public}s isActive_ : %{public}d", __func__, isActive);
std::unique_lock<std::mutex> lock(statusLock_);
isActive_ = isActive;
return;
}
} // namespace Sensors
} // namespace OHOS
+53
View File
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2021 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 "medical_basic_info.h"
namespace OHOS {
namespace Sensors {
MedicalSensorBasicInfo::MedicalSensorBasicInfo() : samplingPeriodNs_(0L), maxReportDelayNs_(0L), sensorState_(SENSOR_DISABLED)
{}
int64_t MedicalSensorBasicInfo::GetSamplingPeriodNs() const
{
return samplingPeriodNs_;
}
void MedicalSensorBasicInfo::SetSamplingPeriodNs(int64_t samplingPeriodNs)
{
samplingPeriodNs_ = samplingPeriodNs;
}
int64_t MedicalSensorBasicInfo::GetMaxReportDelayNs() const
{
return maxReportDelayNs_;
}
void MedicalSensorBasicInfo::SetMaxReportDelayNs(int64_t maxReportDelayNs)
{
maxReportDelayNs_ = maxReportDelayNs;
}
MedicalSensorState MedicalSensorBasicInfo::GetSensorState() const
{
return sensorState_;
}
void MedicalSensorBasicInfo::SetSensorState(MedicalSensorState sensorState)
{
sensorState_ = sensorState;
}
} // namespace Sensors
} // namespace OHOS
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2021 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 "medical_channel_info.h"
namespace OHOS {
namespace Sensors {
MedicalSensorChannelInfo::MedicalSensorChannelInfo() : uid_(0), sensorId_(0), samplingPeriodNs_(0), fifoCount_(0)
{}
int32_t MedicalSensorChannelInfo::GetUid() const
{
return uid_;
}
void MedicalSensorChannelInfo::SetUid(int32_t uid)
{
uid_ = uid;
}
std::string MedicalSensorChannelInfo::GetPackageName() const
{
return packageName_;
}
void MedicalSensorChannelInfo::SetPackageName(const std::string &packageName)
{
packageName_ = packageName;
}
uint32_t MedicalSensorChannelInfo::GetSensorId() const
{
return sensorId_;
}
void MedicalSensorChannelInfo::SetSensorId(uint32_t sensorId)
{
sensorId_ = sensorId;
}
int64_t MedicalSensorChannelInfo::GetSamplingPeriodNs() const
{
return samplingPeriodNs_;
}
void MedicalSensorChannelInfo::SetSamplingPeriodNs(int64_t samplingPeriodNs)
{
samplingPeriodNs_ = samplingPeriodNs;
}
int32_t MedicalSensorChannelInfo::GetFifoCount() const
{
return fifoCount_;
}
void MedicalSensorChannelInfo::SetFifoCount(int32_t fifoCount)
{
fifoCount_ = fifoCount;
}
std::vector<int32_t> MedicalSensorChannelInfo::GetCmdType() const
{
return cmdType_;
}
void MedicalSensorChannelInfo::SetCmdType(const std::vector<int32_t> &cmdType)
{
cmdType_ = cmdType;
}
} // namespace Sensors
} // namespace OHOS
+118
View File
@@ -0,0 +1,118 @@
/*
* Copyright (c) 2021 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 "permission_util.h"
#include <thread>
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr HiLogLabel LABEL = { LOG_CORE, MedicalSensorLogDomain::SENSOR_UTILS, "PermissionUtil" };
constexpr uint32_t SENSOR_PPG_ID = 256;
constexpr uint32_t SENSOR_HEART_RATE_ID = 83886336;
constexpr int32_t GET_SERVICE_MAX_COUNT = 30;
constexpr uint32_t WAIT_MS = 200;
const std::string PPG_PERMISSION = "ohos.permission.PPG";
const std::string READ_HEALTH_DATA_PERMISSION = "ohos.permission.READ_HEALTH_DATA";
} // namespace
std::unordered_map<uint32_t, std::string> PermissionUtil::sensorPermissions_ = {
{ SENSOR_PPG_ID, PPG_PERMISSION },
{ SENSOR_HEART_RATE_ID, READ_HEALTH_DATA_PERMISSION }
};
PermissionUtil::~PermissionUtil()
{
appPermissionStatus_.clear();
}
bool PermissionUtil::CheckCallingPermission(const int32_t afeId)
{
auto permissionIt = sensorPermissions_.find(afeId);
if (permissionIt == sensorPermissions_.end()) {
return true;
}
return true;
}
bool PermissionUtil::IsPermissionRegisted(int32_t uid)
{
HiLog::Debug(LABEL, "%{public}s appPermissionStatus_.size : %{public}d", __func__,
int32_t { appPermissionStatus_.size() });
std::lock_guard<std::mutex> permissionLock(permissionStatusMutex_);
auto permissionIt = appPermissionStatus_.find(uid);
if (permissionIt != appPermissionStatus_.end()) {
HiLog::Debug(LABEL, "%{public}s uid : %{public}d permission has registered", __func__, uid);
return true;
}
return false;
}
bool PermissionUtil::RegistPermissionChanged(const MedicalThreadInfo &appThreadInfo)
{
HiLog::Debug(LABEL, "%{public}s begin, uid : %{public}d, pid : %{public}d", __func__, appThreadInfo.uid,
appThreadInfo.pid);
// Avoid registering callback functions repeatedly
if (IsPermissionRegisted(appThreadInfo.uid)) {
HiLog::Debug(LABEL, "%{public}s uid : %{public}d permission has registered", __func__, appThreadInfo.uid);
return true;
}
int32_t retry = 0;
while (retry < GET_SERVICE_MAX_COUNT) {
std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS));
HiLog::Error(LABEL, "%{public}s registered failed, retry : %{public}d", __func__, retry);
retry++;
}
HiLog::Debug(LABEL, "%{public}s end", __func__);
return true;
}
void PermissionUtil::UnregistPermissionChanged(const MedicalThreadInfo &appThreadInfo)
{
HiLog::Debug(LABEL, "%{public}s begin, uid : %{public}d, pid : %{public}d", __func__, appThreadInfo.uid,
appThreadInfo.pid);
std::lock_guard<std::mutex> permissionLock(permissionStatusMutex_);
auto permissionIt = appPermissionStatus_.find(appThreadInfo.uid);
if (permissionIt != appPermissionStatus_.end()) {
HiLog::Debug(LABEL, "%{public}s erase uid : %{public}d permission", __func__, appThreadInfo.uid);
appPermissionStatus_.erase(permissionIt);
return;
}
HiLog::Debug(LABEL, "%{public}s end", __func__);
}
void PermissionUtil::UpdatePermissionStatus(int32_t uid, const std::string &permissionName, bool permissionStatus)
{
HiLog::Debug(LABEL, "%{public}s begin", __func__);
std::lock_guard<std::mutex> permissionLock(permissionStatusMutex_);
auto permissionIt = appPermissionStatus_.find(uid);
if (permissionIt == appPermissionStatus_.end()) {
std::unordered_map<std::string, bool> permissionMap;
permissionMap.insert(std::make_pair(permissionName, permissionStatus));
appPermissionStatus_.insert(std::make_pair(uid, permissionMap));
HiLog::Debug(LABEL, "%{public}s end", __func__);
return;
}
permissionIt->second[permissionName] = permissionStatus;
HiLog::Debug(LABEL, "%{public}s end", __func__);
}
} // namespace Sensors
} // namespace OHOS
+102
View File
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2021 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 "report_data_cache.h"
#include <cstdlib>
#include <cstring>
#include "errors.h"
#include "securec.h"
#include "medical_errors.h"
#include "medical_log_domain.h"
namespace OHOS {
namespace Sensors {
using namespace OHOS::HiviewDFX;
namespace {
constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
LOG_CORE, MedicalSensorLogDomain::SENSOR_UTILS, "ReportDataCache"
};
} // namespace
ReportDataCache::ReportDataCache()
{
eventsBuf_.circularBuf = new struct SensorEvent[CIRCULAR_BUF_LEN];
eventsBuf_.readPosition = 0;
eventsBuf_.writePosition = 0;
eventsBuf_.eventNum = 0;
}
ReportDataCache::~ReportDataCache()
{
if (eventsBuf_.circularBuf != nullptr) {
delete[] eventsBuf_.circularBuf;
}
eventsBuf_.circularBuf = nullptr;
eventsBuf_.readPosition = 0;
eventsBuf_.writePosition = 0;
eventsBuf_.eventNum = 0;
}
int32_t ReportDataCache::CacheData(const struct SensorEvent* event, sptr<ReportDataCache> cache)
{
if (cache == nullptr || cache->eventsBuf_.circularBuf == nullptr || event == nullptr) {
HiLog::Error(LABEL, "%{public}s callback or circularBuf or event cannot be null", __func__);
return ERROR;
}
struct SensorEvent eventCopy = {
.sensorTypeId = event->sensorTypeId,
.version = event->version,
.timestamp = event->timestamp,
.option = event->option,
.mode = event->mode,
.dataLen = event->dataLen
};
uint32_t len = (event->dataLen < SENSOR_DATA_LENGHT) ? event->dataLen : SENSOR_DATA_LENGHT;
eventCopy.data = new uint8_t[len];
HiLog::Info(LABEL, "%{public}s dataLength: %{public}d, len = %{public}d", __func__, event->dataLen, len);
if (memcpy_s(eventCopy.data, len, event->data, event->dataLen) != EOK) {
HiLog::Error(LABEL, "%{public}s copy data failed", __func__);
return COPY_ERR;
}
int32_t leftSize = CIRCULAR_BUF_LEN - cache->eventsBuf_.eventNum;
int32_t toEndLen = CIRCULAR_BUF_LEN - cache->eventsBuf_.writePosition;
if (toEndLen == 0) {
cache->eventsBuf_.circularBuf[0] = eventCopy;
cache->eventsBuf_.writePosition = 1 - toEndLen;
} else {
cache->eventsBuf_.circularBuf[cache->eventsBuf_.writePosition] = eventCopy;
cache->eventsBuf_.writePosition += 1;
}
if (leftSize < 1) {
cache->eventsBuf_.readPosition = cache->eventsBuf_.writePosition;
}
cache->eventsBuf_.eventNum += 1;
if (cache->eventsBuf_.eventNum >= CIRCULAR_BUF_LEN) {
cache->eventsBuf_.eventNum = CIRCULAR_BUF_LEN;
}
if (cache->eventsBuf_.writePosition == CIRCULAR_BUF_LEN) {
cache->eventsBuf_.writePosition = 0;
}
return ERR_OK;
}
struct CircularEventBuf &ReportDataCache::GetEventData()
{
return eventsBuf_;
}
} // namespace Sensors
} // namespace OHOS