diff --git a/services/sensor/BUILD.gn b/services/sensor/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..1ca86991ff05f38ffc9c1d568473277f233a5bc9 --- /dev/null +++ b/services/sensor/BUILD.gn @@ -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. + +import("//build/ohos.gni") + +SUBSYSTEM_DIR = "//base/sensors" +ohos_shared_library("libsensor_service") { + sources = [ + "src/client_info.cpp", + "src/fifo_cache_data.cpp", + "src/flush_info_record.cpp", + "src/sensor_client_stub.cpp", + "src/sensor_data_processer.cpp", + "src/sensor_dump.cpp", + "src/sensor_manager.cpp", + "src/sensor_service.cpp", + "src/sensor_service_impl.cpp", + "src/sensor_service_stub.cpp", + ] + + include_dirs = [ + "include", + "$SUBSYSTEM_DIR/sensor/frameworks/native/sensor/include", + "$SUBSYSTEM_DIR/sensor/interfaces/native/include", + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/services/sensor/include", + "//drivers/peripheral/sensor/interfaces/include", + ] + + cflags = [ "-Wno-error=inconsistent-missing-override" ] + + deps = [ + "$SUBSYSTEM_DIR/sensor/utils:libsensor_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_L2:samgr_proxy", + ] + part_name = "sensors_sensor" + subsystem_name = "sensors" +} + +group("sensor_service_target") { + deps = [ ":libsensor_service" ] +} diff --git a/services/sensor/include/client_info.h b/services/sensor/include/client_info.h new file mode 100755 index 0000000000000000000000000000000000000000..21686710fa83ba5ba14faf823c9547803b426cb6 --- /dev/null +++ b/services/sensor/include/client_info.h @@ -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 +#include +#include +#include + +#include "refbase.h" +#include "singleton.h" + +#include "app_thread_info.h" +#include "iremote_object.h" +#include "nocopyable.h" +#include "sensor_basic_data_channel.h" +#include "sensor_basic_info.h" +#include "sensor_channel_info.h" +#include "sensor_agent_type.h" + +namespace OHOS { +namespace Sensors { +class ClientInfo : public Singleton { +public: + ClientInfo() = default; + virtual ~ClientInfo() = default; + + SensorState GetSensorState(uint32_t sensorId); + SensorBasicInfo GetBestSensorInfo(uint32_t sensorId); + bool OnlyCurPidSensorEnabled(uint32_t sensorId, int32_t pid); + std::vector> GetSensorChannel(uint32_t sensorId); + std::vector> GetSensorChannelByUid(int32_t uid); + sptr GetSensorChannelByPid(int32_t pid); + bool UpdateSensorInfo(uint32_t sensorId, int32_t pid, const SensorBasicInfo &sensorInfo); + void RemoveSubscriber(uint32_t sensorId, uint32_t pid); + bool UpdateSensorChannel(int32_t pid, const sptr &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); + SensorBasicInfo GetCurPidSensorInfo(uint32_t sensorId, int32_t pid); + uint64_t ComputeBestPeriodCount(uint32_t sensorId, sptr &channel); + uint64_t ComputeBestFifoCount(uint32_t sensorId, sptr &channel); + int32_t GetStoreEvent(int32_t sensorId, struct SensorEvent &event); + void StoreEvent(const struct SensorEvent &event); + void ClearEvent(); + AppThreadInfo GetAppInfoByChannel(const sptr &channel); + bool SaveClientPid(const sptr &sensorClient, int32_t pid); + int32_t FindClientPid(const sptr &sensorClient); + void DestroyClientPid(const sptr &sensorClient); + std::vector GetSensorIdByPid(int32_t pid); + void GetSensorChannelInfo(std::vector &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> GetDataQueue(); + void ClearDataQueue(int32_t sensorId); + +private: + DISALLOW_COPY_AND_MOVE(ClientInfo); + int32_t GetUidByPid(int32_t pid); + std::vector 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> clientMap_; + std::unordered_map> channelMap_; + std::unordered_map storedEvent_; + std::unordered_map uidMap_; + std::map, int32_t> clientPidMap_; + std::unordered_map>> cmdMap_; + std::unordered_map> dataQueue_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // CLIENT_INFO_H diff --git a/services/sensor/include/fifo_cache_data.h b/services/sensor/include/fifo_cache_data.h new file mode 100755 index 0000000000000000000000000000000000000000..89e4b5ebf8c33935499ffd6b9c86e3c39b5d6bc6 --- /dev/null +++ b/services/sensor/include/fifo_cache_data.h @@ -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 + +#include "refbase.h" +#include "sensor_agent_type.h" +#include "sensor_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 &fifoCacheData); + std::vector GetFifoCacheData() const; + void SetChannel(const sptr &channel); + sptr GetChannel() const; + void InitFifoCache(); + +private: + DISALLOW_COPY_AND_MOVE(FifoCacheData); + uint64_t periodCount_; + sptr channel_; + std::vector fifoCacheData_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // FIFO_CACHE_DATA_H \ No newline at end of file diff --git a/services/sensor/include/flush_info_record.h b/services/sensor/include/flush_info_record.h new file mode 100755 index 0000000000000000000000000000000000000000..c908430bf3bceaa90284214de78a0e10f7b1694c --- /dev/null +++ b/services/sensor/include/flush_info_record.h @@ -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 +#include +#include + +#include "client_info.h" +#include "refbase.h" +#include "sensor_basic_data_channel.h" +#include "sensor_service_impl.h" +#include "sensors_errors.h" +#include "singleton.h" +#include "nocopyable.h" +#include "sensor_agent_type.h" + +namespace OHOS { +namespace Sensors { +struct FlushInfo { + sptr flushChannel; + bool flushFromEnable; + + FlushInfo(const sptr &channel, bool enableFlush) + : flushChannel(channel), flushFromEnable(enableFlush){}; +}; + +class FlushInfoRecord : public Singleton { +public: + FlushInfoRecord() = default; + ~FlushInfoRecord() + { + flushInfo_.clear(); + } + + std::unordered_map> GetFlushInfo(); + void ClearFlushInfoItem(uint32_t sensorId); + ErrCode SetFlushInfo(uint32_t sensorId, const sptr &channel, bool isFirstFlush); + bool IsFlushChannelValid(const std::vector> &currChannelList, + const sptr &flushChannel); + int32_t GetFlushChannelIndex(const std::vector &flushInfoList, + const sptr &channel); + ErrCode FlushProcess(const uint32_t sensorId, const uint32_t flag, const int32_t pid, const bool isEnableFlush); + +private: + DISALLOW_COPY_AND_MOVE(FlushInfoRecord); + SensorServiceImpl &sensorServiceImpl_ = SensorServiceImpl::GetInstance(); + ClientInfo &clientInfo_ = ClientInfo::GetInstance(); + // sensorId, channel pointer for pending flush. + std::unordered_map> flushInfo_; + std::mutex flushInfoMutex_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // FLUSH_INFO_RECORD_H diff --git a/services/sensor/include/sensor_convert.h b/services/sensor/include/sensor_convert.h new file mode 100755 index 0000000000000000000000000000000000000000..b470b1fad53583d92d5adac847afb00deeb742ed --- /dev/null +++ b/services/sensor/include/sensor_convert.h @@ -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 SENSOR_DATA_CALLBACK_H +#define SENSOR_DATA_CALLBACK_H + +#include +#include +#include +#include "sensor_agent_type.h" +#include "refbase.h" +#include "sensor_device.h" + +namespace OHOS { +namespace Sensors { +using ConvertFun = int32_t (*)(const SensorEvent &event, struct SensorEvent &zEvent); + +class SensorConvert { +public: + int32_t ConvertToSensorEvent(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToHeartRate(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToOffbodyDetect(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToStepDetector(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToStepCounter(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToMetaData(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToMotionCali(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToMotionUncali(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToSignMotion(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToEnvironmentCali(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToEnvironmentUnCali(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToEnvironmentOther(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToOrientationPose(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToOrientationDevice(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToOrientation(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToOrientationVec(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToPressuePsAls(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToUnsupport(const SensorEvent &event, struct SensorEvent &zEvent); + static int32_t ConvertToDefaultEvent(const SensorEvent &event, struct SensorEvent &zEvent); + +private: + static SensorDevice &sensorDevice_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_DATA_CALLBACK_H diff --git a/services/sensor/include/sensor_data_processer.h b/services/sensor/include/sensor_data_processer.h new file mode 100755 index 0000000000000000000000000000000000000000..ecee8b14f85013380217cb40329877d12a38cfea --- /dev/null +++ b/services/sensor/include/sensor_data_processer.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 SENSORS_DATA_PROCESSER_H +#define SENSORS_DATA_PROCESSER_H + +#include +#include + +#include "refbase.h" + +#include "client_info.h" +#include "fifo_cache_data.h" +#include "flush_info_record.h" +#include "nocopyable.h" +#include "report_data_callback.h" +#include "sensor.h" +#include "sensors_log_domain.h" +#include "sensor_service_impl.h" +#include "sensor_agent_type.h" + +namespace OHOS { +namespace Sensors { +class SensorDataProcesser : public RefBase { +public: + explicit SensorDataProcesser(const std::unordered_map &sensorMap); + virtual ~SensorDataProcesser(); + int32_t ProcessEvents(sptr dataCallback); + int32_t SendEvents(sptr &channel, struct SensorEvent &event); + static int DataThread(sptr dataProcesser, sptr dataCallback); + int32_t CacheSensorEvent(const struct SensorEvent &event, sptr &channel); + +private: + DISALLOW_COPY_AND_MOVE(SensorDataProcesser); + void ReportData(sptr &channel, struct SensorEvent &event); + bool ReportNotContinuousData(std::unordered_map &cacheBuf, + sptr &channel, struct SensorEvent &event); + void SendNoneFifoCacheData(std::unordered_map &cacheBuf, + sptr &channel, struct SensorEvent &event, uint64_t periodCount); + void SendFifoCacheData(std::unordered_map &cacheBuf, + sptr &channel, struct SensorEvent &event, uint64_t periodCount, + uint64_t fifoCount); + void SendRawData(std::unordered_map &cacheBuf, sptr channel, + std::vector event); + void EventFilter(struct CircularEventBuf &eventsBuf); + bool CheckSendDataPermission(sptr channel, uint32_t sensorId); + ClientInfo &clientInfo_ = ClientInfo::GetInstance(); + FlushInfoRecord &flushInfo_ = FlushInfoRecord::GetInstance(); + std::mutex dataCountMutex_; + std::unordered_map>> dataCountMap_; + std::mutex sensorMutex_; + std::unordered_map sensorMap_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // endif SENSORS_DATA_PROCESSER_H diff --git a/services/sensor/include/sensor_dump.h b/services/sensor/include/sensor_dump.h new file mode 100755 index 0000000000000000000000000000000000000000..bdce904143f9fa5ee11f9125b53653c2995557f3 --- /dev/null +++ b/services/sensor/include/sensor_dump.h @@ -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_DUMP_H +#define SENSOR_DUMP_H + +#include + +#include "singleton.h" + +#include "client_info.h" +#include "sensor.h" +#include "nocopyable.h" +#include "sensor_agent_type.h" + +namespace OHOS { +namespace Sensors { +class SensorDump : public Singleton { +public: + SensorDump() = default; + virtual ~SensorDump() = default; + void DumpHelp(int32_t fd); + bool DumpSensorHelp(int32_t fd, const std::vector &args); + bool DumpSensorList(int32_t fd, const std::vector &sensors, const std::vector &args); + bool DumpSensorChannel(int32_t fd, ClientInfo &clientInfo, const std::vector &args); + bool DumpOpeningSensor(int32_t fd, const std::vector &sensors, ClientInfo &clientInfo, + const std::vector &args); + bool DumpSensorData(int32_t fd, ClientInfo &clientInfo, const std::vector &args); + +private: + DISALLOW_COPY_AND_MOVE(SensorDump); + void DumpCurrentTime(int32_t fd); + int32_t DataSizeBySensorId(uint32_t sensorId); + std::string GetDataBySensorId(uint32_t sensorId, struct SensorEvent &sensorData); + static std::unordered_map sensorMap_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_DUMP_H diff --git a/services/sensor/include/sensor_manager.h b/services/sensor/include/sensor_manager.h new file mode 100755 index 0000000000000000000000000000000000000000..cd17052b3f8f75cba8f2b6f1a582d0fac8cdcc13 --- /dev/null +++ b/services/sensor/include/sensor_manager.h @@ -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 +#include +#include + +#include "client_info.h" +#include "flush_info_record.h" +#include "sensor_data_processer.h" +#include "sensor_service_impl.h" +#include "sensor_agent_type.h" + +namespace OHOS { +namespace Sensors { +class SensorManager : public Singleton { +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(); + SensorBasicInfo 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 &sensorMap, sptr dataProcesser, + sptr dataCallback); + uint32_t GetSensorFlag(uint32_t sensorId); + void GetPackageNameFromUid(int32_t uid, std::string &packageName); + +private: + SensorServiceImpl &sensorServiceImpl_ = SensorServiceImpl::GetInstance(); + ClientInfo &clientInfo_ = ClientInfo::GetInstance(); + std::thread dataThread_; + sptr sensorDataProcesser_; + sptr reportDataCallback_; + std::unordered_map sensorMap_; + std::mutex sensorMapMutex_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_MANAGER_H diff --git a/services/sensor/include/sensor_service.h b/services/sensor/include/sensor_service.h new file mode 100755 index 0000000000000000000000000000000000000000..141a385b9ca1f71966a3bd6f4183cee43c9f2272 --- /dev/null +++ b/services/sensor/include/sensor_service.h @@ -0,0 +1,101 @@ +/* + * 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 +#include +#include + +#include "client_info.h" +#include "sensor_service_impl.h" + +#include "death_recipient_template.h" +#include "nocopyable.h" +#include "sensor_manager.h" +#include "sensor_service_stub.h" +#include "system_ability.h" +#include "sensor_agent_type.h" + +namespace OHOS { +namespace Sensors { +enum class SensorServiceState { + STATE_STOPPED, + STATE_RUNNING, +}; + +class SensorService : public SystemAbility, public SensorServiceStub { + DECLARE_SYSTEM_ABILITY(SensorService) +public: + explicit SensorService(int32_t systemAbilityId, bool runOnCreate = false); + + virtual ~SensorService() = default; + + void OnDump() override; + + void OnStart() override; + + void OnStop() override; + + int Dump(int fd, const std::vector &args) override; + + ErrCode EnableSensor(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) override; + + ErrCode DisableSensor(uint32_t sensorId) override; + + int32_t GetSensorState(uint32_t sensorId) override; + + ErrCode RunCommand(uint32_t sensorId, uint32_t cmdType, uint32_t params) override; + + std::vector GetSensorList() override; + + ErrCode TransferDataChannel(const sptr &sensorBasicDataChannel, + const sptr &sensorClient) override; + + ErrCode DestroySensorChannel(sptr sensorClient) override; + + void ProcessDeathObserver(const wptr &object); + +private: + DISALLOW_COPY_AND_MOVE(SensorService); + void RegisterClientDeathRecipient(sptr sensorClient, int32_t pid); + void UnregisterClientDeathRecipient(sptr sensorClient); + bool InitInterface(); + bool InitDataCallback(); + bool InitSensorList(); + bool InitSensorPolicy(); + void ReportOnChangeData(uint32_t sensorId); + void ReportSensorUsedInfo(uint32_t sensorId, bool enable); + SensorServiceState state_; + std::mutex serviceLock_; + std::mutex sensorsMutex_; + std::mutex sensorMapMutex_; + std::vector sensors_; + std::unordered_map sensorMap_; + SensorServiceImpl &sensorServiceImpl_ = SensorServiceImpl::GetInstance(); + ClientInfo &clientInfo_ = ClientInfo::GetInstance(); + SensorManager &sensorManager_ = SensorManager::GetInstance(); + FlushInfoRecord &flushInfo_ = FlushInfoRecord::GetInstance(); + sptr sensorDataProcesser_; + sptr reportDataCallback_; + std::mutex uidLock_; + // death recipient of sensor client + sptr clientDeathObserver_; + ErrCode SaveSubscriber(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs); +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_SERVICE_H diff --git a/services/sensor/include/sensor_service_impl.h b/services/sensor/include/sensor_service_impl.h new file mode 100755 index 0000000000000000000000000000000000000000..ba425f4b7d2813abea917f8eb6350f0e85ec59c8 --- /dev/null +++ b/services/sensor/include/sensor_service_impl.h @@ -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. + */ + +#ifndef SENSOR_INTERFACE_H +#define SENSOR_INTERFACE_H + +#include "report_data_callback.h" +#include "errors.h" +#include "refbase.h" +#include "singleton.h" +#include "sensor.h" +#include "sensor_if.h" +#include "sensor_agent_type.h" +#include "nocopyable.h" + +namespace OHOS { +namespace Sensors { +class SensorServiceImpl : public Singleton { +public: + SensorServiceImpl() = default; + virtual ~SensorServiceImpl() = default; + std::vector GetSensorList() const; + + ErrCode EnableSensor(uint32_t sensorId) const; + + ErrCode DisableSensor(uint32_t sensorId) 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(ZReportDataCb cb, sptr reportDataCallback); + + ErrCode Unregister(void) const; + + static int32_t SensorDataCallback(const struct SensorEvents *event); + static std::mutex dataMutex_; + static std::condition_variable dataCondition_; + +private: + DISALLOW_COPY_AND_MOVE(SensorServiceImpl); + const struct SensorInterface *sensorInterface_ = nullptr; + ErrCode Register(RecordDataCallback cb) const; + static ZReportDataCb reportDataCb_; + static sptr reportDataCallback_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_INTERFACE_H diff --git a/services/sensor/include/sensor_service_proxy.h b/services/sensor/include/sensor_service_proxy.h new file mode 100755 index 0000000000000000000000000000000000000000..a694ca2d388eaa8a8695688373b9c0e21362ab81 --- /dev/null +++ b/services/sensor/include/sensor_service_proxy.h @@ -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. + */ + +#ifndef SENSOR_SERVICE_PROXY_H +#define SENSOR_SERVICE_PROXY_H + +#include "errors.h" +#include "i_sensor_service.h" +#include "iremote_proxy.h" +#include "nocopyable.h" +#include "sensor_agent_type.h" + +namespace OHOS { +namespace Sensors { +class SensorServiceProxy : public IRemoteProxy { +public: + explicit SensorServiceProxy(const sptr &impl); + virtual ~SensorServiceProxy() = default; + ErrCode EnableSensor(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) override; + ErrCode DisableSensor(uint32_t sensorId) override; + int32_t GetSensorState(uint32_t sensorId) override; + ErrCode RunCommand(uint32_t sensorId, uint32_t cmdType, uint32_t params) override; + std::vector GetSensorList() override; + ErrCode TransferDataChannel(const sptr &sensorBasicDataChannel, + const sptr &sensorClient) override; + ErrCode DestroySensorChannel(sptr sensorClient) override; + +private: + DISALLOW_COPY_AND_MOVE(SensorServiceProxy); + static inline BrokerDelegator delegator_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_SERVICE_PROXY_H diff --git a/services/sensor/include/sensor_service_stub.h b/services/sensor/include/sensor_service_stub.h new file mode 100755 index 0000000000000000000000000000000000000000..6b2022082156a675d0f55451b0e99151ab56eb19 --- /dev/null +++ b/services/sensor/include/sensor_service_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_SERVICE_STUB_H +#define SENSOR_SERVICE_STUB_H + +#include "iremote_stub.h" +#include "message_parcel.h" +#include "nocopyable.h" + +#include "i_sensor_service.h" + +namespace OHOS { +namespace Sensors { +class SensorServiceStub : public IRemoteStub { +public: + SensorServiceStub(); + virtual ~SensorServiceStub(); + virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) override; + +private: + DISALLOW_COPY_AND_MOVE(SensorServiceStub); + using SensorBaseFunc = ErrCode (SensorServiceStub::*)(MessageParcel &data, MessageParcel &reply); + + ErrCode SensorEnableInner(MessageParcel &data, MessageParcel &reply); + ErrCode SensorDisableInner(MessageParcel &data, MessageParcel &reply); + ErrCode GetSensorStateInner(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); + + bool CheckSensorPermission(uint32_t sensorId); + std::unordered_map baseFuncs_; + static std::unordered_map sensorIdPermissions_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_SERVICE_STUB_H diff --git a/services/sensor/src/client_info.cpp b/services/sensor/src/client_info.cpp new file mode 100755 index 0000000000000000000000000000000000000000..7c504dbc994f2a12763dccfa2e8083ac61f10645 --- /dev/null +++ b/services/sensor/src/client_info.cpp @@ -0,0 +1,719 @@ +/* + * 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 + +#include "securec.h" +#include "sensor_service_impl.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +#include "permission_util.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::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 + +SensorState 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 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; +} + +SensorBasicInfo 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; + SensorBasicInfo 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 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 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 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 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; + } + } + AppThreadInfo 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> 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> sensorChannel; + std::lock_guard uidLock(uidMutex_); + for (const auto &uidIt : uidMap_) { + if (uid != uidIt.second) { + continue; + } + std::lock_guard channelLock(channelMutex_); + auto channelIt = channelMap_.find(uidIt.first); + if (channelIt == channelMap_.end()) { + continue; + } + sensorChannel.push_back(channelIt->second); + } + HiLog::Debug(LABEL, "%{public}s end", __func__); + return sensorChannel; +} + +sptr 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 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> ClientInfo::GetSensorChannel(uint32_t sensorId) +{ + if (sensorId == INVALID_SENSOR_ID) { + HiLog::Error(LABEL, "%{public}s sensorId is invalid", __func__); + return {}; + } + + std::lock_guard 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> sensorChannel; + for (const auto &sensorInfoIt : clientIt->second) { + std::lock_guard channelLock(channelMutex_); + auto channelIt = channelMap_.find(sensorInfoIt.first); + if (channelIt == channelMap_.end()) { + continue; + } + sensorChannel.push_back(channelIt->second); + } + return sensorChannel; +} + +bool ClientInfo::UpdateSensorInfo(uint32_t sensorId, int32_t pid, const SensorBasicInfo &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 clientLock(clientMutex_); + auto it = clientMap_.find(sensorId); + if (it == clientMap_.end()) { + std::unordered_map 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 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 &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 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 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 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 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 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; +} + +SensorBasicInfo 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; + SensorBasicInfo 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 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 &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 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 Sensor 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 &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 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 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 = &SensorServiceImpl::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 lock(eventMutex_); + storedEvent_[storedEvent.sensorTypeId] = storedEvent; + } +} + +bool ClientInfo::SaveClientPid(const sptr &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 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 &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 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 &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 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 lock(eventMutex_); + storedEvent_.clear(); +} + +std::vector ClientInfo::GetSensorIdByPid(int32_t pid) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + std::vector sensorIdVec; + std::lock_guard 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; +} + +AppThreadInfo ClientInfo::GetAppInfoByChannel(const sptr &channel) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + AppThreadInfo appThreadInfo; + { + std::lock_guard channelLock(channelMutex_); + for (auto channelIt = channelMap_.begin(); channelIt != channelMap_.end(); channelIt++) { + if (channelIt->second == channel) { + appThreadInfo.pid = channelIt->first; + } + } + } + { + std::lock_guard uidLock(uidMutex_); + auto it = uidMap_.find(appThreadInfo.pid); + if (it != uidMap_.end()) { + appThreadInfo.uid = it->second; + } + } + return appThreadInfo; +} + +void ClientInfo::GetSensorChannelInfo(std::vector &channelInfo) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + std::lock_guard clientLock(clientMutex_); + for (const auto &sensorIt : clientMap_) { + for (const auto &pidIt : sensorIt.second) { + SensorChannelInfo 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 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 cmdLock(cmdMutex_); + auto cmdIt = cmdMap_.find(sensorId); + if (cmdIt == cmdMap_.end()) { + std::unordered_map> cmds; + std::vector 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 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 cmdLock(cmdMutex_); + cmdMap_.erase(uid); +} + +std::vector ClientInfo::GetCmdList(uint32_t sensorId, int32_t uid) +{ + std::lock_guard 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 queueLock(dataQueueMutex_); + auto it = dataQueue_.find(sensorId); + if (it == dataQueue_.end()) { + std::queue 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> ClientInfo::GetDataQueue() +{ + return dataQueue_; +} + +void ClientInfo::ClearDataQueue(int32_t sensorId) +{ + std::lock_guard queueLock(dataQueueMutex_); + auto it = dataQueue_.find(sensorId); + if (it != dataQueue_.end()) { + dataQueue_.erase(it); + } +} +} // namespace Sensors +} // namespace OHOS diff --git a/services/sensor/src/fifo_cache_data.cpp b/services/sensor/src/fifo_cache_data.cpp new file mode 100755 index 0000000000000000000000000000000000000000..efa3dadc09507c9fd372c94ab89a10a8e35de2d7 --- /dev/null +++ b/services/sensor/src/fifo_cache_data.cpp @@ -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 &fifoCacheData) +{ + fifoCacheData_ = fifoCacheData; +} + +std::vector FifoCacheData::GetFifoCacheData() const +{ + return fifoCacheData_; +} + +void FifoCacheData::SetChannel(const sptr &channel) +{ + channel_ = channel; +} +sptr FifoCacheData::GetChannel() const +{ + return channel_; +} +} // namespace Sensors +} // namespace OHOS diff --git a/services/sensor/src/flush_info_record.cpp b/services/sensor/src/flush_info_record.cpp new file mode 100755 index 0000000000000000000000000000000000000000..80a1ba5c120a6add58309efd335a40c5c1fd0ffa --- /dev/null +++ b/services/sensor/src/flush_info_record.cpp @@ -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 "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_SERVICE, "FlushInfoRecord" }; +constexpr int32_t CHANNEL_NO_FLUSH = -1; +enum { + FLUSH = 0, + SET_MODE, + RESERVED, +}; +} // namespace + +std::unordered_map> FlushInfoRecord::GetFlushInfo() +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + std::lock_guard flushLock(flushInfoMutex_); + return flushInfo_; +} + +void FlushInfoRecord::ClearFlushInfoItem(uint32_t sensorId) +{ + std::lock_guard 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 &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 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 vec { flush }; + flushInfo_.insert(std::make_pair(sensorId, vec)); + } + return ERR_OK; +} + +bool FlushInfoRecord::IsFlushChannelValid(const std::vector> &currChannelList, + const sptr &flushChannel) +{ + HiLog::Debug(LABEL, "%{public}s channel list size : %{public}u", __func__, + static_cast(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 &flushInfoList, + const sptr &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 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 diff --git a/services/sensor/src/sensor_client_stub.cpp b/services/sensor/src/sensor_client_stub.cpp new file mode 100755 index 0000000000000000000000000000000000000000..41c6cacb07b1a6ebae62106cdf1b3f404d1589ff --- /dev/null +++ b/services/sensor/src/sensor_client_stub.cpp @@ -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 "sensor_client_stub.h" + +#include "message_parcel.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_SERVICE, "SensorClientStub" }; +} + +int32_t SensorClientStub::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 diff --git a/services/sensor/src/sensor_convert.cpp b/services/sensor/src/sensor_convert.cpp new file mode 100755 index 0000000000000000000000000000000000000000..2373128c4b4b3314e20bb3ce114f02044b102a43 --- /dev/null +++ b/services/sensor/src/sensor_convert.cpp @@ -0,0 +1,259 @@ +/* + * 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 "sensor_convert.h" + +#include "report_data_callback.h" +#include "securec.h" +#include "sensor_mapping.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_ADAPTER, "SensorDataCallback" }; +constexpr uint32_t INVALID_SENSOR_ID = -1; + +enum { + RET_OK = 0, + COPY_FAIL = -1, + DATA_TYPE_UNSUPPORT = -2, +}; + +enum { + X_VALUE = 0, + Y_VALUE = 1, + Z_VALUE = 2, + X_BIAS_VALUE = 3, + Y_BIAS_VALUE = 4, + Z_BIAS_VALUE = 5, + W_VALUE = 3, +}; + +enum { + LIGHT_DIMENSION = 3, + POSE_6DOF_DIMENSION = 15, + DEFAULT_DIMENSION = 16, +}; +} // namespace + +static std::map g_convertMap { + { SENSOR_TYPE_ACCELEROMETER, SensorDataCallback::ConvertToMotionCali }, + { SENSOR_TYPE_LINEAR_ACCELERATION, SensorDataCallback::ConvertToMotionCali }, + { SENSOR_TYPE_GRAVITY, SensorDataCallback::ConvertToMotionCali }, + { SENSOR_TYPE_GYROSCOPE, SensorDataCallback::ConvertToMotionCali }, + { SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED, SensorDataCallback::ConvertToMotionUncali }, + { SENSOR_TYPE_GYROSCOPE_UNCALIBRATED, SensorDataCallback::ConvertToMotionUncali }, + { SENSOR_TYPE_SIGNIFICANT_MOTION, SensorDataCallback::ConvertToSignMotion }, + { SensorType::STEP_DETECTOR, SensorDataCallback::ConvertToStepDetector }, + { SensorType::STEP_COUNTER, SensorDataCallback::ConvertToStepCounter }, + + { SENSOR_TYPE_AMBIENT_TEMPERATURE, SensorDataCallback::ConvertToEnvironmentOther }, + { SENSOR_TYPE_HUMIDITY, SensorDataCallback::ConvertToEnvironmentOther }, + { SENSOR_TYPE_MAGNETIC_FIELD, SensorDataCallback::ConvertToEnvironmentCali }, + { SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED, SensorDataCallback::ConvertToEnvironmentUnCali }, + { SensorType::PRESSURE, SensorDataCallback::ConvertToPressuePsAls }, + + { SensorType::POSE_6DOF, SensorDataCallback::ConvertToOrientationPose }, + { SENSOR_TYPE_DEVICE_ORIENTATION, SensorDataCallback::ConvertToOrientationDevice }, + { SENSOR_TYPE_ORIENTATION, SensorDataCallback::ConvertToOrientation }, + { SENSOR_TYPE_ROTATION_VECTOR, SensorDataCallback::ConvertToOrientationVec }, + { SENSOR_TYPE_GAME_ROTATION_VECTOR, SensorDataCallback::ConvertToOrientationVec }, + { SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR, SensorDataCallback::ConvertToOrientationVec }, + + { SENSOR_TYPE_PROXIMITY, SensorDataCallback::ConvertToPressuePsAls }, + { SENSOR_TYPE_AMBIENT_LIGHT, SensorDataCallback::ConvertToPressuePsAls }, + + { SensorType::META_DATA, SensorDataCallback::ConvertToMetaData }, + { SensorType::DYNAMIC_SENSOR_META, SensorDataCallback::ConvertToUnsupport }, + { SensorType::ADDITIONAL_INFO, SensorDataCallback::ConvertToUnsupport }, + + { SENSOR_TYPE_HEART_RATE, SensorDataCallback::ConvertToHeartRate }, + { SensorType::LOW_LATENCY_OFFBODY_DETECT, SensorDataCallback::ConvertToOffbodyDetect }, +}; + +int32_t SensorDataCallback::ConvertToHeartRate(const SensorEvent &event, struct SensorEvent &zEvent) +{ + zEvent.body.data[0] = aEvent.u.heartRate.bpm; + zEvent.body.data[1] = static_cast(aEvent.u.heartRate.status); + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToOffbodyDetect(const SensorEvent &event, struct SensorEvent &zEvent) +{ + zEvent.body.data[0] = aEvent.u.scalar; + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToStepCounter(const SensorEvent &event, struct SensorEvent &zEvent) +{ + zEvent.motion.data[0] = aEvent.u.stepCount; + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToStepDetector(const SensorEvent &event, struct SensorEvent &zEvent) +{ + zEvent.motion.data[0] = aEvent.u.scalar; + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToMotionCali(const SensorEvent &event, struct SensorEvent &zEvent) +{ + zEvent.motion.data[X_VALUE] = aEvent.u.vec3.x; + zEvent.motion.data[Y_VALUE] = aEvent.u.vec3.y; + zEvent.motion.data[Z_VALUE] = aEvent.u.vec3.z; + zEvent.accuracy = static_cast(aEvent.u.vec3.status); + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToMotionUncali(const SensorEvent &event, struct SensorEvent &zEvent) +{ + zEvent.motion.data[X_VALUE] = aEvent.u.uncal.x; + zEvent.motion.data[Y_VALUE] = aEvent.u.uncal.y; + zEvent.motion.data[Z_VALUE] = aEvent.u.uncal.z; + zEvent.motion.data[X_BIAS_VALUE] = aEvent.u.uncal.x_bias; + zEvent.motion.data[Y_BIAS_VALUE] = aEvent.u.uncal.y_bias; + zEvent.motion.data[Z_BIAS_VALUE] = aEvent.u.uncal.z_bias; + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToSignMotion(const SensorEvent &event, struct SensorEvent &zEvent) +{ + zEvent.motion.data[0] = aEvent.u.scalar; + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToEnvironmentCali(const SensorEvent &event, struct SensorEvent &zEvent) +{ + zEvent.environment.data[X_VALUE] = aEvent.u.vec3.x; + zEvent.environment.data[Y_VALUE] = aEvent.u.vec3.y; + zEvent.environment.data[Z_VALUE] = aEvent.u.vec3.z; + zEvent.accuracy = static_cast(aEvent.u.vec3.status); + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToEnvironmentUnCali(const SensorEvent &event, struct SensorEvent &zEvent) +{ + zEvent.environment.data[X_VALUE] = aEvent.u.uncal.x; + zEvent.environment.data[Y_VALUE] = aEvent.u.uncal.y; + zEvent.environment.data[Z_VALUE] = aEvent.u.uncal.z; + zEvent.environment.data[X_BIAS_VALUE] = aEvent.u.uncal.x_bias; + zEvent.environment.data[Y_BIAS_VALUE] = aEvent.u.uncal.y_bias; + zEvent.environment.data[Z_BIAS_VALUE] = aEvent.u.uncal.z_bias; + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToEnvironmentOther(const SensorEvent &event, struct SensorEvent &zEvent) +{ + zEvent.environment.data[0] = aEvent.u.scalar; + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToOrientationPose(const SensorEvent &event, struct SensorEvent &zEvent) +{ + for (int32_t i = 0; i < POSE_6DOF_DIMENSION; ++i) { + zEvent.orientation.data[i] = aEvent.u.pose6DOF[i]; + } + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToOrientationDevice(const SensorEvent &event, struct SensorEvent &zEvent) +{ + zEvent.orientation.data[0] = aEvent.u.scalar; + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToOrientation(const SensorEvent &event, struct SensorEvent &zEvent) +{ + zEvent.orientation.data[X_VALUE] = aEvent.u.vec3.x; + zEvent.orientation.data[Y_VALUE] = aEvent.u.vec3.y; + zEvent.orientation.data[Z_VALUE] = aEvent.u.vec3.z; + zEvent.accuracy = static_cast(aEvent.u.vec3.status); + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToOrientationVec(const SensorEvent &event, struct SensorEvent &zEvent) +{ + zEvent.orientation.data[X_VALUE] = aEvent.u.vec4.x; + zEvent.orientation.data[Y_VALUE] = aEvent.u.vec4.y; + zEvent.orientation.data[Z_VALUE] = aEvent.u.vec4.z; + zEvent.orientation.data[W_VALUE] = aEvent.u.vec4.w; + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToPressuePsAls(const SensorEvent &event, struct SensorEvent &zEvent) +{ + for (int32_t i = 0; i < LIGHT_DIMENSION; i++) { + zEvent.light.data[i] = aEvent.u.data[i]; + } + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToMetaData(const SensorEvent &event, struct SensorEvent &zEvent) +{ + SensorMapping sensorMapping; + zEvent.other.data[0] = static_cast(aEvent.u.meta.what); + // for Meta data, meta sensorId is stored in the 'sensorId' of zEvent header, + // real sensorid store in zEvent.other.reserved[0] + uint32_t realType = sensorDevice_.GetSensorTypeFromHandle(aEvent.sensorHandle); + zEvent.other.reserved[0] = sensorMapping.GetSensorIdByAType(static_cast(realType)); + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToUnsupport(const SensorEvent &event, struct SensorEvent &zEvent) +{ + return DATA_TYPE_UNSUPPORT; +} + +std::mutex SensorDataCallback::dataMutex_; +std::condition_variable SensorDataCallback::dataCondition_; + +int32_t SensorDataCallback::ConvertToDefaultEvent(const SensorEvent &event, struct SensorEvent &zEvent) +{ + if (aEvent.sensorType >= SensorType::DEVICE_PRIVATE_BASE) { + // data is defined with 16 float array + if (memcpy_s(zEvent.other.data, DEFAULT_DIMENSION * sizeof(float), aEvent.u.data.data(), + DEFAULT_DIMENSION * sizeof(float)) != EOK) { + HiLog::Error(LABEL, "%{public}s : memcpy_s is failed", __func__); + return COPY_FAIL; + } + } + return ERR_OK; +} + +int32_t SensorDataCallback::ConvertToSensorEvent(const SensorEvent &event, struct SensorEvent &zEvent) +{ + int32_t sensorTypeId = event.sensorTypeId; + if (sensorId == INVALID_SENSOR_ID) { + HiLog::Error(LABEL, "%{public}s failed", __func__); + return ERR_INVALID_VALUE; + } + + zEvent = { .version = sensorDevice_.GetHalDeviceVersion(), + .sensorId = sensorId, + .flags = 0, + .timestamp = aEvent.timestamp, + .accuracy = 0 }; + + auto it = g_convertMap.find(aEvent.sensorType); + if (it != g_convertMap.end()) { + return it->second(aEvent, zEvent); + } + return ConvertToDefaultEvent(aEvent, zEvent); +} +} // namespace Sensors +} // namespace OHOS diff --git a/services/sensor/src/sensor_data_processer.cpp b/services/sensor/src/sensor_data_processer.cpp new file mode 100755 index 0000000000000000000000000000000000000000..c499a4f4acfb635985e78719ca541c7883aa858e --- /dev/null +++ b/services/sensor/src/sensor_data_processer.cpp @@ -0,0 +1,412 @@ +/* + * 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 "sensor_data_processer.h" + +#include +#include + +#include "permission_util.h" +#include "securec.h" +#include "sensor_basic_data_channel.h" +#include "sensor_catalog.h" +#include "sensors_errors.h" +#include "system_ability_definition.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_UTILS, "SensorDataProcesser" }; + +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 + +SensorDataProcesser::SensorDataProcesser(const std::unordered_map &sensorMap) +{ + sensorMap_.insert(sensorMap.begin(), sensorMap.end()); + HiLog::Debug(LABEL, "%{public}s sensorMap_.size : %{public}d", __func__, int32_t { sensorMap_.size() }); +} + +SensorDataProcesser::~SensorDataProcesser() +{ + dataCountMap_.clear(); + sensorMap_.clear(); +} + +void SensorDataProcesser::SendNoneFifoCacheData(std::unordered_map &cacheBuf, + sptr &channel, struct SensorEvent &event, + uint64_t periodCount) +{ + std::vector sendEvents; + std::lock_guard 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> channelFifoList; + sptr 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 = 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 SensorDataProcesser::SendFifoCacheData(std::unordered_map &cacheBuf, + sptr &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 dataCountLock(dataCountMutex_); + auto dataCountIt = dataCountMap_.find(sensorId); + // there is no channelFifoList + if (dataCountIt == dataCountMap_.end()) { + std::vector> channelFifoList; + sptr 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 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 = 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 SensorDataProcesser::ReportData(sptr &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 &>(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 SensorDataProcesser::ReportNotContinuousData(std::unordered_map &cacheBuf, + sptr &channel, struct SensorEvent &event) +{ + uint32_t sensorId = event.sensorTypeId; + if (sensorId == FLUSH_COMPLETE_ID) { + sensorId = event.sensorTypeId; + } + std::lock_guard 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 sendEvents; + sendEvents.push_back(event); + SendRawData(cacheBuf, channel, sendEvents); + return true; + } + return false; +} + +bool SensorDataProcesser::CheckSendDataPermission(sptr channel, uint32_t sensorId) +{ + return true; +} + +void SensorDataProcesser::SendRawData(std::unordered_map &cacheBuf, + sptr channel, std::vector 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 transferEvents; + for (int32_t i = 0; i < (int32_t)eventSize; i++) { + struct TransferSensorEvents 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, event[i].dataLen, 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 TransferSensorEvents)); + 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 SensorDataProcesser::CacheSensorEvent(const struct SensorEvent &event, sptr &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 &>(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 SensorDataProcesser::EventFilter(struct CircularEventBuf &eventsBuf) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + uint32_t realSensorId = 0; + uint32_t sensorId = eventsBuf.circularBuf[eventsBuf.readPosition].sensorTypeId; + std::vector> 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 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 SensorDataProcesser::ProcessEvents(sptr dataCallback) +{ + if (dataCallback == nullptr) { + HiLog::Error(LABEL, "%{public}s dataCallback cannot be null", __func__); + return INVALID_POINTER; + } + std::unique_lock lk(SensorServiceImpl::dataMutex_); + SensorServiceImpl::dataCondition_.wait(lk); + auto &eventsBuf = dataCallback->GetEventData(); + if (eventsBuf.eventNum <= 0) { + HiLog::Error(LABEL, "%{public}s data cannot be empty", __func__); + return NO_EVENT; + } + int32_t eventNum = eventsBuf.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 SensorDataProcesser::SendEvents(sptr &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 SensorDataProcesser::DataThread(sptr dataProcesser, sptr dataCallback) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + do { + if (dataProcesser->ProcessEvents(dataCallback) == INVALID_POINTER) { + HiLog::Error(LABEL, "%{public}s callback cannot be null", __func__); + return INVALID_POINTER; + } + } while (1); +} +} // namespace Sensors +} // namespace OHOS diff --git a/services/sensor/src/sensor_dump.cpp b/services/sensor/src/sensor_dump.cpp new file mode 100755 index 0000000000000000000000000000000000000000..1d04e2dd4fe29f9a53fc65451874dc5253767a5b --- /dev/null +++ b/services/sensor/src/sensor_dump.cpp @@ -0,0 +1,293 @@ +/* + * 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 "sensor_dump.h" + +#include +#include +#include + +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_SERVICE, "SensorDump" }; +constexpr uint32_t MAX_DUMP_DATA_SIZE = 10; +constexpr uint32_t MS_NS = 1000000; +constexpr uint32_t ACCELEROMETER = 256; +constexpr uint32_t ACCELEROMETER_UNCALIBRATED = 65792; +constexpr uint32_t LINEAR_ACCELERATION = 131328; +constexpr uint32_t GRAVITY = 196864; +constexpr uint32_t GYROSCOPE = 262400; +constexpr uint32_t GYROSCOPE_UNCALIBRATED = 327936; +constexpr uint32_t SIGNIFICANT_MOTION = 393472; +constexpr uint32_t DROP_DETECTION = 459008; +constexpr uint32_t PEDOMETER_DETECTION = 524544; +constexpr uint32_t PEDOMETER = 590080; +constexpr uint32_t AMBIENT_TEMPERATURE = 16777472; +constexpr uint32_t MAGNETIC_FIELD = 16843008; +constexpr uint32_t MAGNETIC_FIELD_UNCALIBRATED = 16908544; +constexpr uint32_t HUMIDITY = 16974080; +constexpr uint32_t BAROMETER = 17039616; +constexpr uint32_t SAR = 17105152; +constexpr uint32_t SIXDOF_ATTITUDE = 33554688; +constexpr uint32_t SCREEN_ROTATION = 33620224; +constexpr uint32_t DEVICE_ORIENTATION = 33685760; +constexpr uint32_t ORIENTATION = 33751296; +constexpr uint32_t ROTATION_VECTOR = 33816832; +constexpr uint32_t GAME_ROTATION_VECTOR = 33882368; +constexpr uint32_t GEOMAGNETIC_ROTATION_VECTOR = 33947904; +constexpr uint32_t PROXIMITY = 50331904; +constexpr uint32_t TOF = 50397440; +constexpr uint32_t AMBIENT_LIGHT = 50462976; +constexpr uint32_t COLOR_TEMPERATURE = 50528512; +constexpr uint32_t COLOR_RGB = 50594048; +constexpr uint32_t COLOR_XYZ = 50659584; +constexpr uint32_t HALL = 67109120; +constexpr uint32_t GRIP_DETECTOR = 67174656; +constexpr uint32_t MAGNET_BRACKET = 67240192; +constexpr uint32_t PRESSURE_DETECTOR = 67305728; +constexpr uint32_t HEART_RATE = 83886336; +constexpr uint32_t WEAR_DETECTION = 83951872; + +enum { + SOLITARIES_DIMENSION = 1, + COMMON_DIMENSION = 3, + VECTOR_DIMENSION = 4, + POSE_6DOF_DIMENSION = 15, + UNCALIBRATED_DIMENSION = 6, + DEFAULT_DIMENSION = 16, +}; +} // namespace + +std::unordered_map SensorDump::sensorMap_ = { + { ACCELEROMETER, "ACCELEROMETER" }, + { ACCELEROMETER_UNCALIBRATED, "ACCELEROMETER UNCALIBRATED" }, + { LINEAR_ACCELERATION, "LINEAR ACCELERATION" }, + { GRAVITY, "GRAVITY" }, + { GYROSCOPE, "GYROSCOPE" }, + { GYROSCOPE_UNCALIBRATED, "GYROSCOPE UNCALIBRATED" }, + { SIGNIFICANT_MOTION, "SIGNIFICANT MOTION" }, + { DROP_DETECTION, "DROP DETECTION" }, + { PEDOMETER_DETECTION, "PEDOMETER DETECTION" }, + { PEDOMETER, "PEDOMETER" }, + { AMBIENT_TEMPERATURE, "AMBIENT TEMPERATURE" }, + { MAGNETIC_FIELD, "MAGNETIC FIELD" }, + { MAGNETIC_FIELD_UNCALIBRATED, "MAGNETIC FIELD UNCALIBRATED" }, + { HUMIDITY, "HUMIDITY" }, + { BAROMETER, "BAROMETER" }, + { SAR, "SAR" }, + { SIXDOF_ATTITUDE, "6DOF ATTITUDE" }, + { SCREEN_ROTATION, "SCREEN ROTATION" }, + { DEVICE_ORIENTATION, "DEVICE ORIENTATION" }, + { ORIENTATION, "ORIENTATION" }, + { ROTATION_VECTOR, "ROTATION VECTOR" }, + { GAME_ROTATION_VECTOR, "GAME ROTATION VECTOR" }, + { GEOMAGNETIC_ROTATION_VECTOR, "GEOMAGNETIC ROTATION VECTOR" }, + { PROXIMITY, "PROXIMITY" }, + { TOF, "TOF" }, + { AMBIENT_LIGHT, "AMBIENT LIGHT" }, + { COLOR_TEMPERATURE, "COLOR TEMPERATURE" }, + { COLOR_RGB, "COLOR RGB" }, + { COLOR_XYZ, "COLOR XYZ" }, + { HALL, "HALL" }, + { GRIP_DETECTOR, "GRIP DETECTOR" }, + { MAGNET_BRACKET, "MAGNET BRACKET" }, + { PRESSURE_DETECTOR, "PRESSURE DETECTOR" }, + { HEART_RATE, "HEART RATE" }, + { WEAR_DETECTION, "WEAR DETECTION" }, +}; + +bool SensorDump::DumpSensorHelp(int32_t fd, const std::vector &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 SensorDump::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 SensorDump::DumpSensorList(int32_t fd, const std::vector &sensors, const std::vector &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, Sensor 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 SensorDump::DumpSensorChannel(int32_t fd, ClientInfo &clientInfo, const std::vector &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, "Sensor channel info:\n"); + std::vector 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 SensorDump::DumpOpeningSensor(int32_t fd, const std::vector &sensors, ClientInfo &clientInfo, + const std::vector &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 SensorDump::DumpSensorData(int32_t fd, ClientInfo &clientInfo, const std::vector &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 SensorDump::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 SensorDump::DataSizeBySensorId(uint32_t sensorId) +{ + switch (sensorId) { + case SIXDOF_ATTITUDE: + return POSE_6DOF_DIMENSION; + case ACCELEROMETER_UNCALIBRATED: + case MAGNETIC_FIELD_UNCALIBRATED: + case GYROSCOPE_UNCALIBRATED: + return UNCALIBRATED_DIMENSION; + case GEOMAGNETIC_ROTATION_VECTOR: + case GAME_ROTATION_VECTOR: + case ROTATION_VECTOR: + return VECTOR_DIMENSION; + case SIGNIFICANT_MOTION: + case PEDOMETER_DETECTION: + case PEDOMETER: + case AMBIENT_TEMPERATURE: + case HUMIDITY: + case HEART_RATE: + case DEVICE_ORIENTATION: + case WEAR_DETECTION: + return SOLITARIES_DIMENSION; + default: + return COMMON_DIMENSION; + } +} + +std::string SensorDump::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) { + if (sensorId >= ACCELEROMETER && sensorId <= PEDOMETER) { + buffer.append(std::to_string(sensorData.data[i])); + } else if (sensorId >= AMBIENT_TEMPERATURE && sensorId <= SAR) { + buffer.append(std::to_string(sensorData.data[i])); + } else if (sensorId >= SIXDOF_ATTITUDE && sensorId <= GEOMAGNETIC_ROTATION_VECTOR) { + buffer.append(std::to_string(sensorData.data[i])); + } else if (sensorId >= PROXIMITY && sensorId <= COLOR_XYZ) { + buffer.append(std::to_string(sensorData.data[i])); + } else if (sensorId >= HALL && sensorId <= PRESSURE_DETECTOR) { + buffer.append(std::to_string(sensorData.data[i])); + } else if (sensorId >= HEART_RATE && sensorId <= WEAR_DETECTION) { + buffer.append(std::to_string(sensorData.data[i])); + } + buffer.append(","); + } + buffer.append("\n"); + return buffer; +} +} // namespace Sensors +} // namespace OHOS diff --git a/services/sensor/src/sensor_manager.cpp b/services/sensor/src/sensor_manager.cpp new file mode 100755 index 0000000000000000000000000000000000000000..872653ee657088b9cc426d244ec30fdf587b6a3b --- /dev/null +++ b/services/sensor/src/sensor_manager.cpp @@ -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 "sensor_manager.h" + +#include "sensor.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_SERVICE, "SensorManager" }; +constexpr uint32_t INVALID_SENSOR_ID = -1; +constexpr uint32_t PROXIMITY_SENSOR_ID = 50331904; +constexpr float PROXIMITY_FAR = 5.0; +} // namespace + +void SensorManager::InitSensorMap(std::unordered_map &sensorMap, + sptr dataProcesser, sptr dataCallback) +{ + std::lock_guard sensorLock(sensorMapMutex_); + sensorMap_.insert(sensorMap.begin(), sensorMap.end()); + sensorDataProcesser_ = dataProcesser; + reportDataCallback_ = dataCallback; + HiLog::Debug(LABEL, "%{public}s begin sensorMap_.size : %{public}d", __func__, int32_t { sensorMap_.size() }); + return; +} + +uint32_t SensorManager::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 SensorManager::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; + } + SensorBasicInfo 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 SensorManager::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; + } + SensorBasicInfo 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; +} + +SensorBasicInfo SensorManager::GetSensorInfo(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) +{ + HiLog::Debug(LABEL, "%{public}s begin, sensorId : %{public}u", __func__, sensorId); + SensorBasicInfo sensorInfo; + std::lock_guard 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 SensorManager::SaveSubscriber(uint32_t sensorId, uint32_t pid, int64_t samplingPeriodNs, + int64_t maxReportDelayNs) +{ + SensorBasicInfo 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 SensorManager::StartDataReportThread() +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + if (!dataThread_.joinable()) { + HiLog::Warn(LABEL, "%{public}s dataThread_ started", __func__); + std::thread senocdDataThread(SensorDataProcesser::DataThread, sensorDataProcesser_, reportDataCallback_); + dataThread_ = std::move(senocdDataThread); + } + HiLog::Debug(LABEL, "%{public}s end", __func__); +} + +bool SensorManager::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 SensorManager::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 SensorManager::GetPackageNameFromUid(int32_t uid, std::string &packageName) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); +} +} // namespace Sensors +} // namespace OHOS diff --git a/services/sensor/src/sensor_service.cpp b/services/sensor/src/sensor_service.cpp new file mode 100755 index 0000000000000000000000000000000000000000..a715761c7f0d56447dc20e55e603e111ba5a47e1 --- /dev/null +++ b/services/sensor/src/sensor_service.cpp @@ -0,0 +1,466 @@ +/* + * 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 "sensor_service.h" + +#include +#include +#include + +#include "hisysevent.h" +#include "iservice_registry.h" +#include "permission_util.h" +#include "securec.h" +#include "sensor.h" +#include "sensor_dump.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" +#include "system_ability_definition.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_SERVICE, "SensorService" }; +constexpr uint32_t INVALID_SENSOR_ID = -1; +constexpr int32_t MAX_DMUP_PARAM = 2; +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(SensorService, SENSOR_SERVICE_ABILITY_ID, true); + +SensorService::SensorService(int32_t systemAbilityId, bool runOnCreate) + : SystemAbility(systemAbilityId, runOnCreate), state_(SensorServiceState::STATE_STOPPED) +{} + +void SensorService::OnDump() +{ + HiLog::Info(LABEL, "OnDump"); +} + +void SensorService::OnStart() +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + if (state_ == SensorServiceState::STATE_RUNNING) { + HiLog::Warn(LABEL, "%{public}s SensorService has already started", __func__); + return; + } + if (!InitInterface()) { + HiLog::Error(LABEL, "%{public}s Init interface error", __func__); + return; + } + if (!InitDataCallback()) { + 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) SensorDataProcesser(sensorMap_); + if (sensorDataProcesser_ == nullptr) { + HiLog::Error(LABEL, "%{public}s failed, sensorDataProcesser_ cannot be null", __func__); + return; + } + if (!InitSensorPolicy()) { + HiLog::Error(LABEL, "%{public}s Init sensor policy error", __func__); + } + + bool isPublished = SystemAbility::Publish(this); + if (!isPublished) { + HiLog::Error(LABEL, "%{public}s publish SensorService error", __func__); + return; + } + sensorManager_.InitSensorMap(sensorMap_, sensorDataProcesser_, reportDataCallback_); + + state_ = SensorServiceState::STATE_RUNNING; +} + +bool SensorService::InitInterface() +{ + auto ret = sensorServiceImpl_.InitSensorServiceImpl(); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s InitSensorServiceImpl failed", __func__); + return false; + } + return true; +} + +bool SensorService::InitDataCallback() +{ + reportDataCallback_ = new (std::nothrow) ReportDataCallback(); + if (reportDataCallback_ == nullptr) { + HiLog::Error(LABEL, "%{public}s failed, reportDataCallback_ cannot be null", __func__); + return false; + } + ZReportDataCb cb = &ReportDataCallback::ZReportDataCallback; + auto ret = sensorServiceImpl_.RegisteDataReport(cb, reportDataCallback_); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s RegisterDataReport failed", __func__); + return false; + } + return true; +} + +bool SensorService::InitSensorList() +{ + std::lock_guard sensorLock(sensorsMutex_); + sensors_ = sensorServiceImpl_.GetSensorList(); + { + std::lock_guard sensorMapLock(sensorMapMutex_); + for (const auto &it : sensors_) { + sensorMap_.insert(std::make_pair(it.GetSensorId(), it)); + } + } + return true; +} + +bool SensorService::InitSensorPolicy() +{ + return true; +} + +void SensorService::OnStop() +{ + if (state_ == SensorServiceState::STATE_STOPPED) { + HiLog::Warn(LABEL, "%{public}s already stopped", __func__); + return; + } + state_ = SensorServiceState::STATE_STOPPED; +} + +void SensorService::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, "EnableSensor", HiSysEvent::EventType::FAULT, + "LEVEL", logLevel, "TAG", "DUBAI_TAG_HSENSOR_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, "DisableSensor", HiSysEvent::EventType::FAULT, + "LEVEL", logLevel, "TAG", "DUBAI_TAG_HSENSOR_DISABLE", "MESSAGE", message); + } + + HiLog::Info(LABEL, "%{public}s end, packageName : %{public}s", __func__, packageName.c_str()); +} + +void SensorService::ReportOnChangeData(uint32_t sensorId) +{ + std::lock_guard 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 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 SensorService::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 SensorService::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 serviceLock(serviceLock_); + if (clientInfo_.GetSensorState(sensorId) == SENSOR_ENABLED) { + HiLog::Warn(LABEL, "%{public}s sensor 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__); + 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 SensorService::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 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 (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); +} + +int32_t SensorService::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(state); +} + +ErrCode SensorService::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 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 SensorService::GetSensorList() +{ + std::lock_guard sensorLock(sensorsMutex_); + sensors_ = sensorServiceImpl_.GetSensorList(); + for (const auto &it : sensors_) { + std::lock_guard sensorMapLock(sensorMapMutex_); + sensorMap_.insert(std::make_pair(it.GetSensorId(), it)); + } + return sensors_; +} + +ErrCode SensorService::TransferDataChannel(const sptr &sensorBasicDataChannel, + const sptr &sensorClient) +{ + 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; + } + AppThreadInfo appThreadInfo(pid, uid); + sensorBasicDataChannel->SetSensorStatus(true); + RegisterClientDeathRecipient(sensorClient, pid); + return ERR_OK; +} + +ErrCode SensorService::DestroySensorChannel(sptr sensorClient) +{ + 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 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(sensorClient); + HiLog::Info(LABEL, "%{public}s end", __func__); + return ERR_OK; +} + +void SensorService::ProcessDeathObserver(const wptr &object) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + sptr 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 SensorService::RegisterClientDeathRecipient(sptr sensorClient, int32_t pid) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + sptr client = iface_cast(sensorClient); + clientDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast(this)); + if (clientDeathObserver_ == nullptr) { + HiLog::Error(LABEL, "%{public}s clientDeathObserver_ cannot be null", __func__); + return; + } + client->AsObject()->AddDeathRecipient(clientDeathObserver_); + clientInfo_.SaveClientPid(sensorClient, pid); + HiLog::Info(LABEL, "%{public}s end", __func__); +} + +void SensorService::UnregisterClientDeathRecipient(sptr sensorClient) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + sptr client = iface_cast(sensorClient); + clientDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast(this)); + if (clientDeathObserver_ == nullptr) { + HiLog::Error(LABEL, "%{public}s clientDeathObserver_ cannot be null", __func__); + return; + } + client->AsObject()->RemoveDeathRecipient(clientDeathObserver_); + clientInfo_.DestroyClientPid(sensorClient); + HiLog::Info(LABEL, "%{public}s end", __func__); +} + +int32_t SensorService::Dump(int32_t fd, const std::vector &args) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + SensorDump &sensorDump = SensorDump::GetInstance(); + 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"); + sensorDump.DumpHelp(fd); + return DUMP_PARAM_ERR; + } + bool helpRet = sensorDump.DumpSensorHelp(fd, args); + bool listRet = sensorDump.DumpSensorList(fd, sensors_, args); + bool channelRet = sensorDump.DumpSensorChannel(fd, clientInfo_, args); + bool openRet = sensorDump.DumpOpeningSensor(fd, sensors_, clientInfo_, args); + bool dataRet = sensorDump.DumpSensorData(fd, clientInfo_, args); + bool total = helpRet + listRet + channelRet + openRet + dataRet; + if (!total) { + dprintf(fd, "cmd param is error\n"); + sensorDump.DumpHelp(fd); + return DUMP_PARAM_ERR; + } + HiLog::Info(LABEL, "%{public}s end", __func__); + return ERR_OK; +} +} // namespace Sensors +} // namespace OHOS diff --git a/services/sensor/src/sensor_service_impl.cpp b/services/sensor/src/sensor_service_impl.cpp new file mode 100755 index 0000000000000000000000000000000000000000..87cef45761181cdc53b2a557a8da94be2f1b8d9a --- /dev/null +++ b/services/sensor/src/sensor_service_impl.cpp @@ -0,0 +1,200 @@ +/* + * 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 "sensor_service_impl.h" +#include +#include +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_SERVICE, "SensorServiceImpl" }; +} + +ZReportDataCb SensorServiceImpl::reportDataCb_ = nullptr; +sptr SensorServiceImpl::reportDataCallback_ = nullptr; +std::mutex SensorServiceImpl::dataMutex_; +std::condition_variable SensorServiceImpl::dataCondition_; + +ErrCode SensorServiceImpl::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 SensorServiceImpl::GetSensorList() const +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + 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(); + } + HiLog::Info(LABEL, "GetAllSensors result: %{public}d, count: %{public}d", ret, count); + std::vector 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; + const float power = sensorInfo->power; + const float maxRange = sensorInfo->maxRange; + HiLog::Info(LABEL, " %{public}d, %{public}s, %{public}s, %{public}f", sensorId, sensorName.c_str(), + vendorName.c_str(), power); + Sensor sensor; + sensor.SetSensorId(sensorId); + sensor.SetMaxRange(maxRange); + 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 SensorServiceImpl::EnableSensor(uint32_t sensorId) const +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + 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 SensorServiceImpl::DisableSensor(uint32_t sensorId) const +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + 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 SensorServiceImpl::RunCommand(uint32_t sensorId, int32_t cmd, int32_t params) const +{ + return ERR_OK; +} + +ErrCode SensorServiceImpl::SetSensorConfig(uint32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) const +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + int32_t ret = sensorInterface_->SetBatch(sensorId, samplingPeriodNs, maxReportDelayNs); + if (SENSOR_NOT_SUPPORT == ret) { + HiLog::Debug(LABEL, "%{public}s : The operation is not supported!", __func__); + return SENSOR_NOT_SUPPORT; + } + if (SENSOR_INVALID_PARAM == ret) { + HiLog::Debug(LABEL, "%{public}s : The sensor parameter is invalid", __func__); + return SENSOR_INVALID_PARAM; + } + HiLog::Debug(LABEL, "%{public}s end", __func__); + return ret; +} + +int32_t SensorServiceImpl::SensorDataCallback(const struct SensorEvents *event) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + const int32_t SENSOR_AXISZ = 2; + if ((event == nullptr) || (event->dataLen == 0)) { + HiLog::Error(LABEL, "%{public}s event is NULL", __func__); + return ERR_INVALID_VALUE; + } + + float *data = (float*)event->data; + if (event->sensorId == 0) { + printf("sensor id [%d] data [%f]\n\r", event->sensorId, *(data)); + HiLog::Info(LABEL, "sensor id: %{public}d, data: %{public}f", event->sensorId, *(data)); + if (fabs(*data) > 1e-5) { + } + } else if (event->sensorId == 1) { + printf("sensor id [%d] x-[%f] y-[%f] z-[%f]\n\r", + event->sensorId, (*data), *(data + 1), *(data + SENSOR_AXISZ)); + HiLog::Info(LABEL, "sensor id: %{public}d x-%{public}f y-%{public}f z-%{public}f\n\r", + event->sensorId, (*data), *(data + 1), *(data + SENSOR_AXISZ)); + } + + if (reportDataCb_ == nullptr) { + HiLog::Error(LABEL, "%{public}s reportDataCb_ cannot be null", __func__); + return ERR_INVALID_VALUE; + } + (void)(reportDataCallback_->*reportDataCb_)(reinterpret_cast(event), + reportDataCallback_); + dataCondition_.notify_one(); + return ERR_OK; +} + +ErrCode SensorServiceImpl::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(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 SensorServiceImpl::RegisteDataReport(ZReportDataCb cb, sptr 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(SensorDataCallback); + + reportDataCb_ = cb; + reportDataCallback_ = reportDataCallback; + HiLog::Info(LABEL, "%{public}s end", __func__); + return ERR_OK; +} + +ErrCode SensorServiceImpl::Unregister(void) const +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + int32_t ret = sensorInterface_->Unregister(); + 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 diff --git a/services/sensor/src/sensor_service_stub.cpp b/services/sensor/src/sensor_service_stub.cpp new file mode 100755 index 0000000000000000000000000000000000000000..31e6476df8c06dba66e3256e98f0593e8c95d5d9 --- /dev/null +++ b/services/sensor/src/sensor_service_stub.cpp @@ -0,0 +1,201 @@ +/* + * 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 "sensor_service_stub.h" + +#include +#include +#include +#include + +#include "ipc_skeleton.h" +#include "message_parcel.h" +#include "permission_util.h" +#include "sensor_client_proxy.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_SERVICE, "SensorServiceStub" }; +constexpr uint32_t SENSOR_ACCELEROMETER_ID = 256; +constexpr uint32_t SENSOR_ACCELEROMETER_UNCALIBRATED_ID = 65792; +constexpr uint32_t SENSOR_LINEAR_ACCELERATION_ID = 131328; +constexpr uint32_t SENSOR_GYROSCOPE_ID = 262400; +constexpr uint32_t SENSOR_GYROSCOPE_UNCALIBRATED_ID = 327936; +constexpr uint32_t SENSOR_PEDOMETER_DETECTION_ID = 524544; +constexpr uint32_t SENSOR_PEDOMETER_ID = 590080; +constexpr uint32_t SENSOR_HEART_RATE_ID = 83886336; +const std::string ACCELEROMETER_PERMISSION = "ohos.permission.ACCELEROMETER"; +const std::string GYROSCOPE_PERMISSION = "ohos.permission.GYROSCOPE"; +const std::string ACTIVITY_MOTION_PERMISSION = "ohos.permission.ACTIVITY_MOTION"; +const std::string READ_HEALTH_DATA_PERMISSION = "ohos.permission.READ_HEALTH_DATA"; +} // namespace + +std::unordered_map SensorServiceStub::sensorIdPermissions_ = { + { SENSOR_ACCELEROMETER_ID, ACCELEROMETER_PERMISSION }, + { SENSOR_ACCELEROMETER_UNCALIBRATED_ID, ACCELEROMETER_PERMISSION }, + { SENSOR_LINEAR_ACCELERATION_ID, ACCELEROMETER_PERMISSION }, + { SENSOR_GYROSCOPE_ID, GYROSCOPE_PERMISSION }, + { SENSOR_GYROSCOPE_UNCALIBRATED_ID, GYROSCOPE_PERMISSION }, + { SENSOR_PEDOMETER_DETECTION_ID, ACTIVITY_MOTION_PERMISSION }, + { SENSOR_PEDOMETER_ID, ACTIVITY_MOTION_PERMISSION }, + { SENSOR_HEART_RATE_ID, READ_HEALTH_DATA_PERMISSION } +}; + +SensorServiceStub::SensorServiceStub() +{ + HiLog::Info(LABEL, "%{public}s begin, %{public}p", __func__, this); + baseFuncs_[ENABLE_SENSOR] = &SensorServiceStub::SensorEnableInner; + baseFuncs_[DISABLE_SENSOR] = &SensorServiceStub::SensorDisableInner; + baseFuncs_[GET_SENSOR_STATE] = &SensorServiceStub::GetSensorStateInner; + baseFuncs_[RUN_COMMAND] = &SensorServiceStub::RunCommandInner; + baseFuncs_[GET_SENSOR_LIST] = &SensorServiceStub::GetAllSensorsInner; + baseFuncs_[TRANSFER_DATA_CHANNEL] = &SensorServiceStub::CreateDataChannelInner; + baseFuncs_[DESTROY_SENSOR_CHANNEL] = &SensorServiceStub::DestroyDataChannelInner; +} + +SensorServiceStub::~SensorServiceStub() +{ + HiLog::Info(LABEL, "%{public}s begin, yigou %{public}p", __func__, this); + baseFuncs_.clear(); +} + +int32_t SensorServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + HiLog::Debug(LABEL, "%{public}s begin, cmd : %{public}u", __func__, code); + std::u16string descriptor = SensorServiceStub::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); +} + +bool SensorServiceStub::CheckSensorPermission(uint32_t sensorId) +{ + auto permissionIt = sensorIdPermissions_.find(sensorId); + if (permissionIt == sensorIdPermissions_.end()) { + return true; + } + return true; +} + +ErrCode SensorServiceStub::SensorEnableInner(MessageParcel &data, MessageParcel &reply) +{ + (void)reply; + uint32_t sensorId = data.ReadUint32(); + if (!CheckSensorPermission(sensorId)) { + HiLog::Error(LABEL, "%{public}s permission denied", __func__); + return ERR_PERMISSION_DENIED; + } + return EnableSensor(sensorId, data.ReadInt64(), data.ReadInt64()); +} + +ErrCode SensorServiceStub::SensorDisableInner(MessageParcel &data, MessageParcel &reply) +{ + (void)reply; + uint32_t sensorId = data.ReadUint32(); + if (!CheckSensorPermission(sensorId)) { + HiLog::Error(LABEL, "%{public}s permission denied", __func__); + return ERR_PERMISSION_DENIED; + } + return DisableSensor(sensorId); +} + +ErrCode SensorServiceStub::GetSensorStateInner(MessageParcel &data, MessageParcel &reply) +{ + (void)reply; + uint32_t sensorId = data.ReadUint32(); + if (!CheckSensorPermission(sensorId)) { + HiLog::Error(LABEL, "%{public}s permission denied", __func__); + return ERR_PERMISSION_DENIED; + } + return GetSensorState(sensorId); +} + +ErrCode SensorServiceStub::RunCommandInner(MessageParcel &data, MessageParcel &reply) +{ + (void)reply; + uint32_t sensorId = data.ReadUint32(); + if (!CheckSensorPermission(sensorId)) { + HiLog::Error(LABEL, "%{public}s permission denied", __func__); + return ERR_PERMISSION_DENIED; + } + return RunCommand(sensorId, data.ReadUint32(), data.ReadUint32()); +} + +ErrCode SensorServiceStub::GetAllSensorsInner(MessageParcel &data, MessageParcel &reply) +{ + (void)data; + std::vector 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 SensorServiceStub::CreateDataChannelInner(MessageParcel &data, MessageParcel &reply) +{ + (void)reply; + sptr sensorChannel = new (std::nothrow) SensorBasicDataChannel(); + if (sensorChannel == nullptr) { + HiLog::Error(LABEL, "%{public}s sensorChannel cannot be null", __func__); + return OBJECT_NULL; + } + auto ret = sensorChannel->CreateSensorBasicChannel(data); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s CreateSensorBasicChannel ret : %{public}d", __func__, ret); + return OBJECT_NULL; + } + sptr sensorClient = data.ReadRemoteObject(); + if (sensorClient == nullptr) { + HiLog::Error(LABEL, "%{public}s sensorClient cannot be null", __func__); + return OBJECT_NULL; + } + return TransferDataChannel(sensorChannel, sensorClient); +} + +ErrCode SensorServiceStub::DestroyDataChannelInner(MessageParcel &data, MessageParcel &reply) +{ + sptr sensorClient = data.ReadRemoteObject(); + if (sensorClient == nullptr) { + HiLog::Error(LABEL, "%{public}s sensorClient cannot be null", __func__); + return OBJECT_NULL; + } + return DestroySensorChannel(sensorClient); +} +} // namespace Sensors +} // namespace OHOS diff --git a/services/sensor/src/sensor_suspend_policy.cpp b/services/sensor/src/sensor_suspend_policy.cpp new file mode 100755 index 0000000000000000000000000000000000000000..0553b8d16f441765781dcf78c86b92d127961eb1 --- /dev/null +++ b/services/sensor/src/sensor_suspend_policy.cpp @@ -0,0 +1,184 @@ +/* + * 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 "sensor_suspend_policy.h" + +#include "sensor.h" +#include "sensor_service.h" +#include "sensors_log_domain.h" +#include "system_ability_definition.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_SERVICE, "SensorSuspendPolicy" }; +constexpr uint32_t INVALID_SENSOR_ID = -1; +constexpr int64_t MAX_EVENT_COUNT = 1000; +constexpr int64_t DEFAULT_SAMPLEING_RATE = 200000000; +constexpr int64_t DEFAULT_REPORT_DELAY = 0; +constexpr uint32_t STEP_COUNTER_ID = 524544; +constexpr uint32_t STEP_DETECOTR_ID = 590080; +} // namespace + +SensorSuspendPolicy::~SensorSuspendPolicy() +{} + +bool SensorSuspendPolicy::CheckFreezingSensor(uint32_t sensorId) +{ + return ((sensorId == STEP_COUNTER_ID) || (sensorId == STEP_DETECOTR_ID)); +} + +ErrCode SensorSuspendPolicy::DisableSensor(uint32_t sensorId, int32_t pid) +{ + 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 (sensorManager_.IsOtherClientUsingSensor(sensorId, pid)) { + HiLog::Warn(LABEL, "%{public}s other client is using this sensor now, cannot disable", __func__); + return ERR_OK; + } + if (interface_.DisableSensor(sensorId) != ERR_OK) { + HiLog::Error(LABEL, "%{public}s DisableSensor failed", __func__); + return DISABLE_SENSOR_ERR; + } + return sensorManager_.AfterDisableSensor(sensorId); +} + +void SensorSuspendPolicy::DoSuspend(const std::shared_ptr &info) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + std::lock_guard suspendLock(suspendMutex_); + auto &list = info->GetAppIPCInfoList(); + for (const auto &appInfo : list) { + std::vector sensorIdList = clientInfo_.GetSensorIdByPid(appInfo.pid); + if (sensorIdList.empty()) { + continue; + } + pidSensorIdMap_.emplace(std::make_pair(appInfo.pid, sensorIdList)); + for (auto &sensorId : sensorIdList) { + if (CheckFreezingSensor(sensorId)) { + continue; + } + auto sensorInfo = clientInfo_.GetCurPidSensorInfo(sensorId, appInfo.pid); + sensorIdInfoMap_.emplace(std::make_pair(sensorId, sensorInfo)); + DisableSensor(sensorId, appInfo.pid); + } + } + HiLog::Debug(LABEL, "%{public}s end", __func__); +} + +ErrCode SensorSuspendPolicy::SaveSubscriber(uint32_t sensorId, int64_t samplingPeriodNs, + int64_t maxReportDelayNs, int32_t pid) +{ + auto ret = sensorManager_.SaveSubscriber(sensorId, pid, 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, pid); + return ENABLE_SENSOR_ERR; + } + return ret; +} + +ErrCode SensorSuspendPolicy::EnableSensor(uint32_t sensorId, int32_t pid, 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) || (samplingPeriodNs == 0) || + ((samplingPeriodNs != 0L) && (maxReportDelayNs / samplingPeriodNs > MAX_EVENT_COUNT))) { + HiLog::Error(LABEL, "%{public}s sensorId is 0 or maxReportDelayNs exceed the maximum value", __func__); + return ERR_NO_INIT; + } + if (clientInfo_.GetSensorState(sensorId) == SENSOR_ENABLED) { + HiLog::Warn(LABEL, "%{public}s sensor has been enabled already", __func__); + auto ret = SaveSubscriber(sensorId, samplingPeriodNs, maxReportDelayNs, pid); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s SaveSubscriber failed", __func__); + return ret; + } + uint32_t flag = sensorManager_.GetSensorFlag(sensorId); + ret = flushInfo_.FlushProcess(sensorId, flag, pid, true); + if (ret != ERR_OK) { + HiLog::Warn(LABEL, "%{public}s ret : %{public}d", __func__, ret); + } + return ERR_OK; + } + auto ret = SaveSubscriber(sensorId, samplingPeriodNs, maxReportDelayNs, pid); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s SaveSubscriber failed", __func__); + return ret; + } + ret = interface_.EnableSensor(sensorId); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s EnableSensor failed", __func__); + clientInfo_.RemoveSubscriber(sensorId, pid); + return ENABLE_SENSOR_ERR; + } + return ret; +} + +std::vector SensorSuspendPolicy::GetSensorIdByPid(int32_t pid) +{ + HiLog::Debug(LABEL, "%{public}s pid : %{public}d", __func__, pid); + auto it = pidSensorIdMap_.find(pid); + if (it != pidSensorIdMap_.end()) { + HiLog::Debug(LABEL, "%{public}s pid : %{public}d found", __func__, pid); + return it->second; + } + HiLog::Debug(LABEL, "%{public}s pid : %{public}d not found", __func__, pid); + return {}; +} + +void SensorSuspendPolicy::DoActive(const std::shared_ptr &info) +{ + HiLog::Debug(LABEL, "%{public}s begin", __func__); + int64_t samplePeriod = DEFAULT_SAMPLEING_RATE; + int64_t maxReportDelay = DEFAULT_REPORT_DELAY; + std::vector sensorIdList; + std::lock_guard suspendLock(suspendMutex_); + auto &list = info->GetAppIPCInfoList(); + for (const auto &appInfo : list) { + sensorIdList = GetSensorIdByPid(appInfo.pid); + for (auto &sensorId : sensorIdList) { + if (CheckFreezingSensor(sensorId)) { + continue; + } + auto it = sensorIdInfoMap_.find(sensorId); + if (it != sensorIdInfoMap_.end()) { + samplePeriod = it->second.GetSamplingPeriodNs(); + maxReportDelay = it->second.GetMaxReportDelayNs(); + } + auto ret = EnableSensor(sensorId, appInfo.pid, samplePeriod, maxReportDelay); + if (ret != ERR_OK) { + HiLog::Error(LABEL, "%{public}s sensorId : %{public}u, pid : %{public}d, ret : %{public}d", __func__, + sensorId, appInfo.pid, ret); + } + } + } + pidSensorIdMap_.clear(); + sensorIdInfoMap_.clear(); + HiLog::Debug(LABEL, "%{public}s end", __func__); +} +} // namespace Sensors +} // namespace OHOS diff --git a/services/sensor/test/BUILD.gn b/services/sensor/test/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..080ceab40fb94153921bbd13d5936255108592eb --- /dev/null +++ b/services/sensor/test/BUILD.gn @@ -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" ] + } +} diff --git a/services/sensor/test/unittest/common/BUILD.gn b/services/sensor/test/unittest/common/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..29cc473873c8f2ffcab9746f880d04cb932d899c --- /dev/null +++ b/services/sensor/test/unittest/common/BUILD.gn @@ -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" +module_output_path = "sensors/sensor/services/sensor" + +###########################ClientInfoTest########################### +ohos_unittest("ClientInfoCommonTest") { + module_out_path = module_output_path + + sources = [ "./client_info_test.cpp" ] + + include_dirs = [ + "//utils/native/base/include", + "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/services/sensor/include", + "$SUBSYSTEM_DIR/sensor/interfaces/native/include", + ] + + deps = [ + "$SUBSYSTEM_DIR/sensor/services/sensor:libsensor_service", + "$SUBSYSTEM_DIR/sensor/utils:libsensor_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" ] +} diff --git a/services/sensor/test/unittest/common/client_info_test.cpp b/services/sensor/test/unittest/common/client_info_test.cpp new file mode 100755 index 0000000000000000000000000000000000000000..0ab75e64edc3aa7f000c986187a0591dbda891c9 --- /dev/null +++ b/services/sensor/test/unittest/common/client_info_test.cpp @@ -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 + +#include "client_info.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace testing::ext; +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::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; + SensorBasicInfo 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; + SensorBasicInfo 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; + SensorBasicInfo 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; + SensorBasicInfo 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; + SensorBasicInfo 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; + SensorBasicInfo 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__); + SensorState 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__); + SensorState 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 sensorChannel = new (std::nothrow) SensorBasicDataChannel(); + 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 sensorChannel = new (std::nothrow) SensorBasicDataChannel(); + 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 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 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 sensorChannel = new (std::nothrow) SensorBasicDataChannel(); + 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; + + SensorState 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__); + + SensorState 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 diff --git a/services/sensor/test/unittest/phone/BUILD.gn b/services/sensor/test/unittest/phone/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..7b1f6b25aceaa3d19b79dacc17c92a8354248002 --- /dev/null +++ b/services/sensor/test/unittest/phone/BUILD.gn @@ -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" +module_output_path = "sensors/sensor/services/sensor" + +###########################SensorDataProcesserTest########################### +ohos_unittest("SensorDataProcesserTest") { + module_out_path = module_output_path + + sources = [ "./sensor_data_processer_test.cpp" ] + + include_dirs = [ + "//utils/native/base/include", + "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/services/sensor/include", + "$SUBSYSTEM_DIR/sensor/frameworks/native/sensor/include", + "//drivers/peripheral/sensor/interfaces/include", + "$SUBSYSTEM_DIR/sensor/interfaces/native/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", + ] + + deps = [ + "$SUBSYSTEM_DIR/sensor/frameworks/native/sensor:libsensor_native", + "$SUBSYSTEM_DIR/sensor/services/sensor:libsensor_service", + "$SUBSYSTEM_DIR/sensor/utils:libsensor_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_L2:samgr_proxy", + ] +} + +###########################SensorProxyTest########################### +ohos_unittest("SensorProxyTest") { + module_out_path = module_output_path + + sources = [ "./sensor_proxy_test.cpp" ] + + include_dirs = [ + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/services/sensor/include", + "$SUBSYSTEM_DIR/sensor/frameworks/native/sensor/include", + "$SUBSYSTEM_DIR/sensor/interfaces/native/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", + ] + + deps = [ + "$SUBSYSTEM_DIR/sensor/frameworks/native/sensor:libsensor_native", + "$SUBSYSTEM_DIR/sensor/services/sensor:libsensor_service", + "$SUBSYSTEM_DIR/sensor/utils:libsensor_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_L2:samgr_proxy", + ] +} + +###########################SensorServiceImplTest########################### +ohos_unittest("SensorServiceImplTest") { + module_out_path = module_output_path + + sources = [ "./sensor_service_impl_test.cpp" ] + + include_dirs = [ + "//utils/native/base/include", + "//utils/system/safwk/native/include", + "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/services/sensor/include", + "$SUBSYSTEM_DIR/sensor/frameworks/native/sensor/include", + "//drivers/peripheral/sensor/interfaces/include", + "$SUBSYSTEM_DIR/sensor/interfaces/native/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler/include", + ] + + deps = [ + "$SUBSYSTEM_DIR/sensor/frameworks/native/sensor:libsensor_native", + "$SUBSYSTEM_DIR/sensor/services/sensor:libsensor_service", + "$SUBSYSTEM_DIR/sensor/utils:libsensor_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_L2:samgr_proxy", + ] +} + +###########################end########################### +group("unittest") { + testonly = true + deps = [ + ":SensorDataProcesserTest", + ":SensorProxyTest", + ":SensorServiceImplTest", + ] +} diff --git a/services/sensor/test/unittest/phone/sensor_data_processer_test.cpp b/services/sensor/test/unittest/phone/sensor_data_processer_test.cpp new file mode 100755 index 0000000000000000000000000000000000000000..00aa4d78b15332489a20c56091cfccfe37855cfe --- /dev/null +++ b/services/sensor/test/unittest/phone/sensor_data_processer_test.cpp @@ -0,0 +1,206 @@ +/* + * 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 +#include +#include +#include + +#include "report_data_callback.h" +#include "sensor_data_channel.h" +#include "sensor_service_client.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace testing::ext; +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_TEST, "SensorDataProcesserTest" }; +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(OTHER) << SENSOR_CATAGORY_SHIFT) | + (static_cast(SENSOR_TYPE_FLUSH) << SENSOR_TYPE_SHIFT) | + (static_cast(FIRST_INDEX) << SENSOR_INDEX_SHIFT); +class SensorDataProcesserTest : 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 g_sensorsList; + static sptr g_dataChannel; + static sptr g_dataCallback; + static std::vector g_eventsBuf; + static std::unique_ptr g_serviceClient; + static int32_t g_dataCount; + static bool g_getFlushComplete; +}; + +struct SensorEvent g_event; +int32_t SensorDataProcesserTest::g_dataCount = 0; +bool SensorDataProcesserTest::g_getFlushComplete = false; +std::vector SensorDataProcesserTest::g_sensorsList; +sptr SensorDataProcesserTest::g_dataChannel; +sptr SensorDataProcesserTest::g_dataCallback; +std::vector SensorDataProcesserTest::g_eventsBuf; +std::unique_ptr SensorDataProcesserTest::g_serviceClient; +} // namespace + +void SensorDataProcesserTest::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 SensorDataProcesserTest::SetUpTestCase() +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + g_dataChannel = new (std::nothrow) SensorDataChannel(); + ASSERT_NE(g_dataChannel, nullptr); + g_serviceClient = std::make_unique(); + ASSERT_NE(g_serviceClient, nullptr); + g_dataCallback = new (std::nothrow) ReportDataCallback(); + ASSERT_NE(g_dataCallback, nullptr); + g_sensorsList = 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 SensorDataProcesserTest::TearDownTestCase() +{ + g_dataChannel->DestroySensorDataChannel(); + g_serviceClient->DestroyDataChannel(); +} + +void SensorDataProcesserTest::SetUp() +{} + +void SensorDataProcesserTest::TearDown() +{} + +/* + * @tc.name: EnableSensor_001 + * @tc.desc: enable sensor + * @tc.type: FUNC + */ +HWTEST_F(SensorDataProcesserTest, 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 sensorId = ACC_SENSOR_ID; + auto ret = g_serviceClient->EnableSensor(sensorId, 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 sensor data + * @tc.type: FUNC + */ +HWTEST_F(SensorDataProcesserTest, 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(SensorDataProcesserTest, 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 sensor + * @tc.type: FUNC + */ +HWTEST_F(SensorDataProcesserTest, 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 sensor + * @tc.type: FUNC + */ +HWTEST_F(SensorDataProcesserTest, 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: DisableStepDetector_001 + * @tc.desc: disable step detector sensor + * @tc.type: FUNC + */ +HWTEST_F(SensorDataProcesserTest, 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 diff --git a/services/sensor/test/unittest/phone/sensor_proxy_test.cpp b/services/sensor/test/unittest/phone/sensor_proxy_test.cpp new file mode 100755 index 0000000000000000000000000000000000000000..22ce909005601b54e52878b73ea3b902b376d0ac --- /dev/null +++ b/services/sensor/test/unittest/phone/sensor_proxy_test.cpp @@ -0,0 +1,261 @@ +/* + * 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 +#include +#include +#include + +#include + +#include +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "sensor_data_event.h" +#include "sensor_service_proxy.h" +#include "sensors_errors.h" +#include "sensors_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, SensorsLogDomain::SENSOR_TEST, "SensorProxyTest" }; +const uint32_t INVALID_SENSOR_ID = -1; +const std::string CMD_LINE = "ps -ef | grep 'hardware.sensors' | grep -v grep | awk '{print $2}'"; +constexpr int32_t BUFFER_SIZE = 8; +constexpr pid_t INVALID_PID = -1; + +class SensorProxyTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + pid_t GetSensorServicePid(); + sptr sensorProxy_; + std::vector sensors_; + uint32_t sensorId_; +}; +} // namespace + +void SensorProxyTest::SetUpTestCase() +{} + +void SensorProxyTest::TearDownTestCase() +{} + +void SensorProxyTest::SetUp() +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + ASSERT_NE(systemAbilityManager, nullptr); + sensorProxy_ = iface_cast(systemAbilityManager->GetSystemAbility(SENSOR_SERVICE_ABILITY_ID)); + ASSERT_NE(sensorProxy_, nullptr); + sensors_ = sensorProxy_->GetSensorList(); + ASSERT_NE(sensors_.size(), 0UL); + sensorId_ = sensors_[0].GetSensorId(); + ASSERT_NE(sensorId_, INVALID_SENSOR_ID); + HiLog::Info(LABEL, "%{public}s end", __func__); +} + +void SensorProxyTest::TearDown() +{} + +pid_t SensorProxyTest::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 sensor 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 sensor + * @tc.type: FUNC + */ +HWTEST_F(SensorProxyTest, EnableSensor_001, TestSize.Level1) +{ + HiLog::Info(LABEL, "EnableSensor begin"); + ASSERT_NE(sensorProxy_, nullptr); + int64_t samplingPeriodNs = 100000000L; + int64_t maxReportDelayNs = 0L; + auto ret = sensorProxy_->EnableSensor(sensorId_, samplingPeriodNs, maxReportDelayNs); + HiLog::Info(LABEL, "EnableSensor ret is : %{public}d", ret); + ASSERT_EQ(ret, ERR_OK); + + samplingPeriodNs = 50000000L; + maxReportDelayNs = 0L; + ret = sensorProxy_->EnableSensor(sensorId_, samplingPeriodNs, maxReportDelayNs); + ASSERT_EQ(ret, ERR_OK); + + samplingPeriodNs = 20000000L; + maxReportDelayNs = 0L; + ret = sensorProxy_->EnableSensor(sensorId_, samplingPeriodNs, maxReportDelayNs); + ASSERT_EQ(ret, ERR_OK); + samplingPeriodNs = 10000000L; + maxReportDelayNs = 0L; + ret = sensorProxy_->EnableSensor(sensorId_, samplingPeriodNs, maxReportDelayNs); + ASSERT_EQ(ret, ERR_OK); + + samplingPeriodNs = 20000000L; + maxReportDelayNs = 0L; + ret = sensorProxy_->EnableSensor(sensorId_, samplingPeriodNs, maxReportDelayNs); + ASSERT_EQ(ret, ERR_OK); +} + +/* + * @tc.name: EnableSensor_002 + * @tc.desc: enable sensor + * @tc.type: FUNC + */ +HWTEST_F(SensorProxyTest, EnableSensor_002, TestSize.Level1) +{ + HiLog::Info(LABEL, "EnableSensor begin"); + ASSERT_NE(sensorProxy_, nullptr); + const int64_t samplingPeriodNs = 50000000; + const int64_t maxReportDelayNs = 0; + auto ret = sensorProxy_->EnableSensor(sensorId_, samplingPeriodNs, maxReportDelayNs); + HiLog::Info(LABEL, "EnableSensor ret is : %{public}d", ret); + ASSERT_EQ(ret, ERR_OK); +} + +/* + * @tc.name: EnableSensor_003 + * @tc.desc: enable sensor + * @tc.type: FUNC + */ +HWTEST_F(SensorProxyTest, EnableSensor_003, TestSize.Level1) +{ + HiLog::Info(LABEL, "EnableSensor begin"); + ASSERT_NE(sensorProxy_, nullptr); + const int64_t samplingPeriodNs = 50000000; + const int64_t maxReportDelayNs = 0; + auto ret = sensorProxy_->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(SensorProxyTest, RunCommand_001, TestSize.Level1) +{ + ASSERT_NE(sensorProxy_, nullptr); + uint32_t cmdType = 0; // flush cmd + uint32_t params = 1; // flush cmd doesn't need this param, just give a value + + auto ret = sensorProxy_->RunCommand(sensorId_, cmdType, params); + HiLog::Info(LABEL, "RunCommand_001 ret is : %{public}d", ret); + // because the SensorProxyTest 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(SensorProxyTest, RunCommand_002, TestSize.Level1) +{ + ASSERT_NE(sensorProxy_, nullptr); + uint32_t cmdType = 4; // unknown cmd + uint32_t params = 1; + auto ret = sensorProxy_->RunCommand(sensorId_, cmdType, params); + ASSERT_NE(ret, ERR_OK); +} + +/* + * @tc.name: RunCommand_003 + * @tc.desc: run command unknown + * @tc.type: FUNC + */ +HWTEST_F(SensorProxyTest, RunCommand_003, TestSize.Level1) +{ + ASSERT_NE(sensorProxy_, nullptr); + uint32_t cmdType = 4; // unknown cmd + uint32_t params = 1; + auto ret = sensorProxy_->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(SensorProxyTest, RunCommand_004, TestSize.Level1) +{ + ASSERT_NE(sensorProxy_, nullptr); + uint32_t cmdType = 0; // flush cmd + uint32_t params = 1; + auto ret = sensorProxy_->RunCommand(INVALID_SENSOR_ID, cmdType, params); + ASSERT_NE(ret, ERR_OK); +} + +/* + * @tc.name: DisableSensor_001 + * @tc.desc: disable sensor + * @tc.type: FUNC + */ +HWTEST_F(SensorProxyTest, DisableSensor_001, TestSize.Level1) +{ + ASSERT_NE(sensorProxy_, nullptr); + auto ret = sensorProxy_->DisableSensor(sensorId_); + HiLog::Info(LABEL, "DisableSensor ret is : %{public}d", ret); + ASSERT_EQ(ret, ERR_OK); +} + +/* + * @tc.name: DisableSensor_002 + * @tc.desc: disable sensor + * @tc.type: FUNC + */ +HWTEST_F(SensorProxyTest, DisableSensor_002, TestSize.Level1) +{ + ASSERT_NE(sensorProxy_, nullptr); + auto ret = sensorProxy_->DisableSensor(INVALID_SENSOR_ID); + HiLog::Info(LABEL, "DisableSensor ret is : %{public}d", ret); + ASSERT_NE(ret, ERR_OK); +} +} // namespace Sensors +} // namespace OHOS diff --git a/services/sensor/test/unittest/phone/sensor_service_impl_test.cpp b/services/sensor/test/unittest/phone/sensor_service_impl_test.cpp new file mode 100755 index 0000000000000000000000000000000000000000..64d9c238fc400c5ac40eed14cdccf05ab61bd0f2 --- /dev/null +++ b/services/sensor/test/unittest/phone/sensor_service_impl_test.cpp @@ -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 +#include +#include +#include + +#include "report_data_callback.h" +#include "sensor_agent_type.h" +#include "sensor_data_channel.h" +#include "sensor_if.h" +#include "sensor_service_client.h" +#include "sensor_service_impl.h" +#include "sensors_errors.h" +#include "sensors_log_domain.h" + +namespace OHOS { +namespace Sensors { +using namespace testing::ext; +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SensorsLogDomain::SENSOR_TEST, "SensorServiceImplTest" }; +} // namespace + +class SensorServiceImplTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + SensorServiceImpl &sensorServiceImpl_ = SensorServiceImpl::GetInstance(); +}; + +void SensorServiceImplTest::SetUpTestCase() +{} + +void SensorServiceImplTest::TearDownTestCase() +{} + +void SensorServiceImplTest::SetUp() +{} + +void SensorServiceImplTest::TearDown() +{} + +/* + * @tc.name: RegisteDataReport_001 + * @tc.desc: register data report. + * @tc.type: FUNC + * @tc.require: SR000F5A2Q AR000F8QO2 + * @tc.author: wuzhihui + */ +HWTEST_F(SensorServiceImplTest, RegisteDataReport_001, TestSize.Level1) +{ + HiLog::Info(LABEL, "%{public}s begin", __func__); + // 获取sensor列表 + sensorServiceImpl_.InitSensorServiceImpl(); + std::vector list = sensorServiceImpl_.GetSensorList(); + for (size_t i=0; i reportDataCallback_; + reportDataCallback_ = new (std::nothrow) ReportDataCallback(); + ASSERT_NE(reportDataCallback_, nullptr); + cb = &ReportDataCallback::ZReportDataCallback; + ret = sensorServiceImpl_.RegisteDataReport(cb, reportDataCallback_); + ASSERT_EQ(ret, 0); + + // 激活 + ret = sensorServiceImpl_.EnableSensor(sensorId); + EXPECT_EQ(0, ret); + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + + HiLog::Info(LABEL, "%{public}s begin", "--->Unregister1111"); + // 去注册 + ret = sensorServiceImpl_.Unregister(); + ASSERT_EQ(ret, 0); + HiLog::Info(LABEL, "%{public}s begin", "--->Unregister222"); + + // 去激活 + ret = sensorServiceImpl_.DisableSensor(sensorId); + ASSERT_EQ(ret, 0); + HiLog::Info(LABEL, "%{public}s end", __func__); +} +} // namespace Sensors +} // namespace OHOS