usbmgmt/usbmgr/host/fdf/production/server/inc/deviceproxy.h
changeset 0 c9bc50fca66e
child 15 f92a4f87e424
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/inc/deviceproxy.h	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,149 @@
+/*
+* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef DEVICEPROXY_H
+#define DEVICEPROXY_H
+
+#include <e32base.h>
+#include "usbhoststack.h"
+
+#ifdef __OVER_DUMMYUSBDI__
+#include <usbhost/dummyusbdi/d32usbdi_hubdriver.h>
+#else
+#include <d32usbdi_hubdriver.h>
+#endif
+
+class TDeviceEvent;
+class TOtgDescriptor;
+
+NONSHARABLE_CLASS(CDeviceProxy) : public CBase
+	{
+public:
+	/** Link between elements of this type in a TSglQue. */
+	TSglQueLink iLink;
+
+public:
+	static CDeviceProxy* NewL(RUsbHubDriver& aHubDriver, TUint aDeviceId);
+	~CDeviceProxy();
+
+public: // querying information from the device
+	TInt GetDeviceDescriptor(TUsbDeviceDescriptor& aDescriptor);
+	TInt GetConfigurationDescriptor(TUsbConfigurationDescriptor& aDescriptor) const;
+	const RArray<TUint>& GetSupportedLanguages() const;
+	void GetManufacturerStringDescriptorL(TUint32 aLangId, TName& aString) const;
+	void GetProductStringDescriptorL(TUint32 aLangId, TName& aString) const;
+	void GetSerialNumberStringDescriptorL(TUint32 aLangId, TName& aString) const;
+	
+	void GetOtgDescriptorL(TOtgDescriptor& aDescriptor) const;
+	void SetOtgDescriptorL(const TUsbOTGDescriptor& aDescriptor);
+
+public: // management
+	TInt GetTokenForInterface(TUint aIndex, TUint32& aToken) const;
+	TUint DeviceId() const;
+	void SetDriverLoadingEventData(TDriverLoadStatus aStatus, TInt aError = KErrNone);
+	TInt Suspend();
+
+	// These methods TAKE OWNERSHIP of the relevant objects.
+	TDeviceEvent* GetAttachmentEventObject();
+	TDeviceEvent* GetDriverLoadingEventObject();
+	TDeviceEvent* GetDetachmentEventObject();
+	inline void SetMultipleDriversFlag()
+	{
+		iMultipleDriversFound = ETrue;
+	}
+
+	inline TBool MultipleDriversFlag()
+	{
+		return iMultipleDriversFound;
+	}
+	inline void SetHasIADFlag()
+	{
+		iHasIAD = ETrue;
+	}
+	inline TBool HasIADFlag()
+	{
+		return iHasIAD;
+	}
+
+private:
+	CDeviceProxy(TUint aDeviceId);
+	void ConstructL(RUsbHubDriver& aHubDriver);
+
+private: // utility
+	void Log();
+	void ReadStringDescriptorsL();
+	void PopulateStringDescriptorsL(TUint8 aStringDescriptorIndex, RArray<TName>& aStringArray);
+	void GetStringDescriptorFromUsbdL(TUint32 aLangId, TName& aString, TUint8 aStringDescriptorIndex) const;
+	void GetStringDescriptorFromCacheL(TUint32 aLangId, TName& aString, const RArray<TName>& aStringArray) const;
+
+private: // owned
+	RUsbDevice iHandle;
+	const TUint iId;
+
+	TDeviceEvent* iAttachmentEvent;
+	TDeviceEvent* iDriverLoadingEvent;
+	TDeviceEvent* iDetachmentEvent;
+
+	// The design of string descriptor access in this class deserves some 
+	// explanation.
+	// In the simplest implementation of the FDF, we handle a device 
+	// attachment without getting or storing any string descriptors from the 
+	// device. If the FDF doesn't load any drivers for the device, it must 
+	// suspend the device to save power. If USBMAN, subsequent to this, 
+	// queries any string descriptors, the FDF will have to resume the device 
+	// first (string descriptors are not requested or cached by USBD). 
+	// Resuming a device is an asynchronous operation. We must therefore 
+	// either make querying a string descriptor asynchronous as far as USBMAN 
+	// is concerned (which would clearly make the relevant APIs much less 
+	// friendly) or find another way round. [For completeness: this 
+	// asynchronicity would rely on 
+	// RHubDriver::QueueDeviceStateChangeNotification.]
+	// Solution 1: if the FDF doesn't load drivers for the device, wait until 
+	// USBSVR has queried string descriptors from us before suspending the 
+	// device. Con: USBMAN only queries string descriptors when its client (in 
+	// licensee-land) does so. We can't make any assumptions about their doing 
+	// it in a timely manner or indeed at all. 
+	// Solution 2: use User::After to give the device time to resume 
+	// synchronously. Con: this is a major no-no in a production thread which 
+	// must remain responsive to user requests and lower-level events. 
+	// Mentioned only for completeness.
+	// Solution 3 (implemented): request and cache all supported string 
+	// descriptors at attachment time. String descriptors are typically small 
+	// (a dozen characters, say), we only support 3 of them (manufacturer, 
+	// product and serial number- not all of which may actually be supported 
+	// by a particular device) and there is usually only 1 language, if that. 
+	// Having cached the string descriptors, it is trivial to look them up 
+	// later when the client wants.
+	// These arrays are tied together, i.e. iManufacturerStrings[2] is the 
+	// manufacturer string in the language with ID iLangIds[2]. Note that this 
+	// may be KNullDesC if the device doesn't support the manufacturer string 
+	// descriptor, but there's still an entry in the array for it.
+	RArray<TUint> iLangIds;
+	RArray<TName> iManufacturerStrings;
+	RArray<TName> iProductStrings;
+	RArray<TName> iSerialNumberStrings;
+	TBool		  iHasIAD;
+	TBool         iMultipleDriversFound;
+	TOtgDescriptor* iOtgDescriptor; // Owned
+	};
+
+#endif // DEVICEPROXY_H