| 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
|
|
|