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( ...@@ -106,6 +106,12 @@ void FontAccessManagerImpl::EnumerateLocalFonts(
#endif #endif
} }
void FontAccessManagerImpl::ChooseLocalFonts(
ChooseLocalFontsCallback callback) {
std::move(callback).Run(blink::mojom::FontEnumerationStatus::kUnimplemented,
{});
}
void FontAccessManagerImpl::FindAllFonts(FindAllFontsCallback callback) { void FontAccessManagerImpl::FindAllFonts(FindAllFontsCallback callback) {
#if !defined(PLATFORM_HAS_LOCAL_FONT_ENUMERATION_IMPL) #if !defined(PLATFORM_HAS_LOCAL_FONT_ENUMERATION_IMPL)
std::move(callback).Run(blink::mojom::FontEnumerationStatus::kUnimplemented, std::move(callback).Run(blink::mojom::FontEnumerationStatus::kUnimplemented,
......
...@@ -40,6 +40,7 @@ class CONTENT_EXPORT FontAccessManagerImpl ...@@ -40,6 +40,7 @@ class CONTENT_EXPORT FontAccessManagerImpl
// blink.mojom.FontAccessManager: // blink.mojom.FontAccessManager:
void EnumerateLocalFonts(EnumerateLocalFontsCallback callback) override; void EnumerateLocalFonts(EnumerateLocalFontsCallback callback) override;
void ChooseLocalFonts(ChooseLocalFontsCallback callback) override;
// content::FontAccessContext: // content::FontAccessContext:
void FindAllFonts(FindAllFontsCallback callback) override; void FindAllFonts(FindAllFontsCallback callback) override;
......
...@@ -19,6 +19,8 @@ enum FontEnumerationStatus { ...@@ -19,6 +19,8 @@ enum FontEnumerationStatus {
kNotVisible, kNotVisible,
// The site doesn't have permission for the requested operation. // The site doesn't have permission for the requested operation.
kPermissionDenied, kPermissionDenied,
// The user canceled the operation.
kCanceled,
}; };
// Bag of data representing a font, used to pass structured data from // Bag of data representing a font, used to pass structured data from
...@@ -36,4 +38,7 @@ interface FontAccessManager { ...@@ -36,4 +38,7 @@ interface FontAccessManager {
// Enumerate locally installed fonts. Results will be gated by a permission // Enumerate locally installed fonts. Results will be gated by a permission
// check. // check.
EnumerateLocalFonts() => (FontEnumerationStatus enumeration_status, mojo_base.mojom.ReadOnlySharedMemoryRegion? enumeration_table); 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 @@ ...@@ -6,13 +6,18 @@
#include <algorithm> #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/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_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.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/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_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.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_iterator.h"
#include "third_party/blink/renderer/modules/font_access/font_metadata.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink { namespace blink {
...@@ -25,6 +30,18 @@ void ReturnDataFunction(const v8::FunctionCallbackInfo<v8::Value>& info) { ...@@ -25,6 +30,18 @@ void ReturnDataFunction(const v8::FunctionCallbackInfo<v8::Value>& info) {
} // namespace } // 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, ScriptValue FontManager::query(ScriptState* script_state,
ExceptionState& exception_state) { ExceptionState& exception_state) {
if (exception_state.HadException()) if (exception_state.HadException())
...@@ -49,14 +66,69 @@ ScriptValue FontManager::query(ScriptState* script_state, ...@@ -49,14 +66,69 @@ ScriptValue FontManager::query(ScriptState* script_state,
ScriptPromise FontManager::showFontChooser(ScriptState* script_state, ScriptPromise FontManager::showFontChooser(ScriptState* script_state,
const QueryOptions* options) { const QueryOptions* options) {
return ScriptPromise::RejectWithDOMException( // TODO(crbug.com/1149621): Queue up font chooser requests.
script_state, if (!pending_resolver_) {
MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, remote_manager_->ChooseLocalFonts(
"Not implemented yet")); WTF::Bind(&FontManager::DidShowFontChooser, WrapWeakPersistent(this)));
pending_resolver_ =
MakeGarbageCollected<ScriptPromiseResolver>(script_state);
}
return pending_resolver_->Promise();
} }
void FontManager::Trace(blink::Visitor* visitor) const { void FontManager::Trace(blink::Visitor* visitor) const {
ScriptWrappable::Trace(visitor); 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 } // namespace blink
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_MANAGER_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FONT_ACCESS_FONT_MANAGER_H_
#define 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/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
...@@ -15,13 +18,15 @@ namespace blink { ...@@ -15,13 +18,15 @@ namespace blink {
class ScriptState; class ScriptState;
class ScriptValue; class ScriptValue;
class ScriptPromise; class ScriptPromise;
class ScriptPromiseResolver;
class QueryOptions; class QueryOptions;
class FontManager final : public ScriptWrappable { class FontManager final : public ScriptWrappable,
public ExecutionContextLifecycleObserver {
DEFINE_WRAPPERTYPEINFO(); DEFINE_WRAPPERTYPEINFO();
public: public:
FontManager() = default; explicit FontManager(ExecutionContext* context);
// Disallow copy and assign. // Disallow copy and assign.
FontManager(const FontManager&) = delete; FontManager(const FontManager&) = delete;
...@@ -32,6 +37,15 @@ class FontManager final : public ScriptWrappable { ...@@ -32,6 +37,15 @@ class FontManager final : public ScriptWrappable {
ScriptPromise showFontChooser(ScriptState*, const QueryOptions* options); ScriptPromise showFontChooser(ScriptState*, const QueryOptions* options);
void Trace(blink::Visitor*) const override; 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 } // namespace blink
......
...@@ -9,5 +9,5 @@ ...@@ -9,5 +9,5 @@
RuntimeEnabled=FontAccess RuntimeEnabled=FontAccess
] interface FontManager { ] interface FontManager {
[CallWith=ScriptState, RaisesException, Measure] object query(); [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 @@ ...@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/modules/font_access/navigator_fonts.h" #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/execution_context/security_context.h"
#include "third_party/blink/renderer/core/frame/navigator.h" #include "third_party/blink/renderer/core/frame/navigator.h"
#include "third_party/blink/renderer/core/workers/worker_navigator.h" #include "third_party/blink/renderer/core/workers/worker_navigator.h"
...@@ -36,9 +37,9 @@ class NavigatorFontsImpl final : public GarbageCollected<NavigatorFontsImpl<T>>, ...@@ -36,9 +37,9 @@ class NavigatorFontsImpl final : public GarbageCollected<NavigatorFontsImpl<T>>,
explicit NavigatorFontsImpl(T& navigator) : Supplement<T>(navigator) {} explicit NavigatorFontsImpl(T& navigator) : Supplement<T>(navigator) {}
FontManager* GetFontManager() const { FontManager* GetFontManager(ExecutionContext* context) const {
if (!font_manager_) { if (!font_manager_) {
font_manager_ = MakeGarbageCollected<FontManager>(); font_manager_ = MakeGarbageCollected<FontManager>(context);
} }
return font_manager_.Get(); return font_manager_.Get();
} }
...@@ -66,7 +67,8 @@ FontManager* NavigatorFonts::fonts(ScriptState* script_state, ...@@ -66,7 +67,8 @@ FontManager* NavigatorFonts::fonts(ScriptState* script_state,
Navigator& navigator, Navigator& navigator,
ExceptionState& exception_state) { ExceptionState& exception_state) {
DCHECK(ExecutionContext::From(script_state)->IsContextThread()); 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 } // 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