1/** 2 * Copyright (c) 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 */ 15import commonEvent from '@ohos.commonEventManager'; 16import telSim from '@ohos.telephony.sms'; 17import http from '@ohos.net.http'; 18 19import common from '../data/commonData'; 20import telephoneUtils from '../utils/TelephoneUtil'; 21import HiLog from '../utils/HiLog'; 22import commonService from '../service/CommonService'; 23import ConversationService from '../service/ConversationService'; 24import NotificationService from '../service/NotificationService'; 25import LooseObject from '../data/LooseObject' 26import ConversationListService from '../service/ConversationListService'; 27import ContactService from '../service/ContactsService'; 28 29const TAG: string = 'MmsStaticSubscriber' 30 31var StaticSubscriberExtensionAbility = globalThis.requireNapi('application.StaticSubscriberExtensionAbility'); 32 33export default class MmsStaticSubscriber extends StaticSubscriberExtensionAbility { 34 35 public onReceiveEvent(data): void { 36 HiLog.i(TAG, 'onReceiveEvent, event:' ); 37 if (data.event === common.string.SUBSCRIBER_EVENT) { 38 this.dealSmsReceiveData(data, this.context); 39 } else { 40 this.dealMmsReceiveData(data, this.context); 41 } 42 } 43 44 public async dealSmsReceiveData(data, context): Promise<void> { 45 let netType: string = data.parameters.isCdma ? '3gpp2' : '3gpp'; 46 // Synchronize wait operation 47 let promisesAll = []; 48 data.parameters.pdus.forEach(pdu => { 49 let promise = telSim.createMessage(this.convertStrArray(pdu), netType); 50 promisesAll.push(promise); 51 }); 52 let result: LooseObject = {}; 53 let createMessagePromise = Promise.all(promisesAll); 54 createMessagePromise.then(shortMsgList => { 55 result.code = common.int.SUCCESS; 56 result.telephone = telephoneUtils.formatTelephone(shortMsgList[0].visibleRawAddress); 57 result.content = common.string.EMPTY_STR; 58 shortMsgList.forEach(shortMessage => { 59 result.content += shortMessage.visibleMessageBody; 60 }); 61 }).catch(error => { 62 HiLog.e(TAG, 'dealSmsReceiveData, error: ' + JSON.stringify(error)); 63 result.code = common.int.FAILURE; 64 }); 65 await createMessagePromise; 66 let actionData: LooseObject = {}; 67 actionData.slotId = data.parameters.slotId; 68 actionData.telephone = result.telephone; 69 actionData.content = result.content; 70 actionData.isMms = false; 71 actionData.mmsSource = []; 72 this.insertMessageDetailBy(actionData, res => { 73 this.sendNotification(result.telephone, res.initDatas[0].id, result.content, context); 74 this.publishData(result.telephone, result.content); 75 }, context); 76 } 77 78 public dealMmsReceiveData(data, context): void { 79 let result = JSON.parse(data.data); 80 this.saveAttachment(result.mmsSource); 81 let content: string = commonService.getMmsContent(result.mmsSource); 82 let actionData: LooseObject = {}; 83 actionData.telephone = result.telephone; 84 actionData.content = content; 85 actionData.isMms = true; 86 actionData.mmsSource = result.mmsSource; 87 actionData.slotId = data.parameters.slotId; 88 this.insertMessageDetailBy(actionData, res => { 89 let notificationContent = this.getNotificationContent(result.mmsSource, content); 90 this.sendNotification(result.telephone, res.initDatas[0].id, notificationContent, context); 91 this.publishData(result.telephone, result.content); 92 }, context); 93 } 94 95 public saveAttachment(mmsSource): void { 96 for (let item of mmsSource) { 97 let baseUrl = item.msgUriPath; 98 let httpRequest = http.createHttp(); 99 httpRequest.request(common.string.MMS_URL, 100 { 101 method: http.RequestMethod.GET, 102 header: { 103 'Content-Type': 'application/json', 104 }, 105 extraData: baseUrl, 106 readTimeout: 50000, 107 connectTimeout: 50000 108 }, (err, data) => { 109 HiLog.i(TAG, 'saveAttachment, err: ' + JSON.stringify(err.message)); 110 } 111 ); 112 } 113 } 114 115 public getNotificationContent(mmsSource, themeContent): string { 116 let content: string = common.string.EMPTY_STR; 117 if (mmsSource.length === 1) { 118 let item = mmsSource[0]; 119 switch (item.msgType) { 120 // Subject 121 case 0: 122 content = themeContent; 123 break; 124 // Pictures 125 case 1: 126 content = '(picture)' + themeContent; 127 break; 128 // Video 129 case 2: 130 content = '(video)' + themeContent; 131 break; 132 // Audio 133 case 3: 134 content = '(audio)' + themeContent; 135 break; 136 } 137 } else { 138 content = '(slide)' + mmsSource[0].content; 139 } 140 return content; 141 } 142 143 public insertMessageDetailBy(param, callback, context): void { 144 let sendResults: Array<LooseObject> = []; 145 let sendResult: LooseObject = {}; 146 sendResult.slotId = param.slotId; 147 sendResult.telephone = param.telephone; 148 sendResult.content = param.content; 149 sendResult.sendStatus = common.int.SEND_MESSAGE_SUCCESS; 150 sendResults.push(sendResult); 151 152 let hasAttachment: boolean = commonService.judgeIsAttachment(param.mmsSource); 153 let actionData: LooseObject = {}; 154 actionData.slotId = param.slotId; 155 actionData.sendResults = sendResults; 156 actionData.isReceive = true; 157 actionData.ownNumber = common.string.EMPTY_STR; 158 actionData.isSender = true; 159 actionData.isMms = param.isMms; 160 actionData.mmsSource = param.mmsSource; 161 actionData.hasAttachment = hasAttachment; 162 ConversationService.getInstance().insertSessionAndDetail(actionData, callback, context); 163 } 164 165 public convertStrArray(sourceStr): Array<number> { 166 let wby: string = sourceStr; 167 let length: number = wby.length; 168 let isDouble: boolean = (length % 2) == 0; 169 let halfSize: number = parseInt('' + length / 2); 170 HiLog.i(TAG, 'convertStrArray, length=' + length + ', isDouble=' + isDouble); 171 if (isDouble) { 172 let number0xArray = new Array(halfSize); 173 for (let i = 0;i < halfSize; i++) { 174 number0xArray[i] = '0x' + wby.substr(i * 2, 2); 175 } 176 let numberArray = new Array(halfSize); 177 for (let i = 0;i < halfSize; i++) { 178 numberArray[i] = parseInt(number0xArray[i], 16); 179 } 180 return numberArray; 181 } else { 182 let number0xArray = new Array(halfSize + 1); 183 for (let i = 0;i < halfSize; i++) { 184 number0xArray[i] = '0x' + wby.substr(i * 2, 2); 185 } 186 number0xArray[halfSize] = '0x' + wby.substr((halfSize * 2) + 1, 1); 187 let numberArray = new Array(halfSize + 1); 188 for (let i = 0;i < halfSize; i++) { 189 numberArray[i] = parseInt(number0xArray[i], 16); 190 } 191 let last0x = '0x' + wby.substr(wby.length - 1, 1); 192 numberArray[halfSize] = parseInt(last0x); 193 return numberArray; 194 } 195 } 196 197 public publishData(telephone, content): void { 198 HiLog.i(TAG, 'publishData, start'); 199 let actionData = { 200 telephone: telephone, 201 content: content 202 }; 203 commonEvent.publish(common.string.RECEIVE_TRANSMIT_EVENT, { 204 bundleName: common.string.BUNDLE_NAME, 205 subscriberPermissions: ['ohos.permission.RECEIVE_SMS'], 206 isOrdered: false, 207 data: JSON.stringify(actionData) 208 }, (res) => { 209 }); 210 } 211 212 public sendNotification(telephone, msgId, content, context): void { 213 let condition: LooseObject = {}; 214 condition.telephones = [telephone]; 215 ContactService.getInstance().queryContactDataByCondition(condition, res => { 216 HiLog.i(TAG, 'sendNotification, callback'); 217 if (res.code == common.int.FAILURE) { 218 return; 219 } 220 let contacts: Array<LooseObject> = res.abilityResult; 221 let actionData: LooseObject = this.dealContactParams(contacts, telephone); 222 if (content.length > 15) { 223 content = content.substring(0, 15) + '...'; 224 } 225 let title: string = telephone; 226 if(contacts.length > 0) { 227 title = contacts[0].displayName 228 } 229 let message: LooseObject = { 230 'title': title, 231 'text': content, 232 }; 233 actionData.message = message; 234 actionData.msgId = msgId; 235 actionData.unreadTotal = 0; 236 NotificationService.getInstance().sendNotify(actionData); 237 ConversationListService.getInstance().statisticalData(res => { 238 if (res.code == common.int.SUCCESS) { 239 NotificationService.getInstance().setBadgeNumber(Number(res.response.totalListCount)); 240 } 241 }, context); 242 }, context); 243 } 244 245 public dealContactParams(contacts, telephone): LooseObject { 246 let actionData: LooseObject = {}; 247 let params: Array<LooseObject> = []; 248 if (contacts.length == 0) { 249 params.push({ 250 telephone: telephone, 251 }); 252 } else { 253 let contact: LooseObject = contacts[0]; 254 params.push({ 255 contactsName: contact.displayName, 256 telephone: telephone, 257 telephoneFormat: contact.detailInfo, 258 }); 259 } 260 actionData.contactObjects = JSON.stringify(params); 261 return actionData; 262 } 263} 264