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