diff --git a/batterymgr.gni b/batterymgr.gni index 399faa2465069fb8f868af2a4560acf5a45ff903..e28bf2aed1b2334324a57c781c1a53a008b44455 100755 --- a/batterymgr.gni +++ b/batterymgr.gni @@ -17,6 +17,7 @@ declare_args() { battery_manager_feature_set_low_capacity_threshold = false battery_manager_feature_enable_charger = false battery_manager_feature_enable_charging_sound = false + battery_manager_feature_support_notification = false battery_manager_feature_enable_wireless_charge = false } diff --git a/bundle.json b/bundle.json index 564606dbe3bb4fecdd19c52a2e818c8c178e4113..4b5aea2b4daf9681ecfa9a1ef4560110380b477e 100644 --- a/bundle.json +++ b/bundle.json @@ -23,7 +23,8 @@ "battery_manager_feature_enable_charger", "battery_manager_feature_enable_charging_sound", "battery_manager_feature_enable_wireless_charge", - "battery_manager_feature_set_low_capacity_threshold" + "battery_manager_feature_set_low_capacity_threshold", + "battery_manager_feature_support_notification" ], "adapted_system_type": [ "standard" @@ -65,7 +66,10 @@ "power_manager", "safwk", "samgr", - "ui_lite" + "ui_lite", + "distributed_notification_service", + "i18n", + "image_framework" ] }, "build": { diff --git a/services/BUILD.gn b/services/BUILD.gn index 80954b359082bf6b9f8a6ec09df5a8cfc2813708..fd6e0f4ab0019b1f92e0e767ac75acbf8ae2e77b 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -16,6 +16,7 @@ import("../batterymgr.gni") config("batterysrv_public_config") { include_dirs = [ "native/include", + "native/notification", "${battery_service_zidl}/include", "${battery_inner_api}/native/include", ] @@ -94,6 +95,10 @@ ohos_shared_library("batteryservice") { defines += [ "BATTERY_MANAGER_SET_LOW_CAPACITY_THRESHOLD" ] } + if (battery_manager_feature_support_notification) { + defines += [ "BATTERY_SUPPORT_NOTIFICATION" ] + } + if (build_variant == "user") { defines += [ "BATTERY_USER_VERSION" ] } @@ -102,10 +107,68 @@ ohos_shared_library("batteryservice") { part_name = "battery_manager" } +ohos_shared_library("battery_notification") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + branch_protector_ret = "pac_ret" + + include_dirs = [ "native/notification" ] + + sources = [ + "native/notification/button_event.cpp", + "native/notification/notification_center.cpp", + "native/notification/notification_decorator.cpp", + "native/notification/notification_locale.cpp", + "native/notification/notification_manager.cpp", + ] + + configs = [ + "${battery_utils}:utils_config", + "${battery_utils}:coverage_flags", + ] + + public_configs = [ ":batterysrv_public_config" ] + + public_external_deps = [ "ability_base:want" ] + + deps = [ "${battery_inner_api}:batterysrv_client" ] + + external_deps = [ + "ability_base:zuri", + "c_utils:utils", + "config_policy:configpolicy_util", + "distributed_notification_service:ans_innerkits", + "hilog:libhilog", + "i18n:intl_util", + "image_framework:image_native", + "jsoncpp:jsoncpp", + ] + + subsystem_name = "powermgr" + part_name = "battery_manager" +} + group("service") { deps = [ + ":battery_notification", ":batteryservice", "native/profile:battery_config", "native/profile:battery_vibrator_config", ] + + if (battery_manager_feature_support_notification) { + deps += [ + "native/resources:battery_locale_path", + "native/resources:battery_notification_base", + "native/resources:battery_notification_bo_CN", + "native/resources:battery_notification_ug", + "native/resources:battery_notification_zh_CN", + "native/resources:battery_notification_zh_HK", + "native/resources:battery_notification_zh_TW", + "native/resources:battery_notification_zz_ZX", + ] + } } diff --git a/services/native/include/battery_config.h b/services/native/include/battery_config.h index 5b249e01c89a03685da2f5dfe2d84deceaaa86f6..8b1a95646793814dac5aadb76858f1a3c5768453 100644 --- a/services/native/include/battery_config.h +++ b/services/native/include/battery_config.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "nocopyable.h" @@ -40,12 +41,34 @@ public: int32_t GetInt(std::string key, int32_t defVal = 0) const; const std::vector& GetLightConf() const; bool GetWirelessChargerConf() const; + struct PopupConf { + std::string name; + int32_t action; + }; + struct NotificationConf { + std::string name; + std::string icon; + std::string title; + std::string text; + std::pair firstButton; + std::pair secondButton; + const std::string GetInfo() const + { + return "name: " + name + ", icon: " + icon + ", title: " + title + ", text: " + text + + ", firstButton: " + firstButton.first + ", " + firstButton.second + + ", secondButton: " + secondButton.first + ", " + secondButton.second; + } + }; + const std::unordered_map>& GetPopupConf() const; + const std::unordered_map& GetNotificationConf() const; private: bool OpenFile(std::ifstream& ifsConf, const std::string& configPath); void ParseConfInner(); void ParseLightConf(std::string level); void ParseWirelessChargerConf(); + void ParsePopupConf(); + void ParseNotificationConf(); Json::Value FindConf(const std::string& key) const; bool SplitKey(const std::string& key, std::vector& keys) const; Json::Value GetValue(std::string key) const; @@ -54,6 +77,8 @@ private: bool wirelessChargerEnable_ { false }; static std::mutex mutex_; static std::shared_ptr instance_; + std::unordered_map> popupConfig_; + std::unordered_map notificationConfMap_; }; } // namespace PowerMgr } // namespace OHOS diff --git a/services/native/include/battery_notify.h b/services/native/include/battery_notify.h index 954ca81f7c1fc7cfa19d1590fc77eade32955de6..f9859f233292f0ab140f049340d3c247dca06176 100755 --- a/services/native/include/battery_notify.h +++ b/services/native/include/battery_notify.h @@ -44,6 +44,7 @@ private: bool PublishChargeTypeChangedEvent(const BatteryInfo& info); bool IsCommonEventServiceAbilityExist() const; bool PublishCustomEvent(const BatteryInfo& info, const std::string& commonEventName) const; + bool HandleNotification(const std::string& ueventName) const; void WirelessPluggedConnected(const BatteryInfo& info) const; void WirelessPluggedDisconnected(const BatteryInfo& info) const; void RotationMotionSubscriber() const; diff --git a/services/native/notification/button_event.cpp b/services/native/notification/button_event.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3f07ef4ea716354f883b1b8009ae18365e00bcb9 --- /dev/null +++ b/services/native/notification/button_event.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2024 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 "button_event.h" +#include "battery_log.h" + +namespace { +constexpr int32_t POWERUID = 5528; +} +namespace OHOS { +namespace PowerMgr { +void ButtonCes::AddEventHandle(const std::string& action, EventHandle func) +{ + eventHandles_[action] = func; +} + +void ButtonCes::RegisterCesEvent() +{ + if (isCesEventSubscribered_) { + return; + } + OHOS::EventFwk::MatchingSkills matchingSkills; + for (auto& itFunc : eventHandles_) { + matchingSkills.AddEvent(itFunc.first); + } + EventFwk::CommonEventSubscribeInfo subscriberInfo(matchingSkills); + subscriberInfo.SetPublisherUid(POWERUID); + cesEventSubscriber_ = std::make_shared(subscriberInfo, eventHandles_); + if (cesEventSubscriber_ == nullptr) { + BATTERY_HILOGE(COMP_SVC, "cesEventSubscriber_ nullptr"); + return; + } + if (!EventFwk::CommonEventManager::SubscribeCommonEvent(cesEventSubscriber_)) { + cesEventSubscriber_ = nullptr; + BATTERY_HILOGE(COMP_SVC, "SubscriberCommonEvent fail"); + } else { + isCesEventSubscribered_ = true; + } +} + +void ButtonCes::UnRegisterCesEvent() +{ + if (!isCesEventSubscribered_) { + return; + } + EventFwk::CommonEventManager::UnSubscribeCommonEvent(cesEventSubscriber_); + cesEventSubscriber_ = nullptr; + isCesEventSubscribered_ = false; +} + +ButtonCes::Ces::Ces(const CommonEventSubscribeInfo &subscriberInfo, + const std::unordered_map& handles) + : CommonEventSubscriber(subscriberInfo), eventHandles_(handles) +{ + BATTERY_HILOGI(COMP_SVC, "Button CesEventSubscriber"); +} + +ButtonCes::Ces::~Ces() +{ + BATTERY_HILOGI(COMP_SVC, "Button ~CesEventSubscriber"); +} + +void ButtonCes::Ces::OnReceiveEvent(const CommonEventData &eventData) +{ + auto action = eventData.GetWant().GetAction(); + auto it = eventHandles_.find(action); + if (it == eventHandles_.end()) { + BATTERY_HILOGI(COMP_SVC, "Ignore Event: %{public}s", action.c_str()); + return; + } + BATTERY_HILOGD(COMP_SVC, "Handle Event: %{public}s", action.c_str()); + auto func = it->second; + if (func) { + it->second(eventData); + } +} +} +} \ No newline at end of file diff --git a/services/native/notification/button_event.h b/services/native/notification/button_event.h new file mode 100644 index 0000000000000000000000000000000000000000..1a64ef5d6280f9cc8388a52a5e0447ec9077d464 --- /dev/null +++ b/services/native/notification/button_event.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 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 BATTERY_BUTTON_EVENT_H +#define BATTERY_BUTTON_EVENT_H + +#include +#include +#include +#include "common_event_manager.h" +#include "common_event_support.h" + +namespace OHOS { +namespace PowerMgr { +using EventHandle = std::function; +using namespace OHOS::EventFwk; +class ButtonCes { +public: + void AddEventHandle(const std::string& action, EventHandle func); + + void RegisterCesEvent(); + + void UnRegisterCesEvent(); + + class Ces : public CommonEventSubscriber { + public: + explicit Ces(const CommonEventSubscribeInfo &subscriberInfo, + const std::unordered_map& handles); + virtual ~Ces(); + void OnReceiveEvent(const CommonEventData &eventData) override; + private: + const std::unordered_map& eventHandles_; + }; +private: + bool isCesEventSubscribered_ = false; + std::shared_ptr cesEventSubscriber_ = nullptr; + std::unordered_map eventHandles_; +}; +} // namespace PowerMgr +} // namespace OHOS + +#endif // BATTERY_BUTTON_EVENT_H \ No newline at end of file diff --git a/services/native/notification/ibattery_notification.h b/services/native/notification/ibattery_notification.h new file mode 100644 index 0000000000000000000000000000000000000000..9da828729bb3f3b6060d582c1fcffc8f4e1be53f --- /dev/null +++ b/services/native/notification/ibattery_notification.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 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 IBATTERY_NOTIFICATION_H +#define IBATTERY_NOTIFICATION_H + +#include +#include +#include "battery_config.h" +namespace OHOS { +namespace PowerMgr { +class IBatteryNotification { +public: + IBatteryNotification() = default; + virtual ~IBatteryNotification() = default; + + virtual void CreateBaseStyle(const BatteryConfig::NotificationConf& nCfg) {} + + virtual void SetActionButton(const std::string& buttonName, const std::string& buttonAction) = 0; + + virtual bool PublishNotification() = 0; + + virtual bool CancelNotification() = 0; +}; +} // namespace PowerMgr +} // namespace OHOS + +#endif // IBATTERY_NOTIFICATION_H \ No newline at end of file diff --git a/services/native/notification/notification_center.cpp b/services/native/notification/notification_center.cpp new file mode 100644 index 0000000000000000000000000000000000000000..903a0c0318e13f7f8e992adea125e1a0d61af1e6 --- /dev/null +++ b/services/native/notification/notification_center.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2024 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 "notification_helper.h" +#include "want_agent_helper.h" +#include "want_agent_info.h" +#include "battery_log.h" +#include "image_source.h" +#include "pixel_map.h" +#include "notification_center.h" + +namespace OHOS { +namespace PowerMgr { +static const int BATTERY_NOTIFICATION_SYS_ABILITY_ID = 5528; +static const std::string BATTERY_NOTIFICATION_SYS_ABILITY_NAME = ""; + +void NotificationCenter::CreateBaseStyle(const BatteryConfig::NotificationConf& nCfg) +{ + SetNotificationId(nCfg.name); + SetContent(nCfg.title, nCfg.text); + SetCreatorUid(); + SetCreatorBundleName(); + SetSlotType(); + SetInProgress(); + SetUnremovable(); + SetBadgeIconStyle(); + SetLittleIcon(nCfg.icon); +} + +void NotificationCenter::SetNotificationId(const std::string& popupName) +{ + int32_t notificationId = std::hash()(popupName); + BATTERY_HILOGI(COMP_SVC, "SetNotificationId notifationId[%{public}d]", notificationId); + request_.SetNotificationId(notificationId); +} + +void NotificationCenter::SetContent(const std::string& title, const std::string& text) +{ + std::shared_ptr content + = std::make_shared(); + if (content == nullptr) { + BATTERY_HILOGE(COMP_SVC, "Failed to create NotificationNormalContent"); + return; + } + content->SetTitle(title); + content->SetText(text); + std::shared_ptr notificationContent + = std::make_shared(content); + if (notificationContent == nullptr) { + BATTERY_HILOGE(COMP_SVC, "Failed to create NotificationContent"); + return; + } + request_.SetContent(notificationContent); +} + +void NotificationCenter::SetCreatorUid() +{ + request_.SetCreatorUid(BATTERY_NOTIFICATION_SYS_ABILITY_ID); +} + +void NotificationCenter::SetCreatorBundleName() +{ + request_.SetCreatorBundleName(BATTERY_NOTIFICATION_SYS_ABILITY_NAME); +} + +void NotificationCenter::SetSlotType() +{ + request_.SetSlotType(OHOS::Notification::NotificationConstant::SlotType::SOCIAL_COMMUNICATION); +} + +void NotificationCenter::SetInProgress() +{ + request_.SetInProgress(true); +} + +void NotificationCenter::SetUnremovable() +{ + request_.SetUnremovable(true); +} + +void NotificationCenter::SetBadgeIconStyle() +{ + request_.SetBadgeIconStyle(Notification::NotificationRequest::BadgeStyle::LITTLE); +} + +void NotificationCenter::SetLittleIcon(const std::string& iconPath) +{ + if (access(iconPath.c_str(), F_OK) != 0) { + BATTERY_HILOGE(COMP_SVC, "iconPath[%{public}s] is invalid", iconPath.c_str()); + return; + } + uint32_t errorCode = 0; + Media::SourceOptions opts; + opts.formatHint = "image/png"; + auto imageSource = Media::ImageSource::CreateImageSource(iconPath, opts, errorCode); + if (imageSource == nullptr) { + BATTERY_HILOGE(COMP_SVC, "Failed to create ImageSource"); + return; + } + Media::DecodeOptions decodeOpts; + std::unique_ptr pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode); + request_.SetLittleIcon(std::move(pixelMap)); +} + +void NotificationCenter::SetActionButton(const std::string& buttonName, const std::string& buttonAction) +{ + if (buttonName.empty()) { + BATTERY_HILOGE(COMP_SVC, "SetActionButton buttonCfg is NULL"); + return; + } + auto want = std::make_shared(); + want->SetAction(buttonAction); + std::vector> wants; + wants.push_back(want); + std::vector flags; + flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::CONSTANT_FLAG); + AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo( + 0, AbilityRuntime::WantAgent::WantAgentConstant::OperationType::SEND_COMMON_EVENT, + flags, wants, nullptr + ); + auto wantAgentDeal = AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo); + std::shared_ptr actionButtonDeal = + Notification::NotificationActionButton::Create(nullptr, buttonName, wantAgentDeal); + request_.AddActionButton(actionButtonDeal); +} + +bool NotificationCenter::PublishNotification() +{ + ErrCode code = Notification::NotificationHelper::PublishNotification(request_); + BATTERY_HILOGI(COMP_SVC, "NotificationCenter::PublishNotification: %{public}d", static_cast(code)); + return true; +} + +bool NotificationCenter::CancelNotification() +{ + int32_t notificationId = request_.GetNotificationId(); + ErrCode code = Notification::NotificationHelper::CancelNotification(notificationId); + BATTERY_HILOGI(COMP_SVC, "NotificationCenter::CancelNotification: %{public}d", static_cast(code)); + return true; +} +} +} \ No newline at end of file diff --git a/services/native/notification/notification_center.h b/services/native/notification/notification_center.h new file mode 100644 index 0000000000000000000000000000000000000000..fcd628794d27131cdf2ccf759928ffd9a961da9f --- /dev/null +++ b/services/native/notification/notification_center.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 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 BATTERY_NOTIFICATION_CENTER_H +#define BATTERY_NOTIFICATION_CENTER_H + +#include "ibattery_notification.h" +#include "notification_helper.h" + +namespace OHOS { +namespace PowerMgr { +class NotificationCenter : public IBatteryNotification { +public: + NotificationCenter() = default; + ~NotificationCenter() override = default; + + void CreateBaseStyle(const BatteryConfig::NotificationConf& nCfg) override; + + bool PublishNotification() override; + + bool CancelNotification() override; + + void SetActionButton(const std::string& buttonName, const std::string& buttonAction) override; +protected: + void SetNotificationId(const std::string& popupName); + + void SetContent(const std::string& title, const std::string& text); + + void SetCreatorUid(); + + void SetCreatorBundleName(); + + void SetSlotType(); + + void SetInProgress(); + + void SetUnremovable(); + + void SetBadgeIconStyle(); + + void SetLittleIcon(const std::string& iconPath); + + Notification::NotificationRequest request_; +}; +} // namespace PowerMgr +} // namespace OHOS + +#endif // BATTERY_NOTIFICATION_CENTER_H \ No newline at end of file diff --git a/services/native/notification/notification_decorator.cpp b/services/native/notification/notification_decorator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b3eb6a7f3af6e313352bee1f6fd4394c1fa0e1a9 --- /dev/null +++ b/services/native/notification/notification_decorator.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024 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 "notification_decorator.h" +#include "battery_log.h" +#include "battery_srv_client.h" + +namespace { +static const std::string REVERSE_SUPER_CHARGE_OPEN = "notification.battery.reverse_super_charge_open"; +static const std::string REVERSE_SUPER_CHARGE_CLOSE = "notification.battery.reverse_super_charge_close"; +} +namespace OHOS { +namespace PowerMgr { +bool NotificationDecorator::PublishNotification() +{ + if (batteryNotification_ == nullptr) { + BATTERY_HILOGW(COMP_SVC, "batteryNotification_ is nullptr"); + return false; + } + batteryNotification_->PublishNotification(); + return true; +} + +bool NotificationDecorator::CancelNotification() +{ + if (batteryNotification_ == nullptr) { + BATTERY_HILOGW(COMP_SVC, "batteryNotification_ is nullptr"); + return false; + } + batteryNotification_->CancelNotification(); + return true; +} + +void ButtonDecorator::SetActionButton(const std::string& buttonName, const std::string& buttonAction) +{ + if (batteryNotification_ == nullptr) { + BATTERY_HILOGW(COMP_SVC, "batteryNotification_ is nullptr"); + return; + } + batteryNotification_->SetActionButton(buttonName, buttonAction); + if (buttonAction == REVERSE_SUPER_CHARGE_OPEN) { + button_ = std::make_shared(); + } else if (buttonAction == REVERSE_SUPER_CHARGE_CLOSE) { + button_ = std::make_shared(); + } + if (button_ == nullptr) { + BATTERY_HILOGW(COMP_SVC, "button_ is nullptr, buttonName[%{public}s] buttonAction[%{public}s]", + buttonName.c_str(), buttonAction.c_str()); + return; + } + button_->RegisterButtonEvent(buttonAction); +} + +void ReverseSuperChargeOpenButton::RegisterButtonEvent(const std::string& buttonAction) +{ + EventHandle onReceiveOpenModeEvent = [this](const OHOS::EventFwk::CommonEventData& data) { + this->OpenMode(); + }; + buttonCes_.AddEventHandle(buttonAction, onReceiveOpenModeEvent); + buttonCes_.RegisterCesEvent(); +} + +void ReverseSuperChargeOpenButton::OpenMode() +{ + BatterySrvClient::GetInstance().SetBatteryConfig("reverse_super_charge", "2"); + BATTERY_HILOGI(COMP_SVC, "onReceiveOpenModeEvent end"); +} + +void ReverseSuperChargeCloseButton::RegisterButtonEvent(const std::string& buttonAction) +{ + EventHandle onReceiveCloseModeEvent = [this](const OHOS::EventFwk::CommonEventData& data) { + this->CloseMode(); + }; + buttonCes_.AddEventHandle(buttonAction, onReceiveCloseModeEvent); + buttonCes_.RegisterCesEvent(); +} + +void ReverseSuperChargeCloseButton::CloseMode() +{ + BatterySrvClient::GetInstance().SetBatteryConfig("reverse_super_charge", "1"); + BATTERY_HILOGI(COMP_SVC, "onReceiveCloseModeEvent end"); +} +} +} \ No newline at end of file diff --git a/services/native/notification/notification_decorator.h b/services/native/notification/notification_decorator.h new file mode 100644 index 0000000000000000000000000000000000000000..5afaa527228858ba99da315300fc8b0f9cc8451b --- /dev/null +++ b/services/native/notification/notification_decorator.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024 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 BATTERY_NOTIFICATION_DECORATOR_H +#define BATTERY_NOTIFICATION_DECORATOR_H + +#include +#include +#include "button_event.h" +#include "notification_center.h" + +namespace OHOS { +namespace PowerMgr { +class ButtonFactory { +public: + ButtonFactory() = default; + virtual ~ButtonFactory() = default; + virtual void RegisterButtonEvent(const std::string& buttonAction); +}; +class NotificationDecorator : public IBatteryNotification { +public: + explicit NotificationDecorator(std::shared_ptr batteryNotification) + : batteryNotification_(batteryNotification) {} + ~NotificationDecorator() override = default; + bool PublishNotification() override; + bool CancelNotification() override; +protected: + std::shared_ptr batteryNotification_; +}; + +class ButtonDecorator : public NotificationDecorator { +public: + explicit ButtonDecorator(std::shared_ptr batteryNotification) + : NotificationDecorator(batteryNotification) {} + ~ButtonDecorator() override = default; + void SetActionButton(const std::string& buttonName, const std::string& buttonAction) override; +private: + std::shared_ptr button_; +}; + +class ReverseSuperChargeOpenButton : public ButtonFactory { +public: + ReverseSuperChargeOpenButton() {} + ~ReverseSuperChargeOpenButton() override + { + buttonCes_.UnRegisterCesEvent(); + } + void RegisterButtonEvent(const std::string& buttonAction) override; +private: + void OpenMode(); + ButtonCes buttonCes_; +}; + +class ReverseSuperChargeCloseButton : public ButtonFactory { +public: + ReverseSuperChargeCloseButton() {} + ~ReverseSuperChargeCloseButton() override + { + buttonCes_.UnRegisterCesEvent(); + } + void RegisterButtonEvent(const std::string& buttonAction) override; +private: + void CloseMode(); + ButtonCes buttonCes_; +}; +} // namespace PowerMgr +} // namespace OHOS + +#endif // BATTERY_NOTIFICATION_DECORATOR_H \ No newline at end of file diff --git a/services/native/notification/notification_locale.cpp b/services/native/notification/notification_locale.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ce94ca78a688e421591781ffa88f58b304cf8dcf --- /dev/null +++ b/services/native/notification/notification_locale.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2024 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 "notification_locale.h" +#include "config_policy_utils.h" +#include "locale_config.h" +#include "locale_matcher.h" +#include "battery_info.h" +#include "battery_log.h" +#include "power_common.h" + +namespace { +constexpr const char* LOCALE_CONFIG_PATH = "/system/etc/battery/resources/locale_path.json"; +constexpr const char* SYSTEM_BATTERY_RESOURCE_PATH = "/system/etc/battery/resources/"; +constexpr const char* SYSTEM_BATTERY_RESOURCEEXT_PATH = "/system/etc/battery/resourcesExt/"; +constexpr const char* ELEMENT_STRING_FILE = "/element/string.json"; +constexpr const char* DEFAULT_LANGUAGE_EN = "base"; +} + +namespace OHOS { +namespace PowerMgr { +std::shared_ptr NotificationLocale::instance_ = nullptr; +std::mutex NotificationLocale::mutex_; +NotificationLocale& NotificationLocale::GetInstance() +{ + std::lock_guard lock(mutex_); + if (instance_ == nullptr) { + instance_ = std::make_shared(); + } + return *(instance_.get()); +} + +bool NotificationLocale::ParseJsonfile(const std::string& targetPath, + std::unordered_map& container) +{ + if (access(targetPath.c_str(), F_OK) != 0) { + BATTERY_HILOGE(COMP_SVC, "targetPath %{public}s invalid", targetPath.c_str()); + return false; + } + std::ifstream inputStream(targetPath.c_str(), std::ios::in | std::ios::binary); + std::string fileStr(std::istreambuf_iterator {inputStream}, std::istreambuf_iterator {}); + Json::Reader reader; + Json::Value root; + if (!reader.parse(fileStr.data(), fileStr.data() + fileStr.size(), root)) { + BATTERY_HILOGE(COMP_SVC, "%{public}s json parse error", targetPath.c_str()); + return false; + } + if (root.isNull() || !root.isObject()) { + BATTERY_HILOGE(COMP_SVC, "%{public}s json root error", targetPath.c_str()); + return false; + } + Json::Value stringConf = root["String"]; + if (stringConf.isNull() || !stringConf.isArray()) { + BATTERY_HILOGE(COMP_SVC, "%{public}s stringConf invalid", targetPath.c_str()); + } + for (const auto& conf : stringConf) { + Json::Value nameObj = conf["name"]; + Json::Value valueObj = conf["value"]; + if (nameObj.isString() && valueObj.isString() && + !nameObj.asString().empty() && !valueObj.asString().empty()) { + container.insert(std::make_pair(nameObj.asString(), valueObj.asString())); + } + } + BATTERY_HILOGE(COMP_SVC, "%{public}s stringConf end", targetPath.c_str()); + return true; +} + +void NotificationLocale::ParseLocaleCfg() +{ + if (islanguageMapInit_) { + return; + } + languageMap_.clear(); + if (ParseJsonfile(LOCALE_CONFIG_PATH, languageMap_)) { + islanguageMapInit_ = true; + } +} + +void NotificationLocale::UpdateStringMap() +{ + OHOS::Global::I18n::LocaleInfo locale(Global::I18n::LocaleConfig::GetSystemLocale()); + std::string curBaseName = locale.GetBaseName(); + if (localeBaseName_ == curBaseName) { + return; + } + BATTERY_HILOGI(COMP_SVC, "UpdateResourceMap: change from [%{public}s] to [%{public}s]", + localeBaseName_.c_str(), curBaseName.c_str()); + localeBaseName_ = curBaseName; + std::string language = DEFAULT_LANGUAGE_EN; + if (languageMap_.find(localeBaseName_) != languageMap_.end()) { + language = languageMap_[localeBaseName_]; + } else { + for (auto& iter : languageMap_) { + OHOS::Global::I18n::LocaleInfo eachLocale(iter.first); + if (OHOS::Global::I18n::LocaleMatcher::Match(&locale, &eachLocale)) { + language = iter.second; + break; + } + } + } + stringMap_.clear(); + std::string resourcePath = SYSTEM_BATTERY_RESOURCE_PATH + language + ELEMENT_STRING_FILE; + ParseJsonfile(resourcePath, stringMap_); + resourcePath = SYSTEM_BATTERY_RESOURCEEXT_PATH + language + ELEMENT_STRING_FILE; + ParseJsonfile(resourcePath, stringMap_); +} + +std::string NotificationLocale::GetStringByKey(const std::string& key) +{ + auto iter = stringMap_.find(key); + if (iter != stringMap_.end()) { + return iter->second; + } + return ""; +} +} +} \ No newline at end of file diff --git a/services/native/notification/notification_locale.h b/services/native/notification/notification_locale.h new file mode 100644 index 0000000000000000000000000000000000000000..9aad066c3a556b67d64496c484bc5dda1e89d6eb --- /dev/null +++ b/services/native/notification/notification_locale.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024 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 BATTERY_NOTIFICATION_LOCALE_H +#define BATTERY_NOTIFICATION_LOCALE_H + +#include +#include +#include +#include +#include +#include "nocopyable.h" + +namespace OHOS { +namespace PowerMgr { +class NotificationLocale : public NoCopyable { +public: + static NotificationLocale& GetInstance(); + + void ParseLocaleCfg(); + + void UpdateStringMap(); + + std::string GetStringByKey(const std::string& key); +private: + bool ParseJsonfile(const std::string& targetPath, std::unordered_map& container); + std::unordered_map languageMap_; + std::unordered_map stringMap_; + std::string localeBaseName_; + bool islanguageMapInit_ { false }; + static std::mutex mutex_; + static std::shared_ptr instance_; +}; +} // namespace PowerMgr +} // namespace OHOS + +#endif // BATTERY_NOTIFICATION_LOCALE_H \ No newline at end of file diff --git a/services/native/notification/notification_manager.cpp b/services/native/notification/notification_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..638f7bbdbc9be7413ad01d6555a33d1a00345e7f --- /dev/null +++ b/services/native/notification/notification_manager.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2024 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 "notification_manager.h" +#include "notification_locale.h" +#include "battery_log.h" + +namespace OHOS { +namespace PowerMgr { +static const uint32_t PUBLISH_POPUP_ACTION = 0; +static const uint32_t CANCLE_POPUP_ACTION = 1; + +void NotificationManager::HandleNotification(const std::string& popupName, uint32_t popupAction, + const std::unordered_map& nConfMap) +{ + NotificationLocale::GetInstance().ParseLocaleCfg(); + NotificationLocale::GetInstance().UpdateStringMap(); + if (popupAction == PUBLISH_POPUP_ACTION) { + auto iter = nConfMap.find(popupName); + if (iter != nConfMap.end()) { + BatteryConfig::NotificationConf nCfg = FillNotificationCfg(iter->second); + PublishNotification(nCfg); + } + } else if (popupAction == CANCLE_POPUP_ACTION) { + CancleNotification(popupName); + } +} + +void NotificationManager::PublishNotification(BatteryConfig::NotificationConf& nCfg) +{ + BATTERY_HILOGI(COMP_SVC, "Satrt PublishNotification %{public}s", nCfg.GetInfo().c_str()); + std::shared_ptr batteryNotification = std::make_shared(); + if (batteryNotification == nullptr) { + BATTERY_HILOGE(COMP_SVC, "PublishNotification batteryNotification is null"); + return; + } + batteryNotification->CreateBaseStyle(nCfg); + + if (!nCfg.firstButton.first.empty()) { + batteryNotification = CreateButtonStyle(batteryNotification, nCfg.firstButton); + } + if (!nCfg.secondButton.first.empty()) { + batteryNotification = CreateButtonStyle(batteryNotification, nCfg.secondButton); + } + + if (batteryNotification == nullptr) { + BATTERY_HILOGE(COMP_SVC, "CreateButtonStyle failed"); + return; + } + batteryNotification->PublishNotification(); + std::lock_guard lock(mapMutex_); + notificationMap_.emplace(nCfg.name, batteryNotification); +} + +std::shared_ptr NotificationManager::CreateButtonStyle( + const std::shared_ptr& batteryNotification, + const std::pair& nButton) +{ + std::shared_ptr buttonWarp = nullptr; + if (batteryNotification == nullptr) { + BATTERY_HILOGE(COMP_SVC, "CreateButtonStyle:%{public}s failed", nButton.first.c_str()); + return buttonWarp; + } + buttonWarp = std::make_shared(batteryNotification); + if (buttonWarp == nullptr) { + BATTERY_HILOGE(COMP_SVC, "buttonWarp is null"); + return buttonWarp; + } + buttonWarp->SetActionButton(nButton.first, nButton.second); + return buttonWarp; +} + + +void NotificationManager::CancleNotification(const std::string& popupName) +{ + std::lock_guard lock(mapMutex_); + auto iter = notificationMap_.find(popupName); + if (iter != notificationMap_.end()) { + std::shared_ptr batteryNotification = iter->second; + if (batteryNotification != nullptr) { + batteryNotification->CancelNotification(); + } + notificationMap_.erase(popupName); + } +} + +BatteryConfig::NotificationConf NotificationManager::FillNotificationCfg(const BatteryConfig::NotificationConf& cfg) +{ + auto& localeConfig = NotificationLocale::GetInstance(); + BatteryConfig::NotificationConf temp = cfg; + temp.title = localeConfig.GetStringByKey(cfg.title); + temp.text = localeConfig.GetStringByKey(cfg.text); + temp.firstButton.first = localeConfig.GetStringByKey(cfg.firstButton.first); + temp.secondButton.first = localeConfig.GetStringByKey(cfg.secondButton.first); + return temp; +} + +extern "C" API void HandleNotification(const std::string& name, int32_t action, + const std::unordered_map& nConfMap) +{ + NotificationManager::GetInstance().HandleNotification(name, action, nConfMap); +} + +} +} \ No newline at end of file diff --git a/services/native/notification/notification_manager.h b/services/native/notification/notification_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..1520ccf982e40b32a5e247a2aa64f37cce55fb91 --- /dev/null +++ b/services/native/notification/notification_manager.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 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 BATTERY_NOTIFICATION_MANAGER_H +#define BATTERY_NOTIFICATION_MANAGER_H + +#define API __attribute__((visibility("default"))) + +#include +#include +#include +#include +#include "battery_config.h" +#include "notification_center.h" +#include "notification_decorator.h" + +namespace OHOS { +namespace PowerMgr { +class API NotificationManager { +public: + static NotificationManager& GetInstance() + { + static NotificationManager notificationMgr; + return notificationMgr; + } + void HandleNotification(const std::string& popupName, uint32_t popupAction, + const std::unordered_map& nConfMap); + void CancleNotification(const std::string& popupName); +private: + NotificationManager() = default; + virtual ~NotificationManager() = default; + void PublishNotification(BatteryConfig::NotificationConf& nCfg); + std::shared_ptr CreateButtonStyle( + const std::shared_ptr& batteryNotification, + const std::pair& nButton); + BatteryConfig::NotificationConf FillNotificationCfg(const BatteryConfig::NotificationConf& cfg); + std::mutex mapMutex_; + std::unordered_map> notificationMap_; +}; + +extern "C" API void HandleNotification(const std::string& name, int32_t action, + const std::unordered_map& nConfMap); + +} // namespace PowerMgr +} // namespace OHOS + +#endif // BATTERY_NOTIFICATION_MANAGER_H \ No newline at end of file diff --git a/services/native/resources/BUILD.gn b/services/native/resources/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..ee2f57ff32bc952effaf404c58d9ca8a75b90da6 --- /dev/null +++ b/services/native/resources/BUILD.gn @@ -0,0 +1,77 @@ +# Copyright (c) 2024 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 + +import("../../../batterymgr.gni") + +## Install locale_path.json to /system/etc/battery/resources/locale_path.json +ohos_prebuilt_etc("battery_locale_path") { + source = "locale_path.json" + relative_install_dir = "battery/resources" + part_name = "${batterymgr_native_part_name}" + subsystem_name = "powermgr" +} + +## Install base/element/string.json to /system/etc/battery/resources/base/element/string.json +ohos_prebuilt_etc("battery_notification_base") { + source = "base/element/string.json" + relative_install_dir = "battery/resources/base/element" + part_name = "${batterymgr_native_part_name}" + subsystem_name = "powermgr" +} + +## Install zh_CN/element/string.json to /system/etc/battery/resources/zh_CN/element/string.json +ohos_prebuilt_etc("battery_notification_zh_CN") { + source = "zh_CN/element/string.json" + relative_install_dir = "battery/resources/zh_CN/element" + part_name = "${batterymgr_native_part_name}" + subsystem_name = "powermgr" +} + +## Install bo_CN/element/string.json to /system/etc/battery/resources/bo_CN/element/string.json +ohos_prebuilt_etc("battery_notification_bo_CN") { + source = "bo_CN/element/string.json" + relative_install_dir = "battery/resources/bo_CN/element" + part_name = "${batterymgr_native_part_name}" + subsystem_name = "powermgr" +} + +## Install ug/element/string.json to /system/etc/battery/resources/ug/element/string.json +ohos_prebuilt_etc("battery_notification_ug") { + source = "ug/element/string.json" + relative_install_dir = "battery/resources/ug/element" + part_name = "${batterymgr_native_part_name}" + subsystem_name = "powermgr" +} + +## Install zh_HK/element/string.json to /system/etc/battery/resources/zh_HK/element/string.json +ohos_prebuilt_etc("battery_notification_zh_HK") { + source = "zh_HK/element/string.json" + relative_install_dir = "battery/resources/zh_HK/element" + part_name = "${batterymgr_native_part_name}" + subsystem_name = "powermgr" +} + +## Install zh_TW/element/string.json to /system/etc/battery/resources/zh_TW/element/string.json +ohos_prebuilt_etc("battery_notification_zh_TW") { + source = "zh_TW/element/string.json" + relative_install_dir = "battery/resources/zh_TW/element" + part_name = "${batterymgr_native_part_name}" + subsystem_name = "powermgr" +} + +## Install zz_ZX/element/string.json to /system/etc/battery/resources/zz_ZX/element/string.json +ohos_prebuilt_etc("battery_notification_zz_ZX") { + source = "zz_ZX/element/string.json" + relative_install_dir = "battery/resources/zz_ZX/element" + part_name = "${batterymgr_native_part_name}" + subsystem_name = "powermgr" +} diff --git a/services/native/resources/base/element/string.json b/services/native/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..04942a1d46cc5bd927438aaae8db06a1fa57061e --- /dev/null +++ b/services/native/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "String":[ + { + "name":"", + "value":"" + } + ] +} \ No newline at end of file diff --git a/services/native/resources/bo_CN/element/string.json b/services/native/resources/bo_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..04942a1d46cc5bd927438aaae8db06a1fa57061e --- /dev/null +++ b/services/native/resources/bo_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "String":[ + { + "name":"", + "value":"" + } + ] +} \ No newline at end of file diff --git a/services/native/resources/locale_path.json b/services/native/resources/locale_path.json new file mode 100644 index 0000000000000000000000000000000000000000..4dff61e061ba69da813a48e4a299edbf4fec20a4 --- /dev/null +++ b/services/native/resources/locale_path.json @@ -0,0 +1,32 @@ +{ + "String":[ + { + "name":"zh-Hans-CN", + "value":"zh_CN" + }, + { + "name":"en-Latn-US", + "value": "base" + }, + { + "name":"zh-Hant-HK", + "value":"zh_HK" + }, + { + "name":"zh-Hant-TW", + "value":"zh_TW" + }, + { + "name":"ug-CN", + "value":"ug" + }, + { + "name":"bo-CN", + "value":"bo_CN" + }, + { + "name":"zz-ZX", + "value":"zz_ZX" + } + ] +} \ No newline at end of file diff --git a/services/native/resources/ug/element/string.json b/services/native/resources/ug/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..04942a1d46cc5bd927438aaae8db06a1fa57061e --- /dev/null +++ b/services/native/resources/ug/element/string.json @@ -0,0 +1,8 @@ +{ + "String":[ + { + "name":"", + "value":"" + } + ] +} \ No newline at end of file diff --git a/services/native/resources/zh_CN/element/string.json b/services/native/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..04942a1d46cc5bd927438aaae8db06a1fa57061e --- /dev/null +++ b/services/native/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "String":[ + { + "name":"", + "value":"" + } + ] +} \ No newline at end of file diff --git a/services/native/resources/zh_HK/element/string.json b/services/native/resources/zh_HK/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..04942a1d46cc5bd927438aaae8db06a1fa57061e --- /dev/null +++ b/services/native/resources/zh_HK/element/string.json @@ -0,0 +1,8 @@ +{ + "String":[ + { + "name":"", + "value":"" + } + ] +} \ No newline at end of file diff --git a/services/native/resources/zh_TW/element/string.json b/services/native/resources/zh_TW/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..04942a1d46cc5bd927438aaae8db06a1fa57061e --- /dev/null +++ b/services/native/resources/zh_TW/element/string.json @@ -0,0 +1,8 @@ +{ + "String":[ + { + "name":"", + "value":"" + } + ] +} \ No newline at end of file diff --git a/services/native/resources/zz_ZX/element/string.json b/services/native/resources/zz_ZX/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..04942a1d46cc5bd927438aaae8db06a1fa57061e --- /dev/null +++ b/services/native/resources/zz_ZX/element/string.json @@ -0,0 +1,8 @@ +{ + "String":[ + { + "name":"", + "value":"" + } + ] +} \ No newline at end of file diff --git a/services/native/src/battery_config.cpp b/services/native/src/battery_config.cpp index 01b17c44aeb4d7f43e1c1298f94c2314cc53b17d..5ec6d1c5adace77eb21d6ae9f3bcdad67c040509 100644 --- a/services/native/src/battery_config.cpp +++ b/services/native/src/battery_config.cpp @@ -38,6 +38,9 @@ constexpr int32_t MAX_DEPTH = 5; constexpr int32_t MIN_DEPTH = 1; constexpr uint32_t MOVE_LEFT_16 = 16; constexpr uint32_t MOVE_LEFT_8 = 8; +constexpr int32_t FIRST_BUTTON_INDEX = 0; +constexpr int32_t SECOND_BUTTON_INDEX = 1; +constexpr int32_t MAX_BUTTON_RANGE = 2; } namespace OHOS { namespace PowerMgr { @@ -130,6 +133,8 @@ void BatteryConfig::ParseConfInner() BATTERY_HILOGD(COMP_SVC, "The battery light configuration size %{public}d", static_cast(lightConf_.size())); ParseWirelessChargerConf(); + ParsePopupConf(); + ParseNotificationConf(); } void BatteryConfig::ParseLightConf(std::string level) @@ -170,6 +175,100 @@ void BatteryConfig::ParseWirelessChargerConf() wirelessChargerEnable_ = static_cast(wirelessCharger.asInt()); } +const std::unordered_map>& BatteryConfig::GetPopupConf() const +{ + BATTERY_HILOGI(COMP_SVC, "GetPopupConf"); + return popupConfig_; +} + +void BatteryConfig::ParsePopupConf() +{ + Json::Value popupConfig = GetValue("popup"); + if (popupConfig.isNull() || !popupConfig.isObject()) { + BATTERY_HILOGW(COMP_SVC, "popupConfig invalid"); + return; + } + popupConfig_.clear(); + Json::Value::Members members = popupConfig.getMemberNames(); + for (auto iter = members.begin(); iter != members.end(); iter++) { + std::string uevent = *iter; + Json::Value valueObj = popupConfig[uevent]; + if (valueObj.isNull() || !valueObj.isArray()) { + BATTERY_HILOGW(COMP_SVC, "ueventConf invalid, key=%{public}s", uevent.c_str()); + continue; + } + std::vector popupConfVec; + for (const auto& popupObj : valueObj) { + Json::Value popupName = popupObj["name"]; + Json::Value popupAction = popupObj["action"]; + if (!popupName.isString() || !popupAction.isUInt()) { + BATTERY_HILOGW(COMP_SVC, "popupObj invalid, key=%{public}s", uevent.c_str()); + continue; + } + BatteryConfig::PopupConf popupCfg = { + .name = popupName.asString(), + .action = popupAction.asUInt() + }; + BATTERY_HILOGI(COMP_SVC, "add popupConf %{public}s, %{public}d", popupCfg.name.c_str(), popupCfg.action); + popupConfVec.emplace_back(popupCfg); + } + BATTERY_HILOGI(COMP_SVC, "popupConfVec size: %{public}d", static_cast(popupConfVec.size())); + popupConfig_.emplace(uevent, popupConfVec); + } + BATTERY_HILOGI(COMP_SVC, "popupConfVec size: %{public}d", static_cast(popupConfig_.size())); +} + +const std::unordered_map& BatteryConfig::GetNotificationConf() const +{ + return notificationConfMap_; +} + +void BatteryConfig::ParseNotificationConf() +{ + Json::Value nConf = GetValue("notification"); + if (nConf.isNull() || !nConf.isArray()) { + BATTERY_HILOGW(COMP_SVC, "nConf is invalid"); + return; + } + for (const auto& conf : nConf) { + Json::Value nameObj = conf["name"]; + Json::Value iconObj = conf["icon"]; + Json::Value titleObj = conf["title"]; + Json::Value textObj = conf["text"]; + Json::Value buttonObj = conf["button"]; + if (!nameObj.isString() || !iconObj.isString() || !titleObj.isString() + || !textObj.isString() || !buttonObj.isArray()) { + BATTERY_HILOGW(COMP_SVC, "stringConf Parse failed"); + continue; + } + if (buttonObj.size() != MAX_BUTTON_RANGE || !buttonObj[FIRST_BUTTON_INDEX].isObject() || + !buttonObj[SECOND_BUTTON_INDEX].isObject()) { + BATTERY_HILOGW(COMP_SVC, "buttonConf is invalid"); + continue; + } + Json::Value firstButtonNameObj = buttonObj[FIRST_BUTTON_INDEX]["name"]; + Json::Value firstButtonActionObj = buttonObj[FIRST_BUTTON_INDEX]["action"]; + Json::Value secondButtonNameObj = buttonObj[SECOND_BUTTON_INDEX]["name"]; + Json::Value secondButtonActionObj = buttonObj[SECOND_BUTTON_INDEX]["action"]; + if (!firstButtonNameObj.isString() || !firstButtonActionObj.isString() + || !secondButtonNameObj.isString() || !secondButtonActionObj.isString()) { + BATTERY_HILOGW(COMP_SVC, "buttonConf Parse failed"); + return; + } + std::string name = nameObj.asString(); + BatteryConfig::NotificationConf notificationConf = { + .name = name, + .icon = iconObj.asString(), + .title = titleObj.asString(), + .firstButton = std::make_pair(firstButtonNameObj.asString(), firstButtonActionObj.asString()), + .secondButton = std::make_pair(secondButtonNameObj.asString(), secondButtonActionObj.asString()) + }; + BATTERY_HILOGI(COMP_SVC, "notificationConf name: %{public}s", name.c_str()); + notificationConfMap_.emplace(name, notificationConf); + } + BATTERY_HILOGI(COMP_SVC, "notificationConf size: %{public}d", static_cast(notificationConfMap_.size())); +} + Json::Value BatteryConfig::FindConf(const std::string& key) const { return (config_.isObject() && config_.isMember(key)) ? config_[key] : Json::Value(); diff --git a/services/native/src/battery_notify.cpp b/services/native/src/battery_notify.cpp index 19d17affcc08514216c5b13552deeea7b5cee77a..92c8fe994e43c5456939fc4e7cd9e2501f62a40b 100644 --- a/services/native/src/battery_notify.cpp +++ b/services/native/src/battery_notify.cpp @@ -56,6 +56,7 @@ const std::string SHUTDOWN = "shutdown"; const std::string REBOOT = "reboot"; const std::string SEND_COMMONEVENT = "sendcommonevent"; const std::string SEND_CUSTOMEVENT = "sendcustomevent"; +const std::string SEND_POPUP = "sendpopup"; const std::string BATTERY_CUSTOM_EVENT = "usual.event.battery.custom"; const std::string BATTERY_CUSTOM_EVENT_PREFIX = "usual.event.battery"; sptr g_service = DelayedSpSingleton::GetInstance(); @@ -127,6 +128,10 @@ void BatteryNotify::HandleUevent(BatteryInfo& info) } else if (ueventAct.compare(0, BATTERY_CUSTOM_EVENT_PREFIX.size(), BATTERY_CUSTOM_EVENT_PREFIX) == 0) { info.SetUevent(ueventName); PublishCustomEvent(info, ueventAct); + } else if (ueventAct == SEND_POPUP) { + info.SetUevent(ueventName); + PublishChangedEvent(info); + HandleNotification(ueventName); } else { BATTERY_HILOGE(COMP_SVC, "undefine uevent act %{public}s", ueventAct.c_str()); } @@ -559,5 +564,42 @@ bool BatteryNotify::PublishCustomEvent(const BatteryInfo& info, const std::strin } return isSuccess; } + +bool BatteryNotify::HandleNotification(const std::string& ueventName) const +{ +#ifdef BATTERY_SUPPORT_NOTIFICATION + std::unordered_map> popupCfg = + BatteryConfig::GetInstance().GetPopupConf(); + auto iter = popupCfg.find(ueventName); + if (iter == popupCfg.end()) { + BATTERY_HILOGW(COMP_SVC, "HandleNotification not found conf: %{public}s", ueventName.c_str()); + return false; + } + typedef void(*HandleNotificationFunc)(const std::string&, int32_t, + const std::unordered_map&); + void* handler = dlopen("libbattery_notification.z.so", RTLD_LAZY | RTLD_NODELETE); + if (handler == nullptr) { + BATTERY_HILOGE(FEATURE_BATT_INFO, "dlopen HandleNotificationFunc failed, reason : %{public}s", dlerror()); + return false; + } + HandleNotificationFunc HandleNotification = + reinterpret_cast(dlsym(handler, "HandleNotification")); + if (HandleNotification == nullptr) { + BATTERY_HILOGE(FEATURE_BATT_INFO, "HandleNotificationFunc is null, reason : %{public}s", dlerror()); + dlclose(handler); + handler = nullptr; + return false; + } + auto nConfMap = BatteryConfig::GetInstance().GetNotificationConf(); + for (auto& item : iter->second) { + HandleNotification(item.name, item.action, nConfMap); + BATTERY_HILOGI(COMP_SVC, "popupName=%{public}s, popupAction=%{public}d", item.name.c_str(), item.action); + } + dlclose(handler); + handler = nullptr; +#endif + return true; +} + } // namespace PowerMgr } // namespace OHOS diff --git a/services/native/src/battery_service.cpp b/services/native/src/battery_service.cpp index 43b6e229ae96b5125ecb9e7db9b3ef83f9e57b96..ec5bde28453983b2aa4b794bbe680ce6b43848a9 100644 --- a/services/native/src/battery_service.cpp +++ b/services/native/src/battery_service.cpp @@ -457,7 +457,8 @@ BatteryError BatteryService::SetBatteryConfig(const std::string& sceneName, cons return BatteryError::ERR_SYSTEM_API_DENIED; } - BATTERY_HILOGD(FEATURE_BATT_INFO, "Enter SetBatteryConfig"); + BATTERY_HILOGI(FEATURE_BATT_INFO, "Enter SetBatteryConfig sceneName:%{public}s value:%{public}s", + sceneName.c_str(), value.c_str()); std::shared_lock lock(mutex_); if (iBatteryInterface_ == nullptr) { BATTERY_HILOGE(FEATURE_BATT_INFO, "iBatteryInterface_ is nullptr");