| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ | 5 #ifndef PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ |
| 6 #define PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ | 6 #define PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ |
| 7 | 7 |
| 8 #include <map> | 8 #include <map> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 13 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
| 14 #include "ppapi/c/pp_stdint.h" | 14 #include "ppapi/c/pp_stdint.h" |
| 15 #include "ppapi/c/pp_var.h" | 15 #include "ppapi/c/pp_var.h" |
| 16 #include "ppapi/proxy/ppapi_proxy_export.h" | 16 #include "ppapi/proxy/ppapi_proxy_export.h" |
| 17 #include "ppapi/shared_impl/var_tracker.h" | 17 #include "ppapi/shared_impl/var_tracker.h" |
| 18 | 18 |
| 19 template<typename T> struct DefaultSingletonTraits; | 19 template<typename T> struct DefaultSingletonTraits; |
| 20 struct PPP_Class_Deprecated; |
| 20 | 21 |
| 21 namespace ppapi { | 22 namespace ppapi { |
| 22 | 23 |
| 23 class ProxyObjectVar; | 24 class ProxyObjectVar; |
| 24 | 25 |
| 25 namespace proxy { | 26 namespace proxy { |
| 26 | 27 |
| 27 class PluginDispatcher; | 28 class PluginDispatcher; |
| 28 | 29 |
| 29 // Tracks live strings and objects in the plugin process. | 30 // Tracks live strings and objects in the plugin process. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 49 PP_Var GetHostObject(const PP_Var& plugin_object) const; | 50 PP_Var GetHostObject(const PP_Var& plugin_object) const; |
| 50 | 51 |
| 51 PluginDispatcher* DispatcherForPluginObject( | 52 PluginDispatcher* DispatcherForPluginObject( |
| 52 const PP_Var& plugin_object) const; | 53 const PP_Var& plugin_object) const; |
| 53 | 54 |
| 54 // Like Release() but the var is identified by its host object ID (as | 55 // Like Release() but the var is identified by its host object ID (as |
| 55 // returned by GetHostObject). | 56 // returned by GetHostObject). |
| 56 void ReleaseHostObject(PluginDispatcher* dispatcher, | 57 void ReleaseHostObject(PluginDispatcher* dispatcher, |
| 57 const PP_Var& host_object); | 58 const PP_Var& host_object); |
| 58 | 59 |
| 60 // VarTracker public overrides. |
| 61 void DidDeleteInstance(PP_Instance instance) OVERRIDE; |
| 62 |
| 63 // Notification that a plugin-implemented object (PPP_Class) was created by |
| 64 // the plugin or deallocated by WebKit over IPC. |
| 65 void PluginImplementedObjectCreated(PP_Instance instance, |
| 66 const PP_Var& created_var, |
| 67 const PPP_Class_Deprecated* ppp_class, |
| 68 void* ppp_class_data); |
| 69 void PluginImplementedObjectDestroyed(void* ppp_class_data); |
| 70 |
| 71 // Returns true if there is an object implemented by the plugin with the |
| 72 // given user_data that has not been deallocated yet. Call this when |
| 73 // receiving a scripting call to the plugin to validate that the object |
| 74 // receiving the call is still alive (see user_data_to_plugin_ below). |
| 75 bool IsPluginImplementedObjectAlive(void* user_data); |
| 76 |
| 77 // Validates that the given class/user_data pair corresponds to a currently |
| 78 // living plugin object. |
| 79 bool ValidatePluginObjectCall(const PPP_Class_Deprecated* ppp_class, |
| 80 void* user_data); |
| 81 |
| 59 private: | 82 private: |
| 60 // VarTracker protected overrides. | 83 // VarTracker protected overrides. |
| 61 virtual int32 AddVarInternal(Var* var, AddVarRefMode mode) OVERRIDE; | 84 virtual int32 AddVarInternal(Var* var, AddVarRefMode mode) OVERRIDE; |
| 62 virtual void TrackedObjectGettingOneRef(VarMap::const_iterator iter) OVERRIDE; | 85 virtual void TrackedObjectGettingOneRef(VarMap::const_iterator iter) OVERRIDE; |
| 63 virtual void ObjectGettingZeroRef(VarMap::iterator iter) OVERRIDE; | 86 virtual void ObjectGettingZeroRef(VarMap::iterator iter) OVERRIDE; |
| 64 virtual bool DeleteObjectInfoIfNecessary(VarMap::iterator iter) OVERRIDE; | 87 virtual bool DeleteObjectInfoIfNecessary(VarMap::iterator iter) OVERRIDE; |
| 65 virtual ArrayBufferVar* CreateArrayBuffer(uint32 size_in_bytes) OVERRIDE; | 88 virtual ArrayBufferVar* CreateArrayBuffer(uint32 size_in_bytes) OVERRIDE; |
| 66 | 89 |
| 67 private: | 90 private: |
| 68 friend struct DefaultSingletonTraits<PluginVarTracker>; | 91 friend struct DefaultSingletonTraits<PluginVarTracker>; |
| 69 friend class PluginProxyTestHarness; | 92 friend class PluginProxyTestHarness; |
| 70 | 93 |
| 71 // Represents a var as received from the host. | 94 // Represents a var as received from the host. |
| 72 struct HostVar { | 95 struct HostVar { |
| 73 HostVar(PluginDispatcher* d, int32 i); | 96 HostVar(PluginDispatcher* d, int32 i); |
| 74 | 97 |
| 75 bool operator<(const HostVar& other) const; | 98 bool operator<(const HostVar& other) const; |
| 76 | 99 |
| 77 // The dispatcher that sent us this object. This is used so we know how to | 100 // The dispatcher that sent us this object. This is used so we know how to |
| 78 // send back requests on this object. | 101 // send back requests on this object. |
| 79 PluginDispatcher* dispatcher; | 102 PluginDispatcher* dispatcher; |
| 80 | 103 |
| 81 // The object ID that the host generated to identify the object. This is | 104 // The object ID that the host generated to identify the object. This is |
| 82 // unique only within that host: different hosts could give us different | 105 // unique only within that host: different hosts could give us different |
| 83 // objects with the same ID. | 106 // objects with the same ID. |
| 84 int32 host_object_id; | 107 int32 host_object_id; |
| 85 }; | 108 }; |
| 86 | 109 |
| 110 struct PluginImplementedVar { |
| 111 const PPP_Class_Deprecated* ppp_class; |
| 112 |
| 113 // The instance that created this Var. This will be 0 if the instance has |
| 114 // been destroyed but the object is still alive. |
| 115 PP_Instance instance; |
| 116 |
| 117 // Represents the plugin var ID for the var corresponding to this object. |
| 118 // If the plugin does not have a ref to the object but it's still alive |
| 119 // (the DOM could be holding a ref keeping it alive) this will be 0. |
| 120 // |
| 121 // There is an obscure corner case. If the plugin returns an object to the |
| 122 // renderer and releases all of its refs, the object will still be alive |
| 123 // but there will be no plugin refs. It's possible for the plugin to get |
| 124 // this same object again through the DOM, and we'll lose the correlation |
| 125 // between plugin implemented object and car. This means we won't know when |
| 126 // the plugin releases its last refs and may call Deallocate when the |
| 127 // plugin is still holding a ref. |
| 128 // |
| 129 // However, for the plugin to be depending on holding a ref to an object |
| 130 // that it implements that it previously released but got again through |
| 131 // indirect means would be extremely rare, and we only allow var scripting |
| 132 // in limited cases anyway. |
| 133 int32 plugin_object_id; |
| 134 }; |
| 135 |
| 87 // Returns the existing var ID for the given object var, creating and | 136 // Returns the existing var ID for the given object var, creating and |
| 88 // assigning an ID to it if necessary. This does not affect the reference | 137 // assigning an ID to it if necessary. This does not affect the reference |
| 89 // count, so in the creation case the refcount will be 0. It's assumed in | 138 // count, so in the creation case the refcount will be 0. It's assumed in |
| 90 // this case the caller will either adjust the refcount or the | 139 // this case the caller will either adjust the refcount or the |
| 91 // track_with_no_reference_count. | 140 // track_with_no_reference_count. |
| 92 PP_Var GetOrCreateObjectVarID(ProxyObjectVar* object); | 141 PP_Var GetOrCreateObjectVarID(ProxyObjectVar* object); |
| 93 | 142 |
| 94 // Sends an addref or release message to the browser for the given object ID. | 143 // Sends an addref or release message to the browser for the given object ID. |
| 95 void SendAddRefObjectMsg(const ProxyObjectVar& proxy_object); | 144 void SendAddRefObjectMsg(const ProxyObjectVar& proxy_object); |
| 96 void SendReleaseObjectMsg(const ProxyObjectVar& proxy_object); | 145 void SendReleaseObjectMsg(const ProxyObjectVar& proxy_object); |
| 97 | 146 |
| 98 // Looks up the given host var. If we already know about it, returns a | 147 // Looks up the given host var. If we already know about it, returns a |
| 99 // reference to the already-tracked object. If it doesn't creates a new one | 148 // reference to the already-tracked object. If it doesn't creates a new one |
| 100 // and returns it. If it's created, it's not added to the map. | 149 // and returns it. If it's created, it's not added to the map. |
| 101 scoped_refptr<ProxyObjectVar> FindOrMakePluginVarFromHostVar( | 150 scoped_refptr<ProxyObjectVar> FindOrMakePluginVarFromHostVar( |
| 102 const PP_Var& var, | 151 const PP_Var& var, |
| 103 PluginDispatcher* dispatcher); | 152 PluginDispatcher* dispatcher); |
| 104 | 153 |
| 105 // Maps host vars in the host to IDs in the plugin process. | 154 // Maps host vars in the host to IDs in the plugin process. |
| 106 typedef std::map<HostVar, int32> HostVarToPluginVarMap; | 155 typedef std::map<HostVar, int32> HostVarToPluginVarMap; |
| 107 HostVarToPluginVarMap host_var_to_plugin_var_; | 156 HostVarToPluginVarMap host_var_to_plugin_var_; |
| 108 | 157 |
| 158 // Maps "user data" for plugin implemented objects (PPP_Class) that are |
| 159 // alive to various tracking info. |
| 160 // |
| 161 // This is tricky because there may not actually be any vars in the plugin |
| 162 // associated with a plugin-implemented object, so they won't all have |
| 163 // entries in our HostVarToPluginVarMap or the base class VarTracker's map. |
| 164 // |
| 165 // All objects that the plugin has created using CreateObject that have not |
| 166 // yet been Deallocate()-ed by WebKit will be in this map. When the instance |
| 167 // that created the object goes away, we know to call Deallocate on all |
| 168 // remaining objects for that instance so that the data backing the object |
| 169 // that the plugin owns is not leaked. We may not receive normal Deallocate |
| 170 // calls from WebKit because the object could be leaked (attached to the DOM |
| 171 // and outliving the plugin instance) or WebKit could send the deallocate |
| 172 // after the out-of-process routing for that instance was torn down. |
| 173 // |
| 174 // There is an additional complexity. In WebKit, objects created by the |
| 175 // plugin aren't actually bound to the plugin instance (for example, you |
| 176 // could attach it to the DOM or send it to another plugin instance). It's |
| 177 // possible that we could force deallocate an object when an instance id |
| 178 // destroyed, but then another instance could get to that object somehow |
| 179 // (like by reading it out of the DOM). We will then have deallocated the |
| 180 // object and can't complete the call. We do not care about this case, and |
| 181 // the calls will just fail. |
| 182 typedef std::map<void*, PluginImplementedVar> |
| 183 UserDataToPluginImplementedVarMap; |
| 184 UserDataToPluginImplementedVarMap user_data_to_plugin_; |
| 185 |
| 109 DISALLOW_COPY_AND_ASSIGN(PluginVarTracker); | 186 DISALLOW_COPY_AND_ASSIGN(PluginVarTracker); |
| 110 }; | 187 }; |
| 111 | 188 |
| 112 } // namespace proxy | 189 } // namespace proxy |
| 113 } // namespace ppapi | 190 } // namespace ppapi |
| 114 | 191 |
| 115 #endif // PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ | 192 #endif // PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ |
| OLD | NEW |