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