Index: net/android/network_change_notifier_delegate_android.cc |
diff --git a/net/android/network_change_notifier_delegate_android.cc b/net/android/network_change_notifier_delegate_android.cc |
index 91b0cb0465e65c7a7513b5a2fc80a1aa090231b8..6e781414fe822426300a0d37d2aed015ec63cb78 100644 |
--- a/net/android/network_change_notifier_delegate_android.cc |
+++ b/net/android/network_change_notifier_delegate_android.cc |
@@ -4,7 +4,11 @@ |
#include "net/android/network_change_notifier_delegate_android.h" |
+#include "base/bind.h" |
+#include "base/compiler_specific.h" |
#include "base/logging.h" |
+#include "base/message_loop_proxy.h" |
+#include "base/single_thread_task_runner.h" |
#include "jni/NetworkChangeNotifier_jni.h" |
namespace net { |
@@ -31,19 +35,25 @@ bool CheckConnectionType(int connection_type) { |
} // namespace |
NetworkChangeNotifierDelegateAndroid::NetworkChangeNotifierDelegateAndroid() |
- : observers_(new ObserverListThreadSafe<Observer>()) { |
+ : jni_task_runner_(base::MessageLoopProxy::current()), |
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), |
+ weak_ptr_(weak_ptr_factory_.GetWeakPtr()), |
+ observers_(new ObserverListThreadSafe<Observer>()), |
+ connection_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN) { |
+ JNIEnv* env = base::android::AttachCurrentThread(); |
java_network_change_notifier_.Reset( |
- Java_NetworkChangeNotifier_createInstance( |
- base::android::AttachCurrentThread(), |
- base::android::GetApplicationContext(), |
- reinterpret_cast<jint>(this))); |
+ Java_NetworkChangeNotifier_init( |
+ env, base::android::GetApplicationContext())); |
+ Java_NetworkChangeNotifier_addNativeObserver( |
+ env, java_network_change_notifier_.obj(), reinterpret_cast<jint>(this)); |
} |
NetworkChangeNotifierDelegateAndroid::~NetworkChangeNotifierDelegateAndroid() { |
DCHECK(thread_checker_.CalledOnValidThread()); |
observers_->AssertEmpty(); |
JNIEnv* env = base::android::AttachCurrentThread(); |
- Java_NetworkChangeNotifier_destroyInstance(env); |
+ Java_NetworkChangeNotifier_removeNativeObserver( |
+ env, java_network_change_notifier_.obj(), reinterpret_cast<jint>(this)); |
} |
void NetworkChangeNotifierDelegateAndroid::NotifyConnectionTypeChanged( |
@@ -66,6 +76,7 @@ jint NetworkChangeNotifierDelegateAndroid::GetConnectionType(JNIEnv*, |
void NetworkChangeNotifierDelegateAndroid::AddObserver( |
Observer* observer) { |
observers_->AddObserver(observer); |
+ SendInitialNotification(); |
} |
void NetworkChangeNotifierDelegateAndroid::RemoveObserver( |
@@ -85,4 +96,27 @@ bool NetworkChangeNotifierDelegateAndroid::Register(JNIEnv* env) { |
return RegisterNativesImpl(env); |
} |
+void NetworkChangeNotifierDelegateAndroid::SendInitialNotification() { |
+ // This function must be executed on the JNI thread since it reads |
+ // |connection_type_| which is written on the JNI thread (with no lock). |
+ if (!jni_task_runner_->BelongsToCurrentThread()) { |
+ // Note that copying a weak pointer (which is constructed on the JNI thread |
+ // in this case) is thread-safe. |
+ jni_task_runner_->PostTask( |
+ FROM_HERE, |
+ base::Bind( |
+ &NetworkChangeNotifierDelegateAndroid::SendInitialNotification, |
+ weak_ptr_)); |
+ return; |
+ } |
+ // Ideally only the newly added observer should be notified to receive the |
+ // current connection type. ObserverListThreadSafe doesn't support this |
+ // functionality unfortunately. Note that the observers (a small number of |
+ // NetworkChangeNotifierAndroid instances) will forward the notification only |
+ // if the provided connection type is different from the previous one. This |
+ // means that notifying all observers has no impact from the client |
+ // perspective. |
+ observers_->Notify(&Observer::OnConnectionTypeChanged, connection_type_); |
+} |
+ |
} // namespace net |