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

Side by Side Diff: chrome/browser/extensions/app_host/binaries_installer_internal.cc

Issue 10825364: Upon execution of the App Host, ask Omaha to install the Chrome Binaries if they are not present on… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/extensions/app_host/binaries_installer_internal.h"
6
7 #include "base/logging.h"
8 #include "base/win/scoped_bstr.h"
9 #include "base/win/scoped_comptr.h"
10 #include "google_update/google_update_idl.h"
11
12 using base::win::ScopedBstr;
13 using base::win::ScopedComPtr;
14
15 namespace app_host {
16 namespace internal {
17
18 namespace {
19 const wchar_t kBinariesAppId[] = L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}";
20 const wchar_t kAppHostAppId[] = L"{FDA71E6F-AC4C-4a00-8B70-9958A68906BF}";
21 } // namespace
22
23 bool CheckIfDone(IAppBundle* app_bundle, IApp* app, HRESULT* hr) {
24 *hr = S_OK;
25 ScopedComPtr<ICurrentState> current_state;
26 {
27 ScopedComPtr<IDispatch> idispatch;
28 *hr = app->get_currentState(idispatch.Receive());
29 if (FAILED(*hr)) {
30 LOG(ERROR) << "Failed to get App Bundle state: " << *hr;
31 return true;
32 }
33 *hr = current_state.QueryFrom(idispatch);
34 if (FAILED(*hr)) {
35 LOG(ERROR) << "get_currentState return object is not an ICurrentState.";
36 return true;
37 }
38 }
39
40 LONG long_state_value;
41 CurrentState state_value;
42 *hr = current_state->get_stateValue(&long_state_value);
43 if (FAILED(*hr)) {
44 LOG(ERROR) << "Failed to get App Bundle state value: " << *hr;
45 return true;
46 }
47 state_value = static_cast<CurrentState>(long_state_value);
48 switch (state_value) {
49 case STATE_WAITING_TO_CHECK_FOR_UPDATE:
50 case STATE_CHECKING_FOR_UPDATE:
51 case STATE_WAITING_TO_DOWNLOAD:
52 case STATE_RETRYING_DOWNLOAD:
53 case STATE_DOWNLOADING:
54 case STATE_WAITING_TO_INSTALL:
55 case STATE_INSTALLING:
56 case STATE_DOWNLOAD_COMPLETE:
57 case STATE_EXTRACTING:
58 case STATE_APPLYING_DIFFERENTIAL_PATCH:
59 // These states will all transition on their own.
60 break;
61
62 case STATE_UPDATE_AVAILABLE:
63 // If the app bundle is 'busy' we will just wait some more.
64 {
65 VARIANT_BOOL is_busy = VARIANT_TRUE;
66 *hr = app_bundle->isBusy(&is_busy);
67 if (FAILED(*hr)) {
68 LOG(ERROR) << "Failed to check app_bundle->isBusy: " << *hr;
69 return true;
70 }
71
72 if (!is_busy) {
73 *hr = app_bundle->download();
74 if (FAILED(*hr)) {
75 LOG(ERROR) << "Failed to initiate bundle download: " << *hr;
76 return true;
77 }
78 }
79 }
80 break;
81
82 case STATE_READY_TO_INSTALL:
83 // If the app bundle is 'busy' we will just wait some more.
84 {
85 VARIANT_BOOL is_busy = VARIANT_TRUE;
86 *hr = app_bundle->isBusy(&is_busy);
87 if (FAILED(*hr)) {
88 LOG(ERROR) << "Failed to check app_bundle->isBusy: " << *hr;
89 return true;
robertshield 2012/08/16 13:08:16 as a readability thing, could we reduce the number
erikwright (departed) 2012/08/16 21:05:15 Done.
90 }
91
92 if (!is_busy) {
93 *hr = app_bundle->install();
94 if (FAILED(*hr)) {
95 LOG(ERROR) << "Failed to initiate bundle install: " << *hr;
96 return true;
97 }
98 }
99 }
100 break;
101
102 case STATE_NO_UPDATE:
103 LOG(INFO) << "Google Update reports that the binaries are already "
104 << "installed and up-to-date.";
105 *hr = S_OK;
106 return true;
107
108 case STATE_INSTALL_COMPLETE:
109 return S_OK;
110 *hr = S_OK;
robertshield 2012/08/16 13:08:16 this should be warning about unreachable code
erikwright (departed) 2012/08/16 21:05:15 Done.
111 return true;
112
113 case STATE_ERROR: {
114 LONG error_code;
115 *hr = current_state->get_errorCode(&error_code);
116 if (FAILED(*hr)) {
117 LOG(ERROR) << "Failed to retrieve bundle error code: " << *hr;
118 return true;
119 }
120 *hr = error_code;
121 ScopedBstr completion_message;
122 HRESULT completion_message_hr =
123 current_state->get_completionMessage(completion_message.Receive());
124 if (FAILED(completion_message_hr)) {
125 LOG(ERROR) << "Bundle installation failed with error " << *hr
126 << ". Error message retrieval failed with error: "
127 << completion_message_hr;
128 } else {
129 LOG(ERROR) << "Bundle installation failed with error " << *hr << ": "
130 << completion_message;
131 }
132 return true;
133 }
134
135 case STATE_INIT:
136 case STATE_PAUSED:
137 LOG(ERROR) << "Unexpected bundle state: " << state_value << ".";
138 *hr = E_FAIL;
139 return true;
140
141 default:
142 LOG(ERROR) << "Unknown bundle state: " << state_value << ".";
143 *hr = E_FAIL;
144 return true;
145 }
146
147 DCHECK_EQ(*hr, S_OK);
148 return false;
149 }
150
151 HRESULT CreateAppBundle(IGoogleUpdate3* update3, IAppBundle** app_bundle) {
152 HRESULT hr = S_OK;
153 ScopedComPtr<IAppBundle> temp_app_bundle;
154 {
155 ScopedComPtr<IDispatch> idispatch;
156 hr = update3->createAppBundle(idispatch.Receive());
157 if (FAILED(hr)) {
158 LOG(ERROR) << "Failed to createAppBundle: " << hr;
159 return hr;
160 }
161
162 hr = temp_app_bundle.QueryFrom(idispatch);
163 if (FAILED(hr)) {
164 LOG(ERROR) << "Unexpected error: " << hr;
165 return hr;
166 }
167 }
168
169 hr = temp_app_bundle->initialize();
170 if (FAILED(hr)) {
171 LOG(ERROR) << "Failed to initialize App Bundle: " << hr;
172 return hr;
173 }
174
175 *app_bundle = temp_app_bundle.Detach();
176
177 return S_OK;
178 }
179
180 HRESULT GetAppHostAPValue(IGoogleUpdate3* update3, BSTR* ap_value) {
181 ScopedComPtr<IAppBundle> app_bundle;
182 HRESULT hr = CreateAppBundle(update3, app_bundle.Receive());
183 if (FAILED(hr)) {
184 return hr;
185 }
186
187 ScopedComPtr<IApp> app;
188 {
189 ScopedComPtr<IDispatch> idispatch;
190 hr = app_bundle->createInstalledApp(ScopedBstr(kAppHostAppId),
191 idispatch.Receive());
192 if (FAILED(hr)) {
193 LOG(ERROR) << "Failed to configure App Bundle: " << hr;
194 return hr;
robertshield 2012/08/16 13:08:16 I would encourage you to rewrite stuff like this w
erikwright (departed) 2012/08/16 21:05:15 Done.
195 }
196 hr = app.QueryFrom(idispatch);
197 if (FAILED(hr)) {
198 LOG(ERROR) << "Unexpected error: " << hr;
199 return hr;
200 }
201 }
202 hr = app->get_ap(ap_value);
203 if (FAILED(hr)) {
204 LOG(ERROR) << "Failed to get the App Host AP value.";
205 return hr;
206 }
207 return S_OK;
208 }
209
210 HRESULT CreateBinariesIApp(IAppBundle* app_bundle, BSTR ap, IApp** app) {
robertshield 2012/08/16 13:08:16 app, ap, and app_bundle :) maybe ap -> "channel_va
erikwright (departed) 2012/08/16 21:05:15 What does AP stand for?
robertshield 2012/08/16 21:15:53 That knowledge is lost in the sands of time. Omaha
211 HRESULT hr(S_OK);
212 ScopedComPtr<IApp> temp_app;
213 {
214 ScopedComPtr<IDispatch> idispatch;
215 hr = app_bundle->createApp(ScopedBstr(kBinariesAppId), idispatch.Receive());
216 if (FAILED(hr)) {
217 LOG(ERROR) << "Failed to configure App Bundle: " << hr;
218 return hr;
219 }
220 hr = temp_app.QueryFrom(idispatch);
221 if (FAILED(hr)) {
222 LOG(ERROR) << "Unexpected error: " << hr;
223 return hr;
224 }
225 }
226 hr = temp_app->put_isEulaAccepted(VARIANT_TRUE);
227 if (FAILED(hr)) {
228 LOG(ERROR) << "Failed to set 'EULA Accepted': " << hr;
229 return hr;
230 }
231 hr = temp_app->put_ap(ap);
232 if (FAILED(hr)) {
233 LOG(ERROR) << "Failed to set AP value: " << hr;
234 return hr;
235 }
236 *app = temp_app.Detach();
237 return S_OK;
238 }
239
240 HRESULT CreateGoogleUpdate3(IGoogleUpdate3** update3) {
241 ScopedComPtr<IGoogleUpdate3> temp_update3;
242 HRESULT hr = temp_update3.CreateInstance(CLSID_GoogleUpdate3UserClass);
243 if (FAILED(hr)) {
244 // TODO(erikwright): Try in-proc to support running elevated? According
245 // to update3_utils.cc (CreateGoogleUpdate3UserClass):
246 // The primary reason for the LocalServer activation failing on Vista/Win7
247 // is that COM does not look at HKCU registration when the code is running
248 // elevated. We fall back to an in-proc mode. The in-proc mode is limited to
249 // one install at a time, so we use it only as a backup mechanism.
250 LOG(ERROR) << "Failed to instantiate GoogleUpdate3: " << hr;
251 } else {
252 *update3 = temp_update3.Detach();
253 }
254 return hr;
255 }
256
257 HRESULT SelectBinariesApValue(IGoogleUpdate3* update3, BSTR* ap_value) {
258 HRESULT hr = GetAppHostAPValue(update3, ap_value);
259 if (FAILED(hr)) {
260 // TODO(erikwright): distinguish between AppHost not installed and an
261 // error in GetAppHostAPValue.
262 // TODO(erikwright): Use stable by default when App Host support is in
263 // stable.
264 ScopedBstr temp_ap_value;
265 if (NULL == temp_ap_value.Allocate(L"2.0-dev-multi-apphost")) {
266 LOG(ERROR) << "Unexpected error in ScopedBstr::Allocate.";
267 hr = E_FAIL;
268 } else {
269 *ap_value = temp_ap_value.Release();
270 hr = S_OK;
271 }
272 }
273
274 return hr;
275 }
276
277 } // namespace internal
278 } // namespace app_host
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698