[CrOS Tether] Create CryptAuthService and implement it via ChromeCryptAuthService and ChromeCryptAuthServiceFactory.

These classes are currently unused. In a follow-up CL, I will integrate the new service into Chrome and refactor some of the code shared between this new class and the various EasyUnlock classes which share similar functionality.

BUG=672263

Review-Url: https://codereview.chromium.org/2739053002
Cr-Commit-Position: refs/heads/master@{#457194}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index b3682d0..d8af69c 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1895,7 +1895,6 @@
       "//chrome/common/extensions/api",
       "//chrome/common/extensions/api:api_registration",
       "//chrome/common/extensions/api:extensions_features",
-      "//components/cryptauth",
       "//components/drive",
       "//components/proximity_auth/ble",
       "//extensions/components/javascript_dialog_extensions_client",
@@ -3129,6 +3128,10 @@
       "chrome_browser_main_posix.h",
       "chrome_process_singleton.cc",
       "chrome_process_singleton.h",
+      "cryptauth/chrome_cryptauth_service.cc",
+      "cryptauth/chrome_cryptauth_service.h",
+      "cryptauth/chrome_cryptauth_service_factory.cc",
+      "cryptauth/chrome_cryptauth_service_factory.h",
       "custom_handlers/register_protocol_handler_permission_request.cc",
       "custom_handlers/register_protocol_handler_permission_request.h",
       "custom_home_pages_table_model.cc",
@@ -3506,6 +3509,8 @@
       "//chrome/browser/policy:path_parser",
       "//chrome/browser/profile_resetter:profile_reset_report_proto",
       "//chrome/common/importer:interfaces",
+      "//components/cryptauth",
+      "//components/cryptauth/proto",
       "//components/feedback",
       "//components/web_modal",
       "//device/battery",
diff --git a/chrome/browser/cryptauth/OWNERS b/chrome/browser/cryptauth/OWNERS
new file mode 100644
index 0000000..22bd8d3
--- /dev/null
+++ b/chrome/browser/cryptauth/OWNERS
@@ -0,0 +1,6 @@
[email protected]
[email protected]
[email protected]
[email protected]
+
+# COMPONENT: UI>ProximityAuth
diff --git a/chrome/browser/cryptauth/chrome_cryptauth_service.cc b/chrome/browser/cryptauth/chrome_cryptauth_service.cc
new file mode 100644
index 0000000..2af6938
--- /dev/null
+++ b/chrome/browser/cryptauth/chrome_cryptauth_service.cc
@@ -0,0 +1,231 @@
+// 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.
+
+#include "chrome/browser/cryptauth/chrome_cryptauth_service.h"
+
+#include "base/guid.h"
+#include "base/memory/ptr_util.h"
+#include "base/sys_info.h"
+#include "base/time/default_clock.h"
+#include "base/version.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_content_browser_client.h"
+#include "chrome/browser/chromeos/login/easy_unlock/secure_message_delegate_chromeos.h"
+#include "chrome/browser/gcm/gcm_profile_service_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/common/pref_names.h"
+#include "components/cryptauth/cryptauth_client.h"
+#include "components/cryptauth/cryptauth_client_impl.h"
+#include "components/cryptauth/cryptauth_device_manager.h"
+#include "components/cryptauth/cryptauth_enroller.h"
+#include "components/cryptauth/cryptauth_enroller_impl.h"
+#include "components/cryptauth/cryptauth_enrollment_manager.h"
+#include "components/cryptauth/cryptauth_enrollment_utils.h"
+#include "components/cryptauth/cryptauth_gcm_manager_impl.h"
+#include "components/cryptauth/proto/cryptauth_api.pb.h"
+#include "components/cryptauth/secure_message_delegate.h"
+#include "components/gcm_driver/gcm_profile_service.h"
+#include "components/prefs/pref_service.h"
+#include "components/signin/core/browser/profile_oauth2_token_service.h"
+#include "components/signin/core/browser/signin_manager.h"
+#include "components/translate/core/browser/translate_download_manager.h"
+#include "components/version_info/version_info.h"
+
+#if defined(OS_CHROMEOS)
+#include "ash/shell.h"
+#include "base/linux_util.h"
+#include "ui/display/manager/display_manager.h"
+#include "ui/display/manager/managed_display_info.h"
+#include "ui/gfx/geometry/rect.h"
+#endif
+
+namespace {
+
+PrefService* GetLocalState() {
+  return g_browser_process ? g_browser_process->local_state() : nullptr;
+}
+
+// TODO(khorimoto): Refactor this and combine it with EasyUnlockService's
+// static function.
+std::string GetDeviceId() {
+  PrefService* local_state = GetLocalState();
+  if (!local_state)
+    return std::string();
+
+  std::string device_id = local_state->GetString(prefs::kEasyUnlockDeviceId);
+  if (device_id.empty()) {
+    device_id = base::GenerateGUID();
+    local_state->SetString(prefs::kEasyUnlockDeviceId, device_id);
+  }
+  return device_id;
+}
+
+cryptauth::DeviceClassifier GetDeviceClassifierInternal() {
+  cryptauth::DeviceClassifier device_classifier;
+
+#if defined(OS_CHROMEOS)
+  int32_t major_version;
+  int32_t minor_version;
+  int32_t bugfix_version;
+  // TODO(tengs): base::OperatingSystemVersionNumbers only works for ChromeOS.
+  // We need to get different numbers for other platforms.
+  base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version,
+                                               &bugfix_version);
+  device_classifier.set_device_os_version_code(major_version);
+  device_classifier.set_device_type(cryptauth::CHROME);
+#endif
+
+  const std::vector<uint32_t>& version_components =
+      base::Version(version_info::GetVersionNumber()).components();
+  if (!version_components.empty())
+    device_classifier.set_device_software_version_code(version_components[0]);
+
+  device_classifier.set_device_software_package(version_info::GetProductName());
+  return device_classifier;
+}
+
+cryptauth::GcmDeviceInfo GetGcmDeviceInfo() {
+  cryptauth::GcmDeviceInfo device_info;
+  device_info.set_long_device_id(GetDeviceId());
+  device_info.set_device_type(cryptauth::CHROME);
+  device_info.set_device_software_version(version_info::GetVersionNumber());
+  google::protobuf::int64 software_version_code =
+      cryptauth::HashStringToInt64(version_info::GetLastChange());
+  device_info.set_device_software_version_code(software_version_code);
+  ChromeContentBrowserClient chrome_content_browser_client;
+  device_info.set_locale(chrome_content_browser_client.GetApplicationLocale());
+
+#if defined(OS_CHROMEOS)
+  device_info.set_device_model(base::SysInfo::GetLsbReleaseBoard());
+  device_info.set_device_os_version(base::GetLinuxDistro());
+  // The Chrome OS version tracks the Chrome version, so fill in the same value
+  // as |device_software_version_code|.
+  device_info.set_device_os_version_code(software_version_code);
+
+  // There may not be a Shell instance in tests.
+  if (!ash::Shell::HasInstance())
+    return device_info;
+
+  display::DisplayManager* display_manager =
+      ash::Shell::GetInstance()->display_manager();
+  int64_t primary_display_id =
+      display_manager->GetPrimaryDisplayCandidate().id();
+  display::ManagedDisplayInfo display_info =
+      display_manager->GetDisplayInfo(primary_display_id);
+  gfx::Rect bounds = display_info.bounds_in_native();
+
+  // TODO(tengs): This is a heuristic to deterimine the DPI of the display, as
+  // there is no convenient way of getting this information right now.
+  const double dpi = display_info.device_scale_factor() > 1.0f ? 239.0f : 96.0f;
+  double width_in_inches = (bounds.width() - bounds.x()) / dpi;
+  double height_in_inches = (bounds.height() - bounds.y()) / dpi;
+  double diagonal_in_inches = sqrt(width_in_inches * width_in_inches +
+                                   height_in_inches * height_in_inches);
+
+  // Note: The unit of this measument is in milli-inches.
+  device_info.set_device_display_diagonal_mils(diagonal_in_inches * 1000.0);
+#else
+// TODO(tengs): Fill in device information for other platforms.
+#endif
+  return device_info;
+}
+
+std::string GetAccountId(Profile* profile) {
+#if defined(OS_CHROMEOS)
+  SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile);
+#else
+  SigninManager* manager = SigninManagerFactory::GetForProfile(profile);
+#endif
+  return manager ? manager->GetAuthenticatedAccountId() : std::string();
+}
+
+std::unique_ptr<cryptauth::CryptAuthClientFactory> CreateCryptAuthClientFactory(
+    Profile* profile) {
+  return base::MakeUnique<cryptauth::CryptAuthClientFactoryImpl>(
+      ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
+      GetAccountId(profile), profile->GetRequestContext(),
+      GetDeviceClassifierInternal());
+}
+
+std::unique_ptr<cryptauth::SecureMessageDelegate>
+CreateSecureMessageDelegate() {
+#if defined(OS_CHROMEOS)
+  return base::MakeUnique<chromeos::SecureMessageDelegateChromeOS>();
+#else
+  return nullptr;
+#endif
+}
+
+// TODO(khorimoto): When integrating ChromeCryptAuthService into EasyUnlock
+// code, delete this class and refactor
+// proximity_auth::CryptAuthEnrollerFactory.
+class CryptAuthEnrollerFactoryImpl
+    : public cryptauth::CryptAuthEnrollerFactory {
+ public:
+  explicit CryptAuthEnrollerFactoryImpl(Profile* profile) : profile_(profile) {}
+
+  std::unique_ptr<cryptauth::CryptAuthEnroller> CreateInstance() override {
+    return base::MakeUnique<cryptauth::CryptAuthEnrollerImpl>(
+        CreateCryptAuthClientFactory(profile_), CreateSecureMessageDelegate());
+  }
+
+ private:
+  Profile* profile_;
+};
+
+}  // namespace
+
+// static
+std::unique_ptr<ChromeCryptAuthService> ChromeCryptAuthService::Create(
+    Profile* profile) {
+  std::unique_ptr<cryptauth::CryptAuthGCMManager> gcm_manager =
+      base::MakeUnique<cryptauth::CryptAuthGCMManagerImpl>(
+          gcm::GCMProfileServiceFactory::GetForProfile(profile)->driver(),
+          profile->GetPrefs());
+
+  std::unique_ptr<cryptauth::CryptAuthDeviceManager> device_manager =
+      base::MakeUnique<cryptauth::CryptAuthDeviceManager>(
+          base::MakeUnique<base::DefaultClock>(),
+          CreateCryptAuthClientFactory(profile), gcm_manager.get(),
+          profile->GetPrefs());
+
+  std::unique_ptr<cryptauth::CryptAuthEnrollmentManager> enrollment_manager =
+      base::MakeUnique<cryptauth::CryptAuthEnrollmentManager>(
+          base::MakeUnique<base::DefaultClock>(),
+          base::MakeUnique<CryptAuthEnrollerFactoryImpl>(profile),
+          CreateSecureMessageDelegate(), GetGcmDeviceInfo(), gcm_manager.get(),
+          profile->GetPrefs());
+
+  return base::WrapUnique(new ChromeCryptAuthService(
+      std::move(gcm_manager), std::move(device_manager),
+      std::move(enrollment_manager)));
+}
+
+ChromeCryptAuthService::ChromeCryptAuthService(
+    std::unique_ptr<cryptauth::CryptAuthGCMManager> gcm_manager,
+    std::unique_ptr<cryptauth::CryptAuthDeviceManager> device_manager,
+    std::unique_ptr<cryptauth::CryptAuthEnrollmentManager> enrollment_manager)
+    : KeyedService(),
+      cryptauth::CryptAuthService(),
+      gcm_manager_(std::move(gcm_manager)),
+      enrollment_manager_(std::move(enrollment_manager)),
+      device_manager_(std::move(device_manager)) {}
+
+ChromeCryptAuthService::~ChromeCryptAuthService() {}
+
+cryptauth::CryptAuthDeviceManager*
+ChromeCryptAuthService::GetCryptAuthDeviceManager() {
+  return device_manager_.get();
+}
+
+cryptauth::CryptAuthEnrollmentManager*
+ChromeCryptAuthService::GetCryptAuthEnrollmentManager() {
+  return enrollment_manager_.get();
+}
+
+cryptauth::DeviceClassifier ChromeCryptAuthService::GetDeviceClassifier() {
+  return GetDeviceClassifierInternal();
+}
diff --git a/chrome/browser/cryptauth/chrome_cryptauth_service.h b/chrome/browser/cryptauth/chrome_cryptauth_service.h
new file mode 100644
index 0000000..7c6fd485
--- /dev/null
+++ b/chrome/browser/cryptauth/chrome_cryptauth_service.h
@@ -0,0 +1,49 @@
+// 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 CHROME_BROWSER_CRYPTAUTH_CHROME_CRYPTAUTH_SERVICE_H_
+#define CHROME_BROWSER_CRYPTAUTH_CHROME_CRYPTAUTH_SERVICE_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "components/cryptauth/cryptauth_service.h"
+#include "components/cryptauth/proto/cryptauth_api.pb.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+class Profile;
+
+namespace cryptauth {
+class CryptAuthGCMManager;
+}  // namespace cryptauth
+
+// Implementation of cryptauth::CryptAuthService.
+class ChromeCryptAuthService : public KeyedService,
+                               public cryptauth::CryptAuthService {
+ public:
+  static std::unique_ptr<ChromeCryptAuthService> Create(Profile* profile);
+  ~ChromeCryptAuthService() override;
+
+  // cryptauth::CryptAuthService:
+  cryptauth::CryptAuthDeviceManager* GetCryptAuthDeviceManager() override;
+  cryptauth::CryptAuthEnrollmentManager* GetCryptAuthEnrollmentManager()
+      override;
+  cryptauth::DeviceClassifier GetDeviceClassifier() override;
+
+ protected:
+  ChromeCryptAuthService(
+      std::unique_ptr<cryptauth::CryptAuthGCMManager> gcm_manager,
+      std::unique_ptr<cryptauth::CryptAuthDeviceManager> device_manager,
+      std::unique_ptr<cryptauth::CryptAuthEnrollmentManager>
+          enrollment_manager);
+
+ private:
+  std::unique_ptr<cryptauth::CryptAuthGCMManager> gcm_manager_;
+  std::unique_ptr<cryptauth::CryptAuthEnrollmentManager> enrollment_manager_;
+  std::unique_ptr<cryptauth::CryptAuthDeviceManager> device_manager_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeCryptAuthService);
+};
+
+#endif  // CHROME_BROWSER_CRYPTAUTH_CHROME_CRYPTAUTH_SERVICE_H_
diff --git a/chrome/browser/cryptauth/chrome_cryptauth_service_factory.cc b/chrome/browser/cryptauth/chrome_cryptauth_service_factory.cc
new file mode 100644
index 0000000..2471226
--- /dev/null
+++ b/chrome/browser/cryptauth/chrome_cryptauth_service_factory.cc
@@ -0,0 +1,34 @@
+// 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.
+
+#include "chrome/browser/cryptauth/chrome_cryptauth_service_factory.h"
+
+#include "chrome/browser/cryptauth/chrome_cryptauth_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+// static
+cryptauth::CryptAuthService* CryptAuthServiceFactory::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return static_cast<ChromeCryptAuthService*>(
+      GetInstance()->GetServiceForBrowserContext(context, true));
+}
+
+// static
+CryptAuthServiceFactory* CryptAuthServiceFactory::GetInstance() {
+  return base::Singleton<CryptAuthServiceFactory>::get();
+}
+
+CryptAuthServiceFactory::CryptAuthServiceFactory()
+    : BrowserContextKeyedServiceFactory(
+          "CryptAuthService",
+          BrowserContextDependencyManager::GetInstance()) {}
+
+CryptAuthServiceFactory::~CryptAuthServiceFactory() {}
+
+KeyedService* CryptAuthServiceFactory::BuildServiceInstanceFor(
+    content::BrowserContext* context) const {
+  Profile* profile = Profile::FromBrowserContext(context);
+  return ChromeCryptAuthService::Create(profile).release();
+}
diff --git a/chrome/browser/cryptauth/chrome_cryptauth_service_factory.h b/chrome/browser/cryptauth/chrome_cryptauth_service_factory.h
new file mode 100644
index 0000000..d71319c
--- /dev/null
+++ b/chrome/browser/cryptauth/chrome_cryptauth_service_factory.h
@@ -0,0 +1,34 @@
+// 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 CHROME_BROWSER_CRYPTAUTH_CHROME_CRYPTAUTH_SERVICE_FACTORY_H_
+#define CHROME_BROWSER_CRYPTAUTH_CHROME_CRYPTAUTH_SERVICE_FACTORY_H_
+
+#include "base/macros.h"
+#include "base/memory/singleton.h"
+#include "components/cryptauth/cryptauth_service.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+// Factory which is used to access the CryptAuthService singleton.
+class CryptAuthServiceFactory : public BrowserContextKeyedServiceFactory {
+ public:
+  static cryptauth::CryptAuthService* GetForBrowserContext(
+      content::BrowserContext* context);
+
+  static CryptAuthServiceFactory* GetInstance();
+
+ private:
+  friend struct base::DefaultSingletonTraits<CryptAuthServiceFactory>;
+
+  CryptAuthServiceFactory();
+  ~CryptAuthServiceFactory() override;
+
+  // BrowserContextKeyedServiceFactory
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* context) const override;
+
+  DISALLOW_COPY_AND_ASSIGN(CryptAuthServiceFactory);
+};
+
+#endif  // CHROME_BROWSER_CRYPTAUTH_CHROME_CRYPTAUTH_SERVICE_FACTORY_H_
diff --git a/components/cryptauth/BUILD.gn b/components/cryptauth/BUILD.gn
index 01954c4..b6a7a42 100644
--- a/components/cryptauth/BUILD.gn
+++ b/components/cryptauth/BUILD.gn
@@ -36,6 +36,7 @@
     "cryptauth_gcm_manager.h",
     "cryptauth_gcm_manager_impl.cc",
     "cryptauth_gcm_manager_impl.h",
+    "cryptauth_service.h",
     "device_to_device_authenticator.cc",
     "device_to_device_authenticator.h",
     "device_to_device_initiator_operations.cc",
diff --git a/components/cryptauth/cryptauth_service.h b/components/cryptauth/cryptauth_service.h
new file mode 100644
index 0000000..475fbaee
--- /dev/null
+++ b/components/cryptauth/cryptauth_service.h
@@ -0,0 +1,33 @@
+// 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 COMPONENTS_CRYPTAUTH_CRYPTAUTH_SERVICE_H_
+#define COMPONENTS_CRYPTAUTH_CRYPTAUTH_SERVICE_H_
+
+#include "base/macros.h"
+#include "components/cryptauth/proto/cryptauth_api.pb.h"
+
+namespace cryptauth {
+
+class CryptAuthDeviceManager;
+class CryptAuthEnrollmentManager;
+
+// Service which provides access to various CryptAuth singletons.
+class CryptAuthService {
+ public:
+  virtual CryptAuthDeviceManager* GetCryptAuthDeviceManager() = 0;
+  virtual CryptAuthEnrollmentManager* GetCryptAuthEnrollmentManager() = 0;
+  virtual DeviceClassifier GetDeviceClassifier() = 0;
+
+ protected:
+  CryptAuthService() {}
+  virtual ~CryptAuthService() {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CryptAuthService);
+};
+
+}  // namespace cryptauth
+
+#endif  // COMPONENTS_CRYPTAUTH_CRYPTAUTH_SERVICE_H_