| 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..52a21f2a44bd01cdeeb2862d4df11f66c6e23123
|
| --- /dev/null
|
| +++ b/chrome/browser/ui/ash/vpn_delegate_chromeos.cc
|
| @@ -0,0 +1,169 @@
|
| +// 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/bind.h"
|
| +#include "base/location.h"
|
| +#include "base/logging.h"
|
| +#include "base/thread_task_runner_handle.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 "content/public/browser/notification_source.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"
|
| +#include "ui/base/l10n/l10n_util.h"
|
| +#include "ui/chromeos/strings/grit/ui_chromeos_strings.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() : weak_factory_(this) {
|
| + 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 until the first user logs in (thus becoming
|
| + // the primary user) and a profile is created for that user.
|
| + registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
|
| + content::NotificationService::AllSources());
|
| + }
|
| +}
|
| +
|
| +VPNDelegateChromeOS::~VPNDelegateChromeOS() {
|
| + if (extension_registry_)
|
| + extension_registry_->RemoveObserver(this);
|
| +}
|
| +
|
| +bool VPNDelegateChromeOS::HaveThirdPartyVPNProviders() const {
|
| + for (const ash::VPNProvider& provider : vpn_providers_) {
|
| + if (provider.key.third_party)
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +const std::vector<ash::VPNProvider>& VPNDelegateChromeOS::GetVPNProviders()
|
| + const {
|
| + return vpn_providers_;
|
| +}
|
| +
|
| +void VPNDelegateChromeOS::ShowAddPage(const ash::VPNProvider::Key& key) {
|
| + if (!key.third_party) {
|
| + // Show the "add network" dialog for the built-in OpenVPN/L2TP provider.
|
| + 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 |key.extension_id|
|
| + // show its "add network" dialog.
|
| + chromeos::VpnServiceFactory::GetForBrowserContext(profile)
|
| + ->SendShowAddDialogToExtension(key.extension_id);
|
| +}
|
| +
|
| +void VPNDelegateChromeOS::OnExtensionLoaded(
|
| + content::BrowserContext* browser_context,
|
| + const extensions::Extension* extension) {
|
| + if (IsVPNProvider(extension))
|
| + UpdateVPNProviders();
|
| +}
|
| +
|
| +void VPNDelegateChromeOS::OnExtensionUnloaded(
|
| + content::BrowserContext* browser_context,
|
| + const extensions::Extension* extension,
|
| + extensions::UnloadedExtensionInfo::Reason reason) {
|
| + if (IsVPNProvider(extension))
|
| + UpdateVPNProviders();
|
| +}
|
| +
|
| +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) {
|
| + DCHECK_EQ(chrome::NOTIFICATION_PROFILE_CREATED, type);
|
| + const Profile* const profile = content::Source<Profile>(source).ptr();
|
| + if (!chromeos::ProfileHelper::Get()->IsPrimaryProfile(profile)) {
|
| + // If the profile that was just created does not belong to the primary user
|
| + // (e.g. login profile), ignore it.
|
| + return;
|
| + }
|
| +
|
| + // The first user logged in (thus becoming the primary user) and a profile was
|
| + // created for that user. Stop observing profile creation. Wait one message
|
| + // loop cycle to allow other code which observes the
|
| + // chrome::NOTIFICATION_PROFILE_CREATED notification to finish initializing
|
| + // the profile, then start observing the primary user's extension registry.
|
| + registrar_.RemoveAll();
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&VPNDelegateChromeOS::AttachToPrimaryUserExtensionRegistry,
|
| + weak_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +void VPNDelegateChromeOS::UpdateVPNProviders() {
|
| + DCHECK(extension_registry_);
|
| +
|
| + vpn_providers_.clear();
|
| + for (const auto& extension : extension_registry_->enabled_extensions()) {
|
| + if (IsVPNProvider(extension.get())) {
|
| + vpn_providers_.push_back(ash::VPNProvider(
|
| + ash::VPNProvider::Key(extension->id()), extension->name()));
|
| + }
|
| + }
|
| + // Add the built-in OpenVPN/L2TP provider. The ash::VPNProvider::Key()
|
| + // constructor generates a key that identifies that built-in provider and has
|
| + // no extension ID.
|
| + vpn_providers_.push_back(ash::VPNProvider(
|
| + ash::VPNProvider::Key(),
|
| + l10n_util::GetStringUTF8(IDS_NETWORK_VPN_BUILT_IN_PROVIDER)));
|
| +
|
| + NotifyObservers();
|
| +}
|
| +
|
| +void VPNDelegateChromeOS::AttachToPrimaryUserExtensionRegistry() {
|
| + DCHECK(!extension_registry_);
|
| + extension_registry_ =
|
| + extensions::ExtensionRegistry::Get(GetProfileForPrimaryUser());
|
| + extension_registry_->AddObserver(this);
|
| +
|
| + UpdateVPNProviders();
|
| +}
|
|
|