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 |