Index: chrome/browser/policy/device_token_fetcher.cc |
diff --git a/chrome/browser/policy/device_token_fetcher.cc b/chrome/browser/policy/device_token_fetcher.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9362747a8caa12b7405ddba5cd011ef9bf1ef7c3 |
--- /dev/null |
+++ b/chrome/browser/policy/device_token_fetcher.cc |
@@ -0,0 +1,165 @@ |
+// Copyright (c) 2010 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/policy/device_token_fetcher.h" |
+ |
+#include "base/file_util.h" |
+#include "base/path_service.h" |
+#include "base/singleton.h" |
+#include "chrome/browser/net/gaia/token_service.h" |
+#include "chrome/browser/policy/mock_device_management_backend.h" |
+#include "chrome/common/chrome_paths.h" |
+#include "chrome/common/net/gaia/gaia_constants.h" |
+#include "chrome/common/notification_details.h" |
+#include "chrome/common/notification_service.h" |
+#include "chrome/common/notification_source.h" |
+#include "chrome/common/notification_type.h" |
+ |
+namespace { |
+ |
+static const char kPlaceholderDeviceID[] = "placeholder_device_id"; |
+ |
+} // namespace |
+ |
+namespace policy { |
+ |
+bool UserDirDeviceTokenPathProvider::GetPath(FilePath* path) const { |
+ FilePath dir_path; |
+ if ( PathService::Get(chrome::DIR_USER_DATA, &dir_path)) |
+ return false; |
+ *path = dir_path.Append(FILE_PATH_LITERAL("DeviceManagementToken")); |
+ return true; |
+} |
+ |
+DeviceTokenFetcher::DeviceTokenFetcher( |
+ DeviceManagementBackend* backend, |
+ StoredDeviceTokenPathProvider* path_provider) |
+ : backend_(backend), |
+ path_provider_(path_provider), |
+ state_(kStateLoadDeviceTokenFromDisk), |
+ device_token_load_complete_event_(true, false) { |
+} |
+ |
+void DeviceTokenFetcher::Observe(NotificationType type, |
+ const NotificationSource& source, |
+ const NotificationDetails& details) { |
+ DCHECK(CalledOnValidThread()); |
+ if (type == NotificationType::TOKEN_AVAILABLE) { |
+ const Source<TokenService> token_service(source); |
+ const TokenService::TokenAvailableDetails* token_details = |
+ Details<const TokenService::TokenAvailableDetails>(details).ptr(); |
+ if (token_details->service() == GaiaConstants::kDeviceManagementService && |
+ state_ < kStateHasAuthToken) { |
+ DCHECK_EQ(kStateFetchingAuthToken, state_); |
+ SetState(kStateHasAuthToken); |
+ em::DeviceRegisterRequest register_request; |
+ backend_->ProcessRegisterRequest(token_details->token(), |
+ GetDeviceID(), |
+ register_request, |
+ this); |
+ } |
+ } else { |
+ NOTREACHED(); |
+ } |
+} |
+ |
+void DeviceTokenFetcher::HandleRegisterResponse( |
+ const em::DeviceRegisterResponse& response) { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK_EQ(kStateHasAuthToken, state_); |
+ if (response.has_device_management_token()) { |
+ device_token_ = response.device_management_token(); |
+ FilePath device_token_path; |
+ if (path_provider_->GetPath(&device_token_path)) { |
+ BrowserThread::PostTask( |
+ BrowserThread::FILE, |
+ FROM_HERE, |
+ NewRunnableFunction(&WriteDeviceTokenToDisk, |
+ device_token_path, |
+ device_token_)); |
+ } |
+ SetState(kStateHasDeviceToken); |
+ } else { |
+ NOTREACHED(); |
+ SetState(kStateFailure); |
+ } |
+} |
+ |
+void DeviceTokenFetcher::OnError(DeviceManagementBackend::ErrorCode code) { |
+ DCHECK(CalledOnValidThread()); |
+ SetState(kStateFailure); |
+} |
+ |
+void DeviceTokenFetcher::StartFetching() { |
+ DCHECK(CalledOnValidThread()); |
+ if (state_ < kStateHasDeviceToken) { |
+ FilePath device_token_path; |
+ FetcherState new_state = kStateFailure; |
+ if (path_provider_->GetPath(&device_token_path)) { |
+ if (file_util::PathExists(device_token_path)) { |
+ std::string device_token; |
+ if (file_util::ReadFileToString(device_token_path, &device_token_)) { |
+ new_state = kStateHasDeviceToken; |
+ } |
+ } |
+ if (new_state != kStateHasDeviceToken) { |
+ new_state = kStateFetchingAuthToken; |
+ // The policy provider gets initialized with the PrefService and Profile |
+ // before ServiceTokens are available. Install a notification observer |
+ // to ensure that the device management token gets fetched after the |
+ // AuthTokens are available if it's needed. |
+ registrar_.Add(this, |
+ NotificationType::TOKEN_AVAILABLE, |
+ NotificationService::AllSources()); |
+ } |
+ } |
+ SetState(new_state); |
+ } |
+} |
+ |
+bool DeviceTokenFetcher::IsTokenPending() { |
+ DCHECK(CalledOnValidThread()); |
+ return !device_token_load_complete_event_.IsSignaled(); |
+} |
+ |
+std::string DeviceTokenFetcher::GetDeviceToken() { |
+ DCHECK(CalledOnValidThread()); |
+ device_token_load_complete_event_.Wait(); |
+ return device_token_; |
+} |
+ |
+void DeviceTokenFetcher::SetState(FetcherState state) { |
+ DCHECK(CalledOnValidThread()); |
+ state_ = state; |
+ if (state == kStateFailure) { |
+ device_token_load_complete_event_.Signal(); |
+ } else if (state == kStateHasDeviceToken) { |
+ device_token_load_complete_event_.Signal(); |
+ NotificationService::current()->Notify( |
+ NotificationType::DEVICE_TOKEN_AVAILABLE, |
+ Source<DeviceTokenFetcher>(this), |
+ NotificationService::NoDetails()); |
+ } |
+} |
+ |
+bool DeviceTokenFetcher::IsTokenValid() const { |
+ return state_ == kStateHasDeviceToken; |
+} |
+ |
+// static |
+void DeviceTokenFetcher::WriteDeviceTokenToDisk( |
+ const FilePath& path, |
+ const std::string& device_token) { |
+ file_util::WriteFile(path, |
+ device_token.c_str(), |
+ device_token.length()); |
+} |
+ |
+// static |
+std::string DeviceTokenFetcher::GetDeviceID() { |
+ // TODO(danno): fetch a real device_id |
+ return kPlaceholderDeviceID; |
+} |
+ |
+} |