1 // Copyright 2015 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 "extensions/browser/api/socket/app_firewall_hole_manager.h"
10 #include "base/stl_util.h"
11 #include "components/keyed_service/content/browser_context_dependency_manager.h"
12 #include "content/public/browser/browser_context.h"
13 #include "extensions/browser/app_window/app_window.h"
15 using chromeos::FirewallHole
;
16 using content::BrowserContext
;
18 namespace extensions
{
22 class AppFirewallHoleManagerFactory
: public BrowserContextKeyedServiceFactory
{
24 static AppFirewallHoleManager
* GetForBrowserContext(BrowserContext
* context
,
26 return static_cast<AppFirewallHoleManager
*>(
27 GetInstance()->GetServiceForBrowserContext(context
, create
));
30 static AppFirewallHoleManagerFactory
* GetInstance() {
31 return Singleton
<AppFirewallHoleManagerFactory
>::get();
34 AppFirewallHoleManagerFactory()
35 : BrowserContextKeyedServiceFactory(
36 "AppFirewallHoleManager",
37 BrowserContextDependencyManager::GetInstance()) {
38 DependsOn(AppWindowRegistry::Factory::GetInstance());
41 ~AppFirewallHoleManagerFactory() override
{}
44 // BrowserContextKeyedServiceFactory
45 KeyedService
* BuildServiceInstanceFor(
46 BrowserContext
* context
) const override
{
47 return new AppFirewallHoleManager(context
);
50 BrowserContext
* GetBrowserContextToUse(
51 BrowserContext
* context
) const override
{
56 bool HasVisibleAppWindows(BrowserContext
* context
,
57 const std::string
& extension_id
) {
58 AppWindowRegistry
* registry
= AppWindowRegistry::Get(context
);
60 for (const AppWindow
* window
: registry
->GetAppWindowsForApp(extension_id
)) {
61 if (!window
->is_hidden()) {
71 AppFirewallHole::~AppFirewallHole() {
72 manager_
->Close(this);
75 AppFirewallHole::AppFirewallHole(AppFirewallHoleManager
* manager
,
78 const std::string
& extension_id
)
81 extension_id_(extension_id
),
86 void AppFirewallHole::SetVisible(bool app_visible
) {
87 app_visible_
= app_visible
;
89 if (!firewall_hole_
) {
90 FirewallHole::Open(type_
, port_
, "" /* all interfaces */,
91 base::Bind(&AppFirewallHole::OnFirewallHoleOpened
,
92 weak_factory_
.GetWeakPtr()));
95 firewall_hole_
.reset(nullptr);
99 void AppFirewallHole::OnFirewallHoleOpened(
100 scoped_ptr
<FirewallHole
> firewall_hole
) {
102 DCHECK(!firewall_hole_
);
103 firewall_hole_
= firewall_hole
.Pass();
107 AppFirewallHoleManager::AppFirewallHoleManager(BrowserContext
* context
)
108 : context_(context
), observer_(this) {
109 observer_
.Add(AppWindowRegistry::Get(context
));
112 AppFirewallHoleManager::~AppFirewallHoleManager() {
113 STLDeleteValues(&tracked_holes_
);
116 AppFirewallHoleManager
* AppFirewallHoleManager::Get(BrowserContext
* context
) {
117 return AppFirewallHoleManagerFactory::GetForBrowserContext(context
, true);
120 scoped_ptr
<AppFirewallHole
> AppFirewallHoleManager::Open(
121 AppFirewallHole::PortType type
,
123 const std::string
& extension_id
) {
124 scoped_ptr
<AppFirewallHole
> hole(
125 new AppFirewallHole(this, type
, port
, extension_id
));
126 tracked_holes_
.insert(std::make_pair(extension_id
, hole
.get()));
127 if (HasVisibleAppWindows(context_
, extension_id
)) {
128 hole
->SetVisible(true);
133 void AppFirewallHoleManager::Close(AppFirewallHole
* hole
) {
134 auto range
= tracked_holes_
.equal_range(hole
->extension_id());
135 for (auto iter
= range
.first
; iter
!= range
.second
; ++iter
) {
136 if (iter
->second
== hole
) {
137 tracked_holes_
.erase(iter
);
144 void AppFirewallHoleManager::OnAppWindowRemoved(AppWindow
* app_window
) {
145 OnAppWindowHidden(app_window
);
148 void AppFirewallHoleManager::OnAppWindowHidden(AppWindow
* app_window
) {
149 DCHECK(context_
== app_window
->browser_context());
150 if (!HasVisibleAppWindows(context_
, app_window
->extension_id())) {
151 const auto& range
= tracked_holes_
.equal_range(app_window
->extension_id());
152 for (auto iter
= range
.first
; iter
!= range
.second
; ++iter
) {
153 iter
->second
->SetVisible(false);
158 void AppFirewallHoleManager::OnAppWindowShown(AppWindow
* app_window
,
160 const auto& range
= tracked_holes_
.equal_range(app_window
->extension_id());
161 for (auto iter
= range
.first
; iter
!= range
.second
; ++iter
) {
162 iter
->second
->SetVisible(true);
166 } // namespace extensions