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 */ 15 16/** 17 * @file: Call management 18 */ 19import CallDataManager from './CallDataManager'; 20import CallUtils from '../common/utils/CallUtils'; 21import Utils from '../common/utils/utils'; 22import CallServiceProxy from './CallServiceProxy'; 23import LogUtils from '../common/utils/LogUtils' 24import call from '@ohos.telephony.call'; 25import CallStateConst from '../common/constant/CallStateConst'; 26import DefaultCallData from '../common/struct/TypeUtils'; 27import CallListStruct from '../common/struct/CallListStruct'; 28import VibrationAndProximityUtils from '../common/utils/VibrationAndProximityUtils'; 29 30const TAG = 'CallManager'; 31const TIMING = 1000; 32 33/** 34 * class CallManager 35 */ 36export default class CallManager { 37 private callData: DefaultCallData = new DefaultCallData(); 38 private callList: Array<CallListStruct> = []; 39 private timer = null; 40 public callTimeList = []; 41 private ctx = []; 42 private sendNotificationHandle: Function; 43 private mCallDataManager: CallDataManager; 44 private mCallServiceProxy: CallServiceProxy; 45 private mUtils: Utils; 46 private diffSeconds 47 private mTimeMeter; 48 private isServiceConnected: boolean = false; 49 50 public static getInstance(): CallManager { 51 if (globalThis.callManager == null) { 52 globalThis.callManager = new CallManager(); 53 } 54 return globalThis.callManager; 55 } 56 57 private constructor() { 58 this.mCallServiceProxy = CallServiceProxy.getInstance(); 59 this.mUtils = Utils.getInstance(); 60 this.timer = null; 61 this.mCallDataManager = CallDataManager.getInstance(); 62 } 63 64 init(ctx) { 65 this.callData = ctx.callData; 66 this.ctx = ctx; 67 this.callTimeList = ctx.callTimeList; 68 this.mCallDataManager?.init(ctx.callData, ctx.callList, ctx.callTimeList); 69 this.openTimer(); 70 this.sendNotificationHandle = (arg) => arg; 71 this.initCallData(); 72 } 73 74 /** 75 * init CallData 76 */ 77 private initCallData() { 78 if (globalThis.abilityWant && globalThis.abilityWant.parameters && ('callState' in globalThis.abilityWant.parameters)) { 79 if (!this.isServiceConnected) { 80 globalThis.calluiAbilityContext?.terminateSelf().then((data) => { 81 LogUtils.i(TAG, 'calluiAbility terminateSelf because service disconnected'); 82 }); 83 return; 84 } 85 let callData = this.getCallDataFromWant(globalThis.abilityWant.parameters); 86 this.update(callData); 87 LogUtils.i(TAG, 'initCallData featureAbility.getWant :') 88 } else { 89 this.mCallServiceProxy.publish({ 90 key: 'getInitCallData', 91 params: [] 92 }); 93 } 94 } 95 96 setServiceConnected(isServiceConnected: boolean): void { 97 this.isServiceConnected = isServiceConnected; 98 } 99 100 /** 101 * get callData from want parameters 102 */ 103 private getCallDataFromWant(parameters) { 104 return Object.assign({}, { 105 accountId: parameters.accountId, 106 accountNumber: parameters.accountNumber, 107 callId: parameters.callId, 108 callState: parameters.callState, 109 callType: parameters.callType, 110 conferenceState: parameters.conferenceState, 111 isEcc: parameters.isEcc, 112 startTime: parameters.startTime, 113 videoState: parameters.videoState}); 114 } 115 116 /** 117 * update callData callBack 118 * 119 * @param { Object } callData -Object 120 */ 121 async update(callData) { 122 LogUtils.i(TAG, 'update calldata:') 123 if (this.callData != undefined && this.callData.callId === callData.callId) { 124 const { callState } = this.callData; 125 if (callState === 6 && this.callList.length === 1) { 126 globalThis.calluiAbilityContext?.terminateSelf().then((data) => { 127 LogUtils.i(TAG, 'calluiAbility terminateSelf because service disconnected'); 128 }); 129 // remove Proximity Listener 130 VibrationAndProximityUtils.wakeupScreen(); 131 VibrationAndProximityUtils.stopVibration(); 132 return; 133 } 134 } 135 this.callData = callData; 136 this.mCallDataManager.update(callData); 137 call.formatPhoneNumber(callData.accountNumber, (err, data) => { 138 if (err) { 139 LogUtils.i(TAG, 'updata calldata formatPhoneNumber err:' + JSON.stringify(err)); 140 } else if (data === undefined) { 141 AppStorage.SetOrCreate('AccountNumber', callData.accountNumber); 142 } else { 143 LogUtils.i(TAG, 'updata calldata formatPhoneNumber success:' + JSON.stringify(data)); 144 AppStorage.SetOrCreate('AccountNumber', data); 145 } 146 }); 147 CallUtils.isEmergencyPhoneNumber(callData.accountNumber); 148 LogUtils.i(TAG, 'update :'); 149 } 150 151 /** 152 * update call time list 153 */ 154 updateCallTimeList() { 155 if (!this.mCallDataManager.hasActiveCall()) { 156 LogUtils.i(TAG, 'no active calls to update'); 157 return; 158 } 159 160 this.callTimeList = AppStorage.Get('CallTimeList'); 161 this.callTimeList.forEach((item, i) => { 162 if (this.mCallDataManager.isActiveCall(item.callId)) { 163 item.endTimestamp = new Date().valueOf(); 164 const diffSeconds = item.endTimestamp - item.startTimestamp; 165 this.diffSeconds = diffSeconds 166 item.callTime = this.mUtils.formatTime(diffSeconds); 167 this.callTimeList.splice(i, 1, { 168 ...item, 169 }); 170 AppStorage.SetOrCreate('CallTimeList', this.callTimeList); 171 } 172 }); 173 this.mTimeMeter = setTimeout(() => { 174 this.updateCallTimeList(); 175 }, 1000 - this.diffSeconds % 1000); 176 177 } 178 179 /** 180 * open timer 181 * 182 * @param { Function } callBack - add updateCallTimeList callBack 183 */ 184 openTimer() { 185 this.timer = setInterval(() => { 186 this.updateCallTimeList(); 187 if (this.callData.callState === CallStateConst.CALL_STATUS_ACTIVE && this.callList.length === 1) { 188 clearInterval(this.timer); 189 } 190 }, TIMING); 191 } 192 193 /** 194 * clear timer 195 */ 196 clearTimer() { 197 clearInterval(this.timer); 198 } 199} 200