• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "cj_inputmethod_extension.h"
17 #include "ability_handler.h"
18 #include "configuration_utils.h"
19 #include "global.h"
20 #include "inputmethod_extension_ability_service_impl.h"
21 #include "inputmethod_trace.h"
22 #include "iservice_registry.h"
23 #include "system_ability_definition.h"
24 #include "task_manager.h"
25 #include "tasks/task_ams.h"
26 #include "tasks/task_imsa.h"
27 
28 namespace OHOS {
29 namespace AbilityRuntime {
30 
31 CjInputMethodExtension *CjInputMethodExtension::cjInputMethodExtension = nullptr;
32 using namespace OHOS::AppExecFwk;
33 using namespace OHOS::MiscServices;
34 
35 constexpr int32_t SUCCESS_CODE = 0;
36 
OHOS_ABILITY_CjInputMethodExtension()37 extern "C" __attribute__((visibility("default"))) InputMethodExtension *OHOS_ABILITY_CjInputMethodExtension()
38 {
39     return new (std::nothrow) CjInputMethodExtension();
40 }
41 
CjInputMethodExtension()42 CjInputMethodExtension::CjInputMethodExtension() { }
43 
~CjInputMethodExtension()44 CjInputMethodExtension::~CjInputMethodExtension()
45 {
46     IMSA_HILOGD("~CjInputMethodExtension");
47     auto context = GetContext();
48     if (context != nullptr) {
49         context->Unbind();
50     }
51     cjObj_.Destroy();
52 }
53 
Init(const std::shared_ptr<AbilityLocalRecord> & record,const std::shared_ptr<OHOSApplication> & application,std::shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)54 void CjInputMethodExtension::Init(const std::shared_ptr<AbilityLocalRecord> &record,
55     const std::shared_ptr<OHOSApplication> &application, std::shared_ptr<AbilityHandler> &handler,
56     const sptr<IRemoteObject> &token)
57 {
58     IMSA_HILOGD("initalize CjInputMethodExtension");
59     InputMethodExtension::Init(record, application, handler, token);
60     // init and bindContext
61     int32_t ret = cjObj_.Init(abilityInfo_->name, this);
62     if (ret != SUCCESS_CODE) {
63         IMSA_HILOGE("initalization failed");
64         return;
65     }
66     handler_ = handler;
67     InitDisplayCache();
68     ListenWindowManager();
69     IMSA_HILOGI("initalize success");
70 }
71 
ListenWindowManager()72 void CjInputMethodExtension::ListenWindowManager()
73 {
74     IMSA_HILOGD("register window manager service listener.");
75     auto abilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
76     if (abilityManager == nullptr) {
77         IMSA_HILOGE("failed to get SaMgr!");
78         return;
79     }
80 
81     auto cjInputMethodExtension = std::static_pointer_cast<CjInputMethodExtension>(shared_from_this());
82     displayListener_ = sptr<CjInputMethodExtensionDisplayListener>::MakeSptr(cjInputMethodExtension);
83     if (displayListener_ == nullptr) {
84         IMSA_HILOGE("failed to create display listener!");
85         return;
86     }
87 
88     auto listener = sptr<SystemAbilityStatusChangeListener>::MakeSptr(displayListener_);
89     if (listener == nullptr) {
90         IMSA_HILOGE("failed to create status change listener!");
91         return;
92     }
93 
94     auto ret = abilityManager->SubscribeSystemAbility(WINDOW_MANAGER_SERVICE_ID, listener);
95     if (ret != 0) {
96         IMSA_HILOGE("failed to subscribe system ability, ret: %{public}d!", ret);
97     }
98 }
99 
OnConfigurationUpdated(const AppExecFwk::Configuration & config)100 void CjInputMethodExtension::OnConfigurationUpdated(const AppExecFwk::Configuration &config) { }
101 
ConfigurationUpdated()102 void CjInputMethodExtension::ConfigurationUpdated() { }
103 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)104 void CjInputMethodExtension::SystemAbilityStatusChangeListener::OnAddSystemAbility(
105     int32_t systemAbilityId, const std::string &deviceId)
106 {
107     IMSA_HILOGD("add systemAbilityId: %{public}d.", systemAbilityId);
108     if (systemAbilityId == WINDOW_MANAGER_SERVICE_ID) {
109         Rosen::DisplayManager::GetInstance().RegisterDisplayListener(listener_);
110     }
111 }
112 
OnStart(const AAFwk::Want & want)113 void CjInputMethodExtension::OnStart(const AAFwk::Want &want)
114 {
115     auto task = std::make_shared<TaskAmsInit>();
116     TaskManager::GetInstance().PostTask(task);
117     InputMethodAbility::GetInstance().InitConnect();
118     StartAsync("OnStart", static_cast<int32_t>(TraceTaskId::ONSTART_EXTENSION));
119     StartAsync("Extension::OnStart", static_cast<int32_t>(TraceTaskId::ONSTART_MIDDLE_EXTENSION));
120     Extension::OnStart(want);
121     FinishAsync("Extension::OnStart", static_cast<int32_t>(TraceTaskId::ONSTART_MIDDLE_EXTENSION));
122     IMSA_HILOGI("CjInputMethodExtension OnStart begin.");
123     StartAsync("onCreate", static_cast<int32_t>(TraceTaskId::ONCREATE_EXTENSION));
124     cjObj_.OnCreate(want);
125     FinishAsync("onCreate", static_cast<int32_t>(TraceTaskId::ONCREATE_EXTENSION));
126     TaskManager::GetInstance().PostTask(std::make_shared<TaskImsaSetCoreAndAgent>());
127     IMSA_HILOGI("ime bind imf");
128     FinishAsync("OnStart", static_cast<int32_t>(TraceTaskId::ONSTART_EXTENSION));
129     TaskManager::GetInstance().Complete(task->GetSeqId());
130 }
131 
InitDisplayCache()132 void CjInputMethodExtension::InitDisplayCache()
133 {
134     auto foldStatus = Rosen::DisplayManager::GetInstance().GetFoldStatus();
135     auto displayPtr = Rosen::DisplayManager::GetInstance().GetDefaultDisplaySync();
136     if (displayPtr == nullptr) {
137         IMSA_HILOGE("displayPtr is null");
138         return;
139     }
140     cacheDisplay_.SetCacheDisplay(
141         displayPtr->GetWidth(), displayPtr->GetHeight(), displayPtr->GetRotation(), foldStatus);
142 }
143 
OnStop()144 void CjInputMethodExtension::OnStop()
145 {
146     InputMethodExtension::OnStop();
147     IMSA_HILOGI("CjInputMethodExtension OnStop start.");
148     cjObj_.OnDestroy();
149     auto context = GetContext();
150     if (context == nullptr) {
151         IMSA_HILOGE("context is invalid!");
152         return;
153     }
154     bool ret = ConnectionManager::GetInstance().DisconnectCaller(context->GetToken());
155     if (ret) {
156         IMSA_HILOGI("the input method extension connection is not disconnected.");
157     }
158     IMSA_HILOGI("CjInputMethodExtension OnStop end.");
159 }
160 
OnConnect(const AAFwk::Want & want)161 sptr<IRemoteObject> CjInputMethodExtension::OnConnect(const AAFwk::Want &want)
162 {
163     IMSA_HILOGI("CjInputMethodExtension OnConnect start.");
164     Extension::OnConnect(want);
165     auto remoteObj = new (std::nothrow) InputMethodExtensionAbilityServiceImpl();
166     if (remoteObj == nullptr) {
167         IMSA_HILOGE("failed to create InputMethodExtensionAbilityServiceImpl!");
168         return nullptr;
169     }
170     return remoteObj;
171 }
172 
OnDisconnect(const AAFwk::Want & want)173 void CjInputMethodExtension::OnDisconnect(const AAFwk::Want &want) { }
174 
OnCommand(const AAFwk::Want & want,bool restart,int startId)175 void CjInputMethodExtension::OnCommand(const AAFwk::Want &want, bool restart, int startId) { }
176 
OnCreate(Rosen::DisplayId displayId)177 void CjInputMethodExtension::OnCreate(Rosen::DisplayId displayId)
178 {
179     IMSA_HILOGD("enter");
180 }
181 
OnDestroy(Rosen::DisplayId displayId)182 void CjInputMethodExtension::OnDestroy(Rosen::DisplayId displayId)
183 {
184     IMSA_HILOGD("exit");
185 }
186 
CheckNeedAdjustKeyboard(Rosen::DisplayId displayId)187 void CjInputMethodExtension::CheckNeedAdjustKeyboard(Rosen::DisplayId displayId)
188 {
189     auto displayPtr = Rosen::DisplayManager::GetInstance().GetDefaultDisplaySync();
190     if (displayPtr == nullptr) {
191         return;
192     }
193     auto defaultDisplayId = displayPtr->GetId();
194     if (displayId != defaultDisplayId) {
195         return;
196     }
197     auto foldStatus = Rosen::DisplayManager::GetInstance().GetFoldStatus();
198     auto width = displayPtr->GetWidth();
199     auto height = displayPtr->GetHeight();
200     auto rotation = displayPtr->GetRotation();
201     IMSA_HILOGD("display width: %{public}d, height: %{public}d, rotation: %{public}d, foldStatus: %{public}d",
202         width, height, rotation, foldStatus);
203     if (!cacheDisplay_.IsEmpty()) {
204         if ((cacheDisplay_.displayWidth != width ||
205                 cacheDisplay_.displayHeight != height) &&
206             cacheDisplay_.displayFoldStatus == foldStatus &&
207             cacheDisplay_.displayRotation == rotation) {
208             InputMethodAbility::GetInstance().AdjustKeyboard();
209         }
210     }
211     cacheDisplay_.SetCacheDisplay(width, height, rotation, foldStatus);
212 }
213 
OnChange(Rosen::DisplayId displayId)214 void CjInputMethodExtension::OnChange(Rosen::DisplayId displayId)
215 {
216     IMSA_HILOGD("displayId: %{public}" PRIu64 "", displayId);
217     auto context = GetContext();
218     if (context == nullptr) {
219         IMSA_HILOGE("context is invalid!");
220         return;
221     }
222 
223     auto contextConfig = context->GetConfiguration();
224     if (contextConfig == nullptr) {
225         IMSA_HILOGE("configuration is invalid!");
226         return;
227     }
228 
229     bool isConfigChanged = false;
230     auto configUtils = std::make_shared<ConfigurationUtils>();
231     configUtils->UpdateDisplayConfig(displayId, contextConfig, context->GetResourceManager(), isConfigChanged);
232     IMSA_HILOGD("OnChange, isConfigChanged: %{public}d, Config after update: %{public}s.", isConfigChanged,
233         contextConfig->GetName().c_str());
234 
235     if (!isConfigChanged) {
236         return;
237     }
238     auto inputMethodExtension = std::static_pointer_cast<CjInputMethodExtension>(shared_from_this());
239     auto task = [inputMethodExtension]() {
240         if (inputMethodExtension) {
241             inputMethodExtension->ConfigurationUpdated();
242         }
243     };
244     if (handler_ != nullptr) {
245         handler_->PostTask(task, "CjInputMethodExtension:OnChange", 0, AppExecFwk::EventQueue::Priority::VIP);
246     }
247 }
248 } // namespace AbilityRuntime
249 } // namespace OHOS
250