0

[iOS][Enhanced Cal] Moved page context work directly into Mojo service

The mojo service now holds onto a webstate, and everything it needs to
take care of populating the page context proto itself. This way, when
its usage is simplified to creating the service, passing it the correct
parameters, and calling `Execute...`. The mojo interface itself was
modified to be passed the strict minimum in terms of necessary strings
for the request to be created within the service itself. Organized in
a `RequestParams` struct.

Bug: 390621435
Change-Id: I15b874ac0ec8fbbb30feaee7c9a001f8ac7a98eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6340887
Commit-Queue: Nicolas MacBeth <nicolasmacbeth@google.com>
Reviewed-by: Giovanni Ortuno Urquidi <ortuno@chromium.org>
Reviewed-by: Adam Arcaro <adamta@google.com>
Auto-Submit: Nicolas MacBeth <nicolasmacbeth@google.com>
Cr-Commit-Position: refs/heads/main@{#1430996}
This commit is contained in:
Nicolas MacBeth
2025-03-11 10:41:03 -07:00
committed by Chromium LUCI CQ
parent b791bfcebb
commit 486786e6aa
4 changed files with 110 additions and 61 deletions
ios/chrome/browser
ai_prototyping
intelligence
optimization_guide

@ -97,7 +97,8 @@
_enhanced_calendar_service.BindNewPipeAndPassReceiver();
_enhanced_calendar_service_impl =
std::make_unique<ai::EnhancedCalendarServiceImpl>(
std::move(enhanced_calendar_receiver), browserState);
std::move(enhanced_calendar_receiver),
_webStateList->GetActiveWebState());
}
return self;
}
@ -237,40 +238,30 @@
- (void)executeEnhancedCalendarQueryWithPrompt:(NSString*)prompt
selectedText:(NSString*)selectedText {
optimization_guide::proto::EnhancedCalendarRequest request;
// Set the selected text on the request.
request.set_selected_text(base::SysNSStringToUTF8(selectedText));
// Create and set the request params.
ai::mojom::EnhancedCalendarServiceRequestParamsPtr request_params =
ai::mojom::EnhancedCalendarServiceRequestParams::New();
request_params->selected_text = base::SysNSStringToUTF8(selectedText);
request_params->surrounding_text = base::SysNSStringToUTF8(selectedText);
// Set the whitespace-trimmed prompt on the request, if not empty.
NSString* trimmedPrompt = [prompt
stringByTrimmingCharactersInSet:[NSCharacterSet
whitespaceAndNewlineCharacterSet]];
if (trimmedPrompt.length) {
request.set_prompt(base::SysNSStringToUTF8(trimmedPrompt));
request_params->optional_prompt = base::SysNSStringToUTF8(trimmedPrompt);
}
// Callback to execute when the PageContext proto is done being generated.
// The response handling callback.
__weak __typeof(self) weakSelf = self;
base::OnceCallback<void(
std::unique_ptr<optimization_guide::proto::PageContext>)>
page_context_completion_callback = base::BindOnce(
^void(std::unique_ptr<optimization_guide::proto::PageContext>
page_context) {
[weakSelf
executeEnhancedCalendarRequestWithPageContext:std::move(
page_context)
request:request];
base::OnceCallback<void(ai::mojom::EnhancedCalendarResponseResultPtr)>
handle_response_callback = base::BindOnce(
^void(ai::mojom::EnhancedCalendarResponseResultPtr result) {
[weakSelf handleEnhancedCalendarResponseResult:std::move(result)];
});
// Populate the PageContext proto and then execute the query.
_pageContextWrapper = [[PageContextWrapper alloc]
initWithWebState:_webStateList->GetActiveWebState()
completionCallback:std::move(page_context_completion_callback)];
[_pageContextWrapper setShouldGetInnerText:YES];
[_pageContextWrapper setShouldGetSnapshot:YES];
[_pageContextWrapper setTextToHighlight:selectedText];
[_pageContextWrapper populatePageContextFieldsAsync];
_enhanced_calendar_service->ExecuteEnhancedCalendarRequest(
std::move(request_params), std::move(handle_response_callback));
}
#pragma mark - Private
@ -299,29 +290,6 @@
std::move(proto_wrapper), std::move(handle_response_callback));
}
// Execute the Enhanced Calendar request with the Page Context.
- (void)
executeEnhancedCalendarRequestWithPageContext:
(std::unique_ptr<optimization_guide::proto::PageContext>)page_context
request:(optimization_guide::proto::
EnhancedCalendarRequest)
request {
_pageContextWrapper = nil;
request.set_allocated_page_context(page_context.release());
// The response handling callback.
__weak __typeof(self) weakSelf = self;
base::OnceCallback<void(ai::mojom::EnhancedCalendarResponseResultPtr)>
handle_response_callback = base::BindOnce(
^void(ai::mojom::EnhancedCalendarResponseResultPtr result) {
[weakSelf handleEnhancedCalendarResponseResult:std::move(result)];
});
::mojo_base::ProtoWrapper proto_wrapper = mojo_base::ProtoWrapper(request);
_enhanced_calendar_service->ExecuteEnhancedCalendarRequest(
std::move(proto_wrapper), std::move(handle_response_callback));
}
// Handles the Enhanced Calendar by outputting the response proto or an error
// message into the result text field.
- (void)handleEnhancedCalendarResponseResult:

@ -14,10 +14,17 @@ class OptimizationGuideService;
namespace optimization_guide {
class ModelQualityLogEntry;
struct OptimizationGuideModelExecutionResult;
namespace proto {
class PageContext;
class EnhancedCalendarRequest;
} // namespace proto
} // namespace optimization_guide
@class PageContextWrapper;
namespace web {
class BrowserState;
class WebState;
} // namespace web
namespace ai {
@ -26,7 +33,7 @@ class EnhancedCalendarServiceImpl : public mojom::EnhancedCalendarService {
public:
explicit EnhancedCalendarServiceImpl(
mojo::PendingReceiver<mojom::EnhancedCalendarService> receiver,
web::BrowserState* browser_state);
web::WebState* web_state);
~EnhancedCalendarServiceImpl() override;
EnhancedCalendarServiceImpl(const EnhancedCalendarServiceImpl&) = delete;
EnhancedCalendarServiceImpl& operator=(const EnhancedCalendarServiceImpl&) =
@ -34,10 +41,17 @@ class EnhancedCalendarServiceImpl : public mojom::EnhancedCalendarService {
// ai::mojom::EnhancedCalendarServiceImpl:
void ExecuteEnhancedCalendarRequest(
::mojo_base::ProtoWrapper request,
mojom::EnhancedCalendarServiceRequestParamsPtr request_params,
ExecuteEnhancedCalendarRequestCallback request_callback) override;
private:
// Handles the generated PageContext proto and executes the Enhanced Calendar
// request.
void OnPageContextGenerated(
optimization_guide::proto::EnhancedCalendarRequest request,
ExecuteEnhancedCalendarRequestCallback request_callback,
std::unique_ptr<optimization_guide::proto::PageContext> page_context);
// Handles the Enhanced Calendar response (calls `request_callback` with the
// response proto or error).
void OnEnhancedCalendarResponse(
@ -51,6 +65,12 @@ class EnhancedCalendarServiceImpl : public mojom::EnhancedCalendarService {
// Receiver throughout the EnhancedCalendarService lifecycle.
mojo::Receiver<mojom::EnhancedCalendarService> receiver_;
// Weak WebState.
base::WeakPtr<web::WebState> web_state_;
// The service's PageContext wrapper.
PageContextWrapper* page_context_wrapper_;
// Weak pointer factory.
base::WeakPtrFactory<EnhancedCalendarServiceImpl> weak_ptr_factory_{this};
};

@ -8,15 +8,18 @@
#import <utility>
#import "base/functional/bind.h"
#import "base/strings/sys_string_conversions.h"
#import "base/time/time.h"
#import "components/optimization_guide/core/model_execution/feature_keys.h"
#import "components/optimization_guide/core/model_quality/model_quality_log_entry.h"
#import "components/optimization_guide/core/optimization_guide_model_executor.h"
#import "components/optimization_guide/core/optimization_guide_util.h"
#import "components/optimization_guide/proto/features/enhanced_calendar.pb.h"
#import "ios/chrome/browser/intelligence/proto_wrappers/page_context_wrapper.h"
#import "ios/chrome/browser/optimization_guide/model/optimization_guide_service.h"
#import "ios/chrome/browser/optimization_guide/model/optimization_guide_service_factory.h"
#import "ios/chrome/browser/shared/model/profile/profile_ios.h"
#import "ios/web/public/web_state.h"
#import "mojo/public/cpp/base/proto_wrapper.h"
namespace ai {
@ -29,29 +32,73 @@ const base::TimeDelta kEnhancedCalendarRequestTimeout = base::Seconds(15);
// the `OptimizationGuideService`.
EnhancedCalendarServiceImpl::EnhancedCalendarServiceImpl(
mojo::PendingReceiver<mojom::EnhancedCalendarService> receiver,
web::BrowserState* browser_state)
web::WebState* web_state)
: service_(*OptimizationGuideServiceFactory::GetForProfile(
ProfileIOS::FromBrowserState(browser_state))),
receiver_(this, std::move(receiver)) {}
ProfileIOS::FromBrowserState(web_state->GetBrowserState()))),
receiver_(this, std::move(receiver)) {
web_state_ = web_state->GetWeakPtr();
}
EnhancedCalendarServiceImpl::~EnhancedCalendarServiceImpl() = default;
void EnhancedCalendarServiceImpl::ExecuteEnhancedCalendarRequest(
::mojo_base::ProtoWrapper request,
mojom::EnhancedCalendarServiceRequestParamsPtr request_params,
ExecuteEnhancedCalendarRequestCallback request_callback) {
optimization_guide::proto::EnhancedCalendarRequest request_proto =
request.As<optimization_guide::proto::EnhancedCalendarRequest>().value();
if (!web_state_) {
mojom::EnhancedCalendarResponseResultPtr result_union =
mojom::EnhancedCalendarResponseResult::NewError(
"WebState destroyed before executing request");
std::move(request_callback).Run(std::move(result_union));
return;
}
// Create the request, and set the selected and surrounding texts on it.
optimization_guide::proto::EnhancedCalendarRequest request;
request.set_selected_text(request_params->selected_text);
request.set_surrounding_text(request_params->surrounding_text);
// Set the prompt, if it exists.
if (request_params->optional_prompt.has_value() &&
!request_params->optional_prompt.value().empty()) {
request.set_prompt(request_params->optional_prompt.value());
}
// Callback to execute when the PageContext proto is done being generated.
auto page_context_completion_callback =
base::BindOnce(&EnhancedCalendarServiceImpl::OnPageContextGenerated,
weak_ptr_factory_.GetWeakPtr(), std::move(request),
std::move(request_callback));
// Populate the PageContext proto and then execute the query.
page_context_wrapper_ = [[PageContextWrapper alloc]
initWithWebState:web_state_.get()
completionCallback:std::move(page_context_completion_callback)];
[page_context_wrapper_ setShouldGetInnerText:YES];
[page_context_wrapper_ setShouldGetSnapshot:YES];
[page_context_wrapper_
setTextToHighlight:base::SysUTF8ToNSString(
request_params->surrounding_text)];
[page_context_wrapper_ populatePageContextFieldsAsync];
}
#pragma mark - Private
// Execute the Enhanced Calendar request with the generated Page Context.
void EnhancedCalendarServiceImpl::OnPageContextGenerated(
optimization_guide::proto::EnhancedCalendarRequest request,
ExecuteEnhancedCalendarRequestCallback request_callback,
std::unique_ptr<optimization_guide::proto::PageContext> page_context) {
page_context_wrapper_ = nil;
request.set_allocated_page_context(page_context.release());
service_->ExecuteModel(
optimization_guide::ModelBasedCapabilityKey::kEnhancedCalendar,
request_proto, kEnhancedCalendarRequestTimeout,
optimization_guide::ModelBasedCapabilityKey::kEnhancedCalendar, request,
kEnhancedCalendarRequestTimeout,
base::BindOnce(&EnhancedCalendarServiceImpl::OnEnhancedCalendarResponse,
weak_ptr_factory_.GetWeakPtr(),
std::move(request_callback)));
}
#pragma mark - Private
void EnhancedCalendarServiceImpl::OnEnhancedCalendarResponse(
ExecuteEnhancedCalendarRequestCallback request_callback,
optimization_guide::OptimizationGuideModelExecutionResult result,

@ -6,6 +6,20 @@ module ai.mojom;
import "mojo/public/mojom/base/proto_wrapper.mojom";
// Represents an Enhanced Calendar Service request parameters.
struct EnhancedCalendarServiceRequestParams {
// The text that was selected by the user for which this Enhanced Calendar
// request is for.
string selected_text;
// Text surrounding the `selected text`, to help uniquely identify it within
// the page's innerText.
string surrounding_text;
// An optional prompt to override the default one.
string? optional_prompt;
};
// Represents the result of an Enhanced Calendar response. Only one of these
// fields can hold a value.
union EnhancedCalendarResponseResult {
@ -22,7 +36,7 @@ interface EnhancedCalendarService {
// Executes an enhanced calendar feature request. The result can either
// hold a wrapper of the EnhancedCalendarResponse proto, or an error
// string.
ExecuteEnhancedCalendarRequest(mojo_base.mojom.ProtoWrapper request)
ExecuteEnhancedCalendarRequest(EnhancedCalendarServiceRequestParams request_params)
=> (EnhancedCalendarResponseResult result);
};