Home | History | Annotate | Download | only in signin
      1 // Copyright 2014 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 "base/command_line.h"
      6 #include "base/macros.h"
      7 #include "base/run_loop.h"
      8 #include "base/values.h"
      9 #include "chrome/browser/chromeos/login/login_manager_test.h"
     10 #include "chrome/browser/chromeos/login/startup_utils.h"
     11 #include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
     12 #include "chrome/browser/chromeos/profiles/profile_helper.h"
     13 #include "chrome/browser/extensions/extension_service.h"
     14 #include "chrome/browser/profiles/profile.h"
     15 #include "chrome/browser/signin/easy_unlock_service.h"
     16 #include "chrome/browser/ui/browser.h"
     17 #include "chrome/common/extensions/extension_constants.h"
     18 #include "chrome/test/base/in_process_browser_test.h"
     19 #include "chromeos/dbus/dbus_thread_manager.h"
     20 #include "chromeos/dbus/fake_power_manager_client.h"
     21 #include "components/policy/core/browser/browser_policy_connector.h"
     22 #include "components/policy/core/common/mock_configuration_policy_provider.h"
     23 #include "components/policy/core/common/policy_map.h"
     24 #include "components/policy/core/common/policy_types.h"
     25 #include "components/user_manager/user_manager.h"
     26 #include "content/public/common/content_switches.h"
     27 #include "device/bluetooth/bluetooth_adapter_factory.h"
     28 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
     29 #include "extensions/browser/extension_system.h"
     30 #include "policy/policy_constants.h"
     31 #include "testing/gmock/include/gmock/gmock.h"
     32 
     33 using chromeos::DBusThreadManagerSetter;
     34 using chromeos::FakePowerManagerClient;
     35 using chromeos::PowerManagerClient;
     36 using chromeos::ProfileHelper;
     37 using chromeos::LoginManagerTest;
     38 using chromeos::StartupUtils;
     39 using chromeos::UserAddingScreen;
     40 using user_manager::UserManager;
     41 using device::MockBluetoothAdapter;
     42 using testing::_;
     43 using testing::Return;
     44 
     45 namespace {
     46 
     47 const char kTestUser1[] = "primary.user (at) example.com";
     48 const char kTestUser2[] = "secondary.user (at) example.com";
     49 
     50 #if defined(GOOGLE_CHROME_BUILD)
     51 bool HasEasyUnlockAppForProfile(Profile* profile) {
     52   extensions::ExtensionSystem* extension_system =
     53       extensions::ExtensionSystem::Get(profile);
     54   ExtensionService* extension_service = extension_system->extension_service();
     55   return !!extension_service->GetExtensionById(
     56       extension_misc::kEasyUnlockAppId, false);
     57 }
     58 #endif
     59 
     60 void SetUpBluetoothMock(
     61     scoped_refptr<testing::NiceMock<MockBluetoothAdapter> > mock_adapter,
     62     bool is_present) {
     63   device::BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter);
     64 
     65   EXPECT_CALL(*mock_adapter, IsPresent())
     66       .WillRepeatedly(testing::Return(is_present));
     67 
     68   // These functions are called from ash system tray. They are speculations of
     69   // why flaky gmock errors are seen on bots.
     70   EXPECT_CALL(*mock_adapter, IsPowered())
     71       .WillRepeatedly(testing::Return(true));
     72   EXPECT_CALL(*mock_adapter, GetDevices()).WillRepeatedly(
     73       testing::Return(device::BluetoothAdapter::ConstDeviceList()));
     74 }
     75 
     76 }  // namespace
     77 
     78 class EasyUnlockServiceTest : public InProcessBrowserTest {
     79  public:
     80   EasyUnlockServiceTest() : is_bluetooth_adapter_present_(true) {}
     81   virtual ~EasyUnlockServiceTest() {}
     82 
     83   void SetEasyUnlockAllowedPolicy(bool allowed) {
     84     policy::PolicyMap policy;
     85     policy.Set(policy::key::kEasyUnlockAllowed,
     86                policy::POLICY_LEVEL_MANDATORY,
     87                policy::POLICY_SCOPE_USER,
     88                new base::FundamentalValue(allowed),
     89                NULL);
     90     provider_.UpdateChromePolicy(policy);
     91     base::RunLoop().RunUntilIdle();
     92   }
     93 
     94 #if defined(GOOGLE_CHROME_BUILD)
     95   bool HasEasyUnlockApp() const {
     96     return HasEasyUnlockAppForProfile(profile());
     97   }
     98 #endif
     99 
    100   // InProcessBrowserTest:
    101   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    102     EXPECT_CALL(provider_, IsInitializationComplete(_))
    103         .WillRepeatedly(Return(true));
    104     policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
    105 
    106     mock_adapter_ = new testing::NiceMock<MockBluetoothAdapter>();
    107     SetUpBluetoothMock(mock_adapter_, is_bluetooth_adapter_present_);
    108 
    109     scoped_ptr<DBusThreadManagerSetter> dbus_setter =
    110         chromeos::DBusThreadManager::GetSetterForTesting();
    111     power_manager_client_ = new FakePowerManagerClient;
    112     dbus_setter->SetPowerManagerClient(
    113         scoped_ptr<PowerManagerClient>(power_manager_client_));
    114   }
    115 
    116   Profile* profile() const { return browser()->profile(); }
    117 
    118   EasyUnlockService* service() const {
    119     return EasyUnlockService::Get(profile());
    120   }
    121 
    122   void set_is_bluetooth_adapter_present(bool is_present) {
    123     is_bluetooth_adapter_present_ = is_present;
    124   }
    125 
    126   FakePowerManagerClient* power_manager_client() {
    127     return power_manager_client_;
    128   }
    129 
    130  private:
    131   policy::MockConfigurationPolicyProvider provider_;
    132   scoped_refptr<testing::NiceMock<MockBluetoothAdapter> > mock_adapter_;
    133   bool is_bluetooth_adapter_present_;
    134   FakePowerManagerClient* power_manager_client_;
    135 
    136   DISALLOW_COPY_AND_ASSIGN(EasyUnlockServiceTest);
    137 };
    138 
    139 IN_PROC_BROWSER_TEST_F(EasyUnlockServiceTest, NoFinchNoService) {
    140   EXPECT_FALSE(service()->IsAllowed());
    141 #if defined(GOOGLE_CHROME_BUILD)
    142   EXPECT_FALSE(HasEasyUnlockApp());
    143 #endif
    144 }
    145 
    146 class EasyUnlockServiceNoBluetoothTest : public EasyUnlockServiceTest {
    147  public:
    148   EasyUnlockServiceNoBluetoothTest() {}
    149   virtual ~EasyUnlockServiceNoBluetoothTest() {}
    150 
    151   // InProcessBrowserTest:
    152   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    153     set_is_bluetooth_adapter_present(false);
    154     EasyUnlockServiceTest::SetUpInProcessBrowserTestFixture();
    155   }
    156 
    157  private:
    158   DISALLOW_COPY_AND_ASSIGN(EasyUnlockServiceNoBluetoothTest);
    159 };
    160 
    161 IN_PROC_BROWSER_TEST_F(EasyUnlockServiceNoBluetoothTest, NoService) {
    162   EXPECT_FALSE(service()->IsAllowed());
    163 #if defined(GOOGLE_CHROME_BUILD)
    164   EXPECT_FALSE(HasEasyUnlockApp());
    165 #endif
    166 }
    167 
    168 class EasyUnlockServiceFinchEnabledTest : public EasyUnlockServiceTest {
    169  public:
    170   EasyUnlockServiceFinchEnabledTest() {}
    171   virtual ~EasyUnlockServiceFinchEnabledTest() {}
    172 
    173   // InProcessBrowserTest:
    174   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    175     command_line->AppendSwitchASCII(switches::kForceFieldTrials,
    176                                     "EasyUnlock/Enable/");
    177   }
    178 
    179  private:
    180   DISALLOW_COPY_AND_ASSIGN(EasyUnlockServiceFinchEnabledTest);
    181 };
    182 
    183 IN_PROC_BROWSER_TEST_F(EasyUnlockServiceFinchEnabledTest, Enabled) {
    184   EXPECT_TRUE(service()->IsAllowed());
    185 #if defined(GOOGLE_CHROME_BUILD)
    186   EXPECT_TRUE(HasEasyUnlockApp());
    187 #endif
    188 }
    189 
    190 #if defined(GOOGLE_CHROME_BUILD)
    191 IN_PROC_BROWSER_TEST_F(EasyUnlockServiceFinchEnabledTest, UnloadsOnSuspend) {
    192   EXPECT_TRUE(HasEasyUnlockApp());
    193   power_manager_client()->SendSuspendImminent();
    194   EXPECT_FALSE(HasEasyUnlockApp());
    195   power_manager_client()->SendSuspendDone();
    196   EXPECT_TRUE(HasEasyUnlockApp());
    197 }
    198 #endif
    199 
    200 // Tests that policy can override finch to turn easy unlock off.
    201 IN_PROC_BROWSER_TEST_F(EasyUnlockServiceFinchEnabledTest, PolicyOveride) {
    202   EXPECT_TRUE(service()->IsAllowed());
    203 #if defined(GOOGLE_CHROME_BUILD)
    204   EXPECT_TRUE(HasEasyUnlockApp());
    205 #endif
    206 
    207   // Overridden by policy.
    208   SetEasyUnlockAllowedPolicy(false);
    209   EXPECT_FALSE(service()->IsAllowed());
    210 #if defined(GOOGLE_CHROME_BUILD)
    211   EXPECT_FALSE(HasEasyUnlockApp());
    212 #endif
    213 
    214   SetEasyUnlockAllowedPolicy(true);
    215   EXPECT_TRUE(service()->IsAllowed());
    216 #if defined(GOOGLE_CHROME_BUILD)
    217   EXPECT_TRUE(HasEasyUnlockApp());
    218 #endif
    219 }
    220 
    221 class EasyUnlockServiceFinchDisabledTest : public EasyUnlockServiceTest {
    222  public:
    223   EasyUnlockServiceFinchDisabledTest() {}
    224   virtual ~EasyUnlockServiceFinchDisabledTest() {}
    225 
    226   // InProcessBrowserTest:
    227   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    228     command_line->AppendSwitchASCII(switches::kForceFieldTrials,
    229                                     "EasyUnlock/Disable/");
    230   }
    231 
    232  private:
    233   DISALLOW_COPY_AND_ASSIGN(EasyUnlockServiceFinchDisabledTest);
    234 };
    235 
    236 // Tests that easy unlock is off when finch is disabled and policy overrides
    237 // finch.
    238 IN_PROC_BROWSER_TEST_F(EasyUnlockServiceFinchDisabledTest, PolicyOverride) {
    239   // Finch is disabled.
    240   EXPECT_FALSE(service()->IsAllowed());
    241 #if defined(GOOGLE_CHROME_BUILD)
    242   EXPECT_FALSE(HasEasyUnlockApp());
    243 #endif
    244 
    245   // Policy overrides finch and turns on Easy unlock.
    246   SetEasyUnlockAllowedPolicy(true);
    247   EXPECT_TRUE(service()->IsAllowed());
    248 #if defined(GOOGLE_CHROME_BUILD)
    249   EXPECT_TRUE(HasEasyUnlockApp());
    250 #endif
    251 }
    252 
    253 class EasyUnlockServiceMultiProfileTest : public LoginManagerTest {
    254  public:
    255   EasyUnlockServiceMultiProfileTest() : LoginManagerTest(false) {}
    256   virtual ~EasyUnlockServiceMultiProfileTest() {}
    257 
    258   // InProcessBrowserTest:
    259   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    260     LoginManagerTest::SetUpInProcessBrowserTestFixture();
    261 
    262     mock_adapter_ = new testing::NiceMock<MockBluetoothAdapter>();
    263     SetUpBluetoothMock(mock_adapter_, true);
    264   }
    265 
    266  private:
    267   scoped_refptr<testing::NiceMock<MockBluetoothAdapter> > mock_adapter_;
    268   DISALLOW_COPY_AND_ASSIGN(EasyUnlockServiceMultiProfileTest);
    269 };
    270 
    271 IN_PROC_BROWSER_TEST_F(EasyUnlockServiceMultiProfileTest,
    272                        PRE_DisallowedOnSecondaryProfile) {
    273   RegisterUser(kTestUser1);
    274   RegisterUser(kTestUser2);
    275   StartupUtils::MarkOobeCompleted();
    276 }
    277 
    278 IN_PROC_BROWSER_TEST_F(EasyUnlockServiceMultiProfileTest,
    279                        DisallowedOnSecondaryProfile) {
    280   LoginUser(kTestUser1);
    281   chromeos::UserAddingScreen::Get()->Start();
    282   base::RunLoop().RunUntilIdle();
    283   AddUser(kTestUser2);
    284   const user_manager::User* primary_user =
    285       user_manager::UserManager::Get()->FindUser(kTestUser1);
    286   const user_manager::User* secondary_user =
    287       user_manager::UserManager::Get()->FindUser(kTestUser2);
    288 
    289   Profile* primary_profile = ProfileHelper::Get()->GetProfileByUserIdHash(
    290       primary_user->username_hash());
    291   Profile* secondary_profile = ProfileHelper::Get()->GetProfileByUserIdHash(
    292       secondary_user->username_hash());
    293 
    294   EXPECT_TRUE(EasyUnlockService::Get(primary_profile)->IsAllowed());
    295   EXPECT_FALSE(EasyUnlockService::Get(secondary_profile)->IsAllowed());
    296 #if defined(GOOGLE_CHROME_BUILD)
    297   EXPECT_TRUE(HasEasyUnlockAppForProfile(primary_profile));
    298   EXPECT_FALSE(HasEasyUnlockAppForProfile(secondary_profile));
    299 #endif
    300 }
    301