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 manager service 18 */ 19 20import TelephonyCall from './TelephonyApi'; 21import commonEvent from '@ohos.commonEvent'; 22import LogUtils from "../common/utils/LogUtils"; 23import CallManager from '../model/CallManager' 24 25let subscriber; 26const TAG = "CallManagerService"; 27const CALL_BUNDLE_NAME = 'com.ohos.callui'; 28const ABILITY_NAME = 'com.ohos.callui.MainAbility'; 29const CALL_STATUS_INCOMING = 4; 30const CALL_STATUS_WAITING = 5; 31const CALL_STATUS_DIALING = 2; 32const CALL_STATUS_DISCONNECTED = 6; 33const CALL_STATUS_DISCONNECTING = 7; 34const events = ['callui.event.callEvent', 'callui.event.click']; 35 36/** 37 * class CallManagerService 38 */ 39export default class CallManagerService { 40 private mTelephonyCall: TelephonyCall ; 41 private callData = null; 42 private callList = []; 43 private context: any; 44 45 public constructor(context: any) { 46 this.mTelephonyCall = new TelephonyCall; 47 this.addRegisterListener(); 48 this.addSubscriber(); 49 this.context = context; 50 } 51 52 /** 53 * add callui app subscriber 54 */ 55 async addSubscriber() { 56 LogUtils.i(TAG, "addSubscriber") 57 subscriber = await new Promise((resolve) => { 58 commonEvent.createSubscriber({ 59 events, 60 publisherPermission: "ohos.permission.GET_TELEPHONY_STATE" 61 }, (err, data) => { 62 resolve(data); 63 }); 64 }); 65 66 commonEvent.subscribe(subscriber, (err, res) => { 67 if (err.code === 0) { 68 if (res.event === events[0]) { 69 const obj = JSON.parse(res.data); 70 if (obj && obj.key === 'getInitCallData') { 71 this.publishData(this.callData); 72 } 73 } 74 75 if (res.event === events[1]) { 76 const {callId,btnType} = res.parameters 77 this.btnclickAgent(callId, btnType) 78 } 79 } else { 80 LogUtils.i(TAG, "addSubscriber commonEvent.subscribe failed err :" + JSON.stringify(err)) 81 } 82 subscriber.finishCommonEvent() 83 .then(() => { 84 LogUtils.i(TAG, "addSubscriber finishCommonEvent") 85 }) 86 }); 87 } 88 89 /** 90 * click button agent 91 * 92 * @param { number } callId - call id 93 * @param { string } btnType - button type 94 */ 95 btnclickAgent(callId, btnType) { 96 LogUtils.i(TAG, "btnclickAgent btnType :" + btnType) 97 this.getMapObj(btnType, callId) 98 } 99 100 getMapObj(typeKey, callId) { 101 if (typeKey === 'answer') { 102 this.mTelephonyCall.acceptCall(callId) 103 this.startAbility(this.callData) 104 } 105 if (typeKey === 'reject') { 106 this.mTelephonyCall.rejectCall(callId) 107 } 108 if (typeKey === 'hangUp') { 109 this.mTelephonyCall.hangUpCall(callId) 110 } 111 } 112 113 /** 114 * add register listener 115 */ 116 addRegisterListener() { 117 this.mTelephonyCall.registerCallStateCallback(this.getCallData.bind(this)); 118 } 119 120 /** 121 * get callData 122 * 123 * @param { Object } callData - Object 124 */ 125 getCallData(callData) { 126 this.callData = callData; 127 this.updateCallList(); 128 const {callState} = this.callData; 129 130 /** 131 * single call or dialing pull up the application 132 */ 133 if (callState === CALL_STATUS_INCOMING || callState === CALL_STATUS_WAITING || callState === CALL_STATUS_DIALING) { 134 if (this.callList.length > 1) { 135 this.publishData(callData) 136 } 137 this.startAbility(callData); 138 } else if (callState !== CALL_STATUS_DISCONNECTING) { 139 this.publishData(callData); 140 } 141 } 142 143 /** 144 * service disconnected 145 * 146 * @return void 147 */ 148 public onDisconnected(): void { 149 this.callData.callState = CALL_STATUS_DISCONNECTED; 150 this.publishData(this.callData); 151 } 152 153 /** 154 * start ability 155 * 156 * @param { Object } callData - Object 157 */ 158 startAbility(callData) { 159 this.context.startAbility({ 160 bundleName: CALL_BUNDLE_NAME, 161 abilityName: ABILITY_NAME, 162 parameters: callData 163 }).then((data) => { 164 LogUtils.i(TAG, "callUI service startAbility data :" + JSON.stringify(data)) 165 }).catch((err) => { 166 LogUtils.i(TAG, "callUI service startAbility err :" + JSON.stringify(err)) 167 }); 168 } 169 170 /** 171 * update callList 172 */ 173 updateCallList() { 174 const {callState, callId} = this.callData; 175 const targetObj = this.callList.find((v) => v.callId === callId); 176 if (targetObj) { 177 Object.assign(targetObj, { 178 ...this.callData 179 }); 180 } else { 181 this.callList.push({ 182 ...this.callData 183 }); 184 } 185 if (callState === CALL_STATUS_DISCONNECTED) { 186 const index = this.callList.findIndex((v) => v.callId === callId); 187 this.callList.splice(index, 1); 188 } 189 } 190 191 /** 192 * commonEvent publish data 193 * 194 * @param { Object } callData - Object 195 */ 196 publishData(callData) { 197 CallManager.getInstance().update(callData); 198 } 199 200 /** 201 * unsubscribe 202 */ 203 unsubscribe() { 204 commonEvent.unsubscribe(subscriber, (err) => { 205 if (err.code !== 0) { 206 LogUtils.i(TAG, "unsubscribe commonEvent.unsubscribe err:" + JSON.stringify(err)) 207 } 208 }); 209 } 210 211 /** 212 * remove register listener 213 */ 214 removeRegisterListener() { 215 this.mTelephonyCall.unRegisterCallStateCallback(); 216 } 217}