| Index: extensions/browser/extension_api_frame_id_map.h
|
| diff --git a/extensions/browser/extension_api_frame_id_map.h b/extensions/browser/extension_api_frame_id_map.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..176099b48195223adc944dbeb99b1fc8ae25cd9a
|
| --- /dev/null
|
| +++ b/extensions/browser/extension_api_frame_id_map.h
|
| @@ -0,0 +1,134 @@
|
| +// 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_BROWSER_EXTENSION_API_FRAME_ID_MAP_H_
|
| +#define EXTENSIONS_BROWSER_EXTENSION_API_FRAME_ID_MAP_H_
|
| +
|
| +#include <list>
|
| +#include <map>
|
| +
|
| +#include "base/callback.h"
|
| +#include "base/gtest_prod_util.h"
|
| +#include "base/lazy_instance.h"
|
| +#include "base/synchronization/lock.h"
|
| +
|
| +namespace content {
|
| +class RenderFrameHost;
|
| +class WebContents;
|
| +} // namespace content
|
| +
|
| +namespace extensions {
|
| +
|
| +// Extension frame IDs are exposed through the chrome.* APIs and have the
|
| +// following characteristics:
|
| +// - The top-level frame has ID 0.
|
| +// - Any child frame has a positive ID.
|
| +// - A non-existant frame has ID -1.
|
| +// - They are only guaranteed to be unique within a tab.
|
| +// - The ID does not change during the frame's lifetime and is not re-used after
|
| +// the frame is removed. The frame may change its current RenderFrameHost over
|
| +// time, so multiple RenderFrameHosts may map to the same extension frame ID.
|
| +struct ExtensionApiFrameId {
|
| + static const int kInvalidFrameId = -1;
|
| +
|
| + ExtensionApiFrameId();
|
| + ExtensionApiFrameId(int frame_id, int parent_frame_id);
|
| +
|
| + bool operator==(const ExtensionApiFrameId& other) const {
|
| + return frame_id == other.frame_id &&
|
| + parent_frame_id == other.parent_frame_id;
|
| + }
|
| +
|
| + // The name "ExtensionApiFrameId" refers to |frame_id|.
|
| + int frame_id;
|
| +
|
| + // The extension frame ID of the parent frame ID is also included because
|
| + // some extension APIs need both IDs.
|
| + int parent_frame_id;
|
| +};
|
| +
|
| +// This class provides a mapping from a (render_process_id, frame_routing_id)
|
| +// pair that maps a RenderFrameHost to an extension frame ID.
|
| +// Unless stated otherwise, the methods can only be called on the UI thread.
|
| +class ExtensionApiFrameIdMap {
|
| + public:
|
| + using FrameIdCallback = base::Callback<void(const ExtensionApiFrameId&)>;
|
| +
|
| + static ExtensionApiFrameIdMap* Get();
|
| +
|
| + // Runs |callback| with the result that is equivalent to calling GetFrameId()
|
| + // on the UI thread. If the result was cached the callback is immediately run.
|
| + // Otherwise the callback is queued and run in order when the result becomes
|
| + // available. Queued callbacks are not called when the class is destroyed.
|
| + void GetFrameIdOnIO(int render_process_id,
|
| + int frame_routing_id,
|
| + const FrameIdCallback& callback);
|
| +
|
| + // Get the frameId for a RenderFrameHost identified by |render_process_id| and
|
| + // |frame_routing_id|. These methods always returns the same value when called
|
| + // with the same parameters.
|
| + const ExtensionApiFrameId& GetFrameId(int render_process_id,
|
| + int frame_routing_id);
|
| + const ExtensionApiFrameId& GetFrameId(content::RenderFrameHost* rfh);
|
| +
|
| + // Find the current RenderFrameHost for a given WebContents and extension
|
| + // frame ID.
|
| + // Returns nullptr if not found.
|
| + content::RenderFrameHost* GetRenderFrameHostById(
|
| + content::WebContents* web_contents,
|
| + int frame_id);
|
| +
|
| + protected:
|
| + friend struct base::DefaultLazyInstanceTraits<ExtensionApiFrameIdMap>;
|
| + FRIEND_TEST_ALL_PREFIXES(ExtensionApiFrameIdMapTest, Basic);
|
| + FRIEND_TEST_ALL_PREFIXES(ExtensionApiFrameIdMapTest, GetFrameIdOnIO);
|
| +
|
| + // A set of identifiers that uniquely identifies a RenderFrame.
|
| + struct RenderFrameIdKey {
|
| + RenderFrameIdKey();
|
| + RenderFrameIdKey(int render_process_id, int frame_routing_id);
|
| +
|
| + // The process ID of the renderer that contains the RenderFrame.
|
| + int render_process_id;
|
| + // The routing ID of the RenderFrame.
|
| + int frame_routing_id;
|
| +
|
| + bool operator<(const RenderFrameIdKey& other) const;
|
| + };
|
| +
|
| + // This is a std::list so that iterators are not invalidated when the list is
|
| + // modified during an iteration.
|
| + using FrameIdCallbackList = std::list<FrameIdCallback>;
|
| + using FrameIdMap = std::map<RenderFrameIdKey, ExtensionApiFrameId>;
|
| + using CallbackMap = std::map<RenderFrameIdKey, FrameIdCallbackList>;
|
| +
|
| + ExtensionApiFrameIdMap();
|
| + ~ExtensionApiFrameIdMap();
|
| +
|
| + // Determines the value to be stored in |frame_id_map_| for a given key.
|
| + // virtual for testing.
|
| + virtual ExtensionApiFrameId KeyToValue(const RenderFrameIdKey& key) const;
|
| +
|
| + const ExtensionApiFrameId& LookupFrameIdOnUI(const RenderFrameIdKey& key);
|
| + void GotFrameIdOnIO(const RenderFrameIdKey& key);
|
| +
|
| + // Queued callbacks for use on the IO thread. This queue is only used when the
|
| + // frameId needs to be fetched from the UI thread.
|
| + CallbackMap callbacks_map_;
|
| +
|
| + // This frameId map is only modified on the UI thread and used for 2 purposes:
|
| + // - On the IO thread, it avoids unnecessary thread hops.
|
| + // - On the UI thread and the IO thread, it ensures that the frameId remains
|
| + // constant, even after removing a frame.
|
| + // Items are never removed from this map.
|
| + FrameIdMap frame_id_map_;
|
| +
|
| + // This lock protects |frame_id_map| from being concurrently written on the UI
|
| + // thread and read on the IO thread.
|
| + base::Lock frame_id_map_lock_;
|
| +};
|
| +
|
| +} // namespace extensions
|
| +
|
| +#endif // EXTENSIONS_BROWSER_EXTENSION_API_FRAME_ID_MAP_H_
|
|
|