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 observer from '@ohos.telephony.observer'; 17import telephonySim from '@ohos.telephony.sim'; 18 19import { HiLog } from '../../../../../common/src/main/ets/util/HiLog'; 20import SharedPreferencesUtils from "./SharedPreferencesUtils"; 21 22export const simId_NONE: number = -1; 23 24export const simId_ONE: number = 0; 25 26export const simId_TWO: number = 1; 27 28const INTERVAL = 1000; 29 30const TIME_OUT = 10; 31 32const KEY_LAST_ID: string = "last_used_sim_key" 33 34const TAG = 'SimUtil'; 35 36interface Observer { 37 (): void; 38} 39 40class SimCardState { 41 mSimStateArray: Array<telephonySim.SimState> = 42 [telephonySim.SimState.SIM_STATE_UNKNOWN, telephonySim.SimState.SIM_STATE_UNKNOWN]; 43 haveSimCard: boolean = false; 44 haveMultiSimCard: boolean = false; 45 private observers: Observer[] = []; 46 47 constructor() { 48 try { 49 this.addSimChangeListener(); 50 this.getSimCardState(); 51 } catch (error) { 52 HiLog.w(TAG, "SimCardState, get sim state error.") 53 } 54 } 55 56 /** 57 * attachObserver The subscription management methods. 58 * 59 * @param Observer the Observer need attach 60 */ 61 public attachObserver(observer: Observer): void { 62 const isExist = this.observers.includes(observer); 63 if (isExist) { 64 return console.log('Subject: Observer has been attached already.'); 65 } 66 HiLog.d(TAG, 'Subject: Attached an observer.'); 67 this.observers.push(observer); 68 if (observer) { 69 observer(); 70 } 71 } 72 73 /** 74 * detachObserver 75 * 76 * @param Observer the Observer need detach 77 */ 78 public detachObserver(observer: Observer): void { 79 const observerIndex = this.observers.indexOf(observer); 80 if (observerIndex === -1) { 81 return console.log('Subject: Nonexistent observer.'); 82 } 83 84 this.observers.splice(observerIndex, 1); 85 HiLog.d(TAG, 'Subject: Detached an observer.'); 86 } 87 88 /** 89 * isSimReady 90 * 91 * @param slotId the sim slot id number 92 * @return boolean the sim is ready or not 93 */ 94 public isSimReady(slotId: number) { 95 return this.mSimStateArray[slotId] == telephonySim.SimState.SIM_STATE_READY || this.mSimStateArray[slotId] 96 == telephonySim.SimState.SIM_STATE_LOADED; 97 } 98 99 private notify(): void { 100 HiLog.d(TAG, 'sim state changed: Notifying observers...'); 101 for (const observer of this.observers) { 102 observer(); 103 } 104 } 105 106 private addSimChangeListener() { 107 HiLog.i(TAG, 'addSimChangeListener start ! '); 108 for (let i = 0; i < telephonySim.getMaxSimCount(); i++) { 109 observer.on('simStateChange', { 110 slotId: i 111 }, value => { 112 let simState = value?.state; 113 HiLog.i(TAG, 'simStateChange for simId_ONE, SIM value: ' + simState); 114 this.parseSimCardStateForSlot(i, simState); 115 }); 116 } 117 } 118 119 private getSimCardState() { 120 HiLog.i(TAG, '-----getSimCardState-----'); 121 for (let i = 0; i < telephonySim.getMaxSimCount(); i++) { 122 telephonySim.getSimState(i, (err, value) => { 123 if (err) { 124 HiLog.e(TAG, `getSimCardState, ${i} error: ${JSON.stringify(err.message)}`); 125 } else { 126 this.parseSimCardStateForSlot(i, value) 127 } 128 }); 129 } 130 } 131 132 private parseSimCardStateForSlot(slotId: number, value) { 133 HiLog.i(TAG, 'parseSimCardStateForSlot, slotId: ' + slotId + ', SimCardState value: ' + value); 134 let changed: boolean = (value != this.mSimStateArray[slotId]); 135 if (!changed) { 136 return; 137 } 138 this.mSimStateArray[slotId] = value; 139 this.haveSimCard = this.isSimReady(simId_ONE) || this.isSimReady(simId_TWO); 140 this.haveMultiSimCard = this.isSimReady(simId_ONE) && this.isSimReady(simId_TWO); 141 HiLog.i(TAG, 'parseSimCardStateForSlot sim state changed, haveSimCard: ' + this.haveSimCard + 142 ', haveMultiSimCard: ' + this.haveMultiSimCard); 143 this.notify(); 144 } 145} 146 147export const simCardState: SimCardState = new SimCardState(); 148 149/** 150 * getLastUsedSlotId 151 * 152 * @return the last sim id number used to dail 153 */ 154export function getLastUsedSlotId(): Promise<number> { 155 return new Promise<number>(async (resolve) => { 156 const value = <number> await SharedPreferencesUtils.getFromPreferences(KEY_LAST_ID, simId_NONE) 157 HiLog.i(TAG, "getLastUsedSlotId:" + value); 158 resolve(value) 159 }); 160} 161 162/** 163 * setLastUsedSlotId 164 * 165 * @param simId the sim id number 166 */ 167export function setLastUsedSlotId(simId: number) { 168 HiLog.i(TAG, "setLastUsedSlotId:" + simId) 169 SharedPreferencesUtils.getFromPreferences(KEY_LAST_ID, simId); 170} 171 172/** 173 * getSimName 174 * 175 * @param simId the sim id number 176 * @return the sim name to show 177 */ 178export function getSimName(simId: number): Promise<string> { 179 return new Promise((resolveInner) => { 180 telephonySim.getSimSpn(simId, (error, data) => { 181 if (error || !data) { 182 HiLog.i(TAG, "getSimSpn error" + JSON.stringify(error)) 183 telephonySim.getSimOperatorNumeric(simId, (error, opNum) => { 184 if (error) { 185 HiLog.i(TAG, "getSimOperatorNumeric error" + JSON.stringify(error)) 186 } else { 187 HiLog.i(TAG, "getSimSpn error, opNum:" + opNum) 188 resolveInner(opNum); 189 } 190 }) 191 } else { 192 resolveInner(data); 193 } 194 }) 195 }) 196}