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