1 // Copyright 2015 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 CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BRIDGE_MESSAGE_FILTER_H_
6 #define CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BRIDGE_MESSAGE_FILTER_H_
7 
8 #include <stdint.h>
9 
10 #include <map>
11 #include <set>
12 
13 #include "base/memory/ref_counted.h"
14 #include "base/synchronization/lock.h"
15 #include "base/thread_annotations.h"
16 #include "content/browser/android/java/gin_java_bound_object.h"
17 #include "content/common/android/gin_java_bridge_errors.h"
18 #include "content/public/browser/browser_message_filter.h"
19 #include "content/public/browser/render_process_host_observer.h"
20 
21 namespace base {
22 class ListValue;
23 }
24 
25 namespace IPC {
26 class Message;
27 }
28 
29 namespace content {
30 
31 class GinJavaBridgeDispatcherHost;
32 class RenderFrameHost;
33 
34 class GinJavaBridgeMessageFilter : public BrowserMessageFilter,
35                                    public RenderProcessHostObserver {
36  public:
37   // BrowserMessageFilter
38   void OnDestruct() const override;
39   bool OnMessageReceived(const IPC::Message& message) override;
40   scoped_refptr<base::SequencedTaskRunner> OverrideTaskRunnerForMessage(
41       const IPC::Message& message) override;
42 
43   // RenderProcessHostObserver
44   void RenderProcessExited(RenderProcessHost* rph,
45                            const ChildProcessTerminationInfo& info) override;
46 
47   // Called on the UI thread.
48   void AddRoutingIdForHost(GinJavaBridgeDispatcherHost* host,
49                            RenderFrameHost* render_frame_host);
50   void RemoveHost(GinJavaBridgeDispatcherHost* host);
51 
52   static scoped_refptr<GinJavaBridgeMessageFilter> FromHost(
53       GinJavaBridgeDispatcherHost* host, bool create_if_not_exists);
54 
55  private:
56   friend class BrowserThread;
57   friend class base::DeleteHelper<GinJavaBridgeMessageFilter>;
58 
59   // The filter keeps its own routing map of RenderFrames for two reasons:
60   //  1. Message dispatching must be done on the background thread,
61   //     without resorting to the UI thread, which can be in fact currently
62   //     blocked, waiting for an event from an injected Java object.
63   //  2. As RenderFrames pass away earlier than JavaScript wrappers,
64   //     messages from the latter can arrive after the RenderFrame has been
65   //     removed from the WebContents' routing table.
66   typedef std::map<int32_t, scoped_refptr<GinJavaBridgeDispatcherHost>> HostMap;
67 
68   GinJavaBridgeMessageFilter();
69   ~GinJavaBridgeMessageFilter() override;
70 
71   // Called on the background thread.
72   scoped_refptr<GinJavaBridgeDispatcherHost> FindHost();
73   void OnGetMethods(GinJavaBoundObject::ObjectID object_id,
74                     std::set<std::string>* returned_method_names);
75   void OnHasMethod(GinJavaBoundObject::ObjectID object_id,
76                    const std::string& method_name,
77                    bool* result);
78   void OnInvokeMethod(GinJavaBoundObject::ObjectID object_id,
79                       const std::string& method_name,
80                       const base::ListValue& arguments,
81                       base::ListValue* result,
82                       content::GinJavaBridgeError* error_code);
83   void OnObjectWrapperDeleted(GinJavaBoundObject::ObjectID object_id);
84 
85   // Accessed both from UI and background threads.
86   HostMap hosts_ GUARDED_BY(hosts_lock_);
87   base::Lock hosts_lock_;
88 
89   // The routing id of the RenderFrameHost whose request we are processing.
90   // Used on the background thread.
91   int32_t current_routing_id_;
92 };
93 
94 }  // namespace content
95 
96 #endif  // CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BRIDGE_MESSAGE_FILTER_H_
97