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