usbmgmt/usbmgrtest/t_charging_emu/src/tbatterycharging.cpp
changeset 0 c9bc50fca66e
child 15 f92a4f87e424
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgrtest/t_charging_emu/src/tbatterycharging.cpp	Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,573 @@
+/*
+* 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:
+*
+*/
+
+#include "tbatterycharging.h"
+#include "musbdevicenotify.h"
+
+#include <e32svr.h>
+#include <e32base.h>
+#include <e32std.h>
+#include <usbman.rsg>
+#include <f32file.h>
+#include <barsc.h>
+#include <barsread.h>
+#include <bautils.h>
+#include "UsbUtils.h"
+
+
+#include"tbatterychargingdefinitions.h"
+
+
+LOCAL_C void ConsoleMainL();
+
+GLDEF_C TInt E32Main()
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
+	
+	TRAPD(error, ConsoleMainL() );
+	
+	__ASSERT_ALWAYS(!error,User::Panic(_L("UsbChargingTest"), error));
+	delete cleanup; // destroy clean-up stack
+	__UHEAP_MARKEND;
+	return KErrNone;
+	}
+
+void ConsoleMainL()
+	{
+    CActiveScheduler* myScheduler = new(ELeave) CActiveScheduler;
+    CleanupStack::PushL(myScheduler);
+    CActiveScheduler::Install(myScheduler);	
+    
+	CDummyUsbDevice* device = CDummyUsbDevice::NewL();
+	CleanupStack::PushL(device);
+	device->DoTestsL();
+	CActiveScheduler::Start();
+
+	CleanupStack::PopAndDestroy(2, myScheduler);
+	}
+
+CDummyUsbDevice* CDummyUsbDevice::NewL()
+/**
+ * Constructs a CDummyUsbDevice object.
+ *
+ * @return	A new CDummyUsbDevice object
+ */
+	{
+	CDummyUsbDevice* r = new (ELeave) CDummyUsbDevice();
+	CleanupStack::PushL(r);
+	r->ConstructL();
+	CleanupStack::Pop();
+	return r;
+	}
+
+CDummyUsbDevice::~CDummyUsbDevice()
+/**
+ * Destructor.
+ */
+	{
+	// Cancel any outstanding asynchronous operation.
+	Cancel();
+	iTimer.Close();
+	//delete iRepository;
+	iExtensionPlugins.ResetAndDestroy();
+
+	if(iEcom)
+		iEcom->Close();
+	REComSession::FinalClose();
+
+	// Free any memory allocated to the list of observers. Note that
+	// we don't want to call ResetAndDestroy, because we don't own
+	// the observers themselves.
+	iObservers.Reset();
+	delete iText;
+	iTest.Close();
+	
+	iProperty.Close();
+	iPropertyWriteToRepositoryAck.Close();
+	iPropertyReadChargingCurrentAck.Close();
+
+	}
+
+CDummyUsbDevice::CDummyUsbDevice()
+	: CActive(EPriorityStandard), iTest(_L("Usb Charging Plugin Test")), iPtr(0,200), iLine(0,200)
+/**
+ * Constructor.
+ */
+	{
+	CActiveScheduler::Add(this);
+	}
+
+void CDummyUsbDevice::ConstructL()
+/**
+ * Performs 2nd phase construction of the USB device.
+ */
+	{
+	iEcom = &(REComSession::OpenL());
+
+	InstantiateExtensionPluginsL();
+
+	if (iExtensionPlugins.Count() != 1)
+		{
+		User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicIncorrectPlugin);
+		}
+
+	iPlugin = iExtensionPlugins[0];
+
+	iDummyLdd.Initialise();
+	//iRepository = CRepository::NewL(KUsbBatteryChargingCentralRepositoryUid);
+	User::LeaveIfError(iTimer.CreateLocal());
+	
+	DefinePropertyL(KBattChargWriteRepositoryUid, KBattChargWriteRepositoryKey,RProperty::EInt);
+	DefinePropertyL(KBattChargReadPropertyCurrentUid,KBattChargReadCurrentChargingKey,RProperty::EInt);
+	
+	User::LeaveIfError(iPropertyWriteToRepositoryAck.Attach(TUid::Uid(KBattChargWriteRepositoryUid), KBattChargWriteRepositoryAckKey));
+	User::LeaveIfError(iPropertyReadChargingCurrentAck.Attach(TUid::Uid(KBattChargReadPropertyCurrentUid), KBattChargReadCurrentChargingAckKey));
+	
+	User::LeaveIfError(StartPropertyBatteryCharging());
+
+	}
+	
+void CDummyUsbDevice::DefinePropertyL(const TInt32 aCategory, TUint aKey,RProperty::TType eType)
+	{
+	
+	_LIT_SECURITY_POLICY_PASS(KAlwaysPass);
+
+	TInt err = iProperty.Define(TUid::Uid(aCategory),
+									aKey,
+									eType,
+									KAlwaysPass,
+									KAlwaysPass
+									);
+	if ( err != KErrAlreadyExists )
+		{
+		User::LeaveIfError(err);
+		}
+	}
+
+
+	
+void CDummyUsbDevice::InstantiateExtensionPluginsL()
+	{
+	const TUid KUidExtensionPluginInterface = TUid::Uid(KUsbmanExtensionPluginInterfaceUid);
+	RImplInfoPtrArray implementations;
+	const TEComResolverParams noResolverParams;
+	REComSession::ListImplementationsL(KUidExtensionPluginInterface, noResolverParams, KRomOnlyResolverUid, implementations);
+	CleanupResetAndDestroyPushL(implementations);
+
+	for (TInt i=0; i<implementations.Count(); i++)
+		{
+		const TUid KTestPluginUid = {0x1020DEA8};
+		if (implementations[i]->ImplementationUid() == KTestPluginUid)
+			{
+			CUsbmanExtensionPlugin* plugin = CUsbmanExtensionPlugin::NewL(implementations[i]->ImplementationUid(), *this);
+			CleanupStack::PushL(plugin);
+			// there will most likely be two plugins - the standard one, and the test one (which
+			// is an extension of the standard one, to include the interface 
+			// MUsbBatteryChargingTestPluginInterface2. So check, and only keep the test one:
+			MUsbBatteryChargingTestPluginInterface2* pluginIf
+				= reinterpret_cast<MUsbBatteryChargingTestPluginInterface2*>(
+					plugin->GetInterface(KUidUsbBatteryChargingTestPluginInterface2));
+			
+			if (pluginIf)
+				{
+				iExtensionPlugins.AppendL(plugin); // transfer ownership to iExtensionPlugins
+				CleanupStack::Pop(plugin);
+				}
+			else
+				{ // destroy it - it's the standard plugin.
+				CleanupStack::PopAndDestroy(plugin);
+				iObservers.Remove(iObservers.Count() - 1);
+				}
+			}
+		}
+	CleanupStack::PopAndDestroy(&implementations);
+	}
+
+void CDummyUsbDevice::RegisterObserverL(MUsbDeviceNotify& aObserver)
+/**
+ * Register an observer of the device.
+ * Presently, the device supports watching state.
+ *
+ * @param	aObserver	New Observer of the device
+ */
+	{
+	User::LeaveIfError(iObservers.Append(&aObserver));
+	}
+
+
+void CDummyUsbDevice::DeRegisterObserver(MUsbDeviceNotify& aObserver)
+/**
+ * De-registers an existing device observer.
+ *
+ * @param	aObserver	The existing device observer to be de-registered
+ */
+	{
+	TInt index = iObservers.Find(&aObserver);
+
+	if (index >= 0)
+		iObservers.Remove(index);
+	}
+
+void CDummyUsbDevice::RunL()
+	{
+	DoCheck();
+	if (GetNextLine() < 0)
+		{
+		iTest.End();
+		iTest.Getch();
+		CActiveScheduler::Stop();
+		}
+	else
+		{
+		iLineNumber++;
+		iTest.Next(_L(""));
+		InterpretLine();
+		DoCommand();
+		DoAsyncOp();	
+		}
+	}
+
+void CDummyUsbDevice::DoCancel()
+	{
+	iTimer.Cancel();
+	}
+
+TInt CDummyUsbDevice::RunError(TInt /*aError*/)
+	{
+
+	return KErrNone;
+	}
+
+RDevUsbcClient& CDummyUsbDevice::MuepoDoDevUsbcClient()
+/**
+ * Inherited from MUsbmanExtensionPluginObserver - Function used by plugins to
+ * retrieve our handle to the LDD
+ *
+ * @return The LDD handle
+ */
+	{
+	return iDummyLdd;
+	}
+
+void CDummyUsbDevice::MuepoDoRegisterStateObserverL(MUsbDeviceNotify& aObserver)
+/**
+ * Inherited from MUsbmanExtensionPluginObserver - Function used by plugins to
+ * register themselves for notifications of device/service state changes.
+ *
+ * @param aObserver New Observer of the device
+ */
+	{
+	RegisterObserverL(aObserver);
+	}
+
+void CDummyUsbDevice::UpdatePluginInfo()
+	{
+	// we can assume our plugin does support this interface....
+	reinterpret_cast<MUsbBatteryChargingTestPluginInterface2*>(iPlugin->GetInterface(KUidUsbBatteryChargingTestPluginInterface2))->GetPluginInfo(iInfo);
+	}
+
+void CDummyUsbDevice::DoTestsL()
+	{
+	iTest.SetLogged(ETrue);
+	iTest.Title();
+	OpenFileL();
+	TInt length = GetNextLine();
+	if (length <= 0)
+		{
+		User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadInputData);
+		}
+	iLineNumber = 1;
+	iTest.Start(_L("test"));
+	InterpretLine();
+	DoCommand();
+	DoAsyncOp();
+	}
+
+void CDummyUsbDevice::InterpretLine()
+	{
+	TLex8 lex(iLine);
+	lex.SkipCharacters();
+	iCommand = GetCommand(iLine.Left(lex.Offset()));
+	lex.SkipSpace();
+	lex.Val(iCommandValue);
+	lex.SkipSpace();
+	TInt pos = lex.Offset();
+	lex.SkipCharacters();
+	iAsyncOp = GetAsyncOp(iLine.Mid(pos,lex.Offset()-pos));
+	lex.SkipSpace();
+	lex.Val(iAsyncOpValue);
+	lex.SkipSpace();
+	pos = lex.Offset();
+	lex.SkipCharacters();
+	iCheck = GetCheck(iLine.Mid(pos,lex.Offset()-pos));
+	lex.SkipSpace();
+	lex.Val(iCheckValue);
+	}
+
+void CDummyUsbDevice::OpenFileL()
+	{
+	RFs fs;
+	User::LeaveIfError(fs.Connect());
+	CleanupClosePushL(fs);
+
+	TFindFile ff(fs);
+	User::LeaveIfError(ff.FindByDir(_L("\\system\\data\\t_charging.txt"),KNullDesC));
+	
+	RFile file;
+	TInt size;
+	User::LeaveIfError(file.Open(fs,ff.File(),EFileStreamText|EFileRead|EFileShareReadersOnly));
+	CleanupClosePushL(file);
+	
+	User::LeaveIfError(file.Size(size));
+
+	iText = REINTERPRET_CAST(TText8*, User::AllocL(size));
+	iPtr.Set(iText, size/sizeof(TText8), size/sizeof(TText8));
+	TPtr8 dest(REINTERPRET_CAST(TUint8*,iText), 0, size);
+	User::LeaveIfError(file.Read(dest)); 
+
+	CleanupStack::PopAndDestroy(); // file
+	CleanupStack::PopAndDestroy(); // fs
+	}
+
+TInt CDummyUsbDevice::GetNextLine()
+	{
+	TInt newLineOffset = (iPtr.Mid(iFileOffset)).Locate(13);//Find(_L("\r\n"));
+	if (newLineOffset < 0)
+		{
+		return newLineOffset;
+		}
+	if (newLineOffset == 0)
+		{
+		iFileOffset += 2;
+		return GetNextLine();
+		}
+	iLine.Set(iPtr.MidTPtr(iFileOffset, newLineOffset));
+	iFileOffset += (newLineOffset + 2);
+	if (iLine.Find(_L8("//")) == 0) // i.e. line begins with "//"
+		{
+		return GetNextLine();
+		}
+	if (iLine.Find(_L8("**")) == 0) // line begins with **, so display it
+		{
+		TBuf<100> buf; // max length 100 for test messages
+		buf.Copy(iLine);
+		iTest.Printf(_L("\n%S\n\n"),&buf);
+		return GetNextLine();
+		};
+	return newLineOffset;
+	}
+
+TInt CDummyUsbDevice::GetCommand(const TDesC8& aDes)
+	{
+	if (aDes.MatchF(_L8("none")) != KErrNotFound)
+		return EUsbChargingTestCommandNone;
+	if (aDes.MatchF(_L8("devicestate")) != KErrNotFound)
+		return EUsbChargingTestCommandDeviceState;
+	if (aDes.MatchF(_L8("usersetting")) != KErrNotFound)
+		return EUsbChargingTestCommandUserSetting;
+	User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadInputData);
+	return -1;
+	}
+
+TInt CDummyUsbDevice::GetAsyncOp(const TDesC8& aDes)
+	{
+	if (aDes.MatchF(_L8("none")) != KErrNotFound)
+		return EUsbChargingTestAsyncOpNone;
+	if (aDes.MatchF(_L8("delay")) != KErrNotFound)
+		return EUsbChargingTestAsyncOpDelay;
+	User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadInputData);
+	return -1;
+	}
+
+TInt CDummyUsbDevice::GetCheck(const TDesC8& aDes)
+	{
+	if (aDes.MatchF(_L8("none")) != KErrNotFound)
+		return EUsbChargingTestCheckNone;
+	if (aDes.MatchF(_L8("pluginstate")) != KErrNotFound)
+		return EUsbChargingTestCheckPluginState;
+	if (aDes.MatchF(_L8("milliamps")) != KErrNotFound)
+		return EUsbChargingTestCheckMilliAmps;
+	if (aDes.MatchF(_L8("charging")) != KErrNotFound)
+		return EUsbChargingTestCheckCharging;
+	User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadInputData);
+	return -1;
+	}
+
+void CDummyUsbDevice::DoCommand()
+	{
+	switch (iCommand)
+		{
+		case EUsbChargingTestCommandNone:
+			{
+			// do nothing	
+			}
+			break;
+		case EUsbChargingTestCommandDeviceState:
+			{
+			iObservers[0]->UsbDeviceStateChange(KErrNone, iDeviceState, TUsbDeviceState(iCommandValue));
+			iDeviceState = TUsbDeviceState(iCommandValue);
+			}
+			break;
+		case EUsbChargingTestCommandUserSetting:
+			{
+			TInt err = WriteToRepositoryProperty(iCommandValue);
+			
+			//TInt err = iRepository->Set(KUsbBatteryChargingKeyEnabledUserSetting, iCommandValue);
+			iTest(err == KErrNone);
+			}
+			break;
+		default:
+			User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadCommand);
+		}
+	}
+
+void CDummyUsbDevice::DoAsyncOp()
+	{
+	switch (iAsyncOp)
+		{
+		case EUsbChargingTestAsyncOpNone:
+			{
+			SetActive();
+			TRequestStatus* status = &iStatus;
+			User::RequestComplete(status, KErrNone);
+			}
+			break;
+		case EUsbChargingTestAsyncOpDelay:
+			{
+			iTimer.After(iStatus, TTimeIntervalMicroSeconds32(iAsyncOpValue));
+			SetActive();
+			}
+			break;
+		default:
+			User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadAsyncOp);
+		}
+	}
+
+void CDummyUsbDevice::DoCheck()
+	{
+	UpdatePluginInfo();
+	switch (iCheck)
+		{
+		case EUsbChargingTestCheckNone:
+			{
+			// do nothing
+			}
+			break;
+		case EUsbChargingTestCheckPluginState:
+			{
+			iTest(iInfo.iPluginState == iCheckValue);
+			}
+			break;
+		case EUsbChargingTestCheckMilliAmps:
+			{
+			iTest(iInfo.iRequestedCurrentValue == iCheckValue);
+			}
+			break;
+		case EUsbChargingTestCheckCharging:
+			{
+			TInt current;			
+			TInt err = GetChargingCurrentFromProperty(current);
+			
+			//TInt err = RProperty::Get(KPropertyUidUsbBatteryChargingCategory,
+			//	KPropertyUidUsbBatteryChargingChargingCurrent, current);
+			iTest(err == KErrNone);
+			iTest(current == iCheckValue);
+			}
+			break;
+		default:
+			User::Panic(KUsbChargingTestPanic, EUsbChargingTestPanicBadCheck);
+		}
+	}
+	
+TInt CDummyUsbDevice::GetChargingCurrentFromProperty(TInt &aCurrent)
+	{
+	
+	TRequestStatus stat;
+	iPropertyReadChargingCurrentAck.Subscribe(stat);
+	
+	TInt err = iProperty.Set(TUid::Uid(KBattChargReadPropertyCurrentUid),
+								KBattChargReadCurrentChargingKey,
+								1);
+	ASSERT(!err);	
+	User::WaitForRequest(stat);
+	
+	TBufC8<50> value;
+	TPtr8 myPtr(value.Des());
+	TInt error = iPropertyReadChargingCurrentAck.Get(myPtr);
+	ASSERT(!error);
+	
+	TDataFromPropBattChargToTBatteryCharging received;
+	TPckg<TDataFromPropBattChargToTBatteryCharging>tmp(received);
+	tmp.Copy(value);
+	aCurrent = received.iCurrent;
+	return received.iError;
+	
+	}
+
+TInt CDummyUsbDevice::WriteToRepositoryProperty(TInt iCommandValue)
+	{
+	TRequestStatus stat;
+	iPropertyWriteToRepositoryAck.Subscribe(stat);
+		
+	TInt err = iProperty.Set(TUid::Uid(KBattChargWriteRepositoryUid),
+									KBattChargWriteRepositoryKey,
+									iCommandValue);
+	ASSERT(!err);	
+	User::WaitForRequest(stat);
+	TInt value;
+	err = iPropertyWriteToRepositoryAck.Get(value);
+	ASSERT(!err);
+	return value;
+	}
+	
+TInt CDummyUsbDevice::StartPropertyBatteryCharging()
+	{
+	const TUidType serverUid(KNullUid, KNullUid, KBatteryChargingTUid);
+	RProcess server;
+	TInt err = server.Create(KBattChargingImg, KNullDesC, serverUid);
+	if ( err != KErrNone )
+		{
+		return err;
+		}
+	TRequestStatus stat;
+	server.Rendezvous(stat);
+	
+	if ( stat != KRequestPending )
+		{		
+		server.Kill(0); 	// abort startup
+		}
+	else
+		{		
+		server.Resume();	// logon OK - start the server
+		}
+	
+	User::WaitForRequest(stat); 	// wait for start or death
+	
+	// we can't use the 'exit reason' if the server panicked as this
+	// is the panic 'reason' and may be '0' which cannot be distinguished
+	// from KErrNone
+	
+	err = (server.ExitType() == EExitPanic) ? KErrServerTerminated : stat.Int();
+	
+	server.Close();	
+	
+	return err;
+	
+	}
+	
+