privacy_screen_controller_unittest.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  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. #include "ash/display/privacy_screen_controller.h"
  5. #include "ash/constants/ash_pref_names.h"
  6. #include "ash/dbus/privacy_screen_service_provider.h"
  7. #include "ash/session/session_controller_impl.h"
  8. #include "ash/shell.h"
  9. #include "ash/test/ash_test_base.h"
  10. #include "base/callback_helpers.h"
  11. #include "chromeos/ash/components/dbus/services/service_provider_test_helper.h"
  12. #include "components/prefs/pref_service.h"
  13. #include "dbus/message.h"
  14. #include "dbus/object_path.h"
  15. #include "testing/gmock/include/gmock/gmock.h"
  16. #include "third_party/cros_system_api/dbus/service_constants.h"
  17. #include "ui/display/fake/fake_display_snapshot.h"
  18. #include "ui/display/manager/display_change_observer.h"
  19. #include "ui/display/manager/display_manager.h"
  20. #include "ui/display/manager/test/action_logger_util.h"
  21. #include "ui/display/manager/test/test_native_display_delegate.h"
  22. #include "ui/display/types/display_constants.h"
  23. namespace ash {
  24. namespace {
  25. constexpr char kUser1Email[] = "user1@privacyscreen";
  26. constexpr char kUser2Email[] = "user2@privacyscreen";
  27. constexpr gfx::Size kDisplaySize{1024, 768};
  28. class MockObserver : public PrivacyScreenController::Observer {
  29. public:
  30. MockObserver() {}
  31. ~MockObserver() override = default;
  32. MOCK_METHOD(void,
  33. OnPrivacyScreenSettingChanged,
  34. (bool enabled, bool notify_ui),
  35. (override));
  36. };
  37. class PrivacyScreenControllerTest : public NoSessionAshTestBase {
  38. public:
  39. PrivacyScreenControllerTest()
  40. : logger_(std::make_unique<display::test::ActionLogger>()) {}
  41. ~PrivacyScreenControllerTest() override = default;
  42. PrivacyScreenControllerTest(const PrivacyScreenControllerTest&) = delete;
  43. PrivacyScreenControllerTest& operator=(const PrivacyScreenControllerTest&) =
  44. delete;
  45. PrivacyScreenController* controller() {
  46. return Shell::Get()->privacy_screen_controller();
  47. }
  48. PrefService* user1_pref_service() const {
  49. return Shell::Get()->session_controller()->GetUserPrefServiceForUser(
  50. AccountId::FromUserEmail(kUser1Email));
  51. }
  52. void SetUp() override {
  53. NoSessionAshTestBase::SetUp();
  54. // Create user 1 session and simulate its login.
  55. SimulateUserLogin(kUser1Email);
  56. // Create user 2 session.
  57. GetSessionControllerClient()->AddUserSession(kUser2Email);
  58. native_display_delegate_ =
  59. new display::test::TestNativeDisplayDelegate(logger_.get());
  60. display_manager()->configurator()->SetDelegateForTesting(
  61. std::unique_ptr<display::NativeDisplayDelegate>(
  62. native_display_delegate_));
  63. display_change_observer_ =
  64. std::make_unique<display::DisplayChangeObserver>(display_manager());
  65. test_api_ = std::make_unique<display::DisplayConfigurator::TestApi>(
  66. display_manager()->configurator());
  67. controller()->AddObserver(observer());
  68. }
  69. struct TestSnapshotParams {
  70. int64_t id;
  71. bool is_internal_display;
  72. bool supports_privacy_screen;
  73. };
  74. void TearDown() override {
  75. // DisplayChangeObserver access DeviceDataManager in its destructor, so
  76. // destroy it first.
  77. display_change_observer_ = nullptr;
  78. controller()->RemoveObserver(observer());
  79. AshTestBase::TearDown();
  80. }
  81. void SwitchActiveUser(const std::string& email) {
  82. GetSessionControllerClient()->SwitchActiveUser(
  83. AccountId::FromUserEmail(email));
  84. }
  85. // Builds displays snapshots into |owned_snapshots_| and update the display
  86. // configurator and display manager with it.
  87. void BuildAndUpdateDisplaySnapshots(
  88. const std::vector<TestSnapshotParams>& snapshot_params) {
  89. owned_snapshots_.clear();
  90. std::vector<display::DisplaySnapshot*> outputs;
  91. for (const auto& param : snapshot_params) {
  92. owned_snapshots_.emplace_back(
  93. display::FakeDisplaySnapshot::Builder()
  94. .SetId(param.id)
  95. .SetNativeMode(kDisplaySize)
  96. .SetCurrentMode(kDisplaySize)
  97. .SetType(param.is_internal_display
  98. ? display::DISPLAY_CONNECTION_TYPE_INTERNAL
  99. : display::DISPLAY_CONNECTION_TYPE_HDMI)
  100. .SetPrivacyScreen(param.supports_privacy_screen
  101. ? display::kDisabled
  102. : display::kNotSupported)
  103. .Build());
  104. outputs.push_back(owned_snapshots_.back().get());
  105. }
  106. native_display_delegate_->set_outputs(outputs);
  107. display_manager()->configurator()->OnConfigurationChanged();
  108. display_manager()->configurator()->ForceInitialConfigure();
  109. EXPECT_TRUE(test_api_->TriggerConfigureTimeout());
  110. display_change_observer_->OnDisplayModeChanged(outputs);
  111. }
  112. MockObserver* observer() { return &observer_; }
  113. private:
  114. std::unique_ptr<display::test::ActionLogger> logger_;
  115. display::test::TestNativeDisplayDelegate*
  116. native_display_delegate_; // Not owned.
  117. std::unique_ptr<display::DisplayChangeObserver> display_change_observer_;
  118. std::unique_ptr<display::DisplayConfigurator::TestApi> test_api_;
  119. std::vector<std::unique_ptr<display::DisplaySnapshot>> owned_snapshots_;
  120. ::testing::NiceMock<MockObserver> observer_;
  121. };
  122. class PrivacyScreenServiceProviderTest : public PrivacyScreenControllerTest {
  123. public:
  124. PrivacyScreenServiceProviderTest() = default;
  125. ~PrivacyScreenServiceProviderTest() override = default;
  126. PrivacyScreenServiceProviderTest(const PrivacyScreenServiceProviderTest&) =
  127. delete;
  128. PrivacyScreenServiceProviderTest& operator=(
  129. const PrivacyScreenServiceProviderTest&) = delete;
  130. // PrivacyScreenControllerTest:
  131. void SetUp() override {
  132. PrivacyScreenControllerTest::SetUp();
  133. service_provider_ = std::make_unique<PrivacyScreenServiceProvider>();
  134. test_helper_.SetUp(
  135. privacy_screen::kPrivacyScreenServiceName,
  136. dbus::ObjectPath(privacy_screen::kPrivacyScreenServicePath),
  137. privacy_screen::kPrivacyScreenServiceInterface,
  138. privacy_screen::kPrivacyScreenServiceGetPrivacyScreenSettingMethod,
  139. service_provider_.get());
  140. }
  141. void TearDown() override {
  142. test_helper_.TearDown();
  143. service_provider_.reset();
  144. PrivacyScreenControllerTest::TearDown();
  145. }
  146. privacy_screen::PrivacyScreenSetting_PrivacyScreenState
  147. GetPrivacyScreenSettingStateFromDBus() {
  148. dbus::MethodCall method_call(
  149. privacy_screen::kPrivacyScreenServiceInterface,
  150. privacy_screen::kPrivacyScreenServiceGetPrivacyScreenSettingMethod);
  151. std::unique_ptr<dbus::Response> response =
  152. test_helper_.CallMethod(&method_call);
  153. dbus::MessageReader reader(response.get());
  154. privacy_screen::PrivacyScreenSetting setting;
  155. EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&setting));
  156. EXPECT_FALSE(reader.HasMoreData());
  157. return setting.state();
  158. }
  159. void ConnectToPrivacyScreenSettingChangedDBusSignal() {
  160. test_helper_.SetUpReturnSignal(
  161. privacy_screen::kPrivacyScreenServiceInterface,
  162. privacy_screen::kPrivacyScreenServicePrivacyScreenSettingChangedSignal,
  163. base::BindRepeating(&PrivacyScreenServiceProviderTest::
  164. OnPrivacyScreenSettingChangedDBusSignal,
  165. base::Unretained(this)),
  166. base::DoNothing());
  167. }
  168. void OnPrivacyScreenSettingChangedDBusSignal(dbus::Signal* signal) {
  169. dbus::MessageReader reader(signal);
  170. privacy_screen::PrivacyScreenSetting setting;
  171. EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&setting));
  172. last_signal_state_ = setting.state();
  173. EXPECT_FALSE(reader.HasMoreData());
  174. }
  175. protected:
  176. privacy_screen::PrivacyScreenSetting_PrivacyScreenState last_signal_state_ =
  177. privacy_screen::PrivacyScreenSetting_PrivacyScreenState_NOT_SUPPORTED;
  178. std::unique_ptr<PrivacyScreenServiceProvider> service_provider_;
  179. ServiceProviderTestHelper test_helper_;
  180. };
  181. // Test that user prefs do not get mixed up between user changes on a device
  182. // with a single supporting display.
  183. TEST_F(PrivacyScreenControllerTest, TestEnableAndDisable) {
  184. // Create a single internal display that supports privacy screen.
  185. BuildAndUpdateDisplaySnapshots({{
  186. /*id=*/123u,
  187. /*is_internal_display=*/true,
  188. /*supports_privacy_screen=*/true,
  189. }});
  190. EXPECT_EQ(1u, display_manager()->GetNumDisplays());
  191. ASSERT_TRUE(controller()->IsSupported());
  192. // Enable for user 1, and switch to user 2. User 2 should have it disabled.
  193. EXPECT_CALL(*observer(), OnPrivacyScreenSettingChanged(true, true));
  194. controller()->SetEnabled(true,
  195. PrivacyScreenController::kToggleUISurfaceCount);
  196. EXPECT_TRUE(controller()->GetEnabled());
  197. // Switching accounts should trigger observers but should not notify ui.
  198. ::testing::Mock::VerifyAndClear(observer());
  199. EXPECT_CALL(*observer(), OnPrivacyScreenSettingChanged(false, false));
  200. SwitchActiveUser(kUser2Email);
  201. EXPECT_FALSE(controller()->GetEnabled());
  202. // Switch back to user 1, expect it to be enabled.
  203. ::testing::Mock::VerifyAndClear(observer());
  204. EXPECT_CALL(*observer(), OnPrivacyScreenSettingChanged(true, false));
  205. SwitchActiveUser(kUser1Email);
  206. EXPECT_TRUE(controller()->GetEnabled());
  207. }
  208. // Checks that when the privacy screen is enforced by Data Leak Prevention
  209. // feature, it's turned on regardless of the user pref state.
  210. TEST_F(PrivacyScreenControllerTest, TestDlpEnforced) {
  211. // Create a single internal display that supports privacy screen.
  212. BuildAndUpdateDisplaySnapshots({{
  213. /*id=*/123u,
  214. /*is_internal_display=*/true,
  215. /*supports_privacy_screen=*/true,
  216. }});
  217. EXPECT_EQ(1u, display_manager()->GetNumDisplays());
  218. ASSERT_TRUE(controller()->IsSupported());
  219. EXPECT_FALSE(controller()->GetEnabled());
  220. // Enforce privacy screen and check notification.
  221. EXPECT_CALL(*observer(), OnPrivacyScreenSettingChanged(true, true));
  222. controller()->SetEnforced(true);
  223. EXPECT_TRUE(controller()->GetEnabled());
  224. // Additionally enable it via pref, no change.
  225. ::testing::Mock::VerifyAndClear(observer());
  226. EXPECT_CALL(*observer(), OnPrivacyScreenSettingChanged(true, true));
  227. controller()->SetEnabled(true,
  228. PrivacyScreenController::kToggleUISurfaceCount);
  229. EXPECT_TRUE(controller()->GetEnabled());
  230. // Shouldn't be turned off when pref is disabled, because already enforced.
  231. ::testing::Mock::VerifyAndClear(observer());
  232. EXPECT_CALL(*observer(), OnPrivacyScreenSettingChanged(true, true));
  233. controller()->SetEnabled(false,
  234. PrivacyScreenController::kToggleUISurfaceCount);
  235. EXPECT_TRUE(controller()->GetEnabled());
  236. // Privacy screen enforced again by DLP, no notification should be shown.
  237. ::testing::Mock::VerifyAndClear(observer());
  238. EXPECT_CALL(*observer(),
  239. OnPrivacyScreenSettingChanged(::testing::_, ::testing::_))
  240. .Times(0);
  241. controller()->SetEnforced(true);
  242. EXPECT_TRUE(controller()->GetEnabled());
  243. // Remove enforcement, turned off as pref was not changed.
  244. ::testing::Mock::VerifyAndClear(observer());
  245. EXPECT_CALL(*observer(), OnPrivacyScreenSettingChanged(false, true));
  246. controller()->SetEnforced(false);
  247. EXPECT_FALSE(controller()->GetEnabled());
  248. // Add pref back.
  249. ::testing::Mock::VerifyAndClear(observer());
  250. EXPECT_CALL(*observer(), OnPrivacyScreenSettingChanged(true, true));
  251. controller()->SetEnabled(true,
  252. PrivacyScreenController::kToggleUISurfaceCount);
  253. EXPECT_TRUE(controller()->GetEnabled());
  254. // Privacy screen enforced again by DLP, no notification should be shown as
  255. // privacy screen already turned on by the user.
  256. ::testing::Mock::VerifyAndClear(observer());
  257. EXPECT_CALL(*observer(),
  258. OnPrivacyScreenSettingChanged(::testing::_, ::testing::_))
  259. .Times(0);
  260. controller()->SetEnforced(true);
  261. EXPECT_TRUE(controller()->GetEnabled());
  262. // Remove enforcement, privacy screen should still be on due to pref and no
  263. // notification.
  264. ::testing::Mock::VerifyAndClear(observer());
  265. EXPECT_CALL(*observer(),
  266. OnPrivacyScreenSettingChanged(::testing::_, ::testing::_))
  267. .Times(0);
  268. controller()->SetEnforced(false);
  269. EXPECT_TRUE(controller()->GetEnabled());
  270. // Disable via pref, privacy screen is turned off with a notification.
  271. ::testing::Mock::VerifyAndClear(observer());
  272. EXPECT_CALL(*observer(), OnPrivacyScreenSettingChanged(false, true));
  273. controller()->SetEnabled(false,
  274. PrivacyScreenController::kToggleUISurfaceCount);
  275. EXPECT_FALSE(controller()->GetEnabled());
  276. }
  277. // Tests that updates of the Privacy Screen user prefs from outside the
  278. // PrivacyScreenController (such as Settings UI) are observed and applied.
  279. TEST_F(PrivacyScreenControllerTest, TestOutsidePrefsUpdates) {
  280. BuildAndUpdateDisplaySnapshots({{
  281. /*id=*/123u,
  282. /*is_internal_display=*/true,
  283. /*supports_privacy_screen=*/true,
  284. }});
  285. EXPECT_EQ(1u, display_manager()->GetNumDisplays());
  286. ASSERT_TRUE(controller()->IsSupported());
  287. EXPECT_CALL(*observer(), OnPrivacyScreenSettingChanged(true, true));
  288. EXPECT_FALSE(controller()->GetEnabled());
  289. user1_pref_service()->SetBoolean(prefs::kDisplayPrivacyScreenEnabled, true);
  290. EXPECT_TRUE(controller()->GetEnabled());
  291. ::testing::Mock::VerifyAndClear(observer());
  292. EXPECT_CALL(*observer(), OnPrivacyScreenSettingChanged(false, true));
  293. user1_pref_service()->SetBoolean(prefs::kDisplayPrivacyScreenEnabled, false);
  294. EXPECT_FALSE(controller()->GetEnabled());
  295. }
  296. TEST_F(PrivacyScreenControllerTest, SupportedOnSingleInternalDisplay) {
  297. BuildAndUpdateDisplaySnapshots({{
  298. /*id=*/123u,
  299. /*is_internal_display=*/true,
  300. /*supports_privacy_screen=*/true,
  301. }});
  302. EXPECT_EQ(1u, display_manager()->GetNumDisplays());
  303. ASSERT_TRUE(controller()->IsSupported());
  304. EXPECT_CALL(*observer(), OnPrivacyScreenSettingChanged(true, true));
  305. controller()->SetEnabled(true,
  306. PrivacyScreenController::kToggleUISurfaceCount);
  307. EXPECT_TRUE(controller()->GetEnabled());
  308. }
  309. TEST_F(PrivacyScreenControllerTest, NotSupportedOnSingleInternalDisplay) {
  310. BuildAndUpdateDisplaySnapshots({{
  311. /*id=*/123u,
  312. /*is_internal_display=*/true,
  313. /*supports_privacy_screen=*/false,
  314. }});
  315. EXPECT_EQ(1u, display_manager()->GetNumDisplays());
  316. ASSERT_FALSE(controller()->IsSupported());
  317. EXPECT_FALSE(controller()->GetEnabled());
  318. }
  319. // Test that the privacy screen is not supported when the device is connected
  320. // to an external display and the lid is closed (a.k.a. docked mode).
  321. TEST_F(PrivacyScreenControllerTest, NotSupportedOnInternalDisplayWhenDocked) {
  322. BuildAndUpdateDisplaySnapshots({{
  323. /*id=*/123u,
  324. /*is_internal_display=*/true,
  325. /*supports_privacy_screen=*/true,
  326. },
  327. {
  328. /*id=*/234u,
  329. /*is_internal_display=*/false,
  330. /*supports_privacy_screen=*/false,
  331. }});
  332. EXPECT_EQ(2u, display_manager()->GetNumDisplays());
  333. // Turn off the internal display
  334. display_manager()->configurator()->SetDisplayPower(
  335. chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
  336. display::DisplayConfigurator::kSetDisplayPowerNoFlags, base::DoNothing());
  337. ASSERT_FALSE(controller()->IsSupported());
  338. EXPECT_FALSE(controller()->GetEnabled());
  339. }
  340. TEST_F(PrivacyScreenControllerTest,
  341. SupportedOnInternalDisplayWithMultipleExternalDisplays) {
  342. BuildAndUpdateDisplaySnapshots({{
  343. /*id=*/1234u,
  344. /*is_internal_display=*/true,
  345. /*supports_privacy_screen=*/true,
  346. },
  347. {
  348. /*id=*/2341u,
  349. /*is_internal_display=*/false,
  350. /*supports_privacy_screen=*/false,
  351. },
  352. {
  353. /*id=*/3412u,
  354. /*is_internal_display=*/false,
  355. /*supports_privacy_screen=*/false,
  356. }});
  357. EXPECT_EQ(3u, display_manager()->GetNumDisplays());
  358. ASSERT_TRUE(controller()->IsSupported());
  359. controller()->SetEnabled(true,
  360. PrivacyScreenController::kToggleUISurfaceCount);
  361. EXPECT_TRUE(controller()->GetEnabled());
  362. }
  363. TEST_F(PrivacyScreenControllerTest,
  364. NotSupportedOnInternalDisplayWithMultipleExternalDisplays) {
  365. BuildAndUpdateDisplaySnapshots({{
  366. /*id=*/1234u,
  367. /*is_internal_display=*/true,
  368. /*supports_privacy_screen=*/false,
  369. },
  370. {
  371. /*id=*/2341u,
  372. /*is_internal_display=*/false,
  373. /*supports_privacy_screen=*/false,
  374. },
  375. {
  376. /*id=*/3412u,
  377. /*is_internal_display=*/false,
  378. /*supports_privacy_screen=*/false,
  379. }});
  380. EXPECT_EQ(3u, display_manager()->GetNumDisplays());
  381. ASSERT_FALSE(controller()->IsSupported());
  382. EXPECT_FALSE(controller()->GetEnabled());
  383. }
  384. TEST_F(PrivacyScreenServiceProviderTest, PrivacyScreenNotSupported) {
  385. BuildAndUpdateDisplaySnapshots({{
  386. /*id=*/123u,
  387. /*is_internal_display=*/true,
  388. /*supports_privacy_screen=*/false,
  389. }});
  390. ASSERT_EQ(
  391. GetPrivacyScreenSettingStateFromDBus(),
  392. privacy_screen::PrivacyScreenSetting_PrivacyScreenState_NOT_SUPPORTED);
  393. }
  394. TEST_F(PrivacyScreenServiceProviderTest, PrivacyScreenDisabled) {
  395. BuildAndUpdateDisplaySnapshots({{
  396. /*id=*/123u,
  397. /*is_internal_display=*/true,
  398. /*supports_privacy_screen=*/true,
  399. }});
  400. ASSERT_EQ(GetPrivacyScreenSettingStateFromDBus(),
  401. privacy_screen::PrivacyScreenSetting_PrivacyScreenState_DISABLED);
  402. }
  403. TEST_F(PrivacyScreenServiceProviderTest, PrivacyScreenEnabled) {
  404. ConnectToPrivacyScreenSettingChangedDBusSignal();
  405. BuildAndUpdateDisplaySnapshots({{
  406. /*id=*/123u,
  407. /*is_internal_display=*/true,
  408. /*supports_privacy_screen=*/true,
  409. }});
  410. controller()->SetEnabled(true,
  411. PrivacyScreenController::kToggleUISurfaceCount);
  412. // Expects PrivacyScreenSettingChanged D-Bus signal to be called once.
  413. ASSERT_EQ(last_signal_state_,
  414. privacy_screen::PrivacyScreenSetting_PrivacyScreenState_ENABLED);
  415. ASSERT_EQ(GetPrivacyScreenSettingStateFromDBus(),
  416. privacy_screen::PrivacyScreenSetting_PrivacyScreenState_ENABLED);
  417. }
  418. } // namespace
  419. } // namespace ash