blob: dce10751e1402013949c89100a654c4b7419a44e [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_SYSTEM_WEB_APPS_SYSTEM_WEB_APP_BACKGROUND_TASK_H_
#define CHROME_BROWSER_ASH_SYSTEM_WEB_APPS_SYSTEM_WEB_APP_BACKGROUND_TASK_H_
#include <memory.h>
#include <optional>
#include <utility>
#include "ash/webui/system_apps/public/system_web_app_type.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/one_shot_event.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/ash/system_web_apps/types/system_web_app_background_task_info.h"
#include "chrome/browser/profiles/profile.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/webapps/browser/web_contents/web_app_url_loader.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
class Profile;
namespace ash {
// Used to manage a running periodic background task for a SWA.
class SystemWebAppBackgroundTask {
public:
enum TimerState {
INITIAL_WAIT = 0,
WAIT_PERIOD = 1,
WAIT_IDLE = 2,
INACTIVE = 3
};
// Wait for 2 minutes before starting background tasks. User login is busy,
// and this will give a little time to settle down. We could get even more
// sophisticated, and smear all the different start_immediately tasks across a
// couple minutes instead of setting their start timers to the same time.
static const int kInitialWaitForBackgroundTasksSeconds = 120;
// User idle for 1 minute.
static const int kIdleThresholdSeconds = 60;
// Else, poll every 30 seconds
static const int kIdlePollIntervalSeconds = 30;
// For up to an hour.
static const int kIdlePollMaxTimeToWaitSeconds = 3600;
SystemWebAppBackgroundTask(Profile* profile,
const SystemWebAppBackgroundTaskInfo& info);
~SystemWebAppBackgroundTask();
// Start the timer, at the specified period. This will also run immediately if
// needed
void StartTask();
// Bring down the background task if open, and stop the timer.
void StopTask();
bool open_immediately_for_testing() const { return open_immediately_; }
SystemWebAppType app_type_for_testing() const { return app_type_; }
GURL url_for_testing() const { return url_; }
content::WebContents* web_contents_for_testing() const {
return web_contents_.get();
}
std::optional<base::TimeDelta> period_for_testing() const { return period_; }
unsigned long opened_count_for_testing() const { return opened_count_; }
unsigned long timer_activated_count_for_testing() const {
return timer_activated_count_;
}
base::Time polling_since_time_for_testing() const {
return polling_since_time_;
}
webapps::WebAppUrlLoader* UrlLoaderForTesting() {
return web_app_url_loader_.get();
}
// Set the url loader for testing. Takes ownership of the argument.
void SetUrlLoaderForTesting(
std::unique_ptr<webapps::WebAppUrlLoader> loader) {
web_app_url_loader_ = std::move(loader);
}
TimerState get_state_for_testing() const { return state_; }
base::OneShotTimer* get_timer_for_testing() { return timer_.get(); }
private:
// A delegate to reset the WebContents owned by this background task and free
// up the resources. Called when the page calls window.close() to exit.
class CloseDelegate : public content::WebContentsDelegate {
public:
explicit CloseDelegate(SystemWebAppBackgroundTask* task) : task_(task) {}
void CloseContents(content::WebContents* contents) override;
private:
raw_ptr<SystemWebAppBackgroundTask> task_;
};
// A state machine to either poll and fail, stop polling and succeed, or stop
// polling and fail
void MaybeOpenPage();
void NavigateBackgroundPage();
void OnPageReady(webapps::WebAppUrlLoaderResult);
void CloseWebContents(content::WebContents* contents);
raw_ptr<Profile> profile_;
SystemWebAppType app_type_;
std::unique_ptr<content::WebContents> web_contents_;
std::unique_ptr<webapps::WebAppUrlLoader> web_app_url_loader_;
std::unique_ptr<base::OneShotTimer> timer_;
TimerState state_;
GURL url_;
std::optional<base::TimeDelta> period_;
unsigned long opened_count_ = 0U;
unsigned long timer_activated_count_ = 0U;
bool open_immediately_ = false;
base::Time polling_since_time_;
CloseDelegate delegate_;
base::WeakPtrFactory<SystemWebAppBackgroundTask> weak_ptr_factory_{this};
};
} // namespace ash
#endif // CHROME_BROWSER_ASH_SYSTEM_WEB_APPS_SYSTEM_WEB_APP_BACKGROUND_TASK_H_