diff --git a/browser/ui/BUILD.gn b/browser/ui/BUILD.gn index ca2e002131cf..c06889f82483 100644 --- a/browser/ui/BUILD.gn +++ b/browser/ui/BUILD.gn @@ -231,6 +231,10 @@ source_set("ui") { "tabs/shared_pinned_tab_service.h", "tabs/shared_pinned_tab_service_factory.cc", "tabs/shared_pinned_tab_service_factory.h", + "tabs/gmail_fetcher.cc", + "tabs/gmail_fetcher.h", + "tabs/gmail_fetcher_factory.cc", + "tabs/gmail_fetcher_factory.h", "tabs/split_view_browser_data.cc", "tabs/split_view_browser_data.h", "tabs/split_view_browser_data_observer.h", diff --git a/browser/ui/tabs/gmail_fetcher.cc b/browser/ui/tabs/gmail_fetcher.cc new file mode 100644 index 000000000000..0b792b63dbf0 --- /dev/null +++ b/browser/ui/tabs/gmail_fetcher.cc @@ -0,0 +1,78 @@ +#include "gmail_fetcher.h" + +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/navigation_handle.h" +#include "content/browser/web_contents/web_contents_impl.h" + +// Constructor +GmailFetcher::GmailFetcher(base::raw_ptr profile) : profile_(profile) { + LOG(INFO) << "GmailFetcher created with profile: " << profile; +} + +// Destructor +GmailFetcher::~GmailFetcher() { + // DestroyGmailContents(); + LOG(INFO) << "GmailFetcher destroyed"; + LOG(INFO) << gmail_contents_.get(); +} + +// Fetch Gmail +void GmailFetcher::FetchGmail() { + LOG(INFO) << "webcontents Profile: " << profile_; + content::WebContents::CreateParams create_params(profile_); + create_params.initially_hidden = true; // WebContents is hidden + create_params.desired_renderer_state = content::WebContents::CreateParams::kNoRendererProcess; + + gmail_contents_ = content::WebContents::Create(create_params); + LOG(INFO) << "Dummy WebContents created: " << gmail_contents_.get(); + + // Start observing WebContents for navigation events + Observe(gmail_contents_.get()); + + gmail_contents_->GetController().LoadURL(GURL("https://mail.google.com/mail/u/0/"), content::Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); + LOG(INFO) << "Loading Gmail URL: " << gmail_contents_->GetURL().spec(); +} + +void GmailFetcher::SetNavigationSuccessCallback(NavigationSuccessCallback callback) { + success_callback_ = std::move(callback); +} + + +// Handle navigation completion +void GmailFetcher::DidFinishNavigation(content::NavigationHandle* navigation_handle) { + + if (!gmail_contents_) { + LOG(INFO) << "Navigation handle received but WebContents is already destroyed."; + return; + } + LOG(INFO) << "Navigation completed for URL: " << navigation_handle->GetURL().spec(); + LOG(INFO) << "Net error code: " << navigation_handle->GetNetErrorCode(); + LOG(INFO) << "Is error page: " << navigation_handle->IsErrorPage(); + LOG(INFO) << "Has committed: " << navigation_handle->HasCommitted(); + LOG(INFO) << "Is same document: " << navigation_handle->IsSameDocument(); + LOG(INFO) << "Is renderer initiated: " << navigation_handle->IsRendererInitiated(); + LOG(INFO) << "Is main frame: " << navigation_handle->IsInMainFrame(); + + if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) { + LOG(INFO) << "Navigation finished. Committed URL: " << navigation_handle->GetURL().spec(); + + // Invoke the success callback if it's set + if (success_callback_) { + success_callback_(navigation_handle->GetURL()); + } + } else { + LOG(INFO) << "Navigation did not commit successfully."; + } +} + + +// Destroy Gmail WebContents +void GmailFetcher::DestroyGmailContents() { + if (gmail_contents_) { + LOG(INFO) << "Destroying WebContents: " << gmail_contents_.get(); + Observe(nullptr); // Stop observing + gmail_contents_->Close(); + gmail_contents_.reset(); + LOG(INFO) << "WebContents destroyed"; + } +} diff --git a/browser/ui/tabs/gmail_fetcher.h b/browser/ui/tabs/gmail_fetcher.h new file mode 100644 index 000000000000..7413373449c8 --- /dev/null +++ b/browser/ui/tabs/gmail_fetcher.h @@ -0,0 +1,41 @@ +#ifndef BRAVE_BROWSER_UI_TABS_GMAIL_FETCHER_H_ +#define BRAVE_BROWSER_UI_TABS_GMAIL_FETCHER_H_ + +#include "base/memory/weak_ptr.h" +#include "base/memory/raw_ptr.h" +#include "chrome/browser/profiles/profile.h" +#include "components/keyed_service/core/keyed_service.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" + +class GmailFetcher : public KeyedService, public content::WebContentsObserver { +public: + using NavigationSuccessCallback = std::function; + + explicit GmailFetcher(base::raw_ptr profile); + ~GmailFetcher() override; + + // Initiates fetching Gmail + void FetchGmail(); + + // Sets the success callback + void SetNavigationSuccessCallback(NavigationSuccessCallback callback); + + // Destroys the WebContents instance + void DestroyGmailContents(); + + // content::WebContentsObserver overrides + void DidFinishNavigation(content::NavigationHandle* navigation_handle) override; + + base::WeakPtr GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } +private: + base::raw_ptr profile_; // Profile associated with this fetcher + std::unique_ptr gmail_contents_; // Stores the WebContents instance + NavigationSuccessCallback success_callback_; // Success callback for navigation + + base::WeakPtrFactory weak_ptr_factory_{this}; // For creating weak pointers +}; + +#endif // BRAVE_BROWSER_UI_TABS_GMAIL_FETCHER_H_ diff --git a/browser/ui/tabs/gmail_fetcher_factory.cc b/browser/ui/tabs/gmail_fetcher_factory.cc new file mode 100644 index 000000000000..e44094228eab --- /dev/null +++ b/browser/ui/tabs/gmail_fetcher_factory.cc @@ -0,0 +1,44 @@ +/* Copyright (c) 2023 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/browser/ui/tabs/gmail_fetcher_factory.h" + +#include + +#include "base/no_destructor.h" +#include "brave/browser/ui/tabs/gmail_fetcher.h" +#include "chrome/browser/profiles/profile.h" + +// static +GmailFetcher* GmailFetcherFactory::GetForProfile(Profile* profile) { + return static_cast( + GetInstance()->GetServiceForBrowserContext(profile, true)); +} + +GmailFetcherFactory* GmailFetcherFactory::GetInstance() { + static base::NoDestructor instance; + return instance.get(); +} + +GmailFetcherFactory::GmailFetcherFactory() + : ProfileKeyedServiceFactory( + "GmailFetcher", + ProfileSelections::Builder() + .WithRegular(ProfileSelection::kOwnInstance) + .WithGuest(ProfileSelection::kOwnInstance) + .Build()) {} + +GmailFetcherFactory::~GmailFetcherFactory() {} + +std::unique_ptr +GmailFetcherFactory::BuildServiceInstanceForBrowserContext( + content::BrowserContext* context) const { + return std::make_unique( + Profile::FromBrowserContext(context)); +} + +bool GmailFetcherFactory::ServiceIsCreatedWithBrowserContext() const { + return true; +} \ No newline at end of file diff --git a/browser/ui/tabs/gmail_fetcher_factory.h b/browser/ui/tabs/gmail_fetcher_factory.h new file mode 100644 index 000000000000..060e05977423 --- /dev/null +++ b/browser/ui/tabs/gmail_fetcher_factory.h @@ -0,0 +1,38 @@ +/* Copyright (c) 2023 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_BROWSER_UI_TABS_GMAIL_FETCHER_FACTORY_H_ +#define BRAVE_BROWSER_UI_TABS_GMAIL_FETCHER_FACTORY_H_ + +#include + +#include "chrome/browser/profiles/profile_keyed_service_factory.h" + +namespace base { +template +class NoDestructor; +} // namespace base + +class GmailFetcher; + +class GmailFetcherFactory : public ProfileKeyedServiceFactory { + public: + static GmailFetcher* GetForProfile(Profile* profile); + + static GmailFetcherFactory* GetInstance(); + + private: + friend base::NoDestructor; + + GmailFetcherFactory(); + ~GmailFetcherFactory() override; + + // BrowserContextKeyedServiceFactory: + std::unique_ptr BuildServiceInstanceForBrowserContext( + content::BrowserContext* context) const override; + bool ServiceIsCreatedWithBrowserContext() const override; +}; + +#endif // BRAVE_BROWSER_UI_TABS_GMAIL_FETCHER_FACTORY_H_ \ No newline at end of file diff --git a/browser/ui/views/toolbar/brave_toolbar_view.cc b/browser/ui/views/toolbar/brave_toolbar_view.cc index d82212f0b98a..852da40ca0f6 100644 --- a/browser/ui/views/toolbar/brave_toolbar_view.cc +++ b/browser/ui/views/toolbar/brave_toolbar_view.cc @@ -41,6 +41,10 @@ #include "ui/base/window_open_disposition_utils.h" #include "ui/events/event.h" #include "ui/views/window/hit_test_utils.h" +#include "base/values.h" +#include "components/prefs/pref_service.h" +#include +#include "brave/browser/ui/tabs/gmail_fetcher.h" #if BUILDFLAG(ENABLE_AI_CHAT) #include "brave/browser/ai_chat/ai_chat_utils.h" @@ -244,6 +248,17 @@ void BraveToolbarView::Init() { UpdateWalletButtonVisibility(); + custom_button_ = container_view->AddChildViewAt( + std::make_unique( + base::BindRepeating(&BraveToolbarView::FetchGmailOnClick, base::Unretained(this)), + u"Custom Button"), + *container_view->GetIndexOf(GetAppMenuButton()) - 1); + + custom_button_->SetTriggerableEventFlags(ui::EF_LEFT_MOUSE_BUTTON); + custom_button_->SetAccessibleName(u"Open Popup"); + custom_button_->SetVisible(true); + + #if BUILDFLAG(ENABLE_AI_CHAT) // Don't check policy status since we're going to // setup a watcher for policy pref. @@ -521,5 +536,25 @@ void BraveToolbarView::UpdateWalletButtonVisibility() { wallet_->SetVisible(false); } +void BraveToolbarView::FetchGmailOnClick() { + + Profile* profile = browser()->profile(); + + // Create an instance of GmailFetcher directly as a raw pointer + auto* gmail_fetcher = new GmailFetcher(base::raw_ptr(profile)); + + LOG(INFO) << "Created GmailFetcher with profile: " << profile; + + // Set navigation success callback + gmail_fetcher->SetNavigationSuccessCallback([gmail_fetcher](const GURL& url) { + LOG(INFO) << "GmailFetcher navigation succeeded for URL: " << url.spec(); + gmail_fetcher->DestroyGmailContents(); + delete gmail_fetcher; + }); + + // Trigger navigation + gmail_fetcher->FetchGmail(); +} + BEGIN_METADATA(BraveToolbarView) END_METADATA diff --git a/browser/ui/views/toolbar/brave_toolbar_view.h b/browser/ui/views/toolbar/brave_toolbar_view.h index 497f0fcede65..434b11d56efb 100644 --- a/browser/ui/views/toolbar/brave_toolbar_view.h +++ b/browser/ui/views/toolbar/brave_toolbar_view.h @@ -14,6 +14,10 @@ #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "components/prefs/pref_member.h" #include "ui/base/metadata/metadata_header_macros.h" +#include +#include "ui/views/controls/textfield/textfield_controller.h" +#include "ui/views/controls/textfield/textfield.h" +#include "components/prefs/pref_service.h" #if BUILDFLAG(ENABLE_AI_CHAT) class AIChatButton; @@ -68,6 +72,12 @@ class BraveToolbarView : public ToolbarView, void ResetLocationBarBounds(); void ResetButtonBounds(); void UpdateBookmarkVisibility(); + std::u16string note_input_; + std::vector notes_; + raw_ptr text_field_ = nullptr; + raw_ptr pref_service_ = nullptr; + raw_ptr custom_button_ = nullptr; + void FetchGmailOnClick(); // ToolbarButtonProvider: views::View* GetAnchorView(std::optional type) override;