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 16import mediaQuery from '@ohos.mediaquery'; 17import wantAgent from '@ohos.wantAgent'; 18import ContactCard from '../common/components/ContactCard'; 19import FuncBtnGroup from '../common/components/FuncBtnGroup'; 20import BottomBtn from '../common/components/BottomBtn'; 21import Keyboard from '../common/components/Keyboard'; 22import IncomingCom from '../common/components/IncomingCom'; 23import CallStateConst from '../common/constant/CallStateConst'; 24import LogUtils from '../common/utils/LogUtils'; 25import byTrace from "@ohos.bytrace" 26import NotificationManager from '../model/NotificationManager'; 27import CallManager from '../model/CallManager'; 28import backgroundTaskManager from '@ohos.backgroundTaskManager'; 29import Constants from '../common/utils/Constants'; 30import CallDataManager from '../model/CallDataManager'; 31import MultiContactCard from '../common/components/MultiContactCard'; 32import GlobalThisHelper from '../common/utils/GlobalThisHelper'; 33 34const TAG = "Index"; 35 36/** 37 * @file: Main interface 38 */ 39@Entry 40@Component 41struct Index { 42 @StorageLink("InputNum") inputNum: any = []; 43 @State callData: any = CallStateConst.defaultCallData; 44 @State isShowKeyboard: boolean = false; 45 @State callList: Array<any> = []; 46 @State callTimeList: Array<any> = []; 47 private notificationManager: NotificationManager; 48 private mCallDataManager: CallDataManager; 49 @State curBp: string = 'md'; 50 private smListener: mediaQuery.MediaQueryListener; 51 private mdListener: mediaQuery.MediaQueryListener; 52 private lgListener: mediaQuery.MediaQueryListener; 53 isBreakpointSM = (mediaQueryResult) => { 54 if (mediaQueryResult.matches) { 55 this.curBp = 'sm' 56 AppStorage.SetOrCreate('curBp', this.curBp) 57 } 58 } 59 isBreakpointMD = (mediaQueryResult) => { 60 if (mediaQueryResult.matches) { 61 this.curBp = 'md' 62 AppStorage.SetOrCreate('curBp', this.curBp) 63 } 64 } 65 isBreakpointLG = (mediaQueryResult) => { 66 if (mediaQueryResult.matches) { 67 this.curBp = 'lg' 68 AppStorage.SetOrCreate('curBp', this.curBp) 69 } 70 } 71 72 aboutToAppear(): void { 73 LogUtils.i(TAG, "aboutToAppear") 74 byTrace.startTrace('aboutToAppear', 0); 75 this.notificationManager = new NotificationManager(); 76 CallManager.getInstance()?.init(this); 77 AppStorage.SetOrCreate<NotificationManager>('notificationManager', this.notificationManager); 78 this.mCallDataManager = CallDataManager.getInstance(); 79 byTrace.finishTrace('aboutToAppear', 0); 80 this.smListener = mediaQuery.matchMediaSync('(320vp<width<=520vp)'); 81 this.smListener.on("change", this.isBreakpointSM); 82 this.mdListener = mediaQuery.matchMediaSync('(520vp<width<=840vp)'); 83 this.mdListener.on("change", this.isBreakpointMD); 84 this.lgListener = mediaQuery.matchMediaSync('(840vp<width)'); 85 this.lgListener.on("change", this.isBreakpointLG); 86 } 87 88 onPageShow() { 89 LogUtils.i(TAG, "onPageShow"); 90 byTrace.startTrace('onPageShow', 1); 91 GlobalThisHelper.set<boolean>(Constants.GLOBALTHIS_APPINACTIVE_STATE, false); 92 this.stopBackgroundRunning(); 93 this.notificationManager?.cancelNotification(); 94 this.notificationManager?.sendCapsuleNotification(this.callData, false); 95 byTrace.finishTrace('onPageShow', 1); 96 LogUtils.i(TAG, "onPageShow end"); 97 } 98 99 onPageHide() { 100 LogUtils.i(TAG, "onPageHide"); 101 GlobalThisHelper.set<boolean>(Constants.GLOBALTHIS_APPINACTIVE_STATE, true); 102 this.updateNotification(); 103 LogUtils.i(TAG, "onPageHide end"); 104 } 105 106 updateNotification() { 107 const {callState, callId} = this.callData; 108 if (callState !== CallStateConst.callStateObj.CALL_STATUS_DISCONNECTED && callId) { 109 if (this.mCallDataManager.hasAliveCall()) { 110 this.startBackgroundRunning(); 111 } 112 this.notificationManager?.sendNotification(this.callData); 113 this.notificationManager?.sendCapsuleNotification(this.callData, true); 114 } 115 } 116 117 118 aboutToDisappear() { 119 LogUtils.i(TAG, "aboutToDisappear"); 120 this.stopBackgroundRunning(); 121 this.updateNotification(); 122 this.smListener.off('change', this.isBreakpointSM); 123 this.mdListener.off('change', this.isBreakpointMD); 124 this.lgListener.off('change', this.isBreakpointLG); 125 } 126 127 private stopBackgroundRunning() { 128 backgroundTaskManager.stopBackgroundRunning(GlobalThisHelper.get<any>(Constants.GLOBALTHIS_CONTEXT)).then(() => { 129 LogUtils.i(TAG, "stopBackgroundRunning succeeded"); 130 }).catch((err) => { 131 LogUtils.i(TAG, "stopBackgroundRunning failed"); 132 }); 133 } 134 135 private startBackgroundRunning() { 136 let wantAgentInfo = { 137 wants: [{ 138 bundleName: Constants.CALL_BUNDLE_NAME, 139 abilityName: Constants.CALL_ABILITY_NAME, 140 }], 141 requestCode: 0, 142 operationType: wantAgent.OperationType.START_ABILITY, 143 wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] 144 }; 145 wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj) => { 146 backgroundTaskManager.startBackgroundRunning(GlobalThisHelper.get<any>(Constants.GLOBALTHIS_CONTEXT), 147 backgroundTaskManager.BackgroundMode.VOIP, wantAgentObj).then(() => { 148 LogUtils.i(TAG, "startBackgroundRunning succeeded") 149 }).catch((err) => { 150 LogUtils.i(TAG, "startBackgroundRunning failed cause:" + JSON.stringify(err)) 151 }); 152 }); 153 } 154 155 /** 156 * method to control the display of DTMF keyboard 157 * 158 * parent component pass by value child component 159 */ 160 public showKeyboard() { 161 this.isShowKeyboard = !this.isShowKeyboard; 162 } 163 164 /** 165 * Call status 166 * 167 * @return {number} - callState 168 */ 169 private callState() { 170 LogUtils.i(TAG, "callState : " + this.callData.callState) 171 return this.callData.callState; 172 } 173 174 /** 175 * is Triple Call 176 * 177 * @return {boolean} - isTripleCall 178 */ 179 private isTripleCall() { 180 return (this.callData.callState === CallStateConst.callStateObj.CALL_STATUS_WAITING 181 || this.callData.callState === CallStateConst.callStateObj.CALL_STATUS_INCOMING) 182 && this.callList.length === 3; 183 } 184 185 build() { 186 Flex({ 187 direction: FlexDirection.Column, 188 alignItems: ItemAlign.Center, 189 justifyContent: FlexAlign.SpaceBetween 190 }) { 191 if (this.callList.length > 1) { 192 MultiContactCard({ 193 callData: $callData, 194 isShowKeyboard: this.isShowKeyboard, 195 callList: $callList 196 }) 197 .margin({ top: this.isShowKeyboard ? 0 : 56 }) 198 .layoutWeight(this.isShowKeyboard ? 1 : 0) 199 } else { 200 ContactCard({ 201 callData: $callData, 202 isShowKeyboard: this.isShowKeyboard, 203 callList: $callList 204 }) 205 .margin({ top: this.isShowKeyboard ? 0 : 56 }) 206 .layoutWeight(this.isShowKeyboard ? 1 : 0) 207 } 208 209 if (this.callState() !== CallStateConst.callStateObj.CALL_STATUS_WAITING 210 && this.callState() !== CallStateConst.callStateObj.CALL_STATUS_INCOMING) { 211 Column() { 212 if (!this.isShowKeyboard) { 213 FuncBtnGroup({ callData: $callData, callList: $callList }) 214 .margin({ bottom: 32 }) 215 } else { 216 Keyboard({ callData: $callData }) 217 .margin({ bottom: 32 }) 218 } 219 BottomBtn({ 220 callData: $callData, 221 onItemClick: () => { 222 this.showKeyboard() 223 } 224 }) 225 } 226 } else { 227 Column() { 228 IncomingCom({ callData: $callData }) 229 230 if (this.isTripleCall()) { 231 Column() { 232 Text($r("app.string.end_holding_call")) 233 .fontColor('#FFFFFF') 234 .fontSize(14) 235 .height(19) 236 .lineHeight(19) 237 } 238 .margin({ top: 16 }) 239 } 240 } 241 } 242 } 243 .padding({ bottom: this.isTripleCall() ? 71 : 106 }) 244 .width("100%") 245 .height("100%") 246 .backgroundImage('assets/picture/wallpaper.png', ImageRepeat.NoRepeat) 247 .backgroundImageSize(ImageSize.Cover) 248 } 249} 250