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

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