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