blob: 6204c6336f6c556d30c332e32d402ad14505ecad [file] [log] [blame]
// Copyright 2017 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.
#ifndef CHROMEOS_COMPONENTS_TETHER_HOST_CONNECTION_METRICS_LOGGER_H_
#define CHROMEOS_COMPONENTS_TETHER_HOST_CONNECTION_METRICS_LOGGER_H_
#include <map>
#include <string>
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "chromeos/components/tether/active_host.h"
#include "chromeos/components/tether/ble_connection_manager.h"
namespace base {
class Clock;
}
namespace chromeos {
namespace tether {
// Wrapper around metrics reporting for host connection results. Clients are
// expected to report the result of a host connection attempt once it has
// concluded.
class HostConnectionMetricsLogger
: public BleConnectionManager::MetricsObserver,
public ActiveHost::Observer {
public:
enum ConnectionToHostResult {
CONNECTION_RESULT_PROVISIONING_FAILED,
CONNECTION_RESULT_SUCCESS,
CONNECTION_RESULT_FAILURE_UNKNOWN_ERROR,
CONNECTION_RESULT_FAILURE_CLIENT_CONNECTION_TIMEOUT,
CONNECTION_RESULT_FAILURE_CLIENT_CONNECTION_CANCELED_BY_USER,
CONNECTION_RESULT_FAILURE_CLIENT_CONNECTION_INTERNAL_ERROR,
CONNECTION_RESULT_FAILURE_TETHERING_TIMED_OUT_FIRST_TIME_SETUP_WAS_REQUIRED,
CONNECTION_RESULT_FAILURE_TETHERING_TIMED_OUT_FIRST_TIME_SETUP_WAS_NOT_REQUIRED,
CONNECTION_RESULT_FAILURE_TETHERING_UNSUPPORTED,
CONNECTION_RESULT_FAILURE_NO_CELL_DATA,
CONNECTION_RESULT_FAILURE_ENABLING_HOTSPOT_FAILED,
CONNECTION_RESULT_FAILURE_ENABLING_HOTSPOT_TIMEOUT,
CONNECTION_RESULT_FAILURE_NO_RESPONSE,
CONNECTION_RESULT_FAILURE_INVALID_HOTSPOT_CREDENTIALS
};
// Record the result of an attempted host connection.
virtual void RecordConnectionToHostResult(ConnectionToHostResult result,
const std::string& device_id);
HostConnectionMetricsLogger(BleConnectionManager* connection_manager,
ActiveHost* active_host);
virtual ~HostConnectionMetricsLogger();
protected:
// BleConnectionManager::MetricsObserver:
void OnAdvertisementReceived(const std::string& device_id,
bool is_background_advertisement) override;
// ActiveHost::Observer:
void OnActiveHostChanged(
const ActiveHost::ActiveHostChangeInfo& change_info) override;
private:
friend class HostConnectionMetricsLoggerTest;
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectionResultProvisioningFailure);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectionResultSuccess);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectionResultSuccess_Background);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectionResultSuccess_MultiDeviceApiEnabled);
FRIEND_TEST_ALL_PREFIXES(
HostConnectionMetricsLoggerTest,
RecordConnectionResultSuccess_Background_DifferentDevice);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectionResultFailure);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectionResultFailure_Background);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectionResultFailure_MultiDeviceApiEnabled);
FRIEND_TEST_ALL_PREFIXES(
HostConnectionMetricsLoggerTest,
RecordConnectionResultFailure_Background_DifferentDevice);
FRIEND_TEST_ALL_PREFIXES(
HostConnectionMetricsLoggerTest,
RecordConnectionResultFailureClientConnection_Timeout);
FRIEND_TEST_ALL_PREFIXES(
HostConnectionMetricsLoggerTest,
RecordConnectionResultFailureClientConnection_CanceledByUser);
FRIEND_TEST_ALL_PREFIXES(
HostConnectionMetricsLoggerTest,
RecordConnectionResultFailureClientConnection_InternalError);
FRIEND_TEST_ALL_PREFIXES(
HostConnectionMetricsLoggerTest,
RecordConnectionResultFailureTetheringTimeout_SetupRequired);
FRIEND_TEST_ALL_PREFIXES(
HostConnectionMetricsLoggerTest,
RecordConnectionResultFailureTetheringTimeout_SetupNotRequired);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectionResultFailureTetheringUnsupported);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectionResultFailureNoCellData);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectionResultFailureEnablingHotspotFailed);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectionResultFailureEnablingHotspotTimeout);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectToHostDuration);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectToHostDuration_Background);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectToHostDuration_MultiDeviceApiEnabled);
FRIEND_TEST_ALL_PREFIXES(HostConnectionMetricsLoggerTest,
RecordConnectionResultFailureNoResponse);
FRIEND_TEST_ALL_PREFIXES(
HostConnectionMetricsLoggerTest,
RecordConnectionResultFailureInvalidHotspotCredentials);
// An Instant Tethering connection can fail for several different reasons.
// Though traditionally success and each failure case would be logged to a
// single enum, we have chosen to start at a top-level of view of simply
// "success vs failure", and then iteratively breaking down the failure count
// into its types (and possibly sub-types). Because of this cascading nature,
// when a failure sub-type occurs, the code path in question must report that
// sub-type as well as all the super-types above it. This would be cumbersome,
// and thus HostConnectionMetricsLogger exists to provide a simple API which
// handles all the other metrics that need to be reported.
//
// The most top-level metric is
// InstantTethering.ConnectionToHostResult.ProvisioningFailureRate. Its
// breakdown, and the breakdown of its subsquent metrics, is described in
// tools/metrics/histograms/histograms.xml.
enum ConnectionToHostResult_ProvisioningFailureEventType {
PROVISIONING_FAILED = 0,
OTHER = 1,
PROVISIONING_FAILURE_MAX
};
enum ConnectionToHostResult_SuccessEventType {
SUCCESS = 0,
FAILURE = 1,
SUCCESS_MAX
};
enum ConnectionToHostResult_FailureEventType {
UNKNOWN_ERROR = 0,
TETHERING_TIMED_OUT = 1,
CLIENT_CONNECTION_ERROR = 2,
TETHERING_UNSUPPORTED = 3,
NO_CELL_DATA = 4,
ENABLING_HOTSPOT_FAILED = 5,
ENABLING_HOTSPOT_TIMEOUT = 6,
NO_RESPONSE = 7,
INVALID_HOTSPOT_CREDENTIALS = 8,
FAILURE_MAX
};
enum ConnectionToHostResult_FailureClientConnectionEventType {
TIMEOUT = 0,
CANCELED_BY_USER = 1,
INTERNAL_ERROR = 2,
FAILURE_CLIENT_CONNECTION_MAX
};
enum ConnectionToHostResult_FailureTetheringTimeoutEventType {
FIRST_TIME_SETUP_WAS_REQUIRED = 0,
FIRST_TIME_SETUP_WAS_NOT_REQUIRED = 1,
FAILURE_TETHERING_TIMEOUT_MAX
};
// Record if a host connection attempt never went through due to provisioning
// failure, or otherwise continued.
void RecordConnectionResultProvisioningFailure(
ConnectionToHostResult_ProvisioningFailureEventType event_type);
// Record if a host connection attempt succeeded or failed. Failure is
// covered by the RecordConnectionResultFailure() method.
void RecordConnectionResultSuccess(
ConnectionToHostResult_SuccessEventType event_type);
// Record how a host connection attempt failed. Failure due to client error or
// tethering timeout is covered by the
// RecordConnectionResultFailureClientConnection() or
// RecordConnectionResultFailureTetheringTimeout() methods, respectively.
void RecordConnectionResultFailure(
ConnectionToHostResult_FailureEventType event_type);
// Record how a host connection attempt failed due to a client error.
void RecordConnectionResultFailureClientConnection(
ConnectionToHostResult_FailureClientConnectionEventType event_type);
// Record the conditions of when host connection attempt failed due to
// the host timing out during tethering.
void RecordConnectionResultFailureTetheringTimeout(
ConnectionToHostResult_FailureTetheringTimeoutEventType event_type);
void RecordConnectToHostDuration(const std::string device_id);
void SetClockForTesting(base::Clock* test_clock);
BleConnectionManager* connection_manager_;
ActiveHost* active_host_;
base::Clock* clock_;
std::map<std::string, bool> device_id_to_received_background_advertisement_;
base::Time connect_to_host_start_time_;
std::string active_host_device_id_;
DISALLOW_COPY_AND_ASSIGN(HostConnectionMetricsLogger);
};
} // namespace tether
} // namespace chromeos
#endif // CHROMEOS_COMPONENTS_TETHER_HOST_CONNECTION_METRICS_LOGGER_H_