// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

////////////////////////////////////////////////////////////////////////////////
// Threading considerations:
//
// This class is designed to meet various threading guarantees starting from the
// ones imposed by NetworkChangeNotifier:
// - The notifier can be constructed on any thread.
// - GetCurrentConnectionType() can be called on any thread.
//
// The fact that this implementation of NetworkChangeNotifier is backed by a
// Java side singleton class (see NetworkChangeNotifier.java) adds another
// threading constraint:
// - The calls to the Java side (stateful) object must be performed from a
//   single thread. This object happens to be a singleton which is used on the
//   application side on the main thread. Therefore all the method calls from
//   the native NetworkChangeNotifierAndroid class to its Java counterpart are
//   performed on the main thread.
//
// This leads to a design involving the following native classes:
// 1) NetworkChangeNotifierFactoryAndroid ('factory')
// 2) NetworkChangeNotifierDelegateAndroid ('delegate')
// 3) NetworkChangeNotifierAndroid ('notifier')
//
// The factory constructs and owns the delegate. The factory is constructed and
// destroyed on the main thread which makes it construct and destroy the
// delegate on the main thread too. This guarantees that the calls to the Java
// side are performed on the main thread.
// Note that after the factory's construction, the factory's creation method can
// be called from any thread since the delegate's construction (performing the
// JNI calls) already happened on the main thread (when the factory was
// constructed).
//
////////////////////////////////////////////////////////////////////////////////
// Propagation of network change notifications:
//
// When the factory is requested to create a new instance of the notifier, the
// factory passes the delegate to the notifier (without transferring ownership).
// Note that there is a one-to-one mapping between the factory and the
// delegate as explained above. But the factory naturally creates multiple
// instances of the notifier. That means that there is a one-to-many mapping
// between delegate and notifier (i.e. a single delegate can be shared by
// multiple notifiers).
// At construction the notifier (which is also an observer) subscribes to
// notifications fired by the delegate. These notifications, received by the
// delegate (and forwarded to the notifier(s)), are sent by the Java side
// notifier (see NetworkChangeNotifier.java) and are initiated by the Android
// platform.
// Notifications from the Java side always arrive on the main thread. The
// delegate then forwards these notifications to the threads of each observer
// (network change notifier). The network change notifier than processes the
// state change, and notifies each of its observers on their threads.
//
// This can also be seen as:
// Android platform -> NetworkChangeNotifier (Java) ->
// NetworkChangeNotifierDelegateAndroid -> NetworkChangeNotifierAndroid.

#include "net/android/network_change_notifier_android.h"

#include <unordered_set>

#include "base/android/build_info.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram_macros.h"
#include "base/threading/thread.h"
#include "net/base/address_tracker_linux.h"
#include "net/dns/dns_config_service.h"

namespace net {

// Expose kInvalidNetworkHandle out to Java as NetId.INVALID. The notion of
// a NetID is an Android framework one, see android.net.Network.netId.
// NetworkChangeNotifierAndroid implements NetworkHandle to simply be the NetID.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net
enum NetId {
  // Cannot use |kInvalidNetworkHandle| here as the Java generator fails,
  // instead enforce their equality with CHECK in
  // NetworkChangeNotifierAndroid().
  INVALID = -1
};

// Thread on which we can run DnsConfigService, which requires a TYPE_IO
// message loop to monitor /system/etc/hosts.
class NetworkChangeNotifierAndroid::DnsConfigServiceThread
    : public base::Thread {
 public:
  DnsConfigServiceThread()
      : base::Thread("DnsConfigService"),
        address_tracker_(base::DoNothing(),
                         base::DoNothing(),
                         // We're only interested in tunnel interface changes.
                         base::Bind(NotifyNetworkChangeNotifierObservers),
                         std::unordered_set<std::string>()) {}

  ~DnsConfigServiceThread() override {
    Stop();
  }

  void Init() override {
    address_tracker_.Init();
    dns_config_service_ = DnsConfigService::CreateSystemService();
    dns_config_service_->WatchConfig(
        base::Bind(&NetworkChangeNotifier::SetDnsConfig));
  }

  void CleanUp() override { dns_config_service_.reset(); }

  static void NotifyNetworkChangeNotifierObservers() {
    NetworkChangeNotifier::NotifyObserversOfIPAddressChange();
    NetworkChangeNotifier::NotifyObserversOfConnectionTypeChange();
  }

 private:
  std::unique_ptr<DnsConfigService> dns_config_service_;
  // Used to detect tunnel state changes.
  internal::AddressTrackerLinux address_tracker_;

  DISALLOW_COPY_AND_ASSIGN(DnsConfigServiceThread);
};

NetworkChangeNotifierAndroid::~NetworkChangeNotifierAndroid() {
  delegate_->RemoveObserver(this);
}

NetworkChangeNotifier::ConnectionType
NetworkChangeNotifierAndroid::GetCurrentConnectionType() const {
  return delegate_->GetCurrentConnectionType();
}

NetworkChangeNotifier::ConnectionSubtype
NetworkChangeNotifierAndroid::GetCurrentConnectionSubtype() const {
  return delegate_->GetCurrentConnectionSubtype();
}

void NetworkChangeNotifierAndroid::GetCurrentMaxBandwidthAndConnectionType(
    double* max_bandwidth_mbps,
    ConnectionType* connection_type) const {
  delegate_->GetCurrentMaxBandwidthAndConnectionType(max_bandwidth_mbps,
                                                     connection_type);
}

void NetworkChangeNotifierAndroid::ForceNetworkHandlesSupportedForTesting() {
  force_network_handles_supported_for_testing_ = true;
}

bool NetworkChangeNotifierAndroid::AreNetworkHandlesCurrentlySupported() const {
  // Notifications for API using NetworkHandles and querying using
  // NetworkHandles only implemented for Android versions >= L.
  return force_network_handles_supported_for_testing_ ||
         (base::android::BuildInfo::GetInstance()->sdk_int() >=
              base::android::SDK_VERSION_LOLLIPOP &&
          !delegate_->IsProcessBoundToNetwork() &&
          !delegate_->RegisterNetworkCallbackFailed());
}

void NetworkChangeNotifierAndroid::GetCurrentConnectedNetworks(
    NetworkChangeNotifier::NetworkList* networks) const {
  delegate_->GetCurrentlyConnectedNetworks(networks);
}

NetworkChangeNotifier::ConnectionType
NetworkChangeNotifierAndroid::GetCurrentNetworkConnectionType(
    NetworkHandle network) const {
  return delegate_->GetNetworkConnectionType(network);
}

NetworkChangeNotifier::NetworkHandle
NetworkChangeNotifierAndroid::GetCurrentDefaultNetwork() const {
  return delegate_->GetCurrentDefaultNetwork();
}

void NetworkChangeNotifierAndroid::OnConnectionTypeChanged() {
  DnsConfigServiceThread::NotifyNetworkChangeNotifierObservers();
}

void NetworkChangeNotifierAndroid::OnMaxBandwidthChanged(
    double max_bandwidth_mbps,
    ConnectionType type) {
  NetworkChangeNotifier::NotifyObserversOfMaxBandwidthChange(max_bandwidth_mbps,
                                                             type);
}

void NetworkChangeNotifierAndroid::OnNetworkConnected(NetworkHandle network) {
  NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChange(
      NetworkChangeType::CONNECTED, network);
}

void NetworkChangeNotifierAndroid::OnNetworkSoonToDisconnect(
    NetworkHandle network) {
  NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChange(
      NetworkChangeType::SOON_TO_DISCONNECT, network);
}

void NetworkChangeNotifierAndroid::OnNetworkDisconnected(
    NetworkHandle network) {
  NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChange(
      NetworkChangeType::DISCONNECTED, network);
}

void NetworkChangeNotifierAndroid::OnNetworkMadeDefault(NetworkHandle network) {
  NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChange(
      NetworkChangeType::MADE_DEFAULT, network);
}

NetworkChangeNotifierAndroid::NetworkChangeNotifierAndroid(
    NetworkChangeNotifierDelegateAndroid* delegate)
    : NetworkChangeNotifier(NetworkChangeCalculatorParamsAndroid()),
      delegate_(delegate),
      dns_config_service_thread_(new DnsConfigServiceThread()),
      force_network_handles_supported_for_testing_(false) {
  CHECK_EQ(NetId::INVALID, NetworkChangeNotifier::kInvalidNetworkHandle)
      << "kInvalidNetworkHandle doesn't match NetId::INVALID";
  delegate_->AddObserver(this);
  dns_config_service_thread_->StartWithOptions(
      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
}

// static
NetworkChangeNotifier::NetworkChangeCalculatorParams
NetworkChangeNotifierAndroid::NetworkChangeCalculatorParamsAndroid() {
  NetworkChangeCalculatorParams params;
  // IPAddressChanged is produced immediately prior to ConnectionTypeChanged
  // so delay IPAddressChanged so they get merged with the following
  // ConnectionTypeChanged signal.
  params.ip_address_offline_delay_ = base::TimeDelta::FromSeconds(1);
  params.ip_address_online_delay_ = base::TimeDelta::FromSeconds(1);
  params.connection_type_offline_delay_ = base::TimeDelta::FromSeconds(0);
  params.connection_type_online_delay_ = base::TimeDelta::FromSeconds(0);
  return params;
}

void NetworkChangeNotifierAndroid::OnFinalizingMetricsLogRecord() {
  // Metrics logged here will be included in every metrics log record.  It's not
  // yet clear if these metrics are generally useful enough to warrant being
  // added to the SystemProfile proto, so they are logged here as histograms for
  // now.
  const NetworkChangeNotifier::ConnectionType type =
      NetworkChangeNotifier::GetConnectionType();
  NetworkChangeNotifier::LogOperatorCodeHistogram(type);
  if (NetworkChangeNotifier::IsConnectionCellular(type)) {
    UMA_HISTOGRAM_ENUMERATION("NCN.CellularConnectionSubtype",
                              delegate_->GetCurrentConnectionSubtype(),
                              SUBTYPE_LAST + 1);
  }
}

}  // namespace net
