OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "modules/webshare/NavigatorShare.h" | 5 #include "modules/webshare/NavigatorShare.h" |
6 | 6 |
7 #include "core/dom/DOMException.h" | 7 #include "core/dom/DOMException.h" |
8 #include "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
9 #include "core/dom/ExceptionCode.h" | 9 #include "core/dom/ExceptionCode.h" |
10 #include "core/frame/LocalFrame.h" | 10 #include "core/frame/LocalFrame.h" |
11 #include "core/frame/Navigator.h" | 11 #include "core/frame/Navigator.h" |
12 #include "modules/webshare/ShareData.h" | 12 #include "modules/webshare/ShareData.h" |
13 #include "platform/UserGestureIndicator.h" | 13 #include "platform/UserGestureIndicator.h" |
14 #include "platform/mojo/MojoHelper.h" | 14 #include "platform/mojo/MojoHelper.h" |
15 #include "public/platform/InterfaceProvider.h" | 15 #include "public/platform/InterfaceProvider.h" |
16 #include "public/platform/Platform.h" | 16 #include "public/platform/Platform.h" |
17 | 17 |
18 namespace blink { | 18 namespace blink { |
19 | 19 |
20 class NavigatorShare::ShareClientImpl final | 20 class NavigatorShare::ShareClientImpl final |
21 : public GarbageCollected<ShareClientImpl> { | 21 : public GarbageCollected<ShareClientImpl> { |
22 public: | 22 public: |
23 ShareClientImpl(NavigatorShare*, ScriptPromiseResolver*); | 23 ShareClientImpl(NavigatorShare*, ScriptPromiseResolver*); |
24 | 24 |
25 void callback(const String& error); | 25 void callback(const String& error); |
26 | 26 |
| 27 void onConnectionError(); |
| 28 |
27 DEFINE_INLINE_TRACE() { | 29 DEFINE_INLINE_TRACE() { |
28 visitor->trace(m_navigator); | 30 visitor->trace(m_navigator); |
29 visitor->trace(m_resolver); | 31 visitor->trace(m_resolver); |
30 } | 32 } |
31 | 33 |
32 private: | 34 private: |
33 WeakMember<NavigatorShare> m_navigator; | 35 WeakMember<NavigatorShare> m_navigator; |
34 Member<ScriptPromiseResolver> m_resolver; | 36 Member<ScriptPromiseResolver> m_resolver; |
35 }; | 37 }; |
36 | 38 |
37 NavigatorShare::ShareClientImpl::ShareClientImpl( | 39 NavigatorShare::ShareClientImpl::ShareClientImpl( |
38 NavigatorShare* navigator_share, | 40 NavigatorShare* navigator_share, |
39 ScriptPromiseResolver* resolver) | 41 ScriptPromiseResolver* resolver) |
40 : m_navigator(navigator_share), m_resolver(resolver) {} | 42 : m_navigator(navigator_share), m_resolver(resolver) {} |
41 | 43 |
42 void NavigatorShare::ShareClientImpl::callback(const String& error) { | 44 void NavigatorShare::ShareClientImpl::callback(const String& error) { |
43 if (m_navigator) | 45 if (m_navigator) |
44 m_navigator->m_clients.remove(this); | 46 m_navigator->m_clients.remove(this); |
45 | 47 |
46 if (error.isNull()) { | 48 if (error.isNull()) { |
47 m_resolver->resolve(); | 49 m_resolver->resolve(); |
48 } else { | 50 } else { |
49 // TODO(mgiuca): Work out which error type to use. | 51 // TODO(mgiuca): Work out which error type to use. |
50 m_resolver->reject(DOMException::create(AbortError, error)); | 52 m_resolver->reject(DOMException::create(AbortError, error)); |
51 } | 53 } |
52 } | 54 } |
53 | 55 |
| 56 void NavigatorShare::ShareClientImpl::onConnectionError() { |
| 57 m_resolver->reject( |
| 58 DOMException::create(SecurityError, "WebShare is disabled.")); |
| 59 } |
| 60 |
54 NavigatorShare::~NavigatorShare() = default; | 61 NavigatorShare::~NavigatorShare() = default; |
55 | 62 |
56 NavigatorShare& NavigatorShare::from(Navigator& navigator) { | 63 NavigatorShare& NavigatorShare::from(Navigator& navigator) { |
57 NavigatorShare* supplement = static_cast<NavigatorShare*>( | 64 NavigatorShare* supplement = static_cast<NavigatorShare*>( |
58 Supplement<Navigator>::from(navigator, supplementName())); | 65 Supplement<Navigator>::from(navigator, supplementName())); |
59 if (!supplement) { | 66 if (!supplement) { |
60 supplement = new NavigatorShare(); | 67 supplement = new NavigatorShare(); |
61 provideTo(navigator, supplementName(), supplement); | 68 provideTo(navigator, supplementName(), supplement); |
62 } | 69 } |
63 return *supplement; | 70 return *supplement; |
(...skipping 23 matching lines...) Expand all Loading... |
87 "Must be handling a user gesture to perform a share request."); | 94 "Must be handling a user gesture to perform a share request."); |
88 return ScriptPromise::rejectWithDOMException(scriptState, error); | 95 return ScriptPromise::rejectWithDOMException(scriptState, error); |
89 } | 96 } |
90 | 97 |
91 Document* doc = toDocument(scriptState->getExecutionContext()); | 98 Document* doc = toDocument(scriptState->getExecutionContext()); |
92 DCHECK(doc); | 99 DCHECK(doc); |
93 if (!m_service) { | 100 if (!m_service) { |
94 LocalFrame* frame = doc->frame(); | 101 LocalFrame* frame = doc->frame(); |
95 DCHECK(frame); | 102 DCHECK(frame); |
96 frame->interfaceProvider()->getInterface(mojo::GetProxy(&m_service)); | 103 frame->interfaceProvider()->getInterface(mojo::GetProxy(&m_service)); |
| 104 m_service.set_connection_error_handler(convertToBaseCallback(WTF::bind( |
| 105 &NavigatorShare::onConnectionError, wrapWeakPersistent(this)))); |
97 DCHECK(m_service); | 106 DCHECK(m_service); |
98 } | 107 } |
99 | 108 |
100 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 109 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
101 ShareClientImpl* client = new ShareClientImpl(this, resolver); | 110 ShareClientImpl* client = new ShareClientImpl(this, resolver); |
102 m_clients.add(client); | 111 m_clients.add(client); |
103 ScriptPromise promise = resolver->promise(); | 112 ScriptPromise promise = resolver->promise(); |
104 | 113 |
105 m_service->Share(shareData.hasTitle() ? shareData.title() : emptyString(), | 114 m_service->Share(shareData.hasTitle() ? shareData.title() : emptyString(), |
106 shareData.hasText() ? shareData.text() : emptyString(), | 115 shareData.hasText() ? shareData.text() : emptyString(), |
107 doc->completeURL(shareData.url()), | 116 doc->completeURL(shareData.url()), |
108 convertToBaseCallback(WTF::bind(&ShareClientImpl::callback, | 117 convertToBaseCallback(WTF::bind(&ShareClientImpl::callback, |
109 wrapPersistent(client)))); | 118 wrapPersistent(client)))); |
110 | 119 |
111 return promise; | 120 return promise; |
112 } | 121 } |
113 | 122 |
114 ScriptPromise NavigatorShare::share(ScriptState* scriptState, | 123 ScriptPromise NavigatorShare::share(ScriptState* scriptState, |
115 Navigator& navigator, | 124 Navigator& navigator, |
116 const ShareData& shareData) { | 125 const ShareData& shareData) { |
117 return from(navigator).share(scriptState, shareData); | 126 return from(navigator).share(scriptState, shareData); |
118 } | 127 } |
119 | 128 |
| 129 void NavigatorShare::onConnectionError() { |
| 130 for (auto& client : m_clients) { |
| 131 client->onConnectionError(); |
| 132 } |
| 133 m_clients.clear(); |
| 134 m_service.reset(); |
| 135 } |
| 136 |
120 } // namespace blink | 137 } // namespace blink |
OLD | NEW |