device_token_fetcher.cc revision 513209b27ff55e2841eac0e4120199c23acce758
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/policy/device_token_fetcher.h" 6 7#include "base/file_util.h" 8#include "base/path_service.h" 9#include "base/singleton.h" 10#include "chrome/browser/net/gaia/token_service.h" 11#include "chrome/browser/policy/mock_device_management_backend.h" 12#include "chrome/common/chrome_paths.h" 13#include "chrome/common/net/gaia/gaia_constants.h" 14#include "chrome/common/notification_details.h" 15#include "chrome/common/notification_service.h" 16#include "chrome/common/notification_source.h" 17#include "chrome/common/notification_type.h" 18 19namespace { 20 21static const char kPlaceholderDeviceID[] = "placeholder_device_id"; 22 23} // namespace 24 25namespace policy { 26 27bool UserDirDeviceTokenPathProvider::GetPath(FilePath* path) const { 28 FilePath dir_path; 29 if ( PathService::Get(chrome::DIR_USER_DATA, &dir_path)) 30 return false; 31 *path = dir_path.Append(FILE_PATH_LITERAL("DeviceManagementToken")); 32 return true; 33} 34 35DeviceTokenFetcher::DeviceTokenFetcher( 36 DeviceManagementBackend* backend, 37 StoredDeviceTokenPathProvider* path_provider) 38 : backend_(backend), 39 path_provider_(path_provider), 40 state_(kStateLoadDeviceTokenFromDisk), 41 device_token_load_complete_event_(true, false) { 42} 43 44void DeviceTokenFetcher::Observe(NotificationType type, 45 const NotificationSource& source, 46 const NotificationDetails& details) { 47 DCHECK(CalledOnValidThread()); 48 if (type == NotificationType::TOKEN_AVAILABLE) { 49 const Source<TokenService> token_service(source); 50 const TokenService::TokenAvailableDetails* token_details = 51 Details<const TokenService::TokenAvailableDetails>(details).ptr(); 52 if (token_details->service() == GaiaConstants::kDeviceManagementService && 53 state_ < kStateHasAuthToken) { 54 DCHECK_EQ(kStateFetchingAuthToken, state_); 55 SetState(kStateHasAuthToken); 56 em::DeviceRegisterRequest register_request; 57 backend_->ProcessRegisterRequest(token_details->token(), 58 GetDeviceID(), 59 register_request, 60 this); 61 } 62 } else { 63 NOTREACHED(); 64 } 65} 66 67void DeviceTokenFetcher::HandleRegisterResponse( 68 const em::DeviceRegisterResponse& response) { 69 DCHECK(CalledOnValidThread()); 70 DCHECK_EQ(kStateHasAuthToken, state_); 71 if (response.has_device_management_token()) { 72 device_token_ = response.device_management_token(); 73 FilePath device_token_path; 74 if (path_provider_->GetPath(&device_token_path)) { 75 BrowserThread::PostTask( 76 BrowserThread::FILE, 77 FROM_HERE, 78 NewRunnableFunction(&WriteDeviceTokenToDisk, 79 device_token_path, 80 device_token_)); 81 } 82 SetState(kStateHasDeviceToken); 83 } else { 84 NOTREACHED(); 85 SetState(kStateFailure); 86 } 87} 88 89void DeviceTokenFetcher::OnError(DeviceManagementBackend::ErrorCode code) { 90 DCHECK(CalledOnValidThread()); 91 SetState(kStateFailure); 92} 93 94void DeviceTokenFetcher::StartFetching() { 95 DCHECK(CalledOnValidThread()); 96 if (state_ < kStateHasDeviceToken) { 97 FilePath device_token_path; 98 FetcherState new_state = kStateFailure; 99 if (path_provider_->GetPath(&device_token_path)) { 100 if (file_util::PathExists(device_token_path)) { 101 std::string device_token; 102 if (file_util::ReadFileToString(device_token_path, &device_token_)) { 103 new_state = kStateHasDeviceToken; 104 } 105 } 106 if (new_state != kStateHasDeviceToken) { 107 new_state = kStateFetchingAuthToken; 108 // The policy provider gets initialized with the PrefService and Profile 109 // before ServiceTokens are available. Install a notification observer 110 // to ensure that the device management token gets fetched after the 111 // AuthTokens are available if it's needed. 112 registrar_.Add(this, 113 NotificationType::TOKEN_AVAILABLE, 114 NotificationService::AllSources()); 115 } 116 } 117 SetState(new_state); 118 } 119} 120 121bool DeviceTokenFetcher::IsTokenPending() { 122 DCHECK(CalledOnValidThread()); 123 return !device_token_load_complete_event_.IsSignaled(); 124} 125 126std::string DeviceTokenFetcher::GetDeviceToken() { 127 DCHECK(CalledOnValidThread()); 128 device_token_load_complete_event_.Wait(); 129 return device_token_; 130} 131 132void DeviceTokenFetcher::SetState(FetcherState state) { 133 DCHECK(CalledOnValidThread()); 134 state_ = state; 135 if (state == kStateFailure) { 136 device_token_load_complete_event_.Signal(); 137 } else if (state == kStateHasDeviceToken) { 138 device_token_load_complete_event_.Signal(); 139 NotificationService::current()->Notify( 140 NotificationType::DEVICE_TOKEN_AVAILABLE, 141 Source<DeviceTokenFetcher>(this), 142 NotificationService::NoDetails()); 143 } 144} 145 146bool DeviceTokenFetcher::IsTokenValid() const { 147 return state_ == kStateHasDeviceToken; 148} 149 150// static 151void DeviceTokenFetcher::WriteDeviceTokenToDisk( 152 const FilePath& path, 153 const std::string& device_token) { 154 file_util::WriteFile(path, 155 device_token.c_str(), 156 device_token.length()); 157} 158 159// static 160std::string DeviceTokenFetcher::GetDeviceID() { 161 // TODO(danno): fetch a real device_id 162 return kPlaceholderDeviceID; 163} 164 165} 166