summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/app_host/binaries_installer.cc436
1 files changed, 200 insertions, 236 deletions
diff --git a/chrome/browser/extensions/app_host/binaries_installer.cc b/chrome/browser/extensions/app_host/binaries_installer.cc
index 97e8f056..b5c9693 100644
--- a/chrome/browser/extensions/app_host/binaries_installer.cc
+++ b/chrome/browser/extensions/app_host/binaries_installer.cc
@@ -11,11 +11,11 @@
#include "base/win/scoped_comptr.h"
#include "google_update/google_update_idl.h"
-using base::win::ScopedBstr;
-using base::win::ScopedComPtr;
namespace app_host {
+// Helpers --------------------------------------------------------------------
+
namespace {
const wchar_t kAppHostAppId[] = L"{FDA71E6F-AC4C-4a00-8B70-9958A68906BF}";
@@ -25,89 +25,92 @@ const int kInstallationPollingIntervalMs = 50;
HRESULT CreateInstalledApp(IAppBundle* app_bundle,
const wchar_t* app_guid,
IApp** app) {
- ScopedComPtr<IApp> temp_app;
- ScopedComPtr<IDispatch> idispatch;
- HRESULT hr = app_bundle->createInstalledApp(ScopedBstr(app_guid),
+ base::win::ScopedComPtr<IDispatch> idispatch;
+ HRESULT hr = app_bundle->createInstalledApp(base::win::ScopedBstr(app_guid),
idispatch.Receive());
if (FAILED(hr)) {
LOG(ERROR) << "Failed to configure App Bundle: " << hr;
+ return hr;
+ }
+
+ base::win::ScopedComPtr<IApp> temp_app;
+ hr = temp_app.QueryFrom(idispatch);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Unexpected error querying IApp from "
+ << "IAppBundle->createInstalledApp return value: " << hr;
} else {
- hr = temp_app.QueryFrom(idispatch);
- if (FAILED(hr)) {
- LOG(ERROR) << "Unexpected error querying IApp from "
- << "IAppBundle->createInstalledApp return value: " << hr;
- } else {
- *app = temp_app.Detach();
- }
+ *app = temp_app.Detach();
}
+ return hr;
+}
+HRESULT GetAppHostApValue(IGoogleUpdate3* update3,
+ IAppBundle* app_bundle,
+ BSTR* ap_value) {
+ base::win::ScopedComPtr<IApp> app;
+ HRESULT hr = CreateInstalledApp(app_bundle, kAppHostAppId, app.Receive());
+ if (FAILED(hr))
+ return hr;
+
+ hr = app->get_ap(ap_value);
+ if (FAILED(hr))
+ LOG(ERROR) << "Failed to get the App Host AP value.";
return hr;
}
HRESULT GetCurrentState(IApp* app,
ICurrentState** current_state,
CurrentState* state_value) {
- HRESULT hr = S_OK;
-
- ScopedComPtr<ICurrentState> temp_current_state;
- {
- ScopedComPtr<IDispatch> idispatch;
- hr = app->get_currentState(idispatch.Receive());
- if (FAILED(hr)) {
- LOG(ERROR) << "Failed to get App Bundle state: " << hr;
- } else {
- hr = temp_current_state.QueryFrom(idispatch);
- if (FAILED(hr)) {
- LOG(ERROR) << "Unexpected error querying ICurrentState from "
- << "IApp::get_currentState return value: " << hr;
- }
- }
+ base::win::ScopedComPtr<IDispatch> idispatch;
+ HRESULT hr = app->get_currentState(idispatch.Receive());
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to get App Bundle state: " << hr;
+ return hr;
}
+ base::win::ScopedComPtr<ICurrentState> temp_current_state;
+ hr = temp_current_state.QueryFrom(idispatch);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Unexpected error querying ICurrentState from "
+ << "IApp::get_currentState return value: " << hr;
+ return hr;
+ }
+
+ LONG long_state_value;
+ hr = temp_current_state->get_stateValue(&long_state_value);
if (SUCCEEDED(hr)) {
- LONG long_state_value;
- hr = temp_current_state->get_stateValue(&long_state_value);
- if (FAILED(hr))
- LOG(ERROR) << "Failed to get App Bundle state value: " << hr;
*state_value = static_cast<CurrentState>(long_state_value);
*current_state = temp_current_state.Detach();
+ } else {
+ LOG(ERROR) << "Failed to get App Bundle state value: " << hr;
}
-
return hr;
}
-HRESULT CheckIsBusy(IAppBundle* app_bundle, bool* is_busy) {
+bool CheckIsBusy(IAppBundle* app_bundle, HRESULT* hr) {
VARIANT_BOOL variant_is_busy = VARIANT_TRUE;
- HRESULT hr = app_bundle->isBusy(&variant_is_busy);
- if (FAILED(hr))
- LOG(ERROR) << "Failed to check app_bundle->isBusy: " << hr;
- else
- *is_busy = (variant_is_busy == VARIANT_TRUE);
- return hr;
+ *hr = app_bundle->isBusy(&variant_is_busy);
+ if (FAILED(*hr))
+ LOG(ERROR) << "Failed to check app_bundle->isBusy: " << *hr;
+ return (variant_is_busy == VARIANT_TRUE);
}
-HRESULT OnUpdateAvailable(IAppBundle* app_bundle) {
+void OnUpdateAvailable(IAppBundle* app_bundle, HRESULT* hr) {
// If the app bundle is busy we will just wait some more.
- bool is_busy = false;
- HRESULT hr = CheckIsBusy(app_bundle, &is_busy);
- if (SUCCEEDED(hr) && !is_busy) {
- hr = app_bundle->download();
- if (FAILED(hr))
- LOG(ERROR) << "Failed to initiate bundle download: " << hr;
- }
- return hr;
+ if (CheckIsBusy(app_bundle, hr) || FAILED(*hr))
+ return;
+ *hr = app_bundle->download();
+ if (FAILED(*hr))
+ LOG(ERROR) << "Failed to initiate bundle download: " << *hr;
}
-HRESULT OnReadyToInstall(IAppBundle* app_bundle) {
+void OnReadyToInstall(IAppBundle* app_bundle, HRESULT* hr) {
// If the app bundle is busy we will just wait some more.
- bool is_busy = false;
- HRESULT hr = CheckIsBusy(app_bundle, &is_busy);
- if (SUCCEEDED(hr) && !is_busy) {
- hr = app_bundle->install();
- if (FAILED(hr))
- LOG(ERROR) << "Failed to initiate bundle install: " << hr;
- }
- return hr;
+ if (CheckIsBusy(app_bundle, hr) || FAILED(*hr))
+ return;
+ *hr = app_bundle->install();
+ if (FAILED(*hr))
+ LOG(ERROR) << "Failed to initiate bundle install: " << *hr;
}
HRESULT OnError(ICurrentState* current_state) {
@@ -115,27 +118,25 @@ HRESULT OnError(ICurrentState* current_state) {
HRESULT hr = current_state->get_errorCode(&error_code);
if (FAILED(hr)) {
LOG(ERROR) << "Failed to retrieve bundle error code: " << hr;
- } else {
- 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 hr;
}
- return hr;
+ base::win::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 " << error_code
+ << ". Error message retrieval failed with error: "
+ << completion_message_hr;
+ } else {
+ LOG(ERROR) << "Bundle installation failed with error " << error_code << ": "
+ << completion_message;
+ }
+ return error_code;
}
HRESULT CreateGoogleUpdate3(IGoogleUpdate3** update3) {
- ScopedComPtr<IGoogleUpdate3> temp_update3;
+ base::win::ScopedComPtr<IGoogleUpdate3> temp_update3;
HRESULT hr = temp_update3.CreateInstance(CLSID_GoogleUpdate3UserClass);
if (SUCCEEDED(hr)) {
*update3 = temp_update3.Detach();
@@ -152,211 +153,174 @@ HRESULT CreateGoogleUpdate3(IGoogleUpdate3** update3) {
}
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;
- } else {
- hr = temp_app_bundle.QueryFrom(idispatch);
- if (FAILED(hr)) {
- LOG(ERROR) << "Unexpected error querying IAppBundle from "
- << "IGoogleUpdate3->createAppBundle return value: " << hr;
- }
- }
- }
-
- if (SUCCEEDED(hr)) {
- hr = temp_app_bundle->initialize();
- if (FAILED(hr))
- LOG(ERROR) << "Failed to initialize App Bundle: " << hr;
- else
- *app_bundle = temp_app_bundle.Detach();
+ base::win::ScopedComPtr<IDispatch> idispatch;
+ HRESULT hr = update3->createAppBundle(idispatch.Receive());
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to createAppBundle: " << hr;
+ return hr;
}
- return hr;
-}
-
-HRESULT GetAppHostApValue(IGoogleUpdate3* update3, BSTR* ap_value) {
- ScopedComPtr<IAppBundle> app_bundle;
- HRESULT hr = CreateAppBundle(update3, app_bundle.Receive());
- if (SUCCEEDED(hr)) {
- ScopedComPtr<IApp> app;
- hr = CreateInstalledApp(app_bundle, kAppHostAppId, app.Receive());
- if (SUCCEEDED(hr)) {
- hr = app->get_ap(ap_value);
- if (FAILED(hr))
- LOG(ERROR) << "Failed to get the App Host AP value.";
- }
+ base::win::ScopedComPtr<IAppBundle> temp_app_bundle;
+ hr = temp_app_bundle.QueryFrom(idispatch);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Unexpected error querying IAppBundle from "
+ << "IGoogleUpdate3->createAppBundle return value: " << hr;
+ return hr;
}
+ hr = temp_app_bundle->initialize();
+ if (FAILED(hr))
+ LOG(ERROR) << "Failed to initialize App Bundle: " << hr;
+ else
+ *app_bundle = temp_app_bundle.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;
- }
+HRESULT SelectBinariesApValue(IGoogleUpdate3* update3,
+ IAppBundle* app_bundle,
+ BSTR* ap_value) {
+ HRESULT hr = GetAppHostApValue(update3, app_bundle, ap_value);
+ if (SUCCEEDED(hr))
+ return 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.
+ base::win::ScopedBstr temp_ap_value;
+ if (temp_ap_value.Allocate(L"2.0-dev-multi-apphost") == NULL) {
+ LOG(ERROR) << "Unexpected error in ScopedBstr::Allocate.";
+ return E_FAIL;
}
-
- return hr;
+ *ap_value = temp_ap_value.Release();
+ return S_OK;
}
HRESULT CreateBinariesIApp(IAppBundle* app_bundle, BSTR ap, IApp** app) {
- 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;
- } else {
- hr = temp_app.QueryFrom(idispatch);
- if (FAILED(hr)) {
- LOG(ERROR) << "Unexpected error querying IApp from "
- << "IAppBundle->createApp return value: " << hr;
- }
- }
+ base::win::ScopedComPtr<IDispatch> idispatch;
+ HRESULT hr = app_bundle->createApp(base::win::ScopedBstr(kBinariesAppId),
+ idispatch.Receive());
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to configure App Bundle: " << hr;
+ return hr;
}
- if (SUCCEEDED(hr)) {
- hr = temp_app->put_isEulaAccepted(VARIANT_TRUE);
- if (FAILED(hr))
- LOG(ERROR) << "Failed to set 'EULA Accepted': " << hr;
+ base::win::ScopedComPtr<IApp> temp_app;
+ hr = temp_app.QueryFrom(idispatch);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Unexpected error querying IApp from "
+ << "IAppBundle->createApp return value: " << hr;
+ return hr;
}
- if (SUCCEEDED(hr)) {
- hr = temp_app->put_ap(ap);
- if (FAILED(hr))
- LOG(ERROR) << "Failed to set AP value: " << hr;
+ hr = temp_app->put_isEulaAccepted(VARIANT_TRUE);
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to set 'EULA Accepted': " << hr;
+ return hr;
}
- if (SUCCEEDED(hr))
+ hr = temp_app->put_ap(ap);
+ if (FAILED(hr))
+ LOG(ERROR) << "Failed to set AP value: " << hr;
+ else
*app = temp_app.Detach();
-
return hr;
}
bool CheckIfDone(IAppBundle* app_bundle, IApp* app, HRESULT* hr) {
- ScopedComPtr<ICurrentState> current_state;
+ base::win::ScopedComPtr<ICurrentState> current_state;
CurrentState state_value;
*hr = GetCurrentState(app, current_state.Receive(), &state_value);
-
- bool complete = false;
-
- if (SUCCEEDED(hr)) {
- 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:
- *hr = OnUpdateAvailable(app_bundle);
- break;
-
- case STATE_READY_TO_INSTALL:
- *hr = OnReadyToInstall(app_bundle);
- break;
-
- case STATE_NO_UPDATE:
- LOG(INFO) << "Google Update reports that the binaries are already "
- << "installed and up-to-date.";
- complete = true;
- break;
-
- case STATE_INSTALL_COMPLETE:
- complete = true;
- break;
-
- case STATE_ERROR:
- *hr = OnError(current_state);
- break;
-
- case STATE_INIT:
- case STATE_PAUSED:
- default:
- LOG(ERROR) << "Unexpected bundle state: " << state_value << ".";
- *hr = E_FAIL;
- break;
- }
+ if (FAILED(*hr))
+ return true;
+
+ 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.
+ return false;
+
+ case STATE_UPDATE_AVAILABLE:
+ OnUpdateAvailable(app_bundle, hr);
+ return FAILED(*hr);
+
+ case STATE_READY_TO_INSTALL:
+ OnReadyToInstall(app_bundle, hr);
+ return FAILED(*hr);
+
+ case STATE_NO_UPDATE:
+ LOG(INFO) << "Google Update reports that the binaries are already "
+ << "installed and up-to-date.";
+ return true;
+
+ case STATE_INSTALL_COMPLETE:
+ return true;
+
+ case STATE_ERROR:
+ *hr = OnError(current_state);
+ return FAILED(*hr);
+
+ case STATE_INIT:
+ case STATE_PAUSED:
+ default:
+ LOG(ERROR) << "Unexpected bundle state: " << state_value << ".";
+ *hr = E_FAIL;
+ return true;
}
-
- return FAILED(*hr) || complete;
}
} // namespace
-// Attempts to install the Chrome Binaries using the IGoogleUpdate3 interface.
-// Blocks until the installation process completes, without message pumping.
+
+// Globals --------------------------------------------------------------------
+
HRESULT InstallBinaries() {
base::win::ScopedCOMInitializer initialize_com;
-
- HRESULT hr = S_OK;
if (!initialize_com.succeeded()) {
LOG(ERROR) << "COM initialization failed";
- hr = E_FAIL;
+ return E_FAIL;
}
- ScopedComPtr<IGoogleUpdate3> update3;
- if (SUCCEEDED(hr)) {
- hr = CreateGoogleUpdate3(update3.Receive());
- }
+ base::win::ScopedComPtr<IGoogleUpdate3> update3;
+ HRESULT hr = CreateGoogleUpdate3(update3.Receive());
+ if (FAILED(hr))
+ return hr;
- ScopedBstr ap_value;
- if (SUCCEEDED(hr)) {
- hr = SelectBinariesApValue(update3, ap_value.Receive());
- }
+ base::win::ScopedComPtr<IAppBundle> app_bundle;
+ hr = CreateAppBundle(update3, app_bundle.Receive());
+ if (FAILED(hr))
+ return hr;
- ScopedComPtr<IAppBundle> app_bundle;
- if (SUCCEEDED(hr)) {
- hr = CreateAppBundle(update3, app_bundle.Receive());
- }
+ base::win::ScopedBstr ap_value;
+ hr = SelectBinariesApValue(update3, app_bundle, ap_value.Receive());
+ if (FAILED(hr))
+ return hr;
- ScopedComPtr<IApp> app;
- if (SUCCEEDED(hr)) {
- hr = CreateBinariesIApp(app_bundle, ap_value, app.Receive());
- }
+ base::win::ScopedComPtr<IApp> app;
+ hr = CreateBinariesIApp(app_bundle, ap_value, app.Receive());
+ if (FAILED(hr))
+ return hr;
- if (SUCCEEDED(hr)) {
- hr = app_bundle->checkForUpdate();
- if (FAILED(hr)) {
- LOG(ERROR) << "Failed to initiate update check: " << hr;
- }
+ hr = app_bundle->checkForUpdate();
+ if (FAILED(hr)) {
+ LOG(ERROR) << "Failed to initiate update check: " << hr;
+ return hr;
}
- if (SUCCEEDED(hr)) {
- // We rely upon Omaha to eventually time out and transition to a failure
- // state.
- while (!CheckIfDone(app_bundle, app, &hr)) {
- base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
- kInstallationPollingIntervalMs));
- }
+ // We rely upon Omaha to eventually time out and transition to a failure
+ // state.
+ while (!CheckIfDone(app_bundle, app, &hr)) {
+ base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
+ kInstallationPollingIntervalMs));
}
-
return hr;
}