summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins/pepper_resource.h
blob: 417a06b96621e6867436cdfa7001ed6603262780 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright (c) 2010 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 WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_H_
#define WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_H_

#include "base/logging.h"
#include "base/basictypes.h"
#include "base/ref_counted.h"
#include "third_party/ppapi/c/pp_resource.h"
#include "webkit/glue/plugins/pepper_resource_tracker.h"

namespace pepper {

class Buffer;
class DeviceContext2D;
class DirectoryReader;
class FileChooser;
class FileIO;
class FileRef;
class Font;
class ImageData;
class PluginModule;
class Scrollbar;
class URLLoader;
class URLRequestInfo;
class URLResponseInfo;
class Widget;

class Resource : public base::RefCountedThreadSafe<Resource> {
 public:
  explicit Resource(PluginModule* module)  : resource_id_(0), module_(module) {}
  virtual ~Resource() {}

  // Returns NULL if the resource is invalid or is a different type.
  template<typename T>
  static scoped_refptr<T> GetAs(PP_Resource res) {
    scoped_refptr<Resource> resource = ResourceTracker::Get()->GetResource(res);
    return resource ? resource->Cast<T>() : NULL;
  }

  PluginModule* module() const { return module_; }

  // Cast the resource into a specified type. This will return NULL if the
  // resource does not match the specified type. Specializations of this
  // template call into As* functions.
  template <typename T> T* Cast() { return NULL; }

  // Returns an resource id of this object. If the object doesn't have a
  // resource id, new one is created with plugin refcount of 1. If it does,
  // the refcount is incremented. Use this when you need to return a new
  // reference to the plugin.
  PP_Resource GetReference();

  // When you need to ensure that a resource has a reference, but you do not
  // want to increase the refcount (for example, if you need to call a plugin
  // callback function with a reference), you can use this class. For example:
  //
  // plugin_callback(.., ScopedResourceId(resource).id, ...);
  class ScopedResourceId {
   public:
    explicit ScopedResourceId(Resource* resource)
        : id(resource->GetReference()) {}
    ~ScopedResourceId() {
      ResourceTracker::Get()->UnrefResource(id);
    }
    const PP_Resource id;
  };

 private:
  // Type-specific getters for individual resource types. These will return
  // NULL if the resource does not match the specified type. Used by the Cast()
  // function.
  virtual Buffer* AsBuffer() { return NULL; }
  virtual DeviceContext2D* AsDeviceContext2D() { return NULL; }
  virtual DirectoryReader* AsDirectoryReader() { return NULL; }
  virtual FileChooser* AsFileChooser() { return NULL; }
  virtual FileIO* AsFileIO() { return NULL; }
  virtual FileRef* AsFileRef() { return NULL; }
  virtual Font* AsFont() { return NULL; }
  virtual ImageData* AsImageData() { return NULL; }
  virtual Scrollbar* AsScrollbar() { return NULL; }
  virtual URLLoader* AsURLLoader() { return NULL; }
  virtual URLRequestInfo* AsURLRequestInfo() { return NULL; }
  virtual URLResponseInfo* AsURLResponseInfo() { return NULL; }
  virtual Widget* AsWidget() { return NULL; }

 private:
  // If referenced by a plugin, holds the id of this resource object. Do not
  // access this member directly, because it is possible that the plugin holds
  // no references to the object, and therefore the resource_id_ is zero. Use
  // either GetReference() to obtain a new resource_id and increase the
  // refcount, or TemporaryReference when you do not want to increase the
  // refcount.
  PP_Resource resource_id_;

  // Non-owning pointer to our module.
  PluginModule* module_;

  // Called by the resource tracker when the last plugin reference has been
  // dropped.
  friend class ResourceTracker;
  void StoppedTracking() {
    DCHECK(resource_id_ != 0);
    resource_id_ = 0;
  }

  DISALLOW_COPY_AND_ASSIGN(Resource);
};

// Cast() specializations.
#define DEFINE_RESOURCE_CAST(Type)                   \
  template <> inline Type* Resource::Cast<Type>() {  \
      return As##Type();                             \
  }

DEFINE_RESOURCE_CAST(Buffer)
DEFINE_RESOURCE_CAST(DeviceContext2D)
DEFINE_RESOURCE_CAST(DirectoryReader)
DEFINE_RESOURCE_CAST(FileChooser)
DEFINE_RESOURCE_CAST(FileIO)
DEFINE_RESOURCE_CAST(FileRef)
DEFINE_RESOURCE_CAST(Font)
DEFINE_RESOURCE_CAST(ImageData)
DEFINE_RESOURCE_CAST(Scrollbar)
DEFINE_RESOURCE_CAST(URLLoader)
DEFINE_RESOURCE_CAST(URLRequestInfo)
DEFINE_RESOURCE_CAST(URLResponseInfo)
DEFINE_RESOURCE_CAST(Widget)

#undef DEFINE_RESOURCE_CAST
}  // namespace pepper

#endif  // WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_H_