1/* 2 * Copyright (c) 2021-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 CapsuleModel from '../model/CapsuleModel'; 17import Log from '../../../../../../../common/src/main/ets/default/Log'; 18import AbilityManager from '../../../../../../../common/src/main/ets/default/abilitymanager/abilityManager'; 19import ResourceUtil from '../../../../../../../common/src/main/ets/default/ResourceUtil'; 20import Trace from '../../../../../../../common/src/main/ets/default/Trace' 21 22let sCapsuleViewModel; 23 24const SEC_VAL = 1000; 25const MIN_VAL = 60 * SEC_VAL; 26const TAG = "CapsuleViewModel"; 27 28function fixInteger(num) { 29 return (num >= 10) ? String(num) : '0' + num; 30} 31 32function parseTime(num) { 33 return fixInteger(Math.floor(num / MIN_VAL)) + ":" + fixInteger(Math.floor((num % MIN_VAL) / SEC_VAL)); 34} 35 36export const VIEW_MODEL_ID = "CapsuleViewModelVm"; 37 38export enum CallState { 39 CALL_ACTIVE, //通话中* 40 CALL_HOLDING, //通话保持 41 CALL_DIALING, //拨号开始 42 CALL_ALERTING, //正在呼出 43 CALL_INCOMING, //来电* 44 CALL_WAITING, //第三方来电* 45 CALL_DISCONNECTED, //挂断完成 * 46 CALL_DISCONNECTING, //正在挂断 47 CALL_IDLE //空闲 48} 49 50export default class CapsuleViewModel { 51 mText: string = "00:00"; 52 mStartTime: number = 0; 53 mCallState: CallState = CallState.CALL_DISCONNECTED; 54 mIsBackground: boolean = false; 55 mWantBundleName: string = ""; 56 mWantAbilityName: string = ""; 57 mTimeMeter: any; 58 mCallback: any; 59 60 async initViewModel() { 61 this.mCallback = { 62 "onStateChange": this.onStateChange.bind(this) 63 }; 64 CapsuleModel.registerCallback(this.mCallback); 65 } 66 67 async onStateChange(data) { 68 Log.showInfo(TAG, `onStateChange, data: ${JSON.stringify(data)}`); 69 this.mIsBackground = data.isBackground; 70 this.mWantBundleName = data.wantBundleName; 71 this.mWantAbilityName = data.wantAbilityName; 72 await ResourceUtil.initResourceManager(AbilityManager.ABILITY_NAME_STATUS_BAR); 73 if (data.callState == CallState.CALL_INCOMING || data.callState == CallState.CALL_WAITING) { 74 this.mStartTime = 0; 75 this.mText = await ResourceUtil.getString($r("app.string.incoming_call")); 76 } else if (data.callState == CallState.CALL_ACTIVE) { 77 clearTimeout(this.mTimeMeter); 78 if (this.mCallState != CallState.CALL_ACTIVE) { 79 this.mStartTime = new Date().valueOf(); 80 }; 81 this.mCallState = data.callState; 82 83 let startTime; 84 let commonTimeDiff = new Date().valueOf() - data.startTime; 85 let localTimeDiff = new Date().valueOf() - this.mStartTime; 86 if (commonTimeDiff < 0) { 87 if (localTimeDiff < 0) { 88 startTime = new Date().valueOf(); 89 } else { 90 startTime = this.mStartTime; 91 }; 92 } else { 93 startTime = data.startTime; 94 }; 95 96 this.startUpdateTime(startTime); 97 } else if (data.callState == CallState.CALL_DISCONNECTED){ 98 clearTimeout(this.mTimeMeter); 99 this.mStartTime = 0; 100 this.mIsBackground = false; 101 this.mText = ""; 102 Log.showInfo(TAG, `cannot show`); 103 } else { 104 this.mStartTime = 0; 105 this.mText = await ResourceUtil.getString($r("app.string.communicate_by_phone")); 106 }; 107 this.mCallState = data.callState; 108 } 109 110 startUpdateTime(startTime) { 111 if (!this.mIsBackground || this.mCallState != CallState.CALL_ACTIVE) { 112 return; 113 } 114 let val = new Date().valueOf() - startTime.valueOf(); 115 if (val < 0) { 116 val = 0; 117 } 118 this.mText = parseTime(val); 119 this.mTimeMeter = setTimeout(() => { 120 this.startUpdateTime(startTime); 121 }, 1000 - val % 1000); 122 } 123 124 onClickEvent() { 125 Trace.start(Trace.CORE_METHOD_CLICK_CAPSULE); 126 if (this.mIsBackground) { 127 this.mIsBackground = false; 128 } 129 Log.showDebug(TAG, `onClickEvent `); 130 Log.showDebug(TAG, `startAbility`); 131 AbilityManager.startAbility(AbilityManager.getContext(AbilityManager.ABILITY_NAME_STATUS_BAR), { 132 bundleName: this.mWantBundleName, 133 abilityName: this.mWantAbilityName 134 }, () => { 135 Trace.end(Trace.CORE_METHOD_CLICK_CAPSULE); 136 }); 137 } 138 139 static getInstance() { 140 if (sCapsuleViewModel == null) { 141 sCapsuleViewModel = new CapsuleViewModel(); 142 AppStorage.SetAndLink(VIEW_MODEL_ID, sCapsuleViewModel); 143 }; 144 return sCapsuleViewModel; 145 } 146}