1 /*
2 * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "notification_clone_bundle_service.h"
17
18 #include "ans_log_wrapper.h"
19 #include "notification_preferences.h"
20 #include "notification_clone_util.h"
21 #include "notification_clone_bundle_info.h"
22 #include "os_account_manager_helper.h"
23
24 namespace OHOS {
25 namespace Notification {
GetInstance()26 std::shared_ptr<NotificationCloneBundle> NotificationCloneBundle::GetInstance()
27 {
28 static std::shared_ptr<NotificationCloneBundle> instance =
29 std::make_shared<NotificationCloneBundle>();
30 return instance;
31 }
32
NotificationCloneBundle()33 NotificationCloneBundle::NotificationCloneBundle()
34 {
35 cloneBundleQueue_ = std::make_shared<ffrt::queue>("NotificationCloneBundleQueue");
36 if (!cloneBundleQueue_) {
37 ANS_LOGE("ffrt create failed!");
38 return;
39 }
40 }
41
~NotificationCloneBundle()42 NotificationCloneBundle::~NotificationCloneBundle()
43 {
44 }
45
OnBackup(nlohmann::json & jsonObject)46 ErrCode NotificationCloneBundle::OnBackup(nlohmann::json &jsonObject)
47 {
48 ANS_LOGI("Notification bundle backup.");
49 int32_t userId = NotificationCloneUtil::GetActiveUserId();
50 std::vector<NotificationCloneBundleInfo> cloneBundles;
51 NotificationPreferences::GetInstance()->GetAllCLoneBundlesInfo(userId, cloneBundles);
52
53 if (cloneBundles.empty()) {
54 ANS_LOGI("Notification bundle list is empty.");
55 return ERR_OK;
56 }
57 jsonObject = nlohmann::json::array();
58 for (size_t index = 0; index < cloneBundles.size(); index++) {
59 nlohmann::json jsonNode;
60 cloneBundles[index].ToJson(jsonNode);
61 jsonObject.emplace_back(jsonNode);
62 ANS_LOGD("Event bundle backup %{public}s.", cloneBundles[index].Dump().c_str());
63 }
64 ANS_LOGD("Notification bundle list %{public}s", jsonObject.dump().c_str());
65 return ERR_OK;
66 }
67
OnRestore(const nlohmann::json & jsonObject)68 void NotificationCloneBundle::OnRestore(const nlohmann::json &jsonObject)
69 {
70 ANS_LOGI("Notification bundle list on restore.");
71 if (jsonObject.is_null() || !jsonObject.is_array()) {
72 ANS_LOGI("Notification disturb profile list is null or not array.");
73 return;
74 }
75
76 int32_t userId = NotificationCloneUtil::GetActiveUserId();
77 std::unique_lock lock(lock_);
78 bundlesInfo_.clear();
79 for (const auto &profile : jsonObject) {
80 NotificationCloneBundleInfo cloneBundleInfo;;
81 cloneBundleInfo.FromJson(profile);
82 bundlesInfo_.emplace_back(cloneBundleInfo);
83 }
84 ANS_LOGI("Notification bundle list size %{public}zu.", bundlesInfo_.size());
85 if (cloneBundleQueue_ == nullptr || bundlesInfo_.empty()) {
86 ANS_LOGE("Clone bundle is invalidated or empty.");
87 return;
88 }
89
90 for (auto bundle = bundlesInfo_.begin(); bundle != bundlesInfo_.end();) {
91 int32_t uid = NotificationCloneUtil::GetBundleUid(bundle->GetBundleName(),
92 userId, bundle->GetAppIndex());
93 if (uid == -1) {
94 bundle++;
95 continue;
96 }
97 bundle->SetUid(uid);
98 NotificationPreferences::GetInstance()->UpdateCloneBundleInfo(userId, *bundle);
99 bundle = bundlesInfo_.erase(bundle);
100 }
101
102 for (auto bundle = bundlesInfo_.begin(); bundle != bundlesInfo_.end(); bundle++) {
103 ANS_LOGI("Event bundle left %{public}s.", bundle->Dump().c_str());
104 }
105 ANS_LOGI("Notification bundle list on restore end.");
106 }
107
OnBundleDataAdd(const sptr<NotificationBundleOption> & bundleOption)108 void NotificationCloneBundle::OnBundleDataAdd(const sptr<NotificationBundleOption> &bundleOption)
109 {
110 HandleBundleEvent(bundleOption->GetBundleName(), bundleOption->GetAppIndex(), bundleOption->GetUid());
111 }
112
OnBundleDataUpdate(const sptr<NotificationBundleOption> & bundleOption)113 void NotificationCloneBundle::OnBundleDataUpdate(const sptr<NotificationBundleOption> &bundleOption)
114 {
115 HandleBundleEvent(bundleOption->GetBundleName(), bundleOption->GetAppIndex(), bundleOption->GetUid());
116 }
117
HandleBundleEvent(const std::string bundleName,int32_t appIndex,int32_t uid)118 void NotificationCloneBundle::HandleBundleEvent(const std::string bundleName, int32_t appIndex, int32_t uid)
119 {
120 ANS_LOGI("Handle bundle event %{public}s %{public}d %{public}d %{public}zu.",
121 bundleName.c_str(), appIndex, uid, bundlesInfo_.size());
122 if (bundlesInfo_.empty()) {
123 return;
124 }
125
126 int32_t userId = -1;
127 OsAccountManagerHelper::GetInstance().GetOsAccountLocalIdFromUid(uid, userId);
128 std::unique_lock lcck(lock_);
129 for (auto bundle = bundlesInfo_.begin(); bundle != bundlesInfo_.end();) {
130 if (bundle->GetBundleName() == bundleName && bundle->GetAppIndex() == appIndex) {
131 bundle->SetUid(uid);
132 NotificationPreferences::GetInstance()->UpdateCloneBundleInfo(userId, *bundle);
133 bundle = bundlesInfo_.erase(bundle);
134 break;
135 }
136 bundle++;
137 }
138 ANS_LOGI("Event bundle left %{public}zu.", bundlesInfo_.size());
139 }
140
OnUserSwitch(int32_t userId)141 void NotificationCloneBundle::OnUserSwitch(int32_t userId)
142 {
143 ANS_LOGI("Handler user switch %{public}d", userId);
144 if (cloneBundleQueue_ == nullptr) {
145 ANS_LOGW("Clone bundle queue is null.");
146 return;
147 }
148 cloneBundleQueue_->submit_h(std::bind([&]() {
149 std::unique_lock lock(lock_);
150 bundlesInfo_.clear();
151 }));
152 }
153
154 }
155 }
156