OSDN Git Service

Merge change 6506
[android-x86/development.git] / host / windows / usb / api / adb_object_handle.h
1 /*\r
2  * Copyright (C) 2006 The Android Open Source Project\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 #ifndef ANDROID_USB_API_ADB_OBJECT_HANDLE_H__\r
18 #define ANDROID_USB_API_ADB_OBJECT_HANDLE_H__\r
19 /** \file\r
20   This file consists of declaration of a class AdbObjectHandle that\r
21   encapsulates an internal API object that is visible to the outside\r
22   of the API through a handle.\r
23 */\r
24 \r
25 #include "adb_api_private_defines.h"\r
26 \r
27 /** \brief Defines types of internal API objects\r
28 */\r
29 enum AdbObjectType {\r
30   /// Object is AdbInterfaceEnumObject.\r
31   AdbObjectTypeInterfaceEnumerator,\r
32 \r
33   /// Object is AdbInterfaceObject.\r
34   AdbObjectTypeInterface,\r
35 \r
36   /// Object is AdbEndpointObject.\r
37   AdbObjectTypeEndpoint,\r
38 \r
39   /// Object is AdbIOCompletion.\r
40   AdbObjectTypeIoCompletion,\r
41 \r
42   AdbObjectTypeMax\r
43 };\r
44 \r
45 /** \brief Encapsulates an internal API basic object that is visible to the\r
46   outside of the API through a handle.\r
47   \r
48   In order to prevent crashes when API client tries to access an object through\r
49   an invalid or already closed handle, we keep track of all opened handles in\r
50   AdbObjectHandleMap that maps association between valid ADBAPIHANDLE and\r
51   an object that this handle represents. All objects that are exposed to the\r
52   outside of API via ADBAPIHANDLE are self-destructing referenced objects.\r
53   The reference model for these objects is as such:\r
54   1. When CreateHandle() method is called on an object, a handle (ADBAPIHANDLE\r
55      that is) is assigned to it, a pair <handle, object> is added to the global\r
56      AdbObjectHandleMap instance, object is referenced and then handle is\r
57      returned to the API client.\r
58   2. Every time API is called with a handle, a lookup is performed in \r
59      AdbObjectHandleMap to find an object that is associated with the handle.\r
60      If object is not found then ERROR_INVALID_HANDLE is immediatelly returned\r
61      (via SetLastError() call). If object is found then it is referenced and\r
62      API call is dispatched to appropriate method of the found object. Upon\r
63      return from this method, just before returning from the API call, object\r
64      is dereferenced back to match lookup reference.\r
65   3. When object handle gets closed, assuming object is found in the map, that\r
66      <handle, object> pair is deleted from the map and object's refcount is\r
67      decremented to match refcount increment performed when object has been\r
68      added to the map.\r
69   4. When object's refcount drops to zero, the object commits suicide by\r
70      calling "delete this".\r
71   All API objects that have handles that are sent back to API client must be\r
72   derived from this class.\r
73 */\r
74 class AdbObjectHandle {\r
75  public:\r
76   /** \brief Constructs the object\r
77 \r
78     Refernce counter is set to 1 in the constructor.\r
79     @param[in] obj_type Object type from AdbObjectType enum\r
80   */\r
81   explicit AdbObjectHandle(AdbObjectType obj_type);\r
82 \r
83  protected:\r
84   /** \brief Destructs the object.\r
85 \r
86    We hide destructor in order to prevent ourseves from accidentaly allocating\r
87    instances on the stack. If such attempt occurs, compiler will error.\r
88   */\r
89   virtual ~AdbObjectHandle();\r
90 \r
91  public:\r
92   /** \brief References the object.\r
93 \r
94     @return Value of the reference counter after object is referenced in this\r
95             method.\r
96   */\r
97   virtual LONG AddRef();\r
98 \r
99   /** \brief Releases the object.\r
100 \r
101     If refcount drops to zero as the result of this release, the object is\r
102     destroyed in this method. As a general rule, objects must not be touched\r
103     after this method returns even if returned value is not zero.\r
104     @return Value of the reference counter after object is released in this\r
105             method.\r
106   */\r
107   virtual LONG Release();\r
108 \r
109   /** \brief Creates handle to this object.\r
110 \r
111     In this call a handle for this object is generated and object is added\r
112     to the AdbObjectHandleMap.\r
113     @return A handle to this object on success or NULL on an error.\r
114             If NULL is returned GetLastError() provides extended error\r
115             information. ERROR_GEN_FAILURE is set if an attempt was\r
116             made to create already opened object.\r
117   */\r
118   virtual ADBAPIHANDLE CreateHandle();\r
119 \r
120   /** \brief This method is called when handle to this object gets closed.\r
121 \r
122     In this call object is deleted from the AdbObjectHandleMap.\r
123     @return true on success or false if object is already closed. If\r
124             false is returned GetLastError() provides extended error\r
125             information.\r
126   */\r
127   virtual bool CloseHandle();\r
128 \r
129   /** \brief Checks if this object is of the given type.\r
130 \r
131     @param[in] obj_type One of the AdbObjectType types to check\r
132     @return true is this object type matches obj_type, or false otherwise.\r
133   */\r
134   virtual bool IsObjectOfType(AdbObjectType obj_type) const;\r
135 \r
136   /** \brief Looks up AdbObjectHandle instance associated with the given handle\r
137     in the AdbObjectHandleMap.\r
138 \r
139     This method increments reference counter for the returned found object.\r
140     @param[in] adb_handle ADB handle to the object\r
141     @return API object associated with the handle or NULL if object is not\r
142             found. If NULL is returned GetLastError() provides extended error\r
143             information.\r
144   */\r
145   static AdbObjectHandle* Lookup(ADBAPIHANDLE adb_handle);\r
146 \r
147  protected:\r
148   /** \brief Called when last reference to this object is released.\r
149 \r
150     Derived object should override this method to perform cleanup that is not\r
151     suitable for destructors.\r
152   */\r
153   virtual void LastReferenceReleased();\r
154 \r
155  public:\r
156   /// Gets ADB handle associated with this object\r
157   ADBAPIHANDLE adb_handle() const {\r
158     return adb_handle_;\r
159   }\r
160 \r
161   /// Gets type of this object\r
162   AdbObjectType object_type() const {\r
163     return object_type_;\r
164   }\r
165 \r
166   /// Checks if object is still opened. Note that it is not guaranteed that\r
167   /// object remains opened when this method returns.\r
168   bool IsOpened() const {\r
169     return (NULL != adb_handle());\r
170   }\r
171 \r
172  protected:\r
173   /// API handle associated with this object\r
174   ADBAPIHANDLE  adb_handle_;\r
175 \r
176   /// Type of this object\r
177   AdbObjectType object_type_;\r
178 \r
179   /// This object's reference counter\r
180   LONG          ref_count_;\r
181 };\r
182 \r
183 /// Maps ADBAPIHANDLE to associated AdbObjectHandle object\r
184 typedef std::map< ADBAPIHANDLE, AdbObjectHandle* > AdbObjectHandleMap;\r
185 \r
186 /** \brief Template routine that unifies extracting of objects of different\r
187   types from the AdbObjectHandleMap\r
188 \r
189   @param[in] adb_handle API handle for the object\r
190   @return Object associated with the handle or NULL on error. If NULL is\r
191           returned GetLastError() provides extended error information.\r
192 */\r
193 template<class obj_class>\r
194 obj_class* LookupObject(ADBAPIHANDLE adb_handle) {\r
195   // Lookup object for the handle in the map\r
196   AdbObjectHandle* adb_object = AdbObjectHandle::Lookup(adb_handle);\r
197   if (NULL != adb_object) {\r
198     // Make sure it's of the correct type\r
199     if (!adb_object->IsObjectOfType(obj_class::Type())) {\r
200       adb_object->Release();\r
201       adb_object = NULL;\r
202       SetLastError(ERROR_INVALID_HANDLE);\r
203     }\r
204   } else {\r
205     SetLastError(ERROR_INVALID_HANDLE);\r
206   }\r
207   return (adb_object != NULL) ? reinterpret_cast<obj_class*>(adb_object) :\r
208                                 NULL;\r
209 }\r
210 \r
211 #endif  // ANDROID_USB_API_ADB_OBJECT_HANDLE_H__\r