• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 OHOS_ROSEN_CLIENT_AGENT_MANAGER_H
17 #define OHOS_ROSEN_CLIENT_AGENT_MANAGER_H
18 
19 #include <map>
20 #include <mutex>
21 #include <set>
22 #include "agent_death_recipient.h"
23 #include "window_manager_hilog.h"
24 
25 namespace OHOS {
26 namespace Rosen {
27 template <typename T1, typename T2>
28 class ClientAgentContainer {
29 public:
30     ClientAgentContainer();
31     virtual ~ClientAgentContainer() = default;
32 
33     bool RegisterAgent(const sptr<T1>& agent, T2 type);
34     bool UnregisterAgent(const sptr<T1>& agent, T2 type);
35     std::set<sptr<T1>> GetAgentsByType(T2 type);
36 
37 private:
38     void RemoveAgent(const sptr<IRemoteObject>& remoteObject);
39     bool UnregisterAgentLocked(std::set<sptr<T1>>& agents, const sptr<IRemoteObject>& agent);
40 
41     static constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "ClientAgentContainer"};
42 
43     struct finder_t {
finder_tfinder_t44         finder_t(sptr<IRemoteObject> remoteObject) : remoteObject_(remoteObject) {}
45 
operatorfinder_t46         bool operator()(sptr<T1> agent)
47         {
48             return agent->AsObject() == remoteObject_;
49         }
50 
51         sptr<IRemoteObject> remoteObject_;
52     };
53 
54     std::recursive_mutex mutex_;
55     std::map<T2, std::set<sptr<T1>>> agentMap_;
56     sptr<AgentDeathRecipient> deathRecipient_;
57 };
58 
59 template<typename T1, typename T2>
ClientAgentContainer()60 ClientAgentContainer<T1, T2>::ClientAgentContainer() : deathRecipient_(
61     new AgentDeathRecipient(std::bind(&ClientAgentContainer<T1, T2>::RemoveAgent, this, std::placeholders::_1))) {}
62 
63 template<typename T1, typename T2>
RegisterAgent(const sptr<T1> & agent,T2 type)64 bool ClientAgentContainer<T1, T2>::RegisterAgent(const sptr<T1>& agent, T2 type)
65 {
66     std::lock_guard<std::recursive_mutex> lock(mutex_);
67     auto iter = std::find_if(agentMap_[type].begin(), agentMap_[type].end(), finder_t(agent->AsObject()));
68     if (iter != agentMap_[type].end()) {
69         WLOGFW("failed to register agent");
70         return false;
71     }
72     agentMap_[type].insert(agent);
73     if (deathRecipient_ == nullptr || !agent->AsObject()->AddDeathRecipient(deathRecipient_)) {
74         WLOGFI("failed to add death recipient");
75     }
76     return true;
77 }
78 
79 template<typename T1, typename T2>
UnregisterAgent(const sptr<T1> & agent,T2 type)80 bool ClientAgentContainer<T1, T2>::UnregisterAgent(const sptr<T1>& agent, T2 type)
81 {
82     std::lock_guard<std::recursive_mutex> lock(mutex_);
83     if (agent == nullptr || agentMap_.count(type) == 0) {
84         WLOGFE("agent or type is invalid");
85         return false;
86     }
87     auto& agents = agentMap_.at(type);
88     bool ret = UnregisterAgentLocked(agents, agent->AsObject());
89     agent->AsObject()->RemoveDeathRecipient(deathRecipient_);
90     return ret;
91 }
92 
93 template<typename T1, typename T2>
GetAgentsByType(T2 type)94 std::set<sptr<T1>> ClientAgentContainer<T1, T2>::GetAgentsByType(T2 type)
95 {
96     std::lock_guard<std::recursive_mutex> lock(mutex_);
97     if (agentMap_.count(type) == 0) {
98         WLOGFI("no such type of agent registered! type:%{public}u", type);
99         return std::set<sptr<T1>>();
100     }
101     return agentMap_.at(type);
102 }
103 
104 template<typename T1, typename T2>
UnregisterAgentLocked(std::set<sptr<T1>> & agents,const sptr<IRemoteObject> & agent)105 bool ClientAgentContainer<T1, T2>::UnregisterAgentLocked(std::set<sptr<T1>>& agents,
106     const sptr<IRemoteObject>& agent)
107 {
108     auto iter = std::find_if(agents.begin(), agents.end(), finder_t(agent));
109     if (iter == agents.end()) {
110         WLOGFW("could not find this agent");
111         return false;
112     }
113     agents.erase(iter);
114     WLOGFI("agent unregistered");
115     return true;
116 }
117 
118 template<typename T1, typename T2>
RemoveAgent(const sptr<IRemoteObject> & remoteObject)119 void ClientAgentContainer<T1, T2>::RemoveAgent(const sptr<IRemoteObject>& remoteObject)
120 {
121     WLOGFI("RemoveAgent");
122     std::lock_guard<std::recursive_mutex> lock(mutex_);
123     for (auto& elem : agentMap_) {
124         if (UnregisterAgentLocked(elem.second, remoteObject)) {
125             break;
126         }
127     }
128     remoteObject->RemoveDeathRecipient(deathRecipient_);
129 }
130 }
131 }
132 #endif // OHOS_ROSEN_CLIENT_AGENT_MANAGER_H
133