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 <mutex>
17 #include <new>
18
19 #include "c/type_def.h"
20 #include "cpp/task.h"
21 #include "errors.h"
22 #include "extension_manager_client.h"
23 #include "message_option.h"
24 #include "singleton.h"
25 #include "telephony_errors.h"
26 #include "telephony_log_wrapper.h"
27 #include "want.h"
28
29 #include "number_identity_service.h"
30
31 namespace OHOS {
32 namespace Telephony {
33
34 using Client = AAFwk::ExtensionManagerClient;
35 using ffrt::qos_default;
36 using ffrt::task_attr;
37 using std::lock_guard;
38
39 inline constexpr const int USER_ID = 100;
40 const char *NUMBER_IDENTITY_BUNDLE_NAME = "com.numberidentity";
41 const char *NUMBER_IDENTITY_SERVICE_EXT_ABILITY = "NumberIdentityServiceExtAbility";
42
NumberIdentityConnection(ConnectedCallback onConnected,DisconnectedCallback onDisconnected)43 NumberIdentityConnection::NumberIdentityConnection(ConnectedCallback onConnected, DisconnectedCallback onDisconnected)
44 : connectedCallback_(onConnected), disconnectedCallback_(onDisconnected)
45 {
46 TELEPHONY_LOGI("Create connection.");
47 }
48
~NumberIdentityConnection()49 NumberIdentityConnection::~NumberIdentityConnection()
50 {
51 TELEPHONY_LOGI("Connection teardown.");
52 }
53
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)54 void NumberIdentityConnection::OnAbilityConnectDone(
55 const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int resultCode)
56 {
57 lock_guard lock(remoteProxyMutex_);
58 TELEPHONY_LOGI("NumberIdentityService connect done.");
59 if (remoteObject == nullptr) {
60 TELEPHONY_LOGE("remoteObject is nullptr.");
61 return;
62 }
63 remoteObject_ = remoteObject;
64 if (connectedCallback_ == nullptr) {
65 TELEPHONY_LOGE("connectedCallback_ is nullptr.");
66 return;
67 }
68 if (IsAlive()) {
69 ffrt::submit(std::bind(connectedCallback_, remoteObject_), task_attr().qos(qos_default::qos_background));
70 }
71 }
72
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)73 void NumberIdentityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
74 {
75 lock_guard lock(remoteProxyMutex_);
76 TELEPHONY_LOGI("NumberIdentityService disconnect done.");
77 remoteObject_ = nullptr;
78 if (disconnectedCallback_ == nullptr) {
79 TELEPHONY_LOGE("disconnectedCallback_ is nullptr.");
80 return;
81 }
82 ffrt::submit(disconnectedCallback_, task_attr().qos(qos_default::qos_background));
83 }
84
IsAlive()85 bool NumberIdentityConnection::IsAlive()
86 {
87 lock_guard lock(remoteProxyMutex_);
88 return remoteObject_ != nullptr && !remoteObject_->IsObjectDead();
89 }
90
GetAbilityProxy()91 sptr<IRemoteObject> NumberIdentityConnection::GetAbilityProxy()
92 {
93 lock_guard lock(remoteProxyMutex_);
94 return remoteObject_;
95 }
96
NumberIdentityServiceHelper()97 NumberIdentityServiceHelper::NumberIdentityServiceHelper()
98 {
99 TELEPHONY_LOGI("create helper");
100 }
101
Connect(ConnectedCallback onConnected,DisconnectedCallback onDisconnected)102 int NumberIdentityServiceHelper::Connect(ConnectedCallback onConnected, DisconnectedCallback onDisconnected)
103 {
104 lock_guard connectionLock(connectionMutex_);
105 if (connection_ != nullptr && connection_->IsAlive()) {
106 TELEPHONY_LOGI("Already connected, use old connection.");
107 auto remote = connection_->GetAbilityProxy();
108 ffrt::submit(std::bind(onConnected, remote), ffrt::task_attr().qos(ffrt::qos_default::qos_background));
109 return TELEPHONY_SUCCESS;
110 }
111 AAFwk::Want want;
112 want.SetElementName(NUMBER_IDENTITY_BUNDLE_NAME, NUMBER_IDENTITY_SERVICE_EXT_ABILITY);
113 connection_ = new (std::nothrow) NumberIdentityConnection(onConnected, onDisconnected);
114 if (connection_ == nullptr) {
115 TELEPHONY_LOGE("new NumberIdentityConnection failed.");
116 return TELEPHONY_ERR_LOCAL_PTR_NULL;
117 }
118 auto ret = Client::GetInstance().ConnectServiceExtensionAbility(want, connection_, USER_ID);
119 if (ret != ERR_OK) {
120 TELEPHONY_LOGE("ConnectServiceExtensionAbility failed, errCode = %{public}d", ret);
121 return TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL;
122 }
123 TELEPHONY_LOGI("Connect done.");
124 return TELEPHONY_SUCCESS;
125 }
126
Disconnect()127 void NumberIdentityServiceHelper::Disconnect()
128 {
129 lock_guard connectionLock(connectionMutex_);
130 if (connection_ == nullptr) {
131 TELEPHONY_LOGI("Already disconnected.");
132 return;
133 }
134 auto ret = Client::GetInstance().DisconnectAbility(connection_);
135 TELEPHONY_LOGI("DisconnectAbility errCode = %{public}d", ret);
136 connection_ = nullptr;
137 }
138
NotifyNumberMarkDataUpdate()139 void NumberIdentityServiceHelper::NotifyNumberMarkDataUpdate()
140 {
141 TELEPHONY_LOGI("Notify task update begin.");
142 auto &helper = DelayedRefSingleton<NumberIdentityServiceHelper>::GetInstance();
143 ConnectedCallback onConnected = [&helper](sptr<IRemoteObject> remote) {
144 if (helper.working_) {
145 TELEPHONY_LOGI("NumberIdentityService notify task is working, skip this notify.");
146 return;
147 }
148 helper.working_ = true;
149 TELEPHONY_LOGI("NumberIdentityService async notify begin.");
150 NumberIdentityServiceProxy service(remote);
151 service.NotifyNumberMarkDataUpdate();
152 DelayedRefSingleton<NumberIdentityServiceHelper>::GetInstance().Disconnect();
153 TELEPHONY_LOGI("NumberIdentityService async notify end.");
154 };
155 DisconnectedCallback onDisconnected = [&helper]() {
156 TELEPHONY_LOGI("NumberIdentityService notify task disconnected.");
157 helper.working_ = false;
158 };
159 auto ret = helper.Connect(onConnected, onDisconnected);
160 if (ret != TELEPHONY_SUCCESS) {
161 TELEPHONY_LOGE("Connect failed: ret = %{public}d", ret);
162 return;
163 }
164 TELEPHONY_LOGI("Notify task scheduled.");
165 }
166
NumberIdentityServiceProxy(const sptr<IRemoteObject> & remote)167 NumberIdentityServiceProxy::NumberIdentityServiceProxy(const sptr<IRemoteObject> &remote)
168 : IRemoteProxy<INumberIdentityService>(remote)
169 {
170 }
171
NotifyNumberMarkDataUpdate()172 void NumberIdentityServiceProxy::NotifyNumberMarkDataUpdate()
173 {
174 MessageParcel data;
175 MessageParcel reply;
176 MessageOption option;
177 auto remote = Remote();
178 if (remote == nullptr) {
179 TELEPHONY_LOGF("Remote is nullptr!");
180 return;
181 }
182 if (remote->IsObjectDead()) {
183 TELEPHONY_LOGE("Remote died.");
184 }
185 data.WriteInterfaceToken(GetDescriptor());
186 auto ret = remote->SendRequest(NumberIdentityServiceMessageCode::IMPORT_NUMBER_MARK_DATA_FILE, data, reply, option);
187 if (ret != ERR_OK) {
188 TELEPHONY_LOGE("SendRequest failed, ret = %{public}d", ret);
189 return;
190 }
191 ret = reply.ReadInt32();
192 if (ret != ERR_OK) {
193 TELEPHONY_LOGE("Notify failed, reply = %{public}d", ret);
194 return;
195 }
196 TELEPHONY_LOGI("Received ok reply, notify done.");
197 }
198
199 } // namespace Telephony
200 } // namespace OHOS