1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/api/webstore/webstore_api.h"
7 #include "base/lazy_instance.h"
8 #include "base/values.h"
9 #include "chrome/browser/extensions/install_tracker.h"
10 #include "chrome/browser/extensions/install_tracker_factory.h"
11 #include "chrome/common/extensions/chrome_extension_messages.h"
12 #include "extensions/browser/extension_system.h"
13 #include "ipc/ipc_sender.h"
15 namespace extensions
{
19 base::LazyInstance
<BrowserContextKeyedAPIFactory
<WebstoreAPI
> > g_factory
=
20 LAZY_INSTANCE_INITIALIZER
;
24 struct WebstoreAPI::ObservedInstallInfo
{
25 ObservedInstallInfo(int routing_id
,
26 const std::string
& extension_id
,
27 IPC::Sender
* ipc_sender
);
28 ~ObservedInstallInfo();
31 std::string extension_id
;
32 IPC::Sender
* ipc_sender
;
35 WebstoreAPI::ObservedInstallInfo::ObservedInstallInfo(
37 const std::string
& extension_id
,
38 IPC::Sender
* ipc_sender
)
39 : routing_id(routing_id
),
40 extension_id(extension_id
),
41 ipc_sender(ipc_sender
) {}
43 WebstoreAPI::ObservedInstallInfo::~ObservedInstallInfo() {}
45 WebstoreAPI::WebstoreAPI(content::BrowserContext
* browser_context
)
46 : browser_context_(browser_context
),
48 new ScopedObserver
<InstallTracker
, InstallObserver
>(this)) {
49 install_observer_
->Add(
50 InstallTrackerFactory::GetForBrowserContext(browser_context
));
53 WebstoreAPI::~WebstoreAPI() {}
56 WebstoreAPI
* WebstoreAPI::Get(content::BrowserContext
* browser_context
) {
57 return BrowserContextKeyedAPIFactory
<WebstoreAPI
>::Get(browser_context
);
60 void WebstoreAPI::OnInlineInstallStart(int routing_id
,
61 IPC::Sender
* ipc_sender
,
62 const std::string
& extension_id
,
64 if (listeners_mask
& api::webstore::INSTALL_STAGE_LISTENER
) {
65 install_stage_listeners_
.push_back(
66 ObservedInstallInfo(routing_id
, extension_id
, ipc_sender
));
69 if (listeners_mask
& api::webstore::DOWNLOAD_PROGRESS_LISTENER
) {
70 download_progress_listeners_
.push_back(
71 ObservedInstallInfo(routing_id
, extension_id
, ipc_sender
));
75 void WebstoreAPI::OnInlineInstallFinished(int routing_id
,
76 const std::string
& extension_id
) {
77 RemoveListeners(routing_id
, extension_id
, &download_progress_listeners_
);
78 RemoveListeners(routing_id
, extension_id
, &install_stage_listeners_
);
81 void WebstoreAPI::OnBeginExtensionDownload(const std::string
& extension_id
) {
82 SendInstallMessageIfObserved(extension_id
,
83 api::webstore::INSTALL_STAGE_DOWNLOADING
);
86 void WebstoreAPI::OnDownloadProgress(const std::string
& extension_id
,
87 int percent_downloaded
) {
88 for (ObservedInstallInfoList::const_iterator iter
=
89 download_progress_listeners_
.begin();
90 iter
!= download_progress_listeners_
.end();
92 if (iter
->extension_id
== extension_id
) {
93 iter
->ipc_sender
->Send(new ExtensionMsg_InlineInstallDownloadProgress(
94 iter
->routing_id
, percent_downloaded
));
99 void WebstoreAPI::OnBeginCrxInstall(const std::string
& extension_id
) {
100 SendInstallMessageIfObserved(extension_id
,
101 api::webstore::INSTALL_STAGE_INSTALLING
);
104 void WebstoreAPI::OnShutdown() {
105 install_observer_
.reset();
108 void WebstoreAPI::Shutdown() {}
111 BrowserContextKeyedAPIFactory
<WebstoreAPI
>* WebstoreAPI::GetFactoryInstance() {
112 return g_factory
.Pointer();
115 void WebstoreAPI::SendInstallMessageIfObserved(
116 const std::string
& extension_id
,
117 api::webstore::InstallStage install_stage
) {
118 for (ObservedInstallInfoList::const_iterator iter
=
119 install_stage_listeners_
.begin();
120 iter
!= install_stage_listeners_
.end();
122 if (iter
->extension_id
== extension_id
) {
123 iter
->ipc_sender
->Send(new ExtensionMsg_InlineInstallStageChanged(
124 iter
->routing_id
, install_stage
));
129 void WebstoreAPI::RemoveListeners(int routing_id
,
130 const std::string
& extension_id
,
131 ObservedInstallInfoList
* listeners
) {
132 for (ObservedInstallInfoList::iterator iter
= listeners
->begin();
133 iter
!= listeners
->end();) {
134 if (iter
->extension_id
== extension_id
&& iter
->routing_id
== routing_id
)
135 iter
= listeners
->erase(iter
);
141 } // namespace extensions