• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef FEATURE_GNSS_SUPPORT
17 #include "agnss_ni_manager.h"
18 
19 #ifdef SMS_MMS_ENABLE
20 #include "call_manager_client.h"
21 #include "sms_service_manager_client.h"
22 #endif
23 #include "gnss_ability.h"
24 #include "idevmgr_hdi.h"
25 #include "iservice_registry.h"
26 #include "location_data_rdb_manager.h"
27 #include "location_log.h"
28 #include "nlohmann/json.hpp"
29 #ifdef NOTIFICATION_ENABLE
30 #include "notification_helper.h"
31 #endif
32 #include "securec.h"
33 #include "string_utils.h"
34 #include "system_ability_definition.h"
35 #include "ui_extension_ability_connection.h"
36 #include "want_agent_helper.h"
37 #include "want_agent_info.h"
38 
39 namespace OHOS {
40 namespace Location {
41 using namespace EventFwk;
42 constexpr uint32_t MAX_RETRY_TIMES = 3;
43 constexpr uint32_t TIME_AFTER_EMERGENCY_CALL = 10 * 1000;
44 constexpr int32_t INVALID_SUBID = -1;
45 const std::string URN_APPLICATION_ID = "x-oma-application:ulp.ua";
46 const std::string AGNSS_NI_SERVICE_NAME = "agnss_ni";
47 const std::string LOCATION_DIALOG_BUNDLE_NAME = "com.ohos.locationdialog";
48 const std::string AGNSS_NI_DIALOG_ABILITY_NAME = "ConfirmUIExtAbility";
49 #ifdef NOTIFICATION_ENABLE
50 const int32_t GNSS_AGNSS_NI_NOTIFICATION_ID = LOCATION_GNSS_SA_ID * 100;
51 constexpr uint32_t NOTIFICATION_AUTO_DELETED_TIME = 1000;
52 #endif
53 
GetInstance()54 AGnssNiManager* AGnssNiManager::GetInstance()
55 {
56     static AGnssNiManager data;
57     return &data;
58 }
59 
AGnssNiManager()60 AGnssNiManager::AGnssNiManager()
61 {}
62 
~AGnssNiManager()63 AGnssNiManager::~AGnssNiManager()
64 {}
65 
SubscribeSaStatusChangeListerner()66 void AGnssNiManager::SubscribeSaStatusChangeListerner()
67 {
68     LBSLOGI(GNSS, "AGNSS-NI SubscribeSaStatusChangeListerner");
69     sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
70     if (samgrProxy == nullptr) {
71         LBSLOGE(GNSS, "failed to get samgrProxy");
72         return;
73     }
74     statusChangeListener_ = new SystemAbilityStatusChangeListener();
75     if (statusChangeListener_ == nullptr) {
76         LBSLOGE(GNSS, "statusChangeListener_ is nullptr!");
77         return;
78     }
79     int32_t ret = samgrProxy->SubscribeSystemAbility(COMMON_EVENT_SERVICE_ID, statusChangeListener_);
80     if (ret != ERR_OK) {
81         LBSLOGE(GNSS, "subscribe systemAbilityId: call manager service failed!");
82         return;
83     }
84 }
85 
RegisterAgnssNiEvent()86 void AGnssNiManager::RegisterAgnssNiEvent()
87 {
88     MatchingSkills matchingSkills;
89     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SMS_WAPPUSH_RECEIVE_COMPLETED);
90     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SMS_RECEIVE_COMPLETED);
91     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_CALL_STATE_CHANGED);
92     CommonEventSubscribeInfo subscriberInfo(matchingSkills);
93     subscriber_ = std::make_shared<GnssCommonEventSubscriber>(subscriberInfo);
94 
95     uint32_t count = 0;
96     bool result = false;
97     while (!result && count <= MAX_RETRY_TIMES) {
98         result = CommonEventManager::SubscribeCommonEvent(subscriber_);
99         count++;
100     }
101     if (count > MAX_RETRY_TIMES || !result) {
102         LBSLOGE(GNSS, "Failed to subscriber gnss event");
103     } else {
104         LBSLOGI(GNSS, "success to subscriber gnss event");
105     }
106 }
107 
RegisterNiResponseEvent()108 void AGnssNiManager::RegisterNiResponseEvent()
109 {
110     MatchingSkills matchingSkills;
111     matchingSkills.AddEvent(AGNSS_NI_ACCEPT_EVENT);
112     matchingSkills.AddEvent(AGNSS_NI_REJECT_EVENT);
113     CommonEventSubscribeInfo subscriberInfo(matchingSkills);
114     subscriberInfo.SetPermission("ohos.permission.PUBLISH_LOCATION_EVENT");
115     niResponseSubscriber_ = std::make_shared<GnssCommonEventSubscriber>(subscriberInfo);
116 
117     uint32_t count = 0;
118     bool result = false;
119     while (!result && count <= MAX_RETRY_TIMES) {
120         result = CommonEventManager::SubscribeCommonEvent(niResponseSubscriber_);
121         count++;
122     }
123     if (count > MAX_RETRY_TIMES || !result) {
124         LBSLOGE(GNSS, "Failed to subscriber ni response event");
125     } else {
126         LBSLOGI(GNSS, "success to subscriber ni response event");
127     }
128 }
129 
Run()130 void AGnssNiManager::Run()
131 {
132     LBSLOGI(GNSS, "AGNSS-NI: Run");
133     RegisterAgnssNiEvent();
134     RegisterNiResponseEvent();
135     sptr<IGnssInterface> gnssInterface = HDI::Location::Gnss::V2_0::IGnssInterface::Get();
136     if (gnssInterface == nullptr) {
137         auto gnssAbility = GnssAbility::GetInstance();
138         if (!gnssAbility->CheckIfHdiConnected()) {
139             gnssAbility->ConnectHdi();
140             gnssInterface = HDI::Location::Gnss::V2_0::IGnssInterface::Get();
141         }
142     }
143 }
144 
UnRegisterAgnssNiEvent()145 void AGnssNiManager::UnRegisterAgnssNiEvent()
146 {
147     if (subscriber_ == nullptr) {
148         LBSLOGE(GNSS, "UnRegisterAgnssNiEvent subscriber_ is null");
149         return;
150     }
151     bool result = CommonEventManager::UnSubscribeCommonEvent(subscriber_);
152     subscriber_ = nullptr;
153     LBSLOGI(GNSS, "unSubscriber gnss event, result = %{public}d", result);
154 }
155 
UnRegisterNiResponseEvent()156 void AGnssNiManager::UnRegisterNiResponseEvent()
157 {
158     if (niResponseSubscriber_ == nullptr) {
159         LBSLOGE(GNSS, "UnRegisterAgnssNiEvent subscriber_ is null");
160         return;
161     }
162     bool result = CommonEventManager::UnSubscribeCommonEvent(niResponseSubscriber_);
163     niResponseSubscriber_ = nullptr;
164     LBSLOGI(GNSS, "unSubscriber ni response event, result = %{public}d", result);
165 }
166 
AgnssNiSuplInit()167 void AGnssNiManager::AgnssNiSuplInit()
168 {
169 #ifdef HDF_DRIVERS_INTERFACE_AGNSS_ENABLE
170     auto gnssAbility = GnssAbility::GetInstance();
171     if (gnssAbility != nullptr) {
172         gnssAbility->SetAgnssServer();
173     }
174 #endif
175 }
176 
177 #ifdef SMS_MMS_ENABLE
IsFromDefaultSubId(const OHOS::EventFwk::Want & want)178 static bool IsFromDefaultSubId(const OHOS::EventFwk::Want &want)
179 {
180     int32_t subId = want.GetIntParam("slotId", INVALID_SUBID);
181     int32_t defaultId = Singleton<Telephony::SmsServiceManagerClient>::GetInstance().GetDefaultSmsSlotId();
182     LBSLOGD(GNSS, "current subId %{public}d, defaultSubId %{public}d", subId, defaultId);
183     if (subId != INVALID_SUBID && subId != defaultId) {
184         return false;
185     }
186     return true;
187 }
188 #endif
189 
CheckWapSuplInit(const EventFwk::Want & want)190 void AGnssNiManager::CheckWapSuplInit(const EventFwk::Want &want)
191 {
192 #ifdef SMS_MMS_ENABLE
193     AgnssNiSuplInit();
194     if (!IsFromDefaultSubId(want)) {
195         LBSLOGE(GNSS, "supl init message does not come from default sub");
196         return;
197     }
198 
199     std::string applicationId = want.GetStringParam("applicationId");
200     /*
201      * The WAP application id SHALL be as registered with OMNA (URN: x-oma-application:ulp.ua)
202      * and the assigned code value is (0x10).
203      */
204     if (!(applicationId == "16" || applicationId == URN_APPLICATION_ID)) {
205         LBSLOGE(GNSS, "supl init message application Id %{public}s", applicationId.c_str());
206         return;
207     }
208 
209     std::string rawData = want.GetStringParam("rawData");
210     sptr<IGnssInterface> gnssInterface = HDI::Location::Gnss::V2_0::IGnssInterface::Get();
211     if (gnssInterface == nullptr) {
212         LBSLOGE(GNSS, "gnssInterfacev1_0 is nullptr");
213         return;
214     }
215     gnssInterface->SendNetworkInitiatedMsg(rawData, rawData.length());
216 #endif
217 }
218 
CheckSmsSuplInit(const EventFwk::Want & want)219 void AGnssNiManager::CheckSmsSuplInit(const EventFwk::Want &want)
220 {
221 #ifdef SMS_MMS_ENABLE
222     AgnssNiSuplInit();
223     if (!IsFromDefaultSubId(want)) {
224         LBSLOGE(GNSS, "supl init message does not come from default sub");
225         return;
226     }
227 
228     std::vector<std::string> pdus = want.GetStringArrayParam(std::string("pdus"));
229     if (pdus.empty()) {
230         LBSLOGI(GNSS, "pdus is null");
231         return;
232     }
233     bool isCdma = want.GetBoolParam("isCdma", false);
234     std::vector<unsigned char> pdu = StringUtils::HexToByteVector(pdus[0]);
235     auto message = new Telephony::ShortMessage();
236     std::u16string netType = isCdma ? u"3gpp2" : u"3gpp";
237     Telephony::ShortMessage::CreateMessage(pdu, netType, *message);
238 
239     if (message != nullptr) {
240         std::string rawUserData = StringUtils::StringToHex(message->GetRawUserData());
241         sptr<IGnssInterface> gnssInterface = HDI::Location::Gnss::V2_0::IGnssInterface::Get();
242         if (gnssInterface == nullptr) {
243             LBSLOGE(GNSS, "gnssInterfacev1_0 is nullptr");
244             delete message;
245             message = nullptr;
246             return;
247         }
248         gnssInterface->SendNetworkInitiatedMsg(rawUserData, rawUserData.length());
249         delete message;
250         message = nullptr;
251     }
252 #endif
253 }
254 
IsInEmergency()255 bool AGnssNiManager::IsInEmergency()
256 {
257     std::unique_lock<std::mutex> lock(callStateMutex_);
258     bool isInEmergencyExtension = (emergencyCallEndTime_ > 0) &&
259         ((CommonUtils::GetCurrentTime() - emergencyCallEndTime_) < TIME_AFTER_EMERGENCY_CALL);
260 
261     return isInEmergencyCall_ || isInEmergencyExtension;
262 }
263 
OnCallStateChanged(const EventFwk::Want & want)264 void AGnssNiManager::OnCallStateChanged(const EventFwk::Want &want)
265 {
266 #ifdef CALL_MANAGER_ENABLE
267     int32_t state = want.GetIntParam("state", (int32_t)Telephony::TelCallState::CALL_STATUS_UNKNOWN);
268     if (state == (int32_t)Telephony::TelCallState::CALL_STATUS_DIALING) {
269         int32_t slotId = want.GetIntParam("slotId", -1);
270         std::string phoneNumber = want.GetStringParam("number");
271         auto tmpPhoneNumber = Str8ToStr16(phoneNumber);
272         std::unique_lock<std::mutex> lock(callStateMutex_);
273         auto clientPtr = DelayedSingleton<Telephony::CallManagerClient>::GetInstance();
274         clientPtr->Init(OHOS::TELEPHONY_CALL_MANAGER_SYS_ABILITY_ID);
275         clientPtr->IsEmergencyPhoneNumber(tmpPhoneNumber, slotId, isInEmergencyCall_);
276         if (isInEmergencyCall_) {
277             emergencyCallEndTime_ = CommonUtils::GetCurrentTime();
278             isInEmergencyCall_ = false;
279         }
280     }
281     return;
282 #endif
283 }
284 
BuildStartCommand(const GnssNiNotificationRequest & notif)285 std::string AGnssNiManager::BuildStartCommand(const GnssNiNotificationRequest &notif)
286 {
287     nlohmann::json param;
288     std::string uiType = "sysDialog/common";
289     param["ability.want.params.uiExtensionType"] = uiType;
290     std::string message = DecodeNiString(notif.supplicantInfo, notif.supplicantInfoEncoding) +
291         DecodeNiString(notif.notificationText, notif.notificationTextEncoding);
292     param["message"] = message;
293     std::string cmdData = param.dump();
294     LBSLOGD(GNSS, "cmdData is: %{public}s.", cmdData.c_str());
295     return cmdData;
296 }
297 
ConnectExtensionAbility(const AAFwk::Want & want,const std::string & commandStr)298 static void ConnectExtensionAbility(const AAFwk::Want &want, const std::string &commandStr)
299 {
300     std::string bundleName = LOCATION_DIALOG_BUNDLE_NAME;
301     std::string abilityName = AGNSS_NI_DIALOG_ABILITY_NAME;
302     sptr<UIExtensionAbilityConnection> connection(
303         new (std::nothrow) UIExtensionAbilityConnection(commandStr, bundleName, abilityName));
304     if (connection == nullptr) {
305         LBSLOGE(GNSS, "connect UIExtensionAbilityConnection fail");
306         return;
307     }
308 
309     std::string identity = IPCSkeleton::ResetCallingIdentity();
310     auto ret =
311         AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(want, connection, nullptr, -1);
312     LBSLOGI(GNSS, "connect service extension ability result = %{public}d", ret);
313     IPCSkeleton::SetCallingIdentity(identity);
314     return;
315 }
316 
OpenNiDialog(const GnssNiNotificationRequest & notif)317 void AGnssNiManager::OpenNiDialog(const GnssNiNotificationRequest &notif)
318 {
319     LBSLOGI(GNSS, "ConnectExtension");
320     AAFwk::Want want;
321     std::string bundleName = "com.ohos.sceneboard";
322     std::string abilityName = "com.ohos.sceneboard.systemdialog";
323     want.SetElementName(bundleName, abilityName);
324     std::string connectStr = BuildStartCommand(notif);
325     ConnectExtensionAbility(want, connectStr);
326 }
327 
DecodeNiString(std::string original,int coding)328 std::string AGnssNiManager::DecodeNiString(std::string original, int coding)
329 {
330     if (coding == GNSS_NI_ENCODING_FORMAT_NULL) {
331         return original;
332     }
333 
334     std::string tmp = StringUtils::HexToString(original);
335     switch (coding) {
336         case GNSS_NI_ENCODING_FORMAT_SUPL_GSM_DEFAULT: {
337             return StringUtils::Gsm7Decode(tmp);
338         }
339         case GNSS_NI_ENCODING_FORMAT_SUPL_UCS2: {
340             std::wstring decodedUCS2String = StringUtils::Ucs2ToWstring(tmp);
341             return StringUtils::WstringToString(decodedUCS2String);
342         }
343         case GNSS_NI_ENCODING_FORMAT_SUPL_UTF8: {
344             std::wstring decodedUTF8String = StringUtils::Utf8ToWstring(tmp);
345             return StringUtils::WstringToString(decodedUTF8String);
346         }
347         default: {
348             LBSLOGE(GNSS, "unknow encoding %{public}d for NI text %{public}s", coding, original.c_str());
349             return original;
350         }
351     }
352 }
353 
SendNiNotification(const GnssNiNotificationRequest & notif)354 void AGnssNiManager::SendNiNotification(const GnssNiNotificationRequest &notif)
355 {
356 #ifdef NOTIFICATION_ENABLE
357     std::shared_ptr<Notification::NotificationNormalContent> notificationNormalContent =
358         std::make_shared<Notification::NotificationNormalContent>();
359     std::string title = "Location Request";
360     std::string msgBody = DecodeNiString(notif.supplicantInfo, notif.supplicantInfoEncoding) +
361         DecodeNiString(notif.notificationText, notif.notificationTextEncoding);
362     if (msgBody.empty()) {
363         msgBody = "SUPL Service";
364     }
365     std::string message = "Requested by " + msgBody;
366     notificationNormalContent->SetTitle(title);
367     notificationNormalContent->SetText(message);
368     std::shared_ptr<OHOS::Notification::NotificationContent> notificationContent =
369         std::make_shared<OHOS::Notification::NotificationContent>(notificationNormalContent);
370     Notification::NotificationRequest request;
371     request.SetNotificationId(GNSS_AGNSS_NI_NOTIFICATION_ID);
372     request.SetContent(notificationContent);
373     request.SetCreatorUid(LOCATION_GNSS_SA_ID);
374     request.SetAutoDeletedTime(NOTIFICATION_AUTO_DELETED_TIME);
375     request.SetTapDismissed(true);
376     request.SetCreatorBundleName(AGNSS_NI_SERVICE_NAME);
377     request.SetSlotType(Notification::NotificationConstant::SlotType::SOCIAL_COMMUNICATION);
378 
379     int32_t ret = Notification::NotificationHelper::PublishNotification(request);
380     if (ret != 0) {
381         LBSLOGE(GNSS, "Publish Notification errorCode = %{public}d", ret);
382         return;
383     }
384     LBSLOGI(GNSS, "GNSS service publish notification success");
385 #else
386     LBSLOGI(GNSS, "GNSS service publish notification not support");
387 #endif
388 }
389 
SendUserResponse(GnssNiResponseCmd responseCmd)390 void AGnssNiManager::SendUserResponse(GnssNiResponseCmd responseCmd)
391 {
392     sptr<IGnssInterface> gnssInterface = HDI::Location::Gnss::V2_0::IGnssInterface::Get();
393     if (gnssInterface == nullptr) {
394         LBSLOGE(GNSS, "gnssInterfacev1_0 is nullptr");
395         return;
396     }
397     gnssInterface->SendNiUserResponse(niNotificationId_.load(), responseCmd);
398 }
399 
HandleNiNotification(const GnssNiNotificationRequest & notif)400 void AGnssNiManager::HandleNiNotification(const GnssNiNotificationRequest &notif)
401 {
402     niNotificationId_.store(notif.gnssNiNotificationId);
403     bool needNotify = (notif.notificationCategory & GNSS_NI_NOTIFICATION_REQUIRE_NOTIFY) != 0;
404     bool needVerify = (notif.notificationCategory & GNSS_NI_NOTIFICATION_REQUIRE_VERIFY) != 0;
405     bool privacyOverride = (notif.notificationCategory & GNSS_NI_NOTIFICATION_REQUIRE_PRIVACY_OVERRIDE) != 0;
406     if (LocationDataRdbManager::QuerySwitchState() != ENABLED && !IsInEmergency()) {
407         SendUserResponse(GNSS_NI_RESPONSE_CMD_NO_RESPONSE);
408     }
409 
410     if (needNotify) {
411         if (needVerify) {
412             OpenNiDialog(notif);
413         } else {
414             SendNiNotification(notif);
415             SendUserResponse(GNSS_NI_RESPONSE_CMD_ACCEPT);
416         }
417     }
418 
419     if (!needNotify || privacyOverride) {
420         SendUserResponse(GNSS_NI_RESPONSE_CMD_ACCEPT);
421     }
422 }
423 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)424 void SystemAbilityStatusChangeListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
425 {
426     LBSLOGI(GNSS, "AGNSS-NI systemAbilityId:%{public}d", systemAbilityId);
427     if (systemAbilityId != COMMON_EVENT_SERVICE_ID) {
428         LBSLOGE(GNSS, "systemAbilityId is not COMMON_EVENT_SERVICE_ID");
429         return;
430     }
431     auto agnssNiManager = AGnssNiManager::GetInstance();
432     agnssNiManager->Run();
433 
434     return;
435 }
436 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)437 void SystemAbilityStatusChangeListener::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
438 {
439     LBSLOGI(GNSS, "AGNSS-NI systemAbilityId:%{public}d", systemAbilityId);
440     if (systemAbilityId != COMMON_EVENT_SERVICE_ID) {
441         LBSLOGE(GNSS, "systemAbilityId is not COMMON_EVENT_SERVICE_ID");
442         return;
443     }
444     auto agnssNiManager = AGnssNiManager::GetInstance();
445     agnssNiManager->UnRegisterAgnssNiEvent();
446     agnssNiManager->UnRegisterNiResponseEvent();
447     return;
448 }
449 
450 #ifdef NET_MANAGER_ENABLE
NetConnectionPropertiesChange(sptr<NetManagerStandard::NetHandle> & netHandle,const sptr<NetManagerStandard::NetLinkInfo> & info)451 int32_t AGnssNiNetworkCallbackEs::NetConnectionPropertiesChange(
452     sptr<NetManagerStandard::NetHandle> &netHandle, const sptr<NetManagerStandard::NetLinkInfo> &info)
453 {
454     return ERR_OK;
455 }
456 
NetLost(sptr<NetManagerStandard::NetHandle> & netHandle)457 int32_t AGnssNiNetworkCallbackEs::NetLost(sptr<NetManagerStandard::NetHandle> &netHandle)
458 {
459     return ERR_OK;
460 }
461 
NetUnavailable()462 int32_t AGnssNiNetworkCallbackEs::NetUnavailable()
463 {
464     return ERR_OK;
465 }
466 
NetConnectionPropertiesChange(sptr<NetManagerStandard::NetHandle> & netHandle,const sptr<NetManagerStandard::NetLinkInfo> & info)467 int32_t AGnssNiNetworkCallback::NetConnectionPropertiesChange(
468     sptr<NetManagerStandard::NetHandle> &netHandle, const sptr<NetManagerStandard::NetLinkInfo> &info)
469 {
470     return ERR_OK;
471 }
472 
NetLost(sptr<NetManagerStandard::NetHandle> & netHandle)473 int32_t AGnssNiNetworkCallback::NetLost(sptr<NetManagerStandard::NetHandle> &netHandle)
474 {
475     return ERR_OK;
476 }
477 
NetUnavailable()478 int32_t AGnssNiNetworkCallback::NetUnavailable()
479 {
480     return ERR_OK;
481 }
482 #endif
483 }  // namespace Location
484 }  // namespace OHOS
485 #endif
486