diff -r 000000000000 -r c9bc50fca66e usbmgmt/usbmgrtest/t_charging_emu/src/tbatterycharging.cpp --- /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 +#include +#include +#include +#include +#include +#include +#include +#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; iImplementationUid() == 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( + 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(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; + TPckgtmp(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; + + } + +