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