[Security Events] Add chrome sync specifics proto for security events.

This is the first part (cl) for adding a new record only sync data type for recording security events.
This CL adds the Chrome Sync Specifics proto. In the next CL the Sync Data type will be wired.

Bug: 919489
Change-Id: I542f5cae27568927e614f793edfaf374058ea70a
Reviewed-on: https://chromium-review.googlesource.com/c/1455998
Commit-Queue: Markus Heintz <[email protected]>
Reviewed-by: Varun Khaneja <[email protected]>
Reviewed-by: Marc Treib <[email protected]>
Cr-Commit-Position: refs/heads/master@{#629929}
diff --git a/components/safe_browsing/web_ui/safe_browsing_ui.cc b/components/safe_browsing/web_ui/safe_browsing_ui.cc
index 8e2f1e9a..c38323b9 100644
--- a/components/safe_browsing/web_ui/safe_browsing_ui.cc
+++ b/components/safe_browsing/web_ui/safe_browsing_ui.cc
@@ -39,13 +39,12 @@
 #endif
 
 using base::Time;
+using sync_pb::GaiaPasswordReuse;
 using PasswordCaptured = sync_pb::UserEventSpecifics::GaiaPasswordCaptured;
-using PasswordReuseLookup =
-    sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup;
-using PasswordReuseDetected =
-    sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseDetected;
-using PasswordReuseDialogInteraction = sync_pb::UserEventSpecifics::
-    GaiaPasswordReuse::PasswordReuseDialogInteraction;
+using PasswordReuseLookup = sync_pb::GaiaPasswordReuse::PasswordReuseLookup;
+using PasswordReuseDetected = sync_pb::GaiaPasswordReuse::PasswordReuseDetected;
+using PasswordReuseDialogInteraction =
+    sync_pb::GaiaPasswordReuse::PasswordReuseDialogInteraction;
 
 namespace safe_browsing {
 WebUIInfoSingleton::WebUIInfoSingleton() = default;
@@ -607,8 +606,7 @@
                        base::Value(event_trigger));
   }
 
-  sync_pb::UserEventSpecifics::GaiaPasswordReuse reuse =
-      event.gaia_password_reuse_event();
+  GaiaPasswordReuse reuse = event.gaia_password_reuse_event();
   if (reuse.has_reuse_detected()) {
     event_dict.SetPath({"reuse_detected", "status", "enabled"},
                        base::Value(reuse.reuse_detected().status().enabled()));
diff --git a/components/sync/protocol/gaia_password_reuse.proto b/components/sync/protocol/gaia_password_reuse.proto
new file mode 100644
index 0000000..78919e9e
--- /dev/null
+++ b/components/sync/protocol/gaia_password_reuse.proto
@@ -0,0 +1,116 @@
+// Copyright 2019 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.
+//
+// Security Events used for recording security related events.
+
+// If you change or add any fields in this file, update proto_visitors.h and
+// potentially proto_enum_conversions.{h, cc}.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package sync_pb;
+
+// User reused their GAIA password on another website.
+message GaiaPasswordReuse {
+  // Logged when we detect a password re-use event on a non-GAIA site.
+  // If the user hasn’t enabled SafeBrowsing, this will be the last event.
+  message PasswordReuseDetected {
+    message SafeBrowsingStatus {
+      // Is SafeBrowsing enabled?
+      optional bool enabled = 1;
+      // If SafeBrowsing is enabled, is the user opted-in to extended
+      // reporting or Scout?
+      enum ReportingPopulation {
+        REPORTING_POPULATION_UNSPECIFIED = 0;
+        NONE = 1;
+        EXTENDED_REPORTING = 2;
+        SCOUT = 3;
+      }
+      optional ReportingPopulation safe_browsing_reporting_population = 2;
+    }
+    optional SafeBrowsingStatus status = 1;
+  }
+  optional PasswordReuseDetected reuse_detected = 1;
+
+  message PasswordReuseLookup {
+    enum LookupResult {
+      UNSPECIFIED = 0;
+      // URL did match the password reuse whitelist.
+      // No further action required related to this re-use event.
+      WHITELIST_HIT = 1;
+      // The URL exists in the client’s cache.
+      // No further action required related to this re-use event.
+      // This event also logs the ReputationVerdict.
+      CACHE_HIT = 2;
+      // A valid response received from the SafeBrowsing service.
+      // This event also logs the ReputationVerdict.
+      REQUEST_SUCCESS = 3;
+      // Unable to get a valid response from the SafeBrowsing service.
+      REQUEST_FAILURE = 4;
+      // We won't be able to compute reputation for the URL e.g. local IP
+      // address, localhost, not-yet-assigned by ICANN gTLD, etc.
+      URL_UNSUPPORTED = 5;
+      // URL did match enterprise whitelist.
+      // No further action required related to this re-use event.
+      ENTERPRISE_WHITELIST_HIT = 6;
+      // Password reuse lookup is turned off by enterprise policy.
+      // No further action required related to this re-use event.
+      TURNED_OFF_BY_POLICY = 7;
+    }
+    optional LookupResult lookup_result = 1;
+
+    // The following two are only present for CACHE_HIT and REQUEST_SUCCESS.
+    // The verdict received from the Reputation service. This is set only
+    // if the user has SafeBrowsing enabled and we fetch the verdict from the
+    // cache or by sending a verdict request.
+    enum ReputationVerdict {
+      VERDICT_UNSPECIFIED = 0;
+      SAFE = 1;
+      LOW_REPUTATION = 2;
+      PHISHING = 3;
+    }
+    optional ReputationVerdict verdict = 2;
+    // PhishGuard token that identifies the verdict on the server.
+    optional bytes verdict_token = 3;
+  }
+  // Logged when we try to detect whether the password was reused on a
+  // Phishing or a Low-reputation site.
+  optional PasswordReuseLookup reuse_lookup = 2;
+
+  // Logged when the user interacts with the warning UI shown to encourage
+  // password change if the site is Phishing or Low-reputation.
+  message PasswordReuseDialogInteraction {
+    enum InteractionResult {
+      UNSPECIFIED = 0;
+      // The user took the action suggested by the warning prompt.
+      WARNING_ACTION_TAKEN = 1;
+      // The user clicked ignore in the warning prompt.
+      WARNING_ACTION_IGNORED = 2;
+      // The warning UI was ignored, i.e. not interacted with by the user.
+      // This could happen if the user navigates away from the page.
+      WARNING_UI_IGNORED = 3;
+      // The user clicked "Change Password" on chrome://settings page.
+      WARNING_ACTION_TAKEN_ON_SETTINGS = 4;
+    }
+    optional InteractionResult interaction_result = 1;
+  }
+  optional PasswordReuseDialogInteraction dialog_interaction = 3;
+
+  // TODO(markusheintz): Remove
+  // DEPRECATED: DO NOT USE!
+  // Logged when the user logs into Google, and at least once per 28d.
+  message PasswordCaptured {
+    enum EventTrigger {
+      UNSPECIFIED = 0;
+      // Event added because user logged in.
+      USER_LOGGED_IN = 1;
+      // Event added because 28d timer fired.
+      EXPIRED_28D_TIMER = 2;
+    }
+    optional EventTrigger event_trigger = 1;
+  }
+  optional PasswordCaptured password_captured = 4;
+}
diff --git a/components/sync/protocol/proto_enum_conversions.cc b/components/sync/protocol/proto_enum_conversions.cc
index 265cad5..52661cd2 100644
--- a/components/sync/protocol/proto_enum_conversions.cc
+++ b/components/sync/protocol/proto_enum_conversions.cc
@@ -367,53 +367,45 @@
 }
 
 const char* ProtoEnumToString(
-    sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseDetected::
-        SafeBrowsingStatus::ReportingPopulation
-            safe_browsing_reporting_population) {
-  ASSERT_ENUM_BOUNDS(sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                         PasswordReuseDetected::SafeBrowsingStatus,
-                     ReportingPopulation, REPORTING_POPULATION_UNSPECIFIED,
-                     SCOUT);
+    sync_pb::GaiaPasswordReuse::PasswordReuseDetected::SafeBrowsingStatus::
+        ReportingPopulation safe_browsing_reporting_population) {
+  ASSERT_ENUM_BOUNDS(
+      sync_pb::GaiaPasswordReuse::PasswordReuseDetected::SafeBrowsingStatus,
+      ReportingPopulation, REPORTING_POPULATION_UNSPECIFIED, SCOUT);
   switch (safe_browsing_reporting_population) {
-    ENUM_CASE(sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                  PasswordReuseDetected::SafeBrowsingStatus,
-              REPORTING_POPULATION_UNSPECIFIED);
-    ENUM_CASE(sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                  PasswordReuseDetected::SafeBrowsingStatus,
-              NONE);
-    ENUM_CASE(sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                  PasswordReuseDetected::SafeBrowsingStatus,
-              EXTENDED_REPORTING);
-    ENUM_CASE(sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                  PasswordReuseDetected::SafeBrowsingStatus,
-              SCOUT);
+    ENUM_CASE(
+        sync_pb::GaiaPasswordReuse::PasswordReuseDetected::SafeBrowsingStatus,
+        REPORTING_POPULATION_UNSPECIFIED);
+    ENUM_CASE(
+        sync_pb::GaiaPasswordReuse::PasswordReuseDetected::SafeBrowsingStatus,
+        NONE);
+    ENUM_CASE(
+        sync_pb::GaiaPasswordReuse::PasswordReuseDetected::SafeBrowsingStatus,
+        EXTENDED_REPORTING);
+    ENUM_CASE(
+        sync_pb::GaiaPasswordReuse::PasswordReuseDetected::SafeBrowsingStatus,
+        SCOUT);
   }
   NOTREACHED();
   return "";
 }
 
 const char* ProtoEnumToString(
-    sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-        PasswordReuseDialogInteraction::InteractionResult interaction_result) {
-  ASSERT_ENUM_BOUNDS(sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                         PasswordReuseDialogInteraction,
+    sync_pb::GaiaPasswordReuse::PasswordReuseDialogInteraction::
+        InteractionResult interaction_result) {
+  ASSERT_ENUM_BOUNDS(sync_pb::GaiaPasswordReuse::PasswordReuseDialogInteraction,
                      InteractionResult, UNSPECIFIED,
                      WARNING_ACTION_TAKEN_ON_SETTINGS);
   switch (interaction_result) {
-    ENUM_CASE(sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                  PasswordReuseDialogInteraction,
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseDialogInteraction,
               UNSPECIFIED);
-    ENUM_CASE(sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                  PasswordReuseDialogInteraction,
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseDialogInteraction,
               WARNING_ACTION_TAKEN);
-    ENUM_CASE(sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                  PasswordReuseDialogInteraction,
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseDialogInteraction,
               WARNING_ACTION_IGNORED);
-    ENUM_CASE(sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                  PasswordReuseDialogInteraction,
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseDialogInteraction,
               WARNING_UI_IGNORED);
-    ENUM_CASE(sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                  PasswordReuseDialogInteraction,
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseDialogInteraction,
               WARNING_ACTION_TAKEN_ON_SETTINGS);
   }
   NOTREACHED();
@@ -421,78 +413,51 @@
 }
 
 const char* ProtoEnumToString(
-    sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup::
-        LookupResult lookup_result) {
-  ASSERT_ENUM_BOUNDS(
-      sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-      LookupResult, UNSPECIFIED, TURNED_OFF_BY_POLICY);
+    sync_pb::GaiaPasswordReuse::PasswordReuseLookup::LookupResult
+        lookup_result) {
+  ASSERT_ENUM_BOUNDS(sync_pb::GaiaPasswordReuse::PasswordReuseLookup,
+                     LookupResult, UNSPECIFIED, TURNED_OFF_BY_POLICY);
   switch (lookup_result) {
-    ENUM_CASE(
-        sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-        UNSPECIFIED);
-    ENUM_CASE(
-        sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-        WHITELIST_HIT);
-    ENUM_CASE(
-        sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-        CACHE_HIT);
-    ENUM_CASE(
-        sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-        REQUEST_SUCCESS);
-    ENUM_CASE(
-        sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-        REQUEST_FAILURE);
-    ENUM_CASE(
-        sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-        URL_UNSUPPORTED);
-    ENUM_CASE(
-        sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-        ENTERPRISE_WHITELIST_HIT);
-    ENUM_CASE(
-        sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-        TURNED_OFF_BY_POLICY);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseLookup, UNSPECIFIED);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseLookup, WHITELIST_HIT);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseLookup, CACHE_HIT);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseLookup, REQUEST_SUCCESS);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseLookup, REQUEST_FAILURE);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseLookup, URL_UNSUPPORTED);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseLookup,
+              ENTERPRISE_WHITELIST_HIT);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseLookup,
+              TURNED_OFF_BY_POLICY);
   }
   NOTREACHED();
   return "";
 }
 
 const char* ProtoEnumToString(
-    sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup::
-        ReputationVerdict verdict) {
-  ASSERT_ENUM_BOUNDS(
-      sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-      ReputationVerdict, VERDICT_UNSPECIFIED, PHISHING);
+    sync_pb::GaiaPasswordReuse::PasswordReuseLookup::ReputationVerdict
+        verdict) {
+  ASSERT_ENUM_BOUNDS(sync_pb::GaiaPasswordReuse::PasswordReuseLookup,
+                     ReputationVerdict, VERDICT_UNSPECIFIED, PHISHING);
   switch (verdict) {
-    ENUM_CASE(
-        sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-        VERDICT_UNSPECIFIED);
-    ENUM_CASE(
-        sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-        SAFE);
-    ENUM_CASE(
-        sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-        LOW_REPUTATION);
-    ENUM_CASE(
-        sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup,
-        PHISHING);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseLookup,
+              VERDICT_UNSPECIFIED);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseLookup, SAFE);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseLookup, LOW_REPUTATION);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordReuseLookup, PHISHING);
   }
   NOTREACHED();
   return "";
 }
 
 // TODO(markusheintz): Remove.
-const char* ProtoEnumToString(sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                                  PasswordCaptured::EventTrigger trigger) {
-  ASSERT_ENUM_BOUNDS(
-      sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordCaptured,
-      EventTrigger, UNSPECIFIED, EXPIRED_28D_TIMER);
+const char* ProtoEnumToString(
+    sync_pb::GaiaPasswordReuse::PasswordCaptured::EventTrigger trigger) {
+  ASSERT_ENUM_BOUNDS(sync_pb::GaiaPasswordReuse::PasswordCaptured, EventTrigger,
+                     UNSPECIFIED, EXPIRED_28D_TIMER);
   switch (trigger) {
-    ENUM_CASE(sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordCaptured,
-              UNSPECIFIED);
-    ENUM_CASE(sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordCaptured,
-              USER_LOGGED_IN);
-    ENUM_CASE(sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordCaptured,
-              EXPIRED_28D_TIMER);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordCaptured, UNSPECIFIED);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordCaptured, USER_LOGGED_IN);
+    ENUM_CASE(sync_pb::GaiaPasswordReuse::PasswordCaptured, EXPIRED_28D_TIMER);
   }
   NOTREACHED();
   return "";
diff --git a/components/sync/protocol/proto_enum_conversions.h b/components/sync/protocol/proto_enum_conversions.h
index 8a234ec0..bcac2ec 100644
--- a/components/sync/protocol/proto_enum_conversions.h
+++ b/components/sync/protocol/proto_enum_conversions.h
@@ -76,25 +76,23 @@
 const char* ProtoEnumToString(sync_pb::UserConsentTypes::ConsentStatus status);
 
 const char* ProtoEnumToString(
-    sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseDetected::
-        SafeBrowsingStatus::ReportingPopulation
-            safe_browsing_reporting_population);
+    sync_pb::GaiaPasswordReuse::PasswordReuseDetected::SafeBrowsingStatus::
+        ReportingPopulation safe_browsing_reporting_population);
 
 const char* ProtoEnumToString(
-    sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-        PasswordReuseDialogInteraction::InteractionResult interaction_result);
+    sync_pb::GaiaPasswordReuse::PasswordReuseDialogInteraction::
+        InteractionResult interaction_result);
 
 const char* ProtoEnumToString(
-    sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup::
-        LookupResult lookup_result);
+    sync_pb::GaiaPasswordReuse::PasswordReuseLookup::LookupResult
+        lookup_result);
 
 const char* ProtoEnumToString(
-    sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup::
-        ReputationVerdict verdict);
+    sync_pb::GaiaPasswordReuse::PasswordReuseLookup::ReputationVerdict verdict);
 
 // TODO(markusheintz): Remove.
-const char* ProtoEnumToString(sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                                  PasswordCaptured::EventTrigger trigger);
+const char* ProtoEnumToString(
+    sync_pb::GaiaPasswordReuse::PasswordCaptured::EventTrigger trigger);
 
 const char* ProtoEnumToString(
     sync_pb::UserEventSpecifics::GaiaPasswordCaptured::EventTrigger trigger);
diff --git a/components/sync/protocol/proto_value_conversions.cc b/components/sync/protocol/proto_value_conversions.cc
index 0edbf69..a6647430 100644
--- a/components/sync/protocol/proto_value_conversions.cc
+++ b/components/sync/protocol/proto_value_conversions.cc
@@ -343,6 +343,7 @@
 IMPLEMENT_PROTO_TO_VALUE(PriorityPreferenceSpecifics)
 IMPLEMENT_PROTO_TO_VALUE(ReadingListSpecifics)
 IMPLEMENT_PROTO_TO_VALUE(SearchEngineSpecifics)
+IMPLEMENT_PROTO_TO_VALUE(SecurityEventSpecifics)
 IMPLEMENT_PROTO_TO_VALUE(SendTabToSelfSpecifics)
 IMPLEMENT_PROTO_TO_VALUE(SessionHeader)
 IMPLEMENT_PROTO_TO_VALUE(SessionSpecifics)
diff --git a/components/sync/protocol/proto_value_conversions.h b/components/sync/protocol/proto_value_conversions.h
index 6e51ebd..ff0e19b 100644
--- a/components/sync/protocol/proto_value_conversions.h
+++ b/components/sync/protocol/proto_value_conversions.h
@@ -58,6 +58,7 @@
 class PriorityPreferenceSpecifics;
 class ReadingListSpecifics;
 class SearchEngineSpecifics;
+class SecurityEventSpecifics;
 class SendTabToSelfSpecifics;
 class SessionHeader;
 class SessionSpecifics;
@@ -227,6 +228,9 @@
 std::unique_ptr<base::DictionaryValue> SendTabToSelfSpecificsToValue(
     const sync_pb::SendTabToSelfSpecifics& send_tab_specifics);
 
+std::unique_ptr<base::DictionaryValue> SecurityEventSpecificsToValue(
+    const sync_pb::SecurityEventSpecifics& security_event_specifics);
+
 std::unique_ptr<base::DictionaryValue> SessionHeaderToValue(
     const sync_pb::SessionHeader& session_header);
 
diff --git a/components/sync/protocol/proto_value_conversions_unittest.cc b/components/sync/protocol/proto_value_conversions_unittest.cc
index 0b70d097c..e1016be3 100644
--- a/components/sync/protocol/proto_value_conversions_unittest.cc
+++ b/components/sync/protocol/proto_value_conversions_unittest.cc
@@ -95,6 +95,7 @@
 DEFINE_SPECIFICS_TO_VALUE_TEST(priority_preference);
 DEFINE_SPECIFICS_TO_VALUE_TEST(reading_list);
 DEFINE_SPECIFICS_TO_VALUE_TEST(search_engine);
+DEFINE_SPECIFICS_TO_VALUE_TEST(security_event);
 DEFINE_SPECIFICS_TO_VALUE_TEST(send_tab_to_self);
 DEFINE_SPECIFICS_TO_VALUE_TEST(session);
 DEFINE_SPECIFICS_TO_VALUE_TEST(synced_notification);
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h
index 81ded8d..cdacea6 100644
--- a/components/sync/protocol/proto_visitors.h
+++ b/components/sync/protocol/proto_visitors.h
@@ -402,6 +402,7 @@
   VISIT(priority_preference);
   VISIT(reading_list);
   VISIT(search_engine);
+  VISIT(security_event);
   VISIT(send_tab_to_self);
   VISIT(session);
   VISIT(synced_notification);
@@ -821,8 +822,11 @@
 
 VISIT_PROTO_FIELDS(const sync_pb::SyncedNotificationSpecifics& proto) {}
 
-VISIT_PROTO_FIELDS(
-    const sync_pb::UserEventSpecifics::GaiaPasswordReuse& proto) {
+VISIT_PROTO_FIELDS(const sync_pb::SecurityEventSpecifics& proto) {
+  VISIT(gaia_password_reuse_event);
+}
+
+VISIT_PROTO_FIELDS(const sync_pb::GaiaPasswordReuse& proto) {
   VISIT(reuse_detected);
   VISIT(reuse_lookup);
   VISIT(dialog_interaction);
@@ -831,34 +835,31 @@
 }
 
 VISIT_PROTO_FIELDS(
-    const sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseDetected&
-        proto) {
+    const sync_pb::GaiaPasswordReuse::PasswordReuseDetected& proto) {
   VISIT(status);
 }
 
-VISIT_PROTO_FIELDS(const sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                       PasswordReuseDetected::SafeBrowsingStatus& proto) {
+VISIT_PROTO_FIELDS(
+    const sync_pb::GaiaPasswordReuse::PasswordReuseDetected::SafeBrowsingStatus&
+        proto) {
   VISIT(enabled);
   VISIT_ENUM(safe_browsing_reporting_population);
 }
 
-VISIT_PROTO_FIELDS(const sync_pb::UserEventSpecifics::GaiaPasswordReuse::
-                       PasswordReuseDialogInteraction& proto) {
+VISIT_PROTO_FIELDS(
+    const sync_pb::GaiaPasswordReuse::PasswordReuseDialogInteraction& proto) {
   VISIT_ENUM(interaction_result);
 }
 
 VISIT_PROTO_FIELDS(
-    const sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordReuseLookup&
-        proto) {
+    const sync_pb::GaiaPasswordReuse::PasswordReuseLookup& proto) {
   VISIT_ENUM(lookup_result);
   VISIT_ENUM(verdict);
   VISIT(verdict_token);
 }
 
 // TODO(markusheintz): Remove.
-VISIT_PROTO_FIELDS(
-    const sync_pb::UserEventSpecifics::GaiaPasswordReuse::PasswordCaptured&
-        proto) {
+VISIT_PROTO_FIELDS(const sync_pb::GaiaPasswordReuse::PasswordCaptured& proto) {
   VISIT_ENUM(event_trigger);
 }
 
diff --git a/components/sync/protocol/protocol_sources.gni b/components/sync/protocol/protocol_sources.gni
index 59f8b8e..169b3ae 100644
--- a/components/sync/protocol/protocol_sources.gni
+++ b/components/sync/protocol/protocol_sources.gni
@@ -24,6 +24,7 @@
   "extension_specifics",
   "favicon_image_specifics",
   "favicon_tracking_specifics",
+  "gaia_password_reuse",
   "get_updates_caller_info",
   "history_delete_directive_specifics",
   "history_status",
@@ -43,6 +44,7 @@
   "priority_preference_specifics",
   "reading_list_specifics",
   "search_engine_specifics",
+  "security_event_specifics",
   "send_tab_to_self_specifics",
   "session_specifics",
   "sync",
diff --git a/components/sync/protocol/security_event_specifics.proto b/components/sync/protocol/security_event_specifics.proto
new file mode 100644
index 0000000..0adaba66
--- /dev/null
+++ b/components/sync/protocol/security_event_specifics.proto
@@ -0,0 +1,24 @@
+// Copyright 2019 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.
+//
+// Sync protocol datatype extension for security events.
+
+// If you change or add any fields in this file, update proto_visitors.h and
+// potentially proto_enum_conversions.{h, cc}.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package sync_pb;
+
+import "gaia_password_reuse.proto";
+
+message SecurityEventSpecifics {
+  // The specific security event to record.
+  oneof event { GaiaPasswordReuse gaia_password_reuse_event = 1; }
+
+  // Time of event, as measured by client in microseconds since Windows epoch.
+  optional int64 event_time_usec = 2;
+}
diff --git a/components/sync/protocol/sync.proto b/components/sync/protocol/sync.proto
index cd268a5..c4745d68 100644
--- a/components/sync/protocol/sync.proto
+++ b/components/sync/protocol/sync.proto
@@ -46,6 +46,7 @@
 import "priority_preference_specifics.proto";
 import "reading_list_specifics.proto";
 import "search_engine_specifics.proto";
+import "security_event_specifics.proto";
 import "send_tab_to_self_specifics.proto";
 import "session_specifics.proto";
 import "sync_enums.proto";
@@ -147,6 +148,7 @@
     UserConsentSpecifics user_consent = 556014;
     MountainShareSpecifics mountain_share = 545005;
     SendTabToSelfSpecifics send_tab_to_self = 601980;
+    SecurityEventSpecifics security_event = 600372;
   }
 }
 
diff --git a/components/sync/protocol/user_event_specifics.proto b/components/sync/protocol/user_event_specifics.proto
index c931f88..0035a89 100644
--- a/components/sync/protocol/user_event_specifics.proto
+++ b/components/sync/protocol/user_event_specifics.proto
@@ -14,6 +14,7 @@
 package sync_pb;
 
 import "user_consent_types.proto";
+import "gaia_password_reuse.proto";
 
 message UserEventSpecifics {
   // Time of event, as measured by client in microseconds since Windows epoch.
@@ -174,108 +175,6 @@
     optional UserConsentTypes.ConsentStatus status = 5 [deprecated = true];
   }
 
-  // User reused their GAIA password on another website.
-  message GaiaPasswordReuse {
-    // Logged when we detect a password re-use event on a non-GAIA site.
-    // If the user hasn’t enabled SafeBrowsing, this will be the last event.
-    message PasswordReuseDetected {
-      message SafeBrowsingStatus {
-        // Is SafeBrowsing enabled?
-        optional bool enabled = 1;
-        // If SafeBrowsing is enabled, is the user opted-in to extended
-        // reporting or Scout?
-        enum ReportingPopulation {
-          REPORTING_POPULATION_UNSPECIFIED = 0;
-          NONE = 1;
-          EXTENDED_REPORTING = 2;
-          SCOUT = 3;
-        }
-        optional ReportingPopulation safe_browsing_reporting_population = 2;
-      }
-      optional SafeBrowsingStatus status = 1;
-    }
-    optional PasswordReuseDetected reuse_detected = 1;
-
-    message PasswordReuseLookup {
-      enum LookupResult {
-        UNSPECIFIED = 0;
-        // URL did match the password reuse whitelist.
-        // No further action required related to this re-use event.
-        WHITELIST_HIT = 1;
-        // The URL exists in the client’s cache.
-        // No further action required related to this re-use event.
-        // This event also logs the ReputationVerdict.
-        CACHE_HIT = 2;
-        // A valid response received from the SafeBrowsing service.
-        // This event also logs the ReputationVerdict.
-        REQUEST_SUCCESS = 3;
-        // Unable to get a valid response from the SafeBrowsing service.
-        REQUEST_FAILURE = 4;
-        // We won't be able to compute reputation for the URL e.g. local IP
-        // address, localhost, not-yet-assigned by ICANN gTLD, etc.
-        URL_UNSUPPORTED = 5;
-        // URL did match enterprise whitelist.
-        // No further action required related to this re-use event.
-        ENTERPRISE_WHITELIST_HIT = 6;
-        // Password reuse lookup is turned off by enterprise policy.
-        // No further action required related to this re-use event.
-        TURNED_OFF_BY_POLICY = 7;
-      }
-      optional LookupResult lookup_result = 1;
-
-      // The following two are only present for CACHE_HIT and REQUEST_SUCCESS.
-      // The verdict received from the Reputation service. This is set only
-      // if the user has SafeBrowsing enabled and we fetch the verdict from the
-      // cache or by sending a verdict request.
-      enum ReputationVerdict {
-        VERDICT_UNSPECIFIED = 0;
-        SAFE = 1;
-        LOW_REPUTATION = 2;
-        PHISHING = 3;
-      }
-      optional ReputationVerdict verdict = 2;
-      // PhishGuard token that identifies the verdict on the server.
-      optional bytes verdict_token = 3;
-    }
-    // Logged when we try to detect whether the password was reused on a
-    // Phishing or a Low-reputation site.
-    optional PasswordReuseLookup reuse_lookup = 2;
-
-    // Logged when the user interacts with the warning UI shown to encourage
-    // password change if the site is Phishing or Low-reputation.
-    message PasswordReuseDialogInteraction {
-      enum InteractionResult {
-        UNSPECIFIED = 0;
-        // The user took the action suggested by the warning prompt.
-        WARNING_ACTION_TAKEN = 1;
-        // The user clicked ignore in the warning prompt.
-        WARNING_ACTION_IGNORED = 2;
-        // The warning UI was ignored, i.e. not interacted with by the user.
-        // This could happen if the user navigates away from the page.
-        WARNING_UI_IGNORED = 3;
-        // The user clicked "Change Password" on chrome://settings page.
-        WARNING_ACTION_TAKEN_ON_SETTINGS = 4;
-      }
-      optional InteractionResult interaction_result = 1;
-    }
-    optional PasswordReuseDialogInteraction dialog_interaction = 3;
-
-    // TODO(markusheintz): Remove
-    // DEPRECATED: DO NOT USE!
-    // Logged when the user logs into Google, and at least once per 28d.
-    message PasswordCaptured {
-      enum EventTrigger {
-        UNSPECIFIED = 0;
-        // Event added because user logged in.
-        USER_LOGGED_IN = 1;
-        // Event added because 28d timer fired.
-        EXPIRED_28D_TIMER = 2;
-      }
-      optional EventTrigger event_trigger = 1;
-    }
-    optional PasswordCaptured password_captured = 4;
-  }
-
   // Logged when the user logs into Google, and at least once per 28d.
   message GaiaPasswordCaptured {
     enum EventTrigger {