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 16/** 17 * @file: Call data management 18 */ 19import CallStateManager from './CallStateManager'; 20import CallStateConst from '../common/constant/CallStateConst'; 21import ContactManager from './ContactManager'; 22import NotificationManager from '../model/NotificationManager'; 23import LogUtils from '../common/utils/LogUtils'; 24import CallTimeListStruct from '../common/struct/CallTimeListStruct'; 25import CallListStruct from '../common/struct/CallListStruct'; 26import DefaultCallData from '../common/struct/TypeUtils'; 27import VibrationAndProximityUtils from '../common/utils/VibrationAndProximityUtils'; 28 29const TAG = 'CallDataManager'; 30/** 31 * class CallDataManager 32 */ 33export default class CallDataManager { 34 public callData: DefaultCallData = new DefaultCallData(); 35 public callList: Array<CallListStruct> = []; 36 public callTimeList: Array<CallTimeListStruct> = []; 37 private callStateChange: Function; 38 private mCallStateManager: CallStateManager; 39 private mNotificationManager; 40 private contactManager; 41 private static sCallDataManager: CallDataManager; 42 43 public static getInstance(): CallDataManager { 44 if (!CallDataManager.sCallDataManager) { 45 CallDataManager.sCallDataManager = new CallDataManager(); 46 } 47 return CallDataManager.sCallDataManager; 48 } 49 50 /** 51 * Init data. 52 */ 53 public init(callData, callList, callTimeList) { 54 this.mNotificationManager = new NotificationManager(); 55 this.contactManager = new ContactManager(); 56 this.mCallStateManager = CallStateManager.getInstance() 57 if (this.callData == null) { 58 this.callData = callData; 59 } else { 60 let oldCallData = this.callData; 61 this.callData = callData; 62 Object.assign(this.callData, { 63 ...oldCallData 64 }); 65 } 66 if (this.callList.length === 0) { 67 LogUtils.i(TAG, 'init callList: undefined'); 68 this.callList = callList; 69 } else { 70 let oldCallList = this.callList; 71 this.callList = callList; 72 Object.assign(this.callList, { 73 ...oldCallList 74 }); 75 } 76 if (this.callTimeList.length === 0) { 77 LogUtils.i(TAG, 'init callTimeList: undefined'); 78 this.callTimeList = callTimeList; 79 } else { 80 let oldCallTimeList = this.callTimeList; 81 this.callTimeList = callTimeList; 82 Object.assign(this.callTimeList, { 83 ...oldCallTimeList 84 }); 85 } 86 this.callStateChange = (arg) => arg; 87 this.mCallStateManager = new CallStateManager(this.callData); 88 } 89 90 /** 91 * update callList and callData callTimeList 92 *` 93 * @param { object } callData 94 */ 95 public update(callData) { 96 const { callState, callId } = callData; 97 if (callId === undefined || callId === null) { 98 LogUtils.i(TAG, 'callId is not exist'); 99 return; 100 } 101 const targetObj = this.callList.find((v) => v.callId === callId); 102 LogUtils.i(TAG, 'update :') 103 if (targetObj) { 104 const { oldCallState } = targetObj; 105 Object.assign(targetObj, { 106 ...callData 107 }); 108 if (oldCallState != callState) { 109 AppStorage.Get<NotificationManager>('notificationManager').sendCapsuleNotification(callData, 110 globalThis.appInactiveState); 111 } 112 } else { 113 this.addCallList({ 114 ...callData 115 }); 116 117 // use setTimeout to avoid block ui show 118 setTimeout(() => { 119 if (this.contactManager != undefined) { 120 this.contactManager.getContactInfo(callData) 121 } 122 }, 0); 123 } 124 125 if (callData.callState === CallStateConst.CALL_STATUS_ACTIVE) { 126 this.updateCallTimeList(callData); 127 } 128 const singleCallState = callState === CallStateConst.CALL_STATUS_ACTIVE || 129 callState === CallStateConst.CALL_STATUS_WAITING || this.callList.length === 1; 130 const multiCallState = (callState === CallStateConst.CALL_STATUS_DIALING || 131 callState === CallStateConst.CALL_STATUS_ALERTING) && this.callList.length > 1; 132 if (singleCallState || multiCallState) { 133 this.mCallStateManager.update(callData); 134 this.callStateChange(callState); 135 } 136 137 if (callState === CallStateConst.CALL_STATUS_DISCONNECTED) { 138 if (this.callList.length === 1) { 139 if (!AppStorage.Get('AirplaneMode')) { 140 this.clearCall(callData); 141 } 142 } else { 143 this.removeCallById(callId); 144 const activeCallData = this.callList.find((v) => v.callState === CallStateConst.CALL_STATUS_ACTIVE); 145 if (activeCallData) { 146 this.mCallStateManager.update(activeCallData); 147 this.callStateChange(activeCallData); 148 this.sendNotification(activeCallData); 149 } else if (this.callList[0]) { 150 this.mCallStateManager.update(this.callList[0]); 151 this.callStateChange(this.callList[0].callState); 152 this.sendNotification(this.callList[0]); 153 } 154 } 155 } 156 } 157 158 public clearCall(callData) { 159 this.mNotificationManager.cancelNotification(); 160 AppStorage.Get<NotificationManager>('notificationManager').sendCapsuleNotification(callData, true); 161 AppStorage.Delete('CallTimeList'); 162 this.clearData(); 163 globalThis.calluiAbilityContext?.terminateSelf().then((data) => { 164 LogUtils.i(TAG, 'calluiAbility terminateSelf'); 165 }); 166 // remove Proximity Listener 167 VibrationAndProximityUtils.wakeupScreen(); 168 VibrationAndProximityUtils.stopVibration(); 169 } 170 171 sendNotification(callData) { 172 if (globalThis.appInactiveState && callData) { 173 AppStorage.Get<NotificationManager>('notificationManager')?.sendNotification(callData); 174 AppStorage.Get<NotificationManager>('notificationManager')?.sendCapsuleNotification(callData, 175 globalThis.appInactiveState); 176 } 177 } 178 179 /** 180 * Judge whether the call exists. 181 */ 182 public hasAliveCall() { 183 const callData = this.callList.find((call) => call.callState !== CallStateConst.CALL_STATUS_DISCONNECTED && 184 call.callState !== CallStateConst.CALL_STATUS_DISCONNECTING); 185 LogUtils.i(TAG, 'hasAliveCall:' + JSON.stringify(callData !== undefined)); 186 return callData !== undefined; 187 } 188 189 /** 190 * Judge whether the call exists. 191 */ 192 public hasActiveCall(): boolean { 193 const callData = this.callList.find((call) => (call.callState === CallStateConst.CALL_STATUS_ACTIVE || 194 call.callState === CallStateConst.CALL_STATUS_HOLDING)); 195 return callData !== undefined; 196 } 197 198 /** 199 * Judge whether the call is active or holding. 200 */ 201 public isActiveCall(callId): boolean { 202 const callData = this.callList.find((call) => call.callId === callId && (call.callState === 203 CallStateConst.CALL_STATUS_ACTIVE || call.callState === CallStateConst.CALL_STATUS_HOLDING)); 204 return callData !== undefined; 205 } 206 207 /** 208 * addCallList 209 * 210 * @param { object } callData 211 */ 212 private addCallList(callData) { 213 this.callList.push(callData); 214 } 215 216 /** 217 * remove call by call id 218 * 219 * @param { object } callId - call id 220 */ 221 private removeCallById(callId) { 222 const index = this.callList.findIndex((v) => v.callId === callId); 223 this.callList.splice(index, 1); 224 if (this.callTimeList.find((v) => v.callId === callId)) { 225 this.callTimeList.splice(index, 1); 226 } 227 } 228 229 /** 230 * update callTimeList 231 * 232 * @param { object } callData 233 */ 234 updateCallTimeList(callData) { 235 const callTimeObj = this.callTimeList.find((v) => v.callId === callData.callId); 236 LogUtils.i(TAG, 'updateCallTimeList : ' + JSON.stringify(callTimeObj)); 237 if (!callTimeObj && callData.callState === CallStateConst.CALL_STATUS_ACTIVE) { 238 const obj = { 239 callId: callData.callId, 240 callTime: '00:00', 241 startTimestamp: (callData.startTime * 1000).valueOf() || new Date().valueOf(), 242 endTimestamp: 0, 243 }; 244 this.callTimeList.push(obj); 245 AppStorage.SetOrCreate('CallTimeList', this.callTimeList) 246 LogUtils.i(TAG, 'updateCallTimeList : ' + JSON.stringify(this.callTimeList)) 247 } 248 } 249 250 clearData() { 251 this.callList.splice(0, this.callList.length); 252 LogUtils.i(TAG, 'clearData: ' + JSON.stringify(this.callList)); 253 let inputvalue = AppStorage.Delete('TextInputValue'); 254 LogUtils.i(TAG, 'clearData:TextInputValue ' + JSON.stringify(inputvalue)); 255 let textinput = AppStorage.Delete('TextInput'); 256 AppStorage.Delete('CallTimeList'); 257 AppStorage.Delete('notificationManager'); 258 AppStorage.Delete('currentAudioDeviceIcon'); 259 AppStorage.Delete('datalist'); 260 } 261}