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 "on_demand_start_stop_sa.h"
17
18 #include "global.h"
19 #include "iservice_registry.h"
20 #include "system_ability_definition.h"
21
22 namespace OHOS {
23 namespace MiscServices {
24 std::atomic<uint32_t> OnDemandStartStopSa::processingIpcCount_ { 0 };
LoadInputMethodSystemAbility()25 sptr<IRemoteObject> OnDemandStartStopSa::LoadInputMethodSystemAbility()
26 {
27 std::unique_lock<std::mutex> lock(loadSaMtx_);
28 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
29 if (systemAbilityManager == nullptr) {
30 IMSA_HILOGE("get system ability manager fail");
31 return nullptr;
32 }
33
34 auto remoteObject = systemAbilityManager->CheckSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID);
35 if (remoteObject != nullptr) {
36 return remoteObject;
37 }
38
39 auto sharedThis = shared_from_this();
40 sptr<SaLoadCallback> callback = new (std::nothrow) SaLoadCallback(sharedThis);
41 if (callback == nullptr) {
42 IMSA_HILOGE("LoadCallback new fail.");
43 return nullptr;
44 }
45
46 int32_t ret = systemAbilityManager->LoadSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, callback);
47 if (ret != ERR_OK) {
48 IMSA_HILOGE("load input method system ability fail, ret: %{public}d", ret);
49 return nullptr;
50 }
51
52 loadSaCv_.wait_for(lock, std::chrono::seconds(LOAD_SA_MAX_WAIT_TIME), [&sharedThis]() {
53 return sharedThis->remoteObj_ != nullptr;
54 });
55
56 return remoteObj_;
57 }
58
UnloadInputMethodSystemAbility()59 void OnDemandStartStopSa::UnloadInputMethodSystemAbility()
60 {
61 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
62 if (systemAbilityManager == nullptr) {
63 IMSA_HILOGE("get system ability manager fail");
64 return;
65 }
66
67 int32_t ret = systemAbilityManager->UnloadSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID);
68 if (ret != ERR_OK) {
69 IMSA_HILOGE("unload input method system ability fail, ret: %{public}d", ret);
70 return;
71 }
72 IMSA_HILOGI("unload input method system ability success");
73 }
74
OnLoadSystemAbilitySuccess(int32_t said,const sptr<IRemoteObject> & object)75 void OnDemandStartStopSa::SaLoadCallback::OnLoadSystemAbilitySuccess(int32_t said, const sptr<IRemoteObject> &object)
76 {
77 IMSA_HILOGI("load inputmethod sa success");
78 if (onDemandObj_ == nullptr) {
79 IMSA_HILOGE("onDemandObj is null");
80 return;
81 }
82 std::unique_lock<std::mutex> lock(onDemandObj_->loadSaMtx_);
83 onDemandObj_->remoteObj_ = object;
84 onDemandObj_->loadSaCv_.notify_all();
85 }
86
OnLoadSystemAbilityFail(int32_t said)87 void OnDemandStartStopSa::SaLoadCallback::OnLoadSystemAbilityFail(int32_t said)
88 {
89 IMSA_HILOGE("load inputmethod sa fail");
90 if (onDemandObj_ == nullptr) {
91 IMSA_HILOGE("onDemandObj is null");
92 return;
93 }
94 std::unique_lock<std::mutex> lock(onDemandObj_->loadSaMtx_);
95 onDemandObj_->remoteObj_ = nullptr;
96 onDemandObj_->loadSaCv_.notify_all();
97 }
98
GetInputMethodSystemAbility(bool ifRetry)99 sptr<IRemoteObject> OnDemandStartStopSa::GetInputMethodSystemAbility(bool ifRetry)
100 {
101 sptr<ISystemAbilityManager> systemAbilityManager =
102 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
103 if (systemAbilityManager == nullptr) {
104 IMSA_HILOGE("system ability manager is nullptr!");
105 return nullptr;
106 }
107
108 sptr<IRemoteObject> systemAbility = nullptr;
109 if (!ifRetry) {
110 systemAbility = systemAbilityManager->CheckSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID);
111 if (systemAbility == nullptr) {
112 IMSA_HILOGE("check system ability is nullptr!");
113 return nullptr;
114 }
115 return systemAbility;
116 }
117
118 #ifdef IMF_ON_DEMAND_START_STOP_SA_ENABLE
119 auto onDemandStartStopSa = std::make_shared<OnDemandStartStopSa>();
120 systemAbility = onDemandStartStopSa->LoadInputMethodSystemAbility();
121 if (systemAbility == nullptr) {
122 IMSA_HILOGE("load system ability fail");
123 return nullptr;
124 }
125 #else
126 systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID);
127 if (systemAbility == nullptr) {
128 IMSA_HILOGE("get system ability is nullptr!");
129 return nullptr;
130 }
131 #endif
132 return systemAbility;
133 }
134
IncreaseProcessingIpcCnt()135 void OnDemandStartStopSa::IncreaseProcessingIpcCnt()
136 {
137 processingIpcCount_.fetch_add(1);
138 }
DecreaseProcessingIpcCnt()139 void OnDemandStartStopSa::DecreaseProcessingIpcCnt()
140 {
141 processingIpcCount_.fetch_sub(1);
142 }
IsSaBusy()143 bool OnDemandStartStopSa::IsSaBusy()
144 {
145 return processingIpcCount_.load() > 0;
146 }
147 } // namespace MiscServices
148 } // namespace OHOS