You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
7.7 KiB
213 lines
7.7 KiB
/*
|
|
* Copyright (C) 2006 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef ANDROID_USB_API_ADB_OBJECT_HANDLE_H__
|
|
#define ANDROID_USB_API_ADB_OBJECT_HANDLE_H__
|
|
/** \file
|
|
This file consists of declaration of a class AdbObjectHandle that
|
|
encapsulates an internal API object that is visible to the outside
|
|
of the API through a handle.
|
|
*/
|
|
|
|
#include "adb_api.h"
|
|
#include "adb_api_private_defines.h"
|
|
|
|
/** \brief Defines types of internal API objects
|
|
*/
|
|
enum AdbObjectType {
|
|
/// Object is AdbInterfaceEnumObject.
|
|
AdbObjectTypeInterfaceEnumerator,
|
|
|
|
/// Object is AdbInterfaceObject.
|
|
AdbObjectTypeInterface,
|
|
|
|
/// Object is AdbEndpointObject.
|
|
AdbObjectTypeEndpoint,
|
|
|
|
/// Object is AdbIOCompletion.
|
|
AdbObjectTypeIoCompletion,
|
|
|
|
AdbObjectTypeMax
|
|
};
|
|
|
|
/** \brief Encapsulates an internal API basic object that is visible to the
|
|
outside of the API through a handle.
|
|
|
|
In order to prevent crashes when API client tries to access an object through
|
|
an invalid or already closed handle, we keep track of all opened handles in
|
|
AdbObjectHandleMap that maps association between valid ADBAPIHANDLE and
|
|
an object that this handle represents. All objects that are exposed to the
|
|
outside of API via ADBAPIHANDLE are self-destructing referenced objects.
|
|
The reference model for these objects is as such:
|
|
1. When CreateHandle() method is called on an object, a handle (ADBAPIHANDLE
|
|
that is) is assigned to it, a pair <handle, object> is added to the global
|
|
AdbObjectHandleMap instance, object is referenced and then handle is
|
|
returned to the API client.
|
|
2. Every time API is called with a handle, a lookup is performed in
|
|
AdbObjectHandleMap to find an object that is associated with the handle.
|
|
If object is not found then ERROR_INVALID_HANDLE is immediatelly returned
|
|
(via SetLastError() call). If object is found then it is referenced and
|
|
API call is dispatched to appropriate method of the found object. Upon
|
|
return from this method, just before returning from the API call, object
|
|
is dereferenced back to match lookup reference.
|
|
3. When object handle gets closed, assuming object is found in the map, that
|
|
<handle, object> pair is deleted from the map and object's refcount is
|
|
decremented to match refcount increment performed when object has been
|
|
added to the map.
|
|
4. When object's refcount drops to zero, the object commits suicide by
|
|
calling "delete this".
|
|
All API objects that have handles that are sent back to API client must be
|
|
derived from this class.
|
|
*/
|
|
class ADBWIN_API_CLASS AdbObjectHandle {
|
|
public:
|
|
/** \brief Constructs the object
|
|
|
|
Refernce counter is set to 1 in the constructor.
|
|
@param[in] obj_type Object type from AdbObjectType enum
|
|
*/
|
|
explicit AdbObjectHandle(AdbObjectType obj_type);
|
|
|
|
protected:
|
|
/** \brief Destructs the object.
|
|
|
|
We hide destructor in order to prevent ourseves from accidentaly allocating
|
|
instances on the stack. If such attempt occurs, compiler will error.
|
|
*/
|
|
virtual ~AdbObjectHandle();
|
|
|
|
public:
|
|
/** \brief References the object.
|
|
|
|
@return Value of the reference counter after object is referenced in this
|
|
method.
|
|
*/
|
|
virtual LONG AddRef();
|
|
|
|
/** \brief Releases the object.
|
|
|
|
If refcount drops to zero as the result of this release, the object is
|
|
destroyed in this method. As a general rule, objects must not be touched
|
|
after this method returns even if returned value is not zero.
|
|
@return Value of the reference counter after object is released in this
|
|
method.
|
|
*/
|
|
virtual LONG Release();
|
|
|
|
/** \brief Creates handle to this object.
|
|
|
|
In this call a handle for this object is generated and object is added
|
|
to the AdbObjectHandleMap.
|
|
@return A handle to this object on success or NULL on an error.
|
|
If NULL is returned GetLastError() provides extended error
|
|
information. ERROR_GEN_FAILURE is set if an attempt was
|
|
made to create already opened object.
|
|
*/
|
|
virtual ADBAPIHANDLE CreateHandle();
|
|
|
|
/** \brief This method is called when handle to this object gets closed.
|
|
|
|
In this call object is deleted from the AdbObjectHandleMap.
|
|
@return true on success or false if object is already closed. If
|
|
false is returned GetLastError() provides extended error
|
|
information.
|
|
*/
|
|
virtual bool CloseHandle();
|
|
|
|
/** \brief Checks if this object is of the given type.
|
|
|
|
@param[in] obj_type One of the AdbObjectType types to check
|
|
@return true is this object type matches obj_type, or false otherwise.
|
|
*/
|
|
virtual bool IsObjectOfType(AdbObjectType obj_type) const;
|
|
|
|
/** \brief Looks up AdbObjectHandle instance associated with the given handle
|
|
in the AdbObjectHandleMap.
|
|
|
|
This method increments reference counter for the returned found object.
|
|
@param[in] adb_handle ADB handle to the object
|
|
@return API object associated with the handle or NULL if object is not
|
|
found. If NULL is returned GetLastError() provides extended error
|
|
information.
|
|
*/
|
|
static AdbObjectHandle* Lookup(ADBAPIHANDLE adb_handle);
|
|
|
|
protected:
|
|
/** \brief Called when last reference to this object is released.
|
|
|
|
Derived object should override this method to perform cleanup that is not
|
|
suitable for destructors.
|
|
*/
|
|
virtual void LastReferenceReleased();
|
|
|
|
public:
|
|
/// Gets ADB handle associated with this object
|
|
ADBAPIHANDLE adb_handle() const {
|
|
return adb_handle_;
|
|
}
|
|
|
|
/// Gets type of this object
|
|
AdbObjectType object_type() const {
|
|
return object_type_;
|
|
}
|
|
|
|
/// Checks if object is still opened. Note that it is not guaranteed that
|
|
/// object remains opened when this method returns.
|
|
bool IsOpened() const {
|
|
return (NULL != adb_handle());
|
|
}
|
|
|
|
protected:
|
|
/// API handle associated with this object
|
|
ADBAPIHANDLE adb_handle_;
|
|
|
|
/// Type of this object
|
|
AdbObjectType object_type_;
|
|
|
|
/// This object's reference counter
|
|
LONG ref_count_;
|
|
};
|
|
|
|
/// Maps ADBAPIHANDLE to associated AdbObjectHandle object
|
|
typedef std::map< ADBAPIHANDLE, AdbObjectHandle* > AdbObjectHandleMap;
|
|
|
|
/** \brief Template routine that unifies extracting of objects of different
|
|
types from the AdbObjectHandleMap
|
|
|
|
@param[in] adb_handle API handle for the object
|
|
@return Object associated with the handle or NULL on error. If NULL is
|
|
returned GetLastError() provides extended error information.
|
|
*/
|
|
template<class obj_class>
|
|
obj_class* LookupObject(ADBAPIHANDLE adb_handle) {
|
|
// Lookup object for the handle in the map
|
|
AdbObjectHandle* adb_object = AdbObjectHandle::Lookup(adb_handle);
|
|
if (NULL != adb_object) {
|
|
// Make sure it's of the correct type
|
|
if (!adb_object->IsObjectOfType(obj_class::Type())) {
|
|
adb_object->Release();
|
|
adb_object = NULL;
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
}
|
|
} else {
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
}
|
|
return (adb_object != NULL) ? reinterpret_cast<obj_class*>(adb_object) :
|
|
NULL;
|
|
}
|
|
|
|
#endif // ANDROID_USB_API_ADB_OBJECT_HANDLE_H__
|