1 /*
2 * Copyright (c) 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 "clipboard_policy_plugin.h"
17
18 #include "cJSON.h"
19 #include "edm_bundle_manager_impl.h"
20 #include "edm_ipc_interface_code.h"
21 #include "iplugin_manager.h"
22 #include "pasteboard_client.h"
23
24 namespace OHOS {
25 namespace EDM {
26 const bool REGISTER_RESULT = IPluginManager::GetInstance()->AddPlugin(ClipboardPolicyPlugin::GetPlugin());
27 const int32_t MAX_PASTEBOARD_POLICY_NUM = 100;
28
InitPlugin(std::shared_ptr<IPluginTemplate<ClipboardPolicyPlugin,std::map<int32_t,ClipboardInfo>>> ptr)29 void ClipboardPolicyPlugin::InitPlugin(
30 std::shared_ptr<IPluginTemplate<ClipboardPolicyPlugin, std::map<int32_t, ClipboardInfo>>> ptr)
31 {
32 EDMLOGI("ClipboardPolicyPlugin InitPlugin...");
33 ptr->InitAttribute(EdmInterfaceCode::CLIPBOARD_POLICY,
34 "clipboard_policy", EdmPermission::PERMISSION_ENTERPRISE_MANAGE_SECURITY,
35 IPlugin::PermissionType::SUPER_DEVICE_ADMIN, true);
36 ptr->SetSerializer(ClipboardSerializer::GetInstance());
37 ptr->SetOnHandlePolicyListener(&ClipboardPolicyPlugin::OnSetPolicy, FuncOperateType::SET);
38 ptr->SetOnAdminRemoveListener(&ClipboardPolicyPlugin::OnAdminRemove);
39 }
40
OnSetPolicy(std::map<int32_t,ClipboardInfo> & data,std::map<int32_t,ClipboardInfo> & currentData,std::map<int32_t,ClipboardInfo> & mergeData,int32_t userId)41 ErrCode ClipboardPolicyPlugin::OnSetPolicy(std::map<int32_t, ClipboardInfo> &data,
42 std::map<int32_t, ClipboardInfo> ¤tData, std::map<int32_t, ClipboardInfo> &mergeData, int32_t userId)
43 {
44 EDMLOGI("ClipboardPolicyPlugin OnSetPolicy.");
45 if (data.empty()) {
46 EDMLOGD("ClipboardPolicyPlugin data is empty.");
47 return EdmReturnErrCode::PARAM_ERROR;
48 }
49 std::map<int32_t, ClipboardInfo> afterHandle = currentData;
50 auto it = data.begin();
51 ErrCode ret;
52 if (it->second.policy == ClipboardPolicy::UNKNOWN) {
53 EDMLOGE("OnSetPolicy ClipboardPolicy is UNKNOWN.");
54 return EdmReturnErrCode::PARAM_ERROR;
55 }
56 if (it->second.policy == ClipboardPolicy::DEFAULT) {
57 ret = DeleteHandle(data, afterHandle);
58 } else {
59 ret = UpdateHandle(data, afterHandle);
60 }
61 if (ret != ERR_OK) {
62 EDMLOGE("OnSetPolicy ClipboardPolicy PARAM_ERROR.");
63 return EdmReturnErrCode::PARAM_ERROR;
64 }
65 it = data.begin();
66 std::map<int32_t, ClipboardInfo> afterMerge = mergeData;
67 for (const auto& pair : afterHandle) {
68 if (afterMerge.find(pair.first) == afterMerge.end() ||
69 static_cast<int32_t>(pair.second.policy) < static_cast<int32_t>(afterMerge[pair.first].policy)) {
70 afterMerge[pair.first] = pair.second;
71 }
72 }
73 if (afterMerge.size() > MAX_PASTEBOARD_POLICY_NUM) {
74 return EdmReturnErrCode::PARAM_ERROR;
75 }
76 if (mergeData.find(it->first) != mergeData.end()) {
77 data[it->first] = afterMerge[it->first];
78 }
79 if (FAILED(HandlePasteboardPolicy(data))) {
80 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
81 }
82 currentData = afterHandle;
83 mergeData = afterMerge;
84 return ERR_OK;
85 }
86
DeleteHandle(std::map<int32_t,ClipboardInfo> & data,std::map<int32_t,ClipboardInfo> & afterHandle)87 ErrCode ClipboardPolicyPlugin::DeleteHandle(std::map<int32_t, ClipboardInfo> &data,
88 std::map<int32_t, ClipboardInfo> &afterHandle)
89 {
90 auto it = data.begin();
91 ClipboardInfo info = it->second;
92 int32_t tokenId = it->first;
93 if (it->first == 0) {
94 for (const auto& pair: afterHandle) {
95 if (pair.second.userId == (it->second).userId && pair.second.bundleName == (it->second).bundleName) {
96 tokenId = pair.first;
97 }
98 }
99 if (tokenId == 0) {
100 auto bundleMgr = std::make_shared<EdmBundleManagerImpl>();
101 tokenId = bundleMgr->GetTokenId((it->second).bundleName, (it->second).userId);
102 }
103 data.erase(it->first);
104 data.insert(std::make_pair(tokenId, info));
105 }
106 afterHandle.erase(tokenId);
107 return ERR_OK;
108 }
109
UpdateHandle(std::map<int32_t,ClipboardInfo> & data,std::map<int32_t,ClipboardInfo> & afterHandle)110 ErrCode ClipboardPolicyPlugin::UpdateHandle(std::map<int32_t, ClipboardInfo> &data, std::map<int32_t,
111 ClipboardInfo> &afterHandle)
112 {
113 auto it = data.begin();
114 ClipboardInfo info = it->second;
115 if (it->first == 0) {
116 auto bundleMgr = std::make_shared<EdmBundleManagerImpl>();
117 int32_t tokenId = bundleMgr->GetTokenId((it->second).bundleName, (it->second).userId);
118 if (tokenId == 0) {
119 return EdmReturnErrCode::PARAM_ERROR;
120 }
121 info = it->second;
122 data.erase(it);
123 data.insert(std::make_pair(tokenId, info));
124 it = data.begin();
125 } else {
126 auto iter = afterHandle.find(it->first);
127 if (iter != afterHandle.end()) {
128 info = {(it->second).policy, (iter->second).userId, (iter->second).bundleName};
129 }
130 }
131 afterHandle[it->first] = info;
132 return ERR_OK;
133 }
134
OnAdminRemove(const std::string & adminName,std::map<int32_t,ClipboardInfo> & data,std::map<int32_t,ClipboardInfo> & mergeData,int32_t userId)135 ErrCode ClipboardPolicyPlugin::OnAdminRemove(const std::string &adminName,
136 std::map<int32_t, ClipboardInfo> &data, std::map<int32_t, ClipboardInfo> &mergeData, int32_t userId)
137 {
138 EDMLOGI("ClipboardPolicyPlugin OnAdminRemove.");
139 for (auto &iter : data) {
140 if (mergeData.find(iter.first) != mergeData.end()) {
141 data[iter.first] = mergeData[iter.first];
142 } else {
143 ClipboardInfo info = {ClipboardPolicy::DEFAULT, -1, ""};
144 data[iter.first] = info;
145 }
146 EDMLOGI("ClipboardPolicyPlugin HandlePasteboardPolicy.%{public}d, %{public}d", iter.first,
147 static_cast<int32_t>(data[iter.first].policy));
148 }
149 return HandlePasteboardPolicy(data);
150 }
151
HandlePasteboardPolicy(std::map<int32_t,ClipboardInfo> & data)152 ErrCode ClipboardPolicyPlugin::HandlePasteboardPolicy(std::map<int32_t, ClipboardInfo> &data)
153 {
154 EDMLOGI("ClipboardUtils handlePasteboardPolicy.");
155 auto pasteboardClient = MiscServices::PasteboardClient::GetInstance();
156 if (pasteboardClient == nullptr) {
157 EDMLOGE("HandlePasteboardPolicy PasteboardClient null");
158 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
159 }
160 std::map<uint32_t, MiscServices::ShareOption> setMap;
161 std::vector<uint32_t> removeVector;
162 for (const auto &item : data) {
163 switch (item.second.policy) {
164 case ClipboardPolicy::DEFAULT:
165 removeVector.emplace_back(item.first);
166 break;
167 case ClipboardPolicy::IN_APP:
168 setMap.insert(std::make_pair(item.first, MiscServices::ShareOption::InApp));
169 break;
170 case ClipboardPolicy::LOCAL_DEVICE:
171 setMap.insert(std::make_pair(item.first, MiscServices::ShareOption::LocalDevice));
172 break;
173 case ClipboardPolicy::CROSS_DEVICE:
174 setMap.insert(std::make_pair(item.first, MiscServices::ShareOption::CrossDevice));
175 break;
176 default:
177 break;
178 }
179 }
180 ErrCode setRet = ERR_OK;
181 ErrCode rmRet = ERR_OK;
182 if (!setMap.empty()) {
183 setRet = pasteboardClient->SetGlobalShareOption(setMap);
184 }
185 if (!removeVector.empty()) {
186 rmRet = pasteboardClient->RemoveGlobalShareOption(removeVector);
187 }
188 if (setRet != ERR_OK || rmRet != ERR_OK) {
189 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
190 }
191 return ERR_OK;
192 }
193 } // namespace EDM
194 } // namespace OHOS