diff --git a/frameworks/native/sensor/BUILD.gn b/frameworks/native/sensor/BUILD.gn index 9f9c6c3f30563805223a86e625fbc60b0b62ed08..551a5c3b5c0348765eb5fb7da6bb159c1a5baf38 100755 --- a/frameworks/native/sensor/BUILD.gn +++ b/frameworks/native/sensor/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Huawei Device Co., Ltd. +# Copyright (c) 2021-2023 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 @@ -18,6 +18,7 @@ SUBSYSTEM_DIR = "//base/sensors" ############################################## ohos_shared_library("libsensor_native") { sources = [ + "src/fd_listener.cpp", "src/sensor_agent_proxy.cpp", "src/sensor_client_stub.cpp", "src/sensor_data_channel.cpp", @@ -31,10 +32,14 @@ ohos_shared_library("libsensor_native") { "include", "//commonlibrary/c_utils/base/include", "//utils/system/safwk/native/include", - "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/utils/common/include", + "$SUBSYSTEM_DIR/sensor/utils/ipc/include", "$SUBSYSTEM_DIR/sensor/interfaces/native/include", ] - deps = [ "$SUBSYSTEM_DIR/sensor/utils:libsensor_utils" ] + deps = [ + "$SUBSYSTEM_DIR/sensor/utils/common:libsensor_utils", + "$SUBSYSTEM_DIR/sensor/utils/ipc:libsensor_ipc", + ] external_deps = [ "c_utils:utils", diff --git a/frameworks/native/sensor/include/fd_listener.h b/frameworks/native/sensor/include/fd_listener.h new file mode 100644 index 0000000000000000000000000000000000000000..76b45777ed25f6d0beb728499bc6504652edb960 --- /dev/null +++ b/frameworks/native/sensor/include/fd_listener.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 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 FD_LISTENER_H +#define FD_LISTENER_H + +#include "file_descriptor_listener.h" + +#include "sensor_data_channel.h" + +namespace OHOS { +namespace Sensors { +class FdListener : public AppExecFwk::FileDescriptorListener { +public: + FdListener() = default; + ~FdListener() override = default; + void OnReadable(int32_t fd) override; + void OnShutdown(int32_t fd) override; + void OnException(int32_t fd) override; + void SetChannel(SensorDataChannel *channel); + DISALLOW_COPY_AND_MOVE(FdListener); + +private: + SensorDataChannel *channel_ = nullptr; +}; +} // namespace Sensors +} // namespace OHOS +#endif // FD_LISTENER_H diff --git a/frameworks/native/sensor/include/i_sensor_service.h b/frameworks/native/sensor/include/i_sensor_service.h index dab25cb40366ea6aa2068974715969ec12757660..d8ca66e7cb8fff71b54cc1bca5aa826ef71266b2 100755 --- a/frameworks/native/sensor/include/i_sensor_service.h +++ b/frameworks/native/sensor/include/i_sensor_service.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -21,6 +21,7 @@ #include "errors.h" #include "iremote_broker.h" +#include "active_info.h" #include "i_sensor_client.h" #include "sensor_basic_data_channel.h" #include "sensor.h" @@ -39,6 +40,13 @@ public: virtual ErrCode TransferDataChannel(const sptr &sensorBasicDataChannel, const sptr &sensorClient) = 0; virtual ErrCode DestroySensorChannel(sptr sensorClient) = 0; + virtual ErrCode SuspendSensors(int32_t pid) = 0; + virtual ErrCode ResumeSensors(int32_t pid) = 0; + virtual ErrCode GetActiveInfoList(int32_t pid, std::vector &activeInfoList) = 0; + virtual ErrCode CreateSocketChannel(int32_t &clientFd, const sptr &sensorClient) = 0; + virtual ErrCode DestroySocketChannel(const sptr &sensorClient) = 0; + virtual ErrCode EnableActiveInfoCB() = 0; + virtual ErrCode DisableActiveInfoCB() = 0; enum { ENABLE_SENSOR = 0, DISABLE_SENSOR, @@ -47,6 +55,13 @@ public: GET_SENSOR_LIST, TRANSFER_DATA_CHANNEL, DESTROY_SENSOR_CHANNEL, + SUSPEND_SENSORS, + RESUME_SENSORS, + GET_ACTIVE_INFO_LIST, + CREATE_SOCKET_CHANNEL, + DESTROY_SOCKET_CHANNEL, + ENABLE_ACTIVE_INFO_CB, + DISABLE_ACTIVE_INFO_CB, }; }; } // namespace Sensors diff --git a/frameworks/native/sensor/include/sensor_agent_proxy.h b/frameworks/native/sensor/include/sensor_agent_proxy.h index a14ea60d025a305583ed80e6abbfe291b4e07a40..4e36e6ebdbe6878efb6b766c7d1c52cd9206fda6 100644 --- a/frameworks/native/sensor/include/sensor_agent_proxy.h +++ b/frameworks/native/sensor/include/sensor_agent_proxy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -43,6 +43,11 @@ public: int32_t SetMode(int32_t sensorId, const SensorUser *user, int32_t mode) const; int32_t SetOption(int32_t sensorId, const SensorUser *user, int32_t option) const; int32_t GetAllSensors(SensorInfo **sensorInfo, int32_t *count) const; + int32_t SuspendSensors(int32_t pid) const; + int32_t ResumeSensors(int32_t pid) const; + int32_t GetSensorActiveInfos(int32_t pid, SensorActiveInfo **sensorActiveInfos, int32_t *count) const; + int32_t RegisterSensorActiveInfoCB(SensorActiveInfoCB callback) const; + int32_t UnregisterSensorActiveInfoCB(SensorActiveInfoCB callback) const; private: int32_t CreateSensorDataChannel() const; diff --git a/frameworks/native/sensor/include/sensor_data_channel.h b/frameworks/native/sensor/include/sensor_data_channel.h index ecf87bac672e816fa1cf0d4d350a88a7f9817c2d..f6ef699c5a61f12ea7d2ea469e71e8e5f66ec573 100644 --- a/frameworks/native/sensor/include/sensor_data_channel.h +++ b/frameworks/native/sensor/include/sensor_data_channel.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -18,6 +18,8 @@ #include #include +#include +#include #include "sensor_agent_type.h" #include "sensor_event_handler.h" @@ -28,6 +30,8 @@ namespace Sensors { typedef void (*DataChannelCB)(SensorEvent *events, int32_t num, void *data); class SensorDataChannel : public SensorBasicDataChannel { public: + using ReceiveMessageFun = std::function; + using DisconnectFun = std::function; SensorDataChannel() = default; ~SensorDataChannel(); static int32_t HandleEvent(int32_t fd, int32_t events, void *data); @@ -39,14 +43,19 @@ public: int32_t test = 10; DataChannelCB dataCB_ = nullptr; void *privateData_ = nullptr; + int32_t AddFdListener(int32_t fd, ReceiveMessageFun receiveMessage, DisconnectFun disconnect); + int32_t DelFdListener(int32_t fd); + ReceiveMessageFun receiveMessage_; + DisconnectFun disconnect_; private: static void ThreadProcessTask(SensorDataChannel *sensorChannel); int32_t InnerSensorDataChannel(); std::mutex eventRunnerMutex_; - static std::shared_ptr eventHandler_; + std::shared_ptr eventHandler_; static std::shared_ptr eventRunner_; static int32_t receiveFd_; + std::unordered_set listenedFdSet_; }; } // namespace Sensors } // namespace OHOS diff --git a/frameworks/native/sensor/include/sensor_service_client.h b/frameworks/native/sensor/include/sensor_service_client.h index ce45bad04dff32dcdd559d2f02cf4d3f34e490e8..944a8cbcca6ad90d821a82dfc29e5a634a919145 100755 --- a/frameworks/native/sensor/include/sensor_service_client.h +++ b/frameworks/native/sensor/include/sensor_service_client.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -17,11 +17,13 @@ #define SENSOR_SERVICE_CLIENT_H #include +#include #include #include "iservice_registry.h" #include "singleton.h" +#include "active_info.h" #include "sensor_agent_type.h" #include "sensor_basic_data_channel.h" #include "sensor_basic_info.h" @@ -29,12 +31,13 @@ #include "sensor_data_channel.h" #include "sensor.h" #include "sensor_service_proxy.h" - +#include "stream_socket.h" namespace OHOS { namespace Sensors { -class SensorServiceClient : public Singleton { +class SensorServiceClient : public StreamSocket, public Singleton { public: + ~SensorServiceClient(); std::vector GetSensorList(); int32_t EnableSensor(int32_t sensorId, int64_t samplingPeriod, int64_t maxReportDelay); int32_t DisableSensor(int32_t sensorId); @@ -42,6 +45,13 @@ public: int32_t DestroyDataChannel(); void ProcessDeathObserver(const wptr &object); bool IsValid(int32_t sensorId); + int32_t SuspendSensors(int32_t pid); + int32_t ResumeSensors(int32_t pid); + int32_t GetActiveInfoList(int32_t pid, std::vector &activeInfoList); + int32_t RegisterSensorActiveInfoCB(SensorActiveInfoCB callback, sptr sensorDataChannel); + int32_t UnregisterSensorActiveInfoCB(SensorActiveInfoCB callback); + void ReceiveMessage(const char *buf, size_t size); + void Disconnect(); private: int32_t InitServiceClient(); @@ -55,8 +65,14 @@ private: sptr sensorClientStub_; std::mutex mapMutex_; std::map sensorInfoMap_; + + int32_t CreateSocketChannel(); + void HandleNetPacke(NetPacket &pkt); + std::atomic_bool isConnected_ = false; + CircleStreamBuffer circBuf_; + std::mutex activeInfoCBMutex_; + std::set activeInfoCBSet_; }; } // namespace Sensors } // namespace OHOS - #endif // SENSOR_SERVICE_CLIENT_H diff --git a/frameworks/native/sensor/include/sensor_service_proxy.h b/frameworks/native/sensor/include/sensor_service_proxy.h index 01bfde3eadfbf5e818a10c2a0fcec2ebe8c2ceff..59f5a37578e7a3df7d447d0ad0e029e7a92e3280 100755 --- a/frameworks/native/sensor/include/sensor_service_proxy.h +++ b/frameworks/native/sensor/include/sensor_service_proxy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -35,6 +35,13 @@ public: ErrCode TransferDataChannel(const sptr &sensorBasicDataChannel, const sptr &sensorClient) override; ErrCode DestroySensorChannel(sptr sensorClient) override; + ErrCode SuspendSensors(int32_t pid) override; + ErrCode ResumeSensors(int32_t pid) override; + ErrCode GetActiveInfoList(int32_t pid, std::vector &activeInfoList) override; + ErrCode CreateSocketChannel(int32_t &clientFd, const sptr &sensorClient) override; + ErrCode DestroySocketChannel(const sptr &sensorClient) override; + ErrCode EnableActiveInfoCB() override; + ErrCode DisableActiveInfoCB() override; private: DISALLOW_COPY_AND_MOVE(SensorServiceProxy); diff --git a/frameworks/native/sensor/src/fd_listener.cpp b/frameworks/native/sensor/src/fd_listener.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4fcd303aac346ee1e443520df920aed99b2e7318 --- /dev/null +++ b/frameworks/native/sensor/src/fd_listener.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2023 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 "fd_listener.h" + +#include + +#include "sensors_errors.h" +#include "stream_socket.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::AppExecFwk; +namespace { +constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "FdListener" }; +} + +void FdListener::SetChannel(SensorDataChannel *channel) +{ + channel_ = channel; +} + +void FdListener::OnReadable(int32_t fd) +{ + if (fd < 0) { + SEN_HILOGE("Invalid fd"); + return; + } + char szBuf[MAX_PACKET_BUF_SIZE] = {}; + for (size_t i = 0; i < MAX_RECV_LIMIT; i++) { + ssize_t size = recv(fd, szBuf, MAX_PACKET_BUF_SIZE, MSG_DONTWAIT | MSG_NOSIGNAL); + if (size > 0) { + channel_->receiveMessage_(szBuf, size); + } else if (size < 0) { + if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) { + SEN_HILOGW("Continue for errno EAGAIN|EINTR|EWOULDBLOCK, size:%{public}zu, errno:%{public}d", + size, errno); + continue; + } + SEN_HILOGE("Recv return %{public}zu, errno:%{public}d", size, errno); + break; + } else { + SEN_HILOGD("The service side disconnect with the client. size:0, count:%{public}zu, errno:%{public}d", + i, errno); + break; + } + if (size < MAX_PACKET_BUF_SIZE) { + break; + } + } +} + +void FdListener::OnShutdown(int32_t fd) +{ + if (fd < 0) { + SEN_HILOGE("Invalid fd"); + } + channel_->disconnect_(); +} + +void FdListener::OnException(int32_t fd) +{ + if (fd < 0) { + SEN_HILOGE("Invalid fd"); + } + channel_->disconnect_(); +} +} // namespace Sensors +} // namespace OHOS diff --git a/frameworks/native/sensor/src/sensor_agent_proxy.cpp b/frameworks/native/sensor/src/sensor_agent_proxy.cpp index 21c4671577bdce7b748f5c046c2fa7520d1340bf..f8f72c7c25cc2fa031f408e8e18393dcfd36a0c6 100644 --- a/frameworks/native/sensor/src/sensor_agent_proxy.cpp +++ b/frameworks/native/sensor/src/sensor_agent_proxy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -38,6 +38,8 @@ std::recursive_mutex SensorAgentProxy::subscribeMutex_; std::mutex SensorAgentProxy::chanelMutex_; std::mutex sensorInfoMutex_; SensorInfo *sensorInfos_ = nullptr; +std::mutex sensorActiveInfoMutex_; +SensorActiveInfo *sensorActiveInfos_ = nullptr; int32_t sensorInfoCount_ = 0; std::map SensorAgentProxy::g_subscribeMap; std::map SensorAgentProxy::g_unsubscribeMap; @@ -266,6 +268,10 @@ int32_t SensorAgentProxy::SetMode(int32_t sensorId, const SensorUser *user, int3 void SensorAgentProxy::ClearSensorInfos() const { + if (sensorActiveInfos_ != nullptr) { + free(sensorActiveInfos_); + sensorActiveInfos_ = nullptr; + } CHKPV(sensorInfos_); free(sensorInfos_); sensorInfos_ = nullptr; @@ -330,5 +336,97 @@ int32_t SensorAgentProxy::GetAllSensors(SensorInfo **sensorInfo, int32_t *count) *count = sensorInfoCount_; return SUCCESS; } + +int32_t SensorAgentProxy::SuspendSensors(int32_t pid) const +{ + CALL_LOG_ENTER; + if (pid < 0) { + SEN_HILOGE("Pid is invalid"); + return PARAMETER_ERROR; + } + int32_t ret = SenClient.SuspendSensors(pid); + if (ret != ERR_OK) { + SEN_HILOGE("Suspend sensors failed, ret:%{public}d", ret); + } + return ret; +} + +int32_t SensorAgentProxy::ResumeSensors(int32_t pid) const +{ + CALL_LOG_ENTER; + if (pid < 0) { + SEN_HILOGE("Pid is invalid"); + return PARAMETER_ERROR; + } + int32_t ret = SenClient.ResumeSensors(pid); + if (ret != ERR_OK) { + SEN_HILOGE("Resume sensors failed, ret:%{public}d", ret); + } + return ret; +} + +int32_t SensorAgentProxy::GetSensorActiveInfos(int32_t pid, SensorActiveInfo **sensorActiveInfos, int32_t *count) const +{ + CALL_LOG_ENTER; + if (pid < 0) { + SEN_HILOGE("Pid is invalid"); + return PARAMETER_ERROR; + } + CHKPR(sensorActiveInfos, OHOS::Sensors::ERROR); + CHKPR(count, OHOS::Sensors::ERROR); + std::lock_guard sensorActiveInfoLock(sensorActiveInfoMutex_); + if (sensorActiveInfos_ != nullptr) { + free(sensorActiveInfos_); + sensorActiveInfos_ = nullptr; + } + std::vector activeInfoList; + int32_t ret = SenClient.GetActiveInfoList(pid, activeInfoList); + if (ret != ERR_OK) { + SEN_HILOGE("Get active info list failed, ret:%{public}d", ret); + return ret; + } + if (activeInfoList.empty()) { + SEN_HILOGD("Active info list is empty"); + return ERR_OK; + } + size_t activeInfoCount = activeInfoList.size(); + if (activeInfoCount > MAX_SENSOR_LIST_SIZE) { + SEN_HILOGE("The number of active info exceeds the maximum value, count:%{public}zu", activeInfoCount); + return ERROR; + } + sensorActiveInfos_ = (SensorActiveInfo *)malloc(sizeof(SensorActiveInfo) * activeInfoCount); + CHKPR(sensorActiveInfos_, ERROR); + for (size_t i = 0; i < activeInfoCount; ++i) { + SensorActiveInfo *curActiveInfo= sensorActiveInfos_ + i; + curActiveInfo->pid = activeInfoList[i].GetPid(); + curActiveInfo->sensorId = activeInfoList[i].GetSensorId(); + curActiveInfo->samplingPeriodNs = activeInfoList[i].GetSamplingPeriodNs(); + curActiveInfo->maxReportDelayNs = activeInfoList[i].GetMaxReportDelayNs(); + } + *sensorActiveInfos = sensorActiveInfos_; + *count = static_cast(activeInfoCount); + return ERR_OK; +} + +int32_t SensorAgentProxy::RegisterSensorActiveInfoCB(SensorActiveInfoCB callback) const +{ + CHKPR(callback, OHOS::Sensors::ERROR); + CHKPR(dataChannel_, INVALID_POINTER); + int32_t ret = SenClient.RegisterSensorActiveInfoCB(callback, dataChannel_); + if (ret != ERR_OK) { + SEN_HILOGE("Register sensor active info callback failed, ret:%{public}d", ret); + } + return ret; +} + +int32_t SensorAgentProxy::UnregisterSensorActiveInfoCB(SensorActiveInfoCB callback) const +{ + CHKPR(callback, OHOS::Sensors::ERROR); + int32_t ret = SenClient.UnregisterSensorActiveInfoCB(callback); + if (ret != ERR_OK) { + SEN_HILOGE("Unregister sensor active info callback failed, ret:%{public}d", ret); + } + return ret; +} } // namespace Sensors } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/sensor/src/sensor_data_channel.cpp b/frameworks/native/sensor/src/sensor_data_channel.cpp index 501a6d0e0b9fcb558548b99623f3824ff5cc23db..7dd29d6d56eec8c3ce54f07ca8f4f743e37a32cc 100644 --- a/frameworks/native/sensor/src/sensor_data_channel.cpp +++ b/frameworks/native/sensor/src/sensor_data_channel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -16,6 +16,8 @@ #include "sensor_data_channel.h" #include "errors.h" + +#include "fd_listener.h" #include "sensor_file_descriptor_listener.h" #include "sensors_errors.h" @@ -23,8 +25,6 @@ namespace OHOS { namespace Sensors { using namespace OHOS::HiviewDFX; using namespace OHOS::AppExecFwk; -std::shared_ptr SensorDataChannel::eventHandler_; - namespace { constexpr HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "SensorDataChannel" }; } // namespace @@ -58,9 +58,11 @@ int32_t SensorDataChannel::InnerSensorDataChannel() } auto listener = std::make_shared(); listener->SetChannel(this); - auto myRunner = AppExecFwk::EventRunner::Create(true); - CHKPR(myRunner, ERROR); - eventHandler_ = std::make_shared(myRunner); + if (eventHandler_ == nullptr) { + auto myRunner = AppExecFwk::EventRunner::Create(true); + CHKPR(myRunner, ERROR); + eventHandler_ = std::make_shared(myRunner); + } int32_t receiveFd = GetReceiveDataFd(); auto inResult = eventHandler_->AddFileDescriptorListener(receiveFd, AppExecFwk::FILE_DESCRIPTOR_INPUT_EVENT, listener); @@ -68,15 +70,18 @@ int32_t SensorDataChannel::InnerSensorDataChannel() SEN_HILOGE("AddFileDescriptorListener fail"); return ERROR; } + auto pairRet = listenedFdSet_.insert(receiveFd); + if (!pairRet.second) { + SEN_HILOGE("ListenedFdSet insert fd fail"); + return ERROR; + } return ERR_OK; } int32_t SensorDataChannel::DestroySensorDataChannel() { - std::lock_guard eventRunnerLock(eventRunnerMutex_); - CHKPL(eventHandler_); - eventHandler_ = nullptr; - // destroy sensor basic channelx + int32_t receiveFd = GetReceiveDataFd(); + DelFdListener(receiveFd); return DestroySensorBasicChannel(); } @@ -84,5 +89,48 @@ SensorDataChannel::~SensorDataChannel() { DestroySensorDataChannel(); } + +int32_t SensorDataChannel::AddFdListener(int32_t fd, ReceiveMessageFun receiveMessage, DisconnectFun disconnect) +{ + receiveMessage_ = receiveMessage; + disconnect_ = disconnect; + std::lock_guard eventRunnerLock(eventRunnerMutex_); + if (eventHandler_ == nullptr) { + auto myRunner = AppExecFwk::EventRunner::Create(true); + CHKPR(myRunner, ERROR); + eventHandler_ = std::make_shared(myRunner); + } + auto listener = std::make_shared(); + listener->SetChannel(this); + auto errCode = eventHandler_->AddFileDescriptorListener(fd, AppExecFwk::FILE_DESCRIPTOR_INPUT_EVENT, listener); + if (errCode != ERR_OK) { + SEN_HILOGE("Add fd listener failed, errCode:%{public}u", errCode); + return ERROR; + } + auto pairRet = listenedFdSet_.insert(fd); + if (!pairRet.second) { + SEN_HILOGE("ListenedFdSet insert fd fail"); + return ERROR; + } + return ERR_OK; +} + +int32_t SensorDataChannel::DelFdListener(int32_t fd) +{ + std::lock_guard eventRunnerLock(eventRunnerMutex_); + CHKPL(eventHandler_); + eventHandler_->RemoveFileDescriptorListener(fd); + auto it = listenedFdSet_.find(fd); + if (it == listenedFdSet_.end()) { + SEN_HILOGE("ListenedFdSet not find fd"); + return ERROR; + } + listenedFdSet_.erase(it); + if (listenedFdSet_.empty() && eventHandler_ != nullptr) { + eventHandler_ = nullptr; + SEN_HILOGD("Set eventHandler_ nullptr"); + } + return ERR_OK; +} } // namespace Sensors } // namespace OHOS diff --git a/frameworks/native/sensor/src/sensor_service_client.cpp b/frameworks/native/sensor/src/sensor_service_client.cpp index 419f0e14def90aab8098fc6931c3420e3d2bcd50..910032b68c896189a594d1e42b014492feb4812a 100755 --- a/frameworks/native/sensor/src/sensor_service_client.cpp +++ b/frameworks/native/sensor/src/sensor_service_client.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -38,6 +38,11 @@ constexpr int32_t GET_SERVICE_MAX_COUNT = 30; constexpr uint32_t WAIT_MS = 200; } // namespace +SensorServiceClient::~SensorServiceClient() +{ + Disconnect(); +} + int32_t SensorServiceClient::InitServiceClient() { CALL_LOG_ENTER; @@ -182,7 +187,6 @@ void SensorServiceClient::ProcessDeathObserver(const wptr &object dataChannel_->DestroySensorDataChannel(); // STEP2 : Restore data channel dataChannel_->RestoreSensorDataChannel(); - // STEP3 : Clear sensorlist and sensorServer_ sensorList_.clear(); sensorServer_ = nullptr; @@ -200,6 +204,13 @@ void SensorServiceClient::ProcessDeathObserver(const wptr &object for (const auto &it : sensorInfoMap_) { sensorServer_->EnableSensor(it.first, it.second.GetSamplingPeriodNs(), it.second.GetMaxReportDelayNs()); } + + if (!isConnected_) { + SEN_HILOGD("Previous socket channel status is false, not need retry creat socket channel"); + return; + } + Disconnect(); + CreateSocketChannel(); } void SensorServiceClient::UpdateSensorInfoMap(int32_t sensorId, int64_t samplingPeriod, int64_t maxReportDelay) @@ -224,5 +235,186 @@ void SensorServiceClient::DeleteSensorInfoItem(int32_t sensorId) } return; } + +int32_t SensorServiceClient::SuspendSensors(int32_t pid) +{ + CALL_LOG_ENTER; + int32_t ret = InitServiceClient(); + if (ret != ERR_OK) { + SEN_HILOGE("InitServiceClient failed, ret:%{public}d", ret); + return ret; + } + CHKPR(sensorServer_, ERROR); + StartTrace(HITRACE_TAG_SENSORS, "SuspendSensors"); + ret = sensorServer_->SuspendSensors(pid); + FinishTrace(HITRACE_TAG_SENSORS); + return ret; +} + +int32_t SensorServiceClient::ResumeSensors(int32_t pid) +{ + CALL_LOG_ENTER; + int32_t ret = InitServiceClient(); + if (ret != ERR_OK) { + SEN_HILOGE("InitServiceClient failed, ret:%{public}d", ret); + return ret; + } + CHKPR(sensorServer_, ERROR); + StartTrace(HITRACE_TAG_SENSORS, "ResumeSensors"); + ret = sensorServer_->ResumeSensors(pid); + FinishTrace(HITRACE_TAG_SENSORS); + return ret; +} +int32_t SensorServiceClient::GetActiveInfoList(int32_t pid, std::vector &activeInfoList) +{ + CALL_LOG_ENTER; + int32_t ret = InitServiceClient(); + if (ret != ERR_OK) { + SEN_HILOGE("InitServiceClient failed, ret:%{public}d", ret); + return ret; + } + CHKPR(sensorServer_, ERROR); + StartTrace(HITRACE_TAG_SENSORS, "GetActiveInfoList"); + ret = sensorServer_->GetActiveInfoList(pid, activeInfoList); + FinishTrace(HITRACE_TAG_SENSORS); + return ret; +} + +int32_t SensorServiceClient::RegisterSensorActiveInfoCB(SensorActiveInfoCB callback, sptr sensorDataChannel) +{ + CALL_LOG_ENTER; + if (!isConnected_) { + CHKPR(sensorDataChannel, INVALID_POINTER); + dataChannel_ = sensorDataChannel; + int32_t ret = CreateSocketChannel(); + if (ret != ERR_OK) { + SEN_HILOGE("Register sensor active info callback failed, ret:%{public}d", ret); + return ret; + } + } + std::lock_guard activeInfoCBLock(activeInfoCBMutex_); + activeInfoCBSet_.insert(callback); + return ERR_OK; +} + +int32_t SensorServiceClient::UnregisterSensorActiveInfoCB(SensorActiveInfoCB callback) +{ + CALL_LOG_ENTER; + std::lock_guard activeInfoCBLock(activeInfoCBMutex_); + activeInfoCBSet_.erase(callback); + if (!activeInfoCBSet_.empty()) { + return ERR_OK; + } + int32_t ret = InitServiceClient(); + if (ret != ERR_OK) { + SEN_HILOGE("InitServiceClient failed, ret:%{public}d", ret); + return ret; + } + CHKPR(sensorServer_, ERROR); + StartTrace(HITRACE_TAG_SENSORS, "DisableActiveInfoCB"); + ret = sensorServer_->DisableActiveInfoCB(); + FinishTrace(HITRACE_TAG_SENSORS); + if (ret != ERR_OK) { + SEN_HILOGE("Disable active info callback failed, ret:%{public}d", ret); + return ret; + } + Disconnect(); + StartTrace(HITRACE_TAG_SENSORS, "DestroySocketChannel"); + ret = sensorServer_->DestroySocketChannel(sensorClientStub_); + FinishTrace(HITRACE_TAG_SENSORS); + if (ret != ERR_OK) { + SEN_HILOGE("Destroy socket channel failed, ret:%{public}d", ret); + return ret; + } + isConnected_ = false; + return ERR_OK; +} + +void SensorServiceClient::ReceiveMessage(const char *buf, size_t size) +{ + CHKPV(buf); + if (size == 0 || size > MAX_PACKET_BUF_SIZE) { + SEN_HILOGE("Invalid input param size. size:%{public}zu", size); + return; + } + if (!circBuf_.Write(buf, size)) { + SEN_HILOGE("Write data failed. size:%{public}zu", size); + } + OnReadPackets(circBuf_, std::bind(&SensorServiceClient::HandleNetPacke, this, std::placeholders::_1)); +} + +void SensorServiceClient::HandleNetPacke(NetPacket &pkt) +{ + auto id = pkt.GetMsgId(); + if (id != MessageId::ACTIVE_INFO) { + SEN_HILOGE("NetPacke message id is not ACTIVE_INFO"); + return; + } + SensorActiveInfo sensorActiveInfo; + pkt >> sensorActiveInfo.pid >> sensorActiveInfo.sensorId >> sensorActiveInfo.samplingPeriodNs >> + sensorActiveInfo.maxReportDelayNs; + if (pkt.ChkRWError()) { + SEN_HILOGE("Packet read type failed"); + return; + } + std::lock_guard activeInfoCBLock(activeInfoCBMutex_); + for (auto callback : activeInfoCBSet_) { + if (callback != nullptr) { + callback(sensorActiveInfo); + } + } +} + +void SensorServiceClient::Disconnect() +{ + CALL_LOG_ENTER; + if (fd_ < 0) { + return; + } + CHKPV(dataChannel_); + int32_t ret = dataChannel_->DelFdListener(fd_); + if (ret != ERR_OK) { + SEN_HILOGE("Delete fd listener failed, ret:%{public}d", ret); + } + Close(); +} + +int32_t SensorServiceClient::CreateSocketChannel() +{ + CALL_LOG_ENTER; + int32_t ret = InitServiceClient(); + if (ret != ERR_OK) { + SEN_HILOGE("InitServiceClient failed, ret:%{public}d", ret); + return ret; + } + CHKPR(sensorServer_, ERROR); + int32_t clientFd = -1; + StartTrace(HITRACE_TAG_SENSORS, "CreateSocketChannel"); + ret = sensorServer_->CreateSocketChannel(clientFd, sensorClientStub_); + FinishTrace(HITRACE_TAG_SENSORS); + if (!(ret == ERR_OK && clientFd >= 0)) { + Close(); + SEN_HILOGE("Create socket channel failed, ret:%{public}d", ret); + return ret; + } + fd_ = clientFd; + if (dataChannel_->AddFdListener(fd_, + std::bind(&SensorServiceClient::ReceiveMessage, this, std::placeholders::_1, std::placeholders::_2), + std::bind(&SensorServiceClient::Disconnect, this)) != ERR_OK) { + Close(); + SEN_HILOGE("Add fd listener failed"); + return ERROR; + } + StartTrace(HITRACE_TAG_SENSORS, "EnableActiveInfoCB"); + ret = sensorServer_->EnableActiveInfoCB(); + FinishTrace(HITRACE_TAG_SENSORS); + if (ret != ERR_OK) { + SEN_HILOGE("Enable active info callback failed, ret:%{public}d", ret); + Disconnect(); + return ret; + } + isConnected_ = true; + return ERR_OK; +} } // namespace Sensors } // namespace OHOS diff --git a/frameworks/native/sensor/src/sensor_service_proxy.cpp b/frameworks/native/sensor/src/sensor_service_proxy.cpp index 5ed9c4b2f3aeca04e6490e91f7cb97a1c91080ae..0dd3ac7c4c615766a4f1374b12a3aa339f011ecc 100755 --- a/frameworks/native/sensor/src/sensor_service_proxy.cpp +++ b/frameworks/native/sensor/src/sensor_service_proxy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -46,19 +46,19 @@ ErrCode SensorServiceProxy::EnableSensor(int32_t sensorId, int64_t samplingPerio MessageOption option; if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { SEN_HILOGE("write descriptor failed"); - return WRITE_MSG_ERR; + return WRITE_PARCEL_ERR; } if (!data.WriteInt32(sensorId)) { SEN_HILOGE("write sensorId failed"); - return WRITE_MSG_ERR; + return WRITE_PARCEL_ERR; } if (!data.WriteInt64(samplingPeriodNs)) { SEN_HILOGE("write samplingPeriodNs failed"); - return WRITE_MSG_ERR; + return WRITE_PARCEL_ERR; } if (!data.WriteInt64(maxReportDelayNs)) { SEN_HILOGE("write maxReportDelayNs failed"); - return WRITE_MSG_ERR; + return WRITE_PARCEL_ERR; } sptr remote = Remote(); CHKPR(remote, ERROR); @@ -78,11 +78,11 @@ ErrCode SensorServiceProxy::DisableSensor(int32_t sensorId) MessageOption option; if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { SEN_HILOGE("write descriptor failed"); - return WRITE_MSG_ERR; + return WRITE_PARCEL_ERR; } if (!data.WriteInt32(sensorId)) { SEN_HILOGE("write sensorId failed"); - return WRITE_MSG_ERR; + return WRITE_PARCEL_ERR; } sptr remote = Remote(); CHKPR(remote, ERROR); @@ -147,12 +147,12 @@ ErrCode SensorServiceProxy::TransferDataChannel(const sptrSendToBinder(data); if (!data.WriteRemoteObject(sensorClient)) { SEN_HILOGE("sensorClient failed"); - return WRITE_MSG_ERR; + return WRITE_PARCEL_ERR; } sptr remote = Remote(); CHKPR(remote, ERROR); @@ -174,11 +174,11 @@ ErrCode SensorServiceProxy::DestroySensorChannel(sptr sensorClien MessageOption option; if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { SEN_HILOGE("write descriptor failed"); - return WRITE_MSG_ERR; + return WRITE_PARCEL_ERR; } if (!data.WriteRemoteObject(sensorClient)) { SEN_HILOGE("write sensorClient failed"); - return WRITE_MSG_ERR; + return WRITE_PARCEL_ERR; } sptr remote = Remote(); CHKPR(remote, ERROR); @@ -190,5 +190,188 @@ ErrCode SensorServiceProxy::DestroySensorChannel(sptr sensorClien } return static_cast(ret); } + +ErrCode SensorServiceProxy::SuspendSensors(int32_t pid) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + SEN_HILOGE("Write descriptor failed"); + return WRITE_PARCEL_ERR; + } + if (!data.WriteInt32(pid)) { + SEN_HILOGE("Write pid failed"); + return WRITE_PARCEL_ERR; + } + sptr remote = Remote(); + CHKPR(remote, ERROR); + MessageParcel reply; + MessageOption option; + int32_t ret = remote->SendRequest(ISensorService::SUSPEND_SENSORS, data, reply, option); + if (ret != NO_ERROR) { + HiSysEventWrite(HiSysEvent::Domain::SENSOR, "SENSOR_SERVICE_IPC_EXCEPTION", + HiSysEvent::EventType::FAULT, "PKG_NAME", "SuspendSensors", "ERROR_CODE", ret); + SEN_HILOGE("Failed, ret:%{public}d", ret); + } + return static_cast(ret); +} + +ErrCode SensorServiceProxy::ResumeSensors(int32_t pid) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + SEN_HILOGE("Write descriptor failed"); + return WRITE_PARCEL_ERR; + } + if (!data.WriteInt32(pid)) { + SEN_HILOGE("Write pid failed"); + return WRITE_PARCEL_ERR; + } + sptr remote = Remote(); + CHKPR(remote, ERROR); + MessageParcel reply; + MessageOption option; + int32_t ret = remote->SendRequest(ISensorService::RESUME_SENSORS, data, reply, option); + if (ret != NO_ERROR) { + HiSysEventWrite(HiSysEvent::Domain::SENSOR, "SENSOR_SERVICE_IPC_EXCEPTION", + HiSysEvent::EventType::FAULT, "PKG_NAME", "ResumeSensors", "ERROR_CODE", ret); + SEN_HILOGE("Failed, ret:%{public}d", ret); + } + return static_cast(ret); +} + +ErrCode SensorServiceProxy::GetActiveInfoList(int32_t pid, std::vector &activeInfoList) +{ + MessageParcel data; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + SEN_HILOGE("Write descriptor failed"); + return WRITE_PARCEL_ERR; + } + if (!data.WriteInt32(pid)) { + SEN_HILOGE("Write pid failed"); + return WRITE_PARCEL_ERR; + } + sptr remote = Remote(); + CHKPR(remote, ERROR); + MessageParcel reply; + MessageOption option; + int32_t ret = remote->SendRequest(ISensorService::GET_ACTIVE_INFO_LIST, data, reply, option); + if (ret != NO_ERROR) { + HiSysEventWrite(HiSysEvent::Domain::SENSOR, "SENSOR_SERVICE_IPC_EXCEPTION", + HiSysEvent::EventType::FAULT, "PKG_NAME", "GetActiveInfoList", "ERROR_CODE", ret); + SEN_HILOGE("Failed, ret:%{public}d", ret); + return static_cast(ret); + } + int32_t activeInfoCount; + if (!reply.ReadInt32(activeInfoCount)) { + SEN_HILOGE("Parcel read activeInfoCount failed"); + return READ_PARCEL_ERR; + } + ActiveInfo activeInfo; + for (int32_t i = 0; i < activeInfoCount; ++i) { + auto tmpActiveInfo = activeInfo.Unmarshalling(reply); + if (tmpActiveInfo == nullptr) { + SEN_HILOGE("Current activeInfo is nullptr, i:%{public}d", i); + continue; + } + activeInfoList.push_back(*tmpActiveInfo); + } + return static_cast(ret); +} + +ErrCode SensorServiceProxy::CreateSocketChannel(int32_t &clientFd, const sptr &sensorClient) +{ + CHKPR(sensorClient, OBJECT_NULL); + MessageParcel data; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + SEN_HILOGE("Write descriptor failed"); + return WRITE_PARCEL_ERR; + } + if (!data.WriteRemoteObject(sensorClient)) { + SEN_HILOGE("Write sensorClient failed"); + return WRITE_PARCEL_ERR; + } + MessageParcel reply; + MessageOption option; + sptr remote = Remote(); + CHKPR(remote, ERROR); + int32_t ret = remote->SendRequest(ISensorService::CREATE_SOCKET_CHANNEL, data, reply, option); + if (ret != NO_ERROR) { + HiSysEventWrite(HiSysEvent::Domain::SENSOR, "SERVICE_IPC_EXCEPTION", + HiSysEvent::EventType::FAULT, "PKG_NAME", "CreateSocketChannel", "ERROR_CODE", ret); + SEN_HILOGE("failed, ret:%{public}d", ret); + return ERROR; + } + clientFd = reply.ReadFileDescriptor(); + if (clientFd < 0) { + SEN_HILOGE("Read file descriptor failed"); + return ERROR; + } + return static_cast(ret); +} + +ErrCode SensorServiceProxy::DestroySocketChannel(const sptr &sensorClient) +{ + CHKPR(sensorClient, OBJECT_NULL); + MessageParcel data; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + SEN_HILOGE("write descriptor failed"); + return WRITE_PARCEL_ERR; + } + if (!data.WriteRemoteObject(sensorClient)) { + SEN_HILOGE("Write sensorClient failed"); + return WRITE_PARCEL_ERR; + } + sptr remote = Remote(); + CHKPR(remote, ERROR); + MessageParcel reply; + MessageOption option; + int32_t ret = remote->SendRequest(ISensorService::DESTROY_SOCKET_CHANNEL, data, reply, option); + if (ret != NO_ERROR) { + HiSysEventWrite(HiSysEvent::Domain::SENSOR, "SERVICE_IPC_EXCEPTION", + HiSysEvent::EventType::FAULT, "PKG_NAME", "DestroySocketChannel", "ERROR_CODE", ret); + SEN_HILOGE("failed, ret:%{public}d", ret); + } + return static_cast(ret); +} + +ErrCode SensorServiceProxy::EnableActiveInfoCB() +{ + MessageParcel data; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + SEN_HILOGE("write descriptor failed"); + return WRITE_PARCEL_ERR; + } + sptr remote = Remote(); + CHKPR(remote, ERROR); + MessageParcel reply; + MessageOption option; + int32_t ret = remote->SendRequest(ISensorService::ENABLE_ACTIVE_INFO_CB, data, reply, option); + if (ret != NO_ERROR) { + HiSysEventWrite(HiSysEvent::Domain::SENSOR, "SERVICE_IPC_EXCEPTION", + HiSysEvent::EventType::FAULT, "PKG_NAME", "EnableActiveInfoCB", "ERROR_CODE", ret); + SEN_HILOGE("failed, ret:%{public}d", ret); + } + return static_cast(ret); +} + +ErrCode SensorServiceProxy::DisableActiveInfoCB() +{ + MessageParcel data; + if (!data.WriteInterfaceToken(SensorServiceProxy::GetDescriptor())) { + SEN_HILOGE("write descriptor failed"); + return WRITE_PARCEL_ERR; + } + sptr remote = Remote(); + CHKPR(remote, ERROR); + MessageParcel reply; + MessageOption option; + int32_t ret = remote->SendRequest(ISensorService::DISABLE_ACTIVE_INFO_CB, data, reply, option); + if (ret != NO_ERROR) { + HiSysEventWrite(HiSysEvent::Domain::SENSOR, "SERVICE_IPC_EXCEPTION", + HiSysEvent::EventType::FAULT, "PKG_NAME", "DisableActiveInfoCB", "ERROR_CODE", ret); + SEN_HILOGE("failed, ret:%{public}d", ret); + } + return static_cast(ret); +} } // namespace Sensors } // namespace OHOS diff --git a/interfaces/native/BUILD.gn b/interfaces/native/BUILD.gn index 1050549d522b9148360c3a4b4ac6a2f606a5fb52..9e1bece6fcfc741575bed5145d525c32ad55a25b 100644 --- a/interfaces/native/BUILD.gn +++ b/interfaces/native/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Huawei Device Co., Ltd. +# Copyright (c) 2021-2023 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 @@ -27,7 +27,7 @@ config("sensor_private_config") { "//commonlibrary/c_utils/base/include", "//utils/system/safwk/native/include", "$SUBSYSTEM_DIR/frameworks/native/sensor/include", - "$SUBSYSTEM_DIR/utils/include", + "$SUBSYSTEM_DIR/utils/common/include", "$SUBSYSTEM_DIR/interfaces/native/include", "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", "//base/notification/eventhandler/interfaces/inner_api", diff --git a/interfaces/native/include/sensor_agent.h b/interfaces/native/include/sensor_agent.h index ead362c940d06fbf0c0bbac8ae409765c13a1933..50b37f8c48c215af57608e0477570e79b906662c 100755 --- a/interfaces/native/include/sensor_agent.h +++ b/interfaces/native/include/sensor_agent.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -127,6 +127,53 @@ int32_t DeactivateSensor(int32_t sensorTypeId, const SensorUser *user); * @since 5 */ int32_t SetMode(int32_t sensorTypeId, const SensorUser *user, int32_t mode); +/** + * @brief 休眠一个进程订阅的所有传感器 + * + * @param pid 进程号 + * @return 返回0表示成功,否则表示失败 + * + * @since 10 + */ +int32_t SuspendSensors(int32_t pid); +/** + * @brief 唤醒一个进程订阅的所有传感器 + * + * @param pid 进程号 + * @return 返回0表示成功,否则表示失败 + * + * @since 10 + */ +int32_t ResumeSensors(int32_t pid); +/** + * @brief 查询一个进程打开的所有传感器的信息 + * + * @param pid 进程号 + * @param sensorActiveInfos 返回进程打开的所有传感器信息 + * @param count 返回进程打开的传感器数量 + * @return 返回0表示成功,否则表示失败 + * + * @since 10 + */ +int32_t GetSensorActiveInfos(int32_t pid, SensorActiveInfo **sensorActiveInfos, int32_t *count); +/** + * @brief 注册传感器打开信息上报函数 + * + * @param callback 回调函数 + * @return 返回0表示成功,否则表示失败 + * + * @since 10 + */ +int32_t RegisterSensorActiveInfoCB(SensorActiveInfoCB callback); +/** + * @brief 取消注册传感器打开信息上报函数 + * + * @param callback 回调函数 + * @return 返回0表示成功,否则表示失败 + * + * @since 10 + */ +int32_t UnregisterSensorActiveInfoCB(SensorActiveInfoCB callback); #ifdef __cplusplus #if __cplusplus diff --git a/interfaces/native/include/sensor_agent_type.h b/interfaces/native/include/sensor_agent_type.h index 37b0de0e57418519152160a8e4307367945e1d8f..46d948807c55479cafd4a4ff41220f600a8a1057 100644 --- a/interfaces/native/include/sensor_agent_type.h +++ b/interfaces/native/include/sensor_agent_type.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -395,6 +395,15 @@ typedef struct WearDetectionData { float value; } WearDetectionData; +typedef struct SensorActiveInfo { + int32_t pid = -1; /**< PID */ + int32_t sensorId = -1; /**< Sensor ID */ + int64_t samplingPeriodNs = -1; /**< Sample period, in ns */ + int64_t maxReportDelayNs = -1; /**< Maximum Report Delay, in ns */ +} SensorActiveInfo; + +typedef void (*SensorActiveInfoCB)(SensorActiveInfo &sensorActiveInfo); + #ifdef __cplusplus #if __cplusplus } diff --git a/interfaces/native/src/sensor_agent.cpp b/interfaces/native/src/sensor_agent.cpp index ccae1ff7ad4a70a9a3263e0613f6de74f845fc1e..64b055a544f0ce68f2d06e6b4906e257e5fba7e4 100755 --- a/interfaces/native/src/sensor_agent.cpp +++ b/interfaces/native/src/sensor_agent.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -146,4 +146,81 @@ int32_t SetMode(int32_t sensorId, const SensorUser *user, int32_t mode) return SERVICE_EXCEPTION; } return proxy->SetMode(sensorId, user, mode); +} + +int32_t SuspendSensors(int32_t pid) +{ + const SensorAgentProxy *proxy = GetInstance(); + if (proxy == nullptr) { + SEN_HILOGE("Proxy is nullptr"); + return SERVICE_EXCEPTION; + } + int32_t ret = proxy->SuspendSensors(pid); + if (ret != OHOS::ERR_OK) { + SEN_HILOGE("Suspend sensors failed, ret:%{public}d", ret); + return NormalizeErrCode(ret); + } + return ret; +} + +int32_t ResumeSensors(int32_t pid) +{ + const SensorAgentProxy *proxy = GetInstance(); + if (proxy == nullptr) { + SEN_HILOGE("Proxy is nullptr"); + return SERVICE_EXCEPTION; + } + int32_t ret = proxy->ResumeSensors(pid); + if (ret != OHOS::ERR_OK) { + SEN_HILOGE("Resume sensors failed, ret:%{public}d", ret); + return NormalizeErrCode(ret); + } + return ret; +} + +int32_t GetSensorActiveInfos(int32_t pid, SensorActiveInfo **sensorActiveInfos, int32_t *count) +{ + CHKPR(sensorActiveInfos, OHOS::Sensors::ERROR); + CHKPR(count, OHOS::Sensors::ERROR); + const SensorAgentProxy *proxy = GetInstance(); + if (proxy == nullptr) { + SEN_HILOGE("Proxy is nullptr"); + return SERVICE_EXCEPTION; + } + int32_t ret = proxy->GetSensorActiveInfos(pid, sensorActiveInfos, count); + if (ret != OHOS::ERR_OK) { + SEN_HILOGE("Get sensor active infos failed, ret:%{public}d", ret); + return NormalizeErrCode(ret); + } + return ret; +} + +int32_t RegisterSensorActiveInfoCB(SensorActiveInfoCB callback) +{ + const SensorAgentProxy *proxy = GetInstance(); + if (proxy == nullptr) { + SEN_HILOGE("proxy is nullptr"); + return SERVICE_EXCEPTION; + } + int32_t ret = proxy->RegisterSensorActiveInfoCB(callback); + if (ret != OHOS::ERR_OK) { + SEN_HILOGE("Register sensor active Info callback failed, ret:%{public}d", ret); + return NormalizeErrCode(ret); + } + return ret; +} + +int32_t UnregisterSensorActiveInfoCB(SensorActiveInfoCB callback) +{ + const SensorAgentProxy *proxy = GetInstance(); + if (proxy == nullptr) { + SEN_HILOGE("proxy is nullptr"); + return SERVICE_EXCEPTION; + } + int32_t ret = proxy->UnregisterSensorActiveInfoCB(callback); + if (ret != OHOS::ERR_OK) { + SEN_HILOGE("Unregister sensor active info callback failed, ret:%{public}d", ret); + return NormalizeErrCode(ret); + } + return ret; } \ No newline at end of file diff --git a/interfaces/native/test/BUILD.gn b/interfaces/native/test/BUILD.gn index 5a175be21419441dd1c75a3cef2b693b9dfae6c5..ea0d5c97838279bb5c6858f1c6396a131ef182b6 100644 --- a/interfaces/native/test/BUILD.gn +++ b/interfaces/native/test/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Huawei Device Co., Ltd. +# Copyright (c) 2021-2023 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 @@ -27,14 +27,14 @@ ohos_unittest("SensorAgentTest") { include_dirs = [ "//commonlibrary/c_utils/base/include", - "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/utils/common/include", "$SUBSYSTEM_DIR/sensor/interfaces/native/include", "$SUBSYSTEM_DIR/sensor/test/unittest/common/include", ] deps = [ "$SUBSYSTEM_DIR/sensor/interfaces/native:sensor_ndk_target", - "$SUBSYSTEM_DIR/sensor/utils:libsensor_utils", + "$SUBSYSTEM_DIR/sensor/utils/common:libsensor_utils", "//third_party/googletest:gmock_main", "//third_party/googletest:gtest_main", ] @@ -55,14 +55,14 @@ ohos_unittest("SensorAlgorithmTest") { include_dirs = [ "//commonlibrary/c_utils/base/include", - "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/utils/common/include", "$SUBSYSTEM_DIR/sensor/interfaces/native/include", "$SUBSYSTEM_DIR/sensor/test/unittest/common/include", ] deps = [ "$SUBSYSTEM_DIR/sensor/interfaces/native:sensor_ndk_target", - "$SUBSYSTEM_DIR/sensor/utils:libsensor_utils", + "$SUBSYSTEM_DIR/sensor/utils/common:libsensor_utils", "//third_party/googletest:gmock_main", "//third_party/googletest:gtest_main", ] @@ -73,11 +73,43 @@ ohos_unittest("SensorAlgorithmTest") { ] } +ohos_unittest("SensorPowerTest") { + module_out_path = module_output_path + + sources = [ + "$SUBSYSTEM_DIR/sensor/test/unittest/common/src/system_info.cpp", + "unittest/sensor_power_test.cpp", + ] + + include_dirs = [ + "//commonlibrary/c_utils/base/include", + "$SUBSYSTEM_DIR/sensor/utils/common/include", + "$SUBSYSTEM_DIR/sensor/interfaces/native/include", + "$SUBSYSTEM_DIR/sensor/test/unittest/common/include", + ] + + deps = [ + "$SUBSYSTEM_DIR/sensor/interfaces/native:sensor_ndk_target", + "$SUBSYSTEM_DIR/sensor/utils/common:libsensor_utils", + "//third_party/googletest:gmock_main", + "//third_party/googletest:gtest_main", + ] + external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken", + "access_token:libtoken_setproc", + "c_utils:utils", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + ] +} + ###########################end########################### group("unittest") { testonly = true deps = [ ":SensorAgentTest", ":SensorAlgorithmTest", + ":SensorPowerTest", ] } diff --git a/interfaces/native/test/unittest/sensor_power_test.cpp b/interfaces/native/test/unittest/sensor_power_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d7816721db4556cfbe6ed8726340e37803423dad --- /dev/null +++ b/interfaces/native/test/unittest/sensor_power_test.cpp @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2023 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 "accesstoken_kit.h" +#include "nativetoken_kit.h" +#include "token_setproc.h" + +#include "sensor_agent.h" +#include "sensors_errors.h" +#include "system_info.h" + +namespace OHOS { +namespace Sensors { +using namespace testing::ext; +using namespace OHOS::HiviewDFX; +using namespace Security::AccessToken; +using Security::AccessToken::AccessTokenID; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, OHOS::Sensors::SENSOR_LOG_DOMAIN, "SensorPowerTest" }; +constexpr int32_t sensorId { 1 }; +constexpr int32_t invalidValue { -1 }; +} // namespace + +class SensorPowerTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +int32_t process_pid = 0; + +void SensorPowerTest::SetUpTestCase() +{ + const char **perms = new const char *[1]; + perms[0] = "ohos.permission.ACCELEROMETER"; + TokenInfoParams infoInstance = { + .dcapsNum = 0, + .permsNum = 1, + .aclsNum = 0, + .dcaps = nullptr, + .perms = perms, + .acls = nullptr, + .processName = "SensorPowerTest", + .aplStr = "system_core", + }; + uint64_t tokenId = GetAccessTokenId(&infoInstance); + ASSERT_EQ(SetSelfTokenID(tokenId), 0); + AccessTokenKit::ReloadNativeTokenInfo(); + delete[] perms; + + SYSTEM_INFO::CpuInfo cpuInfo; + const std::string process_name = "SensorPowerTest"; + process_pid = cpuInfo.GetTaskPidFile(process_name); + SEN_HILOGI("Current process pid is %{public}d", process_pid); + ASSERT_NE(process_pid, 0); +} + +void SensorPowerTest::TearDownTestCase() {} + +void SensorPowerTest::SetUp() {} + +void SensorPowerTest::TearDown() {} + +void SensorDataCallbackImpl(SensorEvent *event) +{ + if (event == nullptr) { + SEN_HILOGE("SensorEvent is null"); + return; + } + float *sensorData = (float *)event[0].data; + SEN_HILOGI("SensorId:%{public}d, version:%{public}d,dataLen:%{public}d,data:%{public}f", + event[0].sensorTypeId, event[0].version, event[0].dataLen, *(sensorData)); +} + +void SensorActiveInfoCBImpl(SensorActiveInfo &sensorActiveInfo) +{ + SEN_HILOGI("pid:%{public}d, sensorId:%{public}d, samplingPeriodNs:%{public}" PRId64 ", " + "maxReportDelayNs:%{public}" PRId64 "", sensorActiveInfo.pid, sensorActiveInfo.sensorId, + sensorActiveInfo.samplingPeriodNs, sensorActiveInfo.maxReportDelayNs); +} + +void SensorActiveInfoCBImpl2(SensorActiveInfo &sensorActiveInfo) +{ + SEN_HILOGI("pid:%{public}d, sensorId:%{public}d, samplingPeriodNs:%{public}" PRId64 ", " + "maxReportDelayNs:%{public}" PRId64 "", sensorActiveInfo.pid, sensorActiveInfo.sensorId, + sensorActiveInfo.samplingPeriodNs, sensorActiveInfo.maxReportDelayNs); +} + +HWTEST_F(SensorPowerTest, SensorPowerTest_001, TestSize.Level1) +{ + // 休眠接口异常用例 + SEN_HILOGI("SensorPowerTest_001 in"); + int32_t ret = SuspendSensors(invalidValue); + ASSERT_NE(ret, OHOS::Sensors::SUCCESS); +} + +HWTEST_F(SensorPowerTest, SensorPowerTest_002, TestSize.Level1) +{ + // 恢复接口异常用例 + SEN_HILOGI("SensorPowerTest_002 in"); + int32_t ret = ResumeSensors(invalidValue); + ASSERT_NE(ret, OHOS::Sensors::SUCCESS); +} + +HWTEST_F(SensorPowerTest, SensorPowerTest_003, TestSize.Level1) +{ + // 查询接口异常用例 + SEN_HILOGI("SensorPowerTest_003 in"); + SensorActiveInfo *sensorActiveInfos {nullptr}; + int32_t count { 0 }; + int32_t ret = GetSensorActiveInfos(invalidValue, &sensorActiveInfos, &count); + ASSERT_NE(ret, OHOS::Sensors::SUCCESS); +} + +HWTEST_F(SensorPowerTest, SensorPowerTest_004, TestSize.Level1) +{ + // 注册接口异常用例 + SEN_HILOGI("SensorPowerTest_004 in"); + SensorActiveInfoCB callback = nullptr; + int32_t ret = RegisterSensorActiveInfoCB(callback); + ASSERT_NE(ret, OHOS::Sensors::SUCCESS); +} + +HWTEST_F(SensorPowerTest, SensorPowerTest_005, TestSize.Level1) +{ + // 取消注册接口异常用例 + SEN_HILOGI("SensorPowerTest_005 in"); + SensorActiveInfoCB callback = nullptr; + int32_t ret = UnregisterSensorActiveInfoCB(callback); + ASSERT_NE(ret, OHOS::Sensors::SUCCESS); +} + +HWTEST_F(SensorPowerTest, SensorPowerTest_006, TestSize.Level1) +{ + // 场景用例1,订阅并打开ACC传感器》休眠进程的传感器》恢复进程的传感器》关闭并取消订阅ACC传感器 + SEN_HILOGI("SensorPowerTest_006 in"); + SensorUser user; + user.callback = SensorDataCallbackImpl; + + int32_t ret = SubscribeSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = SetBatch(sensorId, &user, 100000000, 0); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = ActivateSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + ret = SuspendSensors(process_pid); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + ret = ResumeSensors(process_pid); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + ret = DeactivateSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = UnsubscribeSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); +} + +HWTEST_F(SensorPowerTest, SensorPowerTest_007, TestSize.Level1) +{ + // 场景用例2,订阅并打开ACC传感器》查询传感器打开数据》休眠进程的传感器》恢复进程的传感器》关闭并取消订阅ACC传感器 + SEN_HILOGI("SensorPowerTest_007 in"); + SensorUser user; + user.callback = SensorDataCallbackImpl; + + int32_t ret = SubscribeSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = SetBatch(sensorId, &user, 100000000, 0); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = ActivateSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + SensorActiveInfo *sensorActiveInfos {nullptr}; + int32_t count { 0 }; + ret = GetSensorActiveInfos(process_pid, &sensorActiveInfos, &count); + for (int32_t i = 0; i < count; ++i) { + SensorActiveInfo *curSensorActiveInfo = sensorActiveInfos + i; + SEN_HILOGI("pid:%{public}d, sensorId:%{public}d, samplingPeriodNs:%{public}" PRId64 ", " + "maxReportDelayNs:%{public}" PRId64 "", curSensorActiveInfo->pid, curSensorActiveInfo->sensorId, + curSensorActiveInfo->samplingPeriodNs, curSensorActiveInfo->maxReportDelayNs); + } + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + + ret = SuspendSensors(process_pid); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + ret = ResumeSensors(process_pid); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + ret = DeactivateSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = UnsubscribeSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); +} + +HWTEST_F(SensorPowerTest, SensorPowerTest_008, TestSize.Level1) +{ + // 场景用例3,注册回调函数》订阅并打开ACC传感器》休眠进程的传感器》恢复进程的传感器》关闭并取消订阅ACC传感器》取消注册回调函数 + SEN_HILOGI("SensorPowerTest_008 in"); + SensorUser user; + user.callback = SensorDataCallbackImpl; + SensorActiveInfoCB callback = SensorActiveInfoCBImpl; + + int32_t ret = RegisterSensorActiveInfoCB(callback); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + + ret = SubscribeSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = SetBatch(sensorId, &user, 100000000, 0); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = ActivateSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + ret = SuspendSensors(process_pid); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + ret = ResumeSensors(process_pid); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + ret = DeactivateSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = UnsubscribeSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + + ret = UnregisterSensorActiveInfoCB(callback); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); +} + +HWTEST_F(SensorPowerTest, SensorPowerTest_009, TestSize.Level1) +{ + // 场景用例4,注册回调函数1》注册回调函数2》订阅ACC传感器》休眠进程的传感器》恢复进程的传感器》取消订阅ACC传感器》取消注册回调函数1》取消注册回调函数2 + SEN_HILOGI("SensorPowerTest_009 in"); + SensorUser user; + user.callback = SensorDataCallbackImpl; + SensorActiveInfoCB callback = SensorActiveInfoCBImpl; + SensorActiveInfoCB callback2 = SensorActiveInfoCBImpl2; + + int32_t ret = RegisterSensorActiveInfoCB(callback); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = RegisterSensorActiveInfoCB(callback2); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + + ret = SubscribeSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = SetBatch(sensorId, &user, 100000000, 0); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = ActivateSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + ret = SuspendSensors(process_pid); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + ret = ResumeSensors(process_pid); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + ret = DeactivateSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = UnsubscribeSensor(sensorId, &user); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + + ret = UnregisterSensorActiveInfoCB(callback); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); + ret = UnregisterSensorActiveInfoCB(callback2); + ASSERT_EQ(ret, OHOS::Sensors::SUCCESS); +} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/plugin/BUILD.gn b/interfaces/plugin/BUILD.gn index d84452593cb927399ef09017acafd3ecc0080477..4c3db194fd74cad3b67d20f73a53347c94258705 100644 --- a/interfaces/plugin/BUILD.gn +++ b/interfaces/plugin/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Huawei Device Co., Ltd. +# Copyright (c) 2021-2023 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 @@ -21,7 +21,7 @@ ohos_shared_library("libsensor") { "//third_party/libuv/include", "//commonlibrary/c_utils/base/include", "./include", - "//base/sensors/sensor/utils/include", + "./../../utils/common/include", "//foundation/arkui/napi/interfaces/inner_api/napi", ] defines = [ diff --git a/services/sensor/BUILD.gn b/services/sensor/BUILD.gn index de3715a3eaa3c506362f44685db6e83781cc344b..63762c03575b22a16a6299f2a2f8661e34821c7d 100644 --- a/services/sensor/BUILD.gn +++ b/services/sensor/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Huawei Device Co., Ltd. +# Copyright (c) 2021-2023 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 @@ -27,8 +27,10 @@ ohos_shared_library("libsensor_service") { "src/sensor_data_processer.cpp", "src/sensor_dump.cpp", "src/sensor_manager.cpp", + "src/sensor_power_policy.cpp", "src/sensor_service.cpp", "src/sensor_service_stub.cpp", + "src/stream_server.cpp", ] include_dirs = [ @@ -37,7 +39,8 @@ ohos_shared_library("libsensor_service") { "$SUBSYSTEM_DIR/sensor/interfaces/native/include", "//commonlibrary/c_utils/base/include", "//utils/system/safwk/native/include", - "$SUBSYSTEM_DIR/sensor/utils/include", + "$SUBSYSTEM_DIR/sensor/utils/common/include", + "$SUBSYSTEM_DIR/sensor/utils/ipc/include", "$SUBSYSTEM_DIR/sensor/services/sensor/include", "//drivers/peripheral/sensor/interfaces/include", "hdi_connection/interface/include", @@ -45,7 +48,10 @@ ohos_shared_library("libsensor_service") { "hdi_connection/hardware/include", ] - deps = [ "$SUBSYSTEM_DIR/sensor/utils:libsensor_utils" ] + deps = [ + "$SUBSYSTEM_DIR/sensor/utils/common:libsensor_utils", + "$SUBSYSTEM_DIR/sensor/utils/ipc:libsensor_ipc", + ] external_deps = [ "access_token:libaccesstoken_sdk", diff --git a/services/sensor/include/client_info.h b/services/sensor/include/client_info.h index 558e8c226b008d3efd69a9ea73ee7cefb2b607a5..61bc61a394b28f6042bbdaa690bf06a1e859f4ed 100644 --- a/services/sensor/include/client_info.h +++ b/services/sensor/include/client_info.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "refbase.h" @@ -74,6 +75,10 @@ public: void ClearDataQueue(int32_t sensorId); int32_t GetUidByPid(int32_t pid); AccessTokenID GetTokenIdByPid(int32_t pid); + int32_t AddActiveInfoCBPid(int32_t pid); + int32_t DelActiveInfoCBPid(int32_t pid); + std::unordered_set GetActiveInfoCBPid(); + bool IsUnregisterClientDeathRecipient(int32_t pid); private: DISALLOW_COPY_AND_MOVE(ClientInfo); @@ -92,6 +97,8 @@ private: std::map, int32_t> clientPidMap_; std::unordered_map>> cmdMap_; std::unordered_map> dumpQueue_; + std::mutex activeInfoCBPidMutex_; + std::unordered_set activeInfoCBPidSet_; }; } // namespace Sensors } // namespace OHOS diff --git a/services/sensor/include/sensor_power_policy.h b/services/sensor/include/sensor_power_policy.h new file mode 100644 index 0000000000000000000000000000000000000000..7433ecee15dd573c8427f04066a0bdc92019bae1 --- /dev/null +++ b/services/sensor/include/sensor_power_policy.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 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_POWER_POLICY_H +#define SENSOR_POWER_POLICY_H + +#include +#include +#include + +#include "nocopyable.h" + +#include "active_info.h" +#include "client_info.h" +#include "sensor_hdi_connection.h" +#include "sensor_manager.h" +#include "sensors_errors.h" +#include "stream_session.h" + +namespace OHOS { +namespace Sensors { +class SensorPowerPolicy : public Singleton{ +public: + ErrCode SuspendSensors(int32_t pid); + ErrCode ResumeSensors(int32_t pid); + void GetActiveInfoList(int32_t pid, std::vector &activeInfoList); + void ReportActiveInfo(ActiveInfo activeInfo, const std::vector &sessionList); + +private: + bool CheckFreezingSensor(int32_t sensorId); + bool Suspend(std::unordered_map &SensorInfoMap, + std::vector &sensorIdList, int32_t pid); + bool Resume(int32_t pid, int32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs); + ErrCode RestoreSensorInfo(int32_t pid, int32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs); + SensorHdiConnection &sensorHdiConnection_ = SensorHdiConnection::GetInstance(); + ClientInfo &clientInfo_ = ClientInfo::GetInstance(); + SensorManager &sensorManager_ = SensorManager::GetInstance(); + std::mutex pidSensorInfoMutex_; + std::unordered_map> pidSensorInfoMap_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // SENSOR_POWER_POLICY_H \ No newline at end of file diff --git a/services/sensor/include/sensor_service.h b/services/sensor/include/sensor_service.h index e77d05ed44b557bd1c9f24b2578120cdbcec7020..5a8dfbf668e5e0931ed0231e544f6ea8dd19ce3d 100644 --- a/services/sensor/include/sensor_service.h +++ b/services/sensor/include/sensor_service.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -28,7 +28,9 @@ #include "sensor_data_event.h" #include "sensor_hdi_connection.h" #include "sensor_manager.h" +#include "sensor_power_policy.h" #include "sensor_service_stub.h" +#include "stream_server.h" namespace OHOS { namespace Sensors { @@ -37,7 +39,7 @@ enum class SensorServiceState { STATE_RUNNING, }; -class SensorService : public SystemAbility, public SensorServiceStub { +class SensorService : public SystemAbility, public StreamServer, public SensorServiceStub { DECLARE_SYSTEM_ABILITY(SensorService) public: @@ -54,6 +56,13 @@ public: const sptr &sensorClient) override; ErrCode DestroySensorChannel(sptr sensorClient) override; void ProcessDeathObserver(const wptr &object); + ErrCode SuspendSensors(int32_t pid) override; + ErrCode ResumeSensors(int32_t pid) override; + ErrCode GetActiveInfoList(int32_t pid, std::vector &activeInfoList) override; + ErrCode CreateSocketChannel(int32_t &clientFd, const sptr &sensorClient) override; + ErrCode DestroySocketChannel(const sptr &sensorClient) override; + ErrCode EnableActiveInfoCB() override; + ErrCode DisableActiveInfoCB() override; private: DISALLOW_COPY_AND_MOVE(SensorService); @@ -76,12 +85,15 @@ private: ClientInfo &clientInfo_ = ClientInfo::GetInstance(); SensorManager &sensorManager_ = SensorManager::GetInstance(); FlushInfoRecord &flushInfo_ = FlushInfoRecord::GetInstance(); + SensorPowerPolicy &sensorPowerPolicy_ = SensorPowerPolicy::GetInstance(); sptr sensorDataProcesser_ = nullptr; sptr reportDataCallback_ = nullptr; std::mutex uidLock_; // death recipient of sensor client sptr clientDeathObserver_ = nullptr; ErrCode SaveSubscriber(int32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs); + std::atomic_bool isReportActiveInfo_ = false; + void ReportActiveInfo(int32_t sensorId, int32_t pid); }; } // namespace Sensors } // namespace OHOS diff --git a/services/sensor/include/sensor_service_stub.h b/services/sensor/include/sensor_service_stub.h index 9259e793f11101593e9d19465052a4a08266169e..60b4ba49f772ac7a28f8d6d7d213c0a25c023282 100644 --- a/services/sensor/include/sensor_service_stub.h +++ b/services/sensor/include/sensor_service_stub.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -39,6 +39,13 @@ private: ErrCode GetAllSensorsInner(MessageParcel &data, MessageParcel &reply); ErrCode CreateDataChannelInner(MessageParcel &data, MessageParcel &reply); ErrCode DestroyDataChannelInner(MessageParcel &data, MessageParcel &reply); + ErrCode SuspendSensorsInner(MessageParcel &data, MessageParcel &reply); + ErrCode ResumeSensorsInner(MessageParcel &data, MessageParcel &reply); + ErrCode GetActiveInfoListInner(MessageParcel &data, MessageParcel &reply); + ErrCode CreateSocketChannelInner(MessageParcel &data, MessageParcel &reply); + ErrCode DestroySocketChannelInner(MessageParcel &data, MessageParcel &reply); + ErrCode EnableActiveInfoCBInner(MessageParcel &data, MessageParcel &reply); + ErrCode DisableActiveInfoCBInner(MessageParcel &data, MessageParcel &reply); std::unordered_map baseFuncs_; }; } // namespace Sensors diff --git a/services/sensor/include/stream_server.h b/services/sensor/include/stream_server.h new file mode 100644 index 0000000000000000000000000000000000000000..32d3c590cf8fe438778dbe5f2fe8d0bb1034e6af --- /dev/null +++ b/services/sensor/include/stream_server.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 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 STREAM_SERVER_H +#define STREAM_SERVER_H + +#include +#include + +#include "nocopyable.h" +#include "refbase.h" + +#include "stream_session.h" +#include "stream_socket.h" + +namespace OHOS { +namespace Sensors { +class StreamServer : public RefBase, public StreamSocket { +public: + StreamServer() = default; + virtual ~StreamServer(); + bool SendMsg(int32_t fd, NetPacket& pkt); + void Multicast(const std::vector& fdList, NetPacket& pkt); + int32_t GetClientFd(int32_t pid); + int32_t GetClientPid(int32_t fd); + SessionPtr GetSession(int32_t fd); + SessionPtr GetSessionByPid(int32_t pid); + int32_t AddSocketPairInfo(int32_t uid, int32_t pid, int32_t tokenType, int32_t &serverFd, int32_t &clientFd); + DISALLOW_COPY_AND_MOVE(StreamServer); + +protected: + bool AddSession(SessionPtr ses); + void DelSession(int32_t pid); + std::mutex idxPidMutex_; + std::map idxPidMap_; + std::mutex sessionMutex_; + std::map sessionsMap_; +}; +} // namespace Sensors +} // namespace OHOS +#endif // STREAM_SERVER_H diff --git a/services/sensor/src/client_info.cpp b/services/sensor/src/client_info.cpp index 8396fd43c682e2a2a0a2349c7658d5e57be2cd5a..afdb32619abf29665976967751fd40d14be7da1d 100644 --- a/services/sensor/src/client_info.cpp +++ b/services/sensor/src/client_info.cpp @@ -684,5 +684,50 @@ void ClientInfo::ClearDataQueue(int32_t sensorId) dumpQueue_.erase(it); } } + +int32_t ClientInfo::AddActiveInfoCBPid(int32_t pid) +{ + std::lock_guard activeInfoCBPidLock(activeInfoCBPidMutex_); + auto pairRet = activeInfoCBPidSet_.insert(pid); + if (!pairRet.second) { + SEN_HILOGE("ActiveInfoCBPidSet insert pid fail"); + return ERROR; + } + return ERR_OK; +} + +int32_t ClientInfo::DelActiveInfoCBPid(int32_t pid) +{ + std::lock_guard activeInfoCBPidLock(activeInfoCBPidMutex_); + auto it = activeInfoCBPidSet_.find(pid); + if (it == activeInfoCBPidSet_.end()) { + SEN_HILOGE("ActiveInfoCBPidSet not find pid"); + return ERROR; + } + activeInfoCBPidSet_.erase(it); + return ERR_OK; +} + +std::unordered_set ClientInfo::GetActiveInfoCBPid() +{ + return activeInfoCBPidSet_; +} + +bool ClientInfo::IsUnregisterClientDeathRecipient(int32_t pid) +{ + std::lock_guard channelLock(channelMutex_); + auto channelIt = channelMap_.find(pid); + if (channelIt != channelMap_.end()) { + SEN_HILOGD("Pid exist in channelMap"); + return false; + } + std::lock_guard activeInfoCBPidLock(activeInfoCBPidMutex_); + auto pidIt = activeInfoCBPidSet_.find(pid); + if (pidIt != activeInfoCBPidSet_.end()) { + SEN_HILOGD("Pid exist in activeInfoCBPidSet"); + return false; + } + return true; +} } // namespace Sensors } // namespace OHOS diff --git a/services/sensor/src/sensor_power_policy.cpp b/services/sensor/src/sensor_power_policy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9899efce68bce1f13a7830be51ec95557f4039d0 --- /dev/null +++ b/services/sensor/src/sensor_power_policy.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2021-2023 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_power_policy.h" + +#include "sensor.h" +#include "sensor_agent_type.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; + +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "SensorPowerPolicy" }; +constexpr int32_t INVALID_SENSOR_ID = -1; +constexpr int64_t MAX_EVENT_COUNT = 1000; +} // namespace + +bool SensorPowerPolicy::CheckFreezingSensor(int32_t sensorId) +{ + return ((sensorId == SENSOR_TYPE_ID_PEDOMETER_DETECTION) || (sensorId == SENSOR_TYPE_ID_PEDOMETER)); +} + +ErrCode SensorPowerPolicy::SuspendSensors(int32_t pid) +{ + CALL_LOG_ENTER; + std::vector sensorIdList = clientInfo_.GetSensorIdByPid(pid); + std::lock_guard pidSensorInfoLock(pidSensorInfoMutex_); + auto pidSensorInfoIt = pidSensorInfoMap_.find(pid); + if (pidSensorInfoIt != pidSensorInfoMap_.end()) { + if (sensorIdList.empty()) { + SEN_HILOGD("Pid already suspend, all sensors suspend success, not need suspend again"); + return ERR_OK; + } else { + SEN_HILOGD("Pid already suspend, some sensors suspend failed, suspend these sensors again"); + std::unordered_map SensorInfoMap = pidSensorInfoIt->second; + if (!Suspend(SensorInfoMap, sensorIdList, pid)) { + SEN_HILOGE("Some sensor suspend failed"); + return DISABLE_SENSOR_ERR; + } + return ERR_OK; + } + } + if (sensorIdList.empty()) { + SEN_HILOGE("Pid sensorId list is empty"); + return ERROR; + } + std::unordered_map SensorInfoMap; + auto isAllSuspend = Suspend(SensorInfoMap, sensorIdList, pid); + pidSensorInfoMap_.insert(std::make_pair(pid, SensorInfoMap)); + if (!isAllSuspend) { + SEN_HILOGE("Some sensor suspend failed"); + return DISABLE_SENSOR_ERR; + } + return ERR_OK; +} + +bool SensorPowerPolicy::Suspend(std::unordered_map &SensorInfoMap, + std::vector &sensorIdList, int32_t pid) +{ + CALL_LOG_ENTER; + bool isAllSuspend = true; + for (auto &sensorId : sensorIdList) { + if (CheckFreezingSensor(sensorId)) { + SEN_HILOGD("Current sensor is pedometer detectio or pedometer, can not suspend"); + continue; + } + auto sensorInfo = clientInfo_.GetCurPidSensorInfo(sensorId, pid); + if (sensorManager_.IsOtherClientUsingSensor(sensorId, pid)) { + SEN_HILOGD("Other client is using this sensor now, cannot suspend"); + SensorInfoMap.insert(std::make_pair(sensorId, sensorInfo)); + continue; + } + if (sensorHdiConnection_.DisableSensor(sensorId) != ERR_OK) { + SEN_HILOGE("Disable sensor failed, sensorId:%{public}d", sensorId); + isAllSuspend = false; + continue; + } + SensorInfoMap.insert(std::make_pair(sensorId, sensorInfo)); + sensorManager_.AfterDisableSensor(sensorId); + } + return isAllSuspend; +} + +ErrCode SensorPowerPolicy::ResumeSensors(int32_t pid) +{ + CALL_LOG_ENTER; + std::lock_guard pidSensorInfoLock(pidSensorInfoMutex_); + auto pidSensorInfoIt = pidSensorInfoMap_.find(pid); + if (pidSensorInfoIt == pidSensorInfoMap_.end()) { + SEN_HILOGE("Pid not have suspend sensors"); + return ERROR; + } + bool isAllResume = true; + std::unordered_map SensorInfoMap = pidSensorInfoIt->second; + for (auto sensorIt = SensorInfoMap.begin(); sensorIt != SensorInfoMap.end();) { + int32_t sensorId = sensorIt->first; + int64_t samplingPeriodNs = sensorIt->second.GetSamplingPeriodNs(); + int64_t maxReportDelayNs = sensorIt->second.GetMaxReportDelayNs(); + if (!Resume(pid, sensorId, samplingPeriodNs, maxReportDelayNs)) { + SEN_HILOGE("Resume sensor failed. sensorId:%{public}d", sensorId); + isAllResume = false; + ++sensorIt; + } else { + sensorIt = SensorInfoMap.erase(sensorIt); + } + } + if (!isAllResume) { + SEN_HILOGE("Some sensor resume failed"); + return ENABLE_SENSOR_ERR; + } + pidSensorInfoMap_.erase(pidSensorInfoIt); + return ERR_OK; +} + +bool SensorPowerPolicy::Resume(int32_t pid, int32_t sensorId, int64_t samplingPeriodNs, + int64_t maxReportDelayNs) +{ + CALL_LOG_ENTER; + if ((sensorId == INVALID_SENSOR_ID) || (samplingPeriodNs == 0) || + ((samplingPeriodNs != 0L) && (maxReportDelayNs / samplingPeriodNs > MAX_EVENT_COUNT))) { + SEN_HILOGE("SensorId is invalid or maxReportDelayNs exceed the maximum value"); + return false; + } + if (clientInfo_.GetSensorState(sensorId)) { + SEN_HILOGD("Sensor has been resume already, sensorId:%{public}d", sensorId); + auto ret = RestoreSensorInfo(pid, sensorId, samplingPeriodNs, maxReportDelayNs); + if (ret != ERR_OK) { + SEN_HILOGE("Restore sensor info failed, ret:%{public}d", ret); + return false; + } + return true; + } + auto ret = RestoreSensorInfo(pid, sensorId, samplingPeriodNs, maxReportDelayNs); + if (ret != ERR_OK) { + SEN_HILOGE("Restore sensor info failed, ret:%{public}d", ret); + return false; + } + ret = sensorHdiConnection_.EnableSensor(sensorId); + if (ret != ERR_OK) { + SEN_HILOGE("Resume sensor failed, ret:%{public}d", ret); + clientInfo_.RemoveSubscriber(sensorId, pid); + return false; + } + return true; +} + +ErrCode SensorPowerPolicy::RestoreSensorInfo(int32_t pid, int32_t sensorId, int64_t samplingPeriodNs, + int64_t maxReportDelayNs) +{ + CALL_LOG_ENTER; + auto ret = sensorManager_.SaveSubscriber(sensorId, pid, samplingPeriodNs, maxReportDelayNs); + if (ret != ERR_OK) { + SEN_HILOGE("SaveSubscriber failed, ret:%{public}d", ret); + return ret; + } + sensorManager_.StartDataReportThread(); + if (!sensorManager_.SetBestSensorParams(sensorId, samplingPeriodNs, maxReportDelayNs)) { + SEN_HILOGE("SetBestSensorParams failed"); + clientInfo_.RemoveSubscriber(sensorId, pid); + return ENABLE_SENSOR_ERR; + } + return ERR_OK; +} + +void SensorPowerPolicy::GetActiveInfoList(int32_t pid, std::vector &activeInfoList) +{ + CALL_LOG_ENTER; + std::vector sensorIdList = clientInfo_.GetSensorIdByPid(pid); + for (auto &sensorId : sensorIdList) { + auto sensorInfo = clientInfo_.GetCurPidSensorInfo(sensorId, pid); + ActiveInfo activeInfo(pid, sensorId, sensorInfo.GetSamplingPeriodNs(), + sensorInfo.GetMaxReportDelayNs()); + activeInfoList.push_back(activeInfo); + } +} + +void SensorPowerPolicy::ReportActiveInfo(ActiveInfo activeInfo, + const std::vector &sessionList) +{ + CALL_LOG_ENTER; + NetPacket pkt(MessageId::ACTIVE_INFO); + pkt << activeInfo.GetPid() << activeInfo.GetSensorId() << + activeInfo.GetSamplingPeriodNs() << activeInfo.GetMaxReportDelayNs(); + if (pkt.ChkRWError()) { + SEN_HILOGE("Packet write data failed"); + return; + } + for (auto sess : sessionList) { + if (!sess->SendMsg(pkt)) { + SEN_HILOGE("Packet send failed"); + continue; + } + } +} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file diff --git a/services/sensor/src/sensor_service.cpp b/services/sensor/src/sensor_service.cpp index 2c7563b78a2aa52bbef294032e093f361af6762d..d9e135dc3a472de9132920ba00162fa4cfba1a30 100644 --- a/services/sensor/src/sensor_service.cpp +++ b/services/sensor/src/sensor_service.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -20,6 +20,7 @@ #include #include +#include "accesstoken_kit.h" #include "hisysevent.h" #include "iservice_registry.h" #include "permission_util.h" @@ -32,7 +33,7 @@ namespace OHOS { namespace Sensors { using namespace OHOS::HiviewDFX; - +using namespace Security::AccessToken; namespace { constexpr HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "SensorService" }; constexpr int32_t INVALID_SENSOR_ID = -1; @@ -233,6 +234,9 @@ ErrCode SensorService::EnableSensor(int32_t sensorId, int64_t samplingPeriodNs, SEN_HILOGE("ret : %{public}d", ret); } ReportOnChangeData(sensorId); + if (isReportActiveInfo_) { + ReportActiveInfo(sensorId, pid); + } return ERR_OK; } auto ret = SaveSubscriber(sensorId, samplingPeriodNs, maxReportDelayNs); @@ -248,6 +252,9 @@ ErrCode SensorService::EnableSensor(int32_t sensorId, int64_t samplingPeriodNs, return ENABLE_SENSOR_ERR; } ReportSensorSysEvent(sensorId, true, pid); + if (isReportActiveInfo_) { + ReportActiveInfo(sensorId, pid); + } return ret; } @@ -357,6 +364,8 @@ void SensorService::ProcessDeathObserver(const wptr &object) SEN_HILOGE("disablesensor failed, ret:%{public}d", ret); } } + DelSession(pid); + clientInfo_.DelActiveInfoCBPid(pid); clientInfo_.DestroySensorChannel(pid); clientInfo_.DestroyClientPid(client); clientInfo_.DestroyCmd(clientInfo_.GetUidByPid(pid)); @@ -375,6 +384,15 @@ void SensorService::RegisterClientDeathRecipient(sptr sensorClien void SensorService::UnregisterClientDeathRecipient(sptr sensorClient) { CALL_LOG_ENTER; + int32_t pid = clientInfo_.FindClientPid(sensorClient); + if (pid == INVALID_PID) { + SEN_HILOGE("Pid is invalid"); + return; + } + if (!clientInfo_.IsUnregisterClientDeathRecipient(pid)) { + SEN_HILOGD("Client call other service, can not unregister client death recipient"); + return; + } sptr client = iface_cast(sensorClient); clientDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast(this)); CHKPV(clientDeathObserver_); @@ -404,5 +422,95 @@ int32_t SensorService::Dump(int32_t fd, const std::vector &args) sensorDump.ParseCommand(fd, argList, sensors_, clientInfo_); return ERR_OK; } + +ErrCode SensorService::SuspendSensors(int32_t pid) +{ + CALL_LOG_ENTER; + if (pid < 0) { + SEN_HILOGE("Pid is invalid"); + return CLIENT_PID_INVALID_ERR; + } + return sensorPowerPolicy_.SuspendSensors(pid); +} + +ErrCode SensorService::ResumeSensors(int32_t pid) +{ + CALL_LOG_ENTER; + if (pid < 0) { + SEN_HILOGE("Pid is invalid"); + return CLIENT_PID_INVALID_ERR; + } + return sensorPowerPolicy_.ResumeSensors(pid); +} + +ErrCode SensorService::GetActiveInfoList(int32_t pid, std::vector &activeInfoList) +{ + CALL_LOG_ENTER; + if (pid < 0) { + SEN_HILOGE("Pid is invalid"); + return CLIENT_PID_INVALID_ERR; + } + sensorPowerPolicy_.GetActiveInfoList(pid, activeInfoList); + return ERR_OK; +} + +ErrCode SensorService::CreateSocketChannel(int32_t &clientFd, const sptr &sensorClient) +{ + CALL_LOG_ENTER; + int32_t uid = GetCallingUid(); + int32_t pid = GetCallingPid(); + int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(GetCallingTokenID()); + int32_t serverFd = -1; + clientFd = -1; + int32_t ret = AddSocketPairInfo(uid, pid, tokenType, serverFd, std::ref(clientFd)); + if (ret != ERR_OK) { + SEN_HILOGE("Add socket pair info failed, ret:%{public}d", ret); + return ret; + } + RegisterClientDeathRecipient(sensorClient, pid); + return ERR_OK; +} + +ErrCode SensorService::DestroySocketChannel(const sptr &sensorClient) +{ + CALL_LOG_ENTER; + int32_t pid = GetCallingPid(); + DelSession(pid); + UnregisterClientDeathRecipient(sensorClient); + return ERR_OK; +} + +ErrCode SensorService::EnableActiveInfoCB() +{ + CALL_LOG_ENTER; + isReportActiveInfo_ = true; + int32_t pid = GetCallingPid(); + return clientInfo_.AddActiveInfoCBPid(pid); +} + +ErrCode SensorService::DisableActiveInfoCB() +{ + CALL_LOG_ENTER; + isReportActiveInfo_ = false; + int32_t pid = GetCallingPid(); + return clientInfo_.DelActiveInfoCBPid(pid); +} + +void SensorService::ReportActiveInfo(int32_t sensorId, int32_t pid) +{ + CALL_LOG_ENTER; + std::vector sessionList; + auto pidSet = clientInfo_.GetActiveInfoCBPid(); + for (auto pid : pidSet) { + auto sess = GetSessionByPid(pid); + if (sess != nullptr) { + sessionList.push_back(sess); + } + } + SensorBasicInfo sensorInfo = clientInfo_.GetCurPidSensorInfo(sensorId, pid); + ActiveInfo activeInfo(pid, sensorId, sensorInfo.GetSamplingPeriodNs(), + sensorInfo.GetMaxReportDelayNs()); + sensorPowerPolicy_.ReportActiveInfo(activeInfo, sessionList); +} } // namespace Sensors } // namespace OHOS diff --git a/services/sensor/src/sensor_service_stub.cpp b/services/sensor/src/sensor_service_stub.cpp index 94c2a8af6f5a92ba5b2c7021b74a0be2ce2f8b7d..f9d88729c9d2b9e1ba0e6a9974ce6377cc858098 100755 --- a/services/sensor/src/sensor_service_stub.cpp +++ b/services/sensor/src/sensor_service_stub.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 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 @@ -30,7 +30,6 @@ namespace OHOS { namespace Sensors { using namespace OHOS::HiviewDFX; - namespace { constexpr HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "SensorServiceStub" }; } // namespace @@ -43,6 +42,13 @@ SensorServiceStub::SensorServiceStub() baseFuncs_[GET_SENSOR_LIST] = &SensorServiceStub::GetAllSensorsInner; baseFuncs_[TRANSFER_DATA_CHANNEL] = &SensorServiceStub::CreateDataChannelInner; baseFuncs_[DESTROY_SENSOR_CHANNEL] = &SensorServiceStub::DestroyDataChannelInner; + baseFuncs_[SUSPEND_SENSORS] = &SensorServiceStub::SuspendSensorsInner; + baseFuncs_[RESUME_SENSORS] = &SensorServiceStub::ResumeSensorsInner; + baseFuncs_[GET_ACTIVE_INFO_LIST] = &SensorServiceStub::GetActiveInfoListInner; + baseFuncs_[CREATE_SOCKET_CHANNEL] = &SensorServiceStub::CreateSocketChannelInner; + baseFuncs_[DESTROY_SOCKET_CHANNEL] = &SensorServiceStub::DestroySocketChannelInner; + baseFuncs_[ENABLE_ACTIVE_INFO_CB] = &SensorServiceStub::EnableActiveInfoCBInner; + baseFuncs_[DISABLE_ACTIVE_INFO_CB] = &SensorServiceStub::DisableActiveInfoCBInner; } SensorServiceStub::~SensorServiceStub() @@ -153,5 +159,116 @@ ErrCode SensorServiceStub::DestroyDataChannelInner(MessageParcel &data, MessageP CHKPR(sensorClient, OBJECT_NULL); return DestroySensorChannel(sensorClient); } + +ErrCode SensorServiceStub::SuspendSensorsInner(MessageParcel &data, MessageParcel &reply) +{ + PermissionUtil &permissionUtil = PermissionUtil::GetInstance(); + if(!permissionUtil.IsNativeToken(GetCallingTokenID())) { + SEN_HILOGE("TokenType is not TOKEN_NATIVE"); + return PERMISSION_DENIED; + } + (void)reply; + int32_t pid; + if (!data.ReadInt32(pid)) { + SEN_HILOGE("Parcel read failed"); + return ERROR; + } + return SuspendSensors(pid); +} + +ErrCode SensorServiceStub::ResumeSensorsInner(MessageParcel &data, MessageParcel &reply) +{ + PermissionUtil &permissionUtil = PermissionUtil::GetInstance(); + if(!permissionUtil.IsNativeToken(GetCallingTokenID())) { + SEN_HILOGE("TokenType is not TOKEN_NATIVE"); + return PERMISSION_DENIED; + } + (void)reply; + int32_t pid; + if (!data.ReadInt32(pid)) { + SEN_HILOGE("Parcel read failed"); + return ERROR; + } + return ResumeSensors(pid); +} + +ErrCode SensorServiceStub::GetActiveInfoListInner(MessageParcel &data, MessageParcel &reply) +{ + PermissionUtil &permissionUtil = PermissionUtil::GetInstance(); + if(!permissionUtil.IsNativeToken(GetCallingTokenID())) { + SEN_HILOGE("TokenType is not TOKEN_NATIVE"); + return PERMISSION_DENIED; + } + int32_t pid; + if (!data.ReadInt32(pid)) { + SEN_HILOGE("Parcel read failed"); + return ERROR; + } + std::vector activeInfoList; + GetActiveInfoList(pid, activeInfoList); + int32_t activeInfoCount = int32_t { activeInfoList.size() }; + reply.WriteInt32(activeInfoCount); + for (int32_t i = 0; i < activeInfoCount; i++) { + if (!activeInfoList[i].Marshalling(reply)) { + SEN_HILOGE("ActiveInfo %{public}d failed", i); + return ERROR; + } + } + return ERR_OK; +} + +ErrCode SensorServiceStub::CreateSocketChannelInner(MessageParcel &data, MessageParcel &reply) +{ + sptr sensorClient = data.ReadRemoteObject(); + CHKPR(sensorClient, OBJECT_NULL); + int32_t clientFd = -1; + int32_t ret = CreateSocketChannel(clientFd, sensorClient); + if (ret != ERR_OK) { + SEN_HILOGE("Create socket channel failed"); + if (clientFd >= 0) { + close(clientFd); + } + return ret; + } + if (!reply.WriteFileDescriptor(clientFd)) { + SEN_HILOGE("Write file descriptor failed"); + close(clientFd); + return ERROR; + } + close(clientFd); + return ERR_OK; +} + +ErrCode SensorServiceStub::DestroySocketChannelInner(MessageParcel &data, MessageParcel &reply) +{ + sptr sensorClient = data.ReadRemoteObject(); + CHKPR(sensorClient, OBJECT_NULL); + int32_t ret = DestroySocketChannel(sensorClient); + if (ret != ERR_OK) { + SEN_HILOGE("DestroySocketChannel failed"); + return ret; + } + return ERR_OK; +} + +ErrCode SensorServiceStub::EnableActiveInfoCBInner(MessageParcel &data, MessageParcel &reply) +{ + PermissionUtil &permissionUtil = PermissionUtil::GetInstance(); + if(!permissionUtil.IsNativeToken(GetCallingTokenID())) { + SEN_HILOGE("TokenType is not TOKEN_NATIVE"); + return PERMISSION_DENIED; + } + return EnableActiveInfoCB(); +} + +ErrCode SensorServiceStub::DisableActiveInfoCBInner(MessageParcel &data, MessageParcel &reply) +{ + PermissionUtil &permissionUtil = PermissionUtil::GetInstance(); + if(!permissionUtil.IsNativeToken(GetCallingTokenID())) { + SEN_HILOGE("TokenType is not TOKEN_NATIVE"); + return PERMISSION_DENIED; + } + return DisableActiveInfoCB(); +} } // namespace Sensors } // namespace OHOS diff --git a/services/sensor/src/sensor_suspend_policy.cpp b/services/sensor/src/sensor_suspend_policy.cpp deleted file mode 100644 index 82ac98324343a998174c455212e19b7ea2382bbf..0000000000000000000000000000000000000000 --- a/services/sensor/src/sensor_suspend_policy.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * 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_agent_type.h" -#include "sensor_service.h" -#include "system_ability_definition.h" - -namespace OHOS { -namespace Sensors { -using namespace OHOS::HiviewDFX; - -namespace { -constexpr HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "SensorSuspendPolicy" }; -constexpr int32_t INVALID_SENSOR_ID = -1; -constexpr int64_t MAX_EVENT_COUNT = 1000; -constexpr int64_t DEFAULT_SAMPLING_RATE = 200000000; -constexpr int64_t DEFAULT_REPORT_DELAY = 0; -} // namespace - -SensorSuspendPolicy::~SensorSuspendPolicy() -{} - -bool SensorSuspendPolicy::CheckFreezingSensor(int32_t sensorId) -{ - return ((sensorId == SENSOR_TYPE_ID_PEDOMETER_DETECTION) || (sensorId == SENSOR_TYPE_ID_PEDOMETER)); -} - -ErrCode SensorSuspendPolicy::DisableSensor(int32_t sensorId, int32_t pid) -{ - CALL_LOG_ENTER; - if (sensorId == INVALID_SENSOR_ID) { - SEN_HILOGE("sensorId is invalid"); - return ERR_NO_INIT; - } - if (sensorManager_.IsOtherClientUsingSensor(sensorId, pid)) { - SEN_HILOGW("other client is using this sensor now, cannot disable"); - return ERR_OK; - } - if (interface_.DisableSensor(sensorId) != ERR_OK) { - SEN_HILOGE("DisableSensor is failed"); - return DISABLE_SENSOR_ERR; - } - return sensorManager_.AfterDisableSensor(sensorId); -} - -void SensorSuspendPolicy::DoSuspend(const std::shared_ptr &info) -{ - CALL_LOG_ENTER; - 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); - } - } -} - -ErrCode SensorSuspendPolicy::SaveSubscriber(int32_t sensorId, int64_t samplingPeriodNs, - int64_t maxReportDelayNs, int32_t pid) -{ - auto ret = sensorManager_.SaveSubscriber(sensorId, pid, samplingPeriodNs, maxReportDelayNs); - if (ret != ERR_OK) { - SEN_HILOGE("SaveSubscriber is failed"); - return ret; - } - sensorManager_.StartDataReportThread(); - if (!sensorManager_.SetBestSensorParams(sensorId, samplingPeriodNs, maxReportDelayNs)) { - SEN_HILOGE("SetBestSensorParams is failed"); - clientInfo_.RemoveSubscriber(sensorId, pid); - return ENABLE_SENSOR_ERR; - } - return ret; -} - -ErrCode SensorSuspendPolicy::EnableSensor(int32_t sensorId, int32_t pid, int64_t samplingPeriodNs, - int64_t maxReportDelayNs) -{ - CALL_LOG_ENTER; - if ((sensorId == INVALID_SENSOR_ID) || (samplingPeriodNs == 0) || - ((samplingPeriodNs != 0L) && (maxReportDelayNs / samplingPeriodNs > MAX_EVENT_COUNT))) { - SEN_HILOGE("sensorId is 0 or maxReportDelayNs exceed the maximum value"); - return ERR_NO_INIT; - } - if (clientInfo_.GetSensorState(sensorId) == SENSOR_ENABLED) { - SEN_HILOGW("sensor has been enabled already"); - auto ret = SaveSubscriber(sensorId, samplingPeriodNs, maxReportDelayNs, pid); - if (ret != ERR_OK) { - SEN_HILOGE("SaveSubscriber is failed"); - return ret; - } - uint32_t flag = sensorManager_.GetSensorFlag(sensorId); - ret = flushInfo_.FlushProcess(sensorId, flag, pid, true); - if (ret != ERR_OK) { - SEN_HILOGW("ret:%{public}d", ret); - } - return ERR_OK; - } - auto ret = SaveSubscriber(sensorId, samplingPeriodNs, maxReportDelayNs, pid); - if (ret != ERR_OK) { - SEN_HILOGE("SaveSubscriber is failed"); - return ret; - } - ret = interface_.EnableSensor(sensorId); - if (ret != ERR_OK) { - SEN_HILOGE("EnableSensor is failed"); - clientInfo_.RemoveSubscriber(sensorId, pid); - return ENABLE_SENSOR_ERR; - } - return ret; -} - -std::vector SensorSuspendPolicy::GetSensorIdByPid(int32_t pid) -{ - SEN_HILOGD("pid:%{public}d", pid); - auto it = pidSensorIdMap_.find(pid); - if (it != pidSensorIdMap_.end()) { - SEN_HILOGD("pid:%{public}d found", pid); - return it->second; - } - SEN_HILOGD("pid:%{public}d not found", pid); - return {}; -} - -void SensorSuspendPolicy::DoActive(const std::shared_ptr &info) -{ - CALL_LOG_ENTER; - int64_t samplePeriod = DEFAULT_SAMPLING_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) { - SEN_HILOGE("sensorId:%{public}u,pid:%{public}d,ret:%{public}d", sensorId, appInfo.pid, ret); - } - } - } - pidSensorIdMap_.clear(); - sensorIdInfoMap_.clear(); -} -} // namespace Sensors -} // namespace OHOS diff --git a/services/sensor/src/stream_server.cpp b/services/sensor/src/stream_server.cpp new file mode 100644 index 0000000000000000000000000000000000000000..df7f2c92b0c6bfa13c4a2b2898ee9840ec1a6f8f --- /dev/null +++ b/services/sensor/src/stream_server.cpp @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2023 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 "stream_server.h" + +#include +#include + +#include "accesstoken_kit.h" + +#include "sensors_errors.h" + +namespace OHOS { +namespace Sensors { +namespace { +using namespace Security::AccessToken; +constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "StreamServer" }; +constexpr int32_t INVALID_PID = -1; +constexpr int32_t INVALID_FD = -1; +} // namespace +StreamServer::~StreamServer() +{ + CALL_LOG_ENTER; + idxPidMap_.clear(); + for (const auto &item : sessionsMap_) { + item.second->Close(); + } + sessionsMap_.clear(); +} + +bool StreamServer::SendMsg(int32_t fd, NetPacket& pkt) +{ + CALL_LOG_ENTER; + if (fd < 0) { + SEN_HILOGE("Fd is invalid"); + return false; + } + auto ses = GetSession(fd); + if (ses == nullptr) { + SEN_HILOGE("Fd not found, The message was discarded."); + return false; + } + return ses->SendMsg(pkt); +} + +void StreamServer::Multicast(const std::vector& fdList, NetPacket& pkt) +{ + CALL_LOG_ENTER; + for (const auto &item : fdList) { + SendMsg(item, pkt); + } +} + +int32_t StreamServer::GetClientFd(int32_t pid) +{ + std::lock_guard idxPidLock(idxPidMutex_); + auto it = idxPidMap_.find(pid); + if (it == idxPidMap_.end()) { + return INVALID_FD; + } + return it->second; +} + +int32_t StreamServer::GetClientPid(int32_t fd) +{ + std::lock_guard sessionLock(sessionMutex_); + auto it = sessionsMap_.find(fd); + if (it == sessionsMap_.end()) { + return INVALID_PID; + } + return it->second->GetPid(); +} + +SessionPtr StreamServer::GetSession(int32_t fd) +{ + std::lock_guard sessionLock(sessionMutex_); + auto it = sessionsMap_.find(fd); + if (it == sessionsMap_.end()) { + SEN_HILOGE("Session not found"); + return nullptr; + } + CHKPP(it->second); + return it->second->GetSharedPtr(); +} + +SessionPtr StreamServer::GetSessionByPid(int32_t pid) +{ + int32_t fd = GetClientFd(pid); + if (fd <= 0) { + SEN_HILOGE("Session not found"); + return nullptr; + } + return GetSession(fd); +} + +int32_t StreamServer::AddSocketPairInfo(int32_t uid, int32_t pid, int32_t tokenType, + int32_t &serverFd, int32_t &clientFd) +{ + CALL_LOG_ENTER; + std::string programName = ""; + int32_t moduleType = 0; + int32_t sockFds[2] = { -1 }; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockFds) != 0) { + SEN_HILOGE("Call socketpair failed, errno:%{public}d", errno); + return ERROR; + } + serverFd = sockFds[0]; + clientFd = sockFds[1]; + if (serverFd < 0 || clientFd < 0) { + SEN_HILOGE("Call fcntl failed, errno:%{public}d", errno); + return ERROR; + } + static constexpr size_t bufferSize = 32 * 1024; + static constexpr size_t nativeBufferSize = 64 * 1024; + SessionPtr sess = nullptr; + if (setsockopt(serverFd, SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)) != 0) { + SEN_HILOGE("Setsockopt serverFd failed, errno: %{public}d", errno); + goto CLOSE_SOCK; + } + if (setsockopt(serverFd, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)) != 0) { + SEN_HILOGE("Setsockopt serverFd failed, errno: %{public}d", errno); + goto CLOSE_SOCK; + } + if (tokenType == ATokenTypeEnum::TOKEN_NATIVE) { + if (setsockopt(clientFd, SOL_SOCKET, SO_SNDBUF, &nativeBufferSize, sizeof(nativeBufferSize)) != 0) { + SEN_HILOGE("Setsockopt clientFd failed, errno: %{public}d", errno); + goto CLOSE_SOCK; + } + if (setsockopt(clientFd, SOL_SOCKET, SO_RCVBUF, &nativeBufferSize, sizeof(nativeBufferSize)) != 0) { + SEN_HILOGE("Setsockopt clientFd failed, errno: %{public}d", errno); + goto CLOSE_SOCK; + } + } else { + if (setsockopt(clientFd, SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)) != 0) { + SEN_HILOGE("Setsockopt clientFd failed, errno: %{public}d", errno); + goto CLOSE_SOCK; + } + if (setsockopt(clientFd, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)) != 0) { + SEN_HILOGE("Setsockopt clientFd failed, errno: %{public}d", errno); + goto CLOSE_SOCK; + } + } + sess = std::make_shared(programName, moduleType, serverFd, uid, pid); + sess->SetTokenType(tokenType); + if (!AddSession(sess)) { + SEN_HILOGE("AddSession fail"); + goto CLOSE_SOCK; + } + return ERR_OK; + +CLOSE_SOCK: + close(serverFd); + serverFd = -1; + close(clientFd); + clientFd = -1; + return ERROR; +} + +bool StreamServer::AddSession(SessionPtr ses) +{ + CALL_LOG_ENTER; + CHKPF(ses); + auto fd = ses->GetFd(); + if (fd < 0) { + SEN_HILOGE("Fd is Invalid"); + return false; + } + auto pid = ses->GetPid(); + if (pid <= 0) { + SEN_HILOGE("Get process failed"); + return false; + } + if (sessionsMap_.size() > MAX_SESSON_ALARM) { + SEN_HILOGE("Too many clients. Warning Value:%{public}zu, Current Value:%{public}zu", + MAX_SESSON_ALARM, sessionsMap_.size()); + return false; + } + DelSession(pid); + std::lock_guard idxPidLock(idxPidMutex_); + idxPidMap_[pid] = fd; + std::lock_guard sessionLock(sessionMutex_); + sessionsMap_[fd] = ses; + return true; +} + +void StreamServer::DelSession(int32_t pid) +{ + CALL_LOG_ENTER; + std::lock_guard idxPidLock(idxPidMutex_); + auto pidIt = idxPidMap_.find(pid); + if (pidIt == idxPidMap_.end()) { + return; + } + int32_t fd = pidIt->second; + idxPidMap_.erase(pidIt); + std::lock_guard sessionLock(sessionMutex_); + auto fdIt = sessionsMap_.find(fd); + if (fdIt != sessionsMap_.end()) { + sessionsMap_.erase(fdIt); + } + if (fd >= 0) { + auto rf = close(fd); + if (rf > 0) { + SEN_HILOGE("Socket fd close failed, rf:%{public}d", rf); + } + } +} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/common/include/system_info.h b/test/unittest/common/include/system_info.h index b48b8fdad025a93d9677b2581cd72edd083d8afe..0a59896935782f623a8e295918e64b30e17e5f09 100644 --- a/test/unittest/common/include/system_info.h +++ b/test/unittest/common/include/system_info.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -36,6 +36,8 @@ class CpuInfo : public SystemInfo { public: double GetSystemCpuUsage(); double GetProcCpuUsage(const std::string& process_name); + int32_t GetTaskPidFile(const std::string& process_name); + private: struct Total_Cpu_Occupy { char name[20] { 0 }; @@ -56,7 +58,6 @@ private: int32_t cutime { 0 }; int32_t cstime { 0 }; }; - int32_t GetTaskPidFile(const std::string& process_name); int32_t GetProcOccupy(int32_t pid); int32_t GetSystemCpuStatInfo(Total_Cpu_Occupy& info); diff --git a/utils/BUILD.gn b/utils/BUILD.gn index 7a971bb7473fb530b345c66e18a97912ea76e55d..80796c29f2fe5b3edabbe9022504a66bab5b2728 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021 Huawei Device Co., Ltd. +# Copyright (c) 2021-2023 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 @@ -11,38 +11,9 @@ # 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_utils") { - sources = [ - "src/permission_util.cpp", - "src/report_data_callback.cpp", - "src/sensor.cpp", - "src/sensor_basic_data_channel.cpp", - "src/sensor_basic_info.cpp", - "src/sensor_channel_info.cpp", - ] - - include_dirs = [ - "include", - "//commonlibrary/c_utils/base/include", - "//utils/system/safwk/native/include", - "//drivers/peripheral/sensor/interfaces/include", - "$SUBSYSTEM_DIR/sensor/interfaces/native/include", - ] - - external_deps = [ - "access_token:libaccesstoken_sdk", - "access_token:libprivacy_sdk", - "c_utils:utils", - "hisysevent_native:libhisysevent", - "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_core", - ] - part_name = "sensor" - subsystem_name = "sensors" -} - group("sensor_utils_target") { - deps = [ ":libsensor_utils" ] + deps = [ + "common:libsensor_utils", + "ipc:libsensor_ipc", + ] } diff --git a/utils/common/BUILD.gn b/utils/common/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..0afec250d7250e3a5b0bc16392c9bc9e7c05cee2 --- /dev/null +++ b/utils/common/BUILD.gn @@ -0,0 +1,43 @@ +# Copyright (c) 2023 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") + +ohos_shared_library("libsensor_utils") { + sources = [ + "src/active_info.cpp", + "src/permission_util.cpp", + "src/report_data_callback.cpp", + "src/sensor.cpp", + "src/sensor_basic_data_channel.cpp", + "src/sensor_basic_info.cpp", + "src/sensor_channel_info.cpp", + ] + + include_dirs = [ + "include", + "./../../interfaces/native/include", + ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libprivacy_sdk", + "c_utils:utils", + "hisysevent_native:libhisysevent", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + ] + + part_name = "sensor" + subsystem_name = "sensors" +} diff --git a/utils/common/include/active_info.h b/utils/common/include/active_info.h new file mode 100644 index 0000000000000000000000000000000000000000..721e96c4e56932c96a063df26e31ab0aa3e66440 --- /dev/null +++ b/utils/common/include/active_info.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 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 ACTIVE_INFO_H +#define ACTIVE_INFO_H + +#include "parcel.h" + +namespace OHOS { +namespace Sensors { +class ActiveInfo : public Parcelable { +public: + ActiveInfo() = default; + ActiveInfo(int32_t pid, int32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs); + ~ActiveInfo() = default; + int32_t GetPid() const; + void SetPid(int32_t pid); + int32_t GetSensorId() const; + void SetSensorId(int32_t sensorId); + int64_t GetSamplingPeriodNs() const; + void SetSamplingPeriodNs(int64_t samplingPeriodNs); + int64_t GetMaxReportDelayNs() const; + void SetMaxReportDelayNs(int64_t maxReportDelayNs); + bool Marshalling(Parcel &parcel) const; + std::unique_ptr Unmarshalling(Parcel &parcel); + +private: + int32_t pid_ { -1 }; + int32_t sensorId_ { -1 }; + int64_t samplingPeriodNs_ { -1 }; + int64_t maxReportDelayNs_ { -1 }; +}; +} // namespace Sensors +} // namespace OHOS +#endif // ACTIVE_INFO_H \ No newline at end of file diff --git a/utils/include/app_thread_info.h b/utils/common/include/app_thread_info.h similarity index 100% rename from utils/include/app_thread_info.h rename to utils/common/include/app_thread_info.h diff --git a/utils/include/death_recipient_template.h b/utils/common/include/death_recipient_template.h similarity index 100% rename from utils/include/death_recipient_template.h rename to utils/common/include/death_recipient_template.h diff --git a/utils/include/miscdevice_common.h b/utils/common/include/miscdevice_common.h similarity index 100% rename from utils/include/miscdevice_common.h rename to utils/common/include/miscdevice_common.h diff --git a/utils/include/permission_util.h b/utils/common/include/permission_util.h similarity index 96% rename from utils/include/permission_util.h rename to utils/common/include/permission_util.h index ba61b2f896dc9f6710ed433d8f406e56ed9e539a..dadbacbd87bea822a9349374eb8d4bedb306a844 100644 --- a/utils/include/permission_util.h +++ b/utils/common/include/permission_util.h @@ -30,6 +30,7 @@ public: PermissionUtil() = default; virtual ~PermissionUtil() {}; int32_t CheckSensorPermission(AccessTokenID callerToken, int32_t sensorTypeId); + bool IsNativeToken(AccessTokenID tokenID); private: void AddPermissionRecord(AccessTokenID tokenID, const std::string& permissionName, bool status); diff --git a/utils/include/report_data_callback.h b/utils/common/include/report_data_callback.h similarity index 100% rename from utils/include/report_data_callback.h rename to utils/common/include/report_data_callback.h diff --git a/utils/include/sensor.h b/utils/common/include/sensor.h similarity index 100% rename from utils/include/sensor.h rename to utils/common/include/sensor.h diff --git a/utils/include/sensor_basic_data_channel.h b/utils/common/include/sensor_basic_data_channel.h similarity index 100% rename from utils/include/sensor_basic_data_channel.h rename to utils/common/include/sensor_basic_data_channel.h diff --git a/utils/include/sensor_basic_info.h b/utils/common/include/sensor_basic_info.h similarity index 100% rename from utils/include/sensor_basic_info.h rename to utils/common/include/sensor_basic_info.h diff --git a/utils/include/sensor_channel_info.h b/utils/common/include/sensor_channel_info.h similarity index 100% rename from utils/include/sensor_channel_info.h rename to utils/common/include/sensor_channel_info.h diff --git a/utils/include/sensor_data_event.h b/utils/common/include/sensor_data_event.h similarity index 100% rename from utils/include/sensor_data_event.h rename to utils/common/include/sensor_data_event.h diff --git a/utils/include/sensor_log.h b/utils/common/include/sensor_log.h similarity index 100% rename from utils/include/sensor_log.h rename to utils/common/include/sensor_log.h diff --git a/utils/include/sensors_errors.h b/utils/common/include/sensors_errors.h similarity index 98% rename from utils/include/sensors_errors.h rename to utils/common/include/sensors_errors.h index 55e11c3c1811330cd08f4607e528d3235cfae0ee..43edceab7f28f318574e95ec0dfa9506deb4539c 100644 --- a/utils/include/sensors_errors.h +++ b/utils/common/include/sensors_errors.h @@ -87,8 +87,9 @@ enum { COPY_ERR = NO_EVENT + 1, REGIST_PERMISSION_CHANGED_ERR = COPY_ERR + 1, DUMP_PARAM_ERR = REGIST_PERMISSION_CHANGED_ERR + 1, - WRITE_MSG_ERR = DUMP_PARAM_ERR + 1, - SET_SENSOR_MODE_ERR = WRITE_MSG_ERR + 1, + WRITE_PARCEL_ERR = DUMP_PARAM_ERR + 1, + READ_PARCEL_ERR = WRITE_PARCEL_ERR + 1, + SET_SENSOR_MODE_ERR = READ_PARCEL_ERR + 1, SET_SENSOR_OPTION_ERR = SET_SENSOR_MODE_ERR + 1, REGIST_CALLBACK_ERR = SET_SENSOR_OPTION_ERR + 1, }; diff --git a/utils/common/src/active_info.cpp b/utils/common/src/active_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6e2f836e3e202d5c2c364d4c6bb63518d629082b --- /dev/null +++ b/utils/common/src/active_info.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2023 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 "active_info.h" + +#include "sensors_errors.h" + +namespace OHOS { +namespace Sensors { +using namespace OHOS::HiviewDFX; +namespace { +constexpr HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "ActiveInfo" }; +} + +ActiveInfo::ActiveInfo(int32_t pid, int32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs) + :pid_(pid), sensorId_(sensorId), samplingPeriodNs_(samplingPeriodNs), maxReportDelayNs_(maxReportDelayNs) +{} + +int32_t ActiveInfo::GetPid() const +{ + return pid_; +} + +void ActiveInfo::SetPid(int32_t pid) +{ + pid_ = pid; +} + +int32_t ActiveInfo::GetSensorId() const +{ + return sensorId_; +} + +void ActiveInfo::SetSensorId(int32_t sensorId) +{ + sensorId_ = sensorId; +} + +int64_t ActiveInfo::GetSamplingPeriodNs() const +{ + return samplingPeriodNs_; +} + +void ActiveInfo::SetSamplingPeriodNs(int64_t samplingPeriodNs) +{ + samplingPeriodNs_ = samplingPeriodNs; +} + +int64_t ActiveInfo::GetMaxReportDelayNs() const +{ + return maxReportDelayNs_; +} + +void ActiveInfo::SetMaxReportDelayNs(int64_t maxReportDelayNs) +{ + maxReportDelayNs_ = maxReportDelayNs; +} + +bool ActiveInfo::Marshalling(Parcel &parcel) const +{ + if (!parcel.WriteInt32(pid_)) { + SEN_HILOGE("Write pid failed"); + return false; + } + if (!parcel.WriteInt32(sensorId_)) { + SEN_HILOGE("Write sensorId failed"); + return false; + } + if (!parcel.WriteInt64(samplingPeriodNs_)) { + SEN_HILOGE("Write samplingPeriodNs failed"); + return false; + } + if (!parcel.WriteInt64(maxReportDelayNs_)) { + SEN_HILOGE("Write maxReportDelayNs failed"); + return false; + } + return true; +} + +std::unique_ptr ActiveInfo::Unmarshalling(Parcel &parcel) +{ + int32_t pid = -1; + int32_t sensorId = -1; + int64_t samplingPeriodNs = -1; + int64_t maxReportDelayNs = -1; + if (!(parcel.ReadInt32(pid) && parcel.ReadInt32(sensorId) && + parcel.ReadInt64(samplingPeriodNs) && parcel.ReadInt64(maxReportDelayNs))) { + SEN_HILOGE("Read from parcel is failed"); + return nullptr; + } + auto activeInfo = std::make_unique(); + activeInfo->SetPid(pid); + activeInfo->SetSensorId(sensorId); + activeInfo->SetSamplingPeriodNs(samplingPeriodNs); + activeInfo->SetMaxReportDelayNs(maxReportDelayNs); + return activeInfo; +} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file diff --git a/utils/src/permission_util.cpp b/utils/common/src/permission_util.cpp similarity index 90% rename from utils/src/permission_util.cpp rename to utils/common/src/permission_util.cpp index 4e2d91e00fa3f6c7d3029739ca6cca88e7107d0a..9e5bd3050f1ea9e1479a29fa31e7e3b6aca336ba 100644 --- a/utils/src/permission_util.cpp +++ b/utils/common/src/permission_util.cpp @@ -67,5 +67,15 @@ void PermissionUtil::AddPermissionRecord(AccessTokenID tokenID, const std::strin permissionName.c_str(), successCount, failCount); } } + +bool PermissionUtil::IsNativeToken(AccessTokenID tokenID) +{ + int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(tokenID); + if (tokenType != ATokenTypeEnum::TOKEN_NATIVE) { + SEN_HILOGE("TokenType is not TOKEN_NATIVE, tokenType:%{public}d", tokenType); + return false; + } + return true; +} } // namespace Sensors } // namespace OHOS diff --git a/utils/src/report_data_callback.cpp b/utils/common/src/report_data_callback.cpp similarity index 100% rename from utils/src/report_data_callback.cpp rename to utils/common/src/report_data_callback.cpp diff --git a/utils/src/sensor.cpp b/utils/common/src/sensor.cpp similarity index 100% rename from utils/src/sensor.cpp rename to utils/common/src/sensor.cpp diff --git a/utils/src/sensor_basic_data_channel.cpp b/utils/common/src/sensor_basic_data_channel.cpp similarity index 100% rename from utils/src/sensor_basic_data_channel.cpp rename to utils/common/src/sensor_basic_data_channel.cpp diff --git a/utils/src/sensor_basic_info.cpp b/utils/common/src/sensor_basic_info.cpp similarity index 100% rename from utils/src/sensor_basic_info.cpp rename to utils/common/src/sensor_basic_info.cpp diff --git a/utils/src/sensor_channel_info.cpp b/utils/common/src/sensor_channel_info.cpp similarity index 100% rename from utils/src/sensor_channel_info.cpp rename to utils/common/src/sensor_channel_info.cpp diff --git a/utils/ipc/BUILD.gn b/utils/ipc/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..6e579be0b66e15b5e9fae99e9e158c431ba3c0cc --- /dev/null +++ b/utils/ipc/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (c) 2023 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") + +ohos_shared_library("libsensor_ipc") { + sources = [ + "src/circle_stream_buffer.cpp", + "src/net_packet.cpp", + "src/stream_buffer.cpp", + "src/stream_session.cpp", + "src/stream_socket.cpp", + ] + + include_dirs = [ + "include", + "./../common/include", + ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "c_utils:utils", + "hiviewdfx_hilog_native:libhilog", + ] + + part_name = "sensor" + subsystem_name = "sensors" +} diff --git a/utils/ipc/include/circle_stream_buffer.h b/utils/ipc/include/circle_stream_buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..569ab5b10f338af9f230e81f57128a243656bff3 --- /dev/null +++ b/utils/ipc/include/circle_stream_buffer.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 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 CIRCLE_STREAM_BUFFER_H +#define CIRCLE_STREAM_BUFFER_H + +#include "stream_buffer.h" + +namespace OHOS { +namespace Sensors { +class CircleStreamBuffer : public StreamBuffer { + static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "CircleStreamBuffer" }; +public: + CircleStreamBuffer() = default; + ~CircleStreamBuffer() = default; + bool CheckWrite(size_t size); + bool Write(const char *buf, size_t size) override; + DISALLOW_MOVE(CircleStreamBuffer); + +protected: + void CopyDataToBegin(); +}; +} // namespace Sensors +} // namespace OHOS +#endif // CIRCLE_STREAM_BUFFER_H \ No newline at end of file diff --git a/utils/ipc/include/net_packet.h b/utils/ipc/include/net_packet.h new file mode 100644 index 0000000000000000000000000000000000000000..6bf4e501eede4befd27070311ed2c4cbff2c40f8 --- /dev/null +++ b/utils/ipc/include/net_packet.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 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 NET_PACKET_H +#define NET_PACKET_H + +#include "proto.h" +#include "stream_buffer.h" + +#pragma pack(1) +using PACKHEAD = struct PackHead { + OHOS::Sensors::MessageId idMsg; + size_t size; +}; + +#pragma pack() +namespace OHOS { +namespace Sensors { +class NetPacket : public StreamBuffer { + static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "NetPacket" }; +public: + explicit NetPacket(MessageId msgId); + NetPacket(const NetPacket &pkt); + NetPacket &operator = (const NetPacket &pkt); + ~NetPacket() = default; + void MakeData(StreamBuffer &buf) const; + size_t GetSize() const; + size_t GetPacketLength() const; + const char* GetData() const; + MessageId GetMsgId() const; + DISALLOW_MOVE(NetPacket); + +protected: + MessageId msgId_ = MessageId::INVALID; +}; +} // namespace Sensors +} // namespace OHOS +#endif // NET_PACKET_H \ No newline at end of file diff --git a/utils/ipc/include/proto.h b/utils/ipc/include/proto.h new file mode 100644 index 0000000000000000000000000000000000000000..c846508bce1d469491c24f26f00765a7959f70d5 --- /dev/null +++ b/utils/ipc/include/proto.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 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 PROTO_H +#define PROTO_H + +#include + +namespace OHOS { +namespace Sensors { +static const size_t SEND_RETRY_LIMIT = 32; +static const size_t SEND_RETRY_SLEEP_TIME = 10000; +static const size_t MAX_VECTOR_SIZE = 10; +static const size_t MAX_SESSON_ALARM = 100; +static const size_t MAX_RECV_LIMIT = 13; +static const size_t MAX_STREAM_BUF_SIZE = 256; +static const size_t MAX_PACKET_BUF_SIZE = 256; +static const size_t ONCE_PROCESS_NETPACKET_LIMIT = 100; + +enum class MessageId : int32_t { + INVALID, + ACTIVE_INFO, +}; +} // namespace Sensors +} // namespace OHOS +#endif // PROTO_H \ No newline at end of file diff --git a/utils/ipc/include/stream_buffer.h b/utils/ipc/include/stream_buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..6e376b0cec901022708482cbb3262ac6e918f257 --- /dev/null +++ b/utils/ipc/include/stream_buffer.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2023 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 STREAM_BUFFER_H +#define STREAM_BUFFER_H + +#include +#include +#include + +#include "nocopyable.h" +#include "securec.h" + +#include "proto.h" +#include "sensors_errors.h" + +namespace OHOS { +namespace Sensors { +class StreamBuffer { + static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "StreamBuffer" }; +public: + StreamBuffer() = default; + explicit StreamBuffer(const StreamBuffer &buf); + virtual StreamBuffer &operator=(const StreamBuffer &other); + virtual ~StreamBuffer() = default; + void Reset(); + void Clean(); + bool SeekReadPos(size_t n); + bool Read(std::string &buf); + bool Read(StreamBuffer &buf); + bool Read(char *buf, size_t size); + bool Write(const std::string &buf); + bool Write(const StreamBuffer &buf); + virtual bool Write(const char *buf, size_t size); + bool IsEmpty() const; + bool ChkRWError() const; + size_t Size() const; + size_t UnreadSize() const; + size_t GetAvailableBufSize() const; + const std::string& GetErrorStatusRemark() const; + const char* Data() const; + + template + bool Read(T &data); + template + bool Write(const T &data); + template + bool Read(std::vector &data); + template + bool Write(const std::vector &data); + const char *ReadBuf() const; + const char *WriteBuf() const; + template + StreamBuffer &operator >> (T &data); + template + StreamBuffer &operator << (const T &data); + DISALLOW_MOVE(StreamBuffer); + +protected: + bool Clone(const StreamBuffer &buf); + enum class ErrorStatus { + ERROR_STATUS_OK, + ERROR_STATUS_READ, + ERROR_STATUS_WRITE, + }; + ErrorStatus rwErrorStatus_ = ErrorStatus::ERROR_STATUS_OK; + size_t rCount_ { 0 }; + size_t wCount_ { 0 }; + size_t rPos_ { 0 }; + size_t wPos_ { 0 }; + char szBuff_[MAX_STREAM_BUF_SIZE + 1] = {}; +}; + +template +bool StreamBuffer::Read(T &data) +{ + if (!Read(reinterpret_cast(&data), sizeof(data))) { + SEN_HILOGE("%{public}s, size:%{public}zu, count:%{public}zu", + GetErrorStatusRemark().c_str(), sizeof(data), rCount_ + 1); + return false; + } + return true; +} + +template +bool StreamBuffer::Write(const T &data) +{ + if (!Write(reinterpret_cast(&data), sizeof(data))) { + SEN_HILOGE("%{public}s, size:%{public}zu, count:%{public}zu", + GetErrorStatusRemark().c_str(), sizeof(data), wCount_ + 1); + return false; + } + return true; +} + +template +bool StreamBuffer::Read(std::vector &data) +{ + size_t size = 0; + if (!Read(size)) { + SEN_HILOGE("Read vector size failed"); + return false; + } + if (size > MAX_VECTOR_SIZE) { + SEN_HILOGE("Vector size is invalid, size:%{public}zu", size); + return false; + } + for (size_t i = 0; i < size; i++) { + T val; + if (!Read(val)) { + SEN_HILOGE("Read vector data failed"); + return false; + } + data.push_back(val); + } + return true; +} + +template +bool StreamBuffer::Write(const std::vector &data) +{ + if (data.size() > INT32_MAX) { + SEN_HILOGE("Vector exceeds the max range"); + return false; + } + size_t size = data.size(); + if (!Write(size)) { + SEN_HILOGE("Write vector size failed"); + return false; + } + for (const auto &item : data) { + if (!Write(item)) { + SEN_HILOGE("Write vector data failed"); + return false; + } + } + return true; +} + +template +StreamBuffer &StreamBuffer::operator>>(T &data) +{ + if (!Read(data)) { + SEN_HILOGW("Read data failed"); + } + return *this; +} + +template +StreamBuffer &StreamBuffer::operator<<(const T &data) +{ + if (!Write(data)) { + SEN_HILOGW("Write data failed"); + } + return *this; +} +} // namespace Sensors +} // namespace OHOS +#endif // STREAM_BUFFER_H \ No newline at end of file diff --git a/utils/ipc/include/stream_session.h b/utils/ipc/include/stream_session.h new file mode 100644 index 0000000000000000000000000000000000000000..eba3fb1a9240262f78b440829656db92398546d0 --- /dev/null +++ b/utils/ipc/include/stream_session.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023 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 STREAM_SESSION_H +#define STREAM_SESSION_H + +#include +#include +#include + +#include +#include + +#include "accesstoken_kit.h" +#include "nocopyable.h" + +#include "net_packet.h" +#include "proto.h" + +namespace OHOS { +namespace Sensors { +class StreamSession; +using SessionPtr = std::shared_ptr; +using namespace Security::AccessToken; +class StreamSession : public std::enable_shared_from_this { +public: + StreamSession(const std::string &programName, const int32_t moduleType, const int32_t fd, const int32_t uid, + const int32_t pid); + virtual ~StreamSession() = default; + bool SendMsg(const char *buf, size_t size) const; + bool SendMsg(NetPacket &pkt) const; + void Close(); + int32_t GetUid() const; + int32_t GetPid() const; + int32_t GetModuleType() const; + SessionPtr GetSharedPtr(); + int32_t GetFd() const; + const std::string& GetDescript() const; + const std::string GetProgramName() const; + void SetTokenType(int32_t type); + int32_t GetTokenType() const; + void UpdateDescript(); + DISALLOW_COPY_AND_MOVE(StreamSession); + +protected: + struct EventTime { + int32_t id { 0 }; + int64_t eventTime { 0 }; + int32_t timerId { -1 }; + }; + std::map> events_; + std::string descript_; + const std::string programName_; + const int32_t moduleType_ { -1 }; + int32_t fd_ { -1 }; + const int32_t uid_ { -1 }; + const int32_t pid_ { -1 }; + int32_t tokenType_ { ATokenTypeEnum::TOKEN_INVALID }; +}; +} // namespace Sensors +} // namespace OHOS +#endif // STREAM_SESSION_H \ No newline at end of file diff --git a/utils/ipc/include/stream_socket.h b/utils/ipc/include/stream_socket.h new file mode 100644 index 0000000000000000000000000000000000000000..acae2006c5cc9e8d693cb5f0c5ab9100e1e7e441 --- /dev/null +++ b/utils/ipc/include/stream_socket.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023 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 STREAM_SOCKET_H +#define STREAM_SOCKET_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "nocopyable.h" + +#include "circle_stream_buffer.h" +#include "net_packet.h" + +namespace OHOS { +namespace Sensors { +class StreamSocket { +public: + using PacketCallBackFun = std::function; + StreamSocket(); + virtual ~StreamSocket(); + int32_t EpollCreate(int32_t size); + int32_t EpollCtl(int32_t fd, int32_t op, struct epoll_event &event, int32_t epollFd = -1); + int32_t EpollWait(struct epoll_event &events, int32_t maxevents, int32_t timeout, int32_t epollFd = -1); + void OnReadPackets(CircleStreamBuffer &buf, PacketCallBackFun callbackFun); + void EpollClose(); + void Close(); + int32_t GetFd() const; + int32_t GetEpollFd() const; + + DISALLOW_COPY_AND_MOVE(StreamSocket); + +protected: + int32_t fd_ { -1 }; + int32_t epollFd_ { -1 }; +}; +} // namespace Sensors +} // namespace OHOS +#endif // STREAM_SOCKET_H \ No newline at end of file diff --git a/utils/ipc/src/circle_stream_buffer.cpp b/utils/ipc/src/circle_stream_buffer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c086b695719ef5dcfe11925ea450a93cf63f9f53 --- /dev/null +++ b/utils/ipc/src/circle_stream_buffer.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 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 "circle_stream_buffer.h" + +#include "sensors_errors.h" + +namespace OHOS { +namespace Sensors { +bool CircleStreamBuffer::CheckWrite(size_t size) +{ + size_t availSize = GetAvailableBufSize(); + if (size > availSize && rPos_ > 0) { + CopyDataToBegin(); + availSize = GetAvailableBufSize(); + } + return (availSize >= size); +} + +bool CircleStreamBuffer::Write(const char *buf, size_t size) +{ + if (!CheckWrite(size)) { + SEN_HILOGE("Buffer is overflow, availableSize:%{public}zu, size:%{public}zu," + "unreadSize:%{public}zu, rPos:%{public}zu, wPos:%{public}zu", + GetAvailableBufSize(), size, UnreadSize(), rPos_, wPos_); + return false; + } + return StreamBuffer::Write(buf, size); +} + +void CircleStreamBuffer::CopyDataToBegin() +{ + size_t unreadSize = UnreadSize(); + if (unreadSize > 0 && rPos_ > 0) { + size_t pos = 0; + for (size_t i = rPos_; i <= wPos_;) { + szBuff_[pos++] = szBuff_[i++]; + } + } + SEN_HILOGD("UnreadSize:%{public}zu, rPos:%{public}zu, wPos:%{public}zu", unreadSize, rPos_, wPos_); + rPos_ = 0; + wPos_ = unreadSize; +} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file diff --git a/utils/ipc/src/net_packet.cpp b/utils/ipc/src/net_packet.cpp new file mode 100644 index 0000000000000000000000000000000000000000..27dec89bc2f8d14faffdfdd21b2dcb86d7716efb --- /dev/null +++ b/utils/ipc/src/net_packet.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023 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 "net_packet.h" + +#include "sensors_errors.h" + +namespace OHOS { +namespace Sensors { +NetPacket::NetPacket(MessageId msgId) : msgId_(msgId) +{} + +NetPacket::NetPacket(const NetPacket &pkt) : NetPacket(pkt.GetMsgId()) +{ + Clone(pkt); +} + +void NetPacket::MakeData(StreamBuffer &buf) const +{ + PACKHEAD head = {msgId_, wPos_}; + buf << head; + if (wPos_ > 0) { + if (!buf.Write(&szBuff_[0], wPos_)) { + SEN_HILOGE("Write data to stream failed"); + return; + } + } +} + +size_t NetPacket::GetSize() const +{ + return Size(); +} + +size_t NetPacket::GetPacketLength() const +{ + return sizeof(PackHead) + wPos_; +} + +const char* NetPacket::GetData() const +{ + return Data(); +} + +MessageId NetPacket::GetMsgId() const +{ + return msgId_; +} +} // namespace Sensors +} // namespace OHOS diff --git a/utils/ipc/src/stream_buffer.cpp b/utils/ipc/src/stream_buffer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..53764b9707c31b5c8d6ffbf783a4a8ff7c3e0098 --- /dev/null +++ b/utils/ipc/src/stream_buffer.cpp @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2023 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 "stream_buffer.h" + +#include +#include + +namespace OHOS { +namespace Sensors { +StreamBuffer::StreamBuffer(const StreamBuffer &buf) +{ + Clone(buf); +} + +StreamBuffer &StreamBuffer::operator=(const StreamBuffer &other) +{ + Clone(other); + return *this; +} + +void StreamBuffer::Reset() +{ + rPos_ = 0; + wPos_ = 0; + rCount_ = 0; + wCount_ = 0; + rwErrorStatus_ = ErrorStatus::ERROR_STATUS_OK; +} + +void StreamBuffer::Clean() +{ + Reset(); + errno_t ret = memset_sp(&szBuff_, sizeof(szBuff_), 0, sizeof(szBuff_)); + if (ret != EOK) { + SEN_HILOGE("Call memset_s fail"); + return; + } +} + +bool StreamBuffer::SeekReadPos(size_t n) +{ + size_t pos = rPos_ + n; + if (pos > wPos_) { + SEN_HILOGE("The position in the calculation is not as expected. pos:%{public}zu, [0, %{public}zu]", pos, wPos_); + return false; + } + rPos_ = pos; + return true; +} + +bool StreamBuffer::Read(std::string &buf) +{ + if (rPos_ == wPos_) { + SEN_HILOGE("Not enough memory to read"); + rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ; + return false; + } + buf = ReadBuf(); + rPos_ += buf.length() + 1; + return (buf.length() > 0); +} + +bool StreamBuffer::Write(const std::string &buf) +{ + return Write(buf.c_str(), buf.length()+1); +} + +bool StreamBuffer::Read(StreamBuffer &buf) +{ + return buf.Write(Data(), Size()); +} + +bool StreamBuffer::Write(const StreamBuffer &buf) +{ + return Write(buf.Data(), buf.Size()); +} + +bool StreamBuffer::Read(char *buf, size_t size) +{ + if (ChkRWError()) { + return false; + } + if (buf == nullptr) { + SEN_HILOGE("Invalid input parameter, buf is nullptr"); + rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ; + return false; + } + if (size == 0) { + SEN_HILOGE("Invalid input parameter, size:%{public}zu", size); + rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ; + return false; + } + if (rPos_ + size > wPos_) { + SEN_HILOGE("Memory out of bounds on read"); + rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ; + return false; + } + errno_t ret = memcpy_sp(buf, size, ReadBuf(), size); + if (ret != EOK) { + SEN_HILOGE("Failed to call memcpy_sp"); + rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ; + return false; + } + rPos_ += size; + rCount_ += 1; + return true; +} + +bool StreamBuffer::Write(const char *buf, size_t size) +{ + if (ChkRWError()) { + return false; + } + if (buf == nullptr) { + SEN_HILOGE("Invalid input parameter, buf is nullptr"); + rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE; + return false; + } + if (size == 0) { + SEN_HILOGE("Invalid input parameter, size:%{public}zu", size); + rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE; + return false; + } + if (wPos_ + size > MAX_STREAM_BUF_SIZE) { + SEN_HILOGE("The write length exceeds buffer. wPos:%{public}zu, size:%{public}zu, maxBufSize:%{public}zu", + wPos_, size, MAX_STREAM_BUF_SIZE); + rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE; + return false; + } + errno_t ret = memcpy_sp(&szBuff_[wPos_], GetAvailableBufSize(), buf, size); + if (ret != EOK) { + SEN_HILOGE("Failed to call memcpy_sp"); + rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE; + return false; + } + wPos_ += size; + wCount_ += 1; + return true; +} + +bool StreamBuffer::IsEmpty() const +{ + return (rPos_ == wPos_); +} + +size_t StreamBuffer::Size() const +{ + return wPos_; +} + +size_t StreamBuffer::UnreadSize() const +{ + return ((wPos_ <= rPos_) ? 0 : (wPos_ - rPos_)); +} + +size_t StreamBuffer::GetAvailableBufSize() const +{ + return ((wPos_ >= MAX_STREAM_BUF_SIZE) ? 0 : (MAX_STREAM_BUF_SIZE - wPos_)); +} + +bool StreamBuffer::ChkRWError() const +{ + return (rwErrorStatus_ != ErrorStatus::ERROR_STATUS_OK); +} + +const std::string &StreamBuffer::GetErrorStatusRemark() const +{ + static const std::vector> remark { + {ErrorStatus::ERROR_STATUS_OK, "OK"}, + {ErrorStatus::ERROR_STATUS_READ, "READ_ERROR"}, + {ErrorStatus::ERROR_STATUS_WRITE, "WRITE_ERROR"}, + }; + static const std::string invalidStatus { "UNKNOWN" }; + auto tIter = std::find_if(remark.cbegin(), remark.cend(), [this](const auto &item) { + return (item.first == rwErrorStatus_); + }); + return (tIter != remark.cend() ? tIter->second : invalidStatus); +} + +const char *StreamBuffer::Data() const +{ + return &szBuff_[0]; +} + +const char *StreamBuffer::ReadBuf() const +{ + return &szBuff_[rPos_]; +} + +const char *StreamBuffer::WriteBuf() const +{ + return &szBuff_[wPos_]; +} + +bool StreamBuffer::Clone(const StreamBuffer &buf) +{ + Clean(); + return Write(buf.Data(), buf.Size()); +} +} // namespace Sensors +} // namespace OHOS diff --git a/utils/ipc/src/stream_session.cpp b/utils/ipc/src/stream_session.cpp new file mode 100644 index 0000000000000000000000000000000000000000..257f96f36774cdb40a1277fe620b4ab6c4618a4b --- /dev/null +++ b/utils/ipc/src/stream_session.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2023 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 "stream_session.h" + +#include +#include + +#include +#include +#include +#include + +#include "proto.h" +#include "stream_socket.h" +#include "sensors_errors.h" + +namespace OHOS { +namespace Sensors { +namespace { +constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "StreamSession" }; +} + +StreamSession::StreamSession(const std::string &programName, const int32_t moduleType, const int32_t fd, + const int32_t uid, const int32_t pid) + : programName_(programName), + moduleType_(moduleType), + fd_(fd), + uid_(uid), + pid_(pid) +{ + UpdateDescript(); +} + +bool StreamSession::SendMsg(const char *buf, size_t size) const +{ + CHKPF(buf); + if ((size == 0) || (size > MAX_PACKET_BUF_SIZE)) { + SEN_HILOGE("Buf size:%{public}zu", size); + return false; + } + if (fd_ < 0) { + SEN_HILOGE("The fd_ is less than 0"); + return false; + } + size_t idx = 0; + size_t retryCount = 0; + size_t remSize = size; + while (remSize > 0 && retryCount < SEND_RETRY_LIMIT) { + retryCount += 1; + auto count = send(fd_, &buf[idx], remSize, MSG_DONTWAIT | MSG_NOSIGNAL); + if (count < 0) { + if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK) { + usleep(SEND_RETRY_SLEEP_TIME); + SEN_HILOGW("Continue for errno EAGAIN|EINTR|EWOULDBLOCK, errno:%{public}d", errno); + continue; + } + SEN_HILOGE("Send return failed,error:%{public}d fd:%{public}d", errno, fd_); + return false; + } + idx += count; + remSize -= count; + if (remSize > 0) { + usleep(SEND_RETRY_SLEEP_TIME); + } + } + if (retryCount >= SEND_RETRY_LIMIT || remSize != 0) { + SEN_HILOGE("Send too many times:%{public}zu/%{public}zu, size:%{public}zu/%{public}zu, fd:%{public}d", + retryCount, SEND_RETRY_LIMIT, idx, size, fd_); + return false; + } + return true; +} + +void StreamSession::Close() +{ + if (fd_ >= 0) { + close(fd_); + fd_ = -1; + UpdateDescript(); + } +} + +void StreamSession::UpdateDescript() +{ + std::ostringstream oss; + oss << "fd = " << fd_ + << ", programName = " << programName_ + << ", moduleType = " << moduleType_ + << ((fd_ < 0) ? ", closed" : ", opened") + << ", uid = " << uid_ + << ", pid = " << pid_ + << ", tokenType = " << tokenType_ + << std::endl; + descript_ = oss.str().c_str(); +} + +bool StreamSession::SendMsg(NetPacket &pkt) const +{ + if (pkt.ChkRWError()) { + SEN_HILOGE("Read and write status failed"); + return false; + } + StreamBuffer buf; + pkt.MakeData(buf); + return SendMsg(buf.Data(), buf.Size()); +} + +int32_t StreamSession::GetUid() const +{ + return uid_; +} + +int32_t StreamSession::GetPid() const +{ + return pid_; +} + +int32_t StreamSession::GetModuleType() const +{ + return moduleType_; +} + +SessionPtr StreamSession::GetSharedPtr() +{ + return shared_from_this(); +} + +int32_t StreamSession::GetFd() const +{ + return fd_; +} + +const std::string& StreamSession::GetDescript() const +{ + return descript_; +} + +const std::string StreamSession::GetProgramName() const +{ + return programName_; +} + +void StreamSession::SetTokenType(int32_t type) +{ + tokenType_ = type; +} + +int32_t StreamSession::GetTokenType() const +{ + return tokenType_; +} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file diff --git a/utils/ipc/src/stream_socket.cpp b/utils/ipc/src/stream_socket.cpp new file mode 100644 index 0000000000000000000000000000000000000000..77f711726c0927f931eea7392862aa2c7a7442d2 --- /dev/null +++ b/utils/ipc/src/stream_socket.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2023 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 "stream_socket.h" + +#include + +#include "sensors_errors.h" + +namespace OHOS { +namespace Sensors { +namespace { +constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SENSOR_LOG_DOMAIN, "StreamSocket" }; +} // namespace + +StreamSocket::StreamSocket() {} + +StreamSocket::~StreamSocket() +{ + Close(); + EpollClose(); +} + +int32_t StreamSocket::EpollCreate(int32_t size) +{ + epollFd_ = epoll_create(size); + if (epollFd_ < 0) { + SEN_HILOGE("Epoll_create return %{public}d", epollFd_); + } else { + SEN_HILOGI("Epoll_create, epollFd_:%{public}d", epollFd_); + } + return epollFd_; +} + +int32_t StreamSocket::EpollCtl(int32_t fd, int32_t op, struct epoll_event &event, int32_t epollFd) +{ + if (fd < 0) { + SEN_HILOGE("Invalid fd"); + return ERROR; + } + if (epollFd < 0) { + epollFd = epollFd_; + } + if (epollFd < 0) { + SEN_HILOGE("Invalid param epollFd"); + return ERROR; + } + int32_t ret; + if (op == EPOLL_CTL_DEL) { + ret = epoll_ctl(epollFd, op, fd, NULL); + } else { + ret = epoll_ctl(epollFd, op, fd, &event); + } + if (ret < 0) { + SEN_HILOGE("Epoll_ctl ret:%{public}d, epollFd_:%{public}d, op:%{public}d, fd:%{public}d, errno:%{public}d", + ret, epollFd, op, fd, errno); + } + return ret; +} + +int32_t StreamSocket::EpollWait(struct epoll_event &events, int32_t maxevents, int32_t timeout, int32_t epollFd) +{ + if (epollFd < 0) { + epollFd = epollFd_; + } + if (epollFd < 0) { + SEN_HILOGE("Invalid param epollFd"); + return ERROR; + } + auto ret = epoll_wait(epollFd, &events, maxevents, timeout); + if (ret < 0) { + SEN_HILOGE("Epoll_wait ret:%{public}d, errno:%{public}d", ret, errno); + } + return ret; +} + +void StreamSocket::OnReadPackets(CircleStreamBuffer &circBuf, StreamSocket::PacketCallBackFun callbackFun) +{ + constexpr size_t headSize = sizeof(PackHead); + for (size_t i = 0; i < ONCE_PROCESS_NETPACKET_LIMIT; i++) { + const size_t unreadSize = circBuf.UnreadSize(); + if (unreadSize < headSize) { + break; + } + size_t dataSize = unreadSize - headSize; + char *buf = const_cast(circBuf.ReadBuf()); + CHKPB(buf); + PackHead *head = reinterpret_cast(buf); + CHKPB(head); + if (head->size < 0 || head->size > MAX_PACKET_BUF_SIZE) { + SEN_HILOGE("Packet header parsing error, and this error cannot be recovered. The buffer will be reset." + " head->size:%{public}zu, unreadSize:%{public}zu", head->size, unreadSize); + circBuf.Reset(); + break; + } + if (head->size > dataSize) { + break; + } + NetPacket pkt(head->idMsg); + if ((head->size > 0) && (!pkt.Write(&buf[headSize], head->size))) { + SEN_HILOGW("Error writing data in the NetPacket. It will be retried next time. messageid:%{public}d," + "size:%{public}zu", head->idMsg, head->size); + break; + } + if (!circBuf.SeekReadPos(pkt.GetPacketLength())) { + SEN_HILOGW("Set read position error, and this error cannot be recovered, and the buffer will be reset." + " packetSize:%{public}zu, unreadSize:%{public}zu", pkt.GetPacketLength(), unreadSize); + circBuf.Reset(); + break; + } + callbackFun(pkt); + if (circBuf.IsEmpty()) { + circBuf.Reset(); + break; + } + } +} + +void StreamSocket::EpollClose() +{ + if (epollFd_ >= 0) { + close(epollFd_); + epollFd_ = -1; + } +} + +void StreamSocket::Close() +{ + if (fd_ >= 0) { + auto rf = close(fd_); + if (rf > 0) { + SEN_HILOGE("Socket close failed, rf:%{public}d", rf); + } + } + fd_ = -1; +} + +int32_t StreamSocket::GetFd() const +{ + return fd_; +} +int32_t StreamSocket::GetEpollFd() const +{ + return epollFd_; +} +} // namespace Sensors +} // namespace OHOS \ No newline at end of file