1 // Copyright 2020 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 
5 #include "chrome/browser/media/webrtc/camera_pan_tilt_zoom_permission_context.h"
6 
7 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
8 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
9 #include "components/content_settings/core/browser/host_content_settings_map.h"
10 #include "components/content_settings/core/common/content_settings.h"
11 #include "components/content_settings/core/common/content_settings_types.h"
12 
13 namespace {
14 
15 struct TestConfig {
16   const ContentSetting first;   // first content setting to be set
17   const ContentSetting second;  // second content setting to be set
18   const ContentSetting result;  // expected resulting content setting
19 };
20 
21 }  // namespace
22 
23 // Waits until a change is observed for a specific content setting type.
24 class ContentSettingsChangeWaiter : public content_settings::Observer {
25  public:
ContentSettingsChangeWaiter(Profile * profile,ContentSettingsType content_type)26   explicit ContentSettingsChangeWaiter(Profile* profile,
27                                        ContentSettingsType content_type)
28       : profile_(profile), content_type_(content_type) {
29     HostContentSettingsMapFactory::GetForProfile(profile)->AddObserver(this);
30   }
~ContentSettingsChangeWaiter()31   ~ContentSettingsChangeWaiter() override {
32     HostContentSettingsMapFactory::GetForProfile(profile_)->RemoveObserver(
33         this);
34   }
35 
OnContentSettingChanged(const ContentSettingsPattern & primary_pattern,const ContentSettingsPattern & secondary_pattern,ContentSettingsType content_type)36   void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern,
37                                const ContentSettingsPattern& secondary_pattern,
38                                ContentSettingsType content_type) override {
39     if (content_type == content_type_)
40       Proceed();
41   }
42 
Wait()43   void Wait() { run_loop_.Run(); }
44 
45  private:
Proceed()46   void Proceed() { run_loop_.Quit(); }
47 
48   Profile* profile_;
49   ContentSettingsType content_type_;
50   base::RunLoop run_loop_;
51 
52   DISALLOW_COPY_AND_ASSIGN(ContentSettingsChangeWaiter);
53 };
54 
55 class CameraPanTiltZoomPermissionContextTests
56     : public ChromeRenderViewHostTestHarness,
57       public testing::WithParamInterface<TestConfig> {
58  public:
59   CameraPanTiltZoomPermissionContextTests() = default;
60 
SetContentSetting(ContentSettingsType content_settings_type,ContentSetting content_setting)61   void SetContentSetting(ContentSettingsType content_settings_type,
62                          ContentSetting content_setting) {
63     GURL url("https://www.example.com");
64     HostContentSettingsMap* content_settings =
65         HostContentSettingsMapFactory::GetForProfile(profile());
66     content_settings->SetContentSettingDefaultScope(
67         url, GURL(), content_settings_type, content_setting);
68   }
69 
GetContentSetting(ContentSettingsType content_settings_type)70   ContentSetting GetContentSetting(ContentSettingsType content_settings_type) {
71     GURL url("https://www.example.com");
72     HostContentSettingsMap* content_settings =
73         HostContentSettingsMapFactory::GetForProfile(profile());
74     return content_settings->GetContentSetting(url.GetOrigin(), url.GetOrigin(),
75                                                content_settings_type);
76   }
77 
78   DISALLOW_COPY_AND_ASSIGN(CameraPanTiltZoomPermissionContextTests);
79 };
80 
81 class CameraContentSettingTests
82     : public CameraPanTiltZoomPermissionContextTests {
83  public:
84   CameraContentSettingTests() = default;
85 };
86 
TEST_P(CameraContentSettingTests,TestResetPermissionOnCameraChange)87 TEST_P(CameraContentSettingTests, TestResetPermissionOnCameraChange) {
88   CameraPanTiltZoomPermissionContext permission_context(profile());
89   ContentSettingsChangeWaiter waiter(profile(),
90                                      ContentSettingsType::MEDIASTREAM_CAMERA);
91 
92   SetContentSetting(ContentSettingsType::CAMERA_PAN_TILT_ZOOM,
93                     GetParam().first);
94   SetContentSetting(ContentSettingsType::MEDIASTREAM_CAMERA, GetParam().second);
95 
96   waiter.Wait();
97   EXPECT_EQ(GetParam().result,
98             GetContentSetting(ContentSettingsType::CAMERA_PAN_TILT_ZOOM));
99 }
100 
101 INSTANTIATE_TEST_SUITE_P(
102     ResetPermissionOnCameraChange,
103     CameraContentSettingTests,
104     testing::Values(
105         // Granted camera PTZ permission is reset if camera is blocked.
106         TestConfig{CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
107                    CONTENT_SETTING_ASK},
108         // Granted camera PTZ permission is reset if camera is reset.
109         TestConfig{CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK,
110                    CONTENT_SETTING_ASK},
111         // Blocked camera PTZ permission is not reset if camera is granted.
112         TestConfig{CONTENT_SETTING_BLOCK, CONTENT_SETTING_ALLOW,
113                    CONTENT_SETTING_BLOCK},
114         // Blocked camera PTZ permission is not reset if camera is blocked.
115         TestConfig{CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK,
116                    CONTENT_SETTING_BLOCK}));
117 
118 class CameraPanTiltZoomContentSettingTests
119     : public CameraPanTiltZoomPermissionContextTests {
120  public:
121   CameraPanTiltZoomContentSettingTests() = default;
122 };
123 
TEST_P(CameraPanTiltZoomContentSettingTests,TestCameraPermissionOnCameraPanTiltZoomChange)124 TEST_P(CameraPanTiltZoomContentSettingTests,
125        TestCameraPermissionOnCameraPanTiltZoomChange) {
126   CameraPanTiltZoomPermissionContext permission_context(profile());
127   ContentSettingsChangeWaiter waiter(profile(),
128                                      ContentSettingsType::CAMERA_PAN_TILT_ZOOM);
129 
130   SetContentSetting(ContentSettingsType::MEDIASTREAM_CAMERA, GetParam().first);
131   SetContentSetting(ContentSettingsType::CAMERA_PAN_TILT_ZOOM,
132                     GetParam().second);
133 
134   waiter.Wait();
135   EXPECT_EQ(GetParam().result,
136             GetContentSetting(ContentSettingsType::MEDIASTREAM_CAMERA));
137 }
138 
139 INSTANTIATE_TEST_SUITE_P(
140     CameraPermissionOnCameraPanTiltZoomChange,
141     CameraPanTiltZoomContentSettingTests,
142     testing::Values(
143         // Asked camera permission is blocked if camera PTZ is blocked.
144         TestConfig{CONTENT_SETTING_ASK, CONTENT_SETTING_BLOCK,
145                    CONTENT_SETTING_BLOCK},
146         // Asked camera permission is granted if camera PTZ is granted.
147         TestConfig{CONTENT_SETTING_ASK, CONTENT_SETTING_ALLOW,
148                    CONTENT_SETTING_ALLOW},
149         // Asked camera permission is unchanged if camera PTZ is reset.
150         TestConfig{CONTENT_SETTING_ASK, CONTENT_SETTING_DEFAULT,
151                    CONTENT_SETTING_ASK},
152         // Asked camera permission is unchanged if camera PTZ is ask.
153         TestConfig{CONTENT_SETTING_ASK, CONTENT_SETTING_ASK,
154                    CONTENT_SETTING_ASK},
155         // Allowed camera permission is blocked if camera PTZ is blocked.
156         TestConfig{CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK,
157                    CONTENT_SETTING_BLOCK},
158         // Allowed camera permission is unchanged if camera PTZ is granted.
159         TestConfig{CONTENT_SETTING_ALLOW, CONTENT_SETTING_ALLOW,
160                    CONTENT_SETTING_ALLOW},
161         // Allowed camera permission is ask if camera PTZ is reset.
162         TestConfig{CONTENT_SETTING_ALLOW, CONTENT_SETTING_DEFAULT,
163                    CONTENT_SETTING_ASK},
164         // Allowed camera permission is reset if camera PTZ is ask.
165         TestConfig{CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK,
166                    CONTENT_SETTING_ASK},
167         // Blocked camera permission is unchanged if camera PTZ is blocked.
168         TestConfig{CONTENT_SETTING_BLOCK, CONTENT_SETTING_BLOCK,
169                    CONTENT_SETTING_BLOCK},
170         // Blocked camera permission is allowed if camera PTZ is granted.
171         TestConfig{CONTENT_SETTING_BLOCK, CONTENT_SETTING_ALLOW,
172                    CONTENT_SETTING_ALLOW},
173         // Blocked camera permission is ask if camera PTZ is reset.
174         TestConfig{CONTENT_SETTING_BLOCK, CONTENT_SETTING_DEFAULT,
175                    CONTENT_SETTING_ASK},
176         // Blocked camera permission is reset if camera PTZ is ask.
177         TestConfig{CONTENT_SETTING_BLOCK, CONTENT_SETTING_ASK,
178                    CONTENT_SETTING_ASK},
179         // Default camera permission is blocked if camera PTZ is blocked.
180         TestConfig{CONTENT_SETTING_DEFAULT, CONTENT_SETTING_BLOCK,
181                    CONTENT_SETTING_BLOCK},
182         // Default camera permission is allowed if camera PTZ is granted.
183         TestConfig{CONTENT_SETTING_DEFAULT, CONTENT_SETTING_ALLOW,
184                    CONTENT_SETTING_ALLOW},
185         // Default camera permission is unchanged if camera PTZ is reset.
186         TestConfig{CONTENT_SETTING_DEFAULT, CONTENT_SETTING_DEFAULT,
187                    CONTENT_SETTING_ASK},
188         // Default camera permission is ask if camera PTZ is ask.
189         TestConfig{CONTENT_SETTING_DEFAULT, CONTENT_SETTING_ASK,
190                    CONTENT_SETTING_ASK}));
191