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

// See network_change_notifier_android.h for design explanations.

#include "net/android/network_change_notifier_android.h"

#include "base/bind.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/run_loop.h"
#include "net/android/network_change_notifier_delegate_android.h"
#include "net/base/ip_address.h"
#include "net/base/network_change_notifier.h"
#include "net/test/test_with_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

// Types of network changes. See similarly named functions in
// NetworkChangeNotifier::NetworkObserver for descriptions.
enum ChangeType {
  NONE,
  CONNECTED,
  SOON_TO_DISCONNECT,
  DISCONNECTED,
  MADE_DEFAULT,
};

class NetworkChangeNotifierDelegateAndroidObserver
    : public NetworkChangeNotifierDelegateAndroid::Observer {
 public:
  typedef NetworkChangeNotifier::ConnectionType ConnectionType;
  typedef NetworkChangeNotifier::NetworkHandle NetworkHandle;
  typedef NetworkChangeNotifier::NetworkList NetworkList;

  NetworkChangeNotifierDelegateAndroidObserver()
      : type_notifications_count_(0), max_bandwidth_notifications_count_(0) {}

  // NetworkChangeNotifierDelegateAndroid::Observer:
  void OnConnectionTypeChanged() override { type_notifications_count_++; }

  void OnMaxBandwidthChanged(
      double max_bandwidth_mbps,
      net::NetworkChangeNotifier::ConnectionType type) override {
    max_bandwidth_notifications_count_++;
  }

  void OnNetworkConnected(NetworkHandle network) override {}

  void OnNetworkSoonToDisconnect(NetworkHandle network) override {}

  void OnNetworkDisconnected(NetworkHandle network) override {}

  void OnNetworkMadeDefault(NetworkHandle network) override {}

  int type_notifications_count() const { return type_notifications_count_; }
  int bandwidth_notifications_count() const {
    return max_bandwidth_notifications_count_;
  }

 private:
  int type_notifications_count_;
  int max_bandwidth_notifications_count_;
};

class NetworkChangeNotifierObserver
    : public NetworkChangeNotifier::ConnectionTypeObserver {
 public:
  NetworkChangeNotifierObserver() : notifications_count_(0) {}

  // NetworkChangeNotifier::ConnectionTypeObserver:
  void OnConnectionTypeChanged(
      NetworkChangeNotifier::ConnectionType connection_type) override {
    notifications_count_++;
  }

  int notifications_count() const {
    return notifications_count_;
  }

 private:
  int notifications_count_;
};

class NetworkChangeNotifierMaxBandwidthObserver
    : public NetworkChangeNotifier::MaxBandwidthObserver {
 public:
  // NetworkChangeNotifier::MaxBandwidthObserver:
  void OnMaxBandwidthChanged(
      double max_bandwidth_mbps,
      NetworkChangeNotifier::ConnectionType type) override {
    notifications_count_++;
  }

  int notifications_count() const { return notifications_count_; }

 private:
  int notifications_count_ = 0;
};

// A NetworkObserver used for verifying correct notifications are sent.
class TestNetworkObserver : public NetworkChangeNotifier::NetworkObserver {
 public:
  TestNetworkObserver() { Clear(); }

  void ExpectChange(ChangeType change,
                    NetworkChangeNotifier::NetworkHandle network) {
    EXPECT_EQ(last_change_type_, change);
    EXPECT_EQ(last_network_changed_, network);
    Clear();
  }

 private:
  void Clear() {
    last_change_type_ = NONE;
    last_network_changed_ = NetworkChangeNotifier::kInvalidNetworkHandle;
  }

  // NetworkChangeNotifier::NetworkObserver implementation:
  void OnNetworkConnected(
      NetworkChangeNotifier::NetworkHandle network) override {
    ExpectChange(NONE, NetworkChangeNotifier::kInvalidNetworkHandle);
    last_change_type_ = CONNECTED;
    last_network_changed_ = network;
  }
  void OnNetworkSoonToDisconnect(
      NetworkChangeNotifier::NetworkHandle network) override {
    ExpectChange(NONE, NetworkChangeNotifier::kInvalidNetworkHandle);
    last_change_type_ = SOON_TO_DISCONNECT;
    last_network_changed_ = network;
  }
  void OnNetworkDisconnected(
      NetworkChangeNotifier::NetworkHandle network) override {
    ExpectChange(NONE, NetworkChangeNotifier::kInvalidNetworkHandle);
    last_change_type_ = DISCONNECTED;
    last_network_changed_ = network;
  }
  void OnNetworkMadeDefault(
      NetworkChangeNotifier::NetworkHandle network) override {
    // Cannot test for Clear()ed state as we receive CONNECTED immediately prior
    // to MADE_DEFAULT.
    last_change_type_ = MADE_DEFAULT;
    last_network_changed_ = network;
  }

  ChangeType last_change_type_;
  NetworkChangeNotifier::NetworkHandle last_network_changed_;
};

}  // namespace

class BaseNetworkChangeNotifierAndroidTest : public TestWithTaskEnvironment {
 protected:
  typedef NetworkChangeNotifier::ConnectionType ConnectionType;
  typedef NetworkChangeNotifier::ConnectionSubtype ConnectionSubtype;

  ~BaseNetworkChangeNotifierAndroidTest() override {}

  void RunTest(
      const base::RepeatingCallback<int(void)>& notifications_count_getter,
      const base::RepeatingCallback<ConnectionType(void)>&
          connection_type_getter) {
    EXPECT_EQ(0, notifications_count_getter.Run());
    EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN,
              connection_type_getter.Run());

    // Changing from online to offline should trigger a notification.
    SetOffline();
    EXPECT_EQ(1, notifications_count_getter.Run());
    EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE,
              connection_type_getter.Run());

    // No notification should be triggered when the offline state hasn't
    // changed.
    SetOffline();
    EXPECT_EQ(1, notifications_count_getter.Run());
    EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE,
              connection_type_getter.Run());

    // Going from offline to online should trigger a notification.
    SetOnline();
    EXPECT_EQ(2, notifications_count_getter.Run());
    EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN,
              connection_type_getter.Run());
  }

  void SetOnline() {
    delegate_.SetOnline();
    // Note that this is needed because base::ObserverListThreadSafe uses
    // PostTask().
    base::RunLoop().RunUntilIdle();
  }

  void SetOffline() {
    delegate_.SetOffline();
    // See comment above.
    base::RunLoop().RunUntilIdle();
  }

  void FakeConnectionSubtypeChange(ConnectionSubtype subtype) {
    delegate_.FakeConnectionSubtypeChanged(subtype);
    base::RunLoop().RunUntilIdle();
  }

  void FakeNetworkChange(ChangeType change,
                         NetworkChangeNotifier::NetworkHandle network,
                         ConnectionType type) {
    switch (change) {
      case CONNECTED:
        delegate_.FakeNetworkConnected(network, type);
        break;
      case SOON_TO_DISCONNECT:
        delegate_.FakeNetworkSoonToBeDisconnected(network);
        break;
      case DISCONNECTED:
        delegate_.FakeNetworkDisconnected(network);
        break;
      case MADE_DEFAULT:
        delegate_.FakeDefaultNetwork(network, type);
        break;
      case NONE:
        NOTREACHED();
        break;
    }
    // See comment above.
    base::RunLoop().RunUntilIdle();
  }

  void FakePurgeActiveNetworkList(NetworkChangeNotifier::NetworkList networks) {
    delegate_.FakePurgeActiveNetworkList(networks);
    // See comment above.
    base::RunLoop().RunUntilIdle();
  }

  NetworkChangeNotifierDelegateAndroid delegate_;
};

// Tests that NetworkChangeNotifierDelegateAndroid is initialized with the
// actual connection type rather than a hardcoded one (e.g.
// CONNECTION_UNKNOWN). Initializing the connection type to CONNECTION_UNKNOWN
// and relying on the first network change notification to set it correctly can
// be problematic in case there is a long delay between the delegate's
// construction and the notification.
TEST_F(BaseNetworkChangeNotifierAndroidTest,
       DelegateIsInitializedWithCurrentConnectionType) {
  SetOffline();
  ASSERT_EQ(NetworkChangeNotifier::CONNECTION_NONE,
            delegate_.GetCurrentConnectionType());
  // Instantiate another delegate to validate that it uses the actual
  // connection type at construction.
  std::unique_ptr<NetworkChangeNotifierDelegateAndroid> other_delegate(
      new NetworkChangeNotifierDelegateAndroid());
  EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE,
            other_delegate->GetCurrentConnectionType());

  // Toggle the global connectivity state and instantiate another delegate
  // again.
  SetOnline();
  ASSERT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN,
            delegate_.GetCurrentConnectionType());
  other_delegate.reset(new NetworkChangeNotifierDelegateAndroid());
  EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN,
            other_delegate->GetCurrentConnectionType());
}

class NetworkChangeNotifierAndroidTest
    : public BaseNetworkChangeNotifierAndroidTest {
 protected:
  NetworkChangeNotifierAndroidTest() : notifier_(&delegate_) {
    NetworkChangeNotifier::AddConnectionTypeObserver(
        &connection_type_observer_);
    NetworkChangeNotifier::AddConnectionTypeObserver(
        &other_connection_type_observer_);
    NetworkChangeNotifier::AddMaxBandwidthObserver(&max_bandwidth_observer_);
  }

  void ForceNetworkHandlesSupportedForTesting() {
    notifier_.ForceNetworkHandlesSupportedForTesting();
  }

  NetworkChangeNotifierObserver connection_type_observer_;
  NetworkChangeNotifierMaxBandwidthObserver max_bandwidth_observer_;
  NetworkChangeNotifierObserver other_connection_type_observer_;
  NetworkChangeNotifier::DisableForTest disable_for_test_;
  NetworkChangeNotifierAndroid notifier_;
};

class NetworkChangeNotifierDelegateAndroidTest
    : public NetworkChangeNotifierAndroidTest {
 protected:
  NetworkChangeNotifierDelegateAndroidTest() {
    delegate_.AddObserver(&delegate_observer_);
    delegate_.AddObserver(&other_delegate_observer_);
  }

  ~NetworkChangeNotifierDelegateAndroidTest() override {
    delegate_.RemoveObserver(&delegate_observer_);
    delegate_.RemoveObserver(&other_delegate_observer_);
  }

  NetworkChangeNotifierDelegateAndroidObserver delegate_observer_;
  NetworkChangeNotifierDelegateAndroidObserver other_delegate_observer_;
};

// Tests that the NetworkChangeNotifierDelegateAndroid's observers are notified.
// A testing-only observer is used here for testing. In production the
// delegate's observers are instances of NetworkChangeNotifierAndroid.
TEST_F(NetworkChangeNotifierDelegateAndroidTest, DelegateObserverNotified) {
  // Test the logic with a single observer.
  RunTest(base::BindRepeating(&NetworkChangeNotifierDelegateAndroidObserver::
                                  type_notifications_count,
                              base::Unretained(&delegate_observer_)),
          base::BindRepeating(
              &NetworkChangeNotifierDelegateAndroid::GetCurrentConnectionType,
              base::Unretained(&delegate_)));
  // Check that *all* the observers are notified. Both observers should have the
  // same state.
  EXPECT_EQ(delegate_observer_.type_notifications_count(),
            other_delegate_observer_.type_notifications_count());
}


// When a NetworkChangeNotifierAndroid is observing a
// NetworkChangeNotifierDelegateAndroid for network state changes, and the
// NetworkChangeNotifierDelegateAndroid's connectivity state changes, the
// NetworkChangeNotifierAndroid should reflect that state.
TEST_F(NetworkChangeNotifierAndroidTest,
       NotificationsSentToNetworkChangeNotifierAndroid) {
  RunTest(
      base::BindRepeating(&NetworkChangeNotifierObserver::notifications_count,
                          base::Unretained(&connection_type_observer_)),
      base::BindRepeating(
          &NetworkChangeNotifierAndroid::GetCurrentConnectionType,
          base::Unretained(&notifier_)));
}

// When a NetworkChangeNotifierAndroid's connection state changes, it should
// notify all of its observers.
TEST_F(NetworkChangeNotifierAndroidTest,
       NotificationsSentToClientsOfNetworkChangeNotifier) {
  RunTest(
      base::BindRepeating(&NetworkChangeNotifierObserver::notifications_count,
                          base::Unretained(&connection_type_observer_)),
      base::BindRepeating(&NetworkChangeNotifier::GetConnectionType));
  // Check that *all* the observers are notified.
  EXPECT_EQ(connection_type_observer_.notifications_count(),
            other_connection_type_observer_.notifications_count());
}

TEST_F(NetworkChangeNotifierAndroidTest, MaxBandwidth) {
  SetOnline();
  double max_bandwidth_mbps = 0.0;
  NetworkChangeNotifier::ConnectionType connection_type =
      NetworkChangeNotifier::CONNECTION_NONE;
  notifier_.GetMaxBandwidthAndConnectionType(&max_bandwidth_mbps,
                                             &connection_type);
  EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN, connection_type);
  EXPECT_EQ(std::numeric_limits<double>::infinity(), max_bandwidth_mbps);
  SetOffline();
  notifier_.GetMaxBandwidthAndConnectionType(&max_bandwidth_mbps,
                                             &connection_type);
  EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE, connection_type);
  EXPECT_EQ(0.0, max_bandwidth_mbps);
}

TEST_F(NetworkChangeNotifierDelegateAndroidTest, MaxBandwidthCallbackNotifier) {
  // The bandwidth notification should always be forwarded, even if the value
  // doesn't change (because the type might have changed).
  FakeConnectionSubtypeChange(ConnectionSubtype::SUBTYPE_CDMA);
  EXPECT_EQ(1, delegate_observer_.bandwidth_notifications_count());
  EXPECT_EQ(1, max_bandwidth_observer_.notifications_count());

  FakeConnectionSubtypeChange(ConnectionSubtype::SUBTYPE_CDMA);
  EXPECT_EQ(2, delegate_observer_.bandwidth_notifications_count());
  EXPECT_EQ(2, max_bandwidth_observer_.notifications_count());

  FakeConnectionSubtypeChange(ConnectionSubtype::SUBTYPE_LTE);
  EXPECT_EQ(3, delegate_observer_.bandwidth_notifications_count());
  EXPECT_EQ(3, max_bandwidth_observer_.notifications_count());
}

TEST_F(NetworkChangeNotifierDelegateAndroidTest,
       MaxBandwidthNotifiedOnConnectionChange) {
  EXPECT_EQ(0, delegate_observer_.bandwidth_notifications_count());
  SetOffline();
  EXPECT_EQ(1, delegate_observer_.bandwidth_notifications_count());
  SetOnline();
  EXPECT_EQ(2, delegate_observer_.bandwidth_notifications_count());
  SetOnline();
  EXPECT_EQ(2, delegate_observer_.bandwidth_notifications_count());
}

TEST_F(NetworkChangeNotifierAndroidTest, NetworkCallbacks) {
  ForceNetworkHandlesSupportedForTesting();

  TestNetworkObserver network_observer;
  NetworkChangeNotifier::AddNetworkObserver(&network_observer);

  // Test empty values
  EXPECT_EQ(NetworkChangeNotifier::kInvalidNetworkHandle,
            NetworkChangeNotifier::GetDefaultNetwork());
  EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN,
            NetworkChangeNotifier::GetNetworkConnectionType(100));
  NetworkChangeNotifier::NetworkList network_list;
  NetworkChangeNotifier::GetConnectedNetworks(&network_list);
  EXPECT_EQ(0u, network_list.size());
  // Test connecting network
  FakeNetworkChange(CONNECTED, 100, NetworkChangeNotifier::CONNECTION_WIFI);
  network_observer.ExpectChange(CONNECTED, 100);
  EXPECT_EQ(NetworkChangeNotifier::kInvalidNetworkHandle,
            NetworkChangeNotifier::GetDefaultNetwork());
  // Test GetConnectedNetworks()
  NetworkChangeNotifier::GetConnectedNetworks(&network_list);
  EXPECT_EQ(1u, network_list.size());
  EXPECT_EQ(100, network_list[0]);
  // Test GetNetworkConnectionType()
  EXPECT_EQ(NetworkChangeNotifier::CONNECTION_WIFI,
            NetworkChangeNotifier::GetNetworkConnectionType(100));
  // Test deduplication of connecting signal
  FakeNetworkChange(CONNECTED, 100, NetworkChangeNotifier::CONNECTION_WIFI);
  network_observer.ExpectChange(NONE,
                                NetworkChangeNotifier::kInvalidNetworkHandle);
  // Test connecting another network
  FakeNetworkChange(CONNECTED, 101, NetworkChangeNotifier::CONNECTION_3G);
  network_observer.ExpectChange(CONNECTED, 101);
  NetworkChangeNotifier::GetConnectedNetworks(&network_list);
  EXPECT_EQ(2u, network_list.size());
  EXPECT_EQ(100, network_list[0]);
  EXPECT_EQ(101, network_list[1]);
  EXPECT_EQ(NetworkChangeNotifier::CONNECTION_WIFI,
            NetworkChangeNotifier::GetNetworkConnectionType(100));
  EXPECT_EQ(NetworkChangeNotifier::CONNECTION_3G,
            NetworkChangeNotifier::GetNetworkConnectionType(101));
  // Test lingering network
  FakeNetworkChange(SOON_TO_DISCONNECT, 100,
                    NetworkChangeNotifier::CONNECTION_WIFI);
  network_observer.ExpectChange(SOON_TO_DISCONNECT, 100);
  NetworkChangeNotifier::GetConnectedNetworks(&network_list);
  EXPECT_EQ(2u, network_list.size());
  EXPECT_EQ(100, network_list[0]);
  EXPECT_EQ(101, network_list[1]);
  // Test disconnecting network
  FakeNetworkChange(DISCONNECTED, 100, NetworkChangeNotifier::CONNECTION_WIFI);
  network_observer.ExpectChange(DISCONNECTED, 100);
  NetworkChangeNotifier::GetConnectedNetworks(&network_list);
  EXPECT_EQ(1u, network_list.size());
  EXPECT_EQ(101, network_list[0]);
  // Test deduplication of disconnecting signal
  FakeNetworkChange(DISCONNECTED, 100, NetworkChangeNotifier::CONNECTION_WIFI);
  network_observer.ExpectChange(NONE,
                                NetworkChangeNotifier::kInvalidNetworkHandle);
  // Test delay of default network signal until connect signal
  FakeNetworkChange(MADE_DEFAULT, 100, NetworkChangeNotifier::CONNECTION_WIFI);
  network_observer.ExpectChange(NONE,
                                NetworkChangeNotifier::kInvalidNetworkHandle);
  FakeNetworkChange(CONNECTED, 100, NetworkChangeNotifier::CONNECTION_WIFI);
  network_observer.ExpectChange(MADE_DEFAULT, 100);
  EXPECT_EQ(100, NetworkChangeNotifier::GetDefaultNetwork());
  // Test change of default
  FakeNetworkChange(MADE_DEFAULT, 101, NetworkChangeNotifier::CONNECTION_3G);
  network_observer.ExpectChange(MADE_DEFAULT, 101);
  EXPECT_EQ(101, NetworkChangeNotifier::GetDefaultNetwork());
  // Test deduplication default signal
  FakeNetworkChange(MADE_DEFAULT, 101, NetworkChangeNotifier::CONNECTION_3G);
  network_observer.ExpectChange(NONE,
                                NetworkChangeNotifier::kInvalidNetworkHandle);
  // Test that networks can change type
  FakeNetworkChange(CONNECTED, 101, NetworkChangeNotifier::CONNECTION_4G);
  network_observer.ExpectChange(NONE,
                                NetworkChangeNotifier::kInvalidNetworkHandle);
  EXPECT_EQ(NetworkChangeNotifier::CONNECTION_4G,
            NetworkChangeNotifier::GetNetworkConnectionType(101));
  // Test purging the network list
  NetworkChangeNotifier::GetConnectedNetworks(&network_list);
  EXPECT_EQ(2u, network_list.size());
  EXPECT_EQ(100, network_list[0]);
  EXPECT_EQ(101, network_list[1]);
  network_list.erase(network_list.begin() + 1);  // Remove network 101
  FakePurgeActiveNetworkList(network_list);
  network_observer.ExpectChange(DISCONNECTED, 101);
  NetworkChangeNotifier::GetConnectedNetworks(&network_list);
  EXPECT_EQ(1u, network_list.size());
  EXPECT_EQ(100, network_list[0]);
  EXPECT_EQ(NetworkChangeNotifier::kInvalidNetworkHandle,
            NetworkChangeNotifier::GetDefaultNetwork());

  NetworkChangeNotifier::RemoveNetworkObserver(&network_observer);
}

}  // namespace net
