Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Side by Side Diff: goopdate/update_response_utils.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « goopdate/update_response_utils.h ('k') | goopdate/update_response_utils_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2010 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15
16 #include "omaha/goopdate/update_response_utils.h"
17 #include "omaha/base/debug.h"
18 #include "omaha/base/error.h"
19 #include "omaha/base/logging.h"
20 #include "omaha/common/lang.h"
21 #include "omaha/common/experiment_labels.h"
22 #include "omaha/goopdate/model.h"
23 #include "omaha/goopdate/server_resource.h"
24 #include "omaha/goopdate/string_formatter.h"
25
26 namespace omaha {
27
28 namespace update_response_utils {
29
30 // TODO(omaha): unit test the functions below.
31
32 // Returns a pointer to the app object corresponding to the appid in the
33 // response object. Returns NULL if the app is not found.
34 const xml::response::App* GetApp(const xml::response::Response& response,
35 const CString& appid) {
36 size_t app_index = 0;
37 for (; app_index < response.apps.size(); ++app_index) {
38 if (!appid.CompareNoCase(response.apps[app_index].appid)) {
39 return &response.apps[app_index];
40 }
41 }
42 return NULL;
43 }
44
45 HRESULT GetInstallData(const std::vector<xml::response::Data>& data,
46 const CString& install_data_index,
47 CString* install_data) {
48 ASSERT1(install_data);
49 if (install_data_index.IsEmpty()) {
50 return S_OK;
51 }
52
53 std::vector<xml::response::Data>::const_iterator it;
54 for (it = data.begin(); it != data.end(); ++it) {
55 if (install_data_index != it->install_data_index) {
56 continue;
57 }
58
59 if (it->status != kResponseStatusOkValue) {
60 ASSERT1(it->status == kResponseDataStatusNoData);
61 return GOOPDATE_E_INVALID_INSTALL_DATA_INDEX;
62 }
63
64 ASSERT1(!it->install_data.IsEmpty());
65 *install_data = it->install_data;
66 return S_OK;
67 }
68
69 return GOOPDATE_E_INVALID_INSTALL_DATA_INDEX;
70 }
71
72 // Check the outer elements first, then check any child elements only if the
73 // outer element was successful.
74 CString GetAppResponseStatus(const xml::response::App& app) {
75 if (_tcsicmp(kResponseStatusOkValue, app.status) != 0) {
76 ASSERT1(!app.status.IsEmpty());
77 return app.status;
78 }
79
80 if (!app.update_check.status.IsEmpty() &&
81 _tcsicmp(kResponseStatusOkValue, app.update_check.status) != 0) {
82 return app.update_check.status;
83 }
84
85 std::vector<xml::response::Data>::const_iterator data;
86 for (data = app.data.begin(); data != app.data.end(); ++data) {
87 if (!data->status.IsEmpty() &&
88 _tcsicmp(kResponseStatusOkValue, data->status) != 0) {
89 return data->status;
90 }
91 }
92
93 if (!app.ping.status.IsEmpty() &&
94 _tcsicmp(kResponseStatusOkValue, app.ping.status) != 0) {
95 return app.ping.status;
96 }
97
98 std::vector<xml::response::Event>::const_iterator it;
99 for (it = app.events.begin(); it != app.events.end(); ++it) {
100 if (!it->status.IsEmpty() &&
101 _tcsicmp(kResponseStatusOkValue, it->status) != 0) {
102 return it->status;
103 }
104 }
105
106 // TODO(omaha): verify that no other elements can report errors
107 // once we've finalized the protocol.
108
109 return app.status;
110 }
111
112 HRESULT BuildApp(const xml::UpdateResponse* update_response,
113 HRESULT code,
114 App* app) {
115 ASSERT1(update_response);
116 ASSERT1(SUCCEEDED(code) || code == GOOPDATE_E_NO_UPDATE_RESPONSE);
117 ASSERT1(app);
118
119 AppVersion* next_version = app->next_version();
120
121 const CString& app_id = app->app_guid_string();
122
123 const xml::response::App* response_app(GetApp(update_response->response(),
124 app_id));
125 ASSERT1(response_app);
126 const xml::response::UpdateCheck& update_check = response_app->update_check;
127
128 VERIFY1(SUCCEEDED(app->put_ttToken(CComBSTR(update_check.tt_token))));
129
130 if (code == GOOPDATE_E_NO_UPDATE_RESPONSE) {
131 return S_OK;
132 }
133
134 for (size_t i = 0; i < update_check.urls.size(); ++i) {
135 HRESULT hr = next_version->AddDownloadBaseUrl(update_check.urls[i]);
136 if (FAILED(hr)) {
137 return hr;
138 }
139 }
140
141 for (size_t i = 0; i < update_check.install_manifest.packages.size(); ++i) {
142 const xml::InstallPackage& package(
143 update_check.install_manifest.packages[i]);
144 HRESULT hr = next_version->AddPackage(package.name,
145 package.size,
146 package.hash);
147 if (FAILED(hr)) {
148 return hr;
149 }
150 }
151
152 CString server_install_data;
153 HRESULT hr = GetInstallData(response_app->data,
154 app->server_install_data_index(),
155 &server_install_data);
156 if (FAILED(hr)) {
157 return hr;
158 }
159 app->set_server_install_data(server_install_data);
160
161 ASSERT1(!next_version->install_manifest());
162 next_version->set_install_manifest(
163 new xml::InstallManifest(update_check.install_manifest));
164
165 // TODO(omaha): it appears the version_ below holds either the manifest
166 // version or the "pv" version, written by the installer. If this is the case,
167 // then it is confusing and perhaps we need to have two different members to
168 // hold these values.
169 ASSERT1(next_version->version().IsEmpty());
170 next_version->set_version(next_version->install_manifest()->version);
171
172 return S_OK;
173 }
174
175 // "noupdate" is an error for fresh installs, but a successful completion in
176 // the cases of silent and on demand updates. The caller is responsible for
177 // interpreting "noupdate" as it sees fit.
178 xml::UpdateResponseResult GetResult(const xml::UpdateResponse* update_response,
179 const CString& appid,
180 const CString& language) {
181 ASSERT1(update_response);
182 const xml::response::App* response_app(GetApp(update_response->response(),
183 appid));
184
185 StringFormatter formatter(language);
186 CString text;
187
188 if (!response_app) {
189 CORE_LOG(L1, (_T("[UpdateResponse::GetResult][app not found][%s]"), appid));
190 VERIFY1(SUCCEEDED(formatter.LoadString(IDS_UNKNOWN_APPLICATION, &text)));
191 return std::make_pair(GOOPDATE_E_NO_SERVER_RESPONSE, text);
192 }
193
194 const xml::response::UpdateCheck& update_check = response_app->update_check;
195 const CString& status = GetAppResponseStatus(*response_app);
196 const CString& display_name = update_check.install_manifest.name;
197
198 ASSERT1(!status.IsEmpty());
199 CORE_LOG(L1, (_T("[UpdateResponse::GetResult][%s][%s][%s]"),
200 appid, status, display_name));
201
202 // ok
203 if (_tcsicmp(kResponseStatusOkValue, status) == 0) {
204 return std::make_pair(S_OK, CString());
205 }
206
207 // noupdate
208 if (_tcsicmp(kResponseStatusNoUpdate, status) == 0) {
209 VERIFY1(SUCCEEDED(formatter.LoadString(IDS_NO_UPDATE_RESPONSE, &text)));
210 return std::make_pair(GOOPDATE_E_NO_UPDATE_RESPONSE, text);
211 }
212
213 // "restricted"
214 if (_tcsicmp(kResponseStatusRestrictedExportCountry, status) == 0) {
215 VERIFY1(SUCCEEDED(formatter.LoadString(IDS_RESTRICTED_RESPONSE_FROM_SERVER,
216 &text)));
217 return std::make_pair(GOOPDATE_E_RESTRICTED_SERVER_RESPONSE, text);
218 }
219
220 // "error-UnKnownApplication"
221 if (_tcsicmp(kResponseStatusUnKnownApplication, status) == 0) {
222 VERIFY1(SUCCEEDED(formatter.LoadString(IDS_UNKNOWN_APPLICATION, &text)));
223 return std::make_pair(GOOPDATE_E_UNKNOWN_APP_SERVER_RESPONSE, text);
224 }
225
226 // "error-OsNotSupported"
227 if (_tcsicmp(kResponseStatusOsNotSupported, status) == 0) {
228 const CString& error_url(update_check.error_url);
229 VERIFY1(SUCCEEDED(formatter.LoadString(IDS_OS_NOT_SUPPORTED, &text)));
230 if (!error_url.IsEmpty()) {
231 // TODO(omaha3): The error URL is no longer in the error string. Either
232 // we need to provide this URL to the client or we need to deprecate
233 // error_url and put this information in the Get Help redirect.
234 // Alternatively, we could have the COM server build error URLs in all
235 // cases. The current UI would still need to build an URL for the entire
236 // bundle, though, because it does not have per-app links.
237 }
238 return std::make_pair(GOOPDATE_E_OS_NOT_SUPPORTED, text);
239 }
240
241 // "error-internal"
242 if (_tcsicmp(kResponseStatusInternalError, status) == 0) {
243 VERIFY1(SUCCEEDED(formatter.FormatMessage(&text,
244 IDS_NON_OK_RESPONSE_FROM_SERVER,
245 status)));
246 return std::make_pair(GOOPDATE_E_INTERNAL_ERROR_SERVER_RESPONSE, text);
247 }
248
249 // "error-hash"
250 if (_tcsicmp(kResponseStatusHashError, status) == 0) {
251 VERIFY1(SUCCEEDED(formatter.FormatMessage(&text,
252 IDS_NON_OK_RESPONSE_FROM_SERVER,
253 status)));
254 return std::make_pair(GOOPDATE_E_SERVER_RESPONSE_NO_HASH, text);
255 }
256
257 // "error-unsupportedprotocol"
258 if (_tcsicmp(kResponseStatusUnsupportedProtocol, status) == 0) {
259 // TODO(omaha): Ideally, we would provide an app-specific URL instead of
260 // just the publisher name. If it was a link, we could use point to a
261 // redirect URL and provide the app GUID rather than somehow obtaining the
262 // app-specific URL.
263 VERIFY1(SUCCEEDED(formatter.FormatMessage(&text,
264 IDS_INSTALLER_OLD,
265 kShortCompanyName)));
266 return std::make_pair(GOOPDATE_E_SERVER_RESPONSE_UNSUPPORTED_PROTOCOL,
267 text);
268 }
269
270 VERIFY1(SUCCEEDED(formatter.FormatMessage(&text,
271 IDS_NON_OK_RESPONSE_FROM_SERVER,
272 status)));
273 return std::make_pair(GOOPDATE_E_UNKNOWN_SERVER_RESPONSE, text);
274 }
275
276 bool IsOmahaUpdateAvailable(const xml::UpdateResponse* update_response) {
277 ASSERT1(update_response);
278 xml::UpdateResponseResult update_response_result(
279 update_response_utils::GetResult(update_response,
280 kGoogleUpdateAppId,
281 lang::GetDefaultLanguage(true)));
282 return update_response_result.first == S_OK;
283 }
284
285 HRESULT ApplyExperimentLabelDeltas(bool is_machine,
286 const xml::UpdateResponse* update_response) {
287 ASSERT1(update_response);
288
289 for (size_t app_index = 0;
290 app_index < update_response->response().apps.size();
291 ++app_index) {
292 const xml::response::App& app = update_response->response().apps[app_index];
293 if (!app.experiments.IsEmpty()) {
294 VERIFY1(IsGuid(app.appid));
295
296 ExperimentLabels labels;
297 VERIFY1(SUCCEEDED(labels.ReadFromRegistry(is_machine, app.appid)));
298
299 if (!labels.DeserializeAndApplyDelta(app.experiments)) {
300 return E_FAIL;
301 }
302
303 HRESULT hr = labels.WriteToRegistry(is_machine, app.appid);
304 if (FAILED(hr)) {
305 return hr;
306 }
307 }
308 }
309
310 return S_OK;
311 }
312
313 } // namespace update_response_utils
314
315 } // namespace omaha
316
OLDNEW
« no previous file with comments | « goopdate/update_response_utils.h ('k') | goopdate/update_response_utils_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698