Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: talk/app/webrtc/java/jni/androidnetworkmonitor_jni.cc

Issue 1594673002: Get the adapter type information from Android OS. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Addressed comments Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « talk/app/webrtc/java/jni/androidnetworkmonitor_jni.h ('k') | webrtc/base/network.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 if (enum_name == "CONNECTION_BLUETOOTH") { 64 if (enum_name == "CONNECTION_BLUETOOTH") {
65 return NetworkType::NETWORK_BLUETOOTH; 65 return NetworkType::NETWORK_BLUETOOTH;
66 } 66 }
67 if (enum_name == "CONNECTION_NONE") { 67 if (enum_name == "CONNECTION_NONE") {
68 return NetworkType::NETWORK_NONE; 68 return NetworkType::NETWORK_NONE;
69 } 69 }
70 ASSERT(false); 70 ASSERT(false);
71 return NetworkType::NETWORK_UNKNOWN; 71 return NetworkType::NETWORK_UNKNOWN;
72 } 72 }
73 73
74 static rtc::AdapterType AdapterTypeFromNetworkType(NetworkType network_type) {
75 switch (network_type) {
76 case NETWORK_UNKNOWN:
77 RTC_DCHECK(false) << "Unknown network type ";
78 return rtc::ADAPTER_TYPE_UNKNOWN;
79 case NETWORK_ETHERNET:
80 return rtc::ADAPTER_TYPE_ETHERNET;
81 case NETWORK_WIFI:
82 return rtc::ADAPTER_TYPE_WIFI;
83 case NETWORK_4G:
84 case NETWORK_3G:
85 case NETWORK_2G:
86 return rtc::ADAPTER_TYPE_CELLULAR;
87 case NETWORK_BLUETOOTH:
88 // There is no corresponding mapping for bluetooth networks.
89 // Map it to VPN for now.
90 return rtc::ADAPTER_TYPE_VPN;
91 default:
92 RTC_DCHECK(false) << "Invalid network type " << network_type;
93 return rtc::ADAPTER_TYPE_UNKNOWN;
94 }
95 }
96
74 static rtc::IPAddress GetIPAddressFromJava(JNIEnv* jni, jobject j_ip_address) { 97 static rtc::IPAddress GetIPAddressFromJava(JNIEnv* jni, jobject j_ip_address) {
75 jclass j_ip_address_class = GetObjectClass(jni, j_ip_address); 98 jclass j_ip_address_class = GetObjectClass(jni, j_ip_address);
76 jfieldID j_address_id = GetFieldID(jni, j_ip_address_class, "address", "[B"); 99 jfieldID j_address_id = GetFieldID(jni, j_ip_address_class, "address", "[B");
77 jbyteArray j_addresses = 100 jbyteArray j_addresses =
78 static_cast<jbyteArray>(GetObjectField(jni, j_ip_address, j_address_id)); 101 static_cast<jbyteArray>(GetObjectField(jni, j_ip_address, j_address_id));
79 size_t address_length = jni->GetArrayLength(j_addresses); 102 size_t address_length = jni->GetArrayLength(j_addresses);
80 jbyte* addr_array = jni->GetByteArrayElements(j_addresses, nullptr); 103 jbyte* addr_array = jni->GetByteArrayElements(j_addresses, nullptr);
81 CHECK_EXCEPTION(jni) << "Error during GetIPAddressFromJava"; 104 CHECK_EXCEPTION(jni) << "Error during GetIPAddressFromJava";
82 if (address_length == 4) { 105 if (address_length == 4) {
83 // IP4 106 // IP4
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 started_ = true; 202 started_ = true;
180 203
181 // This is kind of magic behavior, but doing this allows the SocketServer to 204 // This is kind of magic behavior, but doing this allows the SocketServer to
182 // use this as a NetworkBinder to bind sockets on a particular network when 205 // use this as a NetworkBinder to bind sockets on a particular network when
183 // it creates sockets. 206 // it creates sockets.
184 worker_thread()->socketserver()->set_network_binder(this); 207 worker_thread()->socketserver()->set_network_binder(this);
185 208
186 jmethodID m = 209 jmethodID m =
187 GetMethodID(jni(), *j_network_monitor_class_, "startMonitoring", "(J)V"); 210 GetMethodID(jni(), *j_network_monitor_class_, "startMonitoring", "(J)V");
188 jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this)); 211 jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this));
189 CHECK_EXCEPTION(jni()) << "Error during NetworkMonitor.startMonitoring"; 212 CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod";
190 } 213 }
191 214
192 void AndroidNetworkMonitor::Stop() { 215 void AndroidNetworkMonitor::Stop() {
193 RTC_CHECK(thread_checker_.CalledOnValidThread()); 216 RTC_CHECK(thread_checker_.CalledOnValidThread());
194 if (!started_) { 217 if (!started_) {
195 return; 218 return;
196 } 219 }
197 started_ = false; 220 started_ = false;
198 221
199 // Once the network monitor stops, it will clear all network information and 222 // Once the network monitor stops, it will clear all network information and
200 // it won't find the network handle to bind anyway. 223 // it won't find the network handle to bind anyway.
201 if (worker_thread()->socketserver()->network_binder() == this) { 224 if (worker_thread()->socketserver()->network_binder() == this) {
202 worker_thread()->socketserver()->set_network_binder(nullptr); 225 worker_thread()->socketserver()->set_network_binder(nullptr);
203 } 226 }
204 227
205 jmethodID m = 228 jmethodID m =
206 GetMethodID(jni(), *j_network_monitor_class_, "stopMonitoring", "(J)V"); 229 GetMethodID(jni(), *j_network_monitor_class_, "stopMonitoring", "(J)V");
207 jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this)); 230 jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this));
208 CHECK_EXCEPTION(jni()) << "Error during NetworkMonitor.stopMonitoring"; 231 CHECK_EXCEPTION(jni()) << "Error during NetworkMonitor.stopMonitoring";
209 232
210 network_info_by_address_.clear(); 233 network_handle_by_address_.clear();
234 network_info_by_handle_.clear();
211 } 235 }
212 236
213 int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd, 237 int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
214 const rtc::IPAddress& address) { 238 const rtc::IPAddress& address) {
215 RTC_CHECK(thread_checker_.CalledOnValidThread()); 239 RTC_CHECK(thread_checker_.CalledOnValidThread());
216 auto it = network_info_by_address_.find(address); 240 // Android prior to Lollipop didn't have support for binding sockets to
217 if (it == network_info_by_address_.end()) { 241 // networks. However, in that case it should not have reached here because
242 // |network_handle_by_address_| should only be populated in Android Lollipop
243 // and above.
244 // TODO(honghaiz): Add a check for Android version here so that it won't try
245 // to look for handle if the Android version is before Lollipop.
246 auto iter = network_handle_by_address_.find(address);
247 if (iter == network_handle_by_address_.end()) {
218 return rtc::NETWORK_BIND_ADDRESS_NOT_FOUND; 248 return rtc::NETWORK_BIND_ADDRESS_NOT_FOUND;
219 } 249 }
220 // Android prior to Lollipop didn't have support for binding sockets to 250 NetworkHandle network_handle = iter->second;
221 // networks. However, in that case it should not have reached here because
222 // |network_info_by_address_| should only be populated in Android Lollipop
223 // and above.
224 NetworkInformation network = it->second;
225 251
226 // NOTE: This does rely on Android implementation details, but 252 // NOTE: This does rely on Android implementation details, but
227 // these details are unlikely to change. 253 // these details are unlikely to change.
228 typedef int (*SetNetworkForSocket)(unsigned netId, int socketFd); 254 typedef int (*SetNetworkForSocket)(unsigned netId, int socketFd);
229 static SetNetworkForSocket setNetworkForSocket; 255 static SetNetworkForSocket setNetworkForSocket;
230 // This is not threadsafe, but we are running this only on the worker thread. 256 // This is not threadsafe, but we are running this only on the worker thread.
231 if (setNetworkForSocket == nullptr) { 257 if (setNetworkForSocket == nullptr) {
232 // Android's netd client library should always be loaded in our address 258 // Android's netd client library should always be loaded in our address
233 // space as it shims libc functions like connect(). 259 // space as it shims libc functions like connect().
234 const std::string net_library_path = "libnetd_client.so"; 260 const std::string net_library_path = "libnetd_client.so";
235 void* lib = dlopen(net_library_path.c_str(), RTLD_LAZY); 261 void* lib = dlopen(net_library_path.c_str(), RTLD_LAZY);
236 if (lib == nullptr) { 262 if (lib == nullptr) {
237 LOG(LS_ERROR) << "Library " << net_library_path << " not found!"; 263 LOG(LS_ERROR) << "Library " << net_library_path << " not found!";
238 return rtc::NETWORK_BIND_NOT_IMPLEMENTED; 264 return rtc::NETWORK_BIND_NOT_IMPLEMENTED;
239 } 265 }
240 setNetworkForSocket = reinterpret_cast<SetNetworkForSocket>( 266 setNetworkForSocket = reinterpret_cast<SetNetworkForSocket>(
241 dlsym(lib, "setNetworkForSocket")); 267 dlsym(lib, "setNetworkForSocket"));
242 } 268 }
243 if (setNetworkForSocket == nullptr) { 269 if (setNetworkForSocket == nullptr) {
244 LOG(LS_ERROR) << "Symbol setNetworkForSocket not found "; 270 LOG(LS_ERROR) << "Symbol setNetworkForSocket not found ";
245 return rtc::NETWORK_BIND_NOT_IMPLEMENTED; 271 return rtc::NETWORK_BIND_NOT_IMPLEMENTED;
246 } 272 }
247 int rv = setNetworkForSocket(network.handle, socket_fd); 273 int rv = setNetworkForSocket(network_handle, socket_fd);
248 // If |network| has since disconnected, |rv| will be ENONET. Surface this as 274 // If |network| has since disconnected, |rv| will be ENONET. Surface this as
249 // ERR_NETWORK_CHANGED, rather than MapSystemError(ENONET) which gives back 275 // ERR_NETWORK_CHANGED, rather than MapSystemError(ENONET) which gives back
250 // the less descriptive ERR_FAILED. 276 // the less descriptive ERR_FAILED.
251 if (rv == 0) { 277 if (rv == 0) {
252 return rtc::NETWORK_BIND_SUCCESS; 278 return rtc::NETWORK_BIND_SUCCESS;
253 } 279 }
254 if (rv == ENONET) { 280 if (rv == ENONET) {
255 return rtc::NETWORK_BIND_NETWORK_CHANGED; 281 return rtc::NETWORK_BIND_NETWORK_CHANGED;
256 } 282 }
257 return rtc::NETWORK_BIND_FAILURE; 283 return rtc::NETWORK_BIND_FAILURE;
258 } 284 }
259 285
260 void AndroidNetworkMonitor::OnNetworkAvailable( 286 void AndroidNetworkMonitor::OnNetworkConnected(
261 const NetworkInformation& network_info) { 287 const NetworkInformation& network_info) {
288 LOG(LS_INFO) << "Network connected: " << network_info.ToString();
262 worker_thread()->Invoke<void>(rtc::Bind( 289 worker_thread()->Invoke<void>(rtc::Bind(
263 &AndroidNetworkMonitor::OnNetworkAvailable_w, this, network_info)); 290 &AndroidNetworkMonitor::OnNetworkConnected_w, this, network_info));
264 } 291 }
265 292
266 void AndroidNetworkMonitor::OnNetworkAvailable_w( 293 void AndroidNetworkMonitor::OnNetworkConnected_w(
267 const NetworkInformation& network_info) { 294 const NetworkInformation& network_info) {
268 LOG(LS_INFO) << "Network available: " << network_info.ToString(); 295 adapter_type_by_name_[network_info.interface_name] =
269 for (rtc::IPAddress address : network_info.ip_addresses) { 296 AdapterTypeFromNetworkType(network_info.type);
270 network_info_by_address_[address] = network_info; 297 network_info_by_handle_[network_info.handle] = network_info;
298 for (const rtc::IPAddress& address : network_info.ip_addresses) {
299 network_handle_by_address_[address] = network_info.handle;
271 } 300 }
272 } 301 }
273 302
303 void AndroidNetworkMonitor::OnNetworkDisconnected(NetworkHandle handle) {
304 LOG(LS_INFO) << "Network disconnected for handle " << handle;
305 worker_thread()->Invoke<void>(
306 rtc::Bind(&AndroidNetworkMonitor::OnNetworkDisconnected_w, this, handle));
307 }
308
309 void AndroidNetworkMonitor::OnNetworkDisconnected_w(NetworkHandle handle) {
310 auto iter = network_info_by_handle_.find(handle);
311 if (iter != network_info_by_handle_.end()) {
312 for (const rtc::IPAddress& address : iter->second.ip_addresses) {
313 network_handle_by_address_.erase(address);
314 }
315 network_info_by_handle_.erase(iter);
316 }
317 }
318
319 void AndroidNetworkMonitor::SetNetworkInfos(
320 const std::vector<NetworkInformation>& network_infos) {
321 RTC_CHECK(thread_checker_.CalledOnValidThread());
322 network_handle_by_address_.clear();
323 network_info_by_handle_.clear();
324 for (NetworkInformation network : network_infos) {
325 OnNetworkConnected_w(network);
326 }
327 }
328
329 rtc::AdapterType AndroidNetworkMonitor::GetAdapterType(
330 const std::string& if_name) {
331 auto iter = adapter_type_by_name_.find(if_name);
332 if (iter == adapter_type_by_name_.end()) {
333 return rtc::ADAPTER_TYPE_UNKNOWN;
334 }
335 return iter->second;
336 }
337
274 rtc::NetworkMonitorInterface* 338 rtc::NetworkMonitorInterface*
275 AndroidNetworkMonitorFactory::CreateNetworkMonitor() { 339 AndroidNetworkMonitorFactory::CreateNetworkMonitor() {
276 return new AndroidNetworkMonitor(); 340 return new AndroidNetworkMonitor();
277 } 341 }
278 342
279 JOW(void, NetworkMonitor_nativeNotifyConnectionTypeChanged)( 343 JOW(void, NetworkMonitor_nativeNotifyConnectionTypeChanged)(
280 JNIEnv* jni, jobject j_monitor, jlong j_native_monitor) { 344 JNIEnv* jni, jobject j_monitor, jlong j_native_monitor) {
281 rtc::NetworkMonitorInterface* network_monitor = 345 rtc::NetworkMonitorInterface* network_monitor =
282 reinterpret_cast<rtc::NetworkMonitorInterface*>(j_native_monitor); 346 reinterpret_cast<rtc::NetworkMonitorInterface*>(j_native_monitor);
283 network_monitor->OnNetworksChanged(); 347 network_monitor->OnNetworksChanged();
284 } 348 }
285 349
350 JOW(void, NetworkMonitor_nativeNotifyOfActiveNetworkList)(
351 JNIEnv* jni, jobject j_monitor, jlong j_native_monitor,
352 jobjectArray j_network_infos) {
353 AndroidNetworkMonitor* network_monitor =
354 reinterpret_cast<AndroidNetworkMonitor*>(j_native_monitor);
355 std::vector<NetworkInformation> network_infos;
356 size_t num_networks = jni->GetArrayLength(j_network_infos);
357 for (size_t i = 0; i < num_networks; ++i) {
358 jobject j_network_info = jni->GetObjectArrayElement(j_network_infos, i);
359 CHECK_EXCEPTION(jni) << "Error during GetObjectArrayElement";
360 network_infos.push_back(GetNetworkInformationFromJava(jni, j_network_info));
361 }
362 network_monitor->SetNetworkInfos(network_infos);
363 }
364
286 JOW(void, NetworkMonitor_nativeNotifyOfNetworkConnect)( 365 JOW(void, NetworkMonitor_nativeNotifyOfNetworkConnect)(
287 JNIEnv* jni, jobject j_monitor, jlong j_native_monitor, 366 JNIEnv* jni, jobject j_monitor, jlong j_native_monitor,
288 jobject j_network_info) { 367 jobject j_network_info) {
289 AndroidNetworkMonitor* network_monitor = 368 AndroidNetworkMonitor* network_monitor =
290 reinterpret_cast<AndroidNetworkMonitor*>(j_native_monitor); 369 reinterpret_cast<AndroidNetworkMonitor*>(j_native_monitor);
291 NetworkInformation network_info = 370 NetworkInformation network_info =
292 GetNetworkInformationFromJava(jni, j_network_info); 371 GetNetworkInformationFromJava(jni, j_network_info);
293 network_monitor->OnNetworkAvailable(network_info); 372 network_monitor->OnNetworkConnected(network_info);
373 }
374
375 JOW(void, NetworkMonitor_nativeNotifyOfNetworkDisconnect)(
376 JNIEnv* jni, jobject j_monitor, jlong j_native_monitor,
377 jint network_handle) {
378 AndroidNetworkMonitor* network_monitor =
379 reinterpret_cast<AndroidNetworkMonitor*>(j_native_monitor);
380 network_monitor->OnNetworkDisconnected(
381 static_cast<NetworkHandle>(network_handle));
294 } 382 }
295 383
296 } // namespace webrtc_jni 384 } // namespace webrtc_jni
OLDNEW
« no previous file with comments | « talk/app/webrtc/java/jni/androidnetworkmonitor_jni.h ('k') | webrtc/base/network.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698