| // Copyright 2015 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef EXTENSIONS_RENDERER_WAKE_EVENT_PAGE_H_ | 
 | #define EXTENSIONS_RENDERER_WAKE_EVENT_PAGE_H_ | 
 |  | 
 | #include <memory> | 
 | #include <string> | 
 | #include <unordered_map> | 
 |  | 
 | #include "base/callback.h" | 
 | #include "base/macros.h" | 
 | #include "base/memory/ref_counted.h" | 
 | #include "base/memory/weak_ptr.h" | 
 | #include "base/synchronization/lock.h" | 
 | #include "content/public/renderer/render_thread_observer.h" | 
 | #include "ipc/ipc_sync_message_filter.h" | 
 | #include "v8/include/v8.h" | 
 |  | 
 | namespace content { | 
 | class RenderThread; | 
 | } | 
 |  | 
 | namespace extensions { | 
 | class ScriptContext; | 
 |  | 
 | // This class implements the wake-event-page JavaScript function, which wakes | 
 | // an event page and runs a callback when done. | 
 | // | 
 | // Note, the function will do a round trip to the browser even if event page is | 
 | // open. Any optimisation to prevent this must be at the JavaScript level. | 
 | class WakeEventPage : public content::RenderThreadObserver { | 
 |  public: | 
 |   WakeEventPage(); | 
 |   ~WakeEventPage() override; | 
 |  | 
 |   // Returns the single instance of the WakeEventPage object. | 
 |   // | 
 |   // Thread safe. | 
 |   static WakeEventPage* Get(); | 
 |  | 
 |   // Initializes the WakeEventPage. | 
 |   // | 
 |   // This must be called before any bindings are installed, and must be called | 
 |   // on the render thread. | 
 |   void Init(content::RenderThread* render_thread); | 
 |  | 
 |   // Returns the wake-event-page function bound to a given context. The | 
 |   // function will be cached as a hidden value in the context's global object. | 
 |   // | 
 |   // To mix C++ and JavaScript, example usage might be: | 
 |   // | 
 |   // WakeEventPage::Get().GetForContext(context)(function() { | 
 |   //   ... | 
 |   // }); | 
 |   // | 
 |   // Thread safe. | 
 |   v8::Local<v8::Function> GetForContext(ScriptContext* context); | 
 |  | 
 |  private: | 
 |   class WakeEventPageNativeHandler; | 
 |  | 
 |   // The response from an ExtensionHostMsg_WakeEvent call, passed true if the | 
 |   // call was successful, false on failure. | 
 |   using OnResponseCallback = base::Callback<void(bool)>; | 
 |  | 
 |   // Makes an ExtensionHostMsg_WakeEvent request for an extension ID. The | 
 |   // second argument is a callback to run when the request has completed. | 
 |   using MakeRequestCallback = | 
 |       base::Callback<void(const std::string&, const OnResponseCallback&)>; | 
 |  | 
 |   // For |requests_|. | 
 |   struct RequestData { | 
 |     RequestData(int thread_id, const OnResponseCallback& on_response); | 
 |     ~RequestData(); | 
 |  | 
 |     // The thread ID the request was made on. |on_response| must be called on | 
 |     // that thread. | 
 |     int thread_id; | 
 |  | 
 |     // Callback to run when the response to the request arrives. | 
 |     OnResponseCallback on_response; | 
 |   }; | 
 |  | 
 |   // Runs |on_response|, passing it |success|. | 
 |   static void RunOnResponseWithResult(const OnResponseCallback& on_response, | 
 |                                       bool success); | 
 |  | 
 |   // Sends the ExtensionHostMsg_WakeEvent IPC for |extension_id|, and | 
 |   // updates |requests_| bookkeeping. | 
 |   void MakeRequest(const std::string& extension_id, | 
 |                    const OnResponseCallback& on_response); | 
 |  | 
 |   // content::RenderThreadObserver: | 
 |   bool OnControlMessageReceived(const IPC::Message& message) override; | 
 |  | 
 |   // OnControlMessageReceived handlers: | 
 |   void OnWakeEventPageResponse(int request_id, bool success); | 
 |  | 
 |   // IPC sender. Belongs to the render thread, but thread safe. | 
 |   scoped_refptr<IPC::SyncMessageFilter> message_filter_; | 
 |  | 
 |   // All in-flight requests, keyed by request ID. Used on multiple threads, so | 
 |   // must be guarded by |requests_lock_|. | 
 |   std::unordered_map<int, std::unique_ptr<RequestData>> requests_; | 
 |  | 
 |   // Lock for |requests_|. | 
 |   base::Lock requests_lock_; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(WakeEventPage); | 
 | }; | 
 |  | 
 | }  //  namespace extensions | 
 |  | 
 | #endif  // EXTENSIONS_RENDERER_WAKE_EVENT_PAGE_H_ |