| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/android/network_change_notifier_delegate_android.h" | 5 #include "net/android/network_change_notifier_delegate_android.h" |
| 6 | 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/compiler_specific.h" |
| 7 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop_proxy.h" |
| 11 #include "base/single_thread_task_runner.h" |
| 8 #include "jni/NetworkChangeNotifier_jni.h" | 12 #include "jni/NetworkChangeNotifier_jni.h" |
| 9 | 13 |
| 10 namespace net { | 14 namespace net { |
| 11 | 15 |
| 12 namespace { | 16 namespace { |
| 13 | 17 |
| 14 // Returns whether the provided connection type is known. | 18 // Returns whether the provided connection type is known. |
| 15 bool CheckConnectionType(int connection_type) { | 19 bool CheckConnectionType(int connection_type) { |
| 16 switch (connection_type) { | 20 switch (connection_type) { |
| 17 case NetworkChangeNotifier::CONNECTION_UNKNOWN: | 21 case NetworkChangeNotifier::CONNECTION_UNKNOWN: |
| 18 case NetworkChangeNotifier::CONNECTION_ETHERNET: | 22 case NetworkChangeNotifier::CONNECTION_ETHERNET: |
| 19 case NetworkChangeNotifier::CONNECTION_WIFI: | 23 case NetworkChangeNotifier::CONNECTION_WIFI: |
| 20 case NetworkChangeNotifier::CONNECTION_2G: | 24 case NetworkChangeNotifier::CONNECTION_2G: |
| 21 case NetworkChangeNotifier::CONNECTION_3G: | 25 case NetworkChangeNotifier::CONNECTION_3G: |
| 22 case NetworkChangeNotifier::CONNECTION_4G: | 26 case NetworkChangeNotifier::CONNECTION_4G: |
| 23 case NetworkChangeNotifier::CONNECTION_NONE: | 27 case NetworkChangeNotifier::CONNECTION_NONE: |
| 24 return true; | 28 return true; |
| 25 default: | 29 default: |
| 26 NOTREACHED() << "Unknown connection type received: " << connection_type; | 30 NOTREACHED() << "Unknown connection type received: " << connection_type; |
| 27 return false; | 31 return false; |
| 28 } | 32 } |
| 29 } | 33 } |
| 30 | 34 |
| 31 } // namespace | 35 } // namespace |
| 32 | 36 |
| 33 NetworkChangeNotifierDelegateAndroid::NetworkChangeNotifierDelegateAndroid() | 37 NetworkChangeNotifierDelegateAndroid::NetworkChangeNotifierDelegateAndroid() |
| 34 : observers_(new ObserverListThreadSafe<Observer>()) { | 38 : jni_task_runner_(base::MessageLoopProxy::current()), |
| 39 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), |
| 40 weak_ptr_(weak_ptr_factory_.GetWeakPtr()), |
| 41 observers_(new ObserverListThreadSafe<Observer>()), |
| 42 connection_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN) { |
| 43 JNIEnv* env = base::android::AttachCurrentThread(); |
| 35 java_network_change_notifier_.Reset( | 44 java_network_change_notifier_.Reset( |
| 36 Java_NetworkChangeNotifier_createInstance( | 45 Java_NetworkChangeNotifier_init( |
| 37 base::android::AttachCurrentThread(), | 46 env, base::android::GetApplicationContext())); |
| 38 base::android::GetApplicationContext(), | 47 Java_NetworkChangeNotifier_addNativeObserver( |
| 39 reinterpret_cast<jint>(this))); | 48 env, java_network_change_notifier_.obj(), reinterpret_cast<jint>(this)); |
| 40 } | 49 } |
| 41 | 50 |
| 42 NetworkChangeNotifierDelegateAndroid::~NetworkChangeNotifierDelegateAndroid() { | 51 NetworkChangeNotifierDelegateAndroid::~NetworkChangeNotifierDelegateAndroid() { |
| 43 DCHECK(thread_checker_.CalledOnValidThread()); | 52 DCHECK(thread_checker_.CalledOnValidThread()); |
| 44 observers_->AssertEmpty(); | 53 observers_->AssertEmpty(); |
| 45 JNIEnv* env = base::android::AttachCurrentThread(); | 54 JNIEnv* env = base::android::AttachCurrentThread(); |
| 46 Java_NetworkChangeNotifier_destroyInstance(env); | 55 Java_NetworkChangeNotifier_removeNativeObserver( |
| 56 env, java_network_change_notifier_.obj(), reinterpret_cast<jint>(this)); |
| 47 } | 57 } |
| 48 | 58 |
| 49 void NetworkChangeNotifierDelegateAndroid::NotifyConnectionTypeChanged( | 59 void NetworkChangeNotifierDelegateAndroid::NotifyConnectionTypeChanged( |
| 50 JNIEnv* env, | 60 JNIEnv* env, |
| 51 jobject obj, | 61 jobject obj, |
| 52 jint new_connection_type) { | 62 jint new_connection_type) { |
| 53 DCHECK(thread_checker_.CalledOnValidThread()); | 63 DCHECK(thread_checker_.CalledOnValidThread()); |
| 54 connection_type_ = CheckConnectionType(new_connection_type) ? | 64 connection_type_ = CheckConnectionType(new_connection_type) ? |
| 55 static_cast<ConnectionType>(new_connection_type) : | 65 static_cast<ConnectionType>(new_connection_type) : |
| 56 NetworkChangeNotifier::CONNECTION_UNKNOWN; | 66 NetworkChangeNotifier::CONNECTION_UNKNOWN; |
| 57 observers_->Notify(&Observer::OnConnectionTypeChanged, connection_type_); | 67 observers_->Notify(&Observer::OnConnectionTypeChanged, connection_type_); |
| 58 } | 68 } |
| 59 | 69 |
| 60 jint NetworkChangeNotifierDelegateAndroid::GetConnectionType(JNIEnv*, | 70 jint NetworkChangeNotifierDelegateAndroid::GetConnectionType(JNIEnv*, |
| 61 jobject) const { | 71 jobject) const { |
| 62 DCHECK(thread_checker_.CalledOnValidThread()); | 72 DCHECK(thread_checker_.CalledOnValidThread()); |
| 63 return connection_type_; | 73 return connection_type_; |
| 64 } | 74 } |
| 65 | 75 |
| 66 void NetworkChangeNotifierDelegateAndroid::AddObserver( | 76 void NetworkChangeNotifierDelegateAndroid::AddObserver( |
| 67 Observer* observer) { | 77 Observer* observer) { |
| 68 observers_->AddObserver(observer); | 78 observers_->AddObserver(observer); |
| 79 SendInitialNotification(); |
| 69 } | 80 } |
| 70 | 81 |
| 71 void NetworkChangeNotifierDelegateAndroid::RemoveObserver( | 82 void NetworkChangeNotifierDelegateAndroid::RemoveObserver( |
| 72 Observer* observer) { | 83 Observer* observer) { |
| 73 observers_->RemoveObserver(observer); | 84 observers_->RemoveObserver(observer); |
| 74 } | 85 } |
| 75 | 86 |
| 76 void NetworkChangeNotifierDelegateAndroid::ForceConnectivityState( | 87 void NetworkChangeNotifierDelegateAndroid::ForceConnectivityState( |
| 77 ConnectivityState state) { | 88 ConnectivityState state) { |
| 78 DCHECK(thread_checker_.CalledOnValidThread()); | 89 DCHECK(thread_checker_.CalledOnValidThread()); |
| 79 JNIEnv* env = base::android::AttachCurrentThread(); | 90 JNIEnv* env = base::android::AttachCurrentThread(); |
| 80 Java_NetworkChangeNotifier_forceConnectivityState(env, state == ONLINE); | 91 Java_NetworkChangeNotifier_forceConnectivityState(env, state == ONLINE); |
| 81 } | 92 } |
| 82 | 93 |
| 83 // static | 94 // static |
| 84 bool NetworkChangeNotifierDelegateAndroid::Register(JNIEnv* env) { | 95 bool NetworkChangeNotifierDelegateAndroid::Register(JNIEnv* env) { |
| 85 return RegisterNativesImpl(env); | 96 return RegisterNativesImpl(env); |
| 86 } | 97 } |
| 87 | 98 |
| 99 void NetworkChangeNotifierDelegateAndroid::SendInitialNotification() { |
| 100 // This function must be executed on the JNI thread since it reads |
| 101 // |connection_type_| which is written on the JNI thread (with no lock). |
| 102 if (!jni_task_runner_->BelongsToCurrentThread()) { |
| 103 // Note that copying a weak pointer (which is constructed on the JNI thread |
| 104 // in this case) is thread-safe. |
| 105 jni_task_runner_->PostTask( |
| 106 FROM_HERE, |
| 107 base::Bind( |
| 108 &NetworkChangeNotifierDelegateAndroid::SendInitialNotification, |
| 109 weak_ptr_)); |
| 110 return; |
| 111 } |
| 112 // Ideally only the newly added observer should be notified to receive the |
| 113 // current connection type. ObserverListThreadSafe doesn't support this |
| 114 // functionality unfortunately. Note that the observers (a small number of |
| 115 // NetworkChangeNotifierAndroid instances) will forward the notification only |
| 116 // if the provided connection type is different from the previous one. This |
| 117 // means that notifying all observers has no impact from the client |
| 118 // perspective. |
| 119 observers_->Notify(&Observer::OnConnectionTypeChanged, connection_type_); |
| 120 } |
| 121 |
| 88 } // namespace net | 122 } // namespace net |
| OLD | NEW |