Home | History | Annotate | Download | only in api
      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
    158   ADBAPIHANDLE adb_handle() const {
    159     return adb_handle_;
    160   }
    161 
    162   /// Gets type of this object
    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.
    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>
    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