xref: /aosp_15_r20/external/webrtc/sdk/objc/native/src/objc_network_monitor.mm (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1/*
2 *  Copyright 2020 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "sdk/objc/native/src/objc_network_monitor.h"
12#include "absl/strings/string_view.h"
13
14#include <algorithm>
15
16#include "rtc_base/logging.h"
17#include "rtc_base/string_utils.h"
18
19namespace webrtc {
20
21rtc::NetworkMonitorInterface* ObjCNetworkMonitorFactory::CreateNetworkMonitor(
22    const FieldTrialsView& field_trials) {
23  return new ObjCNetworkMonitor();
24}
25
26ObjCNetworkMonitor::ObjCNetworkMonitor() {
27  safety_flag_ = PendingTaskSafetyFlag::Create();
28}
29
30ObjCNetworkMonitor::~ObjCNetworkMonitor() {
31  [network_monitor_ stop];
32  network_monitor_ = nil;
33}
34
35void ObjCNetworkMonitor::Start() {
36  if (started_) {
37    return;
38  }
39  thread_ = rtc::Thread::Current();
40  RTC_DCHECK_RUN_ON(thread_);
41  safety_flag_->SetAlive();
42  network_monitor_ = [[RTCNetworkMonitor alloc] initWithObserver:this];
43  if (network_monitor_ == nil) {
44    RTC_LOG(LS_WARNING) << "Failed to create RTCNetworkMonitor; not available on this OS?";
45  }
46  started_ = true;
47}
48
49void ObjCNetworkMonitor::Stop() {
50  RTC_DCHECK_RUN_ON(thread_);
51  if (!started_) {
52    return;
53  }
54  safety_flag_->SetNotAlive();
55  [network_monitor_ stop];
56  network_monitor_ = nil;
57  started_ = false;
58}
59
60rtc::NetworkMonitorInterface::InterfaceInfo ObjCNetworkMonitor::GetInterfaceInfo(
61    absl::string_view interface_name) {
62  RTC_DCHECK_RUN_ON(thread_);
63  if (adapter_type_by_name_.empty()) {
64    // If we have no path update, assume everything's available, because it's
65    // preferable for WebRTC to try all interfaces rather than none at all.
66    return {
67        .adapter_type = rtc::ADAPTER_TYPE_UNKNOWN,
68        .available = true,
69    };
70  }
71  auto iter = adapter_type_by_name_.find(interface_name);
72  if (iter == adapter_type_by_name_.end()) {
73    return {
74        .adapter_type = rtc::ADAPTER_TYPE_UNKNOWN,
75        .available = false,
76    };
77  }
78
79  return {
80      .adapter_type = iter->second,
81      .available = true,
82  };
83}
84
85void ObjCNetworkMonitor::OnPathUpdate(
86    std::map<std::string, rtc::AdapterType, rtc::AbslStringViewCmp> adapter_type_by_name) {
87  RTC_DCHECK(network_monitor_ != nil);
88  thread_->PostTask(SafeTask(safety_flag_, [this, adapter_type_by_name] {
89    RTC_DCHECK_RUN_ON(thread_);
90    adapter_type_by_name_ = adapter_type_by_name;
91    InvokeNetworksChangedCallback();
92  }));
93}
94
95}  // namespace webrtc
96