--- /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;
+
+ }
+
+