| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/policy/device_token_fetcher.h" | 5 #include "chrome/browser/policy/device_token_fetcher.h" |
| 6 | 6 |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/path_service.h" | 8 #include "base/path_service.h" |
| 9 #include "base/singleton.h" | 9 #include "base/singleton.h" |
| 10 #include "chrome/browser/guid.h" | 10 #include "chrome/browser/guid.h" |
| 11 #include "chrome/browser/net/gaia/token_service.h" | 11 #include "chrome/browser/net/gaia/token_service.h" |
| 12 #include "chrome/browser/policy/proto/device_management_local.pb.h" | |
| 13 #include "chrome/common/chrome_paths.h" | 12 #include "chrome/common/chrome_paths.h" |
| 14 #include "chrome/common/net/gaia/gaia_constants.h" | 13 #include "chrome/common/net/gaia/gaia_constants.h" |
| 15 #include "chrome/common/notification_details.h" | 14 #include "chrome/common/notification_details.h" |
| 16 #include "chrome/common/notification_service.h" | 15 #include "chrome/common/notification_service.h" |
| 17 #include "chrome/common/notification_source.h" | 16 #include "chrome/common/notification_source.h" |
| 18 #include "chrome/common/notification_type.h" | 17 #include "chrome/common/notification_type.h" |
| 19 | 18 |
| 20 namespace policy { | 19 namespace policy { |
| 21 | 20 |
| 22 namespace em = enterprise_management; | |
| 23 | |
| 24 DeviceTokenFetcher::DeviceTokenFetcher( | 21 DeviceTokenFetcher::DeviceTokenFetcher( |
| 25 DeviceManagementBackend* backend, | 22 DeviceManagementBackend* backend, |
| 26 const FilePath& token_path) | 23 const FilePath& token_path) |
| 27 : token_path_(token_path), | 24 : token_path_(token_path), |
| 28 backend_(backend), | 25 backend_(backend), |
| 29 state_(kStateNotStarted), | 26 state_(kStateNotStarted), |
| 30 device_token_load_complete_event_(true, false) { | 27 device_token_load_complete_event_(true, false) { |
| 31 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 28 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 32 // The token fetcher gets initialized AuthTokens for the device management | 29 // The token fetcher gets initialized AuthTokens for the device management |
| 33 // server are available. Install a notification observer to ensure that the | 30 // server are available. Install a notification observer to ensure that the |
| (...skipping 26 matching lines...) Expand all Loading... |
| 60 const em::DeviceRegisterResponse& response) { | 57 const em::DeviceRegisterResponse& response) { |
| 61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 58 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 62 DCHECK_EQ(kStateRequestingDeviceTokenFromServer, state_); | 59 DCHECK_EQ(kStateRequestingDeviceTokenFromServer, state_); |
| 63 if (response.has_device_management_token()) { | 60 if (response.has_device_management_token()) { |
| 64 device_token_ = response.device_management_token(); | 61 device_token_ = response.device_management_token(); |
| 65 BrowserThread::PostTask( | 62 BrowserThread::PostTask( |
| 66 BrowserThread::FILE, | 63 BrowserThread::FILE, |
| 67 FROM_HERE, | 64 FROM_HERE, |
| 68 NewRunnableFunction(&WriteDeviceTokenToDisk, | 65 NewRunnableFunction(&WriteDeviceTokenToDisk, |
| 69 token_path_, | 66 token_path_, |
| 70 device_token_, | 67 device_token_)); |
| 71 device_id_)); | |
| 72 SetState(kStateHasDeviceToken); | 68 SetState(kStateHasDeviceToken); |
| 73 } else { | 69 } else { |
| 74 NOTREACHED(); | 70 NOTREACHED(); |
| 75 SetState(kStateFailure); | 71 SetState(kStateFailure); |
| 76 } | 72 } |
| 77 } | 73 } |
| 78 | 74 |
| 79 void DeviceTokenFetcher::OnError(DeviceManagementBackend::ErrorCode code) { | 75 void DeviceTokenFetcher::OnError(DeviceManagementBackend::ErrorCode code) { |
| 80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 81 SetState(kStateFailure); | 77 SetState(kStateFailure); |
| 82 } | 78 } |
| 83 | 79 |
| 84 void DeviceTokenFetcher::StartFetching() { | 80 void DeviceTokenFetcher::StartFetching() { |
| 85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 81 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 86 if (state_ == kStateNotStarted) { | 82 if (state_ == kStateNotStarted) { |
| 87 SetState(kStateLoadDeviceTokenFromDisk); | 83 SetState(kStateLoadDeviceTokenFromDisk); |
| 88 // The file calls for loading the persisted token must be deferred to the | 84 // The file calls for loading the persisted token must be deferred to the |
| 89 // FILE thread. | 85 // FILE thread. |
| 90 BrowserThread::PostTask( | 86 BrowserThread::PostTask( |
| 91 BrowserThread::FILE, | 87 BrowserThread::FILE, |
| 92 FROM_HERE, | 88 FROM_HERE, |
| 93 NewRunnableMethod(this, | 89 NewRunnableMethod(this, |
| 94 &DeviceTokenFetcher::AttemptTokenLoadFromDisk)); | 90 &DeviceTokenFetcher::AttemptTokenLoadFromDisk)); |
| 95 } | 91 } |
| 96 } | 92 } |
| 97 | 93 |
| 98 void DeviceTokenFetcher::AttemptTokenLoadFromDisk() { | 94 void DeviceTokenFetcher::AttemptTokenLoadFromDisk() { |
| 99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 96 FetcherState new_state = kStateFailure; |
| 100 if (file_util::PathExists(token_path_)) { | 97 if (file_util::PathExists(token_path_)) { |
| 101 std::string data; | 98 std::string device_token; |
| 102 em::DeviceCredentials device_credentials; | 99 if (file_util::ReadFileToString(token_path_, &device_token_)) { |
| 103 if (file_util::ReadFileToString(token_path_, &data) && | 100 new_state = kStateHasDeviceToken; |
| 104 device_credentials.ParseFromArray(data.c_str(), data.size())) { | |
| 105 device_token_ = device_credentials.device_token(); | |
| 106 device_id_ = device_credentials.device_id(); | |
| 107 if (!device_token_.empty() && !device_id_.empty()) { | |
| 108 BrowserThread::PostTask( | |
| 109 BrowserThread::UI, | |
| 110 FROM_HERE, | |
| 111 NewRunnableMethod(this, | |
| 112 &DeviceTokenFetcher::SetState, | |
| 113 kStateHasDeviceToken)); | |
| 114 return; | |
| 115 } | |
| 116 } | 101 } |
| 102 BrowserThread::PostTask( |
| 103 BrowserThread::UI, |
| 104 FROM_HERE, |
| 105 NewRunnableMethod(this, |
| 106 &DeviceTokenFetcher::SetState, |
| 107 new_state)); |
| 108 return; |
| 117 } | 109 } |
| 118 | 110 |
| 119 BrowserThread::PostTask( | 111 BrowserThread::PostTask( |
| 120 BrowserThread::UI, | 112 BrowserThread::UI, |
| 121 FROM_HERE, | 113 FROM_HERE, |
| 122 NewRunnableMethod(this, | 114 NewRunnableMethod(this, |
| 123 &DeviceTokenFetcher::MakeReadyToRequestDeviceToken)); | 115 &DeviceTokenFetcher::MakeReadyToRequestDeviceToken)); |
| 124 } | 116 } |
| 125 | 117 |
| 126 void DeviceTokenFetcher::MakeReadyToRequestDeviceToken() { | 118 void DeviceTokenFetcher::MakeReadyToRequestDeviceToken() { |
| 127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 128 SetState(kStateReadyToRequestDeviceTokenFromServer); | 120 SetState(kStateReadyToRequestDeviceTokenFromServer); |
| 129 SendServerRequestIfPossible(); | 121 SendServerRequestIfPossible(); |
| 130 } | 122 } |
| 131 | 123 |
| 132 void DeviceTokenFetcher::SendServerRequestIfPossible() { | 124 void DeviceTokenFetcher::SendServerRequestIfPossible() { |
| 133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 134 if (state_ == kStateReadyToRequestDeviceTokenFromServer | 126 if (state_ == kStateReadyToRequestDeviceTokenFromServer |
| 135 && HasAuthToken()) { | 127 && HasAuthToken()) { |
| 136 em::DeviceRegisterRequest register_request; | 128 em::DeviceRegisterRequest register_request; |
| 137 SetState(kStateRequestingDeviceTokenFromServer); | 129 SetState(kStateRequestingDeviceTokenFromServer); |
| 138 backend_->ProcessRegisterRequest(auth_token_, | 130 backend_->ProcessRegisterRequest(auth_token_, |
| 139 GetDeviceID(), | 131 GenerateNewDeviceID(), |
| 140 register_request, | 132 register_request, |
| 141 this); | 133 this); |
| 142 } | 134 } |
| 143 } | 135 } |
| 144 | 136 |
| 145 bool DeviceTokenFetcher::IsTokenPending() { | 137 bool DeviceTokenFetcher::IsTokenPending() { |
| 146 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 147 return !device_token_load_complete_event_.IsSignaled(); | 139 return !device_token_load_complete_event_.IsSignaled(); |
| 148 } | 140 } |
| 149 | 141 |
| 150 std::string DeviceTokenFetcher::GetDeviceToken() { | 142 std::string DeviceTokenFetcher::GetDeviceToken() { |
| 151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 152 device_token_load_complete_event_.Wait(); | 144 device_token_load_complete_event_.Wait(); |
| 153 return device_token_; | 145 return device_token_; |
| 154 } | 146 } |
| 155 | 147 |
| 156 std::string DeviceTokenFetcher::GetDeviceID() { | |
| 157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 158 // As long as access to this is only allowed from the UI thread, no explicit | |
| 159 // locking is necessary to prevent the ID from being generated twice. | |
| 160 if (device_id_.empty()) | |
| 161 device_id_ = GenerateNewDeviceID(); | |
| 162 return device_id_; | |
| 163 } | |
| 164 | |
| 165 void DeviceTokenFetcher::SetState(FetcherState state) { | 148 void DeviceTokenFetcher::SetState(FetcherState state) { |
| 166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 149 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 167 if (state_ == state) | 150 if (state_ == state) |
| 168 return; | 151 return; |
| 169 state_ = state; | 152 state_ = state; |
| 170 if (state == kStateFailure) { | 153 if (state == kStateFailure) { |
| 171 device_token_load_complete_event_.Signal(); | 154 device_token_load_complete_event_.Signal(); |
| 172 } else if (state == kStateHasDeviceToken) { | 155 } else if (state == kStateHasDeviceToken) { |
| 173 device_token_load_complete_event_.Signal(); | 156 device_token_load_complete_event_.Signal(); |
| 174 NotificationService::current()->Notify( | 157 NotificationService::current()->Notify( |
| 175 NotificationType::DEVICE_TOKEN_AVAILABLE, | 158 NotificationType::DEVICE_TOKEN_AVAILABLE, |
| 176 Source<DeviceTokenFetcher>(this), | 159 Source<DeviceTokenFetcher>(this), |
| 177 NotificationService::NoDetails()); | 160 NotificationService::NoDetails()); |
| 178 } | 161 } |
| 179 } | 162 } |
| 180 | 163 |
| 181 void DeviceTokenFetcher::GetDeviceTokenPath(FilePath* token_path) const { | 164 void DeviceTokenFetcher::GetDeviceTokenPath(FilePath* token_path) const { |
| 182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 165 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 183 *token_path = token_path_; | 166 *token_path = token_path_; |
| 184 } | 167 } |
| 185 | 168 |
| 186 bool DeviceTokenFetcher::IsTokenValid() const { | 169 bool DeviceTokenFetcher::IsTokenValid() const { |
| 187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 188 return state_ == kStateHasDeviceToken; | 171 return state_ == kStateHasDeviceToken; |
| 189 } | 172 } |
| 190 | 173 |
| 191 // static | 174 // static |
| 192 void DeviceTokenFetcher::WriteDeviceTokenToDisk( | 175 void DeviceTokenFetcher::WriteDeviceTokenToDisk( |
| 193 const FilePath& path, | 176 const FilePath& path, |
| 194 const std::string& device_token, | 177 const std::string& device_token) { |
| 195 const std::string& device_id) { | 178 file_util::WriteFile(path, |
| 196 em::DeviceCredentials device_credentials; | 179 device_token.c_str(), |
| 197 device_credentials.set_device_token(device_token); | 180 device_token.length()); |
| 198 device_credentials.set_device_id(device_id); | |
| 199 std::string data; | |
| 200 DCHECK(device_credentials.SerializeToString(&data)); | |
| 201 file_util::WriteFile(path, data.c_str(), data.length()); | |
| 202 } | 181 } |
| 203 | 182 |
| 204 // static | 183 // static |
| 205 std::string DeviceTokenFetcher::GenerateNewDeviceID() { | 184 std::string DeviceTokenFetcher::GenerateNewDeviceID() { |
| 206 return guid::GenerateGUID(); | 185 return guid::GenerateGUID(); |
| 207 } | 186 } |
| 208 | 187 |
| 209 } | 188 } |
| OLD | NEW |