#include "content/browser/background_sync/background_sync_scheduler.h"
#include <map>
#include <vector>
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/browser/background_sync/background_sync_scheduler.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/content_export.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_browser_context.h"
#include "content/test/mock_background_sync_controller.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace content {
namespace {
const char kUrl_1[] = …;
const char kUrl_2[] = …;
class TestBrowserClient : public ContentBrowserClient { … };
}
class BackgroundSyncSchedulerTest : public testing::Test { … };
TEST_F(BackgroundSyncSchedulerTest, ScheduleInvokesCallback) { … }
TEST_F(BackgroundSyncSchedulerTest, ZeroDelayScheduleDoesNotInvokeCallback) { … }
TEST_F(BackgroundSyncSchedulerTest, CancelDoesNotInvokeCallback) { … }
TEST_F(BackgroundSyncSchedulerTest, SchedulingTwiceOverwritesTimer) { … }
TEST_F(BackgroundSyncSchedulerTest, MultipleStoragePartitions) { … }
TEST_F(BackgroundSyncSchedulerTest, ScheduleBothTypesOfSync) { … }
#if BUILDFLAG(IS_ANDROID)
TEST_F(BackgroundSyncSchedulerTest, BrowserWakeupScheduled) {
ScheduleDelayedProcessing(GURL(kUrl_1),
blink::mojom::BackgroundSyncType::ONE_SHOT,
base::Seconds(1), base::DoNothing());
EXPECT_LE(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::ONE_SHOT),
base::Seconds(1));
ScheduleDelayedProcessing(GURL(kUrl_2),
blink::mojom::BackgroundSyncType::ONE_SHOT,
base::Milliseconds(1), base::DoNothing());
EXPECT_LE(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::ONE_SHOT),
base::Milliseconds(1));
}
TEST_F(BackgroundSyncSchedulerTest,
BrowserWakeupScheduleSecondAfterFirstFinishes) {
base::RunLoop run_loop_1;
ScheduleDelayedProcessing(GURL(kUrl_1),
blink::mojom::BackgroundSyncType::ONE_SHOT,
base::Milliseconds(1), run_loop_1.QuitClosure());
EXPECT_LE(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::ONE_SHOT),
base::Milliseconds(1));
run_loop_1.Run();
ScheduleDelayedProcessing(GURL(kUrl_2),
blink::mojom::BackgroundSyncType::ONE_SHOT,
base::Minutes(1), base::DoNothing());
EXPECT_GT(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::ONE_SHOT),
base::Milliseconds(1));
EXPECT_LE(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::ONE_SHOT),
base::Minutes(1));
}
TEST_F(BackgroundSyncSchedulerTest, BrowserWakeupScheduleOneOfEachType) {
ScheduleDelayedProcessing(GURL(kUrl_1),
blink::mojom::BackgroundSyncType::PERIODIC,
base::Seconds(1), base::DoNothing());
base::RunLoop().RunUntilIdle();
EXPECT_LE(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::PERIODIC),
base::Seconds(1));
ScheduleDelayedProcessing(GURL(kUrl_2),
blink::mojom::BackgroundSyncType::ONE_SHOT,
base::Minutes(1), base::DoNothing());
base::RunLoop().RunUntilIdle();
EXPECT_LE(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::ONE_SHOT),
base::Minutes(1));
}
TEST_F(BackgroundSyncSchedulerTest, BrowserWakeupScheduleThenCancel) {
ScheduleDelayedProcessing(GURL(kUrl_1),
blink::mojom::BackgroundSyncType::PERIODIC,
base::Minutes(1), base::DoNothing());
base::RunLoop().RunUntilIdle();
EXPECT_LE(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::PERIODIC),
base::Minutes(1));
CancelDelayedProcessing(GURL(kUrl_1),
blink::mojom::BackgroundSyncType::PERIODIC);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::PERIODIC),
base::TimeDelta::Max());
}
TEST_F(BackgroundSyncSchedulerTest, CancelingOneTypeDoesNotAffectAnother) {
ScheduleDelayedProcessing(GURL(kUrl_1),
blink::mojom::BackgroundSyncType::PERIODIC,
base::Minutes(1), base::DoNothing());
ScheduleDelayedProcessing(GURL(kUrl_2),
blink::mojom::BackgroundSyncType::ONE_SHOT,
base::Seconds(1), base::DoNothing());
CancelDelayedProcessing(GURL(kUrl_1),
blink::mojom::BackgroundSyncType::PERIODIC);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::PERIODIC),
base::TimeDelta::Max());
EXPECT_LE(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::ONE_SHOT),
base::Seconds(1));
}
TEST_F(BackgroundSyncSchedulerTest,
CancelingProcessingForOneStorageParitionUpdatesBrowserWakeup) {
ScheduleDelayedProcessing(GURL(kUrl_1),
blink::mojom::BackgroundSyncType::ONE_SHOT,
base::Minutes(1), base::DoNothing());
ScheduleDelayedProcessing(GURL(kUrl_2),
blink::mojom::BackgroundSyncType::ONE_SHOT,
base::Seconds(1), base::DoNothing());
base::RunLoop().RunUntilIdle();
EXPECT_LE(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::ONE_SHOT),
base::Seconds(1));
auto wakeup_time1 = GetBrowserWakeupTime();
CancelDelayedProcessing(GURL(kUrl_2),
blink::mojom::BackgroundSyncType::ONE_SHOT);
base::RunLoop().RunUntilIdle();
EXPECT_LE(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::ONE_SHOT),
base::Minutes(1));
EXPECT_GT(GetBrowserWakeupDelay(blink::mojom::BackgroundSyncType::ONE_SHOT),
base::Seconds(1));
EXPECT_LT(wakeup_time1, GetBrowserWakeupTime());
}
#endif
}