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

#include "components/signin/core/browser/signin_metrics.h"

#include <limits.h>

#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/numerics/safe_conversions.h"
#include "base/time/time.h"

namespace signin_metrics {

namespace {
void RecordSigninUserActionForAccessPoint(AccessPoint access_point) {
  switch (access_point) {
    case AccessPoint::ACCESS_POINT_START_PAGE:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromStartPage"));
      break;
    case AccessPoint::ACCESS_POINT_NTP_LINK:
      base::RecordAction(base::UserMetricsAction("Signin_Signin_FromNTP"));
      break;
    case AccessPoint::ACCESS_POINT_MENU:
      base::RecordAction(base::UserMetricsAction("Signin_Signin_FromMenu"));
      break;
    case AccessPoint::ACCESS_POINT_SETTINGS:
      base::RecordAction(base::UserMetricsAction("Signin_Signin_FromSettings"));
      break;
    case AccessPoint::ACCESS_POINT_SUPERVISED_USER:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromSupervisedUser"));
      break;
    case AccessPoint::ACCESS_POINT_EXTENSION_INSTALL_BUBBLE:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromExtensionInstallBubble"));
      break;
    case AccessPoint::ACCESS_POINT_EXTENSIONS:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromExtensions"));
      break;
    case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromAppsPageLink"));
      break;
    case AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromBookmarkBubble"));
      break;
    case AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromBookmarkManager"));
      break;
    case AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromAvatarBubbleSignin"));
      break;
    case AccessPoint::ACCESS_POINT_USER_MANAGER:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromUserManager"));
      break;
    case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromDevicesPage"));
      break;
    case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromCloudPrint"));
      break;
    case AccessPoint::ACCESS_POINT_CONTENT_AREA:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromContentArea"));
      break;
    case AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromSigninPromo"));
      break;
    case AccessPoint::ACCESS_POINT_RECENT_TABS:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromRecentTabs"));
      break;
    case AccessPoint::ACCESS_POINT_UNKNOWN:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromUnknownAccessPoint"));
      break;
    case AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromPasswordBubble"));
      break;
    case AccessPoint::ACCESS_POINT_AUTOFILL_DROPDOWN:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromAutofillDropdown"));
      break;
    case AccessPoint::ACCESS_POINT_NTP_CONTENT_SUGGESTIONS:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromNTPContentSuggestions"));
      break;
    case AccessPoint::ACCESS_POINT_RESIGNIN_INFOBAR:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromReSigninInfobar"));
      break;
    case AccessPoint::ACCESS_POINT_TAB_SWITCHER:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromTabSwitcher"));
      break;
    case AccessPoint::ACCESS_POINT_SAVE_CARD_BUBBLE:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromSaveCardBubble"));
      break;
    case AccessPoint::ACCESS_POINT_MANAGE_CARDS_BUBBLE:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromManageCardsBubble"));
      break;
    case AccessPoint::ACCESS_POINT_MACHINE_LOGON:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromMachineLogon"));
      break;
    case AccessPoint::ACCESS_POINT_GOOGLE_SERVICES_SETTINGS:
      base::RecordAction(
          base::UserMetricsAction("Signin_Signin_FromGoogleServicesSettings"));
      break;
    case AccessPoint::ACCESS_POINT_MAX:
      NOTREACHED();
      break;
  }
}

void RecordSigninWithDefaultUserActionForAccessPoint(
    signin_metrics::AccessPoint access_point) {
  switch (access_point) {
    case signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS:
      base::RecordAction(
          base::UserMetricsAction("Signin_SigninWithDefault_FromSettings"));
      break;
    case AccessPoint::ACCESS_POINT_EXTENSION_INSTALL_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninWithDefault_FromExtensionInstallBubble"));
      break;
    case AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninWithDefault_FromBookmarkBubble"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninWithDefault_FromBookmarkManager"));
      break;
    case AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninWithDefault_FromAvatarBubbleSignin"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS:
      base::RecordAction(
          base::UserMetricsAction("Signin_SigninWithDefault_FromRecentTabs"));
      break;
    case AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninWithDefault_FromPasswordBubble"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_TAB_SWITCHER:
      base::RecordAction(
          base::UserMetricsAction("Signin_SigninWithDefault_FromTabSwitcher"));
      break;
    case AccessPoint::ACCESS_POINT_NTP_CONTENT_SUGGESTIONS:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninWithDefault_FromNTPContentSuggestions"));
      break;
    case AccessPoint::ACCESS_POINT_SAVE_CARD_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninWithDefault_FromSaveCardBubble"));
      break;
    case AccessPoint::ACCESS_POINT_MANAGE_CARDS_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninWithDefault_FromManageCardsBubble"));
      break;
    case AccessPoint::ACCESS_POINT_START_PAGE:
    case AccessPoint::ACCESS_POINT_NTP_LINK:
    case AccessPoint::ACCESS_POINT_MENU:
    case AccessPoint::ACCESS_POINT_SUPERVISED_USER:
    case AccessPoint::ACCESS_POINT_EXTENSIONS:
    case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
    case AccessPoint::ACCESS_POINT_USER_MANAGER:
    case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
    case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
    case AccessPoint::ACCESS_POINT_CONTENT_AREA:
    case AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
    case AccessPoint::ACCESS_POINT_AUTOFILL_DROPDOWN:
    case AccessPoint::ACCESS_POINT_RESIGNIN_INFOBAR:
    case AccessPoint::ACCESS_POINT_UNKNOWN:
    case AccessPoint::ACCESS_POINT_MACHINE_LOGON:
    case AccessPoint::ACCESS_POINT_GOOGLE_SERVICES_SETTINGS:
      NOTREACHED() << "Signin_SigninWithDefault_From* user actions"
                   << " are not recorded for access_point "
                   << static_cast<int>(access_point)
                   << " as it does not support a personalized sign-in promo.";
      break;
    case AccessPoint::ACCESS_POINT_MAX:
      NOTREACHED();
      break;
  }
}

void RecordSigninNotDefaultUserActionForAccessPoint(
    signin_metrics::AccessPoint access_point) {
  switch (access_point) {
    case signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS:
      base::RecordAction(
          base::UserMetricsAction("Signin_SigninNotDefault_FromSettings"));
      break;
    case AccessPoint::ACCESS_POINT_EXTENSION_INSTALL_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNotDefault_FromExtensionInstallBubble"));
      break;
    case AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNotDefault_FromBookmarkBubble"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNotDefault_FromBookmarkManager"));
      break;
    case AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNotDefault_FromAvatarBubbleSignin"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS:
      base::RecordAction(
          base::UserMetricsAction("Signin_SigninNotDefault_FromRecentTabs"));
      break;
    case AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNotDefault_FromPasswordBubble"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_TAB_SWITCHER:
      base::RecordAction(
          base::UserMetricsAction("Signin_SigninNotDefault_FromTabSwitcher"));
      break;
    case AccessPoint::ACCESS_POINT_NTP_CONTENT_SUGGESTIONS:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNotDefault_FromNTPContentSuggestions"));
      break;
    case AccessPoint::ACCESS_POINT_SAVE_CARD_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNotDefault_FromSaveCardBubble"));
      break;
    case AccessPoint::ACCESS_POINT_MANAGE_CARDS_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNotDefault_FromManageCardsBubble"));
      break;
    case AccessPoint::ACCESS_POINT_START_PAGE:
    case AccessPoint::ACCESS_POINT_NTP_LINK:
    case AccessPoint::ACCESS_POINT_MENU:
    case AccessPoint::ACCESS_POINT_SUPERVISED_USER:
    case AccessPoint::ACCESS_POINT_EXTENSIONS:
    case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
    case AccessPoint::ACCESS_POINT_USER_MANAGER:
    case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
    case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
    case AccessPoint::ACCESS_POINT_CONTENT_AREA:
    case AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
    case AccessPoint::ACCESS_POINT_AUTOFILL_DROPDOWN:
    case AccessPoint::ACCESS_POINT_RESIGNIN_INFOBAR:
    case AccessPoint::ACCESS_POINT_UNKNOWN:
    case AccessPoint::ACCESS_POINT_MACHINE_LOGON:
    case AccessPoint::ACCESS_POINT_GOOGLE_SERVICES_SETTINGS:
      NOTREACHED() << "Signin_SigninNotDefault_From* user actions"
                   << " are not recorded for access point "
                   << static_cast<int>(access_point)
                   << " as it does not support a personalized sign-in promo.";
      break;
    case AccessPoint::ACCESS_POINT_MAX:
      NOTREACHED();
      break;
  }
}

void RecordSigninNewAccountPreDiceUserActionForAccessPoint(
    signin_metrics::AccessPoint access_point) {
  switch (access_point) {
    case signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountPreDice_FromSettings"));
      break;
    case AccessPoint::ACCESS_POINT_EXTENSION_INSTALL_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountPreDice_FromExtensionInstallBubble"));
      break;
    case AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountPreDice_FromBookmarkBubble"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountPreDice_FromBookmarkManager"));
      break;
    case AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountPreDice_FromAvatarBubbleSignin"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountPreDice_FromRecentTabs"));
      break;
    case AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountPreDice_FromPasswordBubble"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_TAB_SWITCHER:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountPreDice_FromTabSwitcher"));
      break;
    case AccessPoint::ACCESS_POINT_NTP_CONTENT_SUGGESTIONS:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountPreDice_FromNTPContentSuggestions"));
      break;
    case AccessPoint::ACCESS_POINT_SAVE_CARD_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountPreDice_FromSaveCardBubble"));
      break;
    case AccessPoint::ACCESS_POINT_MANAGE_CARDS_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountPreDice_FromManageCardsBubble"));
      break;
    case AccessPoint::ACCESS_POINT_START_PAGE:
    case AccessPoint::ACCESS_POINT_NTP_LINK:
    case AccessPoint::ACCESS_POINT_MENU:
    case AccessPoint::ACCESS_POINT_SUPERVISED_USER:
    case AccessPoint::ACCESS_POINT_EXTENSIONS:
    case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
    case AccessPoint::ACCESS_POINT_USER_MANAGER:
    case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
    case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
    case AccessPoint::ACCESS_POINT_CONTENT_AREA:
    case AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
    case AccessPoint::ACCESS_POINT_AUTOFILL_DROPDOWN:
    case AccessPoint::ACCESS_POINT_RESIGNIN_INFOBAR:
    case AccessPoint::ACCESS_POINT_UNKNOWN:
    case AccessPoint::ACCESS_POINT_MACHINE_LOGON:
    case AccessPoint::ACCESS_POINT_GOOGLE_SERVICES_SETTINGS:
      // These access points do not support personalized sign-in promos, so
      // |Signin_SigninNewAccountPreDice_From*| user actions should not
      // be recorded for them. Note: To avoid bloating the sign-in APIs, the
      // sign-in metrics simply ignore if the caller passes
      // |PROMO_ACTION_NEW_ACCOUNT_PRE_DICE| when a sign-in flow is
      // started from any access point instead of treating it as an error like
      // in the other cases (|WithDefault| and |NotDefault|).
      VLOG(1) << "Signin_SigninNewAccountPreDice_From* user actions"
              << " are not recorded for access point "
              << static_cast<int>(access_point)
              << " as it does not support a personalized sign-in promo.";
      break;
    case AccessPoint::ACCESS_POINT_MAX:
      NOTREACHED();
      break;
  }
}

void RecordSigninNewAccountNoExistingAccountUserActionForAccessPoint(
    signin_metrics::AccessPoint access_point) {
  switch (access_point) {
    case signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountNoExistingAccount_FromSettings"));
      break;
    case AccessPoint::ACCESS_POINT_EXTENSION_INSTALL_BUBBLE:
      // clang-format off
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountNoExistingAccount_FromExtensionInstallBubble"));  // NOLINT(whitespace/line_length)
      // clang-format on
      break;
    case AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountNoExistingAccount_FromBookmarkBubble"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountNoExistingAccount_FromBookmarkManager"));
      break;
    case AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountNoExistingAccount_FromAvatarBubbleSignin"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountNoExistingAccount_FromRecentTabs"));
      break;
    case AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountNoExistingAccount_FromPasswordBubble"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_TAB_SWITCHER:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountNoExistingAccount_FromTabSwitcher"));
      break;
    case AccessPoint::ACCESS_POINT_NTP_CONTENT_SUGGESTIONS:
      // clang-format off
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountNoExistingAccount_FromNTPContentSuggestions"));  // NOLINT(whitespace/line_length)
      // clang-format on
      break;
    case AccessPoint::ACCESS_POINT_SAVE_CARD_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountNoExistingAccount_FromSaveCardBubble"));
      break;
    case AccessPoint::ACCESS_POINT_MANAGE_CARDS_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountNoExistingAccount_FromManageCardsBubble"));
      break;
    case AccessPoint::ACCESS_POINT_START_PAGE:
    case AccessPoint::ACCESS_POINT_NTP_LINK:
    case AccessPoint::ACCESS_POINT_MENU:
    case AccessPoint::ACCESS_POINT_SUPERVISED_USER:
    case AccessPoint::ACCESS_POINT_EXTENSIONS:
    case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
    case AccessPoint::ACCESS_POINT_USER_MANAGER:
    case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
    case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
    case AccessPoint::ACCESS_POINT_CONTENT_AREA:
    case AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
    case AccessPoint::ACCESS_POINT_AUTOFILL_DROPDOWN:
    case AccessPoint::ACCESS_POINT_RESIGNIN_INFOBAR:
    case AccessPoint::ACCESS_POINT_UNKNOWN:
    case AccessPoint::ACCESS_POINT_MACHINE_LOGON:
    case AccessPoint::ACCESS_POINT_GOOGLE_SERVICES_SETTINGS:
      // These access points do not support personalized sign-in promos, so
      // |Signin_SigninNewAccountNoExistingAccount_From*| user actions should
      // not be recorded for them. Note: To avoid bloating the sign-in APIs, the
      // sign-in metrics simply ignore if the caller passes
      // |PROMO_ACTION_NEW_ACCOUNT_NO_EXISTING_ACCOUNT| when a sign-in flow is
      // started from any access point instead of treating it as an error like
      // in the other cases (|WithDefault| and |NotDefault|).
      VLOG(1) << "Signin_SigninNewAccountNoExistingAccount_From* user actions"
              << " are not recorded for access point "
              << static_cast<int>(access_point)
              << " as it does not support a personalized sign-in promo.";
      break;
    case AccessPoint::ACCESS_POINT_MAX:
      NOTREACHED();
      break;
  }
}

void RecordSigninNewAccountExistingAccountUserActionForAccessPoint(
    signin_metrics::AccessPoint access_point) {
  switch (access_point) {
    case signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountExistingAccount_FromSettings"));
      break;
    case AccessPoint::ACCESS_POINT_EXTENSION_INSTALL_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountExistingAccount_FromExtensionInstallBubble"));
      break;
    case AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountExistingAccount_FromBookmarkBubble"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountExistingAccount_FromBookmarkManager"));
      break;
    case AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountExistingAccount_FromAvatarBubbleSignin"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountExistingAccount_FromRecentTabs"));
      break;
    case AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountExistingAccount_FromPasswordBubble"));
      break;
    case signin_metrics::AccessPoint::ACCESS_POINT_TAB_SWITCHER:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountExistingAccount_FromTabSwitcher"));
      break;
    case AccessPoint::ACCESS_POINT_NTP_CONTENT_SUGGESTIONS:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountExistingAccount_FromNTPContentSuggestions"));
      break;
    case AccessPoint::ACCESS_POINT_SAVE_CARD_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountExistingAccount_FromSaveCardBubble"));
      break;
    case AccessPoint::ACCESS_POINT_MANAGE_CARDS_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_SigninNewAccountExistingAccount_FromManageCardsBubble"));
      break;
    case AccessPoint::ACCESS_POINT_START_PAGE:
    case AccessPoint::ACCESS_POINT_NTP_LINK:
    case AccessPoint::ACCESS_POINT_MENU:
    case AccessPoint::ACCESS_POINT_SUPERVISED_USER:
    case AccessPoint::ACCESS_POINT_EXTENSIONS:
    case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
    case AccessPoint::ACCESS_POINT_USER_MANAGER:
    case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
    case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
    case AccessPoint::ACCESS_POINT_CONTENT_AREA:
    case AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
    case AccessPoint::ACCESS_POINT_AUTOFILL_DROPDOWN:
    case AccessPoint::ACCESS_POINT_RESIGNIN_INFOBAR:
    case AccessPoint::ACCESS_POINT_UNKNOWN:
    case AccessPoint::ACCESS_POINT_MACHINE_LOGON:
    case AccessPoint::ACCESS_POINT_GOOGLE_SERVICES_SETTINGS:
      // These access points do not support personalized sign-in promos, so
      // |Signin_SigninNewAccountExistingAccount_From*| user actions should not
      // be recorded for them. Note: To avoid bloating the sign-in APIs, the
      // sign-in metrics simply ignore if the caller passes
      // |PROMO_ACTION_NEW_ACCOUNT_EXISTING_ACCOUNT| when a sign-in flow is
      // started from any access point instead of treating it as an error like
      // in the other cases (|WithDefault| and |NotDefault|).
      VLOG(1) << "Signin_SigninNewAccountExistingAccount_From* user actions"
              << " are not recorded for access point "
              << static_cast<int>(access_point)
              << " as it does not support a personalized sign-in promo.";
      break;
    case AccessPoint::ACCESS_POINT_MAX:
      NOTREACHED();
      break;
  }
}
}  // namespace

// These intermediate macros are necessary when we may emit to different
// histograms from the same logical place in the code. The base histogram macros
// expand in a way that can only work for a single histogram name, so these
// allow a single place in the code to fan out for multiple names.
#define INVESTIGATOR_HISTOGRAM_CUSTOM_COUNTS(name, type, sample, min, max, \
                                             bucket_count)                 \
  switch (type) {                                                          \
    case ReportingType::PERIODIC:                                          \
      UMA_HISTOGRAM_CUSTOM_COUNTS(name "_Periodic", sample, min, max,      \
                                  bucket_count);                           \
      break;                                                               \
    case ReportingType::ON_CHANGE:                                         \
      UMA_HISTOGRAM_CUSTOM_COUNTS(name "_OnChange", sample, min, max,      \
                                  bucket_count);                           \
      break;                                                               \
  }

#define INVESTIGATOR_HISTOGRAM_BOOLEAN(name, type, sample) \
  switch (type) {                                          \
    case ReportingType::PERIODIC:                          \
      UMA_HISTOGRAM_BOOLEAN(name "_Periodic", sample);     \
      break;                                               \
    case ReportingType::ON_CHANGE:                         \
      UMA_HISTOGRAM_BOOLEAN(name "_OnChange", sample);     \
      break;                                               \
  }

#define INVESTIGATOR_HISTOGRAM_ENUMERATION(name, type, sample, boundary_value) \
  switch (type) {                                                              \
    case ReportingType::PERIODIC:                                              \
      UMA_HISTOGRAM_ENUMERATION(name "_Periodic", sample, boundary_value);     \
      break;                                                                   \
    case ReportingType::ON_CHANGE:                                             \
      UMA_HISTOGRAM_ENUMERATION(name "_OnChange", sample, boundary_value);     \
      break;                                                                   \
  }

// Helper method to determine which |DifferentPrimaryAccounts| applies.
DifferentPrimaryAccounts ComparePrimaryAccounts(bool primary_accounts_same,
                                                int pre_count_gaia_cookies) {
  if (primary_accounts_same)
    return ACCOUNTS_SAME;
  if (pre_count_gaia_cookies == 0)
    return NO_COOKIE_PRESENT;
  return COOKIE_AND_TOKEN_PRIMARIES_DIFFERENT;
}

void LogSigninAccessPointStarted(AccessPoint access_point,
                                 PromoAction promo_action) {
  UMA_HISTOGRAM_ENUMERATION("Signin.SigninStartedAccessPoint",
                            static_cast<int>(access_point),
                            static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
  switch (promo_action) {
    case PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO:
      break;
    case PromoAction::PROMO_ACTION_WITH_DEFAULT:
      UMA_HISTOGRAM_ENUMERATION(
          "Signin.SigninStartedAccessPoint.WithDefault",
          static_cast<int>(access_point),
          static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
      break;
    case PromoAction::PROMO_ACTION_NOT_DEFAULT:
      UMA_HISTOGRAM_ENUMERATION(
          "Signin.SigninStartedAccessPoint.NotDefault",
          static_cast<int>(access_point),
          static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
      break;
    case PromoAction::PROMO_ACTION_NEW_ACCOUNT_PRE_DICE:
      UMA_HISTOGRAM_ENUMERATION(
          "Signin.SigninStartedAccessPoint.NewAccountPreDice",
          static_cast<int>(access_point),
          static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
      break;
    case PromoAction::PROMO_ACTION_NEW_ACCOUNT_NO_EXISTING_ACCOUNT:
      UMA_HISTOGRAM_ENUMERATION(
          "Signin.SigninStartedAccessPoint.NewAccountNoExistingAccount",
          static_cast<int>(access_point),
          static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
      break;
    case PromoAction::PROMO_ACTION_NEW_ACCOUNT_EXISTING_ACCOUNT:
      UMA_HISTOGRAM_ENUMERATION(
          "Signin.SigninStartedAccessPoint.NewAccountExistingAccount",
          static_cast<int>(access_point),
          static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
      break;
  }
}

void LogSigninAccessPointCompleted(AccessPoint access_point,
                                   PromoAction promo_action) {
  UMA_HISTOGRAM_ENUMERATION("Signin.SigninCompletedAccessPoint",
                            static_cast<int>(access_point),
                            static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
  switch (promo_action) {
    case PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO:
      break;
    case PromoAction::PROMO_ACTION_WITH_DEFAULT:
      UMA_HISTOGRAM_ENUMERATION(
          "Signin.SigninCompletedAccessPoint.WithDefault",
          static_cast<int>(access_point),
          static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
      break;
    case PromoAction::PROMO_ACTION_NOT_DEFAULT:
      UMA_HISTOGRAM_ENUMERATION(
          "Signin.SigninCompletedAccessPoint.NotDefault",
          static_cast<int>(access_point),
          static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
      break;
    case PromoAction::PROMO_ACTION_NEW_ACCOUNT_PRE_DICE:
      UMA_HISTOGRAM_ENUMERATION(
          "Signin.SigninCompletedAccessPoint.NewAccountPreDice",
          static_cast<int>(access_point),
          static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
      break;
    case PromoAction::PROMO_ACTION_NEW_ACCOUNT_NO_EXISTING_ACCOUNT:
      UMA_HISTOGRAM_ENUMERATION(
          "Signin.SigninCompletedAccessPoint.NewAccountNoExistingAccount",
          static_cast<int>(access_point),
          static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
      break;
    case PromoAction::PROMO_ACTION_NEW_ACCOUNT_EXISTING_ACCOUNT:
      UMA_HISTOGRAM_ENUMERATION(
          "Signin.SigninCompletedAccessPoint.NewAccountExistingAccount",
          static_cast<int>(access_point),
          static_cast<int>(AccessPoint::ACCESS_POINT_MAX));
      break;
  }
}

void LogSigninReason(Reason reason) {
  UMA_HISTOGRAM_ENUMERATION("Signin.SigninReason", static_cast<int>(reason),
                            static_cast<int>(Reason::REASON_MAX));
}

void LogSigninAccountReconciliation(int total_number_accounts,
                                    int count_added_to_cookie_jar,
                                    int count_removed_from_cookie_jar,
                                    bool primary_accounts_same,
                                    bool is_first_reconcile,
                                    int pre_count_gaia_cookies) {
  RecordAccountsPerProfile(total_number_accounts);
  // We want to include zeroes in the counts of added or removed accounts to
  // easily capture _relatively_ how often we merge accounts.
  if (is_first_reconcile) {
    UMA_HISTOGRAM_COUNTS_100("Signin.Reconciler.AddedToCookieJar.FirstRun",
                             count_added_to_cookie_jar);
    UMA_HISTOGRAM_COUNTS_100("Signin.Reconciler.RemovedFromCookieJar.FirstRun",
                             count_removed_from_cookie_jar);
    UMA_HISTOGRAM_ENUMERATION(
        "Signin.Reconciler.DifferentPrimaryAccounts.FirstRun",
        ComparePrimaryAccounts(primary_accounts_same, pre_count_gaia_cookies),
        NUM_DIFFERENT_PRIMARY_ACCOUNT_METRICS);
  } else {
    UMA_HISTOGRAM_COUNTS_100("Signin.Reconciler.AddedToCookieJar.SubsequentRun",
                             count_added_to_cookie_jar);
    UMA_HISTOGRAM_COUNTS_100(
        "Signin.Reconciler.RemovedFromCookieJar.SubsequentRun",
        count_removed_from_cookie_jar);
    UMA_HISTOGRAM_ENUMERATION(
        "Signin.Reconciler.DifferentPrimaryAccounts.SubsequentRun",
        ComparePrimaryAccounts(primary_accounts_same, pre_count_gaia_cookies),
        NUM_DIFFERENT_PRIMARY_ACCOUNT_METRICS);
  }
}

void RecordAccountsPerProfile(int total_number_accounts) {
  UMA_HISTOGRAM_COUNTS_100("Profile.NumberOfAccountsPerProfile",
                           total_number_accounts);
}

void LogSigninAccountReconciliationDuration(base::TimeDelta duration,
                                            bool successful) {
  if (successful) {
    UMA_HISTOGRAM_CUSTOM_TIMES("Signin.Reconciler.Duration.UpTo3mins.Success",
                               duration, base::TimeDelta::FromMilliseconds(1),
                               base::TimeDelta::FromMinutes(3), 100);
  } else {
    UMA_HISTOGRAM_CUSTOM_TIMES("Signin.Reconciler.Duration.UpTo3mins.Failure",
                               duration, base::TimeDelta::FromMilliseconds(1),
                               base::TimeDelta::FromMinutes(3), 100);
  }
}

void LogSigninProfile(bool is_first_run, base::Time install_date) {
  // Track whether or not the user signed in during the first run of Chrome.
  UMA_HISTOGRAM_BOOLEAN("Signin.DuringFirstRun", is_first_run);

  // Determine how much time passed since install when this profile was signed
  // in.
  base::TimeDelta elapsed_time = base::Time::Now() - install_date;
  UMA_HISTOGRAM_COUNTS_1M("Signin.ElapsedTimeFromInstallToSignin",
                          elapsed_time.InMinutes());
}

void LogSigninAddAccount() {
  // Account signin may fail for a wide variety of reasons. There is no
  // explicit false, but one can compare this value with the various UI
  // flows that lead to account sign-in, and deduce that the difference
  // counts the failures.
  UMA_HISTOGRAM_BOOLEAN("Signin.AddAccount", true);
}

void LogSignout(ProfileSignout source_metric, SignoutDelete delete_metric) {
  UMA_HISTOGRAM_ENUMERATION("Signin.SignoutProfile", source_metric,
                            NUM_PROFILE_SIGNOUT_METRICS);
  if (delete_metric != SignoutDelete::IGNORE_METRIC) {
    UMA_HISTOGRAM_BOOLEAN(
        "Signin.SignoutDeleteProfile",
        delete_metric == SignoutDelete::DELETED ? true : false);
  }
}

void LogExternalCcResultFetches(
    bool fetches_completed,
    const base::TimeDelta& time_to_check_connections) {
  UMA_HISTOGRAM_BOOLEAN("Signin.Reconciler.AllExternalCcResultCompleted",
                        fetches_completed);
  if (fetches_completed) {
    UMA_HISTOGRAM_TIMES(
        "Signin.Reconciler.ExternalCcResultTime.Completed",
        time_to_check_connections);
  } else {
    UMA_HISTOGRAM_TIMES(
        "Signin.Reconciler.ExternalCcResultTime.NotCompleted",
        time_to_check_connections);
  }
}

void LogAuthError(const GoogleServiceAuthError& auth_error) {
  UMA_HISTOGRAM_ENUMERATION("Signin.AuthError", auth_error.state(),
                            GoogleServiceAuthError::State::NUM_STATES);
  if (auth_error.state() == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS) {
    UMA_HISTOGRAM_ENUMERATION(
        "Signin.InvalidGaiaCredentialsReason",
        auth_error.GetInvalidGaiaCredentialsReason(),
        GoogleServiceAuthError::InvalidGaiaCredentialsReason::NUM_REASONS);
  }
}

void LogSigninConfirmHistogramValue(ConfirmationUsage action) {
  UMA_HISTOGRAM_ENUMERATION("Signin.OneClickConfirmation", action,
                            HISTOGRAM_CONFIRM_MAX);
}

void LogAccountReconcilorStateOnGaiaResponse(AccountReconcilorState state) {
  UMA_HISTOGRAM_ENUMERATION("Signin.AccountReconcilorState.OnGaiaResponse",
                            state, ACCOUNT_RECONCILOR_HISTOGRAM_COUNT);
}

void LogAccountEquality(AccountEquality equality) {
  UMA_HISTOGRAM_ENUMERATION("Signin.AccountEquality",
                            static_cast<int>(equality),
                            static_cast<int>(AccountEquality::HISTOGRAM_COUNT));
}

void LogCookieJarStableAge(const base::TimeDelta stable_age,
                           const ReportingType type) {
  INVESTIGATOR_HISTOGRAM_CUSTOM_COUNTS(
      "Signin.CookieJar.StableAge", type,
      base::saturated_cast<int>(stable_age.InSeconds()), 1,
      base::saturated_cast<int>(base::TimeDelta::FromDays(365).InSeconds()),
      100);
}

void LogCookieJarCounts(const int signed_in,
                        const int signed_out,
                        const int total,
                        const ReportingType type) {
  INVESTIGATOR_HISTOGRAM_CUSTOM_COUNTS("Signin.CookieJar.SignedInCount", type,
                                       signed_in, 1, 10, 10);
  INVESTIGATOR_HISTOGRAM_CUSTOM_COUNTS("Signin.CookieJar.SignedOutCount", type,
                                       signed_out, 1, 10, 10);
  INVESTIGATOR_HISTOGRAM_CUSTOM_COUNTS("Signin.CookieJar.TotalCount", type,
                                       total, 1, 10, 10);
}

void LogAccountRelation(const AccountRelation relation,
                        const ReportingType type) {
  INVESTIGATOR_HISTOGRAM_ENUMERATION(
      "Signin.CookieJar.ChromeAccountRelation", type,
      static_cast<int>(relation),
      static_cast<int>(AccountRelation::HISTOGRAM_COUNT));
}

void LogIsShared(const bool is_shared, const ReportingType type) {
  INVESTIGATOR_HISTOGRAM_BOOLEAN("Signin.IsShared", type, is_shared);
}

void RecordRefreshTokenUpdatedFromSource(
    bool refresh_token_is_valid,
    SourceForRefreshTokenOperation source) {
  if (refresh_token_is_valid) {
    UMA_HISTOGRAM_ENUMERATION("Signin.RefreshTokenUpdated.ToValidToken.Source",
                              source);
  } else {
    UMA_HISTOGRAM_ENUMERATION(
        "Signin.RefreshTokenUpdated.ToInvalidToken.Source", source);
  }
}

void RecordRefreshTokenRevokedFromSource(
    SourceForRefreshTokenOperation source) {
  UMA_HISTOGRAM_ENUMERATION("Signin.RefreshTokenRevoked.Source", source);
}

// --------------------------------------------------------------
// User actions
// --------------------------------------------------------------

void RecordSigninUserActionForAccessPoint(AccessPoint access_point,
                                          PromoAction promo_action) {
  RecordSigninUserActionForAccessPoint(access_point);
  switch (promo_action) {
    case PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO:
      break;
    case PromoAction::PROMO_ACTION_WITH_DEFAULT:
      RecordSigninWithDefaultUserActionForAccessPoint(access_point);
      break;
    case PromoAction::PROMO_ACTION_NOT_DEFAULT:
      RecordSigninNotDefaultUserActionForAccessPoint(access_point);
      break;
    case PromoAction::PROMO_ACTION_NEW_ACCOUNT_PRE_DICE:
      RecordSigninNewAccountPreDiceUserActionForAccessPoint(access_point);
      break;
    case PromoAction::PROMO_ACTION_NEW_ACCOUNT_NO_EXISTING_ACCOUNT:
      RecordSigninNewAccountNoExistingAccountUserActionForAccessPoint(
          access_point);
      break;
    case PromoAction::PROMO_ACTION_NEW_ACCOUNT_EXISTING_ACCOUNT:
      RecordSigninNewAccountExistingAccountUserActionForAccessPoint(
          access_point);
      break;
  }
}

void RecordSigninImpressionUserActionForAccessPoint(AccessPoint access_point) {
  switch (access_point) {
    case AccessPoint::ACCESS_POINT_START_PAGE:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromStartPage"));
      break;
    case AccessPoint::ACCESS_POINT_NTP_LINK:
      base::RecordAction(base::UserMetricsAction("Signin_Impression_FromNTP"));
      break;
    case AccessPoint::ACCESS_POINT_MENU:
      base::RecordAction(base::UserMetricsAction("Signin_Impression_FromMenu"));
      break;
    case AccessPoint::ACCESS_POINT_SETTINGS:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromSettings"));
      break;
    case AccessPoint::ACCESS_POINT_EXTENSION_INSTALL_BUBBLE:
      base::RecordAction(base::UserMetricsAction(
          "Signin_Impression_FromExtensionInstallBubble"));
      break;
    case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromAppsPageLink"));
      break;
    case AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromBookmarkBubble"));
      break;
    case AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromBookmarkManager"));
      break;
    case AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromAvatarBubbleSignin"));
      break;
    case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromDevicesPage"));
      break;
    case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromCloudPrint"));
      break;
    case AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromSigninPromo"));
      break;
    case AccessPoint::ACCESS_POINT_RECENT_TABS:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromRecentTabs"));
      break;
    case AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromPasswordBubble"));
      break;
    case AccessPoint::ACCESS_POINT_AUTOFILL_DROPDOWN:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromAutofillDropdown"));
      break;
    case AccessPoint::ACCESS_POINT_NTP_CONTENT_SUGGESTIONS:
      base::RecordAction(base::UserMetricsAction(
          "Signin_Impression_FromNTPContentSuggestions"));
      break;
    case AccessPoint::ACCESS_POINT_RESIGNIN_INFOBAR:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromReSigninInfobar"));
      break;
    case AccessPoint::ACCESS_POINT_TAB_SWITCHER:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromTabSwitcher"));
      break;
    case AccessPoint::ACCESS_POINT_SAVE_CARD_BUBBLE:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromSaveCardBubble"));
      break;
    case AccessPoint::ACCESS_POINT_MANAGE_CARDS_BUBBLE:
      base::RecordAction(
          base::UserMetricsAction("Signin_Impression_FromManageCardsBubble"));
      break;
    case AccessPoint::ACCESS_POINT_GOOGLE_SERVICES_SETTINGS:
      base::RecordAction(base::UserMetricsAction(
          "Signin_Impression_FromGoogleServicesSettings"));
      break;
    case AccessPoint::ACCESS_POINT_CONTENT_AREA:
    case AccessPoint::ACCESS_POINT_EXTENSIONS:
    case AccessPoint::ACCESS_POINT_SUPERVISED_USER:
    case AccessPoint::ACCESS_POINT_USER_MANAGER:
    case AccessPoint::ACCESS_POINT_UNKNOWN:
    case AccessPoint::ACCESS_POINT_MACHINE_LOGON:
      NOTREACHED() << "Signin_Impression_From* user actions"
                   << " are not recorded for access point "
                   << static_cast<int>(access_point);
      break;
    case AccessPoint::ACCESS_POINT_MAX:
      NOTREACHED();
      break;
  }
}

void RecordSigninImpressionWithAccountUserActionForAccessPoint(
    AccessPoint access_point,
    bool with_account) {
  switch (access_point) {
    case AccessPoint::ACCESS_POINT_SETTINGS:
      if (with_account) {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithAccount_FromSettings"));
      } else {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithNoAccount_FromSettings"));
      }
      break;
    case AccessPoint::ACCESS_POINT_EXTENSION_INSTALL_BUBBLE:
      if (with_account) {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithAccount_FromExtensionInstallBubble"));
      } else {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithNoAccount_FromExtensionInstallBubble"));
      }
      break;
    case AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE:
      if (with_account) {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithAccount_FromBookmarkBubble"));
      } else {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithNoAccount_FromBookmarkBubble"));
      }
      break;
    case AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER:
      if (with_account) {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithAccount_FromBookmarkManager"));
      } else {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithNoAccount_FromBookmarkManager"));
      }
      break;
    case AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
      if (with_account) {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithAccount_FromAvatarBubbleSignin"));
      } else {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithNoAccount_FromAvatarBubbleSignin"));
      }
      break;
    case AccessPoint::ACCESS_POINT_RECENT_TABS:
      if (with_account) {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithAccount_FromRecentTabs"));
      } else {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithNoAccount_FromRecentTabs"));
      }
      break;
    case AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE:
      if (with_account) {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithAccount_FromPasswordBubble"));
      } else {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithNoAccount_FromPasswordBubble"));
      }
      break;
    case AccessPoint::ACCESS_POINT_TAB_SWITCHER:
      if (with_account) {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithAccount_FromTabSwitcher"));
      } else {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithNoAccount_FromTabSwitcher"));
      }
      break;
    case AccessPoint::ACCESS_POINT_NTP_CONTENT_SUGGESTIONS:
      if (with_account) {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithAccount_FromNTPContentSuggestions"));
      } else {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithNoAccount_FromNTPContentSuggestions"));
      }
      break;
    case AccessPoint::ACCESS_POINT_SAVE_CARD_BUBBLE:
      if (with_account) {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithAccount_FromSaveCardBubble"));
      } else {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithNoAccount_FromSaveCardBubble"));
      }
      break;
    case AccessPoint::ACCESS_POINT_MANAGE_CARDS_BUBBLE:
      if (with_account) {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithAccount_FromManageCardsBubble"));
      } else {
        base::RecordAction(base::UserMetricsAction(
            "Signin_ImpressionWithNoAccount_FromManageCardsBubble"));
      }
      break;
    case AccessPoint::ACCESS_POINT_START_PAGE:
    case AccessPoint::ACCESS_POINT_NTP_LINK:
    case AccessPoint::ACCESS_POINT_MENU:
    case AccessPoint::ACCESS_POINT_SUPERVISED_USER:
    case AccessPoint::ACCESS_POINT_EXTENSIONS:
    case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
    case AccessPoint::ACCESS_POINT_USER_MANAGER:
    case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
    case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
    case AccessPoint::ACCESS_POINT_CONTENT_AREA:
    case AccessPoint::ACCESS_POINT_SIGNIN_PROMO:
    case AccessPoint::ACCESS_POINT_AUTOFILL_DROPDOWN:
    case AccessPoint::ACCESS_POINT_RESIGNIN_INFOBAR:
    case AccessPoint::ACCESS_POINT_UNKNOWN:
    case AccessPoint::ACCESS_POINT_MACHINE_LOGON:
    case AccessPoint::ACCESS_POINT_GOOGLE_SERVICES_SETTINGS:
      NOTREACHED() << "Signin_Impression{With|WithNo}Account_From* user actions"
                   << " are not recorded for access point "
                   << static_cast<int>(access_point)
                   << " as it does not support a personalized sign-in promo.";
      break;
    case AccessPoint::ACCESS_POINT_MAX:
      NOTREACHED();
      break;
  }
}

}  // namespace signin_metrics
