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 commonEvent from "@ohos.commonEvent";
17import Radio from '@ohos.telephony.radio';
18import Sim from '@ohos.telephony.sim';
19import Observer from '@ohos.telephony.observer';
20import Log from "../../../../../../common/src/main/ets/default/Log";
21import Constants from './common/constants';
22
23const TAG = 'SignalStatus-SignalModel';
24
25let isInitObserver = false;
26let commonEventData = null;
27
28var mLevelLink;
29var mTypeLink;
30var mStateLink;
31
32export class SignalModel {
33  constructor() {
34    mLevelLink = AppStorage.SetAndLink("cellularLevel", Constants.CELLULAR_NO_SIM_CARD);
35    mTypeLink = AppStorage.SetAndLink("cellularType", Constants.RADIO_TECHNOLOGY_UNKNOWN);
36    mStateLink = AppStorage.SetAndLink("networkState", Constants.NET_NULL);
37    this.addSubscriberListener();
38  }
39
40  initSignalModel() {
41    Log.showInfo(TAG, 'initSignalModel');
42    this.checkCellularStatus();
43  }
44
45  /**
46   * add mms app subscriber
47   */
48  async addSubscriberListener() {
49    let events = [Constants.COMMON_EVENT_SPN_INFO_CHANGED];
50    let commonEventSubscribeInfo = {
51      events: events
52    };
53    commonEvent.createSubscriber(commonEventSubscribeInfo, this.createSubscriberCallBack.bind(this));
54  }
55
56  createSubscriberCallBack(err, data) {
57    commonEventData = data;
58    commonEvent.subscribe(commonEventData, this.subscriberCallBack.bind(this));
59  }
60
61  subscriberCallBack(err, data) {
62    if (data.event === Constants.COMMON_EVENT_SPN_INFO_CHANGED) {
63      if (data?.parameters?.CUR_PLMN) {
64        Log.showInfo(TAG, `receive stateLink: ${data.parameters.CUR_PLMN}`);
65        mStateLink.set(data.parameters.CUR_PLMN);
66      } else {
67        Log.showError(TAG, `get stateLink failed.`);
68        mStateLink.set(Constants.NET_NULL);
69      }
70    }
71  }
72
73  uninitSignalModel() {
74    Log.showInfo(TAG, 'uninitSignalModel');
75    this.unInitObserver();
76  }
77
78  /**
79     * Check the connection type and signal level of cellular network
80     */
81  checkCellularStatus() {
82    let slotId = 0;
83    Sim.hasSimCard(slotId, (err, value) => {
84      if (value === true) {
85        Radio.getNetworkState((err, value) => {
86          if (err || !value) {
87            mTypeLink.set(Constants.RADIO_TECHNOLOGY_UNKNOWN);
88            mLevelLink.set(Constants.CELLULAR_NO_SIM_CARD);
89          } else {
90            // If there is no service, no signal is displayed.
91            if (value.regState != Constants.REG_STATE_IN_SERVICE) {
92              mTypeLink.set(Constants.RADIO_TECHNOLOGY_UNKNOWN);
93              mLevelLink.set(Constants.CELLULAR_NO_SIM_CARD);
94            } else {
95              mTypeLink.set(value.cfgTech);
96              Radio.getSignalInformation(slotId, (err, value) => {
97                if (err || !value || !value.length) {
98                  mLevelLink.set(Constants.CELLULAR_NO_SIM_CARD);
99                } else {
100                  mLevelLink.set(value[0].signalLevel);
101                }
102              });
103            }
104          }
105        });
106      } else {
107        Log.showWarn(TAG, `hasSimCard failed to hasSimCard because`);
108        mLevelLink.set(Constants.CELLULAR_NO_SIM_CARD);
109        mTypeLink.set(Constants.RADIO_TECHNOLOGY_UNKNOWN);
110        mStateLink.set(Constants.NET_NULL);
111      }
112      if (!isInitObserver) {
113        this.initObserver();
114      }
115    });
116  }
117
118  /**
119     * init the observer of the cellular and signal
120     */
121  initObserver() {
122    Log.showInfo(TAG, 'initObserver');
123    isInitObserver = true;
124    Observer.on('signalInfoChange', (signalInfoChange) => {
125      this.checkCellularStatus();
126    });
127    Observer.on('networkStateChange', (networkState) => {
128      this.checkCellularStatus();
129    });
130    Observer.on('simStateChange', (simStateInfo) => {
131      this.checkCellularStatus();
132    });
133  }
134
135  /**
136     * Uninit the observer of the cellular and signal
137     */
138  unInitObserver() {
139    Log.showInfo(TAG, 'unInitObserver');
140    Observer.off('signalInfoChange');
141    Observer.off('networkStateChange');
142    Observer.off('simStateChange');
143    isInitObserver = false;
144  }
145}
146
147let mSignalModel = new SignalModel();
148
149export default mSignalModel as SignalModel;