Commit 504830a6 authored by sorin@chromium.org's avatar sorin@chromium.org

Define and implement an interface for on-demand component updates.

This interface consolidates the on-demand functionality and it allows for selective friendship for the callers who are allowed to trigger an on-demand update.

BUG=375315

Review URL: https://codereview.chromium.org/292203002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@271770 0039d316-1c4b-4281-b951-d872f2087c98
parent 497edf84
......@@ -149,7 +149,7 @@ void UnblockandReapAllThrottles(CUResourceThrottle::WeakPtrVector* throttles) {
// only from the UI thread. The unpack and installation is done in a blocking
// pool thread. The network requests are done in the IO thread or in the file
// thread.
class CrxUpdateService : public ComponentUpdateService {
class CrxUpdateService : public ComponentUpdateService, public OnDemandUpdater {
public:
explicit CrxUpdateService(ComponentUpdateService::Configurator* config);
virtual ~CrxUpdateService();
......@@ -160,12 +160,15 @@ class CrxUpdateService : public ComponentUpdateService {
virtual Status Start() OVERRIDE;
virtual Status Stop() OVERRIDE;
virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE;
virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE;
virtual void GetComponents(
std::vector<CrxComponentInfo>* components) OVERRIDE;
virtual OnDemandUpdater& GetOnDemandUpdater() OVERRIDE;
// Overrides for OnDemandUpdater.
virtual content::ResourceThrottle* GetOnDemandResourceThrottle(
net::URLRequest* request,
const std::string& crx_id) OVERRIDE;
virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE;
// Context for a crx download url request.
struct CRXContext {
......@@ -496,60 +499,6 @@ ComponentUpdateService::Status CrxUpdateService::RegisterComponent(
return kOk;
}
// Start the process of checking for an update, for a particular component
// that was previously registered.
// |component_id| is a value returned from GetCrxComponentID().
ComponentUpdateService::Status CrxUpdateService::OnDemandUpdate(
const std::string& component_id) {
return OnDemandUpdateInternal(FindUpdateItemById(component_id));
}
ComponentUpdateService::Status CrxUpdateService::OnDemandUpdateInternal(
CrxUpdateItem* uit) {
if (!uit)
return kError;
// Check if the request is too soon.
base::TimeDelta delta = base::Time::Now() - uit->last_check;
if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay()))
return kError;
switch (uit->status) {
// If the item is already in the process of being updated, there is
// no point in this call, so return kInProgress.
case CrxUpdateItem::kChecking:
case CrxUpdateItem::kCanUpdate:
case CrxUpdateItem::kDownloadingDiff:
case CrxUpdateItem::kDownloading:
case CrxUpdateItem::kUpdatingDiff:
case CrxUpdateItem::kUpdating:
return kInProgress;
// Otherwise the item was already checked a while back (or it is new),
// set its status to kNew to give it a slightly higher priority.
case CrxUpdateItem::kNew:
case CrxUpdateItem::kUpdated:
case CrxUpdateItem::kUpToDate:
case CrxUpdateItem::kNoUpdate:
ChangeItemState(uit, CrxUpdateItem::kNew);
uit->on_demand = true;
break;
case CrxUpdateItem::kLastStatus:
NOTREACHED() << uit->status;
}
// In case the current delay is long, set the timer to a shorter value
// to get the ball rolling.
if (timer_.IsRunning()) {
timer_.Stop();
timer_.Start(FROM_HERE,
base::TimeDelta::FromSeconds(config_->StepDelay()),
this,
&CrxUpdateService::ProcessPendingItems);
}
return kOk;
}
void CrxUpdateService::GetComponents(
std::vector<CrxComponentInfo>* components) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
......@@ -565,6 +514,10 @@ void CrxUpdateService::GetComponents(
}
}
OnDemandUpdater& CrxUpdateService::GetOnDemandUpdater() {
return *this;
}
// This is the main loop of the component updater. It updates one component
// at a time if updates are available. Otherwise, it does an update check or
// takes a long sleep until the loop runs again.
......@@ -1010,6 +963,57 @@ void CrxUpdateService::OnNewResourceThrottle(
UnblockResourceThrottle(rt);
}
ComponentUpdateService::Status CrxUpdateService::OnDemandUpdate(
const std::string& component_id) {
return OnDemandUpdateInternal(FindUpdateItemById(component_id));
}
ComponentUpdateService::Status CrxUpdateService::OnDemandUpdateInternal(
CrxUpdateItem* uit) {
if (!uit)
return kError;
// Check if the request is too soon.
base::TimeDelta delta = base::Time::Now() - uit->last_check;
if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay()))
return kError;
switch (uit->status) {
// If the item is already in the process of being updated, there is
// no point in this call, so return kInProgress.
case CrxUpdateItem::kChecking:
case CrxUpdateItem::kCanUpdate:
case CrxUpdateItem::kDownloadingDiff:
case CrxUpdateItem::kDownloading:
case CrxUpdateItem::kUpdatingDiff:
case CrxUpdateItem::kUpdating:
return kInProgress;
// Otherwise the item was already checked a while back (or it is new),
// set its status to kNew to give it a slightly higher priority.
case CrxUpdateItem::kNew:
case CrxUpdateItem::kUpdated:
case CrxUpdateItem::kUpToDate:
case CrxUpdateItem::kNoUpdate:
ChangeItemState(uit, CrxUpdateItem::kNew);
uit->on_demand = true;
break;
case CrxUpdateItem::kLastStatus:
NOTREACHED() << uit->status;
}
// In case the current delay is long, set the timer to a shorter value
// to get the ball rolling.
if (timer_.IsRunning()) {
timer_.Stop();
timer_.Start(FROM_HERE,
base::TimeDelta::FromSeconds(config_->StepDelay()),
this,
&CrxUpdateService::ProcessPendingItems);
}
return kOk;
}
///////////////////////////////////////////////////////////////////////////////
CUResourceThrottle::CUResourceThrottle(const net::URLRequest* request)
......
......@@ -29,7 +29,7 @@ class ResourceThrottle;
namespace component_updater {
class OnDemandTester;
class OnDemandUpdater;
// Component specific installers must derive from this class and implement
// OnUpdateError() and Install(). A valid instance of this class must be
......@@ -208,30 +208,43 @@ class ComponentUpdateService {
// Returns a list of registered components.
virtual void GetComponents(std::vector<CrxComponentInfo>* components) = 0;
// Returns an interface for on-demand updates. On-demand updates are
// proactively triggered outside the normal component update service schedule.
virtual OnDemandUpdater& GetOnDemandUpdater() = 0;
virtual ~ComponentUpdateService() {}
private:
friend class ::ComponentsUI;
};
typedef ComponentUpdateService::Observer ServiceObserver;
class OnDemandUpdater {
public:
virtual ~OnDemandUpdater() {}
// Returns a network resource throttle. It means that a component will be
// downloaded and installed before the resource is unthrottled. This is the
// only function callable from the IO thread.
// downloaded and installed before the resource is unthrottled. This function
// can be called from the IO thread.
virtual content::ResourceThrottle* GetOnDemandResourceThrottle(
net::URLRequest* request,
const std::string& crx_id) = 0;
virtual ~ComponentUpdateService() {}
friend class ::ComponentsUI;
private:
friend class OnDemandTester;
friend class ::ComponentsUI;
private:
// Ask the component updater to do an update check for a previously
// registered component, immediately. If an update or check is already
// in progress, returns |kInProgress|.
// There is no guarantee that the item will actually be updated,
// since an update may not be available. Listeners for the component will
// know the outcome of the check.
virtual Status OnDemandUpdate(const std::string& component_id) = 0;
// Triggers an update check for a component. |component_id| is a value
// returned by GetCrxComponentID(). If an update for this component is already
// in progress, the function returns |kInProgress|. If an update is available,
// the update will be applied. The caller can subscribe to component update
// service notifications to get an indication about the outcome of the
// on-demand update.
virtual ComponentUpdateService::Status OnDemandUpdate(
const std::string& component_id) = 0;
};
typedef ComponentUpdateService::Observer ServiceObserver;
// Creates the component updater. You must pass a valid |config| allocated on
// the heap which the component updater will own.
ComponentUpdateService* ComponentUpdateServiceFactory(
......
......@@ -247,7 +247,7 @@ void ComponentUpdaterTest::RunThreadsUntilIdle() {
ComponentUpdateService::Status OnDemandTester::OnDemand(
ComponentUpdateService* cus,
const std::string& component_id) {
return cus->OnDemandUpdate(component_id);
return cus->GetOnDemandUpdater().OnDemandUpdate(component_id);
}
// Verify that our test fixture work and the component updater can
......@@ -1296,7 +1296,8 @@ content::ResourceThrottle* RequestTestResourceThrottle(
&context);
content::ResourceThrottle* rt =
cus->GetOnDemandResourceThrottle(&url_request, crx_id);
cus->GetOnDemandUpdater().GetOnDemandResourceThrottle(&url_request,
crx_id);
rt->set_controller_for_testing(controller);
controller->SetThrottle(rt);
return rt;
......
......@@ -5,6 +5,7 @@
#include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"
#include <string>
#include <vector>
#include "base/base64.h"
#include "base/logging.h"
......@@ -247,7 +248,8 @@ void AppendComponentUpdaterThrottles(
if (crx_id) {
// We got a component we need to install, so throttle the resource
// until the component is installed.
throttles->push_back(cus->GetOnDemandResourceThrottle(request, crx_id));
throttles->push_back(
cus->GetOnDemandUpdater().GetOnDemandResourceThrottle(request, crx_id));
}
}
......
......@@ -163,7 +163,7 @@ ComponentsUI::ComponentsUI(content::WebUI* web_ui) : WebUIController(web_ui) {
void ComponentsUI::OnDemandUpdate(const std::string& component_id) {
component_updater::ComponentUpdateService* cus =
g_browser_process->component_updater();
cus->OnDemandUpdate(component_id);
cus->GetOnDemandUpdater().OnDemandUpdate(component_id);
}
// static
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment