blob: 10e8d96e7f14493cab46fc2ab7add1ee156e6005 [file] [log] [blame]
// Copyright (c) 2012 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.
#ifndef CHROME_BROWSER_UI_CONTENT_SETTINGS_CONTENT_SETTING_BUBBLE_MODEL_H_
#define CHROME_BROWSER_UI_CONTENT_SETTINGS_CONTENT_SETTING_BUBBLE_MODEL_H_
#include <stdint.h>
#include <map>
#include <set>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/common/custom_handlers/protocol_handler.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/common/media_stream_request.h"
#include "ui/gfx/image/image.h"
#include "url/gurl.h"
class ContentSettingBubbleModelDelegate;
class Profile;
class ProtocolHandlerRegistry;
namespace content {
class WebContents;
}
namespace rappor {
class RapporService;
}
// The hierarchy of bubble models:
//
// ContentSettingsBubbleModel - base class
// ContentSettingMediaStreamBubbleModel - media (camera and mic)
// ContentSettingSimpleBubbleModel - single content setting
// ContentSettingMixedScriptBubbleModel - mixed script
// ContentSettingRPHBubbleModel - protocol handlers
// ContentSettingMidiSysExBubbleModel - midi sysex
// ContentSettingDomainListBubbleModel - domain list (geolocation)
// ContentSettingSingleRadioGroup - radio group
// ContentSettingCookiesBubbleModel - cookies
// ContentSettingPluginBubbleModel - plugins
// ContentSettingPopupBubbleModel - popups
// ContentSettingSubresourceFilterBubbleModel - filtered subresources
// Forward declaration necessary for downcasts.
class ContentSettingMediaStreamBubbleModel;
class ContentSettingSimpleBubbleModel;
class ContentSettingSubresourceFilterBubbleModel;
// This model provides data for ContentSettingBubble, and also controls
// the action triggered when the allow / block radio buttons are triggered.
class ContentSettingBubbleModel : public content::NotificationObserver {
public:
typedef ContentSettingBubbleModelDelegate Delegate;
struct ListItem {
ListItem(const gfx::Image& image,
const std::string& title,
bool has_link,
int32_t item_id)
: image(image), title(title), has_link(has_link), item_id(item_id) {}
gfx::Image image;
std::string title;
bool has_link;
int32_t item_id;
};
typedef std::vector<ListItem> ListItems;
typedef std::vector<std::string> RadioItems;
struct RadioGroup {
RadioGroup();
~RadioGroup();
GURL url;
std::string title;
RadioItems radio_items;
int default_item;
};
struct DomainList {
DomainList();
DomainList(const DomainList& other);
~DomainList();
std::string title;
std::set<std::string> hosts;
};
struct MediaMenu {
MediaMenu();
MediaMenu(const MediaMenu& other);
~MediaMenu();
std::string label;
content::MediaStreamDevice default_device;
content::MediaStreamDevice selected_device;
bool disabled;
};
typedef std::map<content::MediaStreamType, MediaMenu> MediaMenuMap;
struct BubbleContent {
BubbleContent();
~BubbleContent();
base::string16 title;
base::string16 message;
ListItems list_items;
RadioGroup radio_group;
bool radio_group_enabled;
std::vector<DomainList> domain_lists;
std::string custom_link;
bool custom_link_enabled;
std::string manage_text;
bool show_manage_text_as_button;
MediaMenuMap media_menus;
std::string learn_more_link;
private:
DISALLOW_COPY_AND_ASSIGN(BubbleContent);
};
// Creates a bubble model for a particular |content_type|. Note that not all
// bubbles fit this description.
// TODO(msramek): Move this to ContentSettingSimpleBubbleModel or remove
// entirely.
static ContentSettingBubbleModel* CreateContentSettingBubbleModel(
Delegate* delegate,
content::WebContents* web_contents,
Profile* profile,
ContentSettingsType content_type);
~ContentSettingBubbleModel() override;
const BubbleContent& bubble_content() const { return bubble_content_; }
// content::NotificationObserver:
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
virtual void OnRadioClicked(int radio_index) {}
virtual void OnListItemClicked(int index) {}
virtual void OnCustomLinkClicked() {}
virtual void OnManageLinkClicked() {}
virtual void OnLearnMoreLinkClicked() {}
virtual void OnMediaMenuClicked(content::MediaStreamType type,
const std::string& selected_device_id) {}
// Called by the view code when the bubble is closed by the user using the
// Done button.
virtual void OnDoneClicked() {}
// TODO(msramek): The casting methods below are only necessary because
// ContentSettingBubbleController in the Cocoa UI needs to know the type of
// the bubble it wraps. Find a solution that does not require reflection nor
// recreating the entire hierarchy for Cocoa UI.
// Cast this bubble into ContentSettingSimpleBubbleModel if possible.
virtual ContentSettingSimpleBubbleModel* AsSimpleBubbleModel();
// Cast this bubble into ContentSettingMediaStreamBubbleModel if possible.
virtual ContentSettingMediaStreamBubbleModel* AsMediaStreamBubbleModel();
// Cast this bubble into ContentSettingSubresourceFilterBubbleModel
// if possible.
virtual ContentSettingSubresourceFilterBubbleModel*
AsSubresourceFilterBubbleModel();
// Sets the Rappor service used for testing.
void SetRapporServiceForTesting(rappor::RapporService* rappor_service) {
rappor_service_ = rappor_service;
}
protected:
ContentSettingBubbleModel(
Delegate* delegate,
content::WebContents* web_contents,
Profile* profile);
content::WebContents* web_contents() const { return web_contents_; }
Profile* profile() const { return profile_; }
Delegate* delegate() const { return delegate_; }
void set_title(const base::string16& title) { bubble_content_.title = title; }
void set_message(const base::string16& message) {
bubble_content_.message = message;
}
void add_list_item(const ListItem& item) {
bubble_content_.list_items.push_back(item);
}
void set_radio_group(const RadioGroup& radio_group) {
bubble_content_.radio_group = radio_group;
}
void set_radio_group_enabled(bool enabled) {
bubble_content_.radio_group_enabled = enabled;
}
void add_domain_list(const DomainList& domain_list) {
bubble_content_.domain_lists.push_back(domain_list);
}
void set_custom_link(const std::string& link) {
bubble_content_.custom_link = link;
}
void set_custom_link_enabled(bool enabled) {
bubble_content_.custom_link_enabled = enabled;
}
void set_manage_text(const std::string& link) {
bubble_content_.manage_text = link;
}
void set_show_manage_text_as_button(bool show_manage_text_as_button) {
bubble_content_.show_manage_text_as_button = show_manage_text_as_button;
}
void set_learn_more_link(const std::string& link) {
bubble_content_.learn_more_link = link;
}
void add_media_menu(content::MediaStreamType type, const MediaMenu& menu) {
bubble_content_.media_menus[type] = menu;
}
void set_selected_device(const content::MediaStreamDevice& device) {
bubble_content_.media_menus[device.type].selected_device = device;
}
bool setting_is_managed() {
return setting_is_managed_;
}
void set_setting_is_managed(bool managed) {
setting_is_managed_ = managed;
}
rappor::RapporService* rappor_service() const { return rappor_service_; }
private:
virtual void SetTitle() = 0;
virtual void SetManageText() = 0;
content::WebContents* web_contents_;
Profile* profile_;
Delegate* delegate_;
BubbleContent bubble_content_;
// A registrar for listening for WEB_CONTENTS_DESTROYED notifications.
content::NotificationRegistrar registrar_;
// A flag that indicates if the content setting managed i.e. can't be
// controlled by the user.
bool setting_is_managed_;
// The service used to record Rappor metrics. Can be set for testing.
rappor::RapporService* rappor_service_;
DISALLOW_COPY_AND_ASSIGN(ContentSettingBubbleModel);
};
// A generic bubble used for a single content setting.
class ContentSettingSimpleBubbleModel : public ContentSettingBubbleModel {
public:
ContentSettingSimpleBubbleModel(Delegate* delegate,
content::WebContents* web_contents,
Profile* profile,
ContentSettingsType content_type);
ContentSettingsType content_type() { return content_type_; }
// ContentSettingBubbleModel implementation.
ContentSettingSimpleBubbleModel* AsSimpleBubbleModel() override;
private:
// ContentSettingBubbleModel implementation.
void SetTitle() override;
void SetManageText() override;
void OnManageLinkClicked() override;
void SetCustomLink();
void OnCustomLinkClicked() override;
ContentSettingsType content_type_;
DISALLOW_COPY_AND_ASSIGN(ContentSettingSimpleBubbleModel);
};
// RPH stands for Register Protocol Handler.
class ContentSettingRPHBubbleModel : public ContentSettingSimpleBubbleModel {
public:
ContentSettingRPHBubbleModel(Delegate* delegate,
content::WebContents* web_contents,
Profile* profile,
ProtocolHandlerRegistry* registry);
~ContentSettingRPHBubbleModel() override;
void OnRadioClicked(int radio_index) override;
void OnDoneClicked() override;
private:
void RegisterProtocolHandler();
void UnregisterProtocolHandler();
void IgnoreProtocolHandler();
void ClearOrSetPreviousHandler();
int selected_item_;
// Initially false, set to true if the user explicitly interacts with the
// bubble.
bool interacted_;
ProtocolHandlerRegistry* registry_;
ProtocolHandler pending_handler_;
ProtocolHandler previous_handler_;
DISALLOW_COPY_AND_ASSIGN(ContentSettingRPHBubbleModel);
};
// The model for the deceptive content bubble.
class ContentSettingSubresourceFilterBubbleModel
: public ContentSettingBubbleModel {
public:
ContentSettingSubresourceFilterBubbleModel(Delegate* delegate,
content::WebContents* web_contents,
Profile* profile);
~ContentSettingSubresourceFilterBubbleModel() override;
void OnManageLinkClicked() override;
ContentSettingSubresourceFilterBubbleModel* AsSubresourceFilterBubbleModel()
override;
private:
void SetMessage();
// ContentSettingBubbleModel:
void SetTitle() override;
void SetManageText() override;
DISALLOW_COPY_AND_ASSIGN(ContentSettingSubresourceFilterBubbleModel);
};
// The model of the content settings bubble for media settings.
class ContentSettingMediaStreamBubbleModel : public ContentSettingBubbleModel {
public:
ContentSettingMediaStreamBubbleModel(Delegate* delegate,
content::WebContents* web_contents,
Profile* profile);
~ContentSettingMediaStreamBubbleModel() override;
// ContentSettingBubbleModel:
ContentSettingMediaStreamBubbleModel* AsMediaStreamBubbleModel() override;
void OnManageLinkClicked() override;
private:
// Helper functions to check if this bubble was invoked for microphone,
// camera, or both devices.
bool MicrophoneAccessed() const;
bool CameraAccessed() const;
// ContentSettingBubbleModel:
void SetTitle() override;
void SetManageText() override;
// Sets the data for the radio buttons of the bubble.
void SetRadioGroup();
// Sets the data for the media menus of the bubble.
void SetMediaMenus();
// Sets the string that suggests reloading after the settings were changed.
void SetCustomLink();
// Updates the camera and microphone setting with the passed |setting|.
void UpdateSettings(ContentSetting setting);
// Updates the camera and microphone default device with the passed |type|
// and device.
void UpdateDefaultDeviceForType(content::MediaStreamType type,
const std::string& device);
// ContentSettingBubbleModel implementation.
void OnRadioClicked(int radio_index) override;
void OnMediaMenuClicked(content::MediaStreamType type,
const std::string& selected_device) override;
// The index of the selected radio item.
int selected_item_;
// The content settings that are associated with the individual radio
// buttons.
ContentSetting radio_item_setting_[2];
// The state of the microphone and camera access.
TabSpecificContentSettings::MicrophoneCameraState state_;
DISALLOW_COPY_AND_ASSIGN(ContentSettingMediaStreamBubbleModel);
};
#endif // CHROME_BROWSER_UI_CONTENT_SETTINGS_CONTENT_SETTING_BUBBLE_MODEL_H_