| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/enterprise/util/android_enterprise_info.h" |
| |
| #include "base/bind.h" |
| #include "base/optional.h" |
| #include "base/test/bind.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| class AndroidEnterpriseInfoTest : public ::testing::Test { |
| protected: |
| AndroidEnterpriseInfoTest() { |
| instance_ = chrome::enterprise_util::AndroidEnterpriseInfo::GetInstance(); |
| // Java side isn't running, so we need to skip the call to it. |
| instance_->set_skip_jni_call_for_testing(true); |
| } |
| |
| chrome::enterprise_util::AndroidEnterpriseInfo* instance_; |
| }; |
| |
| class EnterpriseInfoCallbackHelper { |
| public: |
| base::Optional<bool> is_profile_owned, is_device_owned; |
| int num_times_called = 0; |
| |
| void OnResult(bool profile_owned, bool device_owned) { |
| is_profile_owned = profile_owned; |
| is_device_owned = device_owned; |
| num_times_called++; |
| } |
| }; |
| |
| // Test that a callback can be queued and receives the correct results when |
| // serviced. |
| TEST_F(AndroidEnterpriseInfoTest, CallbackGetsResult) { |
| EnterpriseInfoCallbackHelper helper; |
| |
| // Add a callback to the queue. |
| instance_->GetAndroidEnterpriseInfoState(base::BindOnce( |
| &EnterpriseInfoCallbackHelper::OnResult, base::Unretained(&helper))); |
| |
| bool profile_value = true; |
| bool device_value = false; |
| // Now pretend we got a result. |
| instance_->ServiceCallbacksForTesting(profile_value, device_value); |
| |
| ASSERT_TRUE(helper.is_profile_owned.has_value()); |
| ASSERT_TRUE(helper.is_device_owned.has_value()); |
| EXPECT_EQ(helper.is_profile_owned, profile_value); |
| EXPECT_EQ(helper.is_device_owned, device_value); |
| } |
| |
| // Test that multiple queued callbacks are all serviced. |
| TEST_F(AndroidEnterpriseInfoTest, MultipleCallbacksServiced) { |
| EnterpriseInfoCallbackHelper helper; |
| |
| const int kCOUNT = 6; |
| for (int i = 0; i < kCOUNT; i++) { |
| instance_->GetAndroidEnterpriseInfoState(base::BindOnce( |
| &EnterpriseInfoCallbackHelper::OnResult, base::Unretained(&helper))); |
| } |
| |
| // Nothing should get called until the callbacks are serviced. |
| EXPECT_EQ(helper.num_times_called, 0); |
| // Now pretend we got a result. Value is irrelevant in this test. |
| instance_->ServiceCallbacksForTesting(false, false); |
| |
| EXPECT_EQ(helper.num_times_called, kCOUNT); |
| } |
| |
| // Test that callbacks are still serviced after prior callbacks have already |
| // been serviced. |
| TEST_F(AndroidEnterpriseInfoTest, MultipleCallbacksNonconcurrentServiced) { |
| EnterpriseInfoCallbackHelper prehelper; |
| |
| instance_->GetAndroidEnterpriseInfoState(base::BindOnce( |
| &EnterpriseInfoCallbackHelper::OnResult, base::Unretained(&prehelper))); |
| instance_->GetAndroidEnterpriseInfoState(base::BindOnce( |
| &EnterpriseInfoCallbackHelper::OnResult, base::Unretained(&prehelper))); |
| |
| // Now pretend we got a result. Value is irrelevant in this test. |
| instance_->ServiceCallbacksForTesting(false, false); |
| |
| // After servicing, load more callbacks. |
| EnterpriseInfoCallbackHelper helper; |
| |
| const int kCOUNT = 4; |
| for (int i = 0; i < kCOUNT; i++) { |
| instance_->GetAndroidEnterpriseInfoState(base::BindOnce( |
| &EnterpriseInfoCallbackHelper::OnResult, base::Unretained(&helper))); |
| } |
| |
| EXPECT_EQ(helper.num_times_called, 0); |
| // Now pretend we got a result. Value is irrelevant in this test, but let's |
| // change this one just to highlight that you can't assume it stays the same |
| // between servicings. |
| instance_->ServiceCallbacksForTesting(true, true); |
| |
| EXPECT_EQ(helper.num_times_called, kCOUNT); |
| } |
| |
| // Test that multiple callbacks all receive the same result. |
| TEST_F(AndroidEnterpriseInfoTest, MultipleCallbacksSameResult) { |
| EnterpriseInfoCallbackHelper helper1, helper2; |
| |
| instance_->GetAndroidEnterpriseInfoState(base::BindOnce( |
| &EnterpriseInfoCallbackHelper::OnResult, base::Unretained(&helper1))); |
| instance_->GetAndroidEnterpriseInfoState(base::BindOnce( |
| &EnterpriseInfoCallbackHelper::OnResult, base::Unretained(&helper2))); |
| |
| bool profile_value = false; |
| bool device_value = true; |
| // Now pretend we got a result. |
| instance_->ServiceCallbacksForTesting(profile_value, device_value); |
| |
| // If at least one optional has a value, then the other optional can only be |
| // equivalent if it has the same value. |
| ASSERT_TRUE(helper2.is_profile_owned.has_value()); |
| ASSERT_TRUE(helper2.is_device_owned.has_value()); |
| EXPECT_EQ(helper1.is_profile_owned, helper2.is_profile_owned); |
| EXPECT_EQ(helper1.is_device_owned, helper2.is_device_owned); |
| } |
| |
| // Test that a reentrant callback doesn't cause a loop. |
| TEST_F(AndroidEnterpriseInfoTest, ReentrantCallback) { |
| EnterpriseInfoCallbackHelper helper; |
| |
| // Insert 4 callbacks into the instance, the 2nd callback will attempt to |
| // insert another callback when it's serviced. |
| chrome::enterprise_util::AndroidEnterpriseInfo::EnterpriseInfoCallback |
| reentrant_callback = |
| base::BindLambdaForTesting([&](bool one, bool two) -> void { |
| // Do nothing with the arguments, just enter the function again. |
| instance_->GetAndroidEnterpriseInfoState( |
| base::BindOnce(&EnterpriseInfoCallbackHelper::OnResult, |
| base::Unretained(&helper))); |
| }); |
| |
| instance_->GetAndroidEnterpriseInfoState(base::BindOnce( |
| &EnterpriseInfoCallbackHelper::OnResult, base::Unretained(&helper))); |
| instance_->GetAndroidEnterpriseInfoState(std::move(reentrant_callback)); |
| instance_->GetAndroidEnterpriseInfoState(base::BindOnce( |
| &EnterpriseInfoCallbackHelper::OnResult, base::Unretained(&helper))); |
| instance_->GetAndroidEnterpriseInfoState(base::BindOnce( |
| &EnterpriseInfoCallbackHelper::OnResult, base::Unretained(&helper))); |
| |
| // Nothing should get called until the callbacks are serviced. |
| EXPECT_EQ(helper.num_times_called, 0); |
| // Now pretend we got a result. Value is irrelevant in this test. |
| instance_->ServiceCallbacksForTesting(false, false); |
| |
| // Only the first 3 |helper| calls should have been serviced at this point. |
| // The last one should be waiting in the (new) callback queue. |
| EXPECT_EQ(helper.num_times_called, 3); |
| |
| // Service callbacks again to get the fourth one. |
| // Value is irrelevant, but mix it up anyway. |
| instance_->ServiceCallbacksForTesting(true, false); |
| EXPECT_EQ(helper.num_times_called, 4); |
| } |