1/** 2 * Copyright (c) 2023 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 16import FuncBtn from './FuncBtn'; 17import InComDialog from './InComDialog'; 18import ImagePathConst from '../constant/ImagePathConst'; 19import CallStateConst from '../constant/CallStateConst'; 20import CallServiceProxy from '../../model/CallServiceProxy'; 21import sms from '@ohos.telephony.sms'; 22import resourceManager from '@ohos.resourceManager'; 23import prompt from '@system.prompt'; 24import LogUtils from '../utils/LogUtils'; 25import DefaultCallData from '../struct/TypeUtils'; 26import CallListStruct from '../struct/CallListStruct' 27import VibrationAndProximityUtils from '../utils/VibrationAndProximityUtils'; 28 29const TAG = "IncomingCom"; 30const SMS_REJECTION = `${ImagePathConst.BASE_URL}ic_public_message.svg`; 31 32/** 33 * SMS sent successfully 34 */ 35const SEND_SMS_SUCCESS = 0; 36 37/** 38 * Failed to send SMS for unknown reason 39 */ 40const SEND_SMS_FAILURE_UNKNOWN = 1; 41 42/** 43 * The wireless module for sending text messages is turned off 44 */ 45const SEND_SMS_FAILURE_RADIO_OFF = 2; 46 47/** 48 * The network sending the text message is unavailable 49 */ 50const SEND_SMS_FAILURE_SERVICE_UNAVAILABLE = 3; 51 52@Component 53export default struct IncomingCom { 54 @Link callList: Array<CallListStruct>; 55 @Link callData: DefaultCallData; 56 @Link hangup: boolean; 57 private btnList = []; 58 private msgList = []; 59 mCallServiceProxy: CallServiceProxy = null; 60 msgDialogController: CustomDialogController = new CustomDialogController 61 ({ 62 builder: InComDialog({ 63 cancel: () => { 64 }, 65 confirm: (item) => { 66 this.msgItemClick(item); 67 }, 68 cancelHandle: () => { 69 }, 70 // @ts-ignore 71 List: this.msgList 72 }), 73 cancel: () => { 74 }, 75 customStyle: true 76 }); 77 78 aboutToAppear() { 79 this.mCallServiceProxy = CallServiceProxy.getInstance(); 80 this.getMsgList(); 81 this.getBtnList(); 82 } 83 84 aboutToDisappear() { 85 this.msgDialogController = null; 86 } 87 88 /** 89 * send Message slotId : card slot, destinationHost : accountNumber ,content: content 90 * 91 * @param obj 92 */ 93 private sendMessage(obj) { 94 let slotId = this.callData.accountId; 95 let destinationHost = this.callData.accountNumber 96 let contactName = this.callData.contactName 97 globalThis.calluiAbilityContext?.resourceManager.getString(obj.msg.id, (err, typeName) => { 98 LogUtils.i(TAG, "sendMessage"); 99 sms.sendMessage({ 100 slotId: slotId, 101 destinationHost: destinationHost, 102 content: typeName, 103 sendCallback: (err, sendResult) => { 104 if (err) { 105 return; 106 } 107 if (sendResult.result === SEND_SMS_SUCCESS) { 108 globalThis.calluiAbilityContext?.resourceManager.getString($r("app.string.SMS_Sent") 109 .id, (err, typeName) => { 110 if (err) { 111 return; 112 } 113 prompt.showToast({ 114 message: contactName ? typeName + `${contactName}` : typeName + `${destinationHost}`, 115 duration: 2000, 116 }); 117 }) 118 } else { 119 globalThis.calluiAbilityContext?.resourceManager.getString($r("app.string.message_Failed") 120 .id, (err, typeName) => { 121 if (err) { 122 return; 123 } 124 prompt.showToast({ 125 message: typeName, 126 duration: 2000, 127 }); 128 }) 129 } 130 } 131 }); 132 }) 133 } 134 135 private getMsgList() { 136 this.msgList = [ 137 { 138 id: 1, 139 msg: $r("app.string.backLater") 140 }, 141 { 142 id: 2, 143 msg: $r("app.string.answerThePhone") 144 }, 145 { 146 id: 3, 147 msg: $r("app.string.contactMeLater") 148 }, 149 { 150 id: 4, 151 msg: $r("app.string.beThereSoon") 152 }, 153 ]; 154 } 155 156 private getBtnList() { 157 this.btnList = [ 158 { 159 type: 'msg', 160 iconText: $r("app.string.sms"), 161 iconDefaultUrl: SMS_REJECTION, 162 iconDisableUrl: SMS_REJECTION, 163 isDisable: false 164 }, 165 ]; 166 } 167 168 /** 169 * Call rejection interface 170 * 171 * @param {string} msg - Send SMS content 172 */ 173 private msgItemClick(obj) { 174 LogUtils.i(TAG, "msgItemClick rejectCall"); 175 this.mCallServiceProxy.rejectCall(this.callData.callId, obj.msg); 176 this.sendMessage(obj); 177 } 178 179 /** 180 * Handling interface call hangup and rejection 181 */ 182 private async onReject() { 183 if (this.callList.length > 1) { 184 const incomingData = this.callList.find((v) => v.callState === CallStateConst.callStateObj.CALL_STATUS_WAITING || v.callState === CallStateConst.callStateObj.CALL_STATUS_INCOMING); 185 Object.assign(this.callData, { 186 ...incomingData 187 }); 188 } 189 const {callId, callState} = this.callData; 190 if (callState !== CallStateConst.CALL_STATUS_WAITING) { 191 this.mCallServiceProxy.rejectCall(callId); 192 LogUtils.i(TAG, "onReject this.mCallServiceProxy.rejectCall :"); 193 } else { 194 this.mCallServiceProxy.hangUpCall(callId); 195 LogUtils.i(TAG, "onReject this.mCallServiceProxy.hangUpCall :"); 196 } 197 if (this.callList.length === 1) { 198 this.hangup = true; 199 globalThis.calluiAbilityContext?.terminateSelf().then((data) => { 200 LogUtils.i(TAG, "onReject terminateSelfCallBack"); 201 }); 202 } 203 } 204 205 /** 206 * Enable the SMS reply pop-up 207 */ 208 private btnClick(type) { 209 LogUtils.i(TAG, "btnClick : %s" + JSON.stringify(type)); 210 if (type === 'msg') { 211 this.msgDialogController.open(); 212 } 213 } 214 215 /** 216 * Answer the phone interface 217 */ 218 private onAnswer() { 219 LogUtils.i(TAG, "onAnswer :"); 220 const incomingData = this.callList.find((v) => v.callState === CallStateConst.callStateObj.CALL_STATUS_WAITING || v.callState === CallStateConst.callStateObj.CALL_STATUS_INCOMING); 221 if (incomingData !== undefined) { 222 this.mCallServiceProxy.acceptCall(incomingData.callId); 223 } else { 224 this.mCallServiceProxy.acceptCall(this.callData.callId); 225 } 226 VibrationAndProximityUtils.suspendScreen(); 227 VibrationAndProximityUtils.stopVibration(); 228 } 229 230 build() { 231 GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: 24 }) { 232 GridCol({ span: { sm: 4, md: 6, lg: 6 }, offset: { sm: 0, md: 1, lg: 3 } }) { 233 Column() { 234 Row() { 235 ForEach(this.btnList, (item) => { 236 Column() { 237 FuncBtn({ 238 btnType: item.type, 239 iconDisableUrl: item.iconDefaultUrl, 240 iconDefaultUrl: item.iconDefaultUrl, 241 iconText: item.iconText, 242 isDisable: item.isDisable, 243 btnClick: (type) => { 244 this.btnClick(type) 245 } 246 }) 247 } 248 }) 249 } 250 .height(51) 251 252 Row() { 253 Column() { 254 Image($r("app.media.ic_public_ring_off")) 255 .width(56) 256 .height(56) 257 .onClick(() => { 258 this.onReject() 259 }) 260 }.layoutWeight(1) 261 262 Column() { 263 Image($r("app.media.ic_public_answer")) 264 .width(56) 265 .height(56) 266 .onClick(() => { 267 this.onAnswer() 268 }) 269 }.layoutWeight(1) 270 } 271 .margin({ top: 32 }) 272 } 273 } 274 } 275 .width('100%') 276 .margin({ left: 24, right: 24 }) 277 } 278} 279