diff --git a/BUILD.gn b/BUILD.gn index 4eea17eb3e3502218d0a179a03fa6996ede6d872..5b21d481ff1a9a763d128f14f4fd81854de8cc84 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -34,6 +34,8 @@ ohos_shared_library("usagestatsinner") { "interfaces/innerkits/src/bundle_active_proxy.cpp", "services/packageusage/src/bundle_active_event.cpp", "services/packageusage/src/bundle_active_package_stats.cpp", + "interfaces/innerkits/src/bundle_active_group_callback_info.cpp", + "interfaces/innerkits/src/bundle_active_group_callback_proxy.cpp", ] public_configs = [ ":usagestatsinner_public_config" ] public_deps = [ ":usagestatservice" ] @@ -103,6 +105,8 @@ ohos_shared_library("usagestatservice") { "services/common/src/bundle_active_shutdown_callback_service.cpp", "services/common/src/bundle_active_shutdown_callback_stub.cpp", "services/common/src/bundle_active_stub.cpp", + "services/common/src/bundle_active_group_callback_stub.cpp", + "interfaces/innerkits/src/bundle_active_group_callback_info.cpp", "services/common/src/bundle_active_usage_database.cpp", "services/packagegroup/src/bundle_active_group_controller.cpp", "services/packagegroup/src/bundle_active_group_handler.cpp", @@ -125,6 +129,7 @@ ohos_shared_library("usagestatservice") { "services/common/include", "services/packageusage/include", "services/packagegroup/include", + "interfaces/innerkits/include", ] external_deps = [ diff --git a/interfaces/innerkits/include/bundle_active_group_callback_info.h b/interfaces/innerkits/include/bundle_active_group_callback_info.h new file mode 100644 index 0000000000000000000000000000000000000000..b774fcf624a3a3b1cfbf7c1457daafabd17b7d2a --- /dev/null +++ b/interfaces/innerkits/include/bundle_active_group_callback_info.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022 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 BUNDLE_ACTIVE_GROUP_CALLBACK_INFO_H +#define BUNDLE_ACTIVE_GROUP_CALLBACK_INFO_H + +#include +#include + +#include "parcel.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveGroupCallbackInfo : public Parcelable { +public: + BundleActiveGroupCallbackInfo() {}; + BundleActiveGroupCallbackInfo(int32_t userId, int32_t oldGroup, int32_t newGroup, uint32_t changeReason, + std::string bundleName); + + /** + * @brief Get the user id. + * + * @return The id of user. + */ + int32_t GetUserId() const; + + /** + * @brief Get the old group. + * + * @return old group of app. + */ + int32_t GetOldGroup() const; + + /** + * @brief Get the new group. + * + * @return the new group of app. + */ + int32_t GetNewGroup() const; + + /** + * @brief Get the reason of change group. + * + * @return the reason of change group. + */ + uint32_t GetChangeReason() const; + + /** + * @brief Get the name of bundle. + * + * @return The name of bundle. + */ + std::string GetBundleName() const; + + /** + * @brief Marshals a purpose into a parcel. + * + * @param parcel Indicates the parcel object for marshalling. + * @return True if success, else false. + */ + bool Marshalling(Parcel &parcel) const; + static BundleActiveGroupCallbackInfo* Unmarshalling(Parcel &parcel); + +private: + bool ReadFromParcel(Parcel &parcel); + +private: + int32_t oldGroup_ {0}; + int32_t newGroup_ {0}; + int32_t userId_ {-1}; + uint32_t changeReason_ {0}; + std::string bundleName_ {""}; +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // BUNDLE_ACTIVE_GROUP_CALLBACK_INFO_H \ No newline at end of file diff --git a/interfaces/innerkits/include/bundle_active_group_callback_proxy.h b/interfaces/innerkits/include/bundle_active_group_callback_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..9b149274cae545e78345a57b2531b4c776a94d86 --- /dev/null +++ b/interfaces/innerkits/include/bundle_active_group_callback_proxy.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 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 BUNDLE_ACTIVE_GROUP_CALLBACK_PROXY_H +#define BUNDLE_ACTIVE_GROUP_CALLBACK_PROXY_H + +#include + +#include "ibundle_active_group_callback.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveGroupCallbackProxy : public IRemoteProxy { +public: + BundleActiveGroupCallbackProxy() = delete; + explicit BundleActiveGroupCallbackProxy(const sptr& impl); + ~BundleActiveGroupCallbackProxy() override; + DISALLOW_COPY_AND_MOVE(BundleActiveGroupCallbackProxy); + + void OnBundleGroupChanged( + const BundleActiveGroupCallbackInfo& continuousTaskCallbackInfo) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // BUNDLE_ACTIVE_GROUP_CALLBACK_PROXY_H \ No newline at end of file diff --git a/interfaces/innerkits/include/bundle_active_proxy.h b/interfaces/innerkits/include/bundle_active_proxy.h index 50db119b8562420253f222480a039971aa6cc1ff..1b40493c8b555970f46fe9a9fefe98786a8a25cc 100644 --- a/interfaces/innerkits/include/bundle_active_proxy.h +++ b/interfaces/innerkits/include/bundle_active_proxy.h @@ -89,6 +89,9 @@ public: */ explicit BundleActiveProxy(const sptr& impl) : IRemoteProxy(impl) {} + + int32_t RegisterGroupCallBack(const sptr &observer) override; + int32_t UnregisterGroupCallBack(const sptr &observer) override; /* * function: ~BundleActiveProxy, default destructor. */ diff --git a/interfaces/innerkits/src/bundle_active_group_callback_info.cpp b/interfaces/innerkits/src/bundle_active_group_callback_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9e21f4cc7927ede524a1511311f4e8f72f9e9cb8 --- /dev/null +++ b/interfaces/innerkits/src/bundle_active_group_callback_info.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2022 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 "bundle_active_log.h" +#include "bundle_active_group_callback_info.h" + +namespace OHOS { +namespace DeviceUsageStats { +BundleActiveGroupCallbackInfo::BundleActiveGroupCallbackInfo(int32_t userId, int32_t oldGroup, int32_t newGroup, + uint32_t changeReason, std::string bundleName) +{ + userId_ = userId; + oldGroup_ = oldGroup; + newGroup_ = newGroup; + changeReason_ = changeReason; + bundleName_ = bundleName; +} + +int32_t BundleActiveGroupCallbackInfo::GetUserId() const +{ + return userId_; +} + +int32_t BundleActiveGroupCallbackInfo::GetOldGroup() const +{ + return oldGroup_; +} + +int32_t BundleActiveGroupCallbackInfo::GetNewGroup() const +{ + return newGroup_; +} + +uint32_t BundleActiveGroupCallbackInfo::GetChangeReason() const +{ + return changeReason_; +} + +std::string BundleActiveGroupCallbackInfo::GetBundleName() const +{ + return bundleName_; +} + +bool BundleActiveGroupCallbackInfo::Marshalling(Parcel &parcel) const +{ + if (!parcel.WriteInt32(userId_)) { + BUNDLE_ACTIVE_LOGE("Failed to write userId_"); + return false; + } + + if (!parcel.WriteInt32(oldGroup_)) { + BUNDLE_ACTIVE_LOGE("Failed to write creator oldGroup_"); + return false; + } + + if (!parcel.WriteInt32(newGroup_)) { + BUNDLE_ACTIVE_LOGE("Failed to write creator newGroup_"); + return false; + } + + if (!parcel.WriteUint32(changeReason_)) { + BUNDLE_ACTIVE_LOGE("Failed to write creator changeReason_"); + return false; + } + + if (!parcel.WriteString(bundleName_)) { + BUNDLE_ACTIVE_LOGE("Failed to write bundleName_"); + return false; + } + return true; +} + +BundleActiveGroupCallbackInfo* BundleActiveGroupCallbackInfo::Unmarshalling(Parcel &parcel) +{ + BundleActiveGroupCallbackInfo* result = new (std::nothrow) BundleActiveGroupCallbackInfo(); + result->userId_ = parcel.ReadInt32(); + result->oldGroup_ = parcel.ReadInt32(); + result->newGroup_ = parcel.ReadInt32(); + result->changeReason_ = parcel.ReadUint32(); + result->bundleName_ = parcel.ReadString(); + return result; +} +} +} + diff --git a/interfaces/innerkits/src/bundle_active_group_callback_proxy.cpp b/interfaces/innerkits/src/bundle_active_group_callback_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6d69c21d3016dba17604d3cfe9bac28607ecb6bc --- /dev/null +++ b/interfaces/innerkits/src/bundle_active_group_callback_proxy.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 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 "bundle_active_log.h" +#include "bundle_active_group_callback_proxy.h" + +namespace OHOS { +namespace DeviceUsageStats { +BundleActiveGroupCallbackProxy::BundleActiveGroupCallbackProxy(const sptr& impl) + : IRemoteProxy(impl) {} +BundleActiveGroupCallbackProxy::~BundleActiveGroupCallbackProxy() {} + +void BundleActiveGroupCallbackProxy::OnBundleGroupChanged( + const BundleActiveGroupCallbackInfo &bundleActiveGroupCallbackInfo) +{ + sptr remote = Remote(); + if (remote == nullptr) { + BUNDLE_ACTIVE_LOGE("remote is dead."); + return; + } + MessageParcel data; + if (!data.WriteInterfaceToken(BundleActiveGroupCallbackProxy::GetDescriptor())) { + BUNDLE_ACTIVE_LOGE("write interface token failed."); + return; + } + if (!data.WriteParcelable(&bundleActiveGroupCallbackInfo)) { + BUNDLE_ACTIVE_LOGE("write parcel failed."); + return; + } + MessageParcel reply; + MessageOption option = {MessageOption::TF_ASYNC}; + int32_t ret = remote->SendRequest(ON_BUNDLE_GROUP_CHANGED, data, reply, option); + if (ret!= ERR_OK) { + BUNDLE_ACTIVE_LOGE("SendRequest failed, error code: %d", ret); + } +} +} // namespace BackgroundTaskMgr +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/innerkits/src/bundle_active_proxy.cpp b/interfaces/innerkits/src/bundle_active_proxy.cpp index 43cfd63e8681295e3d7a08d577c8521bcda09e03..59ed5d9dc5910d67e21458d813f088cada4f4a38 100644 --- a/interfaces/innerkits/src/bundle_active_proxy.cpp +++ b/interfaces/innerkits/src/bundle_active_proxy.cpp @@ -242,6 +242,48 @@ int32_t BundleActiveProxy::QueryFormStatistics(int32_t maxNum, std::vector &observer) +{ + if (!observer) { + BUNDLE_ACTIVE_LOGE("observer null"); + return ERR_INVALID_VALUE; + } + BUNDLE_ACTIVE_LOGI("RegisterApplicationStateObserver start"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + return -1; + } + if (!data.WriteRemoteObject(observer->AsObject())) { + BUNDLE_ACTIVE_LOGE("observer write failed."); + return -1; + } + Remote()->SendRequest(REGISTER_GROUP_CALLBACK, data, reply, option); + return 0; +} + +int32_t BundleActiveProxy::UnregisterGroupCallBack(const sptr &observer) +{ + if (!observer) { + BUNDLE_ACTIVE_LOGE("observer null"); + return ERR_INVALID_VALUE; + } + BUNDLE_ACTIVE_LOGI("RegisterApplicationStateObserver start"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + return -1; + } + if (!data.WriteRemoteObject(observer->AsObject())) { + BUNDLE_ACTIVE_LOGE("observer write failed."); + return -1; + } + Remote()->SendRequest(UNREGISTER_GROUP_CALLBACK, data, reply, option); + return 0; +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/common/include/bundle_active_core.h b/services/common/include/bundle_active_core.h index 3c861ce114a3dc465d943d84b8c1a01a188a2cd9..8eb825d66b36de6cf284564dba74192aacdaf021 100644 --- a/services/common/include/bundle_active_core.h +++ b/services/common/include/bundle_active_core.h @@ -23,6 +23,8 @@ #include "os_account_manager.h" #endif // OS_ACCOUNT_PART_ENABLED #include "ibundle_active_service.h" +#include "remote_deatch_recipient.h" +#include "ibundle_active_group_callback.h" #include "bundle_active_debug_mode.h" #include "bundle_active_stats_update_listener.h" #include "bundle_active_user_service.h" @@ -46,7 +48,7 @@ public: class BundleActiveReportHandler; -class BundleActiveCore : public BundleActiveStatsUpdateListener { +class BundleActiveCore : public BundleActiveStatsUpdateListener, public std::enable_shared_from_this { public: BundleActiveCore(); virtual ~BundleActiveCore(); @@ -145,9 +147,15 @@ public: void UnRegisterSubscriber(); // get system time in MS. int64_t GetSystemTimeMs(); + int32_t RegisterGroupCallBack(const sptr &observer); + int32_t UnregisterGroupCallBack(const sptr &observer); int32_t currentUsedUser_; + void OnBundleGroupChanged(const BundleActiveGroupCallbackInfo& callbackInfo); private: + void AddObserverDeathRecipient(const sptr &observer); + void OnObserverDied(const wptr &remote); + void OnObserverDiedInner(const wptr &remote); int64_t flushInterval_; static const int64_t TIME_CHANGE_THRESHOLD_MILLIS = TWO_SECONDS; const int32_t DEFAULT_USER_ID = -1; @@ -159,10 +167,13 @@ private: int64_t systemTimeShot_; int64_t realTimeShot_; std::mutex mutex_; + std::mutex callbackMutex_; std::map> userStatServices_; void RegisterSubscriber(); std::shared_ptr commonEventSubscriber_; void RestoreAllData(); + std::vector> groupChangeObservers_; + std::map, sptr> recipientMap_; bool debugCore_; }; } // namespace DeviceUsageStats diff --git a/services/common/include/bundle_active_group_callback_stub.h b/services/common/include/bundle_active_group_callback_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..046d36799a4485e5d3a65506467003cca1c12702 --- /dev/null +++ b/services/common/include/bundle_active_group_callback_stub.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BUNDLE_ACTIVE_GROUP_CALLBACK_STUB_H +#define BUNDLE_ACTIVE_GROUP_CALLBACK_STUB_H + +#include +#include + +#include "iremote_stub.h" +#include "nocopyable.h" +#include "string_ex.h" +#include "app_mgr_constants.h" +#include "ibundle_active_group_callback.h" + +namespace OHOS { +namespace DeviceUsageStats { +class BundleActiveGroupCallbackStub : public IRemoteStub { +public: + BundleActiveGroupCallbackStub(); + virtual ~BundleActiveGroupCallbackStub(); + + virtual int OnRemoteRequest( + uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + + virtual void OnBundleGroupChanged( + const BundleActiveGroupCallbackInfo &bundleActiveGroupCallbackInfo) override; + +private: + static std::mutex callbackMutex_; + DISALLOW_COPY_AND_MOVE(BundleActiveGroupCallbackStub); +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // BUNDLE_ACTIVE_GROUP_CALLBACK_STUB_H diff --git a/services/common/include/bundle_active_service.h b/services/common/include/bundle_active_service.h index f72377c859bd17fdff18f8c1565b040ea9dd3c1f..43205301d7595a3df4c18f1db2bc5ca8782c03ff 100644 --- a/services/common/include/bundle_active_service.h +++ b/services/common/include/bundle_active_service.h @@ -107,6 +107,8 @@ public: * parameters: systemAbilityId, runOnCreate */ BundleActiveService(const int32_t systemAbilityId, bool runOnCreate); + int32_t RegisterGroupCallBack(const sptr &observer) override; + int32_t UnregisterGroupCallBack(const sptr &observer) override; protected: void OnStart() override; diff --git a/services/common/include/ibundle_active_group_callback.h b/services/common/include/ibundle_active_group_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..c4a9e761827d469927306d885c2ef92df2db98cf --- /dev/null +++ b/services/common/include/ibundle_active_group_callback.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 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 IBUNDLE_ACTIVE_GROUP_CALLBACK +#define IBUNDLE_ACTIVE_GROUP_CALLBACK + +#include +#include +#include + +#include "bundle_active_log.h" +#include "bundle_active_group_callback_info.h" + +namespace OHOS { +namespace DeviceUsageStats { +class IBundleActiveGroupCallback : public IRemoteBroker { +public: + IBundleActiveGroupCallback() = default; + ~IBundleActiveGroupCallback() override = default; + DISALLOW_COPY_AND_MOVE(IBundleActiveGroupCallback); + + /** + * @brief Called back when a continuous task stop. + * + * @param continuousTaskCallbackInfo Continuous task app info. + */ + virtual void OnBundleGroupChanged( + const BundleActiveGroupCallbackInfo &bundleActiveGroupCallbackInfo) = 0; +public: + DECLARE_INTERFACE_DESCRIPTOR(u"Resourceschedule.IBundleActiveGroupCallback"); + +protected: + enum InterfaceId : uint32_t { + ON_BUNDLE_GROUP_CHANGED + }; +}; +} // namespace BackgroundTaskMgr +} // namespace OHOS +#endif // FOUNDATION_RESOURCESCHEDULE_BACKGROUND_TASK_MGR_FRAMEWORKS_INCLUDE_IBACKGROUND_TASK_SUBSCRIBER_H \ No newline at end of file diff --git a/services/common/include/ibundle_active_service.h b/services/common/include/ibundle_active_service.h index 63d332c2bac2a7d65d779fb9dccf9ecdce54b91f..93a2dc78cfdacf2759e021aec3ed68f195749b7a 100644 --- a/services/common/include/ibundle_active_service.h +++ b/services/common/include/ibundle_active_service.h @@ -33,6 +33,7 @@ #include "system_ability_definition.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" +#include "ibundle_active_group_callback.h" #include "bundle_active_log.h" @@ -105,6 +106,9 @@ public: virtual int32_t QueryFormStatistics(int32_t maxNum, std::vector& results, int32_t userId) = 0; + virtual int32_t RegisterGroupCallBack(const sptr &observer) = 0; + virtual int32_t UnregisterGroupCallBack(const sptr &observer) = 0; + public: enum { REPORT_EVENT = 1, @@ -115,7 +119,9 @@ public: QUERY_CURRENT_EVENTS = 6, QUERY_BUNDLE_GROUP = 7, SET_BUNDLE_GROUP = 8, - QUERY_FORM_STATS = 9 + QUERY_FORM_STATS = 9, + REGISTER_GROUP_CALLBACK = 10, + UNREGISTER_GROUP_CALLBACK = 11 }; public: DECLARE_INTERFACE_DESCRIPTOR(u"Resourceschedule.IBundleActiveService"); diff --git a/services/common/include/remote_deatch_recipient.h b/services/common/include/remote_deatch_recipient.h new file mode 100644 index 0000000000000000000000000000000000000000..3398e220ba9b0a5cd1eb605c010fd9dfc9c33f7f --- /dev/null +++ b/services/common/include/remote_deatch_recipient.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 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 REMOTE_DEATH_RECIPIENT_H +#define REMOTE_DEATH_RECIPIENT_H + +#include + +#include "iremote_object.h" + +namespace OHOS { +namespace DeviceUsageStats { +class RemoteDeathRecipient : public IRemoteObject::DeathRecipient { +public: + explicit RemoteDeathRecipient(std::function &)> callback) + { + callback_ = callback; + } + + ~RemoteDeathRecipient() + { + callback_ = nullptr; + } + + void OnRemoteDied(const wptr &object) + { + if (callback_ != nullptr) { + callback_(object); + } + } + +private: + std::function &)> callback_; +}; +} // namespace DeviceUsageStats +} // namespace OHOS +#endif // REMOTE_DEATH_RECIPIENT_H \ No newline at end of file diff --git a/services/common/src/bundle_active_core.cpp b/services/common/src/bundle_active_core.cpp index 15dcdc5e2513361564e75f65eea31a54b1e2f95a..268445d253cb49327fb59376bf1e1d2927835ce0 100644 --- a/services/common/src/bundle_active_core.cpp +++ b/services/common/src/bundle_active_core.cpp @@ -164,7 +164,7 @@ void BundleActiveCore::InitBundleGroupController() } if (bundleGroupController_ != nullptr && bundleGroupHandler_ != nullptr) { bundleGroupHandler_->Init(bundleGroupController_); - bundleGroupController_->SetHandlerAndCreateUserHistory(bundleGroupHandler_, realTimeShot_); + bundleGroupController_->SetHandlerAndCreateUserHistory(bundleGroupHandler_, realTimeShot_, shared_from_this()); BUNDLE_ACTIVE_LOGI("Init Set group controller and handler done"); } else { return; @@ -596,6 +596,104 @@ int64_t BundleActiveCore::GetSystemTimeMs() } return static_cast(tarDate); } + +void BundleActiveCore::OnBundleGroupChanged(const BundleActiveGroupCallbackInfo& callbackInfo) +{ + std::lock_guard lock(callbackMutex_); + for (const auto &observer : groupChangeObservers_) { + if (observer != nullptr) { + observer->OnBundleGroupChanged(callbackInfo); + } + } +} + +int32_t BundleActiveCore::RegisterGroupCallBack(const sptr &observer) +{ + std::lock_guard lock(callbackMutex_); + if (observer == nullptr) { + BUNDLE_ACTIVE_LOGE("observer is null, return"); + return -1; + } + for (int i = 0; i < (int)groupChangeObservers_.size(); i++) { + if (groupChangeObservers_[i]->AsObject() == observer->AsObject()) { + BUNDLE_ACTIVE_LOGE("observer exist, return"); + return -1; + } + } + groupChangeObservers_.emplace_back(observer); + BUNDLE_ACTIVE_LOGI("observers number is %{public}d", static_cast(groupChangeObservers_.size())); + return 0; +} + +int32_t BundleActiveCore::UnregisterGroupCallBack(const sptr &observer) +{ + BUNDLE_ACTIVE_LOGI("begin"); + auto observerIter = groupChangeObservers_.begin(); + while (observerIter != groupChangeObservers_.end()) { + if ((*observerIter)->AsObject() == observer->AsObject()) { + observerIter = groupChangeObservers_.erase(observerIter); + } else { + observerIter++; + } + } + if (observer->AsObject() == nullptr) { + return -1; + } + auto iter = recipientMap_.find(observer->AsObject()); + if (iter != recipientMap_.end()) { + iter->first->RemoveDeathRecipient(iter->second); + recipientMap_.erase(iter); + } + BUNDLE_ACTIVE_LOGI("end"); + return 0; +} + +void BundleActiveCore::AddObserverDeathRecipient(const sptr &observer) +{ + if (observer == nullptr || observer->AsObject() == nullptr) { + BUNDLE_ACTIVE_LOGE("observer nullptr."); + return; + } + auto remoteObj = observer->AsObject(); + auto it = recipientMap_.find(observer->AsObject()); + if (it != recipientMap_.end()) { + BUNDLE_ACTIVE_LOGE("This death recipient has been added."); + return; + } else { + sptr deathRecipient = new (std::nothrow) RemoteDeathRecipient( + [this](const wptr &remote) { this->OnObserverDied(remote); }); + observer->AsObject()->AddDeathRecipient(deathRecipient); + recipientMap_.emplace(observer->AsObject(), deathRecipient); + } +} + +void BundleActiveCore::OnObserverDied(const wptr &remote) +{ + if (remote == nullptr) { + BUNDLE_ACTIVE_LOGE("remote object is null."); + return; + } + + bundleGroupHandler_->PostSyncTask([this, &remote]() { this->OnObserverDiedInner(remote); }); +} + +void BundleActiveCore::OnObserverDiedInner(const wptr &remote) +{ + sptr objectProxy = remote.promote(); + if (!objectProxy) { + BUNDLE_ACTIVE_LOGE("get remote object failed"); + return; + } + auto iter = groupChangeObservers_.begin(); + while (iter != groupChangeObservers_.end()) { + if ((*iter)->AsObject() == objectProxy) { + iter = groupChangeObservers_.erase(iter); + } else { + iter++; + } + } + recipientMap_.erase(objectProxy); +} } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/common/src/bundle_active_group_callback_stub.cpp b/services/common/src/bundle_active_group_callback_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dcb2d1b8c21162e455f90acf18726e8d057beddf --- /dev/null +++ b/services/common/src/bundle_active_group_callback_stub.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 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 "bundle_active_group_callback_stub.h" + +namespace OHOS { +namespace DeviceUsageStats { +std::mutex BundleActiveGroupCallbackStub::callbackMutex_; +int32_t BundleActiveGroupCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel &reply, + MessageOption &option) +{ + std::u16string descriptor = BundleActiveGroupCallbackStub::GetDescriptor(); + std::u16string remoteDescriptor = data.ReadInterfaceToken(); + if (descriptor != remoteDescriptor) { + BUNDLE_ACTIVE_LOGE("BundleActiveGroupCallbackStub::OnRemoteRequest cannot get power mgr service"); + return -1; + } + switch (code) { + case IBundleActiveGroupCallback::ON_BUNDLE_GROUP_CHANGED: { + BundleActiveGroupCallbackInfo* groupInfo = nullptr; + std::unique_lock lock(callbackMutex_); + groupInfo = data.ReadParcelable(); + if (!groupInfo) { + BUNDLE_ACTIVE_LOGE("ReadParcelable failed"); + return -1; + } + OnBundleGroupChanged(*groupInfo); + delete groupInfo; + break; + } + default: + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + return 0; +} + +void BundleActiveGroupCallbackStub::OnBundleGroupChanged( + const BundleActiveGroupCallbackInfo &bundleActiveGroupCallbackInfo) +{ + +} +} // namespace DeviceUsageStats +} // namespace OHOS + diff --git a/services/common/src/bundle_active_service.cpp b/services/common/src/bundle_active_service.cpp index 2a08c867fcdcceda879bfa01e462e7cdd495e10b..c16097eca05218f71b2cbead179cd475d29f0c08 100644 --- a/services/common/src/bundle_active_service.cpp +++ b/services/common/src/bundle_active_service.cpp @@ -413,6 +413,24 @@ int32_t BundleActiveService::QueryPackageGroup() return result; } +int32_t BundleActiveService::RegisterGroupCallBack(const sptr &observer) +{ + if (bundleActiveCore_ == nullptr) { + return -1; + } + bundleActiveCore_->RegisterGroupCallBack(observer); + return 0; +} + +int32_t BundleActiveService::UnregisterGroupCallBack(const sptr &observer) +{ + if (bundleActiveCore_ == nullptr) { + return -1; + } + bundleActiveCore_->UnregisterGroupCallBack(observer); + return 0; +} + bool BundleActiveService::GetBundleMgrProxy() { if (!sptrBundleMgr_) { diff --git a/services/common/src/bundle_active_stub.cpp b/services/common/src/bundle_active_stub.cpp index ad5037cd8e4eb7371c9c42f8a929d51185d407fe..15d47bf1115b87f62540a64e5c11b4d303a27db2 100644 --- a/services/common/src/bundle_active_stub.cpp +++ b/services/common/src/bundle_active_stub.cpp @@ -142,6 +142,16 @@ int32_t BundleActiveStub::OnRemoteRequest(uint32_t code, MessageParcel& data, Me } return size == 0; } + case REGISTER_GROUP_CALLBACK: { + auto observer = iface_cast(data.ReadRemoteObject()); + int32_t result = RegisterGroupCallBack(observer); + return result; + } + case UNREGISTER_GROUP_CALLBACK: { + auto observer = iface_cast(data.ReadRemoteObject()); + int32_t result = UnregisterGroupCallBack(observer); + return result; + } default: return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } diff --git a/services/packagegroup/include/bundle_active_group_controller.h b/services/packagegroup/include/bundle_active_group_controller.h index 0f534cdf13728234520493df19d02132858464eb..5e645eb56f20614fb339028bda24739a89638430 100644 --- a/services/packagegroup/include/bundle_active_group_controller.h +++ b/services/packagegroup/include/bundle_active_group_controller.h @@ -32,7 +32,6 @@ namespace DeviceUsageStats { using namespace DeviceUsageStatsGroupConst; class BundleActiveGroupHandler; - class BundleActiveGroupController { public: using PowerMgrClient = OHOS::PowerMgr::PowerMgrClient; @@ -55,7 +54,7 @@ public: ~BundleActiveGroupController() {} std::shared_ptr bundleUserHistory_; void SetHandlerAndCreateUserHistory(const std::shared_ptr& groupHandler, - const int64_t bootFromTimeStamp); + const int64_t bootFromTimeStamp, const std::shared_ptr& bundleActiveCore); void ReportEvent(const BundleActiveEvent& event, const int64_t bootBasedTimeStamp, const int32_t userId); void CheckAndUpdateGroup(const std::string& bundleName, const int32_t userId, const int64_t bootBasedTimeStamp); bool CheckEachBundleState(const int32_t userId); diff --git a/services/packagegroup/include/bundle_active_user_history.h b/services/packagegroup/include/bundle_active_user_history.h index 7279324e89387bfa9e657d1b4424b2e2704f6c56..0c966cade72c65375d24a813ca427ebe308ab825 100644 --- a/services/packagegroup/include/bundle_active_user_history.h +++ b/services/packagegroup/include/bundle_active_user_history.h @@ -27,6 +27,7 @@ namespace OHOS { namespace DeviceUsageStats { using namespace DeviceUsageStatsGroupConst; +class BundleActiveCore; class BundleActiveUserHistory { public: @@ -36,7 +37,8 @@ public: int64_t screenOnTimeStamp_; int64_t ScreenOnDuration_; BundleActiveUsageDatabase database_; - BundleActiveUserHistory(const int64_t bootBasedTimeStamp); + BundleActiveUserHistory(const int64_t bootBasedTimeStamp, + const std::shared_ptr& bundleActiveCore); std::shared_ptr GetUsageHistoryForBundle(const std::string& bundleName, const int32_t userId, const int64_t bootBasedTimeStamp, const bool& create); std::shared_ptr>> GetUserHistory( @@ -48,7 +50,7 @@ public: int64_t GetScreenOnTimeStamp(int64_t bootBasedTimeStamp); void ReportUsage(std::shared_ptr oneBundleUsageHistory, const std::string& bundleName, const int32_t newGroup, const uint32_t groupReason, const int64_t bootBasedTimeStamp, - const int64_t timeUntilNextCheck); + const int64_t timeUntilNextCheck, const int32_t userId); void SetBundleGroup(const std::string& bundleName, const int32_t userId, const int64_t bootBasedTimeStamp, int32_t newGroup, uint32_t groupReason, const bool& resetTimeout); int32_t GetLevelIndex(const std::string& bundleName, const int32_t userId, const int64_t bootBasedTimeStamp, @@ -62,6 +64,7 @@ public: private: bool isScreenOn_; + std::weak_ptr bundleActiveCore_; }; } // namespace DeviceUsageStats } // namespace OHOS diff --git a/services/packagegroup/src/bundle_active_group_controller.cpp b/services/packagegroup/src/bundle_active_group_controller.cpp index 119dd4750e043e48a840d64159095d2afbb9a115..e0ea8be82d7ed8cb94c23ddd1d973d8645b166d3 100644 --- a/services/packagegroup/src/bundle_active_group_controller.cpp +++ b/services/packagegroup/src/bundle_active_group_controller.cpp @@ -81,12 +81,13 @@ void BundleActiveGroupController::OnScreenChanged(const bool& isScreenOn, const } void BundleActiveGroupController::SetHandlerAndCreateUserHistory( - const std::shared_ptr& groupHandler, const int64_t bootFromTimeStamp) + const std::shared_ptr& groupHandler, const int64_t bootFromTimeStamp, + const std::shared_ptr& bundleActiveCore) { if (bundleUserHistory_ == nullptr) { BUNDLE_ACTIVE_LOGI("SetHandlerAndCreateUserHistory bundleUserHistory_ is null, " "called constructor, bootstamp is %{public}lld", (long long)bootFromTimeStamp); - bundleUserHistory_ = std::make_shared(bootFromTimeStamp); + bundleUserHistory_ = std::make_shared(bootFromTimeStamp, bundleActiveCore); } OnScreenChanged(IsScreenOn(), bootFromTimeStamp); activeGroupHandler_ = groupHandler; @@ -242,17 +243,17 @@ void BundleActiveGroupController::ReportEvent(const BundleActiveEvent& event, co switch (eventId) { case BundleActiveEvent::NOTIFICATION_SEEN: bundleUserHistory_->ReportUsage(bundleUsageHistory, event.bundleName_, ACTIVE_GROUP_DAILY, - eventReason, 0, bootBasedTimeStamp + timeoutForNotifySeen_); + eventReason, 0, bootBasedTimeStamp + timeoutForNotifySeen_, userId); timeUntilNextCheck = timeoutForNotifySeen_; break; case BundleActiveEvent::SYSTEM_INTERACTIVE: bundleUserHistory_->ReportUsage(bundleUsageHistory, event.bundleName_, ACTIVE_GROUP_ALIVE, - eventReason, 0, bootBasedTimeStamp + timeoutForSystemInteraction_); + eventReason, 0, bootBasedTimeStamp + timeoutForSystemInteraction_, userId); timeUntilNextCheck = timeoutForSystemInteraction_; break; default: bundleUserHistory_->ReportUsage(bundleUsageHistory, event.bundleName_, ACTIVE_GROUP_ALIVE, - eventReason, bootBasedTimeStamp, bootBasedTimeStamp + timeoutForDirectlyUse_); + eventReason, bootBasedTimeStamp, bootBasedTimeStamp + timeoutForDirectlyUse_, userId); timeUntilNextCheck = timeoutForDirectlyUse_; break; } diff --git a/services/packagegroup/src/bundle_active_user_history.cpp b/services/packagegroup/src/bundle_active_user_history.cpp index 42175f3334adf2ab90fa5f639c72761ea113b8d3..c26bce137354da0211bd5003a9d2b5bce11438f5 100644 --- a/services/packagegroup/src/bundle_active_user_history.cpp +++ b/services/packagegroup/src/bundle_active_user_history.cpp @@ -16,6 +16,8 @@ #include "bundle_active_user_history.h" #include "bundle_active_group_common.h" #include "bundle_active_constant.h" +#include "bundle_active_core.h" +#include "bundle_active_group_callback_info.h" namespace OHOS { namespace DeviceUsageStats { @@ -56,7 +58,8 @@ void BundleActiveUserHistory::OnBundleUninstalled(const int32_t userId, const st database_.OnPackageUninstalled(userId, bundleName); } -BundleActiveUserHistory::BundleActiveUserHistory(const int64_t bootBasedTimeStamp) +BundleActiveUserHistory::BundleActiveUserHistory(const int64_t bootBasedTimeStamp, + const std::shared_ptr& bundleActiveCore) { bootBasedTimeStamp_ = bootBasedTimeStamp; screenOnTimeStamp_ = bootBasedTimeStamp; @@ -65,6 +68,9 @@ BundleActiveUserHistory::BundleActiveUserHistory(const int64_t bootBasedTimeStam bootBasedDuration_ = bootAndScreenOnDuraton.first; ScreenOnDuration_ = bootAndScreenOnDuraton.second; isScreenOn_ = false; + if (bundleActiveCore) { + bundleActiveCore_ = bundleActiveCore; + } } int32_t BundleActiveUserHistory::GetLevelIndex(const string& bundleName, const int32_t userId, @@ -162,7 +168,7 @@ shared_ptr BundleActiveUserHistory::GetUsageHistoryF void BundleActiveUserHistory::ReportUsage(shared_ptr oneBundleUsageHistory, const string& bundleName, const int32_t newGroup, const uint32_t groupReason, const int64_t bootBasedTimeStamp, - const int64_t timeUntilNextCheck) + const int64_t timeUntilNextCheck, const int32_t userId) { if (timeUntilNextCheck > bootBasedTimeStamp) { int64_t nextCheckTimeStamp = bootBasedDuration_ + (timeUntilNextCheck - bootBasedTimeStamp_); @@ -181,11 +187,16 @@ void BundleActiveUserHistory::ReportUsage(shared_ptr (bootBasedTimeStamp - bootBasedTimeStamp_); oneBundleUsageHistory->lastScreenUsedTimeStamp_ = GetScreenOnTimeStamp(bootBasedTimeStamp); } + int32_t oldGroup = oneBundleUsageHistory->currentGroup_; if (oneBundleUsageHistory->currentGroup_ > newGroup) { oneBundleUsageHistory->currentGroup_ = newGroup; } oneBundleUsageHistory->reasonInGroup_ = GROUP_CONTROL_REASON_USAGE | groupReason; oneBundleUsageHistory->isChanged_ = true; + BundleActiveGroupCallbackInfo callbackInfo(userId, oldGroup, newGroup, oneBundleUsageHistory->reasonInGroup_, bundleName); + if (!bundleActiveCore_.expired()) { + bundleActiveCore_.lock()->OnBundleGroupChanged(callbackInfo); + } } void BundleActiveUserHistory::SetBundleGroup(const string& bundleName, const int32_t userId, @@ -206,6 +217,7 @@ void BundleActiveUserHistory::SetBundleGroup(const string& bundleName, const int BUNDLE_ACTIVE_LOGI("%{public}s group and reason is same as before, not update", bundleName.c_str()); return; } + int32_t oldGroup = oneBundleHistory->currentGroup_; oneBundleHistory->currentGroup_ = newGroup; oneBundleHistory->reasonInGroup_ = groupReason; int64_t setTimeStamp = GetBootBasedTimeStamp(bootBasedTimeStamp); @@ -214,6 +226,10 @@ void BundleActiveUserHistory::SetBundleGroup(const string& bundleName, const int oneBundleHistory->bundleDailyTimeoutTimeStamp_ = setTimeStamp; } oneBundleHistory->isChanged_ = true; + BundleActiveGroupCallbackInfo callbackInfo(userId, oldGroup, newGroup, oneBundleHistory->reasonInGroup_, bundleName); + if (!bundleActiveCore_.expired()) { + bundleActiveCore_.lock()->OnBundleGroupChanged(callbackInfo); + } } void BundleActiveUserHistory::UpdateBootBasedAndScreenTime(const bool& isScreenOn, const int64_t bootBasedTimeStamp,