blob: 3542b4237b7ec9766d570a2d8be525131a7ba425 [file] [log] [blame]
kalman12033f122015-08-21 19:30:131// 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 EXTENSIONS_RENDERER_WAKE_EVENT_PAGE_H_
6#define EXTENSIONS_RENDERER_WAKE_EVENT_PAGE_H_
7
dchengf6f80662016-04-20 20:26:048#include <memory>
kalman12033f122015-08-21 19:30:139#include <string>
avi7368a3e2016-12-29 01:26:2810#include <unordered_map>
kalman12033f122015-08-21 19:30:1311
12#include "base/callback.h"
kalman12033f122015-08-21 19:30:1313#include "base/macros.h"
14#include "base/memory/ref_counted.h"
kalman12033f122015-08-21 19:30:1315#include "base/memory/weak_ptr.h"
kalman6f984ae2015-09-18 17:21:5816#include "base/synchronization/lock.h"
tyoshino832a58a2016-04-18 08:14:0817#include "content/public/renderer/render_thread_observer.h"
kalman12033f122015-08-21 19:30:1318#include "ipc/ipc_sync_message_filter.h"
19#include "v8/include/v8.h"
20
21namespace content {
22class RenderThread;
23}
24
25namespace extensions {
26class ScriptContext;
27
28// This class implements the wake-event-page JavaScript function, which wakes
29// an event page and runs a callback when done.
30//
31// Note, the function will do a round trip to the browser even if event page is
32// open. Any optimisation to prevent this must be at the JavaScript level.
tyoshino832a58a2016-04-18 08:14:0833class WakeEventPage : public content::RenderThreadObserver {
kalman12033f122015-08-21 19:30:1334 public:
35 WakeEventPage();
36 ~WakeEventPage() override;
37
38 // Returns the single instance of the WakeEventPage object.
39 //
40 // Thread safe.
41 static WakeEventPage* Get();
42
43 // Initializes the WakeEventPage.
44 //
45 // This must be called before any bindings are installed, and must be called
46 // on the render thread.
47 void Init(content::RenderThread* render_thread);
48
49 // Returns the wake-event-page function bound to a given context. The
50 // function will be cached as a hidden value in the context's global object.
51 //
52 // To mix C++ and JavaScript, example usage might be:
53 //
54 // WakeEventPage::Get().GetForContext(context)(function() {
55 // ...
56 // });
57 //
58 // Thread safe.
59 v8::Local<v8::Function> GetForContext(ScriptContext* context);
60
61 private:
62 class WakeEventPageNativeHandler;
63
64 // The response from an ExtensionHostMsg_WakeEvent call, passed true if the
65 // call was successful, false on failure.
66 using OnResponseCallback = base::Callback<void(bool)>;
67
68 // Makes an ExtensionHostMsg_WakeEvent request for an extension ID. The
69 // second argument is a callback to run when the request has completed.
70 using MakeRequestCallback =
71 base::Callback<void(const std::string&, const OnResponseCallback&)>;
72
73 // For |requests_|.
74 struct RequestData {
kalman6f984ae2015-09-18 17:21:5875 RequestData(int thread_id, const OnResponseCallback& on_response);
kalman12033f122015-08-21 19:30:1376 ~RequestData();
kalman6f984ae2015-09-18 17:21:5877
78 // The thread ID the request was made on. |on_response| must be called on
79 // that thread.
80 int thread_id;
81
82 // Callback to run when the response to the request arrives.
kalman12033f122015-08-21 19:30:1383 OnResponseCallback on_response;
84 };
85
86 // Runs |on_response|, passing it |success|.
87 static void RunOnResponseWithResult(const OnResponseCallback& on_response,
88 bool success);
89
90 // Sends the ExtensionHostMsg_WakeEvent IPC for |extension_id|, and
91 // updates |requests_| bookkeeping.
92 void MakeRequest(const std::string& extension_id,
93 const OnResponseCallback& on_response);
94
tyoshino832a58a2016-04-18 08:14:0895 // content::RenderThreadObserver:
kalman12033f122015-08-21 19:30:1396 bool OnControlMessageReceived(const IPC::Message& message) override;
97
98 // OnControlMessageReceived handlers:
99 void OnWakeEventPageResponse(int request_id, bool success);
100
101 // IPC sender. Belongs to the render thread, but thread safe.
102 scoped_refptr<IPC::SyncMessageFilter> message_filter_;
103
kalman6f984ae2015-09-18 17:21:58104 // All in-flight requests, keyed by request ID. Used on multiple threads, so
105 // must be guarded by |requests_lock_|.
avi7368a3e2016-12-29 01:26:28106 std::unordered_map<int, std::unique_ptr<RequestData>> requests_;
kalman12033f122015-08-21 19:30:13107
kalman6f984ae2015-09-18 17:21:58108 // Lock for |requests_|.
109 base::Lock requests_lock_;
kalman12033f122015-08-21 19:30:13110
111 DISALLOW_COPY_AND_ASSIGN(WakeEventPage);
112};
113
114} // namespace extensions
115
116#endif // EXTENSIONS_RENDERER_WAKE_EVENT_PAGE_H_