| 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..fb9687d1883eab42f0ec162b5ae6725e522a7cac
|
| --- /dev/null
|
| +++ b/extensions/browser/extension_api_frame_id_map.h
|
| @@ -0,0 +1,168 @@
|
| +// 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 <deque>
|
| +#include <list>
|
| +#include <map>
|
| +
|
| +#include "base/callback.h"
|
| +#include "base/lazy_instance.h"
|
| +#include "base/synchronization/lock.h"
|
| +
|
| +namespace base {
|
| +class TimeTicks;
|
| +} // namespace base
|
| +
|
| +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. Thread hopping is minimized if possible, and the
|
| + // callbacks are guaranteed to be run in order.
|
| + 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 return 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);
|
| +
|
| + // Remove the frame ID mapping for a given frame. This method can be called at
|
| + // any time, but it is typical to call this method when a frame is destroyed.
|
| + // If this method is not called, the cached mapping for the frame is retained
|
| + // forever.
|
| + void RemoveFrameId(int render_process_id, int frame_routing_id);
|
| + void RemoveFrameId(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>;
|
| +
|
| + // 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;
|
| + bool operator==(const RenderFrameIdKey& other) const;
|
| + };
|
| +
|
| + // A queued callback. After mapping |key| to |value|, |callback| is run with
|
| + // |value|. The fields are only maintained when this struct is a part of the
|
| + // |callbacks_| list.
|
| + struct FrameIdCallbackInfo {
|
| + FrameIdCallbackInfo(const RenderFrameIdKey& key,
|
| + const FrameIdCallback& callback);
|
| + ~FrameIdCallbackInfo();
|
| +
|
| + const RenderFrameIdKey key;
|
| + const FrameIdCallback callback;
|
| + ExtensionApiFrameId value;
|
| + bool has_value;
|
| + };
|
| +
|
| + struct FrameIdRemovalTask {
|
| + FrameIdRemovalTask(const RenderFrameIdKey& key,
|
| + const base::TimeTicks& creation_time);
|
| +
|
| + const RenderFrameIdKey key;
|
| + base::TimeTicks creation_time;
|
| + };
|
| +
|
| + using FrameIdMap = std::map<RenderFrameIdKey, ExtensionApiFrameId>;
|
| +
|
| + ExtensionApiFrameIdMap();
|
| + ~ExtensionApiFrameIdMap();
|
| +
|
| + // Determines the value to be stored in |frame_id_map_| for a given key. This
|
| + // method is only called when |key| is not in |frame_id_map_|.
|
| + // virtual for testing.
|
| + virtual ExtensionApiFrameId KeyToValue(const RenderFrameIdKey& key) const;
|
| +
|
| + ExtensionApiFrameId LookupFrameIdOnUI(const RenderFrameIdKey& key);
|
| + void GotFrameIdOnIO(const RenderFrameIdKey& key,
|
| + const ExtensionApiFrameId& extension_api_frame_id);
|
| +
|
| + // Queued callbacks for use on the IO thread.
|
| + // This is a std::list so that iterators are not invalidated when the list is
|
| + // modified during an iteration.
|
| + std::list<FrameIdCallbackInfo> callbacks_;
|
| +
|
| + // A list of frame IDs that should be deleted soon.
|
| + std::deque<FrameIdRemovalTask> pending_deletions_;
|
| +
|
| + // 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.
|
| + 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_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ExtensionApiFrameIdMap);
|
| +};
|
| +
|
| +} // namespace extensions
|
| +
|
| +#endif // EXTENSIONS_BROWSER_EXTENSION_API_FRAME_ID_MAP_H_
|
|
|