Chromium Code Reviews| Index: chrome/browser/ui/ash/vpn_delegate_chromeos.cc |
| diff --git a/chrome/browser/ui/ash/vpn_delegate_chromeos.cc b/chrome/browser/ui/ash/vpn_delegate_chromeos.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..08804aaa9b8450f1d457d3b34d883cf02589d770 |
| --- /dev/null |
| +++ b/chrome/browser/ui/ash/vpn_delegate_chromeos.cc |
| @@ -0,0 +1,145 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/ui/ash/vpn_delegate_chromeos.h" |
| + |
| +#include "ash/shell.h" |
| +#include "ash/system/tray/system_tray_delegate.h" |
| +#include "base/logging.h" |
| +#include "chrome/browser/chrome_notification_types.h" |
| +#include "chrome/browser/chromeos/profiles/profile_helper.h" |
| +#include "chrome/browser/profiles/profile.h" |
| +#include "components/user_manager/user.h" |
| +#include "components/user_manager/user_manager.h" |
| +#include "content/public/browser/notification_service.h" |
| +#include "extensions/browser/api/vpn_provider/vpn_service.h" |
| +#include "extensions/browser/api/vpn_provider/vpn_service_factory.h" |
| +#include "extensions/browser/extension_registry.h" |
| +#include "extensions/common/extension.h" |
| +#include "extensions/common/extension_set.h" |
| +#include "extensions/common/permissions/api_permission.h" |
| +#include "extensions/common/permissions/permissions_data.h" |
| +#include "third_party/cros_system_api/dbus/service_constants.h" |
| + |
| +namespace { |
| + |
| +bool IsVPNProvider(const extensions::Extension* extension) { |
| + return extension->permissions_data()->HasAPIPermission( |
| + extensions::APIPermission::kVpnProvider); |
| +} |
| + |
| +Profile* GetProfileForPrimaryUser() { |
| + const user_manager::User* const primary_user = |
| + user_manager::UserManager::Get()->GetPrimaryUser(); |
| + if (!primary_user) |
| + return nullptr; |
| + |
| + return chromeos::ProfileHelper::Get()->GetProfileByUser(primary_user); |
| +} |
| + |
| +} // namespace |
| + |
| +VPNDelegateChromeOS::VPNDelegateChromeOS() { |
| + if (user_manager::UserManager::Get()->GetPrimaryUser()) { |
| + // If a user is logged in, start observing the primary user's extension |
| + // registry immediately. |
| + AttachToPrimaryUserExtensionRegistry(); |
| + } else { |
| + // If no user is logged in, wait for the first user to log in and become the |
| + // primary user. |
| + registrar_.Add(this, |
| + chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, |
| + content::NotificationService::AllSources()); |
| + } |
| +} |
| + |
| +VPNDelegateChromeOS::~VPNDelegateChromeOS() { |
| + if (extension_registry_) |
| + extension_registry_->RemoveObserver(this); |
| +} |
| + |
| +bool VPNDelegateChromeOS::HaveThirdPartyVPNProviders() const { |
| + return !third_party_vpn_providers_.empty(); |
| +} |
| + |
| +const std::vector<ash::VPNProvider>& |
| +VPNDelegateChromeOS::GetThirdPartyVPNProviders() const { |
| + return third_party_vpn_providers_; |
| +} |
| + |
| +void VPNDelegateChromeOS::ShowAddPage(const std::string& id) { |
| + if (id.empty()) { |
| + // If |id| is an empty string, show the built-in dialog for adding an |
| + // OpenVPN or L2TP VPN. |
| + ash::Shell::GetInstance()->system_tray_delegate()->ShowOtherNetworkDialog( |
| + shill::kTypeVPN); |
| + return; |
| + } |
| + |
| + Profile* const profile = GetProfileForPrimaryUser(); |
| + if (!profile) |
| + return; |
| + |
| + // Request that the third-party VPN provider identified by |id| show its "add |
| + // network" dialog. |
| + chromeos::VpnServiceFactory::GetForBrowserContext(profile)->TriggerAdd(id); |
| +} |
| + |
| +void VPNDelegateChromeOS::OnExtensionLoaded( |
| + content::BrowserContext* browser_context, |
| + const extensions::Extension* extension) { |
| + if (IsVPNProvider(extension)) |
| + UpdateThirdPartyVPNProviders(); |
| +} |
| + |
| +void VPNDelegateChromeOS::OnExtensionUnloaded( |
| + content::BrowserContext* browser_context, |
| + const extensions::Extension* extension, |
| + extensions::UnloadedExtensionInfo::Reason reason) { |
| + if (IsVPNProvider(extension)) |
| + UpdateThirdPartyVPNProviders(); |
| +} |
| + |
| +void VPNDelegateChromeOS::OnShutdown(extensions::ExtensionRegistry* registry) { |
| + DCHECK(extension_registry_); |
| + extension_registry_->RemoveObserver(this); |
| + extension_registry_ = nullptr; |
| +} |
| + |
| +void VPNDelegateChromeOS::Observe( |
| + int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) { |
| + // A user has logged in and become the primary user. Stop watching user logins |
| + // and start observing the primary user's extension registry. |
| + DCHECK_EQ(chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, type); |
| + registrar_.RemoveAll(); |
| + AttachToPrimaryUserExtensionRegistry(); |
| + |
| +} |
| + |
| +void VPNDelegateChromeOS::UpdateThirdPartyVPNProviders() { |
| + DCHECK(extension_registry_); |
| + |
| + third_party_vpn_providers_.clear(); |
| + const extensions::ExtensionSet& extensions = |
| + extension_registry_->enabled_extensions(); |
| + for (const auto& extension : extensions) { |
| + if (IsVPNProvider(extension.get())) { |
| + third_party_vpn_providers_.push_back(ash::VPNProvider(extension->name(), |
| + extension->id())); |
| + } |
| + } |
|
stevenjb
2015/03/10 18:06:33
nit: Even though loading / unloading extensions is
bartfab (slow)
2015/03/10 21:13:48
UpdateThirdPartyVPNProviders() will only be called
stevenjb
2015/03/10 21:25:13
Oh, I see, there is already an IsVPNProvider(exten
|
| + |
| + NotifyObservers(); |
| +} |
| + |
| +void VPNDelegateChromeOS::AttachToPrimaryUserExtensionRegistry() { |
| + DCHECK(!extension_registry_); |
| + extension_registry_ = extensions::ExtensionRegistry::Get( |
| + GetProfileForPrimaryUser()); |
| + extension_registry_->AddObserver(this); |
| + |
| + UpdateThirdPartyVPNProviders(); |
| +} |