#ifndef CHROME_BROWSER_UI_VIEWS_HATS_HATS_NEXT_WEB_DIALOG_H_
#define CHROME_BROWSER_UI_VIEWS_HATS_HATS_NEXT_WEB_DIALOG_H_
#include "base/callback_list.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/profiles/profile_observer.h"
#include "chrome/browser/ui/hats/hats_service.h"
#include "content/public/browser/web_contents_observer.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/controls/webview/web_dialog_view.h"
#include "ui/views/window/dialog_delegate.h"
#include "ui/web_dialogs/web_dialog_delegate.h"
class BrowserWindowInterface;
class Profile;
namespace views {
class Widget;
}
class HatsNextWebDialog : public views::BubbleDialogDelegateView,
public content::WebContentsDelegate,
public ProfileObserver {
METADATA_HEADER(HatsNextWebDialog, views::BubbleDialogDelegateView)
public:
HatsNextWebDialog(BrowserWindowInterface* browser,
const std::string& trigger_id,
const std::optional<std::string>& hats_histogram_name,
const std::optional<uint64_t> hats_survey_ukm_id,
base::OnceClosure success_callback,
base::OnceClosure failure_callback,
const SurveyBitsData& product_specific_bits_data,
const SurveyStringData& product_specific_string_data);
~HatsNextWebDialog() override;
HatsNextWebDialog(const HatsNextWebDialog&) = delete;
HatsNextWebDialog& operator=(const HatsNextWebDialog&) = delete;
gfx::Size CalculatePreferredSize(
const views::SizeBounds& available_size) const override;
void OnProfileWillBeDestroyed(Profile* profile) override;
std::optional<std::string> GetHistogramName();
void OnSurveyLoaded();
void OnSurveyCompleted();
void OnSurveyClosed();
void OnSurveyQuestionAnswered(const std::string& state);
static bool ParseSurveyQuestionAnswer(const std::string& input,
int* question,
std::vector<int>* answers);
static uint64_t EncodeUkmQuestionAnswers(
const std::vector<int>& question_answers);
enum class SurveyHistogramEnumeration {
kSurveyLoadedEnumeration = 2,
kSurveyCompletedEnumeration = 3,
kSurveyQuestionAnswerParseError = 8,
kSurveyUnknownState = 9
};
protected:
friend class MockHatsNextWebDialog;
FRIEND_TEST_ALL_PREFIXES(HatsNextWebDialogBrowserTest, SurveyLoaded);
FRIEND_TEST_ALL_PREFIXES(HatsNextWebDialogBrowserTest,
SurveyLoadedWithHistogramName);
FRIEND_TEST_ALL_PREFIXES(HatsNextWebDialogBrowserTest,
SurveyQuestionAnsweredFirstQuestionHistograms);
FRIEND_TEST_ALL_PREFIXES(
HatsNextWebDialogBrowserTest,
SurveyQuestionAnsweredSingleSelectQuestionHistograms);
FRIEND_TEST_ALL_PREFIXES(
HatsNextWebDialogBrowserTest,
SurveyQuestionAnsweredMultipleSelectQuestionHistograms);
FRIEND_TEST_ALL_PREFIXES(HatsNextWebDialogBrowserTest,
SurveyQuestionAnsweredMultipleQuestionsHistograms);
FRIEND_TEST_ALL_PREFIXES(HatsNextWebDialogBrowserTest,
SurveyLoadedWithHistogramName);
FRIEND_TEST_ALL_PREFIXES(HatsNextWebDialogBrowserTest,
SurveyQuestionAnsweredMultipleQuestions);
FRIEND_TEST_ALL_PREFIXES(HatsNextWebDialogBrowserTest, DialogResize);
FRIEND_TEST_ALL_PREFIXES(HatsNextWebDialogBrowserTest, MaximumSize);
FRIEND_TEST_ALL_PREFIXES(HatsNextWebDialogBrowserTest, ZoomLevel);
HatsNextWebDialog(BrowserWindowInterface* browser,
const std::string& trigger_id,
const std::optional<std::string>& hats_histogram_name,
const std::optional<uint64_t> hats_survey_ukm_id,
const GURL& hats_survey_url_,
const base::TimeDelta& timeout,
base::OnceClosure success_callback,
base::OnceClosure failure_callback,
const SurveyBitsData& product_specific_bits_data,
const SurveyStringData& product_specific_string_data);
class HatsWebView;
GURL GetParameterizedHatsURL() const;
void LoadTimedOut();
void OnSurveyStateUpdateReceived(std::string state);
void SetHatsSurveyURLforTesting(GURL url);
virtual void ShowWidget();
virtual void CloseWidget();
bool IsWaitingForSurveyForTesting();
int GetHistogramBucket(int question, int answer);
private:
void BrowserDidClose(BrowserWindowInterface* browser);
base::OneShotTimer loading_timer_;
raw_ptr<Profile> otr_profile_;
const raw_ptr<BrowserWindowInterface> browser_;
base::CallbackListSubscription browser_close_subscription_;
const std::string trigger_id_;
const std::optional<std::string> hats_histogram_name_;
const std::optional<uint64_t> hats_survey_ukm_id_;
bool received_survey_loaded_ = false;
bool load_timed_out_ = false;
static constexpr gfx::Size kMinSize = gfx::Size(10, 10);
static constexpr gfx::Size kMaxSize = gfx::Size(800, 600);
raw_ptr<views::WebView> web_view_ = nullptr;
raw_ptr<views::Widget> widget_ = nullptr;
GURL hats_survey_url_;
base::TimeDelta timeout_;
base::OnceClosure success_callback_;
base::OnceClosure failure_callback_;
SurveyBitsData product_specific_bits_data_;
SurveyStringData product_specific_string_data_;
ukm::builders::Feedback_HappinessTrackingSurvey ukm_hats_builder_;
base::WeakPtrFactory<HatsNextWebDialog> weak_factory_{this};
};
#endif