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 #include "multimodal_input_connect_manager.h"
17 #include <chrono>
18 #include <thread>
19 #include "iservice_registry.h"
20 #include "mmi_log.h"
21 #include "multimodal_input_connect_death_recipient.h"
22 #include "multimodal_input_connect_define.h"
23 #include "system_ability_definition.h"
24 #include "util.h"
25
26 namespace OHOS {
27 namespace MMI {
28 namespace {
29 std::shared_ptr<MultimodalInputConnectManager> g_instance;
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, MMI_LOG_DOMAIN, "MultimodalInputConnectManager"};
31 } // namespace
32
GetInstance()33 std::shared_ptr<MultimodalInputConnectManager> MultimodalInputConnectManager::GetInstance()
34 {
35 static std::once_flag flag;
36 std::call_once(flag, [&]() {
37 g_instance.reset(new MultimodalInputConnectManager());
38 });
39
40 if (g_instance != nullptr) {
41 g_instance->ConnectMultimodalInputService();
42 }
43 return g_instance;
44 }
45
AllocSocketPair(const int32_t moduleType)46 int32_t MultimodalInputConnectManager::AllocSocketPair(const int32_t moduleType)
47 {
48 MMI_LOGD("enter");
49 std::lock_guard<std::mutex> guard(lock_);
50 if (multimodalInputConnectService_ == nullptr) {
51 MMI_LOGE("client has not connect server");
52 return RET_ERR;
53 }
54
55 const std::string programName(OHOS::MMI::GetProgramName());
56 int32_t result = multimodalInputConnectService_->AllocSocketFd(programName, moduleType, socketFd_);
57 if (result != RET_OK) {
58 MMI_LOGE("AllocSocketFd has error:%{public}d", result);
59 return RET_ERR;
60 }
61
62 MMI_LOGI("AllocSocketPair success. socketFd_:%{public}d", socketFd_);
63 return RET_OK;
64 }
65
GetClientSocketFdOfAllocedSocketPair() const66 int32_t MultimodalInputConnectManager::GetClientSocketFdOfAllocedSocketPair() const
67 {
68 MMI_LOGD("enter");
69 return socketFd_;
70 }
71
AddInputEventFilter(sptr<IEventFilter> filter)72 int32_t MultimodalInputConnectManager::AddInputEventFilter(sptr<IEventFilter> filter)
73 {
74 std::lock_guard<std::mutex> guard(lock_);
75 if (multimodalInputConnectService_ == nullptr) {
76 MMI_LOGE("multimodalInputConnectService_ is nullptr");
77 return RET_ERR;
78 }
79 return multimodalInputConnectService_->AddInputEventFilter(filter);
80 }
81
ConnectMultimodalInputService()82 bool MultimodalInputConnectManager::ConnectMultimodalInputService()
83 {
84 MMI_LOGD("enter");
85 std::lock_guard<std::mutex> guard(lock_);
86 if (multimodalInputConnectService_ != nullptr) {
87 return true;
88 }
89 auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
90 if (sm == nullptr) {
91 MMI_LOGE("get registry fail");
92 return false;
93 }
94 auto sa = sm->GetSystemAbility(IMultimodalInputConnect::MULTIMODAL_INPUT_CONNECT_SERVICE_ID);
95 if (sa == nullptr) {
96 MMI_LOGE("get sa fail");
97 return false;
98 }
99
100 std::weak_ptr<MultimodalInputConnectManager> weakPtr = shared_from_this();
101 auto deathCallback = [weakPtr](const wptr<IRemoteObject> &object) {
102 auto sharedPtr = weakPtr.lock();
103 if (sharedPtr != nullptr) {
104 sharedPtr->OnDeath();
105 }
106 };
107
108 multimodalInputConnectRecipient_ = new MultimodalInputConnectDeathRecipient(deathCallback);
109 sa->AddDeathRecipient(multimodalInputConnectRecipient_);
110 multimodalInputConnectService_ = iface_cast<IMultimodalInputConnect>(sa);
111 if (multimodalInputConnectService_ == nullptr) {
112 MMI_LOGE("get multimodal input connect service fail");
113 return false;
114 }
115 MMI_LOGI("get multimodal input connect service successful");
116 return true;
117 }
118
OnDeath()119 void MultimodalInputConnectManager::OnDeath()
120 {
121 MMI_LOGD("enter");
122 Clean();
123 NotifyDeath();
124 MMI_LOGD("leave");
125 }
126
Clean()127 void MultimodalInputConnectManager::Clean()
128 {
129 MMI_LOGD("enter");
130 std::lock_guard<std::mutex> guard(lock_);
131 if (multimodalInputConnectService_ != nullptr) {
132 multimodalInputConnectService_.clear();
133 multimodalInputConnectService_ = nullptr;
134 }
135
136 if (multimodalInputConnectRecipient_ != nullptr) {
137 multimodalInputConnectRecipient_.clear();
138 multimodalInputConnectRecipient_ = nullptr;
139 }
140 MMI_LOGD("leave");
141 }
142
NotifyDeath()143 void MultimodalInputConnectManager::NotifyDeath()
144 {
145 MMI_LOGD("enter");
146
147 int32_t retryCount = 50;
148 do {
149 std::this_thread::sleep_for(std::chrono::seconds(1));
150 if (ConnectMultimodalInputService()) {
151 MMI_LOGD("connect multimodal input connect service successful");
152 return;
153 }
154 } while (--retryCount > 0);
155
156 MMI_LOGI("leave");
157 }
158 } // namespace MMI
159 } // namespace OHOS
160