• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 BaseModel from "./BaseModel";
17import common from "../data/commonData";
18import HiLog from "../utils/HiLog";
19import MmsPreferences from "../utils/MmsPreferences";
20import telephonySMS from "@ohos.telephony.sms";
21import telephonySim from "@ohos.telephony.sim";
22import observer from '@ohos.telephony.observer';
23import CommonEvent from '@ohos.commonEventManager';
24import emitter from '@ohos.events.emitter'
25import radio from '@ohos.telephony.radio';
26
27const TAG = "CardModel";
28
29class CardModel extends BaseModel {
30  public SIM_STATE_CHANGE_EVENT: emitter.InnerEvent = {
31    eventId: common.int.EVENT_SIM_STATE_CHANGE,
32    priority: emitter.EventPriority.HIGH
33  }
34  public SLOTID_CHANGE_EVENT: emitter.InnerEvent = {
35    eventId: common.int.EVENT_SLOTID_CHANGE,
36    priority: emitter.EventPriority.HIGH
37  }
38  private mSimStateArray: Array<telephonySim.SimState> = [telephonySim.SimState.SIM_STATE_UNKNOWN,
39  telephonySim.SimState.SIM_STATE_UNKNOWN];
40  private spn: string = '';
41  private spnEventSubscriber: any;
42  private haveMultiSimCardReady: boolean = false;
43  private haveSimCardReady: boolean = false;
44
45  public init(): void {
46    try {
47      HiLog.i(TAG, "init start.");
48      this.setMaxSimCountToMap();
49      this.getSimState();
50      this.addSimStateChangeListener();
51      this.subscribeSpnObserver();
52    } catch (error) {
53      HiLog.e(TAG, "init error: " + JSON.stringify(error));
54    }
55  }
56
57  public deInit(): void {
58    try {
59      HiLog.i(TAG, "deInit start.");
60      this.mSimStateArray = [telephonySim.SimState.SIM_STATE_UNKNOWN, telephonySim.SimState.SIM_STATE_UNKNOWN];
61      this.removeSimStateChangeListener();
62      this.unsubscribeSpnObserver();
63    } catch (error) {
64      HiLog.e(TAG, "deInit error: " + JSON.stringify(error));
65    }
66  }
67
68  public isSimReady(slotId: number): boolean {
69    return this.mSimStateArray[slotId] == telephonySim.SimState.SIM_STATE_READY
70    || this.mSimStateArray[slotId] == telephonySim.SimState.SIM_STATE_LOADED;
71  }
72
73  private setMaxSimCountToMap(): void {
74    MmsPreferences.getInstance().setValueToMap(common.string.KEY_OF_MAX_SIM_COUNT, telephonySim.getMaxSimCount());
75  }
76
77  private getSimState(): void {
78    for (let i = 0; i < telephonySim.getMaxSimCount(); i++) {
79      telephonySim.getSimState(i, (err, value) => {
80        if (err) {
81          HiLog.e(TAG, "getSimState, slotId: " + i + ", error: " + JSON.stringify(err));
82        } else {
83          this.notifySimStateChange(i, value);
84        }
85      });
86    }
87  }
88
89  private removeSimStateChangeListener(): void {
90    observer.off('simStateChange');
91  }
92
93  private addSimStateChangeListener(): void {
94    for (let i = 0; i < telephonySim.getMaxSimCount(); i++) {
95      observer.on('simStateChange', {
96        slotId: i
97      }, value => {
98        let simState = value?.state;
99        HiLog.i(TAG, "simStateChange slotId: " + i + ", simState: " + simState);
100        this.notifySimStateChange(i, simState);
101      });
102    }
103  }
104
105  private notifySimStateChange(slotId: number, simState): void {
106    let changed: boolean = (simState != this.mSimStateArray[slotId]);
107    if (!changed) {
108      return;
109    }
110    this.mSimStateArray[slotId] = simState;
111    if (this.isSimReady(slotId)) {
112      this.setSpnToMap(slotId);
113      this.setSimTelephoneNumberToMap(slotId);
114      this.setSmscNumberToPref(slotId);
115    }
116    this.setSimCardReadyFlagToMap(slotId, simState);
117    this.setDefaultSlotToMap();
118    emitter.emit(this.SIM_STATE_CHANGE_EVENT, {
119      data: {
120        "simState": simState,
121        "slotId": slotId
122      }
123    });
124  }
125
126  private setSimCardReadyFlagToMap(slotId: number, simState): void {
127    this.haveSimCardReady = this.isSimReady(common.int.SIM_ONE) || this.isSimReady(common.int.SIM_TWO);
128    this.haveMultiSimCardReady = this.isSimReady(common.int.SIM_ONE) && this.isSimReady(common.int.SIM_TWO);
129    HiLog.i(TAG, "updateSimCardReadyFlag slotId: " + slotId + ", simState: " + simState + ", haveSimCardReady: "
130    + this.haveSimCardReady + ", haveMultiSimCardReady: " + this.haveMultiSimCardReady);
131    MmsPreferences.getInstance().setValueToMap(common.string.KEY_OF_HAVE_MULTI_SIM_CARD_READY,
132    this.haveMultiSimCardReady);
133    MmsPreferences.getInstance().setValueToMap(common.string.KEY_OF_HAVE_SIM_CARD_READY, this.haveSimCardReady);
134  }
135
136  private setDefaultSlotToMap() {
137    if (this.haveSimCardReady) {
138      if (!this.haveMultiSimCardReady) {
139        if (this.isSimReady(common.int.SIM_ONE)) {
140          MmsPreferences.getInstance().setValueToMap(common.string.KEY_OF_DEFAULT_SLOT, common.int.SIM_ONE);
141        } else {
142          MmsPreferences.getInstance().setValueToMap(common.string.KEY_OF_DEFAULT_SLOT, common.int.SIM_TWO);
143        }
144      } else {
145        telephonySim.getDefaultVoiceSlotId((error, slotId: number) => {
146          if (error) {
147            HiLog.e(TAG, "getDefaultVoiceSlotId error, slotId: " + slotId + ", error: " + JSON.stringify(error));
148          } else {
149            MmsPreferences.getInstance().setValueToMap(common.string.KEY_OF_DEFAULT_SLOT, slotId);
150          }
151        });
152      }
153    }
154  }
155
156  private setSpnToMap(slotId: number): void {
157    // get spn from sim card
158    telephonySim.getSimSpn(slotId, (error, data) => {
159      if (error || !data) {
160        HiLog.w(TAG, "getSpnFromSim fail, slotId: " + slotId + ", data: " + data + ", error: "
161        + JSON.stringify(error));
162      } else {
163        this.notifySetSimSpnToMap(slotId, data);
164        return;
165      }
166    });
167    // get spn from network
168    radio.getOperatorName(slotId, (error, data) => {
169      if (error || !data) {
170        HiLog.w(TAG, "getSpnFromSim fail, slotId: " + slotId + ", data: " + data + ", error: "
171        + JSON.stringify(error));
172      } else {
173        this.notifySetSimSpnToMap(slotId, data);
174        return;
175      }
176    });
177    // get plmn to replace spn
178    telephonySim.getSimOperatorNumeric(slotId, (error, data) => {
179      if (error || !data) {
180        HiLog.w(TAG, "getSimOperatorNumeric fail, slotId: " + slotId + ", data: " + data + ", error: "
181        + JSON.stringify(error));
182      } else {
183        if (common.int.SIM_ONE === slotId) {
184          MmsPreferences.getInstance().setValueToMap(common.string.KEY_OF_SIM_0_SPN, this.spn);
185        } else {
186          MmsPreferences.getInstance().setValueToMap(common.string.KEY_OF_SIM_1_SPN, this.spn);
187        }
188        return;
189      }
190    });
191  }
192
193  private notifySetSimSpnToMap(slotId: number, spn: string): void {
194    HiLog.d(TAG, "notifyUpdateSimSpn slotId: " + slotId + ", spn: " + spn);
195    this.spn = spn;
196    if (common.SPN_CHINA.MOBILE == spn) {
197      this.spn = globalThis.mmsContext.resourceManager.getStringSync($r('app.string.china_mobile').id);
198    } else if (common.SPN_CHINA.TELECOM == spn) {
199      this.spn = globalThis.mmsContext.resourceManager.getStringSync($r('app.string.china_telecom').id);
200    } else if (common.SPN_CHINA.UNICOM == spn) {
201      this.spn = globalThis.mmsContext.resourceManager.getStringSync($r('app.string.china_unicom').id);
202    }
203    if (common.int.SIM_ONE === slotId) {
204      MmsPreferences.getInstance().setValueToMap(common.string.KEY_OF_SIM_0_SPN, this.spn);
205    } else {
206      MmsPreferences.getInstance().setValueToMap(common.string.KEY_OF_SIM_1_SPN, this.spn);
207    }
208  }
209
210  private setSimTelephoneNumberToMap(slotId: number): void {
211    telephonySim.getSimTelephoneNumber(slotId, (error, value) => {
212      if (error) {
213        HiLog.e(TAG, "get slotId: " + slotId + " telephone number error: " + JSON.stringify(error));
214      } else {
215        if (common.int.SIM_ONE === slotId) {
216          MmsPreferences.getInstance().setValueToMap(common.string.KEY_OF_SIM_0_NUMBER, value);
217        } else {
218          MmsPreferences.getInstance().setValueToMap(common.string.KEY_OF_SIM_1_NUMBER, value);
219        }
220      }
221    });
222  }
223
224  private unsubscribeSpnObserver() {
225    if (this.spnEventSubscriber) {
226      CommonEvent.unsubscribe(this.spnEventSubscriber);
227    }
228  }
229
230  private subscribeSpnObserver() {
231    let subscribeInfo = {
232      events: ['usual.event.SPN_INFO_CHANGED']
233    };
234    CommonEvent.createSubscriber(subscribeInfo, (err, data) => {
235      if (err) {
236        HiLog.e(TAG, "subscribeSpnObserver error: " + JSON.stringify(err))
237        return
238      }
239      this.spnEventSubscriber = data;
240      CommonEvent.subscribe(data, (err, data) => {
241        if (data && data.parameters) {
242          let spn = data.parameters.CUR_SPN ? data.parameters.CUR_SPN : data.parameters.CUR_PLMN;
243          if (spn) {
244            HiLog.i(TAG, "SPN_INFO_CHANGED notify slotId: " + data.parameters.CUR_SLOT_ID + ", spn: " + spn);
245            this.notifySetSimSpnToMap(data.parameters.CUR_SLOT_ID, spn);
246          }
247        }
248      })
249    });
250  }
251
252  private setSmscNumberToPref(slotId: number): void {
253    telephonySMS.getSmscAddr(slotId).then((simPhoneNumber) => {
254      if (slotId == common.int.SIM_ONE) {
255        MmsPreferences.getInstance().setValueForSwitch(common.string.KEY_OF_NEW_SIM_0_SMSC, simPhoneNumber);
256      } else if (slotId == common.int.SIM_TWO) {
257        MmsPreferences.getInstance().setValueForSwitch(common.string.KEY_OF_NEW_SIM_1_SMSC, simPhoneNumber);
258      }
259    }).catch((error) => {
260      HiLog.e(TAG, "setSmscNumberToPref error: " + JSON.stringify(error.message));
261    });
262  }
263}
264
265// Singleton
266export default new CardModel();