1/*
2 * Copyright (c) 2023 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 "dupdate_net_observer.h"
17
18#include <pthread.h>
19#include <thread>
20#include <unistd.h>
21
22#include "net_conn_client.h"
23#include "net_conn_constants.h"
24
25#include "string_utils.h"
26#include "update_log.h"
27
28using namespace OHOS::NetManagerStandard;
29
30namespace OHOS {
31namespace UpdateEngine {
32void NetObserver::SetCallback(const std::weak_ptr<INetObserverCallback> &callback)
33{
34    callback_ = callback;
35}
36
37void NetObserver::StartObserver()
38{
39    ENGINE_LOGI("StartObserver");
40    auto observerExecFunc = [this]() {
41        NetSpecifier netSpecifier;
42        NetAllCapabilities netAllCapabilities;
43        netAllCapabilities.netCaps_.insert(NetManagerStandard::NetCap::NET_CAPABILITY_INTERNET);
44        netSpecifier.ident_ = "";
45        netSpecifier.netCapabilities_ = netAllCapabilities;
46        sptr<NetSpecifier> specifier = new NetSpecifier(netSpecifier);
47        constexpr int32_t RETRY_MAX_TIMES = 10;
48        int32_t retryCount = 0;
49        int32_t ret = NetConnResultCode::NET_CONN_SUCCESS;
50        do {
51            ret = NetConnClient::GetInstance().RegisterNetConnCallback(specifier, this, 0);
52            if (ret == NetConnResultCode::NET_CONN_SUCCESS) {
53                ENGINE_LOGI("StartObserver register success");
54                return;
55            }
56            retryCount++;
57            ENGINE_LOGE("StartObserver retry, ret = %{public}d", ret);
58            sleep(1);
59        } while (retryCount < RETRY_MAX_TIMES);
60        ENGINE_LOGE("StartObserver failed");
61    };
62    std::thread th = std::thread(observerExecFunc);
63    th.detach();
64}
65
66int32_t NetObserver::NetCapabilitiesChange(sptr<NetHandle> &netHandle, const sptr<NetAllCapabilities> &netAllCap)
67{
68    if (netAllCap == nullptr) {
69        return 0;
70    }
71    if (netAllCap->netCaps_.count(NET_CAPABILITY_INTERNET) <= 0) {
72        OnNetChange(NetType::NO_NET);
73        return 0;
74    }
75    ENGINE_LOGI("NetCapabilitiesChange NetAvailable");
76    if (netAllCap->bearerTypes_.count(BEARER_ETHERNET) > 0 || netAllCap->bearerTypes_.count(BEARER_WIFI) > 0) {
77        // wifi和以太网都映射为wifi
78        OnNetChange(NetType::NOT_METERED_WIFI);
79        return 0;
80    }
81    if (netAllCap->bearerTypes_.count(BEARER_WIFI_AWARE) > 0) {
82        OnNetChange(NetType::METERED_WIFI);
83        return 0;
84    }
85    if (netAllCap->bearerTypes_.count(BEARER_CELLULAR) > 0) {
86        OnNetChange(NetType::CELLULAR);
87        return 0;
88    }
89    return 0;
90}
91
92int32_t NetObserver::NetLost(sptr<NetHandle> &netHandle)
93{
94    ENGINE_LOGI("NetLost");
95    OnNetChange(NetType::NO_NET);
96    return 0;
97}
98
99void NetObserver::OnNetChange(NetType netType)
100{
101    ENGINE_LOGI("OnNetChange %{public}d", netType);
102    if (callback_.expired()) {
103        ENGINE_LOGI("callback is recycled");
104        return;
105    }
106    bool result = callback_.lock()->OnNetChange(netType);
107    ENGINE_LOGD("OnNetChange callback result %{public}s", StringUtils::GetBoolStr(result).c_str());
108}
109} // namespace UpdateEngine
110} // namespace OHOS