1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef EXTENSIONS_RENDERER_GUEST_VIEW_MIME_HANDLER_VIEW_POST_MESSAGE_SUPPORT_H_
6 #define EXTENSIONS_RENDERER_GUEST_VIEW_MIME_HANDLER_VIEW_POST_MESSAGE_SUPPORT_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "base/memory/weak_ptr.h"
12 #include "base/values.h"
13 #include "v8/include/v8.h"
14 
15 namespace blink {
16 class WebFrame;
17 class WebLocalFrame;
18 }  // namespace blink
19 
20 namespace extensions {
21 
22 // Helper class the implements postMessage support using gin/ to enable an
23 // embedder of MimeHandlerView (in an HTMLPlugInElement) to send messages to
24 // the extension loaded inside the MimeHandlerViewGuest process. This class is
25 // owned by its Delegate.
26 class PostMessageSupport {
27  public:
28   // Provides source and target messages used for posting messages. It is
29   // expected to be alive for the lifetime of PostMessageSupport.
30   class Delegate {
31    public:
32     // Returns the Delegate with source frame |web_local_frame| which will be
33     // used for internal uses of postMessage.
34     static Delegate* FromWebLocalFrame(blink::WebLocalFrame* web_local_frame);
35 
36     Delegate();
37     virtual ~Delegate();
38 
39     // The source frame which is sending the message. This is the embedder frame
40     // for a MimeHandlerViewGuest. Must not return nullptr.
41     virtual blink::WebLocalFrame* GetSourceFrame() = 0;
42 
43     // The target WebFrame which the message is sent to.
44     virtual blink::WebFrame* GetTargetFrame() = 0;
45     // Returns true if the Delegate is embedded. Used to track postMessage usage
46     // to embedded MimeHandlerView (i.e., created using a plugin element but not
47     // as a result of frame navigations to a relevant MimeHandlerView MIME.
48     virtual bool IsEmbedded() const = 0;
49     // Determines whether the (MimeHandlerView) resource in target frame is
50     // accessible from source frame (used for UMA).
51     virtual bool IsResourceAccessibleBySource() const = 0;
52 
post_message_support()53     PostMessageSupport* post_message_support() {
54       return post_message_support_.get();
55     }
56 
57    private:
58     std::unique_ptr<PostMessageSupport> post_message_support_;
59   };
60 
61   // Returns the first postMessage support found on |web_local_frame|. This is
62   // the instance which corresponds to a full page MimeHandlerView.
63   static PostMessageSupport* FromWebLocalFrame(
64       blink::WebLocalFrame* web_local_frame);
65 
66   // |delegate| will take ownership of this class.
67   explicit PostMessageSupport(Delegate* delegate);
68   ~PostMessageSupport();
69 
70   // Returns the gin/ implementation of v8::Object exposing the postMessage API.
71   // This is used as the PluginWrapper() for HTMLPlugInElement.
72   v8::Local<v8::Object> GetScriptableObject(v8::Isolate* isolate);
73 
74   // If |is_active_| the message is sent from source frame to the target frame
75   // (provided by |delegate_|). If |!is_active_| the messages are queued to be
76   // sent as soon as the PostMessageSupport becomes active.
77   void PostJavaScriptMessage(v8::Isolate* isolate,
78                              v8::Local<v8::Value> message);
79   void PostMessageFromValue(const base::Value& message);
80 
81   // Activates the PostMessageSupport. After calling this method all the
82   // messages in |message_queue_| are forwarded to the target frame.
83   void SetActive();
is_active()84   bool is_active() const { return is_active_; }
85 
86  private:
87   PostMessageSupport(const PostMessageSupport&) = delete;
88   PostMessageSupport& operator=(const PostMessageSupport&) = delete;
89 
90   // The scriptable object that backs the plugin.
91   v8::Global<v8::Object> scriptable_object_;
92 
93   // Pending postMessage messages that need to be sent to the guest. These are
94   // queued while the guest is loading and once it is fully loaded they are
95   // delivered so that messages aren't lost.
96   std::vector<v8::Global<v8::Value>> pending_messages_;
97 
98   // When false, all sent messages are queued up in |message_queue_|. When true,
99   // the messages are forwarded to the target frame.
100   bool is_active_ = false;
101 
102   Delegate* const delegate_;
103 
104   base::WeakPtrFactory<PostMessageSupport> weak_factory_{this};
105 };
106 
107 }  // namespace extensions
108 
109 #endif  // EXTENSIONS_RENDERER_GUEST_VIEW_MIME_HANDLER_VIEW_POST_MESSAGE_SUPPORT_H_
110