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) { ...@@ -149,7 +149,7 @@ void UnblockandReapAllThrottles(CUResourceThrottle::WeakPtrVector* throttles) {
// only from the UI thread. The unpack and installation is done in a blocking // 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 // pool thread. The network requests are done in the IO thread or in the file
// thread. // thread.
class CrxUpdateService : public ComponentUpdateService { class CrxUpdateService : public ComponentUpdateService, public OnDemandUpdater {
public: public:
explicit CrxUpdateService(ComponentUpdateService::Configurator* config); explicit CrxUpdateService(ComponentUpdateService::Configurator* config);
virtual ~CrxUpdateService(); virtual ~CrxUpdateService();
...@@ -160,12 +160,15 @@ class CrxUpdateService : public ComponentUpdateService { ...@@ -160,12 +160,15 @@ class CrxUpdateService : public ComponentUpdateService {
virtual Status Start() OVERRIDE; virtual Status Start() OVERRIDE;
virtual Status Stop() OVERRIDE; virtual Status Stop() OVERRIDE;
virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE;
virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE;
virtual void GetComponents( virtual void GetComponents(
std::vector<CrxComponentInfo>* components) OVERRIDE; std::vector<CrxComponentInfo>* components) OVERRIDE;
virtual OnDemandUpdater& GetOnDemandUpdater() OVERRIDE;
// Overrides for OnDemandUpdater.
virtual content::ResourceThrottle* GetOnDemandResourceThrottle( virtual content::ResourceThrottle* GetOnDemandResourceThrottle(
net::URLRequest* request, net::URLRequest* request,
const std::string& crx_id) OVERRIDE; const std::string& crx_id) OVERRIDE;
virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE;
// Context for a crx download url request. // Context for a crx download url request.
struct CRXContext { struct CRXContext {
...@@ -496,60 +499,6 @@ ComponentUpdateService::Status CrxUpdateService::RegisterComponent( ...@@ -496,60 +499,6 @@ ComponentUpdateService::Status CrxUpdateService::RegisterComponent(
return kOk; 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( void CrxUpdateService::GetComponents(
std::vector<CrxComponentInfo>* components) { std::vector<CrxComponentInfo>* components) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
...@@ -565,6 +514,10 @@ void CrxUpdateService::GetComponents( ...@@ -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 // 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 // at a time if updates are available. Otherwise, it does an update check or
// takes a long sleep until the loop runs again. // takes a long sleep until the loop runs again.
...@@ -1010,6 +963,57 @@ void CrxUpdateService::OnNewResourceThrottle( ...@@ -1010,6 +963,57 @@ void CrxUpdateService::OnNewResourceThrottle(
UnblockResourceThrottle(rt); 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) CUResourceThrottle::CUResourceThrottle(const net::URLRequest* request)
......
...@@ -29,7 +29,7 @@ class ResourceThrottle; ...@@ -29,7 +29,7 @@ class ResourceThrottle;
namespace component_updater { namespace component_updater {
class OnDemandTester; class OnDemandUpdater;
// Component specific installers must derive from this class and implement // Component specific installers must derive from this class and implement
// OnUpdateError() and Install(). A valid instance of this class must be // OnUpdateError() and Install(). A valid instance of this class must be
...@@ -208,30 +208,43 @@ class ComponentUpdateService { ...@@ -208,30 +208,43 @@ class ComponentUpdateService {
// Returns a list of registered components. // Returns a list of registered components.
virtual void GetComponents(std::vector<CrxComponentInfo>* components) = 0; 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 // Returns a network resource throttle. It means that a component will be
// downloaded and installed before the resource is unthrottled. This is the // downloaded and installed before the resource is unthrottled. This function
// only function callable from the IO thread. // can be called from the IO thread.
virtual content::ResourceThrottle* GetOnDemandResourceThrottle( virtual content::ResourceThrottle* GetOnDemandResourceThrottle(
net::URLRequest* request, net::URLRequest* request,
const std::string& crx_id) = 0; const std::string& crx_id) = 0;
virtual ~ComponentUpdateService() {} private:
friend class ::ComponentsUI;
friend class OnDemandTester; friend class OnDemandTester;
friend class ::ComponentsUI;
private: // Triggers an update check for a component. |component_id| is a value
// Ask the component updater to do an update check for a previously // returned by GetCrxComponentID(). If an update for this component is already
// registered component, immediately. If an update or check is already // in progress, the function returns |kInProgress|. If an update is available,
// in progress, returns |kInProgress|. // the update will be applied. The caller can subscribe to component update
// There is no guarantee that the item will actually be updated, // service notifications to get an indication about the outcome of the
// since an update may not be available. Listeners for the component will // on-demand update.
// know the outcome of the check. virtual ComponentUpdateService::Status OnDemandUpdate(
virtual Status OnDemandUpdate(const std::string& component_id) = 0; const std::string& component_id) = 0;
}; };
typedef ComponentUpdateService::Observer ServiceObserver;
// Creates the component updater. You must pass a valid |config| allocated on // Creates the component updater. You must pass a valid |config| allocated on
// the heap which the component updater will own. // the heap which the component updater will own.
ComponentUpdateService* ComponentUpdateServiceFactory( ComponentUpdateService* ComponentUpdateServiceFactory(
......
...@@ -247,7 +247,7 @@ void ComponentUpdaterTest::RunThreadsUntilIdle() { ...@@ -247,7 +247,7 @@ void ComponentUpdaterTest::RunThreadsUntilIdle() {
ComponentUpdateService::Status OnDemandTester::OnDemand( ComponentUpdateService::Status OnDemandTester::OnDemand(
ComponentUpdateService* cus, ComponentUpdateService* cus,
const std::string& component_id) { 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 // Verify that our test fixture work and the component updater can
...@@ -1296,7 +1296,8 @@ content::ResourceThrottle* RequestTestResourceThrottle( ...@@ -1296,7 +1296,8 @@ content::ResourceThrottle* RequestTestResourceThrottle(
&context); &context);
content::ResourceThrottle* rt = content::ResourceThrottle* rt =
cus->GetOnDemandResourceThrottle(&url_request, crx_id); cus->GetOnDemandUpdater().GetOnDemandResourceThrottle(&url_request,
crx_id);
rt->set_controller_for_testing(controller); rt->set_controller_for_testing(controller);
controller->SetThrottle(rt); controller->SetThrottle(rt);
return rt; return rt;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h" #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"
#include <string> #include <string>
#include <vector>
#include "base/base64.h" #include "base/base64.h"
#include "base/logging.h" #include "base/logging.h"
...@@ -247,7 +248,8 @@ void AppendComponentUpdaterThrottles( ...@@ -247,7 +248,8 @@ void AppendComponentUpdaterThrottles(
if (crx_id) { if (crx_id) {
// We got a component we need to install, so throttle the resource // We got a component we need to install, so throttle the resource
// until the component is installed. // 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) { ...@@ -163,7 +163,7 @@ ComponentsUI::ComponentsUI(content::WebUI* web_ui) : WebUIController(web_ui) {
void ComponentsUI::OnDemandUpdate(const std::string& component_id) { void ComponentsUI::OnDemandUpdate(const std::string& component_id) {
component_updater::ComponentUpdateService* cus = component_updater::ComponentUpdateService* cus =
g_browser_process->component_updater(); g_browser_process->component_updater();
cus->OnDemandUpdate(component_id); cus->GetOnDemandUpdater().OnDemandUpdate(component_id);
} }
// static // 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