• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 #ifndef SERVICES_EDM_INCLUDE_EDM_IPLUGIN_TEMPLATE_H
17 #define SERVICES_EDM_INCLUDE_EDM_IPLUGIN_TEMPLATE_H
18 
19 #include <functional>
20 #include <memory>
21 #include <unordered_map>
22 #include "edm_log.h"
23 #include "func_code_utils.h"
24 #include "iplugin.h"
25 #include "ipolicy_manager.h"
26 #include "ipolicy_serializer.h"
27 
28 namespace OHOS {
29 namespace EDM {
30 /*
31  * Policy processing template.Implements the IPlugin interface and
32  * provides the event registration method for policy processing.
33  *
34  * @tparam CT Policy processing logic class, which is the code to be implemented.
35  * @tparam DT Policy data type, for example:string,vector<string>,map<string,string>...
36  */
37 template<class CT, class DT>
38 class IPluginTemplate : public IPlugin {
39 public:
40     ErrCode OnHandlePolicy(std::uint32_t funcCode, MessageParcel &data, MessageParcel &reply, std::string &policyData,
41         bool &isChanged, int32_t userId) override;
42 
43     ErrCode MergePolicyData(const std::string &adminName, std::string &policyData) override;
44 
45     void OnHandlePolicyDone(std::uint32_t funcCode, const std::string &adminName,
46         bool isGlobalChanged, int32_t userId) override;
47 
48     ErrCode OnAdminRemove(const std::string &adminName, const std::string &currentJsonData, int32_t userId) override;
49 
50     void OnAdminRemoveDone(const std::string &adminName, const std::string &removedJsonData, int32_t userId) override;
51 
52     ErrCode WritePolicyToParcel(const std::string &policyData, MessageParcel &reply) override;
53 
54     ErrCode OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply, int32_t userId) override;
55 
56     /*
57      * Sets the handle of the policy processing object.
58      *
59      * @param instance std::shared_ptr<CT>
60      */
61     void SetInstance(std::shared_ptr<CT> instance);
62 
63     /*
64      * Define CT as the friend class of IPluginTemplate.
65      */
66     friend CT;
67 
68     IPluginTemplate();
69 
70     ~IPluginTemplate();
71 
72 protected:
73     /*
74      * Represents a function that invoked during handling policy.
75      *
76      * @param one MessageParcel
77      * @param two MessageParcel
78      * @param three Current policy data
79      * @param four Whether the policy data is changed
80      * @param five Handle type
81      * @see OnHandlePolicy
82      * @see HandlePolicyFunc
83      */
84     typedef std::function<ErrCode(MessageParcel &, MessageParcel &, std::string &, bool &, FuncOperateType,
85         int32_t userId)> HandlePolicy;
86 
87     /*
88      * Represents a function that invoked during handling policy.
89      *
90      * @param one Admin name
91      * @param two Whether the policy data is changed
92      * @param three Handle type
93      * @see OnHandlePolicyDone
94      * @see HandlePolicyDoneFunc
95      */
96     typedef std::function<ErrCode(const std::string &, bool, FuncOperateType, int32_t userId)> HandlePolicyDone;
97 
98     /*
99      * Represents a function that invoked during the removal of admin.
100      *
101      * @see OnAdminRemove
102      * @see AdminRemoveFunc
103      */
104     typedef std::function<ErrCode(const std::string &, const std::string &, int32_t userId)> AdminRemove;
105 
106     /*
107      * Represents a function that invoked after the admin is removed.
108      *
109      * @see OnAdminRemoveDone
110      * @see AdminRemoveDoneFunc
111      */
112     typedef std::function<ErrCode(const std::string &, const std::string &, int32_t userId)> AdminRemoveDone;
113 
114     /*
115      * This is a member function pointer type of CT class.
116      * Represents a supplier of results. There is no requirement that a ErrCode result be returned each time the
117      * supplier is invoked.
118      * It is generally used in scenarios where only return values need to be processed and parameters are not concerned.
119      *
120      * @return Whether the policy is handled successfully.
121      * @see SetOnHandlePolicyListener
122      * @see SetOnAdminRemoveListener
123      */
124     typedef ErrCode (CT::*Supplier)();
125 
126     /*
127      * This is a member function pointer type of CT class.
128      * Represents a function that accepts one DT argument and produces a ErrCode result.
129      * It is generally used in the scenario where only one DT parameter and return value need to be processed.
130      *
131      * @param data In: Input policy data parameter,Out: Used to update the admin data.
132      * @return Whether the policy is handled successfully.
133      * @see SetOnHandlePolicyListener
134      */
135     typedef ErrCode (CT::*Function)(DT &data);
136 
137     /*
138      * This is a member function pointer type of CT class.
139      * Represents a function that accepts one DT argument and produces a ErrCode result.
140      * It is generally used in the scenario where only one DT parameter and return value need to be processed.
141      *
142      * @param data In: Input policy data parameter,Out: Used to update the admin data.
143      * @param reply In: return message parcel for ipc,Out: parcel with return value or message.
144      * @return Whether the policy is handled successfully.
145      * @see SetOnHandlePolicyListener
146      */
147     typedef ErrCode (CT::*ReplyFunction)(DT &data, MessageParcel &reply);
148 
149     /*
150      * This is a member function pointer type of CT class.
151      * Represents a function that accepts two DT arguments and produces a ErrCode result.
152      *
153      * @param data Input policy data parameter
154      * @param currentData In: data of the current admin,Out: Used to update the admin data.
155      * @return Whether the policy is handled successfully.
156      * @see SetOnHandlePolicyListener
157      */
158     typedef ErrCode (CT::*BiFunction)(DT &data, DT &currentData, int32_t userId);
159 
160     /*
161      * This is a member function pointer type of CT class.
162      * Represents a function that accepts an string-valued and a DT-valued argument, and produces a ErrCode result.
163      *
164      * @param adminName Admin name
165      * @param data Admin policy data
166      * @see SetOnAdminRemoveListener
167      */
168     typedef ErrCode (CT::*BiAdminFunction)(const std::string &adminName, DT &data, int32_t userId);
169 
170     /*
171      * This is a member function pointer type of CT class.
172      * Represents an operation that accepts a single bool input argument and returns no result.
173      *
174      * @param isGlobalChanged Whether the policy data is changed
175      * @see SetOnHandlePolicyDoneListener
176      */
177     typedef void (CT::*BoolConsumer)(bool isGlobalChanged);
178 
179     /*
180      * This is a member function pointer type of CT class.
181      * Represents an operation that accepts an DT-valued and a bool-valued argument, and returns no result.
182      *
183      * @param data Admin policy data
184      * @param isGlobalChanged Whether the policy data is changed
185      * @see SetOnHandlePolicyDoneListener
186      */
187     typedef void (CT::*BiBoolConsumer)(DT &data, bool isGlobalChanged, int32_t userId);
188 
189     /*
190      * This is a member function pointer type of CT class.
191      * Represents an operation that accepts no arguments and returns no result.
192      *
193      * @param data Admin policy data
194      * @param isGlobalChanged Whether the policy data is changed
195      * @see SetOnAdminRemoveDoneListener
196      */
197     typedef void (CT::*Runner)();
198 
199     /*
200      * This is a member function pointer type of CT class.
201      * Represents an operation that accepts an string-valued and a DT-valued argument, and returns no result.
202      *
203      * @param adminName Admin name
204      * @param data Admin policy data
205      * @see SetOnAdminRemoveDoneListener
206      */
207     typedef void (CT::*BiAdminConsumer)(const std::string &adminName, DT &data, int32_t userId);
208 
209     virtual bool GetMergePolicyData(DT &policyData);
210 
211     void SetSerializer(std::shared_ptr<IPolicySerializer<DT>> serializer);
212 
213     void InitAttribute(uint32_t policyCode, const std::string &policyName, const std::string &permission,
214         IPlugin::PermissionType permissionType, bool needSave = true, bool global = true);
215 
216     void InitAttribute(uint32_t policyCode, const std::string &policyName, bool needSave = true, bool global = true);
217 
218     void InitPermission(FuncOperateType operateType, const std::string &permission,
219         IPlugin::PermissionType permissionType);
220 
221     /*
222      * Registering Listening for HandlePolicy Events.
223      *
224      * @param listener Listening member function pointer of CT Class
225      * @param type Policy Data Processing Mode
226      * @see FuncOperateType
227      */
228     void SetOnHandlePolicyListener(Supplier &&listener, FuncOperateType type);
229 
230     /*
231      * Registering Listening for HandlePolicy Events.
232      *
233      * @param listener Listening member function pointer of CT Class
234      * @param type Policy Data Processing Mode,default FuncOperateType::REMOVE
235      * @see FuncOperateType
236      */
237     void SetOnHandlePolicyListener(Function &&listener, FuncOperateType type);
238 
239     /*
240      * Registering Listening for HandlePolicy Events.
241      *
242      * @param listener Listening member function pointer of CT Class
243      * @param type Policy Data Processing Mode,default FuncOperateType::SET
244      * @see FuncOperateType
245      */
246     void SetOnHandlePolicyListener(BiFunction &&listener, FuncOperateType type);
247 
248     /*
249      * Registering Listening for HandlePolicy Events.
250      *
251      * @param listener Listening member function pointer of CT Class
252      * @param type Policy Data Processing Mode,default FuncOperateType::SET
253      * @see FuncOperateType
254      */
255     void SetOnHandlePolicyListener(ReplyFunction &&listener, FuncOperateType type);
256 
257     /*
258      * Registering listening for HandlePolicyDone events.
259      *
260      * @param listener Listening member function pointer of CT Class
261      * @param type Policy Data Processing Mode
262      */
263     void SetOnHandlePolicyDoneListener(BoolConsumer &&listener, FuncOperateType type);
264 
265     /*
266      * Registering listening for HandlePolicyDone events.
267      *
268      * @param listener Listening member function pointer of CT Class
269      * @param type Policy Data Processing Mode
270      */
271     void SetOnHandlePolicyDoneListener(BiBoolConsumer &&listener, FuncOperateType type);
272 
273     /*
274      * Registering listening for AdminRemove events.
275      *
276      * @param listener Listening member function pointer of CT Class
277      */
278     void SetOnAdminRemoveListener(Supplier &&listener);
279 
280     /*
281      * Registering listening for AdminRemove events.
282      *
283      * @param listener Listening member function pointer of CT Class
284      */
285     void SetOnAdminRemoveListener(BiAdminFunction &&listener);
286 
287     /*
288      * Registering listening for AdminRemoveDone events.
289      *
290      * @param listener Listening member function pointer of CT Class
291      */
292     void SetOnAdminRemoveDoneListener(Runner &&listener);
293 
294     /*
295      * Registering listening for AdminRemoveDone events.
296      *
297      * @param listener Listening member function pointer of CT Class
298      */
299     void SetOnAdminRemoveDoneListener(BiAdminConsumer &&listener);
300 
301     /*
302      * Mapping between HandlePolicy and member function types that support overloading.
303      */
304     struct HandlePolicyFunc {
305         HandlePolicy handlePolicy_ = nullptr;
306         Supplier supplier_ = nullptr;
307         Function function_ = nullptr;
308         ReplyFunction replyfunction_ = nullptr;
309         BiFunction biFunction_ = nullptr;
310 
HandlePolicyFuncHandlePolicyFunc311         HandlePolicyFunc() {}
312 
HandlePolicyFuncHandlePolicyFunc313         HandlePolicyFunc(HandlePolicy handlePolicy, Supplier supplier)
314             : handlePolicy_(std::move(handlePolicy)), supplier_(supplier) {}
315 
HandlePolicyFuncHandlePolicyFunc316         HandlePolicyFunc(HandlePolicy handlePolicy, Function function)
317             : handlePolicy_(std::move(handlePolicy)), function_(function) {}
318 
HandlePolicyFuncHandlePolicyFunc319         HandlePolicyFunc(HandlePolicy handlePolicy, ReplyFunction replyfunction)
320             : handlePolicy_(std::move(handlePolicy)), replyfunction_(replyfunction) {}
321 
HandlePolicyFuncHandlePolicyFunc322         HandlePolicyFunc(HandlePolicy handlePolicy, BiFunction biFunction)
323             : handlePolicy_(std::move(handlePolicy)), biFunction_(biFunction) {}
324     };
325 
326     // Member function callback object of the HandlePolicy event.
327     std::map<FuncOperateType, HandlePolicyFunc> handlePolicyFuncMap_;
328 
329     /*
330      * Mapping between HandlePolicyDone and member function types that support overloading.
331      */
332     struct HandlePolicyDoneFunc {
333         HandlePolicyDone handlePolicyDone_ = nullptr;
334         BoolConsumer boolConsumer_ = nullptr;
335         BiBoolConsumer biBoolConsumer_ = nullptr;
336 
HandlePolicyDoneFuncHandlePolicyDoneFunc337         HandlePolicyDoneFunc() {}
338 
HandlePolicyDoneFuncHandlePolicyDoneFunc339         HandlePolicyDoneFunc(HandlePolicyDone handlePolicyDone, BoolConsumer boolConsumer)
340             : handlePolicyDone_(std::move(handlePolicyDone)), boolConsumer_(boolConsumer) {}
341 
HandlePolicyDoneFuncHandlePolicyDoneFunc342         HandlePolicyDoneFunc(HandlePolicyDone handlePolicyDone, BiBoolConsumer biBoolConsumer)
343             : handlePolicyDone_(std::move(handlePolicyDone)), biBoolConsumer_(biBoolConsumer) {}
344     };
345 
346     // Member function callback object of the HandlePolicyDone event.
347     std::map<FuncOperateType, HandlePolicyDoneFunc> handlePolicyDoneFuncMap_;
348 
349     /*
350      * Mapping between AdminRemove and member function types that support overloading.
351      */
352     struct AdminRemoveFunc {
353         AdminRemove adminRemove_ = nullptr;
354         Supplier supplier_ = nullptr;
355         BiAdminFunction biAdminFunction_ = nullptr;
356 
AdminRemoveFuncAdminRemoveFunc357         AdminRemoveFunc() {}
358 
AdminRemoveFuncAdminRemoveFunc359         AdminRemoveFunc(AdminRemove adminRemove, Supplier supplier)
360             : adminRemove_(std::move(adminRemove)), supplier_(supplier) {}
361 
AdminRemoveFuncAdminRemoveFunc362         AdminRemoveFunc(AdminRemove adminRemove, BiAdminFunction biAdminFunction)
363             : adminRemove_(std::move(adminRemove)), biAdminFunction_(biAdminFunction) {}
364     };
365 
366     // Member function callback object of the AdminRemove event.
367     AdminRemoveFunc adminRemoveFunc_;
368 
369     /*
370      * Mapping between AdminRemoveDone and member function types that support overloading.
371      */
372     struct AdminRemoveDoneFunc {
373         AdminRemoveDone adminRemoveDone_ = nullptr;
374         Runner runner_ = nullptr;
375         BiAdminConsumer biAdminConsumer_ = nullptr;
376 
AdminRemoveDoneFuncAdminRemoveDoneFunc377         AdminRemoveDoneFunc() {}
378 
AdminRemoveDoneFuncAdminRemoveDoneFunc379         AdminRemoveDoneFunc(AdminRemoveDone adminRemoveDone, Runner runner)
380             : adminRemoveDone_(std::move(adminRemoveDone)), runner_(runner) {}
381 
AdminRemoveDoneFuncAdminRemoveDoneFunc382         AdminRemoveDoneFunc(AdminRemoveDone adminRemoveDone, BiAdminConsumer biAdminConsumer)
383             : adminRemoveDone_(std::move(adminRemoveDone)), biAdminConsumer_(biAdminConsumer) {}
384     };
385 
386     // Member function callback object of the AdminRemoveDone event.
387     AdminRemoveDoneFunc adminRemoveDoneFunc_;
388     // Pointer to the callback member function.
389     std::shared_ptr<CT> instance_;
390     // Data serializer for policy data
391     std::shared_ptr<IPolicySerializer<DT>> serializer_;
392 };
393 
394 template<class CT, class DT>
IPluginTemplate()395 IPluginTemplate<CT, DT>::IPluginTemplate() {}
396 
397 template<class CT, class DT>
OnHandlePolicy(std::uint32_t funcCode,MessageParcel & data,MessageParcel & reply,std::string & policyData,bool & isChanged,int32_t userId)398 ErrCode IPluginTemplate<CT, DT>::OnHandlePolicy(std::uint32_t funcCode, MessageParcel &data, MessageParcel &reply,
399     std::string &policyData, bool &isChanged, int32_t userId)
400 {
401     uint32_t typeCode = FUNC_TO_OPERATE(funcCode);
402     FuncOperateType type = FuncCodeUtils::ConvertOperateType(typeCode);
403     auto entry = handlePolicyFuncMap_.find(type);
404     if (entry == handlePolicyFuncMap_.end() || entry->second.handlePolicy_ == nullptr) {
405         return ERR_OK;
406     }
407     ErrCode res = entry->second.handlePolicy_(data, reply, policyData, isChanged, type, userId);
408     EDMLOGI("IPluginTemplate::OnHandlePolicy operate: %{public}d, res: %{public}d", type, res);
409     return res;
410 }
411 
412 template<class CT, class DT>
OnGetPolicy(std::string & policyData,MessageParcel & data,MessageParcel & reply,int32_t userId)413 ErrCode IPluginTemplate<CT, DT>::OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply,
414     int32_t userId)
415 {
416     EDMLOGI("IPluginTemplate::OnGetPolicy");
417     return instance_->OnGetPolicy(policyData, data, reply, userId);
418 }
419 
420 template<class CT, class DT>
SetOnHandlePolicyListener(Supplier && listener,FuncOperateType type)421 void IPluginTemplate<CT, DT>::SetOnHandlePolicyListener(Supplier &&listener, FuncOperateType type)
422 {
423     if (instance_ == nullptr) {
424         return;
425     }
426     auto handle = [this](MessageParcel &data, MessageParcel &reply, std::string &policyData, bool &isChanged,
427         FuncOperateType funcOperate, int32_t userId) -> ErrCode {
428         auto entry = handlePolicyFuncMap_.find(funcOperate);
429         if (entry == handlePolicyFuncMap_.end() || entry->second.supplier_ == nullptr) {
430             return ERR_EDM_NOT_EXIST_FUNC;
431         }
432         return (instance_.get()->*(entry->second.supplier_))();
433     };
434     handlePolicyFuncMap_.insert(std::make_pair(type, HandlePolicyFunc(handle, listener)));
435 }
436 
437 template<class CT, class DT>
SetOnHandlePolicyListener(Function && listener,FuncOperateType type)438 void IPluginTemplate<CT, DT>::SetOnHandlePolicyListener(Function &&listener, FuncOperateType type)
439 {
440     if (instance_ == nullptr) {
441         return;
442     }
443     auto handle = [this](MessageParcel &data, MessageParcel &reply, std::string &policyData, bool &isChanged,
444         FuncOperateType funcOperate, int32_t userId) -> ErrCode {
445         DT handleData;
446         if (!serializer_->GetPolicy(data, handleData)) {
447             return ERR_EDM_OPERATE_PARCEL;
448         }
449         auto entry = handlePolicyFuncMap_.find(funcOperate);
450         if (entry == handlePolicyFuncMap_.end() || entry->second.function_ == nullptr) {
451             return ERR_EDM_NOT_EXIST_FUNC;
452         }
453         ErrCode result = (instance_.get()->*(entry->second.function_))(handleData);
454         if (result != ERR_OK) {
455             return result;
456         }
457         std::string afterHandle;
458         if (!serializer_->Serialize(handleData, afterHandle)) {
459             return ERR_EDM_OPERATE_JSON;
460         }
461         isChanged = (policyData != afterHandle);
462         if (isChanged) {
463             policyData = afterHandle;
464         }
465         return ERR_OK;
466     };
467     handlePolicyFuncMap_.insert(std::make_pair(type, HandlePolicyFunc(handle, listener)));
468 }
469 
470 template<class CT, class DT>
SetOnHandlePolicyListener(ReplyFunction && listener,FuncOperateType type)471 void IPluginTemplate<CT, DT>::SetOnHandlePolicyListener(ReplyFunction &&listener, FuncOperateType type)
472 {
473     if (instance_ == nullptr) {
474         return;
475     }
476     auto handle = [this](MessageParcel &data, MessageParcel &reply, std::string &policyData, bool &isChanged,
477         FuncOperateType funcOperate, int32_t userId) -> ErrCode {
478         DT handleData;
479         if (!serializer_->GetPolicy(data, handleData)) {
480             return ERR_EDM_OPERATE_PARCEL;
481         }
482         auto entry = handlePolicyFuncMap_.find(funcOperate);
483         if (entry == handlePolicyFuncMap_.end() || entry->second.replyfunction_ == nullptr) {
484             return ERR_EDM_NOT_EXIST_FUNC;
485         }
486         ErrCode result = (instance_.get()->*(entry->second.replyfunction_))(handleData, reply);
487         if (result != ERR_OK) {
488             return result;
489         }
490         std::string afterHandle;
491         if (!serializer_->Serialize(handleData, afterHandle)) {
492             return ERR_EDM_OPERATE_JSON;
493         }
494         isChanged = (policyData != afterHandle);
495         if (isChanged) {
496             policyData = afterHandle;
497         }
498         return ERR_OK;
499     };
500     handlePolicyFuncMap_.insert(std::make_pair(type, HandlePolicyFunc(handle, listener)));
501 }
502 
503 template<class CT, class DT>
SetOnHandlePolicyListener(BiFunction && listener,FuncOperateType type)504 void IPluginTemplate<CT, DT>::SetOnHandlePolicyListener(BiFunction &&listener, FuncOperateType type)
505 {
506     if (instance_ == nullptr || instance_.get() == nullptr) {
507         return;
508     }
509     auto handle = [this](MessageParcel &data, MessageParcel &reply, std::string &policyData, bool &isChanged,
510         FuncOperateType funcOperate, int32_t userId) -> ErrCode {
511         DT handleData;
512         if (!serializer_->GetPolicy(data, handleData)) {
513             return ERR_EDM_OPERATE_PARCEL;
514         }
515         DT currentData;
516         if (!policyData.empty() && !serializer_->Deserialize(policyData, currentData)) {
517             return ERR_EDM_OPERATE_JSON;
518         }
519         auto entry = handlePolicyFuncMap_.find(funcOperate);
520         if (entry == handlePolicyFuncMap_.end() || entry->second.biFunction_ == nullptr) {
521             return ERR_EDM_NOT_EXIST_FUNC;
522         }
523         std::string beforeHandle;
524         if (!serializer_->Serialize(currentData, beforeHandle)) {
525             return ERR_EDM_OPERATE_JSON;
526         }
527         ErrCode result = (instance_.get()->*(entry->second.biFunction_))(handleData, currentData, userId);
528         if (result != ERR_OK) {
529             return result;
530         }
531         std::string afterHandle;
532         if (!serializer_->Serialize(currentData, afterHandle)) {
533             return ERR_EDM_OPERATE_JSON;
534         }
535         policyData = afterHandle;
536         isChanged = (beforeHandle != afterHandle);
537         return ERR_OK;
538     };
539     handlePolicyFuncMap_.insert(std::make_pair(type, HandlePolicyFunc(handle, listener)));
540 }
541 using AdminValueItemsMap = std::unordered_map<std::string, std::string>;
542 template<class CT, class DT>
MergePolicyData(const std::string & adminName,std::string & policyData)543 ErrCode IPluginTemplate<CT, DT>::MergePolicyData(const std::string &adminName, std::string &policyData)
544 {
545     AdminValueItemsMap adminValues;
546     IPolicyManager::GetInstance()->GetAdminByPolicyName(GetPolicyName(), adminValues);
547     EDMLOGD("IPluginTemplate::MergePolicyData %{public}s value size %{public}d.",
548         GetPolicyName().c_str(), (uint32_t)adminValues.size());
549     if (adminValues.empty()) {
550         return ERR_OK;
551     }
552     // Update or remove policy value from the cache map.
553     auto entry = adminValues.find(adminName);
554     // Remove policy value from the cache map.
555     if (entry != adminValues.end()) {
556         adminValues.erase(entry);
557     }
558     if (adminValues.empty() && policyData.empty()) {
559         return ERR_OK;
560     }
561     std::vector<DT> data;
562     for (const auto &item : adminValues) {
563         DT dataItem;
564         if (!item.second.empty()) {
565             if (!serializer_->Deserialize(item.second, dataItem)) {
566                 return ERR_EDM_OPERATE_JSON;
567             }
568             data.push_back(dataItem);
569         }
570     }
571     // Add current policy to last, some policy must ensure the order, Deserialize can not parse empty String
572     DT last;
573     if (!policyData.empty()) {
574         if (!serializer_->Deserialize(policyData, last)) {
575             return ERR_EDM_OPERATE_JSON;
576         }
577         data.push_back(last);
578     }
579     DT result;
580     if (!serializer_->MergePolicy(data, result)) {
581         return ERR_EDM_OPERATE_JSON;
582     }
583     if (!serializer_->Serialize(result, policyData)) {
584         return ERR_EDM_OPERATE_JSON;
585     }
586     return ERR_OK;
587 }
588 
589 template<class CT, class DT>
OnHandlePolicyDone(std::uint32_t funcCode,const std::string & adminName,const bool isGlobalChanged,int32_t userId)590 void IPluginTemplate<CT, DT>::OnHandlePolicyDone(std::uint32_t funcCode, const std::string &adminName,
591     const bool isGlobalChanged, int32_t userId)
592 {
593     uint32_t typeCode = FUNC_TO_OPERATE(funcCode);
594     FuncOperateType type = FuncCodeUtils::ConvertOperateType(typeCode);
595     auto entry = handlePolicyDoneFuncMap_.find(type);
596     if (entry == handlePolicyDoneFuncMap_.end() || entry->second.handlePolicyDone_ == nullptr) {
597         return;
598     }
599     ErrCode res = entry->second.handlePolicyDone_(adminName, isGlobalChanged, type, userId);
600     EDMLOGI("IPluginTemplate::OnHandlePolicyDone operate: %{public}d, isGlobalChanged: %{public}d, res: %{public}d",
601         type, isGlobalChanged, res);
602 }
603 
604 template<class CT, class DT>
SetOnHandlePolicyDoneListener(BoolConsumer && listener,FuncOperateType type)605 void IPluginTemplate<CT, DT>::SetOnHandlePolicyDoneListener(BoolConsumer &&listener, FuncOperateType type)
606 {
607     if (instance_ == nullptr) {
608         return;
609     }
610     auto handle = [this](const std::string &adminName, bool isGlobalChanged, FuncOperateType funcOperate,
611         int32_t userId) -> ErrCode {
612         auto entry = handlePolicyDoneFuncMap_.find(funcOperate);
613         if (entry == handlePolicyDoneFuncMap_.end() || entry->second.boolConsumer_ == nullptr) {
614             return ERR_EDM_NOT_EXIST_FUNC;
615         }
616         (instance_.get()->*(entry->second.boolConsumer_))(isGlobalChanged);
617         return ERR_OK;
618     };
619     handlePolicyDoneFuncMap_.insert(std::make_pair(type, HandlePolicyDoneFunc(handle, listener)));
620 }
621 
622 template<class CT, class DT>
SetOnHandlePolicyDoneListener(BiBoolConsumer && listener,FuncOperateType type)623 void IPluginTemplate<CT, DT>::SetOnHandlePolicyDoneListener(BiBoolConsumer &&listener, FuncOperateType type)
624 {
625     if (instance_ == nullptr) {
626         return;
627     }
628     auto handle = [this](const std::string &adminName, bool isGlobalChanged, FuncOperateType funcOperate,
629         int32_t userId) -> ErrCode {
630         auto entry = handlePolicyDoneFuncMap_.find(funcOperate);
631         if (entry == handlePolicyDoneFuncMap_.end() || entry->second.biBoolConsumer_ == nullptr) {
632             return ERR_EDM_NOT_EXIST_FUNC;
633         }
634         DT currentData;
635         if (NeedSavePolicy() && !this->GetMergePolicyData(currentData)) {
636             return ERR_EDM_OPERATE_JSON;
637         }
638         (instance_.get()->*(entry->second.biBoolConsumer_))(currentData, isGlobalChanged, userId);
639         return ERR_OK;
640     };
641     handlePolicyDoneFuncMap_.insert(std::make_pair(type, HandlePolicyDoneFunc(handle, listener)));
642 }
643 
644 template<class CT, class DT>
OnAdminRemove(const std::string & adminName,const std::string & currentJsonData,int32_t userId)645 ErrCode IPluginTemplate<CT, DT>::OnAdminRemove(const std::string &adminName, const std::string &currentJsonData,
646     int32_t userId)
647 {
648     if (adminRemoveFunc_.adminRemove_ == nullptr) {
649         return ERR_OK;
650     }
651     ErrCode res = (adminRemoveFunc_.adminRemove_)(adminName, currentJsonData, userId);
652     EDMLOGI("IPluginTemplate::OnAdminRemove admin:%{public}s, res: %{public}d", adminName.c_str(), res);
653     return res;
654 }
655 
656 template<class CT, class DT>
SetOnAdminRemoveListener(Supplier && listener)657 void IPluginTemplate<CT, DT>::SetOnAdminRemoveListener(Supplier &&listener)
658 {
659     if (instance_ == nullptr) {
660         return;
661     }
662     auto adminRemove = [this](const std::string &adminName, const std::string &currentJsonData,
663         int32_t userId) -> ErrCode {
664         if (adminRemoveFunc_.supplier_ == nullptr) {
665             return ERR_EDM_NOT_EXIST_FUNC;
666         }
667         return (instance_.get()->*(adminRemoveFunc_.supplier_))();
668     };
669     adminRemoveFunc_ = AdminRemoveFunc(adminRemove, listener);
670 }
671 
672 template<class CT, class DT>
SetOnAdminRemoveListener(BiAdminFunction && listener)673 void IPluginTemplate<CT, DT>::SetOnAdminRemoveListener(BiAdminFunction &&listener)
674 {
675     if (instance_ == nullptr) {
676         return;
677     }
678     auto adminRemove = [this](const std::string &adminName, const std::string &currentJsonData,
679         int32_t userId) -> ErrCode {
680         DT currentData;
681         if (!serializer_->Deserialize(currentJsonData, currentData)) {
682             return ERR_EDM_OPERATE_JSON;
683         }
684         if (adminRemoveFunc_.biAdminFunction_ == nullptr) {
685             return ERR_EDM_NOT_EXIST_FUNC;
686         }
687         return (instance_.get()->*(adminRemoveFunc_.biAdminFunction_))(adminName, currentData, userId);
688     };
689     adminRemoveFunc_ = AdminRemoveFunc(adminRemove, listener);
690 }
691 
692 template<class CT, class DT>
OnAdminRemoveDone(const std::string & adminName,const std::string & currentJsonData,int32_t userId)693 void IPluginTemplate<CT, DT>::OnAdminRemoveDone(const std::string &adminName, const std::string &currentJsonData,
694     int32_t userId)
695 {
696     if (instance_ == nullptr) {
697         return;
698     }
699     if (adminRemoveDoneFunc_.adminRemoveDone_ == nullptr) {
700         return;
701     }
702     (adminRemoveDoneFunc_.adminRemoveDone_)(adminName, currentJsonData, userId);
703 }
704 
705 template<class CT, class DT>
SetOnAdminRemoveDoneListener(Runner && listener)706 void IPluginTemplate<CT, DT>::SetOnAdminRemoveDoneListener(Runner &&listener)
707 {
708     if (instance_ == nullptr) {
709         return;
710     }
711     auto adminRemoveDone = [this](const std::string &adminName, const std::string &currentJsonData,
712         int32_t userId) -> ErrCode {
713         if (adminRemoveDoneFunc_.runner_ == nullptr) {
714             return ERR_EDM_NOT_EXIST_FUNC;
715         }
716         (instance_.get()->*(adminRemoveDoneFunc_.runner_))();
717         return ERR_OK;
718     };
719     adminRemoveDoneFunc_ = AdminRemoveDoneFunc(adminRemoveDone, listener);
720 }
721 
722 template<class CT, class DT>
SetOnAdminRemoveDoneListener(BiAdminConsumer && listener)723 void IPluginTemplate<CT, DT>::SetOnAdminRemoveDoneListener(BiAdminConsumer &&listener)
724 {
725     if (instance_ == nullptr) {
726         return;
727     }
728     auto adminRemoveDone = [this](const std::string &adminName, const std::string &currentJsonData,
729         int32_t userId) -> ErrCode {
730         if (adminRemoveDoneFunc_.biAdminConsumer_ == nullptr) {
731             return ERR_EDM_NOT_EXIST_FUNC;
732         }
733         DT currentData;
734         if (!serializer_->Deserialize(currentJsonData, currentData)) {
735             return ERR_EDM_OPERATE_JSON;
736         }
737         (instance_.get()->*(adminRemoveDoneFunc_.biAdminConsumer_))(adminName, currentData, userId);
738         return ERR_OK;
739     };
740     adminRemoveDoneFunc_ = AdminRemoveDoneFunc(adminRemoveDone, listener);
741 }
742 
743 template<class CT, class DT>
WritePolicyToParcel(const std::string & policyData,MessageParcel & reply)744 ErrCode IPluginTemplate<CT, DT>::WritePolicyToParcel(const std::string &policyData, MessageParcel &reply)
745 {
746     DT currentData;
747     if (!serializer_->Deserialize(policyData, currentData)) {
748         return ERR_EDM_OPERATE_JSON;
749     }
750     if (!serializer_->WritePolicy(reply, currentData)) {
751         return ERR_EDM_OPERATE_PARCEL;
752     }
753     return ERR_OK;
754 }
755 
756 template<class CT, class DT>
GetMergePolicyData(DT & policyData)757 bool IPluginTemplate<CT, DT>::GetMergePolicyData(DT &policyData)
758 {
759     AdminValueItemsMap adminValues;
760     IPolicyManager::GetInstance()->GetAdminByPolicyName(GetPolicyName(), adminValues);
761     if (adminValues.empty()) {
762         return true;
763     }
764     if (adminValues.size() == 1) {
765         for (const auto &item : adminValues) {
766             if (!serializer_->Deserialize(item.second, policyData)) {
767                 return false;
768             } else {
769                 return true;
770             }
771         }
772     } else {
773         std::vector<DT> adminValueArray;
774         for (const auto &item : adminValues) {
775             DT dataItem;
776             if (!serializer_->Deserialize(item.second, dataItem)) {
777                 return false;
778             }
779             adminValueArray.push_back(dataItem);
780         }
781         if (!serializer_->MergePolicy(adminValueArray, policyData)) {
782             return false;
783         }
784     }
785     return true;
786 }
787 
788 template<class CT, class DT>
SetInstance(std::shared_ptr<CT> instance)789 void IPluginTemplate<CT, DT>::SetInstance(std::shared_ptr<CT> instance)
790 {
791     instance_ = instance;
792 }
793 
794 template<class CT, class DT>
SetSerializer(std::shared_ptr<IPolicySerializer<DT>> serializer)795 void IPluginTemplate<CT, DT>::SetSerializer(std::shared_ptr<IPolicySerializer<DT>> serializer)
796 {
797     serializer_ = serializer;
798 }
799 
800 template<class CT, class DT>
InitAttribute(uint32_t policyCode,const std::string & policyName,const std::string & permission,IPlugin::PermissionType permissionType,bool needSave,bool global)801 void IPluginTemplate<CT, DT>::InitAttribute(
802     uint32_t policyCode, const std::string &policyName, const std::string &permission,
803     IPlugin::PermissionType permissionType, bool needSave, bool global)
804 {
805     policyCode_ = policyCode;
806     policyName_ = policyName;
807     permission_ = permission;
808     permissionType_ = permissionType;
809     needSave_ = needSave;
810     isGlobal_ = global;
811 }
812 
813 template<class CT, class DT>
InitAttribute(uint32_t policyCode,const std::string & policyName,bool needSave,bool global)814 void IPluginTemplate<CT, DT>::InitAttribute(
815     uint32_t policyCode, const std::string &policyName, bool needSave, bool global)
816 {
817     policyCode_ = policyCode;
818     policyName_ = policyName;
819     needSave_ = needSave;
820     isGlobal_ = global;
821 }
822 
823 template<class CT, class DT>
InitPermission(FuncOperateType operateType,const std::string & permission,IPlugin::PermissionType permissionType)824 void IPluginTemplate<CT, DT>::InitPermission(FuncOperateType operateType, const std::string &permission,
825     IPlugin::PermissionType permissionType)
826 {
827     if (static_cast<int32_t>(operateType) >= static_cast<int32_t>(FuncOperateType::GET) &&
828         static_cast<int32_t>(operateType) <= static_cast<int32_t>(FuncOperateType::REMOVE)) {
829         permissionMap_.insert(std::make_pair(operateType, std::make_pair(permission, permissionType)));
830     }
831 }
832 
833 template<class CT, class DT>
~IPluginTemplate()834 IPluginTemplate<CT, DT>::~IPluginTemplate()
835 {
836     if (instance_ != nullptr) {
837         instance_.reset();
838         instance_ = nullptr;
839     }
840     if (serializer_ != nullptr) {
841         serializer_.reset();
842         serializer_ = nullptr;
843     }
844 }
845 
846 /*
847  * Policy processing plugin singleton mode template,which needs to inherit the template.
848  *
849  * @tparam CT Policy processing logic class, which is the code to be implemented.
850  * @tparam DT Policy data type, for example:string,vector<string>,map<string,string>...
851  */
852 template<typename CT, typename DT>
853 class PluginSingleton : public NoCopyable {
854 public:
855     /*
856      * Initialize the plugin. The subclass needs to implement the pure virtual
857      * function, define the code,name and permission of the plugin, and listen
858      * to policy events.
859      *
860      * @param ptr std::shared_ptr<IPluginTemplate<CT, DT>>
861      */
862     virtual void InitPlugin(std::shared_ptr<IPluginTemplate<CT, DT>> ptr) = 0;
863 
864     /*
865      * Obtains the singleton of the plugin interface.
866      *
867      * @return std::shared_ptr<IPlugin>
868      */
869     static std::shared_ptr<IPlugin> GetPlugin();
870 
871     virtual ErrCode OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply, int32_t userId);
872 
873     static void DestroyPlugin();
874 
875 protected:
876     static std::shared_ptr<IPluginTemplate<CT, DT>> pluginInstance_;
877     static std::mutex mutexLock_;
878 };
879 
880 template<typename CT, typename DT>
881 std::shared_ptr<IPluginTemplate<CT, DT>> PluginSingleton<CT, DT>::pluginInstance_ = nullptr;
882 
883 template<typename CT, typename DT>
884 std::mutex PluginSingleton<CT, DT>::mutexLock_;
885 
886 template<typename CT, typename DT>
GetPlugin()887 std::shared_ptr<IPlugin> PluginSingleton<CT, DT>::GetPlugin()
888 {
889     if (pluginInstance_ == nullptr) {
890         std::lock_guard<std::mutex> lock(mutexLock_);
891         if (pluginInstance_ == nullptr) {
892             std::shared_ptr<CT> ptr = std::make_shared<CT>();
893             pluginInstance_ = std::make_shared<IPluginTemplate<CT, DT>>();
894             pluginInstance_->SetInstance(ptr);
895             ptr->InitPlugin(pluginInstance_);
896         }
897     }
898     return pluginInstance_;
899 }
900 
901 template<typename CT, typename DT>
OnGetPolicy(std::string & policyData,MessageParcel & data,MessageParcel & reply,int32_t userId)902 ErrCode PluginSingleton<CT, DT>::OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply,
903     int32_t userId)
904 {
905     EDMLOGI("PluginSingleton::OnGetPolicy");
906     return ERR_OK;
907 }
908 
909 template<typename CT, typename DT>
DestroyPlugin()910 void PluginSingleton<CT, DT>::DestroyPlugin()
911 {
912     std::lock_guard<std::mutex> lock(mutexLock_);
913     if (pluginInstance_ != nullptr) {
914         pluginInstance_.reset();
915         pluginInstance_ = nullptr;
916     }
917 }
918 } // namespace EDM
919 } // namespace OHOS
920 #endif // SERVICES_EDM_INCLUDE_EDM_IPLUGIN_TEMPLATE_H
921