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

#ifndef SHILL_MANAGER_H_
#define SHILL_MANAGER_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include <base/cancelable_callback.h>
#include <base/files/file_path.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <base/memory/weak_ptr.h>
#include <chromeos/dbus/service_constants.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include "shill/cellular/modem_info.h"
#include "shill/crypto_util_proxy.h"
#include "shill/device.h"
#include "shill/device_info.h"
#include "shill/event_dispatcher.h"
#include "shill/geolocation_info.h"
#include "shill/hook_table.h"
#include "shill/metrics.h"
#include "shill/net/ip_address.h"
#include "shill/power_manager.h"
#include "shill/profile.h"
#include "shill/property_store.h"
#include "shill/service.h"
#include "shill/upstart/upstart.h"
#include "shill/wimax/wimax_provider.h"

namespace shill {

class ControlInterface;
class DBusManager;
class DeviceClaimer;
class DefaultProfile;
class Error;
class EventDispatcher;
class IPAddressStore;
class ManagerAdaptorInterface;
class Resolver;
class StoreInterface;
class VPNProvider;

#if !defined(DISABLE_WIFI)
class WiFiProvider;
#endif  // DISABLE_WIFI

#if !defined(DISABLE_WIRED_8021X)
class EthernetEapProvider;
#endif  // DISABLE_WIRED_8021X

class Manager : public base::SupportsWeakPtr<Manager> {
 public:
  typedef base::Callback<void(const ServiceRefPtr &service)> ServiceCallback;

  struct Properties {
   public:
    Properties()
        : offline_mode(false),
          portal_check_interval_seconds(0),
          arp_gateway(true),
          connection_id_salt(0),
          minimum_mtu(IPConfig::kUndefinedMTU) {}
    bool offline_mode;
    std::string check_portal_list;
    std::string country;
    int32_t portal_check_interval_seconds;
    std::string portal_url;
    std::string host_name;
    // Whether to ARP for the default gateway in the DHCP client after
    // acquiring a lease.
    bool arp_gateway;
    // Comma-separated list of technologies for which link-monitoring is
    // enabled.
    std::string link_monitor_technologies;
    // Comma-separated list of technologies for which auto-connect is disabled.
    std::string no_auto_connect_technologies;
    // Comma-separated list of technologies that should never be enabled.
    std::string prohibited_technologies;
    // Comma-separated list of DNS search paths to be ignored.
    std::string ignored_dns_search_paths;
    // Comma-separated list of DNS servers to prepend to resolver list.
    std::string prepend_dns_servers;
    // Salt value use for calculating network connection ID.
    int connection_id_salt;
    // The minimum MTU value that will be respected in DHCP responses.
    int minimum_mtu;
  };

  Manager(ControlInterface *control_interface,
          EventDispatcher *dispatcher,
          Metrics *metrics,
          GLib *glib,
          const std::string &run_directory,
          const std::string &storage_directory,
          const std::string &user_storage_directory,
          const std::vector<Technology::Identifier> &default_technology_order);
  virtual ~Manager();

  void AddDeviceToBlackList(const std::string &device_name);

  virtual void Start();
  virtual void Stop();
  bool running() const { return running_; }

  const ProfileRefPtr &ActiveProfile() const;
  bool IsActiveProfile(const ProfileRefPtr &profile) const;
  bool MoveServiceToProfile(const ServiceRefPtr &to_move,
                            const ProfileRefPtr &destination);
  ProfileRefPtr LookupProfileByRpcIdentifier(const std::string &profile_rpcid);

  // Called via RPC call on Service (|to_set|) to set the "Profile" property.
  virtual void SetProfileForService(const ServiceRefPtr &to_set,
                                    const std::string &profile,
                                    Error *error);

  virtual void RegisterDevice(const DeviceRefPtr &to_manage);
  virtual void DeregisterDevice(const DeviceRefPtr &to_forget);

  virtual bool HasService(const ServiceRefPtr &service);
  // Register a Service with the Manager. Manager may choose to
  // connect to it immediately.
  virtual void RegisterService(const ServiceRefPtr &to_manage);
  // Deregister a Service from the Manager. Caller is responsible
  // for disconnecting the Service before-hand.
  virtual void DeregisterService(const ServiceRefPtr &to_forget);
  virtual void UpdateService(const ServiceRefPtr &to_update);

  // Persists |to_update| into an appropriate profile.
  virtual void UpdateDevice(const DeviceRefPtr &to_update);

#if !defined(DISABLE_WIFI)
  virtual void UpdateWiFiProvider();
#endif  // DISABLE_WIFI

  std::vector<DeviceRefPtr>
      FilterByTechnology(Technology::Identifier tech) const;

  ServiceRefPtr FindService(const std::string& name);
  RpcIdentifiers EnumerateAvailableServices(Error *error);

  // Return the complete list of services, including those that are not visible.
  RpcIdentifiers EnumerateCompleteServices(Error *error);

  // called via RPC (e.g., from ManagerDBusAdaptor)
  std::map<std::string, std::string> GetLoadableProfileEntriesForService(
      const ServiceConstRefPtr &service);
  ServiceRefPtr GetService(const KeyValueStore &args, Error *error);
  ServiceRefPtr ConfigureService(const KeyValueStore &args, Error *error);
  ServiceRefPtr ConfigureServiceForProfile(
      const std::string &profile_rpcid,
      const KeyValueStore &args,
      Error *error);
  ServiceRefPtr FindMatchingService(const KeyValueStore &args, Error *error);

  // Retrieve geolocation data from the Manager.
  const std::map<std::string, GeolocationInfos>
      &GetNetworksForGeolocation() const;

  // Called by Device when its geolocation data has been updated.
  virtual void OnDeviceGeolocationInfoUpdated(const DeviceRefPtr &device);

  void ConnectToBestServices(Error *error);

  // Method to create connectivity report for connected services.
  void CreateConnectivityReport(Error *error);

  // Request portal detection checks on each registered device until a portal
  // detection attempt starts on one of them.
  void RecheckPortal(Error *error);
  // Request portal detection be restarted on the device connected to
  // |service|.
  virtual void RecheckPortalOnService(const ServiceRefPtr &service);

  virtual void RequestScan(Device::ScanType scan_type,
                           const std::string &technology, Error *error);
  // Configure scheduled scan for wifi devices.
  virtual void SetSchedScan(bool enable, Error *error);
  std::string GetTechnologyOrder();
  void SetTechnologyOrder(const std::string &order, Error *error);
  // Set up the profile list starting with a default profile along with
  // an (optional) list of startup profiles.
  void InitializeProfiles();
  // Create a profile.  This does not affect the profile stack.  Returns
  // the RPC path of the created profile in |path|.
  void CreateProfile(const std::string &name, std::string *path, Error *error);
  // Pushes existing profile with name |name| onto stack of managed profiles.
  // Returns the RPC path of the pushed profile in |path|.
  void PushProfile(const std::string &name, std::string *path, Error *error);
  // Insert an existing user profile with name |name| into the stack of
  // managed profiles.  Associate |user_hash| with this profile entry.
  // Returns the RPC path of the pushed profile in |path|.
  void InsertUserProfile(const std::string &name,
                         const std::string &user_hash,
                         std::string *path,
                         Error *error);
  // Pops profile named |name| off the top of the stack of managed profiles.
  void PopProfile(const std::string &name, Error *error);
  // Remove the active profile.
  void PopAnyProfile(Error *error);
  // Remove all user profiles from the stack of managed profiles leaving only
  // default profiles.
  void PopAllUserProfiles(Error *error);
  // Remove the underlying persistent storage for a profile.
  void RemoveProfile(const std::string &name, Error *error);
  // Give the ownership of the device with name |device_name| to claimer with
  // name |claimer_name|. This will cause shill to stop managing this device.
  void ClaimDevice(const std::string &claimer_name,
                   const std::string &interface_name,
                   Error *error,
                   const ResultCallback &callback);
  // Claimer |claimer_name| release the ownership of the device with
  // |interface_name| back to shill.
  void ReleaseDevice(const std::string &claimer_name,
                     const std::string &interface_name,
                     Error *error);
  // Called by a service to remove its associated configuration.  If |service|
  // is associated with a non-ephemeral profile, this configuration entry
  // will be removed and the manager will search for another matching profile.
  // If the service ends up with no matching profile, it is unloaded (which
  // may also remove the service from the manager's list, e.g. WiFi services
  // that are not visible)..
  void RemoveService(const ServiceRefPtr &service);
  // Handle the event where a profile is about to remove a profile entry.
  // Any Services that are dependent on this storage identifier will need
  // to find new profiles.  Return true if any service has been moved to a new
  // profile.  Any such services will have had the profile group removed from
  // the profile.
  virtual bool HandleProfileEntryDeletion(const ProfileRefPtr &profile,
                                          const std::string &entry_name);
  // Find a registered service that contains a GUID property that
  // matches |guid|.
  virtual ServiceRefPtr GetServiceWithGUID(const std::string &guid,
                                           Error *error);
  // Find a service that is both the member of |profile| and has a
  // storage identifier that matches |entry_name|.  This function is
  // called by the Profile in order to return a profile entry's properties.
  virtual ServiceRefPtr GetServiceWithStorageIdentifier(
      const ProfileRefPtr &profile,
      const std::string &entry_name,
      Error *error);
  // Create a temporary service for an entry |entry_name| within |profile|.
  // Callers must not register this service with the Manager or connect it
  // since it was never added to the provider's service list.
  virtual ServiceRefPtr CreateTemporaryServiceFromProfile(
      const ProfileRefPtr &profile,
      const std::string &entry_name,
      Error *error);
  // Return a reference to the Service associated with the default connection.
  // If there is no such connection, this function returns a reference to NULL.
  virtual ServiceRefPtr GetDefaultService() const;

  // Set enabled state of all |technology_name| devices to |enabled_state|.
  void SetEnabledStateForTechnology(const std::string &technology_name,
                                    bool enabled_state,
                                    Error *error,
                                    const ResultCallback &callback);
  // Return whether a technology is marked as enabled for portal detection.
  virtual bool IsPortalDetectionEnabled(Technology::Identifier tech);
  // Set the start-up value for the portal detection list.  This list will
  // be used until a value set explicitly over the control API.  Until
  // then, we ignore but do not overwrite whatever value is stored in the
  // profile.
  void SetStartupPortalList(const std::string &portal_list);

  // Returns true if profile |a| has been pushed on the Manager's
  // |profiles_| stack before profile |b|.
  virtual bool IsProfileBefore(const ProfileRefPtr &a,
                               const ProfileRefPtr &b) const;

  // Return whether a service belongs to the ephemeral profile.
  virtual bool IsServiceEphemeral(const ServiceConstRefPtr &service) const;

  // Return whether a Technology has any connected Services.
  virtual bool IsTechnologyConnected(Technology::Identifier technology) const;

  // Return whether a technology is enabled for link monitoring.
  virtual bool IsTechnologyLinkMonitorEnabled(
      Technology::Identifier technology) const;

  // Return whether the Wake on LAN feature is enabled.
  virtual bool IsWakeOnLanEnabled() const { return is_wake_on_lan_enabled_; }

  // Return whether a technology is disabled for auto-connect.
  virtual bool IsTechnologyAutoConnectDisabled(
      Technology::Identifier technology) const;

  // Report whether |technology| is prohibited from being enabled.
  virtual bool IsTechnologyProhibited(Technology::Identifier technology) const;

  // Called by Profile when a |storage| completes initialization.
  void OnProfileStorageInitialized(Profile *storage);

  // Return a Device with technology |technology| in the enabled state.
  virtual DeviceRefPtr GetEnabledDeviceWithTechnology(
      Technology::Identifier technology) const;

  // Return a Device with link_name |link_name| in the enabled state.
  virtual DeviceRefPtr GetEnabledDeviceByLinkName(
      const std::string &link_name) const;

  // Returns true if at least one connection exists, and false if there's no
  // connected service.
  virtual bool IsConnected() const;
  // Returns true if at least one connection exists that have Internet
  // connectivity, and false if there's no such service.
  virtual bool IsOnline() const;
  std::string CalculateState(Error *error);

  // Recalculate the |connected_state_| string and emit a singal if it has
  // changed.
  void RefreshConnectionState();

  virtual int GetPortalCheckInterval() const {
    return props_.portal_check_interval_seconds;
  }
  virtual const std::string &GetPortalCheckURL() const {
    return props_.portal_url;
  }

  DBusManager *dbus_manager() const { return dbus_manager_.get(); }
  virtual DeviceInfo *device_info() { return &device_info_; }
#if !defined(DISABLE_CELLULAR)
  virtual ModemInfo *modem_info() { return &modem_info_; }
#endif  // DISABLE_CELLULAR
  PowerManager *power_manager() const { return power_manager_.get(); }
#if !defined(DISABLE_WIRED_8021X)
  virtual EthernetEapProvider *ethernet_eap_provider() const {
    return ethernet_eap_provider_.get();
  }
#endif  // DISABLE_WIRED_8021X
  VPNProvider *vpn_provider() const { return vpn_provider_.get(); }
#if !defined(DISABLE_WIFI)
  WiFiProvider *wifi_provider() const { return wifi_provider_.get(); }
#endif  // DISABLE_WIFI
#if !defined(DISABLE_WIMAX)
  virtual WiMaxProvider *wimax_provider() { return wimax_provider_.get(); }
#endif  // DISABLE_WIMAX
  PropertyStore *mutable_store() { return &store_; }
  virtual const PropertyStore &store() const { return store_; }
  GLib *glib() const { return glib_; }
  virtual const base::FilePath &run_path() const { return run_path_; }
  const base::FilePath &storage_path() const { return storage_path_; }
  IPAddressStore * health_checker_remote_ips() const {
    return health_checker_remote_ips_.get();
  }

  bool GetArpGateway() const { return props_.arp_gateway; }
  const std::string &GetHostName() const { return props_.host_name; }

  virtual int GetMinimumMTU() const { return props_.minimum_mtu; }
  void SetMinimumMTU(const int mtu) { props_.minimum_mtu = mtu; }

  virtual void UpdateEnabledTechnologies();
  virtual void UpdateUninitializedTechnologies();

  // Writes the service |to_update| to persistant storage.  If the service's is
  // ephemeral, it is moved to the current profile.
  void SaveServiceToProfile(const ServiceRefPtr &to_update);

  // Adds a closure to be executed when ChromeOS suspends or shill terminates.
  // |name| should be unique; otherwise, a previous closure by the same name
  // will be replaced.  |start| will be called when RunTerminationActions() is
  // called.  When an action completed, TerminationActionComplete() must be
  // called.
  void AddTerminationAction(const std::string &name,
                            const base::Closure &start);

  // Users call this function to report the completion of an action |name|.
  // This function should be called once for each action.
  void TerminationActionComplete(const std::string &name);

  // Removes the action associtated with |name|.
  void RemoveTerminationAction(const std::string &name);

  // Runs the termination actions and notifies the metrics framework
  // that the termination actions started running, only if any termination
  // actions have been registered. If all actions complete within
  // |kTerminationActionsTimeoutMilliseconds|, |done_callback| is called with a
  // value of Error::kSuccess. Otherwise, it is called with
  // Error::kOperationTimeout.
  //
  // Returns true, if termination actions were run.
  bool RunTerminationActionsAndNotifyMetrics(
      const ResultCallback &done_callback);

  // Registers a |callback| that's invoked whenever the default service
  // changes. Returns a unique tag that can be used to deregister the
  // callback. A tag equal to 0 is invalid.
  virtual int RegisterDefaultServiceCallback(const ServiceCallback &callback);
  virtual void DeregisterDefaultServiceCallback(int tag);

#if !defined(DISABLE_WIFI)
  // Verifies that the destination described by certificate is valid, and that
  // we're currently connected to that destination.  A full description of the
  // rules being enforced is in doc/manager-api.txt.  Returns true iff all
  // checks pass, false otherwise.  On false, error is filled with a
  // descriptive error code and message.
  //
  // |certificate| is a PEM encoded x509 certificate, |public_key| is a base64
  // encoded public half of an RSA key, |nonce| is a random string, and
  // |signed_data| is a base64 encoded string as described in
  // doc/manager-api.txt.
  void VerifyDestination(const std::string &certificate,
                         const std::string &public_key,
                         const std::string &nonce,
                         const std::string &signed_data,
                         const std::string &destination_udn,
                         const std::string &hotspot_ssid,
                         const std::string &hotspot_bssid,
                         const ResultBoolCallback &cb,
                         Error *error);

  // After verifying the destination, encrypt the string data with
  // |public_key|, the base64 encoded public half of an RSA key pair.  Returns
  // the base64 encoded result if successful, or an empty string on failure.
  // On failure, |error| will be filled with an appropriately descriptive
  // message and error code.
  void VerifyAndEncryptData(const std::string &certificate,
                            const std::string &public_key,
                            const std::string &nonce,
                            const std::string &signed_data,
                            const std::string &destination_udn,
                            const std::string &hotspot_ssid,
                            const std::string &hotspot_bssid,
                            const std::string &data,
                            const ResultStringCallback &cb,
                            Error *error);

  // After verifying the destination, encrypt the password for |network_path|
  // under |public_key|.  Similar to EncryptData above except that the
  // information being encrypted is implicitly the authentication credentials
  // of the given network.
  void VerifyAndEncryptCredentials(const std::string &certificate,
                                   const std::string &public_key,
                                   const std::string &nonce,
                                   const std::string &signed_data,
                                   const std::string &destination_udn,
                                   const std::string &hotspot_ssid,
                                   const std::string &hotspot_bssid,
                                   const std::string &network_path,
                                   const ResultStringCallback &cb,
                                   Error *error);
#endif  // DISABLE_WIFI

  // Calculate connection identifier, which is hash of salt value, gateway IP
  // address, and gateway MAC address.
  int CalcConnectionId(std::string gateway_ip, std::string gateway_mac);

  // Report the number of services associated with given connection
  // |connection_id|.
  void ReportServicesOnSameNetwork(int connection_id);

  // Running in passive mode, manager will not manage any devices (all devices
  // are blacklisted) by default. Remote application can specify devices for
  // shill to manage through ReleaseInterface/ClaimInterface DBus API using
  // default claimer (with "" as claimer_name).
  void SetPassiveMode();

  // Decides whether Ethernet-like devices are treated as unknown devices
  // if they do not indicate a driver name.
  void SetIgnoreUnknownEthernet(bool ignore);
  bool ignore_unknown_ethernet() const { return ignore_unknown_ethernet_; }

  // Set the list of prepended DNS servers to |prepend_dns_servers|.
  void SetPrependDNSServers(const std::string &prepend_dns_servers);

  // Accept hostname from DHCP server for devices matching |hostname_from|.
  void SetAcceptHostnameFrom(const std::string &hostname_from);
  virtual bool ShouldAcceptHostnameFrom(const std::string &device_name) const;

  // Filter the list of prepended DNS servers, copying only those that match
  // |family| into |dns_servers|.  |dns_servers| is cleared, regardless of
  // whether or not there are any addresses that match |family|.
  virtual void FilterPrependDNSServersByFamily(
      const IPAddress::Family family,
      std::vector<std::string> *dns_servers);

  // Returns true iff |power_manager_| exists and is suspending (i.e.
  // power_manager->suspending() is true), false otherwise.
  virtual bool IsSuspending();

  void set_suppress_autoconnect(bool val) { suppress_autoconnect_ = val; }
  bool suppress_autoconnect() { return suppress_autoconnect_; }

  void RecordDarkResumeWakeReason(const std::string &wake_reason);

 private:
  friend class CellularTest;
  friend class DeviceInfoTest;
  friend class ManagerAdaptorInterface;
  friend class ManagerTest;
  friend class ModemInfoTest;
  friend class ModemManagerTest;
  friend class ServiceTest;
  friend class VPNServiceTest;
  friend class WiFiObjectTest;
  friend class WiMaxProviderTest;

  FRIEND_TEST(CellularCapabilityUniversalMainTest, TerminationAction);
  FRIEND_TEST(CellularCapabilityUniversalMainTest,
              TerminationActionRemovedByStopModem);
  FRIEND_TEST(CellularTest, LinkEventWontDestroyService);
  FRIEND_TEST(DeviceTest, StartProhibited);
  FRIEND_TEST(ManagerTest, AvailableTechnologies);
  FRIEND_TEST(ManagerTest, ClaimDeviceWhenClaimerNotVerified);
  FRIEND_TEST(ManagerTest, ClaimDeviceWithoutClaimer);
  FRIEND_TEST(ManagerTest, ConnectedTechnologies);
  FRIEND_TEST(ManagerTest, ConnectionStatusCheck);
  FRIEND_TEST(ManagerTest, ConnectToBestServices);
  FRIEND_TEST(ManagerTest, CreateConnectivityReport);
  FRIEND_TEST(ManagerTest, DefaultTechnology);
  FRIEND_TEST(ManagerTest, DetectMultiHomedDevices);
  FRIEND_TEST(ManagerTest, DeviceClaimerVanishedTask);
  FRIEND_TEST(ManagerTest, DevicePresenceStatusCheck);
  FRIEND_TEST(ManagerTest, DeviceRegistrationAndStart);
  FRIEND_TEST(ManagerTest, DisableTechnology);
  FRIEND_TEST(ManagerTest, EnableTechnology);
  FRIEND_TEST(ManagerTest, EnumerateProfiles);
  FRIEND_TEST(ManagerTest, HandleProfileEntryDeletionWithUnload);
  FRIEND_TEST(ManagerTest, InitializeProfilesInformsProviders);
  FRIEND_TEST(ManagerTest, InitializeProfilesHandlesDefaults);
  FRIEND_TEST(ManagerTest, IsDefaultProfile);
  FRIEND_TEST(ManagerTest, IsTechnologyAutoConnectDisabled);
  FRIEND_TEST(ManagerTest, IsTechnologyProhibited);
  FRIEND_TEST(ManagerTest, IsWifiIdle);
  FRIEND_TEST(ManagerTest, LinkMonitorEnabled);
  FRIEND_TEST(ManagerTest, MoveService);
  FRIEND_TEST(ManagerTest, NotifyDefaultServiceChanged);
  FRIEND_TEST(ManagerTest, OnDeviceClaimerAppeared);
  FRIEND_TEST(ManagerTest, PopProfileWithUnload);
  FRIEND_TEST(ManagerTest, RegisterKnownService);
  FRIEND_TEST(ManagerTest, RegisterUnknownService);
  FRIEND_TEST(ManagerTest, ReleaseDevice);
  FRIEND_TEST(ManagerTest, RunTerminationActions);
  FRIEND_TEST(ManagerTest, ServiceRegistration);
  FRIEND_TEST(ManagerTest, SortServicesWithConnection);
  FRIEND_TEST(ManagerTest, StartupPortalList);
  FRIEND_TEST(ServiceTest, IsAutoConnectable);

  struct DeviceClaim {
    DeviceClaim() {}
    DeviceClaim(const std::string &in_device_name,
                const ResultCallback &in_result_callback)
        : device_name(in_device_name),
          result_callback(in_result_callback) {}
    std::string device_name;
    ResultCallback result_callback;
  };

  static const char kErrorNoDevice[];
  static const char kErrorTypeRequired[];
  static const char kErrorUnsupportedServiceType[];

  // Technologies to probe for.
  static const char *kProbeTechnologies[];

  // Name of the default claimer.
  static const char kDefaultClaimerName[];

  // Timeout interval for probing various device status, and report them to
  // UMA stats.
  static const int kDeviceStatusCheckIntervalMilliseconds;
  // Time to wait for termination actions to complete.
  static const int kTerminationActionsTimeoutMilliseconds;

  void AutoConnect();
  std::vector<std::string> AvailableTechnologies(Error *error);
  std::vector<std::string> ConnectedTechnologies(Error *error);
  std::string DefaultTechnology(Error *error);
  std::vector<std::string> EnabledTechnologies(Error *error);
  std::vector<std::string> UninitializedTechnologies(Error *error);
  RpcIdentifiers EnumerateDevices(Error *error);
  RpcIdentifiers EnumerateProfiles(Error *error);
  RpcIdentifiers EnumerateWatchedServices(Error *error);
  std::string GetActiveProfileRpcIdentifier(Error *error);
  std::string GetCheckPortalList(Error *error);
  RpcIdentifier GetDefaultServiceRpcIdentifier(Error *error);
  std::string GetIgnoredDNSSearchPaths(Error *error);
  ServiceRefPtr GetServiceInner(const KeyValueStore &args, Error *error);
  bool SetCheckPortalList(const std::string &portal_list, Error *error);
  bool SetIgnoredDNSSearchPaths(const std::string &ignored_paths, Error *error);
  void EmitDefaultService();
  bool IsTechnologyInList(const std::string &technology_list,
                          Technology::Identifier tech) const;
  void EmitDeviceProperties();
#if !defined(DISABLE_WIFI)
  bool SetDisableWiFiVHT(const bool &disable_wifi_vht, Error *error);
  bool GetDisableWiFiVHT(Error *error);
#endif  // DISABLE_WIFI
  bool SetProhibitedTechnologies(const std::string &prohibited_technologies,
                                 Error *error);
  std::string GetProhibitedTechnologies(Error *error);
  void OnTechnologyProhibited(Technology::Identifier technology,
                              const Error &error);

  // For every device instance that is sharing the same connectivity with
  // another device, enable the multi-home flag.
  void DetectMultiHomedDevices();

  // Unload a service while iterating through |services_|.  Returns true if
  // service was erased (which means the caller loop should not increment
  // |service_iterator|), false otherwise (meaning the caller should
  // increment |service_iterator|).
  bool UnloadService(std::vector<ServiceRefPtr>::iterator *service_iterator);

  // Load Manager default properties from |profile|.
  void LoadProperties(const scoped_refptr<DefaultProfile> &profile);

  // Configure the device with profile data from all current profiles.
  void LoadDeviceFromProfiles(const DeviceRefPtr &device);

  void HelpRegisterConstDerivedRpcIdentifier(
      const std::string &name,
      RpcIdentifier(Manager::*get)(Error *));
  void HelpRegisterConstDerivedRpcIdentifiers(
      const std::string &name,
      RpcIdentifiers(Manager::*get)(Error *));
  void HelpRegisterDerivedString(
      const std::string &name,
      std::string(Manager::*get)(Error *error),
      bool(Manager::*set)(const std::string&, Error *));
  void HelpRegisterConstDerivedStrings(
      const std::string &name,
      Strings(Manager::*get)(Error *));
  void HelpRegisterDerivedBool(
      const std::string &name,
      bool(Manager::*get)(Error *error),
      bool(Manager::*set)(const bool &value, Error *error));

  bool HasProfile(const Profile::Identifier &ident);
  void PushProfileInternal(const Profile::Identifier &ident,
                           std::string *path,
                           Error *error);
  void PopProfileInternal();
  void OnProfilesChanged();

  void SortServices();
  void SortServicesTask();
  void DeviceStatusCheckTask();
  void ConnectionStatusCheck();
  void DevicePresenceStatusCheck();

  bool MatchProfileWithService(const ServiceRefPtr &service);

  // Sets the profile of |service| to |profile|, without notifying its
  // previous profile.  Configures a |service| with |args|, then saves
  // the resulting configuration to |profile|.  This method is useful
  // when copying a service configuration from one profile to another,
  // or writing a newly created service config to a specific profile.
  static void SetupServiceInProfile(ServiceRefPtr service,
                                    ProfileRefPtr profile,
                                    const KeyValueStore &args,
                                    Error *error);

  // For each technology present, connect to the "best" service available,
  // as determined by sorting all services independent of their current state.
  void ConnectToBestServicesTask();

  void NotifyDefaultServiceChanged(const ServiceRefPtr &service);

  // Runs the termination actions.  If all actions complete within
  // |kTerminationActionsTimeoutMilliseconds|, |done_callback| is called with a
  // value of Error::kSuccess.  Otherwise, it is called with
  // Error::kOperationTimeout.
  void RunTerminationActions(const ResultCallback &done_callback);

  // Called when the system is about to be suspended.  Each call will be
  // followed by a call to OnSuspendDone().
  void OnSuspendImminent();

  // Called when the system has completed a suspend attempt (possibly without
  // actually suspending, in the event of the user canceling the attempt).
  void OnSuspendDone();

  // Called when the system is entering a dark resume phase (and hence a dark
  // suspend is imminent).
  void OnDarkSuspendImminent();

  void OnSuspendActionsComplete(const Error &error);
  void OnDarkResumeActionsComplete(const Error &error);

#if !defined(DISABLE_WIFI)
  void VerifyToEncryptLink(std::string public_key, std::string data,
                           ResultStringCallback cb, const Error &error,
                           bool success);
#endif  // DISABLE_WIFI

  // Return true if wifi device is enabled with no existing connection (pending
  // or connected).
  bool IsWifiIdle();

  // For unit testing.
  void set_metrics(Metrics *metrics) { metrics_ = metrics; }
  void UpdateProviderMapping();

  // Used by tests to set a mock PowerManager.  Takes ownership of
  // power_manager.
  void set_power_manager(PowerManager *power_manager) {
    power_manager_.reset(power_manager);
  }

  DeviceRefPtr GetDeviceConnectedToService(ServiceRefPtr service);

  // Called when the DBus service that claimed ownership of devices from shill
  // appear/vanish from the DBus connection.
  void OnDeviceClaimerAppeared(const std::string &/*name*/,
                                    const std::string &owner);
  void OnDeviceClaimerVanished(const std::string &/*name*/);
  // Task for cleanup device claimer when it is vanished.
  void DeviceClaimerVanishedTask();

  void DeregisterDeviceByLinkName(const std::string &link_name);

  // Returns the names of all of the devices that have been claimed by the
  // current DeviceClaimer.  Returns an empty vector if no DeviceClaimer is set.
  std::vector<std::string> ClaimedDevices(Error *error);

  EventDispatcher *dispatcher_;
  const base::FilePath run_path_;
  const base::FilePath storage_path_;
  const std::string user_storage_path_;
  base::FilePath user_profile_list_path_;  // Changed in tests.
  std::unique_ptr<ManagerAdaptorInterface> adaptor_;
  std::unique_ptr<DBusManager> dbus_manager_;
  DeviceInfo device_info_;
#if !defined(DISABLE_CELLULAR)
  ModemInfo modem_info_;
#endif  // DISABLE_CELLULAR
#if !defined(DISABLE_WIRED_8021X)
  std::unique_ptr<EthernetEapProvider> ethernet_eap_provider_;
#endif  // DISABLE_WIRED_8021X
  std::unique_ptr<VPNProvider> vpn_provider_;
#if !defined(DISABLE_WIFI)
  std::unique_ptr<WiFiProvider> wifi_provider_;
#endif  // DISABLE_WIFI
#if !defined(DISABLE_WIMAX)
  std::unique_ptr<WiMaxProvider> wimax_provider_;
#endif  // DISABLE_WIMAX
  // Hold pointer to singleton Resolver instance for testing purposes.
  Resolver *resolver_;
  bool running_;
  // Used to facilitate unit tests which can't use RPC.
  bool connect_profiles_to_rpc_;
  std::vector<DeviceRefPtr> devices_;
  // We store Services in a vector, because we want to keep them sorted.
  // Services that are connected appear first in the vector.  See
  // Service::Compare() for details of the sorting criteria.
  std::vector<ServiceRefPtr> services_;
  // Map of technologies to Provider instances.  These pointers are owned
  // by the respective scoped_reptr objects that are held over the lifetime
  // of the Manager object.
  std::map<Technology::Identifier, ProviderInterface *> providers_;
  // List of startup profile names to push on the profile stack on startup.
  std::vector<ProfileRefPtr> profiles_;
  ProfileRefPtr ephemeral_profile_;
  ControlInterface *control_interface_;
  Metrics *metrics_;
  GLib *glib_;
  std::unique_ptr<PowerManager> power_manager_;
  std::unique_ptr<Upstart> upstart_;

  // The priority order of technologies
  std::vector<Technology::Identifier> technology_order_;

  // This is the last Service RPC Identifier for which we emitted a
  // "DefaultService" signal for.
  RpcIdentifier default_service_rpc_identifier_;

  // Manager can be optionally configured with a list of technologies to
  // do portal detection on at startup.  We need to keep track of that list
  // as well as a flag that tells us whether we should continue using it
  // instead of the configured portal list.
  std::string startup_portal_list_;
  bool use_startup_portal_list_;

  // Properties to be get/set via PropertyStore calls.
  Properties props_;
  PropertyStore store_;

  // Accept hostname supplied by the DHCP server from the specified devices.
  // eg. eth0 or eth*
  std::string accept_hostname_from_;

  base::CancelableClosure sort_services_task_;

  // Task for periodically checking various device status.
  base::CancelableClosure device_status_check_task_;

  // TODO(petkov): Currently this handles both terminate and suspend
  // actions. Rename all relevant identifiers to capture this.
  HookTable termination_actions_;

  // Is a suspend delay currently registered with the power manager?
  bool suspend_delay_registered_;

  // Whether Wake on LAN should be enabled for all Ethernet devices.
  bool is_wake_on_lan_enabled_;

  // Whether to ignore Ethernet-like devices that don't have an assigned driver.
  bool ignore_unknown_ethernet_;

  // Maps tags to callbacks for monitoring default service changes.
  std::map<int, ServiceCallback> default_service_callbacks_;
  int default_service_callback_tag_;

  // Delegate to handle destination verification operations for the manager.
  std::unique_ptr<CryptoUtilProxy> crypto_util_proxy_;

  // Stores IP addresses of some remote hosts that accept port 80 TCP
  // connections. ConnectionHealthChecker uses these IPs.
  // The store resides in Manager so that it persists across Device reset.
  std::unique_ptr<IPAddressStore> health_checker_remote_ips_;

  // Stores the most recent copy of geolocation information for each
  // technology type.
  std::map<std::string, GeolocationInfos> networks_for_geolocation_;

  // Stores the state of the highest ranked connected service.
  std::string connection_state_;

  // Stores the most recent state of all watched services.
  std::map<std::string, Service::ConnectState> watched_service_states_;

  // Device claimer is a remote application/service that claim/release devices
  // from/to shill. To reduce complexity, only allow one device claimer at a
  // time.
  std::unique_ptr<DeviceClaimer> device_claimer_;
  std::vector<DeviceClaim> pending_device_claims_;

  // When true, suppresses autoconnects in Manager::AutoConnect.
  bool suppress_autoconnect_;

  // Whether any of the services is in connected state or not.
  bool is_connected_state_;

  DISALLOW_COPY_AND_ASSIGN(Manager);
};

}  // namespace shill

#endif  // SHILL_MANAGER_H_
