| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |