Skip to content

Commit

Permalink
Notes: mojom API implementation part 1
Browse files Browse the repository at this point in the history
This CL implements part of the notes mojom API using the new power bookmark backend.

Bug: 1378131
Change-Id: I2a9c0b41742bb1612d7f30be5408b7d6a451c47b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4023328
Reviewed-by: Brandon Wylie <wylieb@chromium.org>
Commit-Queue: Yuheng Huang <yuhengh@chromium.org>
Reviewed-by: Matthew Denton <mpdenton@chromium.org>
Reviewed-by: Caroline Rising <corising@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1075166}
  • Loading branch information
Yuheng Huang authored and Chromium LUCI CQ committed Nov 23, 2022
1 parent 0ad07c4 commit 6a20f2a
Show file tree
Hide file tree
Showing 8 changed files with 374 additions and 2 deletions.
1 change: 1 addition & 0 deletions chrome/browser/ui/BUILD.gn
Expand Up @@ -5293,6 +5293,7 @@ static_library("ui") {
"//components/payments/content:utils",
"//components/payments/core",
"//components/power_bookmarks/core:core",
"//components/power_bookmarks/core:powers",
"//components/power_bookmarks/storage",
"//components/qr_code_generator",
"//components/reading_list/features:flags",
Expand Down
3 changes: 3 additions & 0 deletions chrome/browser/ui/webui/side_panel/user_notes/DEPS
@@ -0,0 +1,3 @@
include_rules = [
"+components/power_bookmarks",
]
1 change: 1 addition & 0 deletions chrome/browser/ui/webui/side_panel/user_notes/OWNERS
@@ -1,4 +1,5 @@
corising@chromium.org
yuhengh@chromium.org

per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
64 changes: 63 additions & 1 deletion chrome/browser/ui/webui/side_panel/user_notes/user_notes.mojom
Expand Up @@ -4,8 +4,70 @@

module side_panel.mojom;

import "mojo/public/mojom/base/time.mojom";
import "mojo/public/mojom/base/token.mojom";
import "url/mojom/url.mojom";

// Data structure representing a note.
struct Note {
//unique identifier of the note.
string guid;

// URL of the page where the note is created.
url.mojom.Url url;

// Last modification time of the note.
mojo_base.mojom.Time last_modification_time;

// Last modification time text to display
string last_modification_time_text;

// Text of the note.
string text;
};

// Data structure representing a note overview.
struct NoteOverview {
// URL of the page.
url.mojom.Url url;

// Title of the corresponding bookmark, or URL if no bookmarks found.
string title;

// The text of the first (matched) note of this URL.
string text;

// The number of notes added to this URL.
int32 num_notes;

// Whether the overview item is the current tab.
bool is_current_tab;

// The last modification time of the notes from the url.
mojo_base.mojom.Time last_modification_time;
};

// Browser-side handler for requests from WebUI page.
interface UserNotesPageHandler {
// Notify the backend that the UI is ready to be shown.
ShowUI();
};

// API to render view all notes UI.
// User input can be empty (initial case) or non-empty (search case).
GetNoteOverviews(string user_input) => (array<NoteOverview> overviews);

// API to render view notes in tabs UI.
GetNotesForCurrentTab() => (array<Note> notes);

// Called when finishing a new note from the UI.
NewNoteFinished(string text) => (bool success);

// Called when updating a note from the UI.
UpdateNote(string guid, string text) => (bool success);

// Called when deleting a note from the UI.
DeleteNote(string guid) => (bool success);

// Called when deleting all notes for a url.
DeleteNotesForUrl(url.mojom.Url url) => (bool success);
};
Expand Up @@ -5,14 +5,92 @@
#include "chrome/browser/ui/webui/side_panel/user_notes/user_notes_page_handler.h"

#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/power_bookmarks/power_bookmark_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/side_panel/user_notes/user_notes_side_panel_ui.h"
#include "components/power_bookmarks/core/power_bookmark_service.h"
#include "components/power_bookmarks/core/powers/power.h"
#include "components/power_bookmarks/core/powers/power_overview.h"
#include "components/power_bookmarks/core/proto/power_bookmark_specifics.pb.h"
#include "ui/base/l10n/time_format.h"

namespace {

const int kCurrentVersionNumber = 1;

side_panel::mojom::NoteOverviewPtr PowerOverviewToMojo(
const power_bookmarks::PowerOverview& power_overview) {
auto* power = power_overview.power();
DCHECK(power->power_type() == power_bookmarks::PowerType::POWER_TYPE_NOTE);
DCHECK(power->power_specifics()->has_note_specifics());
auto result = side_panel::mojom::NoteOverview::New();
result->url = power->url();
// TODO(crbug.com/1378131): Get title from the corresponding bookmark.
result->title = power->url().spec();
result->text = power->power_specifics()->note_specifics().plain_text();
result->num_notes = power_overview.count();
result->is_current_tab = false;
// TODO(crbug.com/1378131): Get the last_modification_time of the overview
// item for sorting.
return result;
}

side_panel::mojom::NotePtr PowerToMojo(const power_bookmarks::Power& power) {
DCHECK(power.power_type() == power_bookmarks::PowerType::POWER_TYPE_NOTE);
DCHECK(power.power_specifics()->has_note_specifics());
auto note_specifics = power.power_specifics()->note_specifics();
auto result = side_panel::mojom::Note::New();
result->guid = power.guid().AsLowercaseString();
result->url = power.url();
result->last_modification_time = power.time_modified();
result->last_modification_time_text =
base::UTF16ToUTF8(ui::TimeFormat::Simple(
ui::TimeFormat::FORMAT_ELAPSED, ui::TimeFormat::LENGTH_SHORT,
base::Time::Now() - power.time_modified()));
result->text = note_specifics.plain_text();
return result;
}

bool IsNoteVisible(const power_bookmarks::Power& power) {
DCHECK(power.power_type() == power_bookmarks::PowerType::POWER_TYPE_NOTE);
DCHECK(power.power_specifics()->has_note_specifics());
return power.power_specifics()->note_specifics().current_note_version() <=
kCurrentVersionNumber;
}

std::unique_ptr<power_bookmarks::Power> MakePower(const std::string& guid,
const std::string& text,
GURL url,
bool is_create) {
auto power_specific = std::make_unique<power_bookmarks::PowerSpecifics>();
power_specific->mutable_note_specifics()->set_plain_text(text);
power_specific->mutable_note_specifics()->set_current_note_version(
kCurrentVersionNumber);
power_specific->mutable_note_specifics()->set_target_type(
power_bookmarks::NoteSpecifics::TargetType::
NoteSpecifics_TargetType_TARGET_TYPE_PAGE);
auto result =
std::make_unique<power_bookmarks::Power>(std::move(power_specific));
result->set_guid(base::GUID::ParseLowercase(guid));
result->set_power_type(power_bookmarks::PowerType::POWER_TYPE_NOTE);
if (is_create)
result->set_time_added(base::Time::Now());
result->set_time_modified(base::Time::Now());
result->set_url(url);
return result;
}

} // namespace

UserNotesPageHandler::UserNotesPageHandler(
mojo::PendingReceiver<side_panel::mojom::UserNotesPageHandler> receiver,
Profile* profile,
UserNotesSidePanelUI* user_notes_ui)
: receiver_(this, std::move(receiver)), user_notes_ui_(user_notes_ui) {}
: receiver_(this, std::move(receiver)),
profile_(profile),
service_(PowerBookmarkServiceFactory::GetForBrowserContext(profile_)),
user_notes_ui_(user_notes_ui) {}

UserNotesPageHandler::~UserNotesPageHandler() = default;

Expand All @@ -22,3 +100,76 @@ void UserNotesPageHandler::ShowUI() {
embedder->ShowUI();
}
}

void UserNotesPageHandler::GetNoteOverviews(const std::string& user_input,
GetNoteOverviewsCallback callback) {
service_->GetPowerOverviewsForType(
power_bookmarks::PowerType::POWER_TYPE_NOTE,
base::BindOnce(
[](GetNoteOverviewsCallback callback,
std::vector<std::unique_ptr<power_bookmarks::PowerOverview>>
power_overviews) {
std::vector<side_panel::mojom::NoteOverviewPtr> results;
for (auto& power_overview : power_overviews) {
results.push_back(PowerOverviewToMojo(*power_overview));
}
std::move(callback).Run(std::move(results));
},
std::move(callback)));
}

void UserNotesPageHandler::GetNotesForCurrentTab(
GetNotesForCurrentTabCallback callback) {
service_->GetPowersForURL(
current_tab_url_, power_bookmarks::PowerType::POWER_TYPE_NOTE,
base::BindOnce(
[](GetNotesForCurrentTabCallback callback,
std::vector<std::unique_ptr<power_bookmarks::Power>> powers) {
std::vector<side_panel::mojom::NotePtr> results;
for (auto& power : powers) {
if (!IsNoteVisible(*power))
continue;
results.push_back(PowerToMojo(*power));
}
std::move(callback).Run(std::move(results));
},
std::move(callback)));
}
void UserNotesPageHandler::NewNoteFinished(const std::string& text,
NewNoteFinishedCallback callback) {
std::string guid = base::GUID::GenerateRandomV4().AsLowercaseString();
service_->CreatePower(
MakePower(guid, text, current_tab_url_, /*is_create=*/true),
base::BindOnce([](NewNoteFinishedCallback callback,
bool success) { std::move(callback).Run(success); },
std::move(callback)));
}

void UserNotesPageHandler::UpdateNote(const std::string& guid,
const std::string& text,
UpdateNoteCallback callback) {
service_->UpdatePower(
MakePower(guid, text, current_tab_url_, /*is_create=*/false),
base::BindOnce([](UpdateNoteCallback callback,
bool success) { std::move(callback).Run(success); },
std::move(callback)));
}

void UserNotesPageHandler::DeleteNote(const std::string& guid,
DeleteNoteCallback callback) {
service_->DeletePower(
base::GUID::ParseLowercase(guid),
base::BindOnce([](DeleteNoteCallback callback,
bool success) { std::move(callback).Run(success); },
std::move(callback)));
}

void UserNotesPageHandler::DeleteNotesForUrl(
const ::GURL& url,
DeleteNotesForUrlCallback callback) {
service_->DeletePowersForURL(
url, power_bookmarks::PowerType::POWER_TYPE_NOTE,
base::BindOnce([](DeleteNotesForUrlCallback callback,
bool success) { std::move(callback).Run(success); },
std::move(callback)));
}
Expand Up @@ -10,6 +10,10 @@
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"

namespace power_bookmarks {
class PowerBookmarkService;
}

class UserNotesSidePanelUI;
class Profile;

Expand All @@ -25,10 +29,27 @@ class UserNotesPageHandler : public side_panel::mojom::UserNotesPageHandler {

// side_panel::mojom::UserNotesPageHandler:
void ShowUI() override;
void GetNoteOverviews(const std::string& user_input,
GetNoteOverviewsCallback callback) override;
void GetNotesForCurrentTab(GetNotesForCurrentTabCallback callback) override;
void NewNoteFinished(const std::string& text,
NewNoteFinishedCallback callback) override;
void UpdateNote(const std::string& guid,
const std::string& text,
UpdateNoteCallback callback) override;
void DeleteNote(const std::string& guid,
DeleteNoteCallback callback) override;
void DeleteNotesForUrl(const ::GURL& url,
DeleteNotesForUrlCallback callback) override;

void SetCurrentTabUrlForTesting(GURL url) { current_tab_url_ = url; }

private:
mojo::Receiver<side_panel::mojom::UserNotesPageHandler> receiver_;
const raw_ptr<Profile> profile_;
const raw_ptr<power_bookmarks::PowerBookmarkService> service_;
raw_ptr<UserNotesSidePanelUI> user_notes_ui_ = nullptr;
GURL current_tab_url_;
};

#endif // CHROME_BROWSER_UI_WEBUI_SIDE_PANEL_USER_NOTES_USER_NOTES_PAGE_HANDLER_H_

0 comments on commit 6a20f2a

Please sign in to comment.