1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PERMISSIONS_ONE_TIME_PERMISSIONS_TRACKER_H_
#define CHROME_BROWSER_PERMISSIONS_ONE_TIME_PERMISSIONS_TRACKER_H_
#include <map>
#include <set>
#include "base/observer_list.h"
#include "base/timer/timer.h"
#include "chrome/browser/permissions/one_time_permissions_tracker_observer.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/visibility.h"
#include "url/origin.h"
// This observable class keeps track of one-time permission related browsing
// states.
class OneTimePermissionsTracker : public KeyedService {
using NotifyFunction =
void (OneTimePermissionsTracker::*)(const url::Origin&);
public:
OneTimePermissionsTracker();
~OneTimePermissionsTracker() override;
OneTimePermissionsTracker(const OneTimePermissionsTracker&) = delete;
OneTimePermissionsTracker& operator=(const OneTimePermissionsTracker&) =
delete;
// Handles primary page changes to `origin` and pages of `origin` being
// undiscarded.
void WebContentsLoadedOrigin(const url::Origin& origin);
// Handles primary page changes from `origin`, pages of `origin` getting
// discarded and other WebContent destroy events.
void WebContentsUnloadedOrigin(const url::Origin& origin);
// Adds observer implementing `OneTimePermissionsTrackerObserver`.
void AddObserver(OneTimePermissionsTrackerObserver* observer);
// Removes observer implementing `OneTimePermissionsTrackerObserver`.
void RemoveObserver(OneTimePermissionsTrackerObserver* observer);
// Handles a WebContents visibility changes to `HIDDEN`.
void WebContentsBackgrounded(const url::Origin& origin);
// Handles a WebContents visibility changes to `OCCLUDED` or `VISIBLE`
void WebContentsUnbackgrounded(const url::Origin& origin);
// Handles changes in video capturing state.
void CapturingVideoChanged(const url::Origin& origin,
bool is_capturing_video);
// Handles changes in audio capturing state.
void CapturingAudioChanged(const url::Origin& origin,
bool is_capturing_audio);
void Shutdown() override;
// When the provider expires content settings, this function clears the
// associated state in the tracker. This prevents unnecessary calls to the
// provider for already expired content settings.
void CleanupStateForExpiredContentSetting(
ContentSettingsType type,
ContentSettingsPattern primary_pattern,
ContentSettingsPattern secondary_pattern);
// Fires all running timers for testing purposes.
void FireRunningTimersForTesting();
protected:
void NotifyLastPageFromOriginClosed(const url::Origin& origin);
void NotifyBackgroundTimerExpired(
const url::Origin& origin,
const OneTimePermissionsTrackerObserver::BackgroundExpiryType&
expiry_type);
private:
// Struct to hold the state of an origin
struct OriginTrackEntry {
OriginTrackEntry();
~OriginTrackEntry();
// Tracks how many tabs of this origin are open and undiscarded at any
// given time.
int undiscarded_tab_counter = 0;
// Tracks how many tabs of this origin are in the background.
// Background is defined as either hidden or minimized.
int background_tab_counter = 0;
// Tracks how many active permission uses for a specific content setting
// for this origin are in progress. Currently only used for camera
// and microphone permissions.
std::map<ContentSettingsType, int> content_setting_specific_counter_map;
// Keeps track of which user-media one-time content settings have been used
// for this origin.
std::set<ContentSettingsType> used_content_settings_set;
// One shot timer for expiring permissions that are temporarily disabled by
// backgrounding. This is intentionally not merged with
// `content_setting_specific_expiration_timer_map`, which is used by
// permissions that aren't disabled by backgrounding.
std::unique_ptr<base::OneShotTimer> background_expiration_timer =
std::make_unique<base::OneShotTimer>();
// One shot timer for expiring permissions that are temporarily disabled by
// backgrounding. This timer is only used in the File System Access
// Persistent Permissions implementation to detect tab backgrounding events.
std::unique_ptr<base::OneShotTimer> background_expiration_long_timer =
std::make_unique<base::OneShotTimer>();
// One shot timer for user-media one-time permissions for this origin.
std::map<ContentSettingsType, std::unique_ptr<base::OneShotTimer>>
content_setting_specific_expiration_timer_map;
};
bool ShouldIgnoreOrigin(const url::Origin& origin);
bool AreAllTabsToOriginBackgroundedOrDiscarded(const url::Origin& origin);
void RemoveContentSettingUsedFromOrigin(const url::Origin& origin,
ContentSettingsType content_setting);
void HandleUserMediaState(const url::Origin& origin,
ContentSettingsType content_setting);
void StartContentSpecificExpirationTimer(const url::Origin& origin,
ContentSettingsType content_setting,
NotifyFunction notify_callback);
void NotifyCapturingVideoExpired(const url::Origin& origin);
void NotifyCapturingAudioExpired(const url::Origin& origin);
base::ObserverList<OneTimePermissionsTrackerObserver> observer_list_;
std::map<url::Origin, OriginTrackEntry> origin_tracker_;
base::WeakPtrFactory<OneTimePermissionsTracker> weak_factory_{this};
};
#endif // CHROME_BROWSER_PERMISSIONS_ONE_TIME_PERMISSIONS_TRACKER_H_
|