blob: 1a6bc7f21907aa763da3758d8480069d27e56e19 [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/sync_user_events/user_event_service_impl.h"
#include <utility>
#include "base/metrics/histogram_functions.h"
#include "base/rand_util.h"
#include "base/time/time.h"
#include "components/sync_user_events/user_event_sync_bridge.h"
using sync_pb::UserEventSpecifics;
namespace syncer {
namespace {
enum NavigationPresence {
kMustHave,
kCannotHave,
kEitherOkay,
};
NavigationPresence GetNavigationPresence(
UserEventSpecifics::EventCase event_case) {
switch (event_case) {
case UserEventSpecifics::kTestEvent:
return kEitherOkay;
case UserEventSpecifics::kGaiaPasswordReuseEvent:
return kMustHave;
case UserEventSpecifics::kGaiaPasswordCapturedEvent:
case UserEventSpecifics::kFlocIdComputedEvent:
return kCannotHave;
// The event types below are not recorded anymore, so are not handled here
// (will fall through to the NOTREACHED() below).
case UserEventSpecifics::kLanguageDetectionEvent:
case UserEventSpecifics::kTranslationEvent:
case UserEventSpecifics::EVENT_NOT_SET:
break;
}
NOTREACHED();
}
bool NavigationPresenceValid(UserEventSpecifics::EventCase event_case,
bool has_navigation_id) {
NavigationPresence presence = GetNavigationPresence(event_case);
return presence == kEitherOkay ||
(presence == kMustHave && has_navigation_id) ||
(presence == kCannotHave && !has_navigation_id);
}
// An equivalent to UserEventSpecifics::EventCase (from the proto) that's
// appropriate for recording in UMA. These values are persisted to logs. Entries
// should not be renumbered and numeric values should never be reused. Keep in
// sync with SyncUserEventType in
// tools/metrics/histograms/metadata/sync/enums.xml.
// LINT.IfChange(SyncUserEventType)
enum class EventTypeForUMA {
kUnknown = 0,
kTestEvent = 1,
kGaiaPasswordReuseEvent = 2,
kGaiaPasswordCapturedEvent = 3,
kFlocIdComputedEvent = 4,
kMaxValue = kFlocIdComputedEvent
};
// LINT.ThenChange(/tools/metrics/histograms/metadata/sync/enums.xml:SyncUserEventType)
EventTypeForUMA GetEventTypeForUMA(UserEventSpecifics::EventCase event_case) {
switch (event_case) {
case UserEventSpecifics::kTestEvent:
return EventTypeForUMA::kTestEvent;
case UserEventSpecifics::kGaiaPasswordReuseEvent:
return EventTypeForUMA::kGaiaPasswordReuseEvent;
case UserEventSpecifics::kGaiaPasswordCapturedEvent:
return EventTypeForUMA::kGaiaPasswordCapturedEvent;
case UserEventSpecifics::kFlocIdComputedEvent:
return EventTypeForUMA::kFlocIdComputedEvent;
// The event types below are not recorded anymore, so are not handled here
// (will fall through to the NOTREACHED() below).
case UserEventSpecifics::kLanguageDetectionEvent:
case UserEventSpecifics::kTranslationEvent:
case UserEventSpecifics::EVENT_NOT_SET:
break;
}
NOTREACHED();
}
} // namespace
UserEventServiceImpl::UserEventServiceImpl(
std::unique_ptr<UserEventSyncBridge> bridge)
: bridge_(std::move(bridge)), session_id_(base::RandUint64()) {
DCHECK(bridge_);
}
UserEventServiceImpl::~UserEventServiceImpl() = default;
void UserEventServiceImpl::Shutdown() {}
void UserEventServiceImpl::RecordUserEvent(
std::unique_ptr<UserEventSpecifics> specifics) {
if (!ShouldRecordEvent(*specifics)) {
return;
}
DCHECK(!specifics->has_session_id());
specifics->set_session_id(session_id_);
base::UmaHistogramEnumeration("Sync.RecordedUserEventType",
GetEventTypeForUMA(specifics->event_case()));
bridge_->RecordUserEvent(std::move(specifics));
}
void UserEventServiceImpl::RecordUserEvent(
const UserEventSpecifics& specifics) {
RecordUserEvent(std::make_unique<UserEventSpecifics>(specifics));
}
base::WeakPtr<syncer::DataTypeControllerDelegate>
UserEventServiceImpl::GetControllerDelegate() {
return bridge_->change_processor()->GetControllerDelegate();
}
bool UserEventServiceImpl::ShouldRecordEvent(
const UserEventSpecifics& specifics) {
if (specifics.event_case() == UserEventSpecifics::EVENT_NOT_SET) {
return false;
}
if (!NavigationPresenceValid(specifics.event_case(),
specifics.has_navigation_id())) {
return false;
}
return true;
}
} // namespace syncer