1/*
2 * Copyright (C) 2021 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#include "telephony_state_registry_stub.h"
17
18#include "ipc_skeleton.h"
19#include "string_ex.h"
20
21#include "sim_state_type.h"
22#include "state_registry_errors.h"
23#include "telephony_permission.h"
24
25#ifdef HICOLLIE_ENABLE
26#include "xcollie/xcollie.h"
27#include "xcollie/xcollie_define.h"
28#define XCOLLIE_TIMEOUT_SECONDS 30
29#endif
30
31namespace OHOS {
32namespace Telephony {
33TelephonyStateRegistryStub::TelephonyStateRegistryStub()
34{
35    memberFuncMap_[StateNotifyInterfaceCode::CELL_INFO] =
36        [this](MessageParcel &data, MessageParcel &reply) { return OnUpdateCellInfo(data, reply); };
37    memberFuncMap_[StateNotifyInterfaceCode::SIM_STATE] =
38        [this](MessageParcel &data, MessageParcel &reply) { return OnUpdateSimState(data, reply); };
39    memberFuncMap_[StateNotifyInterfaceCode::SIGNAL_INFO] =
40        [this](MessageParcel &data, MessageParcel &reply) { return OnUpdateSignalInfo(data, reply); };
41    memberFuncMap_[StateNotifyInterfaceCode::NET_WORK_STATE] =
42        [this](MessageParcel &data, MessageParcel &reply) { return OnUpdateNetworkState(data, reply); };
43    memberFuncMap_[StateNotifyInterfaceCode::CALL_STATE] =
44        [this](MessageParcel &data, MessageParcel &reply) { return OnUpdateCallState(data, reply); };
45    memberFuncMap_[StateNotifyInterfaceCode::CALL_STATE_FOR_ID] =
46        [this](MessageParcel &data, MessageParcel &reply) { return OnUpdateCallStateForSlotId(data, reply); };
47    memberFuncMap_[StateNotifyInterfaceCode::CELLULAR_DATA_STATE] =
48        [this](MessageParcel &data, MessageParcel &reply) { return OnUpdateCellularDataConnectState(data, reply); };
49    memberFuncMap_[StateNotifyInterfaceCode::CELLULAR_DATA_FLOW] =
50        [this](MessageParcel &data, MessageParcel &reply) { return OnUpdateCellularDataFlow(data, reply); };
51    memberFuncMap_[StateNotifyInterfaceCode::ADD_OBSERVER] =
52        [this](MessageParcel &data, MessageParcel &reply) { return OnRegisterStateChange(data, reply); };
53    memberFuncMap_[StateNotifyInterfaceCode::REMOVE_OBSERVER] =
54        [this](MessageParcel &data, MessageParcel &reply) { return OnUnregisterStateChange(data, reply); };
55    memberFuncMap_[StateNotifyInterfaceCode::CFU_INDICATOR] =
56        [this](MessageParcel &data, MessageParcel &reply) { return OnUpdateCfuIndicator(data, reply); };
57    memberFuncMap_[StateNotifyInterfaceCode::VOICE_MAIL_MSG_INDICATOR] =
58        [this](MessageParcel &data, MessageParcel &reply) { return OnUpdateVoiceMailMsgIndicator(data, reply); };
59    memberFuncMap_[StateNotifyInterfaceCode::ICC_ACCOUNT_CHANGE] =
60        [this](MessageParcel &data, MessageParcel &reply) { return OnIccAccountUpdated(data, reply); };
61}
62
63TelephonyStateRegistryStub::~TelephonyStateRegistryStub()
64{
65    memberFuncMap_.clear();
66}
67
68int32_t TelephonyStateRegistryStub::OnRemoteRequest(
69    uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
70{
71    TELEPHONY_LOGD("TelephonyStateRegistryStub::OnRemoteRequest start##code = %{public}u", code);
72    std::u16string myToken = TelephonyStateRegistryStub::GetDescriptor();
73    std::u16string remoteToken = data.ReadInterfaceToken();
74    if (myToken != remoteToken) {
75        TELEPHONY_LOGE("TelephonyStateRegistryStub::OnRemoteRequest end##descriptor checked fail");
76        return TELEPHONY_ERR_DESCRIPTOR_MISMATCH;
77    }
78    auto itFunc = memberFuncMap_.find(static_cast<StateNotifyInterfaceCode>(code));
79    if (itFunc != memberFuncMap_.end()) {
80        auto memberFunc = itFunc->second;
81        if (memberFunc != nullptr) {
82            int32_t idTimer = SetTimer(code);
83            int32_t result = memberFunc(data, reply);
84            CancelTimer(idTimer);
85            return result;
86        }
87    }
88    int ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option);
89    TELEPHONY_LOGI("TelephonyStateRegistryStub::OnRemoteRequest end##ret=%{public}d", ret);
90    return ret;
91}
92
93int32_t TelephonyStateRegistryStub::SetTimer(uint32_t code)
94{
95#ifdef HICOLLIE_ENABLE
96    int32_t idTimer = HiviewDFX::INVALID_ID;
97    std::map<uint32_t, std::string>::iterator itCollieId = collieCodeStringMap_.find(code);
98    if (itCollieId != collieCodeStringMap_.end()) {
99        std::string collieStr = itCollieId->second;
100        std::string collieName = "TelephonyStateRegistryStub: " + collieStr;
101        unsigned int flag = HiviewDFX::XCOLLIE_FLAG_NOOP;
102        auto TimerCallback = [collieStr](void *) {
103            TELEPHONY_LOGE("OnRemoteRequest timeout func: %{public}s", collieStr.c_str());
104        };
105        idTimer = HiviewDFX::XCollie::GetInstance().SetTimer(
106            collieName, XCOLLIE_TIMEOUT_SECONDS, TimerCallback, nullptr, flag);
107        TELEPHONY_LOGD("SetTimer id: %{public}d, name: %{public}s.", idTimer, collieStr.c_str());
108    }
109    return idTimer;
110#else
111    TELEPHONY_LOGD("No HICOLLIE_ENABLE");
112    return -1;
113#endif
114}
115
116void TelephonyStateRegistryStub::CancelTimer(int32_t id)
117{
118#ifdef HICOLLIE_ENABLE
119    if (id == HiviewDFX::INVALID_ID) {
120        return;
121    }
122    TELEPHONY_LOGD("CancelTimer id: %{public}d.", id);
123    HiviewDFX::XCollie::GetInstance().CancelTimer(id);
124#else
125    return;
126#endif
127}
128
129int32_t TelephonyStateRegistryStub::OnUpdateCallState(MessageParcel &data, MessageParcel &reply)
130{
131    int32_t callState = data.ReadInt32();
132    std::u16string phoneNumber = data.ReadString16();
133    int32_t ret = UpdateCallState(callState, phoneNumber);
134    TELEPHONY_LOGI("TelephonyStateRegistryStub::OnUpdateCallState end##ret=%{public}d", ret);
135    reply.WriteInt32(ret);
136    return NO_ERROR;
137}
138
139int32_t TelephonyStateRegistryStub::OnUpdateSimState(MessageParcel &data, MessageParcel &reply)
140{
141    int32_t slotId = data.ReadInt32();
142    CardType type = static_cast<CardType>(data.ReadInt32());
143    SimState state = static_cast<SimState>(data.ReadInt32());
144    LockReason reason = static_cast<LockReason>(data.ReadInt32());
145    int32_t ret = UpdateSimState(slotId, type, state, reason);
146    TELEPHONY_LOGI("TelephonyStateRegistryStub::OnUpdateSimState end##ret=%{public}d", ret);
147    reply.WriteInt32(ret);
148    return NO_ERROR;
149}
150
151int32_t TelephonyStateRegistryStub::OnUpdateCallStateForSlotId(MessageParcel &data, MessageParcel &reply)
152{
153    int32_t slotId = data.ReadInt32();
154    int32_t callState = data.ReadInt32();
155    std::u16string incomingNumber = data.ReadString16();
156    int32_t ret = UpdateCallStateForSlotId(slotId, callState, incomingNumber);
157    TELEPHONY_LOGI("TelephonyStateRegistryStub::OnUpdateCallStateForSlotId end##ret=%{public}d", ret);
158    reply.WriteInt32(ret);
159    return NO_ERROR;
160}
161
162int32_t TelephonyStateRegistryStub::OnUpdateCellularDataConnectState(MessageParcel &data, MessageParcel &reply)
163{
164    int32_t slotId = data.ReadInt32();
165    int32_t dataState = data.ReadInt32();
166    int32_t networkType = data.ReadInt32();
167    int32_t ret = UpdateCellularDataConnectState(slotId, dataState, networkType);
168    if (ret != TELEPHONY_SUCCESS) {
169        TELEPHONY_LOGE("TelephonyStateRegistryStub::OnUpdateCellularDataConnectState end fail##ret=%{public}d", ret);
170    }
171    reply.WriteInt32(ret);
172    return NO_ERROR;
173}
174
175int32_t TelephonyStateRegistryStub::OnUpdateCellularDataFlow(MessageParcel &data, MessageParcel &reply)
176{
177    int32_t slotId = data.ReadInt32();
178    int32_t flowData = data.ReadInt32();
179    int32_t ret = UpdateCellularDataFlow(slotId, flowData);
180    if (ret != TELEPHONY_SUCCESS) {
181        TELEPHONY_LOGE("TelephonyStateRegistryStub::OnUpdateCellularDataFlow end fail##ret=%{public}d", ret);
182    }
183    reply.WriteInt32(ret);
184    return NO_ERROR;
185}
186
187int32_t TelephonyStateRegistryStub::OnUpdateSignalInfo(MessageParcel &data, MessageParcel &reply)
188{
189    int32_t ret = TELEPHONY_SUCCESS;
190    int32_t slotId = data.ReadInt32();
191    int32_t size = data.ReadInt32();
192    TELEPHONY_LOGI("TelephonyStateRegistryStub::OnUpdateSignalInfo size=%{public}d", size);
193    size = ((size > SignalInformation::MAX_SIGNAL_NUM) ? 0 : size);
194    if (size < 0) {
195        ret = TELEPHONY_ERR_FAIL;
196        TELEPHONY_LOGE("TelephonyStateRegistryStub::OnUpdateSignalInfo size < 0");
197        return ret;
198    }
199    std::vector<sptr<SignalInformation>> result;
200    parseSignalInfos(data, size, result);
201    ret = UpdateSignalInfo(slotId, result);
202    if (ret != TELEPHONY_SUCCESS) {
203        TELEPHONY_LOGE("TelephonyStateRegistryStub::OnUpdateSignalInfo end fail##ret=%{public}d", ret);
204    }
205    reply.WriteInt32(ret);
206    return NO_ERROR;
207}
208
209void TelephonyStateRegistryStub::parseSignalInfos(
210    MessageParcel &data, const int32_t size, std::vector<sptr<SignalInformation>> &result)
211{
212    SignalInformation::NetworkType type;
213    for (int i = 0; i < size; ++i) {
214        type = static_cast<SignalInformation::NetworkType>(data.ReadInt32());
215        switch (type) {
216            case SignalInformation::NetworkType::GSM: {
217                TELEPHONY_LOGI("TelephonyStateRegistryStub::parseSignalInfos NetworkType::GSM");
218                std::unique_ptr<GsmSignalInformation> signal = std::make_unique<GsmSignalInformation>();
219                if (signal != nullptr) {
220                    signal->ReadFromParcel(data);
221                    result.emplace_back(signal.release());
222                }
223                break;
224            }
225            case SignalInformation::NetworkType::CDMA: {
226                TELEPHONY_LOGI("TelephonyStateRegistryStub::parseSignalInfos NetworkType::CDMA");
227                std::unique_ptr<CdmaSignalInformation> signal = std::make_unique<CdmaSignalInformation>();
228                if (signal != nullptr) {
229                    signal->ReadFromParcel(data);
230                    result.emplace_back(signal.release());
231                }
232                break;
233            }
234            case SignalInformation::NetworkType::LTE:
235                [[fallthrough]]; // fall_through
236            case SignalInformation::NetworkType::NR: {
237                ParseLteNrSignalInfos(data, result, type);
238                break;
239            }
240            case SignalInformation::NetworkType::WCDMA: {
241                TELEPHONY_LOGI("TelephonyStateRegistryStub::parseSignalInfos NetworkType::Wcdma");
242                std::unique_ptr<WcdmaSignalInformation> signal = std::make_unique<WcdmaSignalInformation>();
243                if (signal != nullptr) {
244                    signal->ReadFromParcel(data);
245                    result.emplace_back(signal.release());
246                }
247                break;
248            }
249            default:
250                break;
251        }
252    }
253}
254
255void TelephonyStateRegistryStub::ParseLteNrSignalInfos(
256    MessageParcel &data, std::vector<sptr<SignalInformation>> &result, SignalInformation::NetworkType type)
257{
258    switch (type) {
259        case SignalInformation::NetworkType::LTE: {
260            TELEPHONY_LOGI("TelephonyStateRegistryStub::ParseLteNrSignalInfos NetworkType::LTE");
261            std::unique_ptr<LteSignalInformation> signal = std::make_unique<LteSignalInformation>();
262            if (signal != nullptr) {
263                signal->ReadFromParcel(data);
264                result.emplace_back(signal.release());
265            }
266            break;
267        }
268        case SignalInformation::NetworkType::NR: {
269            TELEPHONY_LOGI("TelephonyStateRegistryStub::ParseSignalInfos");
270            std::unique_ptr<NrSignalInformation> signal = std::make_unique<NrSignalInformation>();
271            if (signal != nullptr) {
272                signal->ReadFromParcel(data);
273                result.emplace_back(signal.release());
274            }
275            break;
276        }
277        default:
278            break;
279    }
280}
281
282int32_t TelephonyStateRegistryStub::OnUpdateCellInfo(MessageParcel &data, MessageParcel &reply)
283{
284    int32_t ret = TELEPHONY_SUCCESS;
285    int32_t slotId = data.ReadInt32();
286    int32_t size = data.ReadInt32();
287    TELEPHONY_LOGI("TelephonyStateRegistryStub OnUpdateCellInfo:size=%{public}d", size);
288    size = ((size > CellInformation::MAX_CELL_NUM) ? 0 : size);
289    if (size <= 0) {
290        ret = TELEPHONY_ERR_FAIL;
291        TELEPHONY_LOGE("TelephonyStateRegistryStub the size less than or equal to 0!");
292        return ret;
293    }
294    std::vector<sptr<CellInformation>> cells;
295    CellInformation::CellType type;
296    for (int i = 0; i < size; ++i) {
297        type = static_cast<CellInformation::CellType>(data.ReadInt32());
298        switch (type) {
299            case CellInformation::CellType::CELL_TYPE_GSM: {
300                std::unique_ptr<GsmCellInformation> cell = std::make_unique<GsmCellInformation>();
301                if (cell != nullptr) {
302                    cell->ReadFromParcel(data);
303                    cells.emplace_back(cell.release());
304                }
305                break;
306            }
307            case CellInformation::CellType::CELL_TYPE_LTE: {
308                std::unique_ptr<LteCellInformation> cell = std::make_unique<LteCellInformation>();
309                if (cell != nullptr) {
310                    cell->ReadFromParcel(data);
311                    cells.emplace_back(cell.release());
312                }
313                break;
314            }
315            case CellInformation::CellType::CELL_TYPE_NR: {
316                std::unique_ptr<NrCellInformation> cell = std::make_unique<NrCellInformation>();
317                if (cell != nullptr) {
318                    cell->ReadFromParcel(data);
319                    cells.emplace_back(cell.release());
320                }
321                break;
322            }
323            default:
324                break;
325        }
326    }
327    ret = UpdateCellInfo(slotId, cells);
328    TELEPHONY_LOGI("TelephonyStateRegistryStub::OnUpdateCellInfo end##ret=%{public}d", ret);
329    reply.WriteInt32(ret);
330    return NO_ERROR;
331}
332
333int32_t TelephonyStateRegistryStub::OnUpdateNetworkState(MessageParcel &data, MessageParcel &reply)
334{
335    int32_t ret = TELEPHONY_SUCCESS;
336    int32_t slotId = data.ReadInt32();
337    sptr<NetworkState> result = NetworkState::Unmarshalling(data);
338    if (result == nullptr) {
339        TELEPHONY_LOGE("TelephonyStateRegistryStub::OnUpdateNetworkState GetNetworkStatus  is null");
340        ret = TELEPHONY_ERR_FAIL;
341        return ret;
342    }
343    ret = UpdateNetworkState(slotId, result);
344    TELEPHONY_LOGI("TelephonyStateRegistryStub::OnUpdateNetworkState end##ret=%{public}d", ret);
345    reply.WriteInt32(ret);
346    return NO_ERROR;
347}
348
349int32_t TelephonyStateRegistryStub::OnRegisterStateChange(MessageParcel &data, MessageParcel &reply)
350{
351    int32_t ret = TELEPHONY_SUCCESS;
352    int32_t slotId = data.ReadInt32();
353    int32_t mask = data.ReadInt32();
354    bool notifyNow = data.ReadBool();
355    sptr<TelephonyObserverBroker> callback = nullptr;
356    ret = ReadData(data, reply, callback);
357    if (ret != TELEPHONY_SUCCESS) {
358        reply.WriteInt32(ret);
359        TELEPHONY_LOGE("TelephonyStateRegistryStub::OnRegisterStateChange ReadData failed");
360        return NO_ERROR;
361    }
362    ret = RegisterStateChange(callback, slotId, mask, notifyNow);
363    if (ret != TELEPHONY_SUCCESS) {
364        TELEPHONY_LOGE("TelephonyStateRegistryStub::OnRegisterStateChange end fail##ret=%{public}d", ret);
365    }
366    reply.WriteInt32(ret);
367    return NO_ERROR;
368}
369
370int32_t TelephonyStateRegistryStub::OnUnregisterStateChange(MessageParcel &data, MessageParcel &reply)
371{
372    int32_t slotId = data.ReadInt32();
373    int32_t mask = data.ReadInt32();
374    int32_t ret = UnregisterStateChange(slotId, mask);
375    if (ret != TELEPHONY_SUCCESS) {
376        TELEPHONY_LOGE("TelephonyStateRegistryStub::OnUnregisterStateChange end fail##ret=%{public}d", ret);
377    }
378    reply.WriteInt32(ret);
379    return NO_ERROR;
380}
381
382int32_t TelephonyStateRegistryStub::ReadData(
383    MessageParcel &data, MessageParcel &reply, sptr<TelephonyObserverBroker> &callback)
384{
385    int32_t result = TELEPHONY_SUCCESS;
386    sptr<IRemoteObject> remote = data.ReadRemoteObject();
387    if (remote == nullptr) {
388        TELEPHONY_LOGE("TelephonyStateRegistryStub::ReadData  remote is nullptr.");
389        result = TELEPHONY_ERR_FAIL;
390        reply.WriteInt32(result);
391        return result;
392    }
393    callback = iface_cast<TelephonyObserverBroker>(remote);
394    if (callback == nullptr) {
395        TELEPHONY_LOGE("TelephonyStateRegistryStub::ReadData callback is nullptr.");
396        result = TELEPHONY_ERR_FAIL;
397        reply.WriteInt32(result);
398        return result;
399    }
400    return result;
401}
402
403int32_t TelephonyStateRegistryStub::OnUpdateCfuIndicator(MessageParcel &data, MessageParcel &reply)
404{
405    int32_t slotId = data.ReadInt32();
406    bool cfuResult = data.ReadBool();
407    int32_t ret = UpdateCfuIndicator(slotId, cfuResult);
408    TELEPHONY_LOGI("TelephonyStateRegistryStub::OnUpdateCfuIndicator end##ret=%{public}d", ret);
409    reply.WriteInt32(ret);
410    return NO_ERROR;
411}
412
413int32_t TelephonyStateRegistryStub::OnUpdateVoiceMailMsgIndicator(MessageParcel &data, MessageParcel &reply)
414{
415    int32_t slotId = data.ReadInt32();
416    bool voiceMailMsgResult = data.ReadBool();
417    int32_t ret = UpdateVoiceMailMsgIndicator(slotId, voiceMailMsgResult);
418    TELEPHONY_LOGI("TelephonyStateRegistryStub::OnUpdateVoiceMailMsgIndicator end##ret=%{public}d", ret);
419    reply.WriteInt32(ret);
420    return NO_ERROR;
421}
422
423int32_t TelephonyStateRegistryStub::OnIccAccountUpdated(MessageParcel &data, MessageParcel &reply)
424{
425    int32_t ret = UpdateIccAccount();
426    TELEPHONY_LOGI("end##ret=%{public}d", ret);
427    reply.WriteInt32(ret);
428    return NO_ERROR;
429}
430
431int32_t TelephonyStateRegistryStub::RegisterStateChange(const sptr<TelephonyObserverBroker> &telephonyObserver,
432    int32_t slotId, uint32_t mask, bool isUpdate)
433{
434    int32_t uid = IPCSkeleton::GetCallingUid();
435    std::string bundleName = "";
436    TelephonyPermission::GetBundleNameByUid(uid, bundleName);
437    int32_t tokenId = static_cast<int32_t>(IPCSkeleton::GetCallingTokenID());
438    return RegisterStateChange(telephonyObserver, slotId, mask, bundleName, isUpdate,
439        IPCSkeleton::GetCallingPid(), uid, tokenId);
440}
441
442int32_t TelephonyStateRegistryStub::UnregisterStateChange(int32_t slotId, uint32_t mask)
443{
444    int32_t tokenId = static_cast<int32_t>(IPCSkeleton::GetCallingTokenID());
445    return UnregisterStateChange(slotId, mask, tokenId, IPCSkeleton::GetCallingPid());
446}
447} // namespace Telephony
448} // namespace OHOS