page_specific_content_settings.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. // Copyright (c) 2012 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.
  4. #ifndef COMPONENTS_CONTENT_SETTINGS_BROWSER_PAGE_SPECIFIC_CONTENT_SETTINGS_H_
  5. #define COMPONENTS_CONTENT_SETTINGS_BROWSER_PAGE_SPECIFIC_CONTENT_SETTINGS_H_
  6. #include <stdint.h>
  7. #include <map>
  8. #include <memory>
  9. #include <set>
  10. #include <string>
  11. #include "base/containers/flat_set.h"
  12. #include "base/memory/raw_ptr.h"
  13. #include "base/memory/ref_counted.h"
  14. #include "base/memory/weak_ptr.h"
  15. #include "base/observer_list.h"
  16. #include "base/scoped_observation.h"
  17. #include "build/build_config.h"
  18. #include "build/chromeos_buildflags.h"
  19. #include "components/browsing_data/content/cookie_helper.h"
  20. #include "components/browsing_data/content/local_shared_objects_container.h"
  21. #include "components/content_settings/common/content_settings_manager.mojom.h"
  22. #include "components/content_settings/core/browser/content_settings_observer.h"
  23. #include "components/content_settings/core/browser/host_content_settings_map.h"
  24. #include "components/content_settings/core/common/content_settings.h"
  25. #include "components/content_settings/core/common/content_settings_types.h"
  26. #include "components/privacy_sandbox/canonical_topic.h"
  27. #include "content/public/browser/allow_service_worker_result.h"
  28. #include "content/public/browser/page_user_data.h"
  29. #include "content/public/browser/render_frame_host.h"
  30. namespace blink {
  31. class StorageKey;
  32. } // namespace blink
  33. namespace content {
  34. class WebContents;
  35. class WebContentsObserver;
  36. }
  37. namespace url {
  38. class Origin;
  39. } // namespace url
  40. namespace content_settings {
  41. // TODO(msramek): Media is storing their state in PageSpecificContentSettings:
  42. // |microphone_camera_state_| without being tied to a single content setting.
  43. // This state is not ideal, potential solution is to save this information via
  44. // content::WebContentsUserData
  45. // This class manages state about permissions, content settings, cookies and
  46. // site data for a specific page (main document and all of its child frames). It
  47. // tracks which content was accessed and which content was blocked. Based on
  48. // this it provides information about which types of content were accessed and
  49. // blocked.
  50. //
  51. // Tracking is done per main document so instances of this class will be deleted
  52. // when the main document is deleted. This can happen after the tab navigates
  53. // away to a new document or when the tab itself is deleted, so you should not
  54. // keep references to objects of this class.
  55. //
  56. // When a page enters the back-forward cache its associated
  57. // PageSpecificContentSettings are not cleared and will be restored along with
  58. // the document when navigating back. These stored instances still listen to
  59. // content settings updates and keep their internal state up to date.
  60. //
  61. // Events tied to a main frame navigation will be associated with the newly
  62. // loaded page once the navigation commits or discarded if it does not.
  63. class PageSpecificContentSettings
  64. : public content_settings::Observer,
  65. public content::PageUserData<PageSpecificContentSettings> {
  66. public:
  67. // Fields describing the current mic/camera state. If a page has attempted to
  68. // access a device, the XXX_ACCESSED bit will be set. If access was blocked,
  69. // XXX_BLOCKED will be set.
  70. enum MicrophoneCameraStateFlags {
  71. MICROPHONE_CAMERA_NOT_ACCESSED = 0,
  72. MICROPHONE_ACCESSED = 1 << 0,
  73. MICROPHONE_BLOCKED = 1 << 1,
  74. CAMERA_ACCESSED = 1 << 2,
  75. CAMERA_BLOCKED = 1 << 3,
  76. };
  77. // Use signed int, that's what the enum flags implicitly convert to.
  78. typedef int32_t MicrophoneCameraState;
  79. class Delegate {
  80. public:
  81. virtual ~Delegate() = default;
  82. // Called when content settings state changes that might require updating
  83. // the location bar.
  84. virtual void UpdateLocationBar() = 0;
  85. // Gets the pref service for the current web contents.
  86. virtual PrefService* GetPrefs() = 0;
  87. // Gets the settings map for the current web contents.
  88. virtual HostContentSettingsMap* GetSettingsMap() = 0;
  89. // Allows delegate to override content setting rules that will be sent to
  90. // the renderer.
  91. virtual void SetDefaultRendererContentSettingRules(
  92. content::RenderFrameHost* rfh,
  93. RendererContentSettingRules* rules) = 0;
  94. // Gets any additional file system types which should be used when
  95. // constructing a browsing_data::FileSystemHelper.
  96. virtual std::vector<storage::FileSystemType>
  97. GetAdditionalFileSystemTypes() = 0;
  98. virtual browsing_data::CookieHelper::IsDeletionDisabledCallback
  99. GetIsDeletionDisabledCallback() = 0;
  100. // Allows the delegate to provide additional logic for detecting state
  101. // changes on top of the camera/microphone permission state.
  102. virtual bool IsMicrophoneCameraStateChanged(
  103. MicrophoneCameraState microphone_camera_state,
  104. const std::string& media_stream_selected_audio_device,
  105. const std::string& media_stream_selected_video_device) = 0;
  106. // Allows the delegate to provide additional logic for getting microphone
  107. // and camera state on top of the microphone and camera state at the last
  108. // media stream request.
  109. virtual MicrophoneCameraState GetMicrophoneCameraState() = 0;
  110. // Notifies the delegate a particular content settings type was allowed for
  111. // the first time on this page.
  112. virtual void OnContentAllowed(ContentSettingsType type) = 0;
  113. // Notifies the delegate a particular content settings type was blocked.
  114. virtual void OnContentBlocked(ContentSettingsType type) = 0;
  115. // Notifies the delegate that access to storage of type |storage_type| was
  116. // granted in |page|.
  117. virtual void OnStorageAccessAllowed(
  118. mojom::ContentSettingsManager::StorageType storage_type,
  119. const url::Origin& origin,
  120. content::Page& page) = 0;
  121. // Notifies the delegate that access was granted to |accessed_cookies| in
  122. // |page|.
  123. virtual void OnCookieAccessAllowed(const net::CookieList& accessed_cookies,
  124. content::Page& page) = 0;
  125. // Notifies the delegate that access was granted to service workers for
  126. // |origin|.
  127. virtual void OnServiceWorkerAccessAllowed(const url::Origin& origin,
  128. content::Page& page) = 0;
  129. };
  130. // Classes that want to be notified about site data events must implement
  131. // this abstract class and add themselves as observer to the
  132. // |PageSpecificContentSettings|.
  133. class SiteDataObserver {
  134. public:
  135. explicit SiteDataObserver(content::WebContents* web_contents);
  136. SiteDataObserver(const SiteDataObserver&) = delete;
  137. SiteDataObserver& operator=(const SiteDataObserver&) = delete;
  138. virtual ~SiteDataObserver();
  139. // Called whenever site data is accessed.
  140. virtual void OnSiteDataAccessed() = 0;
  141. content::WebContents* web_contents() { return web_contents_; }
  142. // Called when the WebContents is destroyed; nulls out
  143. // the local reference.
  144. void WebContentsDestroyed();
  145. private:
  146. raw_ptr<content::WebContents> web_contents_;
  147. };
  148. PageSpecificContentSettings(const PageSpecificContentSettings&) = delete;
  149. PageSpecificContentSettings& operator=(const PageSpecificContentSettings&) =
  150. delete;
  151. ~PageSpecificContentSettings() override;
  152. static void CreateForWebContents(content::WebContents* web_contents,
  153. std::unique_ptr<Delegate> delegate);
  154. static void DeleteForWebContentsForTest(content::WebContents* web_contents);
  155. // Returns the object given a RenderFrameHost ids. Returns nullptr if the
  156. // frame no longer exist or there are no PageSpecificContentSettings attached
  157. // to the document.
  158. static PageSpecificContentSettings* GetForFrame(int render_process_id,
  159. int render_frame_id);
  160. // Returns the object given a RenderFrameHost. Returns nullptr if the frame
  161. // is nullptr or there are no PageSpecificContentSettings attached to the
  162. // document.
  163. static PageSpecificContentSettings* GetForFrame(
  164. content::RenderFrameHost* rfh);
  165. // Returns the Delegate that was associated to |web_contents| in
  166. // CreateForWebContents. Null if CreateForWebContents was not called for
  167. // |web_contents|.
  168. static PageSpecificContentSettings::Delegate* GetDelegateForWebContents(
  169. content::WebContents* web_contents);
  170. static void StorageAccessed(
  171. mojom::ContentSettingsManager::StorageType storage_type,
  172. int render_process_id,
  173. int render_frame_id,
  174. const GURL& url,
  175. bool blocked_by_policy);
  176. // Called when content access is blocked in the renderer process.
  177. static void ContentBlocked(int render_process_id,
  178. int render_frame_id,
  179. ContentSettingsType type);
  180. // Called when a specific Shared Worker was accessed.
  181. static void SharedWorkerAccessed(int render_process_id,
  182. int render_frame_id,
  183. const GURL& worker_url,
  184. const std::string& name,
  185. const blink::StorageKey& storage_key,
  186. bool blocked_by_policy);
  187. // Called when |api_origin| attempts to join an interest group via the
  188. // Interest Group API.
  189. static void InterestGroupJoined(content::RenderFrameHost* rfh,
  190. const url::Origin api_origin,
  191. bool blocked_by_policy);
  192. // Called when |api_origin| attempts to access browsing topics.
  193. static void TopicAccessed(content::RenderFrameHost* rfh,
  194. const url::Origin api_origin,
  195. bool blocked_by_policy,
  196. privacy_sandbox::CanonicalTopic topic);
  197. static content::WebContentsObserver* GetWebContentsObserverForTest(
  198. content::WebContents* web_contents);
  199. // Returns a WeakPtr to this instance. Given that PageSpecificContentSettings
  200. // instances are tied to a page it is generally unsafe to store these
  201. // references, instead a WeakPtr should be used instead.
  202. base::WeakPtr<PageSpecificContentSettings> AsWeakPtr() {
  203. return weak_factory_.GetWeakPtr();
  204. }
  205. // Changes the |content_blocked_| entry for popups.
  206. void ClearPopupsBlocked();
  207. // Called when audio has been blocked on the page.
  208. void OnAudioBlocked();
  209. // Returns whether a particular kind of content has been blocked for this
  210. // page.
  211. bool IsContentBlocked(ContentSettingsType content_type) const;
  212. // Returns whether a particular kind of content has been allowed. Currently
  213. // only tracks cookies.
  214. bool IsContentAllowed(ContentSettingsType content_type) const;
  215. const GURL& media_stream_access_origin() const {
  216. return media_stream_access_origin_;
  217. }
  218. const std::string& media_stream_requested_audio_device() const {
  219. return media_stream_requested_audio_device_;
  220. }
  221. const std::string& media_stream_requested_video_device() const {
  222. return media_stream_requested_video_device_;
  223. }
  224. // Only public for tests.
  225. const std::string& media_stream_selected_audio_device() const {
  226. return media_stream_selected_audio_device_;
  227. }
  228. // Only public for tests.
  229. const std::string& media_stream_selected_video_device() const {
  230. return media_stream_selected_video_device_;
  231. }
  232. bool camera_was_just_granted_on_site_level() {
  233. return camera_was_just_granted_on_site_level_;
  234. }
  235. bool mic_was_just_granted_on_site_level() {
  236. return mic_was_just_granted_on_site_level_;
  237. }
  238. bool geolocation_was_just_granted_on_site_level() {
  239. return geolocation_was_just_granted_on_site_level_;
  240. }
  241. // Returns the state of the camera and microphone usage.
  242. // The return value always includes all active media capture devices, on top
  243. // of the devices from the last request.
  244. MicrophoneCameraState GetMicrophoneCameraState() const;
  245. // Returns whether the camera or microphone permission or media device setting
  246. // has changed since the last permission request.
  247. bool IsMicrophoneCameraStateChanged() const;
  248. // Returns the |LocalSharedObjectsContainer| instances corresponding to all
  249. // allowed, and blocked, respectively, local shared objects like cookies,
  250. // local storage, ... .
  251. const browsing_data::LocalSharedObjectsContainer&
  252. allowed_local_shared_objects() const {
  253. return allowed_local_shared_objects_;
  254. }
  255. const browsing_data::LocalSharedObjectsContainer&
  256. blocked_local_shared_objects() const {
  257. return blocked_local_shared_objects_;
  258. }
  259. // Called to indicate whether access to the Pepper broker was allowed or
  260. // blocked.
  261. void SetPepperBrokerAllowed(bool allowed);
  262. void OnContentBlocked(ContentSettingsType type);
  263. void OnContentAllowed(ContentSettingsType type);
  264. // |originating_page| is non-null when it differs from page(), which happens
  265. // when an embedding page's PSCS is notified of an access that happens in an
  266. // embedded page (through |MaybeUpdateParent|).
  267. void OnStorageAccessed(
  268. mojom::ContentSettingsManager::StorageType storage_type,
  269. const GURL& url,
  270. bool blocked_by_policy,
  271. content::Page* originating_page = nullptr);
  272. void OnSharedWorkerAccessed(const GURL& worker_url,
  273. const std::string& name,
  274. const blink::StorageKey& storage_key,
  275. bool blocked_by_policy);
  276. void OnInterestGroupJoined(const url::Origin api_origin,
  277. bool blocked_by_policy);
  278. void OnTopicAccessed(const url::Origin api_origin,
  279. bool blocked_by_policy,
  280. privacy_sandbox::CanonicalTopic topic);
  281. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
  282. void OnProtectedMediaIdentifierPermissionSet(const GURL& requesting_frame,
  283. bool allowed);
  284. #endif
  285. // This method is called to update the status about the microphone and
  286. // camera stream access.
  287. void OnMediaStreamPermissionSet(
  288. const GURL& request_origin,
  289. MicrophoneCameraState new_microphone_camera_state,
  290. const std::string& media_stream_selected_audio_device,
  291. const std::string& media_stream_selected_video_device,
  292. const std::string& media_stream_requested_audio_device,
  293. const std::string& media_stream_requested_video_device);
  294. // See |OnStorageAccessed| documentation for more info on |originating_page|.
  295. void OnCookiesAccessed(const content::CookieAccessDetails& details,
  296. content::Page* originating_page = nullptr);
  297. void OnServiceWorkerAccessed(const GURL& scope,
  298. content::AllowServiceWorkerResult allowed,
  299. content::Page* originating_page = nullptr);
  300. // Block all content. Used for testing content setting bubbles.
  301. void BlockAllContentForTesting();
  302. // Stores content settings changed by the user via PageInfo.
  303. void ContentSettingChangedViaPageInfo(ContentSettingsType type);
  304. // Returns true if the user changed the given ContentSettingsType via PageInfo
  305. // since the last navigation.
  306. bool HasContentSettingChangedViaPageInfo(ContentSettingsType type) const;
  307. // Returns true if the user was joined to an interest group and if the page
  308. // is the joining origin.
  309. bool HasJoinedUserToInterestGroup() const;
  310. // Returns true if the page has accessed the Topics API.
  311. bool HasAccessedTopics() const;
  312. // Returns the topics that were accessed by this page.
  313. std::vector<privacy_sandbox::CanonicalTopic> GetAccessedTopics() const;
  314. // Runs any queued updates in |updates_queued_during_prerender_|, should be
  315. // called after the page activates.
  316. void OnPrerenderingPageActivation();
  317. private:
  318. friend class content::PageUserData<PageSpecificContentSettings>;
  319. struct PendingUpdates {
  320. PendingUpdates();
  321. ~PendingUpdates();
  322. std::vector<base::OnceClosure> delegate_updates;
  323. bool site_data_accessed = false;
  324. };
  325. explicit PageSpecificContentSettings(content::Page& page, Delegate* delegate);
  326. // content_settings::Observer implementation.
  327. void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern,
  328. const ContentSettingsPattern& secondary_pattern,
  329. ContentSettingsType content_type) override;
  330. // Clears settings changed by the user via PageInfo since the last navigation.
  331. void ClearContentSettingsChangedViaPageInfo();
  332. bool IsPagePrerendering() const;
  333. bool IsEmbeddedPage() const;
  334. // Delays the call of the delegate method if the page is currently
  335. // prerendering until the page is activated; directly calls the method
  336. // otherwise.
  337. template <typename DelegateMethod, typename... Args>
  338. void NotifyDelegate(DelegateMethod method, Args... args) {
  339. if (IsEmbeddedPage())
  340. return;
  341. if (IsPagePrerendering()) {
  342. DCHECK(updates_queued_during_prerender_);
  343. updates_queued_during_prerender_->delegate_updates.emplace_back(
  344. base::BindOnce(method, base::Unretained(delegate_), args...));
  345. return;
  346. }
  347. (*delegate_.*method)(args...);
  348. }
  349. // Used to notify the parent page's PSCS of a content access.
  350. template <typename PSCSMethod, typename... Args>
  351. void MaybeUpdateParent(PSCSMethod method, Args... args) {
  352. if (IsEmbeddedPage()) {
  353. PageSpecificContentSettings* pscs =
  354. PageSpecificContentSettings::GetForFrame(
  355. page().GetMainDocument().GetParentOrOuterDocument());
  356. DCHECK(pscs);
  357. (*pscs.*method)(args...);
  358. }
  359. }
  360. // Notifies observers. Like |NotifyDelegate|, the notification is delayed for
  361. // prerendering pages until the page is activated. Embedded pages will not
  362. // notify observers directly and rely on the outermost page to do so.
  363. void MaybeNotifySiteDataObservers();
  364. // Tells the delegate to update the location bar. This method is a no-op if
  365. // the page is currently prerendering or is embedded.
  366. void MaybeUpdateLocationBar();
  367. content::WebContents* GetWebContents() const;
  368. raw_ptr<Delegate> delegate_;
  369. struct ContentSettingsStatus {
  370. bool blocked;
  371. bool allowed;
  372. };
  373. // Stores which content setting types actually have blocked content.
  374. std::map<ContentSettingsType, ContentSettingsStatus> content_settings_status_;
  375. // Profile-bound, this will outlive this class (which is WebContents bound).
  376. raw_ptr<HostContentSettingsMap> map_;
  377. // Stores the blocked/allowed cookies.
  378. browsing_data::LocalSharedObjectsContainer allowed_local_shared_objects_;
  379. browsing_data::LocalSharedObjectsContainer blocked_local_shared_objects_;
  380. // The origin of the media stream request. Note that we only support handling
  381. // settings for one request per tab. The latest request's origin will be
  382. // stored here. http://crbug.com/259794
  383. GURL media_stream_access_origin_;
  384. // The microphone and camera state at the last media stream request.
  385. MicrophoneCameraState microphone_camera_state_;
  386. // The selected devices at the last media stream request.
  387. std::string media_stream_selected_audio_device_;
  388. std::string media_stream_selected_video_device_;
  389. // The devices to be displayed in the media bubble when the media stream
  390. // request is requesting certain specific devices.
  391. std::string media_stream_requested_audio_device_;
  392. std::string media_stream_requested_video_device_;
  393. // Contains URLs which attempted to join interest groups. Note: The UI will
  394. // only currently show the top frame as having attempted to join.
  395. std::vector<url::Origin> allowed_interest_group_api_;
  396. std::vector<url::Origin> blocked_interest_group_api_;
  397. // Contains topics that were accessed by this page.
  398. base::flat_set<privacy_sandbox::CanonicalTopic> accessed_topics_;
  399. // The Geolocation, camera, and/or microphone permission was granted to this
  400. // origin from a permission prompt that was triggered by the currently active
  401. // document.
  402. bool camera_was_just_granted_on_site_level_ = false;
  403. bool mic_was_just_granted_on_site_level_ = false;
  404. bool geolocation_was_just_granted_on_site_level_ = false;
  405. // Observer to watch for content settings changed.
  406. base::ScopedObservation<HostContentSettingsMap, content_settings::Observer>
  407. observation_{this};
  408. // Stores content settings changed by the user via page info since the last
  409. // navigation. Used to determine whether to display the settings in page info.
  410. std::set<ContentSettingsType> content_settings_changed_via_page_info_;
  411. // Calls to |delegate_| and SiteDataObservers that have been queued up while
  412. // the page is prerendering. These calls are run when the page is activated.
  413. std::unique_ptr<PendingUpdates> updates_queued_during_prerender_;
  414. PAGE_USER_DATA_KEY_DECL();
  415. base::WeakPtrFactory<PageSpecificContentSettings> weak_factory_{this};
  416. };
  417. } // namespace content_settings
  418. #endif // COMPONENTS_CONTENT_SETTINGS_BROWSER_PAGE_SPECIFIC_CONTENT_SETTINGS_H_