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 callData: DefaultCallData = new DefaultCallData(); 35 callList: Array<CallListStruct> = []; 36 callTimeList: Array<CallTimeListStruct> = []; 37 private callStateChange: Function; 38 private mCallStateManager: CallStateManager; 39 private NotificationManager; 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.NotificationManager = 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, globalThis.appInactiveState); 110 } 111 } else { 112 this.addCallList({ 113 ...callData 114 }); 115 116 // use setTimeout to avoid block ui show 117 setTimeout(() => { 118 if (this.contactManager != undefined) { 119 this.contactManager.getContactInfo(callData) 120 } 121 }, 0); 122 } 123 124 if (callData.callState === CallStateConst.CALL_STATUS_ACTIVE) { 125 this.updateCallTimeList(callData); 126 } 127 const singleCallState = callState === CallStateConst.CALL_STATUS_ACTIVE || 128 callState === CallStateConst.CALL_STATUS_WAITING || this.callList.length === 1; 129 const multiCallState = (callState === CallStateConst.CALL_STATUS_DIALING || 130 callState === CallStateConst.CALL_STATUS_ALERTING) && this.callList.length > 1; 131 if (singleCallState || multiCallState) { 132 this.mCallStateManager.update(callData); 133 this.callStateChange(callState); 134 } 135 136 if (callState === CallStateConst.CALL_STATUS_DISCONNECTED) { 137 if (this.callList.length === 1) { 138 if (!AppStorage.Get('AirplaneMode')) { 139 this.clearCall(callData); 140 } 141 } else { 142 this.removeCallById(callId); 143 const activeCallData = this.callList.find((v) => v.callState === CallStateConst.CALL_STATUS_ACTIVE); 144 if (activeCallData) { 145 this.mCallStateManager.update(activeCallData); 146 this.callStateChange(activeCallData); 147 this.sendNotification(activeCallData); 148 } else if (this.callList[0]) { 149 this.mCallStateManager.update(this.callList[0]); 150 this.callStateChange(this.callList[0].callState); 151 this.sendNotification(this.callList[0]); 152 } 153 } 154 } 155 } 156 157 public clearCall(callData) { 158 this.NotificationManager.cancelNotification(); 159 AppStorage.Get<NotificationManager>('notificationManager').sendCapsuleNotification(callData, true); 160 AppStorage.Delete("CallTimeList"); 161 this.clearData(); 162 globalThis.calluiAbilityContext?.terminateSelf().then((data) => { 163 LogUtils.i(TAG, "calluiAbility terminateSelf"); 164 }); 165 // remove Proximity Listener 166 VibrationAndProximityUtils.wakeupScreen(); 167 VibrationAndProximityUtils.stopVibration(); 168 } 169 170 sendNotification(callData) { 171 if (globalThis.appInactiveState && callData) { 172 AppStorage.Get<NotificationManager>('notificationManager')?.sendNotification(callData); 173 AppStorage.Get<NotificationManager>('notificationManager')?.sendCapsuleNotification(callData, globalThis.appInactiveState); 174 } 175 } 176 177 /** 178 * Judge whether the call exists. 179 */ 180 public hasAliveCall() { 181 const callData = this.callList.find((call) => call.callState !== CallStateConst.CALL_STATUS_DISCONNECTED 182 && call.callState !== CallStateConst.CALL_STATUS_DISCONNECTING); 183 LogUtils.i(TAG, "hasAliveCall:" + JSON.stringify(callData !== undefined)); 184 return callData !== undefined; 185 } 186 187 /** 188 * Judge whether the call exists. 189 */ 190 public hasActiveCall(): boolean { 191 const callData = this.callList.find((call) => (call.callState === CallStateConst.CALL_STATUS_ACTIVE 192 || call.callState === CallStateConst.CALL_STATUS_HOLDING)); 193 return callData !== undefined; 194 } 195 196 /** 197 * Judge whether the call is active or holding. 198 */ 199 public isActiveCall(callId): boolean { 200 const callData = this.callList.find((call) => call.callId === callId && (call.callState === CallStateConst.CALL_STATUS_ACTIVE 201 || call.callState === CallStateConst.CALL_STATUS_HOLDING)); 202 return callData !== undefined; 203 } 204 205 /** 206 * addCallList 207 * 208 * @param { object } callData 209 */ 210 private addCallList(callData) { 211 this.callList.push(callData); 212 } 213 214 /** 215 * remove call by call id 216 * 217 * @param { object } callId - call id 218 */ 219 private removeCallById(callId) { 220 const index = this.callList.findIndex((v) => v.callId === callId); 221 this.callList.splice(index, 1); 222 if (this.callTimeList.find((v) => v.callId === callId)) { 223 this.callTimeList.splice(index, 1); 224 } 225 } 226 227 /** 228 * update callTimeList 229 * 230 * @param { object } callData 231 */ 232 updateCallTimeList(callData) { 233 const CallTimeObj = this.callTimeList.find((v) => v.callId === callData.callId); 234 LogUtils.i(TAG, "updateCallTimeList : " + JSON.stringify(CallTimeObj)) 235 if (!CallTimeObj && callData.callState === CallStateConst.CALL_STATUS_ACTIVE) { 236 const obj = { 237 callId: callData.callId, 238 callTime: '00:00', 239 startTimestamp: (callData.startTime * 1000).valueOf() || new Date().valueOf(), 240 endTimestamp: 0, 241 }; 242 this.callTimeList.push(obj); 243 AppStorage.SetOrCreate("CallTimeList", this.callTimeList) 244 LogUtils.i(TAG, "updateCallTimeList : " + JSON.stringify(this.callTimeList)) 245 } 246 } 247 248 clearData() { 249 this.callList.splice(0, this.callList.length); 250 LogUtils.i(TAG, "clearData: " + JSON.stringify(this.callList)); 251 let inputvalue = AppStorage.Delete("TextInputValue"); 252 LogUtils.i(TAG, "clearData:TextInputValue " + JSON.stringify(inputvalue)); 253 let textinput = AppStorage.Delete("TextInput"); 254 AppStorage.Delete("CallTimeList"); 255 AppStorage.Delete("notificationManager"); 256 AppStorage.Delete("currentAudioDeviceIcon"); 257 AppStorage.Delete("datalist"); 258 } 259}