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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/app_host/binaries_installer_internal.cc
diff --git a/chrome/browser/extensions/app_host/binaries_installer_internal.cc b/chrome/browser/extensions/app_host/binaries_installer_internal.cc
new file mode 100644
index 0000000000000000000000000000000000000000..866b8b796d99732d860d43ac89d94b1b4a43619e
--- /dev/null
+++ b/chrome/browser/extensions/app_host/binaries_installer_internal.cc
@@ -0,0 +1,278 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/app_host/binaries_installer_internal.h"
+
+#include "base/logging.h"
+#include "base/win/scoped_bstr.h"
+#include "base/win/scoped_comptr.h"
+#include "google_update/google_update_idl.h"
+
+using base::win::ScopedBstr;
+using base::win::ScopedComPtr;
+
+namespace app_host {
+namespace internal {
+
+namespace {
+const wchar_t kBinariesAppId[] = L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}";
+const wchar_t kAppHostAppId[] = L"{FDA71E6F-AC4C-4a00-8B70-9958A68906BF}";
+} // namespace
+
+bool CheckIfDone(IAppBundle* app_bundle, IApp* app, HRESULT* hr) {
+ *hr = S_OK;
+ ScopedComPtr<ICurrentState> current_state;
+ {
+ ScopedComPtr<IDispatch> idispatch;
+ *hr = app->get_currentState(idispatch.Receive());
+ if (FAILED(*hr)) {
+ LOG(ERROR) << "Failed to get App Bundle state: " << *hr;
+ return true;
+ }
+ *hr = current_state.QueryFrom(idispatch);
+ if (FAILED(*hr)) {
+ LOG(ERROR) << "get_currentState return object is not an ICurrentState.";
+ return true;
+ }
+ }
+
+ LONG long_state_value;
+ CurrentState state_value;
+ *hr = current_state->get_stateValue(&long_state_value);
+ if (FAILED(*hr)) {
+ LOG(ERROR) << "Failed to get App Bundle state value: " << *hr;
+ return true;
+ }
+ state_value = static_cast<CurrentState>(long_state_value);
+ switch (state_value) {
+ case STATE_WAITING_TO_CHECK_FOR_UPDATE:
+ case STATE_CHECKING_FOR_UPDATE:
+ case STATE_WAITING_TO_DOWNLOAD:
+ case STATE_RETRYING_DOWNLOAD:
+ case STATE_DOWNLOADING:
+ case STATE_WAITING_TO_INSTALL:
+ case STATE_INSTALLING:
+ case STATE_DOWNLOAD_COMPLETE:
+ case STATE_EXTRACTING:
+ case STATE_APPLYING_DIFFERENTIAL_PATCH:
+ // These states will all transition on their own.
+ break;
+
+ case STATE_UPDATE_AVAILABLE:
+ // If the app bundle is 'busy' we will just wait some more.
+ {
+ VARIANT_BOOL is_busy = VARIANT_TRUE;
+ *hr = app_bundle->isBusy(&is_busy);
+ if (FAILED(*hr)) {
+ LOG(ERROR) << "Failed to check app_bundle->isBusy: " << *hr;
+ return true;
+ }
+
+ if (!is_busy) {
+ *hr = app_bundle->download();
+ if (FAILED(*hr)) {
+ LOG(ERROR) << "Failed to initiate bundle download: " << *hr;
+ return true;
+ }
+ }
+ }
+ break;
+
+ case STATE_READY_TO_INSTALL:
+ // If the app bundle is 'busy' we will just wait some more.
+ {
+ VARIANT_BOOL is_busy = VARIANT_TRUE;
+ *hr = app_bundle->isBusy(&is_busy);
+ if (FAILED(*hr)) {
+ LOG(ERROR) << "Failed to check app_bundle->isBusy: " << *hr;
+ 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.
+ }
+
+ if (!is_busy) {
+ *hr = app_bundle->install();
+ if (FAILED(*hr)) {
+ LOG(ERROR) << "Failed to initiate bundle install: " << *hr;
+ return true;
+ }
+ }
+ }
+ break;
+
+ case STATE_NO_UPDATE:
+ LOG(INFO) << "Google Update reports that the binaries are already "
+ << "installed and up-to-date.";
+ *hr = S_OK;
+ return true;
+
+ case STATE_INSTALL_COMPLETE:
+ return S_OK;
+ *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.
+ return true;
+
+ case STATE_ERROR: {
+ LONG error_code;
+ *hr = current_state->get_errorCode(&error_code);
+ if (FAILED(*hr)) {
+ LOG(ERROR) << "Failed to retrieve bundle error code: " << *hr;
+ return true;
+ }
+ *hr = error_code;
+ ScopedBstr completion_message;
+ HRESULT completion_message_hr =
+ current_state->get_completionMessage(completion_message.Receive());
+ if (FAILED(completion_message_hr)) {
+ LOG(ERROR) << "Bundle installation failed with error " << *hr
+ << ". Error message retrieval failed with error: "
+ << completion_message_hr;
+ } else {
+ LOG(ERROR) << "Bundle installation failed with error " << *hr << ": "
+ << completion_message;
+ }
+ return true;
+ }
+
+ case STATE_INIT:
+ case STATE_PAUSED:
+ LOG(ERROR) << "Unexpected bundle state: " << state_value << ".";
+ *hr = E_FAIL;
+ return true;
+
+ default:
+ LOG(ERROR) << "Unknown bundle state: " << state_value << ".";
+ *hr = E_FAIL;
+ return true;
+ }
+
+ DCHECK_EQ(*hr, S_OK);
+ return false;
+}
+
+HRESULT CreateAppBundle(IGoogleUpdate3* update3, IAppBundle** app_bundle) {
+ HRESULT hr = S_OK;
+ ScopedComPtr<IAppBundle> temp_app_bundle;
+ {
+ ScopedComPtr<IDispatch> idispatch;
+ hr = update3->createAppBundle(idispatch.Receive());
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to createAppBundle: " << hr;
+ return hr;
+ }
+
+ hr = temp_app_bundle.QueryFrom(idispatch);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Unexpected error: " << hr;
+ return hr;
+ }
+ }
+
+ hr = temp_app_bundle->initialize();
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to initialize App Bundle: " << hr;
+ return hr;
+ }
+
+ *app_bundle = temp_app_bundle.Detach();
+
+ return S_OK;
+}
+
+HRESULT GetAppHostAPValue(IGoogleUpdate3* update3, BSTR* ap_value) {
+ ScopedComPtr<IAppBundle> app_bundle;
+ HRESULT hr = CreateAppBundle(update3, app_bundle.Receive());
+ if (FAILED(hr)) {
+ return hr;
+ }
+
+ ScopedComPtr<IApp> app;
+ {
+ ScopedComPtr<IDispatch> idispatch;
+ hr = app_bundle->createInstalledApp(ScopedBstr(kAppHostAppId),
+ idispatch.Receive());
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to configure App Bundle: " << hr;
+ 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.
+ }
+ hr = app.QueryFrom(idispatch);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Unexpected error: " << hr;
+ return hr;
+ }
+ }
+ hr = app->get_ap(ap_value);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to get the App Host AP value.";
+ return hr;
+ }
+ return S_OK;
+}
+
+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
+ HRESULT hr(S_OK);
+ ScopedComPtr<IApp> temp_app;
+ {
+ ScopedComPtr<IDispatch> idispatch;
+ hr = app_bundle->createApp(ScopedBstr(kBinariesAppId), idispatch.Receive());
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to configure App Bundle: " << hr;
+ return hr;
+ }
+ hr = temp_app.QueryFrom(idispatch);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Unexpected error: " << hr;
+ return hr;
+ }
+ }
+ hr = temp_app->put_isEulaAccepted(VARIANT_TRUE);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to set 'EULA Accepted': " << hr;
+ return hr;
+ }
+ hr = temp_app->put_ap(ap);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to set AP value: " << hr;
+ return hr;
+ }
+ *app = temp_app.Detach();
+ return S_OK;
+}
+
+HRESULT CreateGoogleUpdate3(IGoogleUpdate3** update3) {
+ ScopedComPtr<IGoogleUpdate3> temp_update3;
+ HRESULT hr = temp_update3.CreateInstance(CLSID_GoogleUpdate3UserClass);
+ if (FAILED(hr)) {
+ // TODO(erikwright): Try in-proc to support running elevated? According
+ // to update3_utils.cc (CreateGoogleUpdate3UserClass):
+ // The primary reason for the LocalServer activation failing on Vista/Win7
+ // is that COM does not look at HKCU registration when the code is running
+ // elevated. We fall back to an in-proc mode. The in-proc mode is limited to
+ // one install at a time, so we use it only as a backup mechanism.
+ LOG(ERROR) << "Failed to instantiate GoogleUpdate3: " << hr;
+ } else {
+ *update3 = temp_update3.Detach();
+ }
+ return hr;
+}
+
+HRESULT SelectBinariesApValue(IGoogleUpdate3* update3, BSTR* ap_value) {
+ HRESULT hr = GetAppHostAPValue(update3, ap_value);
+ if (FAILED(hr)) {
+ // TODO(erikwright): distinguish between AppHost not installed and an
+ // error in GetAppHostAPValue.
+ // TODO(erikwright): Use stable by default when App Host support is in
+ // stable.
+ ScopedBstr temp_ap_value;
+ if (NULL == temp_ap_value.Allocate(L"2.0-dev-multi-apphost")) {
+ LOG(ERROR) << "Unexpected error in ScopedBstr::Allocate.";
+ hr = E_FAIL;
+ } else {
+ *ap_value = temp_ap_value.Release();
+ hr = S_OK;
+ }
+ }
+
+ return hr;
+}
+
+} // namespace internal
+} // namespace app_host

Powered by Google App Engine
This is Rietveld 408576698