Commit 4475c8d5 authored by Olivier Yiptong's avatar Olivier Yiptong Committed by Commit Bot

FontAccess: Blink implementation for Chooser API

This implements the blink portion of the API to
trigger a font chooser. This extends the previous stub
to communicate with the Browser process.

The content/embedder side will be extended in a future
CL to complete the implementation end-to-end.

Bug: 1138621
Change-Id: I0d5206b10566eed6a40227f994523cabaf3e0913
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2538143
Commit-Queue: Olivier Yiptong <oyiptong@chromium.org>
Reviewed-by: default avatarMartin Barbella <mbarbella@chromium.org>
Reviewed-by: default avatarJoshua Bell <jsbell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#829904}
parent c3ca9d9b
......@@ -106,6 +106,12 @@ void FontAccessManagerImpl::EnumerateLocalFonts(
#endif
}
void FontAccessManagerImpl::ChooseLocalFonts(
ChooseLocalFontsCallback callback) {
std::move(callback).Run(blink::mojom::FontEnumerationStatus::kUnimplemented,
{});
}
void FontAccessManagerImpl::FindAllFonts(FindAllFontsCallback callback) {
#if !defined(PLATFORM_HAS_LOCAL_FONT_ENUMERATION_IMPL)
std::move(callback).Run(blink::mojom::FontEnumerationStatus::kUnimplemented,
......
......@@ -40,6 +40,7 @@ class CONTENT_EXPORT FontAccessManagerImpl
// blink.mojom.FontAccessManager:
void EnumerateLocalFonts(EnumerateLocalFontsCallback callback) override;
void ChooseLocalFonts(ChooseLocalFontsCallback callback) override;
// content::FontAccessContext:
void FindAllFonts(FindAllFontsCallback callback) override;
......
......@@ -19,6 +19,8 @@ enum FontEnumerationStatus {
kNotVisible,
// The site doesn't have permission for the requested operation.
kPermissionDenied,
// The user canceled the operation.
kCanceled,
};
// Bag of data representing a font, used to pass structured data from
......@@ -36,4 +38,7 @@ interface FontAccessManager {
// Enumerate locally installed fonts. Results will be gated by a permission
// check.
EnumerateLocalFonts() => (FontEnumerationStatus enumeration_status, mojo_base.mojom.ReadOnlySharedMemoryRegion? enumeration_table);
// Begins a UX that gives affordances for a user to choose fonts to be shared
// with the page.
ChooseLocalFonts() => (FontEnumerationStatus status, array<FontMetadata> selection);
};
......@@ -6,13 +6,18 @@
#include <algorithm>
#include "base/feature_list.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/modules/font_access/font_iterator.h"
#include "third_party/blink/renderer/modules/font_access/font_metadata.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink {
......@@ -25,6 +30,18 @@ void ReturnDataFunction(const v8::FunctionCallbackInfo<v8::Value>& info) {
} // namespace
FontManager::FontManager(ExecutionContext* context)
: ExecutionContextLifecycleObserver(context) {
// Only connect if the feature is enabled. Otherwise, there will
// be no service to connect to on the end.
if (base::FeatureList::IsEnabled(blink::features::kFontAccess)) {
context->GetBrowserInterfaceBroker().GetInterface(
remote_manager_.BindNewPipeAndPassReceiver());
remote_manager_.set_disconnect_handler(
WTF::Bind(&FontManager::OnDisconnect, WrapWeakPersistent(this)));
}
}
ScriptValue FontManager::query(ScriptState* script_state,
ExceptionState& exception_state) {
if (exception_state.HadException())
......@@ -49,14 +66,69 @@ ScriptValue FontManager::query(ScriptState* script_state,
ScriptPromise FontManager::showFontChooser(ScriptState* script_state,
const QueryOptions* options) {
return ScriptPromise::RejectWithDOMException(
script_state,
MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError,
"Not implemented yet"));
// TODO(crbug.com/1149621): Queue up font chooser requests.
if (!pending_resolver_) {
remote_manager_->ChooseLocalFonts(
WTF::Bind(&FontManager::DidShowFontChooser, WrapWeakPersistent(this)));
pending_resolver_ =
MakeGarbageCollected<ScriptPromiseResolver>(script_state);
}
return pending_resolver_->Promise();
}
void FontManager::Trace(blink::Visitor* visitor) const {
ScriptWrappable::Trace(visitor);
ContextLifecycleObserver::Trace(visitor);
visitor->Trace(pending_resolver_);
}
void FontManager::DidShowFontChooser(
mojom::blink::FontEnumerationStatus status,
Vector<mojom::blink::FontMetadataPtr> fonts) {
switch (status) {
case mojom::blink::FontEnumerationStatus::kOk:
break;
case mojom::blink::FontEnumerationStatus::kUnimplemented:
pending_resolver_->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotSupportedError,
"Not yet supported on this platform."));
pending_resolver_.Clear();
return;
case mojom::blink::FontEnumerationStatus::kCanceled:
pending_resolver_->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kAbortError, "The user canceled the operation."));
pending_resolver_.Clear();
return;
case mojom::blink::FontEnumerationStatus::kNeedsUserActivation:
pending_resolver_->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kSecurityError, "User activation is required."));
pending_resolver_.Clear();
return;
case mojom::blink::FontEnumerationStatus::kUnexpectedError:
default:
pending_resolver_->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kUnknownError, "An unexpected error occured."));
pending_resolver_.Clear();
return;
}
auto entries = HeapVector<Member<FontMetadata>>();
for (const auto& font : fonts) {
auto entry = FontEnumerationEntry{font->postscript_name, font->full_name,
font->family};
entries.push_back(FontMetadata::Create(std::move(entry)));
}
pending_resolver_->Resolve(std::move(entries));
pending_resolver_.Clear();
}
void FontManager::ContextDestroyed() {
remote_manager_.reset();
}
void FontManager::OnDisconnect() {
remote_manager_.reset();
}
} // namespace blink
......@@ -5,6 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_MANAGER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_MANAGER_H_
#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/font_access/font_access.mojom-blink.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
......@@ -15,13 +18,15 @@ namespace blink {
class ScriptState;
class ScriptValue;
class ScriptPromise;
class ScriptPromiseResolver;
class QueryOptions;
class FontManager final : public ScriptWrappable {
class FontManager final : public ScriptWrappable,
public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO();
public:
FontManager() = default;
explicit FontManager(ExecutionContext* context);
// Disallow copy and assign.
FontManager(const FontManager&) = delete;
......@@ -32,6 +37,15 @@ class FontManager final : public ScriptWrappable {
ScriptPromise showFontChooser(ScriptState*, const QueryOptions* options);
void Trace(blink::Visitor*) const override;
private:
void DidShowFontChooser(mojom::blink::FontEnumerationStatus status,
Vector<mojom::blink::FontMetadataPtr> fonts);
void ContextDestroyed() override;
void OnDisconnect();
mojo::Remote<mojom::blink::FontAccessManager> remote_manager_;
Member<ScriptPromiseResolver> pending_resolver_;
};
} // namespace blink
......
......@@ -9,5 +9,5 @@
RuntimeEnabled=FontAccess
] interface FontManager {
[CallWith=ScriptState, RaisesException, Measure] object query();
[CallWith=ScriptState, RuntimeEnabled=FontAccessChooser] Promise<FontIterator> showFontChooser(optional QueryOptions options = {});
[CallWith=ScriptState, RuntimeEnabled=FontAccessChooser] Promise<sequence<FontMetadata>> showFontChooser(optional QueryOptions options = {});
};
......@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/font_access/navigator_fonts.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/execution_context/security_context.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/core/workers/worker_navigator.h"
......@@ -36,9 +37,9 @@ class NavigatorFontsImpl final : public GarbageCollected<NavigatorFontsImpl<T>>,
explicit NavigatorFontsImpl(T& navigator) : Supplement<T>(navigator) {}
FontManager* GetFontManager() const {
FontManager* GetFontManager(ExecutionContext* context) const {
if (!font_manager_) {
font_manager_ = MakeGarbageCollected<FontManager>();
font_manager_ = MakeGarbageCollected<FontManager>(context);
}
return font_manager_.Get();
}
......@@ -66,7 +67,8 @@ FontManager* NavigatorFonts::fonts(ScriptState* script_state,
Navigator& navigator,
ExceptionState& exception_state) {
DCHECK(ExecutionContext::From(script_state)->IsContextThread());
return NavigatorFontsImpl<Navigator>::From(navigator).GetFontManager();
ExecutionContext* context = ExecutionContext::From(script_state);
return NavigatorFontsImpl<Navigator>::From(navigator).GetFontManager(context);
}
} // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment