| Index: talk/app/webrtc/java/jni/androidnetworkmonitor_jni.cc
|
| diff --git a/talk/app/webrtc/java/jni/androidnetworkmonitor_jni.cc b/talk/app/webrtc/java/jni/androidnetworkmonitor_jni.cc
|
| index 1716c19cf8be84344a3ef1bff3f7bebf8a7d5647..ca0c7821d5ea5f556135affe7566706a0c80ac01 100644
|
| --- a/talk/app/webrtc/java/jni/androidnetworkmonitor_jni.cc
|
| +++ b/talk/app/webrtc/java/jni/androidnetworkmonitor_jni.cc
|
| @@ -71,6 +71,29 @@ static NetworkType GetNetworkTypeFromJava(JNIEnv* jni, jobject j_network_type) {
|
| return NetworkType::NETWORK_UNKNOWN;
|
| }
|
|
|
| +static rtc::AdapterType AdapterTypeFromNetworkType(NetworkType network_type) {
|
| + switch (network_type) {
|
| + case NETWORK_UNKNOWN:
|
| + RTC_DCHECK(false) << "Unknown network type ";
|
| + return rtc::ADAPTER_TYPE_UNKNOWN;
|
| + case NETWORK_ETHERNET:
|
| + return rtc::ADAPTER_TYPE_ETHERNET;
|
| + case NETWORK_WIFI:
|
| + return rtc::ADAPTER_TYPE_WIFI;
|
| + case NETWORK_4G:
|
| + case NETWORK_3G:
|
| + case NETWORK_2G:
|
| + return rtc::ADAPTER_TYPE_CELLULAR;
|
| + case NETWORK_BLUETOOTH:
|
| + // There is no corresponding mapping for bluetooth networks.
|
| + // Map it to VPN for now.
|
| + return rtc::ADAPTER_TYPE_VPN;
|
| + default:
|
| + RTC_DCHECK(false) << "Invalid network type " << network_type;
|
| + return rtc::ADAPTER_TYPE_UNKNOWN;
|
| + }
|
| +}
|
| +
|
| static rtc::IPAddress GetIPAddressFromJava(JNIEnv* jni, jobject j_ip_address) {
|
| jclass j_ip_address_class = GetObjectClass(jni, j_ip_address);
|
| jfieldID j_address_id = GetFieldID(jni, j_ip_address_class, "address", "[B");
|
| @@ -186,7 +209,7 @@ void AndroidNetworkMonitor::Start() {
|
| jmethodID m =
|
| GetMethodID(jni(), *j_network_monitor_class_, "startMonitoring", "(J)V");
|
| jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this));
|
| - CHECK_EXCEPTION(jni()) << "Error during NetworkMonitor.startMonitoring";
|
| + CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod";
|
| }
|
|
|
| void AndroidNetworkMonitor::Stop() {
|
| @@ -207,21 +230,24 @@ void AndroidNetworkMonitor::Stop() {
|
| jni()->CallVoidMethod(*j_network_monitor_, m, jlongFromPointer(this));
|
| CHECK_EXCEPTION(jni()) << "Error during NetworkMonitor.stopMonitoring";
|
|
|
| - network_info_by_address_.clear();
|
| + network_handle_by_address_.clear();
|
| + network_info_by_handle_.clear();
|
| }
|
|
|
| int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
|
| const rtc::IPAddress& address) {
|
| RTC_CHECK(thread_checker_.CalledOnValidThread());
|
| - auto it = network_info_by_address_.find(address);
|
| - if (it == network_info_by_address_.end()) {
|
| - return rtc::NETWORK_BIND_ADDRESS_NOT_FOUND;
|
| - }
|
| // Android prior to Lollipop didn't have support for binding sockets to
|
| // networks. However, in that case it should not have reached here because
|
| - // |network_info_by_address_| should only be populated in Android Lollipop
|
| + // |network_handle_by_address_| should only be populated in Android Lollipop
|
| // and above.
|
| - NetworkInformation network = it->second;
|
| + // TODO(honghaiz): Add a check for Android version here so that it won't try
|
| + // to look for handle if the Android version is before Lollipop.
|
| + auto iter = network_handle_by_address_.find(address);
|
| + if (iter == network_handle_by_address_.end()) {
|
| + return rtc::NETWORK_BIND_ADDRESS_NOT_FOUND;
|
| + }
|
| + NetworkHandle network_handle = iter->second;
|
|
|
| // NOTE: This does rely on Android implementation details, but
|
| // these details are unlikely to change.
|
| @@ -244,7 +270,7 @@ int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
|
| LOG(LS_ERROR) << "Symbol setNetworkForSocket not found ";
|
| return rtc::NETWORK_BIND_NOT_IMPLEMENTED;
|
| }
|
| - int rv = setNetworkForSocket(network.handle, socket_fd);
|
| + int rv = setNetworkForSocket(network_handle, socket_fd);
|
| // If |network| has since disconnected, |rv| will be ENONET. Surface this as
|
| // ERR_NETWORK_CHANGED, rather than MapSystemError(ENONET) which gives back
|
| // the less descriptive ERR_FAILED.
|
| @@ -257,18 +283,56 @@ int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
|
| return rtc::NETWORK_BIND_FAILURE;
|
| }
|
|
|
| -void AndroidNetworkMonitor::OnNetworkAvailable(
|
| +void AndroidNetworkMonitor::OnNetworkConnected(
|
| const NetworkInformation& network_info) {
|
| + LOG(LS_INFO) << "Network connected: " << network_info.ToString();
|
| worker_thread()->Invoke<void>(rtc::Bind(
|
| - &AndroidNetworkMonitor::OnNetworkAvailable_w, this, network_info));
|
| + &AndroidNetworkMonitor::OnNetworkConnected_w, this, network_info));
|
| }
|
|
|
| -void AndroidNetworkMonitor::OnNetworkAvailable_w(
|
| +void AndroidNetworkMonitor::OnNetworkConnected_w(
|
| const NetworkInformation& network_info) {
|
| - LOG(LS_INFO) << "Network available: " << network_info.ToString();
|
| - for (rtc::IPAddress address : network_info.ip_addresses) {
|
| - network_info_by_address_[address] = network_info;
|
| + adapter_type_by_name_[network_info.interface_name] =
|
| + AdapterTypeFromNetworkType(network_info.type);
|
| + network_info_by_handle_[network_info.handle] = network_info;
|
| + for (const rtc::IPAddress& address : network_info.ip_addresses) {
|
| + network_handle_by_address_[address] = network_info.handle;
|
| + }
|
| +}
|
| +
|
| +void AndroidNetworkMonitor::OnNetworkDisconnected(NetworkHandle handle) {
|
| + LOG(LS_INFO) << "Network disconnected for handle " << handle;
|
| + worker_thread()->Invoke<void>(
|
| + rtc::Bind(&AndroidNetworkMonitor::OnNetworkDisconnected_w, this, handle));
|
| +}
|
| +
|
| +void AndroidNetworkMonitor::OnNetworkDisconnected_w(NetworkHandle handle) {
|
| + auto iter = network_info_by_handle_.find(handle);
|
| + if (iter != network_info_by_handle_.end()) {
|
| + for (const rtc::IPAddress& address : iter->second.ip_addresses) {
|
| + network_handle_by_address_.erase(address);
|
| + }
|
| + network_info_by_handle_.erase(iter);
|
| + }
|
| +}
|
| +
|
| +void AndroidNetworkMonitor::SetNetworkInfos(
|
| + const std::vector<NetworkInformation>& network_infos) {
|
| + RTC_CHECK(thread_checker_.CalledOnValidThread());
|
| + network_handle_by_address_.clear();
|
| + network_info_by_handle_.clear();
|
| + for (NetworkInformation network : network_infos) {
|
| + OnNetworkConnected_w(network);
|
| + }
|
| +}
|
| +
|
| +rtc::AdapterType AndroidNetworkMonitor::GetAdapterType(
|
| + const std::string& if_name) {
|
| + auto iter = adapter_type_by_name_.find(if_name);
|
| + if (iter == adapter_type_by_name_.end()) {
|
| + return rtc::ADAPTER_TYPE_UNKNOWN;
|
| }
|
| + return iter->second;
|
| }
|
|
|
| rtc::NetworkMonitorInterface*
|
| @@ -283,6 +347,21 @@ JOW(void, NetworkMonitor_nativeNotifyConnectionTypeChanged)(
|
| network_monitor->OnNetworksChanged();
|
| }
|
|
|
| +JOW(void, NetworkMonitor_nativeNotifyOfActiveNetworkList)(
|
| + JNIEnv* jni, jobject j_monitor, jlong j_native_monitor,
|
| + jobjectArray j_network_infos) {
|
| + AndroidNetworkMonitor* network_monitor =
|
| + reinterpret_cast<AndroidNetworkMonitor*>(j_native_monitor);
|
| + std::vector<NetworkInformation> network_infos;
|
| + size_t num_networks = jni->GetArrayLength(j_network_infos);
|
| + for (size_t i = 0; i < num_networks; ++i) {
|
| + jobject j_network_info = jni->GetObjectArrayElement(j_network_infos, i);
|
| + CHECK_EXCEPTION(jni) << "Error during GetObjectArrayElement";
|
| + network_infos.push_back(GetNetworkInformationFromJava(jni, j_network_info));
|
| + }
|
| + network_monitor->SetNetworkInfos(network_infos);
|
| +}
|
| +
|
| JOW(void, NetworkMonitor_nativeNotifyOfNetworkConnect)(
|
| JNIEnv* jni, jobject j_monitor, jlong j_native_monitor,
|
| jobject j_network_info) {
|
| @@ -290,7 +369,16 @@ JOW(void, NetworkMonitor_nativeNotifyOfNetworkConnect)(
|
| reinterpret_cast<AndroidNetworkMonitor*>(j_native_monitor);
|
| NetworkInformation network_info =
|
| GetNetworkInformationFromJava(jni, j_network_info);
|
| - network_monitor->OnNetworkAvailable(network_info);
|
| + network_monitor->OnNetworkConnected(network_info);
|
| +}
|
| +
|
| +JOW(void, NetworkMonitor_nativeNotifyOfNetworkDisconnect)(
|
| + JNIEnv* jni, jobject j_monitor, jlong j_native_monitor,
|
| + jint network_handle) {
|
| + AndroidNetworkMonitor* network_monitor =
|
| + reinterpret_cast<AndroidNetworkMonitor*>(j_native_monitor);
|
| + network_monitor->OnNetworkDisconnected(
|
| + static_cast<NetworkHandle>(network_handle));
|
| }
|
|
|
| } // namespace webrtc_jni
|
|
|