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
3// found in the LICENSE file.
4
5#include "net/android/network_change_notifier_delegate_android.h"
6
7#include "base/logging.h"
8#include "jni/NetworkChangeNotifier_jni.h"
9
10namespace net {
11
12namespace {
13
14// Converts a Java side connection type (integer) to
15// the native side NetworkChangeNotifier::ConnectionType.
16NetworkChangeNotifier::ConnectionType ConvertConnectionType(
17    jint connection_type) {
18  switch (connection_type) {
19    case NetworkChangeNotifier::CONNECTION_UNKNOWN:
20    case NetworkChangeNotifier::CONNECTION_ETHERNET:
21    case NetworkChangeNotifier::CONNECTION_WIFI:
22    case NetworkChangeNotifier::CONNECTION_2G:
23    case NetworkChangeNotifier::CONNECTION_3G:
24    case NetworkChangeNotifier::CONNECTION_4G:
25    case NetworkChangeNotifier::CONNECTION_NONE:
26    case NetworkChangeNotifier::CONNECTION_BLUETOOTH:
27      break;
28    default:
29      NOTREACHED() << "Unknown connection type received: " << connection_type;
30      return NetworkChangeNotifier::CONNECTION_UNKNOWN;
31  }
32  return static_cast<NetworkChangeNotifier::ConnectionType>(connection_type);
33}
34
35}  // namespace
36
37NetworkChangeNotifierDelegateAndroid::NetworkChangeNotifierDelegateAndroid()
38    : observers_(new ObserverListThreadSafe<Observer>()) {
39  JNIEnv* env = base::android::AttachCurrentThread();
40  java_network_change_notifier_.Reset(
41      Java_NetworkChangeNotifier_init(
42          env, base::android::GetApplicationContext()));
43  Java_NetworkChangeNotifier_addNativeObserver(
44      env, java_network_change_notifier_.obj(),
45      reinterpret_cast<intptr_t>(this));
46  SetCurrentConnectionType(
47      ConvertConnectionType(
48          Java_NetworkChangeNotifier_getCurrentConnectionType(
49              env, java_network_change_notifier_.obj())));
50}
51
52NetworkChangeNotifierDelegateAndroid::~NetworkChangeNotifierDelegateAndroid() {
53  DCHECK(thread_checker_.CalledOnValidThread());
54  observers_->AssertEmpty();
55  JNIEnv* env = base::android::AttachCurrentThread();
56  Java_NetworkChangeNotifier_removeNativeObserver(
57      env, java_network_change_notifier_.obj(),
58      reinterpret_cast<intptr_t>(this));
59}
60
61NetworkChangeNotifier::ConnectionType
62NetworkChangeNotifierDelegateAndroid::GetCurrentConnectionType() const {
63  base::AutoLock auto_lock(connection_type_lock_);
64  return connection_type_;
65}
66
67void NetworkChangeNotifierDelegateAndroid::NotifyConnectionTypeChanged(
68    JNIEnv* env,
69    jobject obj,
70    jint new_connection_type) {
71  DCHECK(thread_checker_.CalledOnValidThread());
72  const ConnectionType actual_connection_type = ConvertConnectionType(
73      new_connection_type);
74  SetCurrentConnectionType(actual_connection_type);
75  observers_->Notify(&Observer::OnConnectionTypeChanged);
76}
77
78jint NetworkChangeNotifierDelegateAndroid::GetConnectionType(JNIEnv*,
79                                                             jobject) const {
80  DCHECK(thread_checker_.CalledOnValidThread());
81  return GetCurrentConnectionType();
82}
83
84void NetworkChangeNotifierDelegateAndroid::AddObserver(
85    Observer* observer) {
86  observers_->AddObserver(observer);
87}
88
89void NetworkChangeNotifierDelegateAndroid::RemoveObserver(
90    Observer* observer) {
91  observers_->RemoveObserver(observer);
92}
93
94// static
95bool NetworkChangeNotifierDelegateAndroid::Register(JNIEnv* env) {
96  return RegisterNativesImpl(env);
97}
98
99void NetworkChangeNotifierDelegateAndroid::SetCurrentConnectionType(
100    ConnectionType new_connection_type) {
101  base::AutoLock auto_lock(connection_type_lock_);
102  connection_type_ = new_connection_type;
103}
104
105void NetworkChangeNotifierDelegateAndroid::SetOnline() {
106  JNIEnv* env = base::android::AttachCurrentThread();
107  Java_NetworkChangeNotifier_forceConnectivityState(env, true);
108}
109
110void NetworkChangeNotifierDelegateAndroid::SetOffline() {
111  JNIEnv* env = base::android::AttachCurrentThread();
112  Java_NetworkChangeNotifier_forceConnectivityState(env, false);
113}
114
115}  // namespace net
116