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

Side by Side Diff: webrtc/sdk/android/src/jni/androidnetworkmonitor_jni.cc

Issue 2646863005: Fixing logic for using android_setsocknetwork() with bind(). (Closed)
Patch Set: comment formatting Created 3 years, 11 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
OLDNEW
1 /* 1 /*
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 GetMethodID(jni(), *j_network_monitor_class_, "stopMonitoring", "(J)V"); 230 GetMethodID(jni(), *j_network_monitor_class_, "stopMonitoring", "(J)V");
231 jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this)); 231 jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this));
232 CHECK_EXCEPTION(jni()) << "Error during NetworkMonitor.stopMonitoring"; 232 CHECK_EXCEPTION(jni()) << "Error during NetworkMonitor.stopMonitoring";
233 233
234 network_handle_by_address_.clear(); 234 network_handle_by_address_.clear();
235 network_info_by_handle_.clear(); 235 network_info_by_handle_.clear();
236 } 236 }
237 237
238 // The implementation is largely taken from UDPSocketPosix::BindToNetwork in 238 // The implementation is largely taken from UDPSocketPosix::BindToNetwork in
239 // https://cs.chromium.org/chromium/src/net/udp/udp_socket_posix.cc 239 // https://cs.chromium.org/chromium/src/net/udp/udp_socket_posix.cc
240 int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd, 240 rtc::NetworkBindingResult AndroidNetworkMonitor::BindSocketToNetwork(
241 const rtc::IPAddress& address) { 241 int socket_fd,
242 const rtc::IPAddress& address) {
242 RTC_CHECK(thread_checker_.CalledOnValidThread()); 243 RTC_CHECK(thread_checker_.CalledOnValidThread());
243 // Android prior to Lollipop didn't have support for binding sockets to 244 // Android prior to Lollipop didn't have support for binding sockets to
244 // networks. In that case it should not have reached here because 245 // networks. In that case it should not have reached here because
245 // |network_handle_by_address_| is only populated in Android Lollipop 246 // |network_handle_by_address_| is only populated in Android Lollipop
246 // and above. 247 // and above.
247 if (android_sdk_int_ < SDK_VERSION_LOLLIPOP) { 248 if (android_sdk_int_ < SDK_VERSION_LOLLIPOP) {
248 LOG(LS_ERROR) << "BindSocketToNetwork is not supported in Android SDK " 249 LOG(LS_ERROR) << "BindSocketToNetwork is not supported in Android SDK "
249 << android_sdk_int_; 250 << android_sdk_int_;
250 return rtc::NETWORK_BIND_NOT_IMPLEMENTED; 251 return rtc::NetworkBindingResult::NOT_IMPLEMENTED;
251 } 252 }
252 253
253 auto iter = network_handle_by_address_.find(address); 254 auto iter = network_handle_by_address_.find(address);
254 if (iter == network_handle_by_address_.end()) { 255 if (iter == network_handle_by_address_.end()) {
255 return rtc::NETWORK_BIND_ADDRESS_NOT_FOUND; 256 return rtc::NetworkBindingResult::ADDRESS_NOT_FOUND;
256 } 257 }
257 NetworkHandle network_handle = iter->second; 258 NetworkHandle network_handle = iter->second;
258 259
259 int rv = 0; 260 int rv = 0;
260 if (android_sdk_int_ >= SDK_VERSION_MARSHMALLOW) { 261 if (android_sdk_int_ >= SDK_VERSION_MARSHMALLOW) {
261 // See declaration of android_setsocknetwork() here: 262 // See declaration of android_setsocknetwork() here:
262 // http://androidxref.com/6.0.0_r1/xref/development/ndk/platforms/android-M/ include/android/multinetwork.h#65 263 // http://androidxref.com/6.0.0_r1/xref/development/ndk/platforms/android-M/ include/android/multinetwork.h#65
263 // Function cannot be called directly as it will cause app to fail to load 264 // Function cannot be called directly as it will cause app to fail to load
264 // on pre-marshmallow devices. 265 // on pre-marshmallow devices.
265 typedef int (*MarshmallowSetNetworkForSocket)(NetworkHandle net, 266 typedef int (*MarshmallowSetNetworkForSocket)(NetworkHandle net,
266 int socket); 267 int socket);
267 static MarshmallowSetNetworkForSocket marshmallowSetNetworkForSocket; 268 static MarshmallowSetNetworkForSocket marshmallowSetNetworkForSocket;
268 // This is not thread-safe, but we are running this only on the worker 269 // This is not thread-safe, but we are running this only on the worker
269 // thread. 270 // thread.
270 if (!marshmallowSetNetworkForSocket) { 271 if (!marshmallowSetNetworkForSocket) {
271 const std::string android_native_lib_path = "libandroid.so"; 272 const std::string android_native_lib_path = "libandroid.so";
272 void* lib = dlopen(android_native_lib_path.c_str(), RTLD_NOW); 273 void* lib = dlopen(android_native_lib_path.c_str(), RTLD_NOW);
273 if (lib == nullptr) { 274 if (lib == nullptr) {
274 LOG(LS_ERROR) << "Library " << android_native_lib_path << " not found!"; 275 LOG(LS_ERROR) << "Library " << android_native_lib_path << " not found!";
275 return rtc::NETWORK_BIND_NOT_IMPLEMENTED; 276 return rtc::NetworkBindingResult::NOT_IMPLEMENTED;
276 } 277 }
277 marshmallowSetNetworkForSocket = 278 marshmallowSetNetworkForSocket =
278 reinterpret_cast<MarshmallowSetNetworkForSocket>( 279 reinterpret_cast<MarshmallowSetNetworkForSocket>(
279 dlsym(lib, "android_setsocknetwork")); 280 dlsym(lib, "android_setsocknetwork"));
280 } 281 }
281 if (!marshmallowSetNetworkForSocket) { 282 if (!marshmallowSetNetworkForSocket) {
282 LOG(LS_ERROR) << "Symbol marshmallowSetNetworkForSocket is not found"; 283 LOG(LS_ERROR) << "Symbol marshmallowSetNetworkForSocket is not found";
283 return rtc::NETWORK_BIND_NOT_IMPLEMENTED; 284 return rtc::NetworkBindingResult::NOT_IMPLEMENTED;
284 } 285 }
285 rv = marshmallowSetNetworkForSocket(network_handle, socket_fd); 286 rv = marshmallowSetNetworkForSocket(network_handle, socket_fd);
286 } else { 287 } else {
287 // NOTE: This relies on Android implementation details, but it won't change 288 // NOTE: This relies on Android implementation details, but it won't change
288 // because Lollipop is already released. 289 // because Lollipop is already released.
289 typedef int (*LollipopSetNetworkForSocket)(unsigned net, int socket); 290 typedef int (*LollipopSetNetworkForSocket)(unsigned net, int socket);
290 static LollipopSetNetworkForSocket lollipopSetNetworkForSocket; 291 static LollipopSetNetworkForSocket lollipopSetNetworkForSocket;
291 // This is not threadsafe, but we are running this only on the worker 292 // This is not threadsafe, but we are running this only on the worker
292 // thread. 293 // thread.
293 if (!lollipopSetNetworkForSocket) { 294 if (!lollipopSetNetworkForSocket) {
294 // Android's netd client library should always be loaded in our address 295 // Android's netd client library should always be loaded in our address
295 // space as it shims libc functions like connect(). 296 // space as it shims libc functions like connect().
296 const std::string net_library_path = "libnetd_client.so"; 297 const std::string net_library_path = "libnetd_client.so";
297 // Use RTLD_NOW to match Android's prior loading of the library: 298 // Use RTLD_NOW to match Android's prior loading of the library:
298 // http://androidxref.com/6.0.0_r5/xref/bionic/libc/bionic/NetdClient.cpp# 37 299 // http://androidxref.com/6.0.0_r5/xref/bionic/libc/bionic/NetdClient.cpp# 37
299 // Use RTLD_NOLOAD to assert that the library is already loaded and 300 // Use RTLD_NOLOAD to assert that the library is already loaded and
300 // avoid doing any disk IO. 301 // avoid doing any disk IO.
301 void* lib = dlopen(net_library_path.c_str(), RTLD_NOW | RTLD_NOLOAD); 302 void* lib = dlopen(net_library_path.c_str(), RTLD_NOW | RTLD_NOLOAD);
302 if (lib == nullptr) { 303 if (lib == nullptr) {
303 LOG(LS_ERROR) << "Library " << net_library_path << " not found!"; 304 LOG(LS_ERROR) << "Library " << net_library_path << " not found!";
304 return rtc::NETWORK_BIND_NOT_IMPLEMENTED; 305 return rtc::NetworkBindingResult::NOT_IMPLEMENTED;
305 } 306 }
306 lollipopSetNetworkForSocket = 307 lollipopSetNetworkForSocket =
307 reinterpret_cast<LollipopSetNetworkForSocket>( 308 reinterpret_cast<LollipopSetNetworkForSocket>(
308 dlsym(lib, "setNetworkForSocket")); 309 dlsym(lib, "setNetworkForSocket"));
309 } 310 }
310 if (!lollipopSetNetworkForSocket) { 311 if (!lollipopSetNetworkForSocket) {
311 LOG(LS_ERROR) << "Symbol lollipopSetNetworkForSocket is not found "; 312 LOG(LS_ERROR) << "Symbol lollipopSetNetworkForSocket is not found ";
312 return rtc::NETWORK_BIND_NOT_IMPLEMENTED; 313 return rtc::NetworkBindingResult::NOT_IMPLEMENTED;
313 } 314 }
314 rv = lollipopSetNetworkForSocket(network_handle, socket_fd); 315 rv = lollipopSetNetworkForSocket(network_handle, socket_fd);
315 } 316 }
316 317
317 // If |network| has since disconnected, |rv| will be ENONET. Surface this as 318 // If |network| has since disconnected, |rv| will be ENONET. Surface this as
318 // ERR_NETWORK_CHANGED, rather than MapSystemError(ENONET) which gives back 319 // ERR_NETWORK_CHANGED, rather than MapSystemError(ENONET) which gives back
319 // the less descriptive ERR_FAILED. 320 // the less descriptive ERR_FAILED.
320 if (rv == 0) { 321 if (rv == 0) {
321 return rtc::NETWORK_BIND_SUCCESS; 322 return rtc::NetworkBindingResult::SUCCESS;
322 } 323 }
323 if (rv == ENONET) { 324 if (rv == ENONET) {
324 return rtc::NETWORK_BIND_NETWORK_CHANGED; 325 return rtc::NetworkBindingResult::NETWORK_CHANGED;
325 } 326 }
326 return rtc::NETWORK_BIND_FAILURE; 327 return rtc::NetworkBindingResult::FAILURE;
327 } 328 }
328 329
329 void AndroidNetworkMonitor::OnNetworkConnected( 330 void AndroidNetworkMonitor::OnNetworkConnected(
330 const NetworkInformation& network_info) { 331 const NetworkInformation& network_info) {
331 worker_thread()->Invoke<void>( 332 worker_thread()->Invoke<void>(
332 RTC_FROM_HERE, rtc::Bind(&AndroidNetworkMonitor::OnNetworkConnected_w, 333 RTC_FROM_HERE, rtc::Bind(&AndroidNetworkMonitor::OnNetworkConnected_w,
333 this, network_info)); 334 this, network_info));
334 // Fire SignalNetworksChanged to update the list of networks. 335 // Fire SignalNetworksChanged to update the list of networks.
335 OnNetworksChanged(); 336 OnNetworksChanged();
336 } 337 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 JOW(void, NetworkMonitor_nativeNotifyOfNetworkDisconnect)( 428 JOW(void, NetworkMonitor_nativeNotifyOfNetworkDisconnect)(
428 JNIEnv* jni, jobject j_monitor, jlong j_native_monitor, 429 JNIEnv* jni, jobject j_monitor, jlong j_native_monitor,
429 jlong network_handle) { 430 jlong network_handle) {
430 AndroidNetworkMonitor* network_monitor = 431 AndroidNetworkMonitor* network_monitor =
431 reinterpret_cast<AndroidNetworkMonitor*>(j_native_monitor); 432 reinterpret_cast<AndroidNetworkMonitor*>(j_native_monitor);
432 network_monitor->OnNetworkDisconnected( 433 network_monitor->OnNetworkDisconnected(
433 static_cast<NetworkHandle>(network_handle)); 434 static_cast<NetworkHandle>(network_handle));
434 } 435 }
435 436
436 } // namespace webrtc_jni 437 } // namespace webrtc_jni
OLDNEW
« webrtc/base/physicalsocketserver.cc ('K') | « webrtc/sdk/android/src/jni/androidnetworkmonitor_jni.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698