Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iOS] Enable History datatype for Sync #20642

Merged
merged 10 commits into from
Oct 24, 2023
9 changes: 1 addition & 8 deletions ios/app/brave_core_main.mm
Original file line number Diff line number Diff line change
Expand Up @@ -356,15 +356,8 @@ - (BraveBookmarksAPI*)bookmarksAPI {

- (BraveHistoryAPI*)historyAPI {
if (!_historyAPI) {
history::HistoryService* history_service_ =
ios::HistoryServiceFactory::GetForBrowserState(
_mainBrowserState, ServiceAccessType::EXPLICIT_ACCESS);
history::WebHistoryService* web_history_service_ =
ios::WebHistoryServiceFactory::GetForBrowserState(_mainBrowserState);

_historyAPI =
[[BraveHistoryAPI alloc] initWithHistoryService:history_service_
webHistoryService:web_history_service_];
[[BraveHistoryAPI alloc] initWithBrowserState:_mainBrowserState];
}
return _historyAPI;
}
Expand Down
7 changes: 7 additions & 0 deletions ios/browser/api/history/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,21 @@ source_set("history") {
"brave_history_api.h",
"brave_history_api.mm",
"brave_history_observer.h",
"history_driver_ios.h",
"history_driver_ios.mm",
"history_service_listener_ios.h",
"history_service_listener_ios.mm",
]

deps = [
"//base",
"//components/browsing_data/core",
"//components/history/core/browser",
"//components/keyed_service/core",
"//ios/chrome/browser/history",
"//ios/chrome/browser/history:history_utils",
"//ios/chrome/browser/shared/model/browser_state",
"//ios/chrome/browser/sync/model",
"//ios/web/public/thread",
"//net",
"//ui/base",
Expand Down
9 changes: 2 additions & 7 deletions ios/browser/api/history/brave_history_api+private.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,10 @@

NS_ASSUME_NONNULL_BEGIN

namespace history {
class HistoryService;
class WebHistoryService;
}
class ChromeBrowserState;

@interface BraveHistoryAPI (Private)
- (instancetype)initWithHistoryService:(history::HistoryService*)historyService
webHistoryService:
(history::WebHistoryService*)webHistoryService;
- (instancetype)initWithBrowserState:(ChromeBrowserState*)mainBrowserState;
@end

NS_ASSUME_NONNULL_END
Expand Down
3 changes: 1 addition & 2 deletions ios/browser/api/history/brave_history_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ OBJC_EXPORT

/// Add History Method which also allows to edit transition type
/// @param history - History Object to be added
/// @param isURLTyped - Bool determine If URL is typed and synced
- (void)addHistory:(IOSHistoryNode*)history isURLTyped:(BOOL)isURLTyped;
- (void)addHistory:(IOSHistoryNode*)history;

/// Remove Specific History
/// @param history - History Object to be removed from history
Expand Down
71 changes: 56 additions & 15 deletions ios/browser/api/history/brave_history_api.mm
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,39 @@

#include "base/functional/bind.h"
#include "base/strings/sys_string_conversions.h"
#include "brave/ios/browser/api/history/brave_history_observer.h"
#include "brave/ios/browser/api/history/history_driver_ios.h"
#include "brave/ios/browser/api/history/history_service_listener_ios.h"
#include "components/history/core/browser/browsing_history_service.h"
#include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/history_types.h"
#include "components/keyed_service/core/service_access_type.h"
#include "ios/chrome/browser/history/history_service_factory.h"
#include "ios/chrome/browser/history/web_history_service_factory.h"
#include "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
#include "ios/chrome/browser/sync/model/sync_service_factory.h"
#include "ios/web/public/thread/web_task_traits.h"
#include "ios/web/public/thread/web_thread.h"
#include "net/base/mac/url_conversions.h"
#include "ui/base/page_transition_types.h"
#include "url/gurl.h"

#include "brave/ios/browser/api/history/brave_history_observer.h"
#include "brave/ios/browser/api/history/history_service_listener_ios.h"

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

namespace {

history::WebHistoryService* WebHistoryServiceGetter(
base::WeakPtr<ChromeBrowserState> weak_browser_state) {
DCHECK(weak_browser_state.get())
<< "Getter should not be called after ChromeBrowserState destruction.";
return ios::WebHistoryServiceFactory::GetForBrowserState(
weak_browser_state.get());
}

} // anonymous namespace

DomainMetricTypeIOS const DomainMetricTypeIOSNoMetric =
static_cast<history::DomainMetricType>(
history::DomainMetricType::kNoMetric);
Expand Down Expand Up @@ -100,20 +116,39 @@ @interface BraveHistoryAPI () {
history::WebHistoryService* web_history_service_;
// Tracker for history requests.
base::CancelableTaskTracker tracker_;

// Provides dependencies and funnels callbacks from BrowsingHistoryService.
std::unique_ptr<HistoryDriverIOS> _browsingHistoryDriver;
// Abstraction to communicate with HistoryService and WebHistoryService.
std::unique_ptr<history::BrowsingHistoryService> _browsingHistoryService;
}
@property(nonatomic, strong) void (^query_completion)(NSArray<IOSHistoryNode*>*)
;
@end

@implementation BraveHistoryAPI
@implementation BraveHistoryAPI {
ChromeBrowserState* _mainBrowserState; // NOT OWNED
}

- (instancetype)initWithHistoryService:(history::HistoryService*)historyService
webHistoryService:
(history::WebHistoryService*)webHistoryService {
- (instancetype)initWithBrowserState:(ChromeBrowserState*)mainBrowserState {
if ((self = [super init])) {
DCHECK_CURRENTLY_ON(web::WebThread::UI);
history_service_ = historyService;
web_history_service_ = webHistoryService;
_mainBrowserState = mainBrowserState;

history_service_ = ios::HistoryServiceFactory::GetForBrowserState(
_mainBrowserState, ServiceAccessType::EXPLICIT_ACCESS);
web_history_service_ =
ios::WebHistoryServiceFactory::GetForBrowserState(_mainBrowserState);

_browsingHistoryDriver =
std::make_unique<HistoryDriverIOS>(base::BindRepeating(
&WebHistoryServiceGetter, _mainBrowserState->AsWeakPtr()));

_browsingHistoryService = std::make_unique<history::BrowsingHistoryService>(
_browsingHistoryDriver.get(),
ios::HistoryServiceFactory::GetForBrowserState(
_mainBrowserState, ServiceAccessType::EXPLICIT_ACCESS),
SyncServiceFactory::GetForBrowserState(_mainBrowserState));
}
return self;
}
Expand All @@ -138,7 +173,7 @@ - (bool)isBackendLoaded {
return history_service_->BackendLoaded();
}

- (void)addHistory:(IOSHistoryNode*)history isURLTyped:(BOOL)isURLTyped {
- (void)addHistory:(IOSHistoryNode*)history {
DCHECK_CURRENTLY_ON(web::WebThread::UI);

// Important! Only Typed URL is being synced in core side
Expand All @@ -149,8 +184,7 @@ - (void)addHistory:(IOSHistoryNode*)history isURLTyped:(BOOL)isURLTyped {
/*nav_entry_id=*/0, /*local_navigation_id=*/absl::nullopt,
/*referrer=*/GURL(),
/*redirect_list*/ history::RedirectList(),
/*transition*/
isURLTyped ? ui::PAGE_TRANSITION_TYPED : ui::PAGE_TRANSITION_LINK,
/*transition*/ ui::PAGE_TRANSITION_TYPED,
/*hidden=*/false, /*visit_source*/ history::VisitSource::SOURCE_BROWSED,
/*did_replace_entry=*/false, /*consider_for_ntp_most_visited=*/true,
/*title*/ base::SysNSStringToUTF16(history.title),
Expand All @@ -163,9 +197,16 @@ - (void)addHistory:(IOSHistoryNode*)history isURLTyped:(BOOL)isURLTyped {
- (void)removeHistory:(IOSHistoryNode*)history {
DCHECK_CURRENTLY_ON(web::WebThread::UI);

// Deletes a specific URL using history service and web history service
history_service_->DeleteLocalAndRemoteUrl(web_history_service_,
net::GURLWithNSURL(history.url));
// Delete items from Browser History and from synced devices
std::vector<history::BrowsingHistoryService::HistoryEntry> entries;
history::BrowsingHistoryService::HistoryEntry entry;
entry.url = net::GURLWithNSURL(history.url);
entry.all_timestamps.insert(base::Time::FromNSDate(history.dateAdded)
.ToDeltaSinceWindowsEpoch()
.InMicroseconds());
entries.push_back(entry);

_browsingHistoryService->RemoveVisits(entries);
}

- (void)removeAllWithCompletion:(void (^)())completion {
Expand Down
55 changes: 55 additions & 0 deletions ios/browser/api/history/history_driver_ios.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* 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_IOS_BROWSER_API_HISTORY_HISTORY_DRIVER_IOS_H_
#define BRAVE_IOS_BROWSER_API_HISTORY_HISTORY_DRIVER_IOS_H_

#include <vector>

#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "components/history/core/browser/browsing_history_driver.h"
#include "components/history/core/browser/browsing_history_service.h"
#include "url/gurl.h"

class HistoryDriverIOS : public history::BrowsingHistoryDriver {
public:
using WebHistoryServiceGetter =
base::RepeatingCallback<history::WebHistoryService*()>;

explicit HistoryDriverIOS(WebHistoryServiceGetter history_service_getter);

HistoryDriverIOS(const HistoryDriverIOS&) = delete;
HistoryDriverIOS& operator=(const HistoryDriverIOS&) = delete;

~HistoryDriverIOS() override;

private:
// history::BrowsingHistoryDriver implementation.
void OnQueryComplete(
const std::vector<history::BrowsingHistoryService::HistoryEntry>& results,
const history::BrowsingHistoryService::QueryResultsInfo&
query_results_info,
base::OnceClosure continuation_closure) override;
void OnRemoveVisitsComplete() override;
void OnRemoveVisitsFailed() override;
void OnRemoveVisits(
const std::vector<history::ExpireHistoryArgs>& expire_list) override;
void HistoryDeleted() override;
void HasOtherFormsOfBrowsingHistory(bool has_other_forms,
bool has_synced_results) override;
bool AllowHistoryDeletions() override;
bool ShouldHideWebHistoryUrl(const GURL& url) override;
history::WebHistoryService* GetWebHistoryService() override;
void ShouldShowNoticeAboutOtherFormsOfBrowsingHistory(
const syncer::SyncService* sync_service,
history::WebHistoryService* history_service,
base::OnceCallback<void(bool)> callback) override;

// The current web history service.
WebHistoryServiceGetter history_service_getter_;
};

#endif // BRAVE_IOS_BROWSER_API_HISTORY_HISTORY_DRIVER_IOS_H_
76 changes: 76 additions & 0 deletions ios/browser/api/history/history_driver_ios.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* 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/ios/browser/api/history/history_driver_ios.h"

#import <utility>

#import "base/check.h"
#import "base/strings/utf_string_conversions.h"
#import "components/browsing_data/core/history_notice_utils.h"
#import "ios/chrome/browser/history/history_utils.h"

using history::BrowsingHistoryService;

#pragma mark - HistoryDriverIOS

HistoryDriverIOS::HistoryDriverIOS(
WebHistoryServiceGetter history_service_getter)
: history_service_getter_(history_service_getter) {
DCHECK(!history_service_getter_.is_null());
}

HistoryDriverIOS::~HistoryDriverIOS() = default;

#pragma mark - Private methods

void HistoryDriverIOS::OnQueryComplete(
const std::vector<BrowsingHistoryService::HistoryEntry>& results,
const BrowsingHistoryService::QueryResultsInfo& query_results_info,
base::OnceClosure continuation_closure) {
// Ignored.
}

void HistoryDriverIOS::OnRemoveVisitsComplete() {
// Ignored.
}

void HistoryDriverIOS::OnRemoveVisitsFailed() {
// Ignored.
}

void HistoryDriverIOS::OnRemoveVisits(
const std::vector<history::ExpireHistoryArgs>& expire_list) {
// Ignored.
}

void HistoryDriverIOS::HistoryDeleted() {
// Ignored.
}

void HistoryDriverIOS::HasOtherFormsOfBrowsingHistory(bool has_other_forms,
bool has_synced_results) {
// Ignored.
}

bool HistoryDriverIOS::AllowHistoryDeletions() {
return true;
}

bool HistoryDriverIOS::ShouldHideWebHistoryUrl(const GURL& url) {
return !ios::CanAddURLToHistory(url);
}

history::WebHistoryService* HistoryDriverIOS::GetWebHistoryService() {
return history_service_getter_.Run();
}

void HistoryDriverIOS::ShouldShowNoticeAboutOtherFormsOfBrowsingHistory(
const syncer::SyncService* sync_service,
history::WebHistoryService* history_service,
base::OnceCallback<void(bool)> callback) {
browsing_data::ShouldShowNoticeAboutOtherFormsOfBrowsingHistory(
sync_service, history_service, std::move(callback));
}