| Index: goopdate/download_manager.cc
|
| diff --git a/goopdate/download_manager.cc b/goopdate/download_manager.cc
|
| deleted file mode 100644
|
| index 49674c3b9d9613bad827ef97cf539fc40634f1b9..0000000000000000000000000000000000000000
|
| --- a/goopdate/download_manager.cc
|
| +++ /dev/null
|
| @@ -1,614 +0,0 @@
|
| -// Copyright 2007-2010 Google Inc.
|
| -//
|
| -// Licensed under the Apache License, Version 2.0 (the "License");
|
| -// you may not use this file except in compliance with the License.
|
| -// You may obtain a copy of the License at
|
| -//
|
| -// http://www.apache.org/licenses/LICENSE-2.0
|
| -//
|
| -// Unless required by applicable law or agreed to in writing, software
|
| -// distributed under the License is distributed on an "AS IS" BASIS,
|
| -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| -// See the License for the specific language governing permissions and
|
| -// limitations under the License.
|
| -// ========================================================================
|
| -//
|
| -// The download manager uses the network request to download the remote file.
|
| -// Once the download is complete, the download manager stores the file in
|
| -// the package cache, then it copies the file out to a location specified
|
| -// by the caller.
|
| -
|
| -// TODO(omaha): the path where to copy the file is hardcoded. Change the
|
| -// class interface to allow the path as a parameter.
|
| -
|
| -#include "omaha/goopdate/download_manager.h"
|
| -#include <algorithm>
|
| -#include <vector>
|
| -#include "omaha/base/debug.h"
|
| -#include "omaha/base/error.h"
|
| -#include "omaha/base/file.h"
|
| -#include "omaha/base/logging.h"
|
| -#include "omaha/base/path.h"
|
| -#include "omaha/base/scoped_impersonation.h"
|
| -#include "omaha/base/safe_format.h"
|
| -#include "omaha/base/string.h"
|
| -#include "omaha/base/synchronized.h"
|
| -#include "omaha/base/user_rights.h"
|
| -#include "omaha/base/utils.h"
|
| -#include "omaha/common/config_manager.h"
|
| -#include "omaha/common/const_goopdate.h"
|
| -#include "omaha/goopdate/model.h"
|
| -#include "omaha/goopdate/package_cache.h"
|
| -#include "omaha/goopdate/server_resource.h"
|
| -#include "omaha/goopdate/string_formatter.h"
|
| -#include "omaha/goopdate/worker_metrics.h"
|
| -#include "omaha/goopdate/worker_utils.h"
|
| -#include "omaha/net/bits_request.h"
|
| -#include "omaha/net/http_client.h"
|
| -#include "omaha/net/network_request.h"
|
| -#include "omaha/net/net_utils.h"
|
| -#include "omaha/net/simple_request.h"
|
| -
|
| -namespace omaha {
|
| -
|
| -namespace {
|
| -
|
| -// Creates and initializes an instance of the NetworkRequest for the
|
| -// DownloadManager to use. Defines the fallback chain: BITS, WinHttp.
|
| -HRESULT CreateNetworkRequest(NetworkRequest** network_request_ptr) {
|
| - NetworkConfig* network_config = NULL;
|
| - NetworkConfigManager& network_manager = NetworkConfigManager::Instance();
|
| - HRESULT hr = network_manager.GetUserNetworkConfig(&network_config);
|
| - if (FAILED(hr)) {
|
| - return hr;
|
| - }
|
| - const NetworkConfig::Session& session(network_config->session());
|
| - NetworkRequest* network_request(new NetworkRequest(session));
|
| -
|
| - // TODO(omaha): provide a mechanism for different timeout values in
|
| - // silent and interactive downloads.
|
| -
|
| - // BITS transfers files only when the job owner is logged on. If the process
|
| - // "Run As" another user, an empty BITS job gets created in suspended state
|
| - // but there is no way to manipulate the job, nor cancel it.
|
| - bool is_logged_on = false;
|
| - hr = UserRights::UserIsLoggedOnInteractively(&is_logged_on);
|
| - if (SUCCEEDED(hr) && is_logged_on) {
|
| - BitsRequest* bits_request(new BitsRequest);
|
| - bits_request->set_minimum_retry_delay(kSecPerMin);
|
| - bits_request->set_no_progress_timeout(5 * kSecPerMin);
|
| - network_request->AddHttpRequest(bits_request);
|
| - }
|
| -
|
| - network_request->AddHttpRequest(new SimpleRequest);
|
| -
|
| - network_request->set_num_retries(3);
|
| - *network_request_ptr = network_request;
|
| - return S_OK;
|
| -}
|
| -
|
| -// TODO(omaha): Unit test this method.
|
| -HRESULT ValidateSize(const CString& file_path, uint64 expected_size) {
|
| - CORE_LOG(L3, (_T("[ValidateSize][%s][%lld]"), file_path, expected_size));
|
| - ASSERT1(File::Exists(file_path));
|
| - ASSERT1(expected_size != 0);
|
| - ASSERT(expected_size <= UINT_MAX,
|
| - (_T("TODO(omaha): Add uint64 support to GetFileSizeUnopen().")));
|
| -
|
| - uint32 file_size(0);
|
| - HRESULT hr = File::GetFileSizeUnopen(file_path, &file_size);
|
| - ASSERT1(SUCCEEDED(hr));
|
| - if (FAILED(hr)) {
|
| - return hr;
|
| - }
|
| -
|
| - if (0 == file_size) {
|
| - return GOOPDATEDOWNLOAD_E_FILE_SIZE_ZERO;
|
| - } else if (file_size < expected_size) {
|
| - return GOOPDATEDOWNLOAD_E_FILE_SIZE_SMALLER;
|
| - } else if (file_size > expected_size) {
|
| - return GOOPDATEDOWNLOAD_E_FILE_SIZE_LARGER;
|
| - }
|
| -
|
| - ASSERT1(file_size == expected_size);
|
| - return S_OK;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -DownloadManager::DownloadManager(bool is_machine)
|
| - : lock_(NULL), is_machine_(false) {
|
| - CORE_LOG(L3, (_T("[DownloadManager::DownloadManager]")));
|
| -
|
| - omaha::interlocked_exchange_pointer(&lock_,
|
| - static_cast<Lockable*>(new LLock));
|
| - __mutexScope(lock());
|
| -
|
| - is_machine_ = is_machine;
|
| -
|
| - package_cache_root_ =
|
| - is_machine ?
|
| - ConfigManager::Instance()->GetMachineSecureDownloadStorageDir() :
|
| - ConfigManager::Instance()->GetUserDownloadStorageDir();
|
| -
|
| - CORE_LOG(L3, (_T("[package_cache_root][%s]"), package_cache_root()));
|
| -
|
| - package_cache_.reset(new PackageCache);
|
| -}
|
| -
|
| -DownloadManager::~DownloadManager() {
|
| - CORE_LOG(L3, (_T("[DownloadManager::~DownloadManager]")));
|
| -
|
| - ASSERT1(!IsBusy());
|
| -
|
| - delete &lock();
|
| - omaha::interlocked_exchange_pointer(&lock_, static_cast<Lockable*>(NULL));
|
| -}
|
| -
|
| -const Lockable& DownloadManager::lock() const {
|
| - return *omaha::interlocked_exchange_pointer(&lock_, lock_);
|
| -}
|
| -
|
| -bool DownloadManager::is_machine() const {
|
| - __mutexScope(lock());
|
| - return is_machine_;
|
| -}
|
| -
|
| -CString DownloadManager::package_cache_root() const {
|
| - __mutexScope(lock());
|
| - return package_cache_root_;
|
| -}
|
| -
|
| -PackageCache* DownloadManager::package_cache() {
|
| - __mutexScope(lock());
|
| - return package_cache_.get();
|
| -}
|
| -
|
| -const PackageCache* DownloadManager::package_cache() const {
|
| - __mutexScope(lock());
|
| - return package_cache_.get();
|
| -}
|
| -
|
| -HRESULT DownloadManager::Initialize() {
|
| - HRESULT hr = package_cache()->Initialize(package_cache_root());
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE, (_T("[failed to initialize the package cache]0x%08x]"), hr));
|
| - return hr;
|
| - }
|
| -
|
| - hr = package_cache()->PurgeOldPackagesIfNecessary();
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LW, (_T("[PurgeOldPackagesIfNecessary failed][0x%08x]"), hr));
|
| - }
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| -CString DownloadManager::GetMessageForError(const ErrorContext& error_context,
|
| - const CString& language) {
|
| - CString message;
|
| - StringFormatter formatter(language);
|
| -
|
| - switch (error_context.error_code) {
|
| - case SIGS_E_INVALID_SIGNATURE:
|
| - case GOOPDATEDOWNLOAD_E_FILE_SIZE_ZERO:
|
| - case GOOPDATEDOWNLOAD_E_FILE_SIZE_SMALLER:
|
| - case GOOPDATEDOWNLOAD_E_FILE_SIZE_LARGER:
|
| - VERIFY1(SUCCEEDED(formatter.LoadString(IDS_DOWNLOAD_HASH_MISMATCH,
|
| - &message)));
|
| - break;
|
| - case GOOPDATEDOWNLOAD_E_CACHING_FAILED:
|
| - VERIFY1(SUCCEEDED(formatter.FormatMessage(
|
| - &message, IDS_CACHING_ERROR, error_context.extra_code1, &message)));
|
| - break;
|
| - default:
|
| - if (!worker_utils::FormatMessageForNetworkError(error_context.error_code,
|
| - language,
|
| - &message)) {
|
| - VERIFY1(SUCCEEDED(formatter.LoadString(IDS_DOWNLOAD_ERROR, &message)));
|
| - }
|
| - break;
|
| - }
|
| -
|
| - ASSERT1(!message.IsEmpty());
|
| - return message;
|
| -}
|
| -
|
| -HRESULT DownloadManager::DownloadApp(App* app) {
|
| - CORE_LOG(L3, (_T("[DownloadManager::DownloadApp][0x%p]"), app));
|
| - ASSERT1(app);
|
| -
|
| - // TODO(omaha3): Maybe rename these to include "app_". Maybe add package
|
| - // metrics too.
|
| - ++metric_worker_download_total;
|
| -
|
| - // We assume the number of packages does not change after download is started.
|
| - // TODO(omaha3): Could be a problem if we allow installers to request more
|
| - // packages (http://b/1969071), but we will have lots of other problems then.
|
| - AppVersion* app_version = app->working_version();
|
| - const size_t num_packages = app_version->GetNumberOfPackages();
|
| -
|
| - State* state = NULL;
|
| - HRESULT hr = CreateStateForApp(app, &state);
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE, (_T("[CreateStateForApp failed][0x%08x]"), hr));
|
| - return hr;
|
| - }
|
| -
|
| - app->Downloading();
|
| -
|
| - CString message;
|
| - hr = S_OK;
|
| -
|
| - for (size_t i = 0; i < num_packages; ++i) {
|
| - Package* package(app_version->GetPackage(i));
|
| - hr = DoDownloadPackage(package, state);
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE, (_T("[DoDownloadPackage failed][%s][%s][0x%08x][%Iu]"),
|
| - app->display_name(), package->filename(), hr, i));
|
| - message = GetMessageForError(ErrorContext(hr, error_extra_code1()),
|
| - app->app_bundle()->display_language());
|
| - break;
|
| - }
|
| - }
|
| -
|
| - if (SUCCEEDED(hr)) {
|
| - app->DownloadComplete();
|
| -
|
| - // TODO(omaha3): Extract and apply differential update if necessary.
|
| -
|
| - app->MarkReadyToInstall();
|
| - } else {
|
| - app->Error(ErrorContext(hr, error_extra_code1()), message);
|
| - }
|
| -
|
| - if (SUCCEEDED(hr)) {
|
| - ++metric_worker_download_succeeded;
|
| - }
|
| -
|
| - VERIFY1(SUCCEEDED(DeleteStateForApp(app)));
|
| -
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT DownloadManager::DownloadPackage(Package* package) {
|
| - CORE_LOG(L3, (_T("[DownloadManager::DownloadPackage][0x%p]"), package));
|
| - ASSERT1(package);
|
| -
|
| - UNREFERENCED_PARAMETER(package);
|
| -
|
| - // TODO(omaha): implement in terms of DoDownloadPackage.
|
| -
|
| - return E_NOTIMPL;
|
| -}
|
| -
|
| -HRESULT DownloadManager::GetPackage(const Package* package,
|
| - const CString& dir) const {
|
| - const CString app_id(package->app_version()->app()->app_guid_string());
|
| - const CString version(package->app_version()->version());
|
| - const CString package_name(package->filename());
|
| -
|
| - const PackageCache::Key key(app_id, version, package_name);
|
| -
|
| - CORE_LOG(L3, (_T("[DownloadManager::GetPackage][%s]"), key.ToString()));
|
| -
|
| - const CString dest_file(ConcatenatePath(dir, package_name));
|
| - CORE_LOG(L3, (_T("[destination file is '%s']"), dest_file));
|
| -
|
| - const CString hash(package->expected_hash());
|
| - HRESULT hr = package_cache()->Get(key, dest_file, hash);
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE, (_T("[failed to get from cache][0x%08x]"), hr));
|
| - return hr;
|
| - }
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| -bool DownloadManager::IsPackageAvailable(const Package* package) const {
|
| - const CString app_id(package->app_version()->app()->app_guid_string());
|
| - const CString version(package->app_version()->version());
|
| - const CString package_name(package->filename());
|
| -
|
| - const PackageCache::Key key(app_id, version, package_name);
|
| -
|
| - CORE_LOG(L3, (_T("[DownloadManager::IsPackageAvailable][%s]"),
|
| - key.ToString()));
|
| -
|
| - const CString hash(package->expected_hash());
|
| - return package_cache()->IsCached(key, hash);
|
| -}
|
| -
|
| -// Attempts a package download by trying the fallback urls. It does not
|
| -// retry the download if the file validation fails.
|
| -// Assumes the packages are not created or destroyed while method is running.
|
| -HRESULT DownloadManager::DoDownloadPackage(Package* package, State* state) {
|
| - ASSERT1(package);
|
| - ASSERT1(state);
|
| -
|
| - App* app = package->app_version()->app();
|
| - const CString app_id(app->app_guid_string());
|
| - const CString version(package->app_version()->version());
|
| - const CString package_name(package->filename());
|
| -
|
| - const ConfigManager& cm = *ConfigManager::Instance();
|
| - // TODO(omaha): Since we don't currently have is_manual, check the least
|
| - // restrictive case of true. It would be nice if we had is_manual. We'll see.
|
| - ASSERT(SUCCEEDED(app->CheckGroupPolicy()),
|
| - (_T("Downloading package app for disallowed app.")));
|
| -
|
| - if (app_id.IsEmpty() || package_name.IsEmpty()) {
|
| - return E_INVALIDARG;
|
| - }
|
| -
|
| - PackageCache::Key key(app_id, version, package_name);
|
| -
|
| - CORE_LOG(L3, (_T("[DownloadManager::DoDownloadPackage][%s]"),
|
| - key.ToString()));
|
| -
|
| - const CString hash(package->expected_hash());
|
| -
|
| - if (!package_cache()->IsCached(key, hash)) {
|
| - CORE_LOG(L3, (_T("[The package is not cached]")));
|
| -
|
| - // TODO(omaha3): May need to consider the DownloadPackage case. Also, we may
|
| - // want a error code that does not include "UPDATE". If this is a valid
|
| - // case, need to add message for
|
| - // GOOPDATE_E_APP_UPDATE_DISABLED_EULA_NOT_ACCEPTED to GetMessageForError().
|
| - // As of 9/7/2010, the offline case does not allow downloading if the
|
| - // package cannot be found, so offline scenarios should never get here.
|
| - if (!app->is_eula_accepted()) {
|
| - ASSERT(false, (_T("Can't download because app EULA is not accepted.")));
|
| - return GOOPDATE_E_APP_UPDATE_DISABLED_EULA_NOT_ACCEPTED;
|
| - }
|
| -
|
| - if (!ConfigManager::Instance()->CanUseNetwork(is_machine_)) {
|
| - CORE_LOG(LE, (_T("[DoDownloadPackage][network use prohibited]")));
|
| - return GOOPDATE_E_CANNOT_USE_NETWORK;
|
| - }
|
| -
|
| - CString unique_filename_path;
|
| - HRESULT hr = BuildUniqueFileName(package_name, &unique_filename_path);
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE, (_T("[BuildUniqueFileName failed][0x%08x]"), hr));
|
| - return hr;
|
| - }
|
| -
|
| - NetworkRequest* network_request = state->network_request();
|
| -
|
| - network_request->set_callback(package);
|
| -
|
| - const std::vector<CString> download_base_urls(
|
| - package->app_version()->download_base_urls());
|
| -
|
| - hr = E_FAIL;
|
| - for (size_t i = 0; i < download_base_urls.size() && FAILED(hr); ++i) {
|
| - // TODO(omaha3): Append nicely.
|
| - const CString url = download_base_urls[i] + package_name;
|
| -
|
| - if (i > 0) {
|
| - CORE_LOG(L3, (_T("[retrying download with fallback base url][%s]"),
|
| - url));
|
| - }
|
| - // TODO(omaha3): Increment a usage stat for the ith url being used.
|
| - // Supporting 3 or 4 should be enough.
|
| -
|
| - CORE_LOG(L3, (_T("[starting file download][from '%s'][to '%s']"),
|
| - url, unique_filename_path));
|
| -
|
| - // Downloading a file is a blocking call. It assumes the model is not
|
| - // locked by the calling thread, otherwise other threads won't be able to
|
| - // to access the model until the file download is complete.
|
| - ASSERT1(!package->model()->IsLockedByCaller());
|
| -
|
| - hr = network_request->DownloadFile(url, unique_filename_path);
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LW, (_T("[DownloadFile failed from url][0x%08x]['%s']['%s']"),
|
| - hr, package_name, download_base_urls[i]));
|
| - worker_utils::AddHttpRequestDataToEventLog(
|
| - hr,
|
| - network_request->http_status_code(),
|
| - network_request->trace(),
|
| - is_machine_);
|
| - continue;
|
| - }
|
| -
|
| - // A file has been successfully downloaded from current url. Validate
|
| - // and cache it.
|
| - hr = CallAsSelfAndImpersonate2(
|
| - this,
|
| - &DownloadManager::CachePackage,
|
| - static_cast<const Package*>(package),
|
| - static_cast<const CString*>(&unique_filename_path));
|
| - if (SUCCEEDED(hr)) {
|
| - break;
|
| - }
|
| -
|
| - CORE_LOG(LE, (_T("[failed to cache package][0x%08x]"), hr));
|
| - }
|
| - VERIFY1(SUCCEEDED(network_request->Close()));
|
| - DeleteBeforeOrAfterReboot(unique_filename_path);
|
| -
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(LE, (_T("[DownloadFile/caching failed from all urls][0x%08x]"),
|
| - hr));
|
| - return hr;
|
| - }
|
| -
|
| - // Assumes that downloaded bytes equal to the expected package size.
|
| - app->UpdateNumBytesDownloaded(package->expected_size());
|
| - } else {
|
| - CORE_LOG(L3, (_T("[package is cached]")));
|
| -
|
| - // TODO(omaha3): We probably need to update the download stats that
|
| - // Package::OnProgress would set. It may be misleading to set
|
| - // bytes_downloaded to anything other than zero, but App uses this to
|
| - // calculate progress. I suppose we could add an is_complete field instead.
|
| - // There is a related issue with the callback not being called with the
|
| - // final size. See the TODO in the unit tests.
|
| - }
|
| -
|
| - ASSERT1(package_cache()->IsCached(key, hash));
|
| - return S_OK;
|
| -}
|
| -
|
| -void DownloadManager::Cancel(App* app) {
|
| - CORE_LOG(L3, (_T("[DownloadManager::Cancel][0x%p]"), app));
|
| - ASSERT1(app);
|
| -
|
| - __mutexScope(lock());
|
| -
|
| - for (size_t i = 0; i != download_state_.size(); ++i) {
|
| - if (app == download_state_[i]->app()) {
|
| - VERIFY1(SUCCEEDED(download_state_[i]->CancelNetworkRequest()));
|
| - }
|
| - }
|
| -}
|
| -
|
| -void DownloadManager::CancelAll() {
|
| - CORE_LOG(L3, (_T("[DownloadManager::CancelAll]")));
|
| -
|
| - __mutexScope(lock());
|
| -
|
| - for (size_t i = 0; i != download_state_.size(); ++i) {
|
| - VERIFY1(SUCCEEDED(download_state_[i]->CancelNetworkRequest()));
|
| - }
|
| -}
|
| -
|
| -bool DownloadManager::IsBusy() const {
|
| - __mutexScope(lock());
|
| - return !download_state_.empty();
|
| -}
|
| -
|
| -HRESULT DownloadManager::PurgeAppLowerVersions(const CString& app_id,
|
| - const CString& version) {
|
| - return package_cache()->PurgeAppLowerVersions(app_id, version);
|
| -}
|
| -
|
| -HRESULT DownloadManager::CachePackage(const Package* package,
|
| - const CString* filename_path) {
|
| - ASSERT1(package);
|
| - ASSERT1(filename_path);
|
| -
|
| - const CString app_id(package->app_version()->app()->app_guid_string());
|
| - const CString version(package->app_version()->version());
|
| - const CString package_name(package->filename());
|
| - PackageCache::Key key(app_id, version, package_name);
|
| -
|
| - const CString hash(package->expected_hash());
|
| -
|
| - HRESULT hr = package_cache()->Put(key, *filename_path, hash);
|
| - if (hr != SIGS_E_INVALID_SIGNATURE) {
|
| - if (FAILED(hr)) {
|
| - set_error_extra_code1(static_cast<int>(hr));
|
| - return GOOPDATEDOWNLOAD_E_CACHING_FAILED;
|
| - }
|
| - return hr;
|
| - }
|
| -
|
| - // Get a more specific error if possible.
|
| - // TODO(omaha): It would be nice to detect that we downloaded a proxy
|
| - // page and tell the user this. It would be even better if we could
|
| - // display it; that would require a lot more plumbing.
|
| - HRESULT size_hr = ValidateSize(*filename_path, package->expected_size());
|
| - if (FAILED(size_hr)) {
|
| - hr = size_hr;
|
| - }
|
| -
|
| - return hr;
|
| -}
|
| -
|
| -// The file is initially downloaded to a temporary unique name, to account
|
| -// for the case where the same file is downloaded by multiple callers.
|
| -HRESULT DownloadManager::BuildUniqueFileName(const CString& filename,
|
| - CString* unique_filename) {
|
| - ASSERT1(unique_filename);
|
| -
|
| - GUID guid(GUID_NULL);
|
| - HRESULT hr = ::CoCreateGuid(&guid);
|
| - if (FAILED(hr)) {
|
| - CORE_LOG(L3, (_T("[CoCreateGuid failed][0x%08x]"), hr));
|
| - return hr;
|
| - }
|
| -
|
| - // Format of the unique file name is: <temp_download_dir>/<guid>-<filename>.
|
| - const CString temp_dir(ConfigManager::Instance()->GetTempDownloadDir());
|
| - CString temp_filename;
|
| - SafeCStringFormat(&temp_filename, _T("%s-%s"), GuidToString(guid), filename);
|
| - *unique_filename = ConcatenatePath(temp_dir, temp_filename);
|
| -
|
| - return unique_filename->IsEmpty() ?
|
| - GOOPDATEDOWNLOAD_E_UNIQUE_FILE_PATH_EMPTY : S_OK;
|
| -}
|
| -
|
| -HRESULT DownloadManager::CreateStateForApp(App* app, State** state) {
|
| - ASSERT1(app);
|
| - ASSERT1(state);
|
| -
|
| - *state = NULL;
|
| -
|
| - NetworkRequest* network_request = NULL;
|
| - HRESULT hr = CreateNetworkRequest(&network_request);
|
| - if (FAILED(hr)) {
|
| - return hr;
|
| - }
|
| -
|
| - ASSERT1(network_request);
|
| -
|
| - const bool use_background_priority =
|
| - (app->app_bundle()->priority() < INSTALL_PRIORITY_HIGH);
|
| - network_request->set_low_priority(use_background_priority);
|
| -
|
| - network_request->set_proxy_auth_config(
|
| - app->app_bundle()->GetProxyAuthConfig());
|
| -
|
| - scoped_ptr<State> state_ptr(new State(app, network_request));
|
| -
|
| - __mutexBlock(lock()) {
|
| - download_state_.push_back(state_ptr.release());
|
| - *state = download_state_.back();
|
| - }
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| -HRESULT DownloadManager::DeleteStateForApp(App* app) {
|
| - ASSERT1(app);
|
| -
|
| - __mutexScope(lock());
|
| -
|
| - typedef std::vector<State*>::iterator Iter;
|
| - for (Iter it(download_state_.begin()); it != download_state_.end(); ++it) {
|
| - if (app == (*it)->app()) {
|
| - delete *it;
|
| - download_state_.erase(it);
|
| - return S_OK;
|
| - }
|
| - }
|
| -
|
| - ASSERT1(false);
|
| -
|
| - return E_UNEXPECTED;
|
| -}
|
| -
|
| -DownloadManager::State::State(App* app, NetworkRequest* network_request)
|
| - : app_(app), network_request_(network_request) {
|
| - ASSERT1(app);
|
| - ASSERT1(network_request);
|
| -}
|
| -
|
| -DownloadManager::State::~State() {
|
| -}
|
| -
|
| -NetworkRequest* DownloadManager::State::network_request() const {
|
| - ASSERT1(ConfigManager::Instance()->CanUseNetwork(
|
| - app_->app_bundle()->is_machine()));
|
| -
|
| - return network_request_.get();
|
| -}
|
| -
|
| -HRESULT DownloadManager::State::CancelNetworkRequest() {
|
| - return network_request_->Cancel();
|
| -}
|
| -
|
| -} // namespace omaha
|
|
|