kerneltest/e32test/property/t_prop_ldd.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "t_prop_ldd.h"
       
    17 #include <kernel/kernel.h>
       
    18 #include "nk_priv.h"
       
    19 
       
    20 class DPropLDevice : public DLogicalDevice
       
    21 	{
       
    22 public:
       
    23 	DPropLDevice();
       
    24 	virtual TInt Install();
       
    25 	virtual void GetCaps(TDes8& aDes) const;
       
    26 	virtual TInt Create(DLogicalChannelBase*& aChannel);
       
    27 	};
       
    28 
       
    29 class DPropLChannel : public DLogicalChannelBase
       
    30 	{
       
    31 public:
       
    32 	DPropLChannel();
       
    33 	~DPropLChannel();
       
    34 
       
    35 	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
       
    36 	virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
       
    37 
       
    38 private:
       
    39 	TInt Basic(RPropChannel::TBasicInfo* aInfo);
       
    40 
       
    41 	static void CompleteFn(TAny* aPtr, TInt aReason);
       
    42 	TInt iReason;
       
    43 	NFastSemaphore iSem;
       
    44 
       
    45 	};
       
    46 
       
    47 DECLARE_STANDARD_LDD()
       
    48 //
       
    49 // Create a new device
       
    50 //
       
    51 	{
       
    52 	return new DPropLDevice;
       
    53 	}
       
    54 
       
    55 DPropLDevice::DPropLDevice()
       
    56 //
       
    57 // Constructor
       
    58 //
       
    59 	{
       
    60 	//iUnitsMask=0;
       
    61 	iVersion = TVersion(1,0,1);
       
    62 	// iParseMask = 0;
       
    63 	}
       
    64 
       
    65 TInt DPropLDevice::Install()
       
    66 //
       
    67 // Install the device driver.
       
    68 //
       
    69 	{
       
    70 	TInt r = SetName(&KPropLdName);
       
    71 	return r;
       
    72 	}
       
    73 
       
    74 void DPropLDevice::GetCaps(TDes8&) const
       
    75 //
       
    76 // Return the Comm capabilities.
       
    77 //
       
    78 	{
       
    79 	}
       
    80 
       
    81 TInt DPropLDevice::Create(DLogicalChannelBase*& aChannel)
       
    82 //
       
    83 // Create a channel on the device.
       
    84 //
       
    85 	{
       
    86 	aChannel = new DPropLChannel;
       
    87 	return aChannel ? KErrNone : KErrNoMemory;
       
    88 	}
       
    89 
       
    90 DPropLChannel::DPropLChannel() 
       
    91 	{
       
    92 	NKern::FSSetOwner(&iSem, NKern::CurrentThread());
       
    93 	}
       
    94 
       
    95 TInt DPropLChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /* aInfo*/ , const TVersion& aVer)
       
    96 //
       
    97 // Create the channel from the passed info.
       
    98 //
       
    99 	{
       
   100 	if (!Kern::QueryVersionSupported(TVersion(1,0,1),aVer))
       
   101 		return KErrNotSupported;
       
   102 	return KErrNone;
       
   103 	}
       
   104 
       
   105 DPropLChannel::~DPropLChannel()
       
   106 	{
       
   107 	}
       
   108 
       
   109 
       
   110 #define BASIC_ERROR(aRes, aCond) \
       
   111 	{\
       
   112 	if (!(aCond)) \
       
   113 		{ \
       
   114 		Kern::Printf("Test '" #aCond "' fails; r = %d;\n\tfile '" __FILE__ "'; line %d;\n", aRes, __LINE__); \
       
   115 		prop.Close(); \
       
   116 		return EFalse; \
       
   117 		} \
       
   118 	}
       
   119 
       
   120 void DPropLChannel::CompleteFn(TAny* aPtr, TInt aReason)
       
   121 	{ // static
       
   122 	DPropLChannel* self = (DPropLChannel*) aPtr;
       
   123 	self->iReason = aReason;
       
   124 	NKern::FSSignal(&self->iSem);
       
   125 	}
       
   126 
       
   127 TBool DPropLChannel::Basic(RPropChannel::TBasicInfo* aInfo)
       
   128 	{
       
   129 
       
   130 	TUid category = aInfo->iCategory;
       
   131 	TUint key = aInfo->iKey;
       
   132 	TUint count = aInfo->iCount;
       
   133 	RProperty::TType type = aInfo->iType;
       
   134 
       
   135 	for (TUint i = 0; i < count; ++i)
       
   136 		{
       
   137 		RPropertyRef prop;
       
   138 		TInt r = prop.Open(category, key);
       
   139 		BASIC_ERROR(r, r == KErrNotFound);
       
   140 		r = prop.Attach(category, key);
       
   141 		BASIC_ERROR(r, r == KErrNone);
       
   142 
       
   143 		//	Defines the attributes and access control for a property. This can only be done 
       
   144 		//	once for each property. Subsequent attempts to define the same property will return
       
   145 		//	KErrAlreadyExists.
       
   146 
       
   147 		TSecurityPolicy policy;
       
   148 
       
   149 		r = prop.Define(type, policy, policy);
       
   150 		BASIC_ERROR(r, r == KErrNone);
       
   151 		r = prop.Define(type, policy, policy);
       
   152 		BASIC_ERROR(r, r == KErrAlreadyExists);
       
   153 		r = prop.Delete();
       
   154 		BASIC_ERROR(r, r == KErrNone);
       
   155 
       
   156 		// Define fails with KErrArgument if wrong type or attribute was specified.
       
   157 		r = prop.Define(RProperty::ETypeLimit, policy, policy);
       
   158 		BASIC_ERROR(r, r == KErrArgument);
       
   159 
       
   160 		static _LIT_SECURITY_POLICY_PASS(KPassPolicy);
       
   161 		TSecurityPolicy badPolicy;
       
   162 		*(TInt*)&badPolicy = -1;
       
   163 
       
   164 		r = prop.Define(type, badPolicy, policy);
       
   165 		BASIC_ERROR(r, r == KErrArgument);
       
   166 		r = prop.Define(type, KPassPolicy, badPolicy);
       
   167 		BASIC_ERROR(r, r == KErrArgument);
       
   168 	
       
   169 		if (type == RProperty::EInt)
       
   170 			{
       
   171 			// Define fails with KErrArgument if aType is TInt and aPreallocate is not 0
       
   172 			r = prop.Define(type, KPassPolicy, KPassPolicy, 16);
       
   173 			BASIC_ERROR(r, r == KErrArgument);
       
   174 
       
   175 			// Following defintion the property has a default value, 0 for integer properties
       
   176 			r = prop.Define(RProperty::EInt, KPassPolicy, KPassPolicy);
       
   177 			BASIC_ERROR(r, r == KErrNone);
       
   178 			TInt value;
       
   179 			r = prop.Get(value);
       
   180 			BASIC_ERROR(r, r == KErrNone);
       
   181 			BASIC_ERROR(value, value == 0);
       
   182 			r = prop.Delete();
       
   183 			BASIC_ERROR(r, r == KErrNone);
       
   184 			}
       
   185 		else 
       
   186 			{
       
   187 			// Defne fails with KErrTooBig if aPeallocate is grater than KMaxPropertySize.
       
   188 			r = prop.Define(RProperty::EByteArray, KPassPolicy, KPassPolicy, RProperty::KMaxPropertySize);
       
   189 			BASIC_ERROR(r, r == KErrNone);
       
   190 			r = prop.Delete();
       
   191 			BASIC_ERROR(r, r == KErrNone);
       
   192 			r = prop.Define(RProperty::EByteArray, KPassPolicy, KPassPolicy, RProperty::KMaxPropertySize+1);
       
   193 			BASIC_ERROR(r, r == KErrTooBig);
       
   194 
       
   195 			// Following defintion the property has a default value, zero-length data for byte-array and text 
       
   196 			// properties. 
       
   197 			r = prop.Define(RProperty::EByteArray, KPassPolicy, KPassPolicy);
       
   198 			BASIC_ERROR(r, r == KErrNone);
       
   199 			TBuf8<16> buf;
       
   200 			r = prop.Get(buf);
       
   201 			BASIC_ERROR(r, r == KErrNone);
       
   202 			BASIC_ERROR(buf.Size(), buf.Size() == 0);
       
   203 			r = prop.Delete();
       
   204 			BASIC_ERROR(r, r == KErrNone);
       
   205 			}
       
   206 
       
   207 		// Pending subscriptions for this property will not be completed until a new value is published.
       
   208 		TPropertySubsRequest subs(CompleteFn, this);
       
   209 		iReason = KRequestPending;
       
   210 		r = prop.Subscribe(subs);
       
   211 		r = prop.Define(type, KPassPolicy, KPassPolicy);
       
   212 		BASIC_ERROR(r, r == KErrNone);
       
   213 		BASIC_ERROR(iReason, iReason == KRequestPending);
       
   214 		r = prop.Delete();
       
   215 		BASIC_ERROR(r, r == KErrNone);
       
   216 		NKern::FSWait(&iSem);
       
   217 		BASIC_ERROR(iReason, iReason == KErrNotFound);
       
   218 
       
   219 		// If the property has not been defined Delete() fails with KErrNotFound.
       
   220 		r = prop.Delete();
       
   221 		BASIC_ERROR(r, r == KErrNotFound);
       
   222 
       
   223 		// When deleted any pending subscriptions for the property will be completed with KErrNotFound.
       
   224 		r = prop.Define(type, KPassPolicy, KPassPolicy);
       
   225 		BASIC_ERROR(r, r == KErrNone);
       
   226 		iReason = KRequestPending;
       
   227 		r = prop.Subscribe(subs);
       
   228 		BASIC_ERROR(r, r == KErrNone);
       
   229 		BASIC_ERROR(iReason, iReason == KRequestPending);
       
   230 		r = prop.Delete();
       
   231 		BASIC_ERROR(r, r == KErrNone);
       
   232 		NKern::FSWait(&iSem);
       
   233 		BASIC_ERROR(iReason, iReason == KErrNotFound);
       
   234 
       
   235 		// Any new request will not complete until the property is defined and published again.
       
   236 		iReason = KRequestPending;
       
   237 		r = prop.Subscribe(subs);
       
   238 		BASIC_ERROR(r, r == KErrNone);
       
   239 		BASIC_ERROR(iReason, iReason == KRequestPending);
       
   240 		r = prop.Define(type, KPassPolicy, KPassPolicy);
       
   241 		BASIC_ERROR(r, r == KErrNone);
       
   242 		BASIC_ERROR(iReason, iReason == KRequestPending);
       
   243 		if (type == RProperty::EInt)
       
   244 			{
       
   245 			r = prop.Set(1);
       
   246 			BASIC_ERROR(r, r == KErrNone);
       
   247 			}
       
   248 		else
       
   249 			{
       
   250 			TBuf8<16> buf((TUint8*) "Foo");
       
   251 			r = prop.Set(buf);
       
   252 			BASIC_ERROR(r, r == KErrNone);
       
   253 			}
       
   254 		NKern::FSWait(&iSem);
       
   255 		BASIC_ERROR(iReason, iReason == KErrNone);
       
   256 		r = prop.Delete();
       
   257 		BASIC_ERROR(r, r == KErrNone);
       
   258 
       
   259 		// If the property has not been defined Set()/Get() fail with KErrNotFound.
       
   260 			{
       
   261 			TInt value;
       
   262 			TBuf8<16> buf;
       
   263 			if (type == RProperty::EInt)
       
   264 				{
       
   265 				r = prop.Get(value);
       
   266 				BASIC_ERROR(r, r == KErrNotFound);
       
   267 				r = prop.Set(value);
       
   268 				BASIC_ERROR(r, r == KErrNotFound);
       
   269 				}
       
   270 			else
       
   271 				{
       
   272 				r = prop.Get(buf);
       
   273 				BASIC_ERROR(r, r == KErrNotFound);
       
   274 				r = prop.Set(buf);
       
   275 				BASIC_ERROR(r, r == KErrNotFound);
       
   276 				}
       
   277 			}
       
   278 
       
   279 		r = prop.Define(type, KPassPolicy, KPassPolicy);
       
   280 		BASIC_ERROR(r, r == KErrNone);
       
   281 
       
   282 		// If the property is larger than KMaxPropertySize Set() fails with KErrTooBig
       
   283 			{
       
   284 			if (type ==  RProperty::EByteArray)
       
   285 				{
       
   286 				TBuf8<RProperty::KMaxPropertySize + 1> buf(RProperty::KMaxPropertySize + 1);
       
   287 				r = prop.Set(buf);
       
   288 				BASIC_ERROR(r, r == KErrTooBig);
       
   289 				}
       
   290 			}
       
   291 
       
   292 		// When type of operation mismatch with the property type Set()/Get() fails with KErrArgument.
       
   293 			{
       
   294 			if (type !=  RProperty::EInt)
       
   295 				{
       
   296 				TInt value;
       
   297 				r = prop.Get(value);
       
   298 				BASIC_ERROR(r, r == KErrArgument);
       
   299 				r = prop.Set(value);
       
   300 				BASIC_ERROR(r, r == KErrArgument);
       
   301 				}
       
   302 			else
       
   303 				{
       
   304 				TBuf8<16> buf;
       
   305 				r = prop.Get(buf);
       
   306 				BASIC_ERROR(r, r == KErrArgument);
       
   307 				r = prop.Set(buf);
       
   308 				BASIC_ERROR(r, r == KErrArgument);
       
   309 				}
       
   310 			}
       
   311 
       
   312 		// Get/Set
       
   313 		if (type == RProperty::EInt)
       
   314 			{
       
   315 			r = prop.Set(1);
       
   316 			BASIC_ERROR(r, r == KErrNone);
       
   317 			TInt value = 0;
       
   318 			r = prop.Get(value);
       
   319 			BASIC_ERROR(r, r == KErrNone);
       
   320 			BASIC_ERROR(value, value == 1);
       
   321 			}
       
   322 		else 
       
   323 			{
       
   324 			TBuf8<16> ibuf((TUint8*)"Foo");
       
   325 			TBuf8<16> obuf;
       
   326 			r = prop.Set(ibuf);
       
   327 			BASIC_ERROR(r, r == KErrNone);
       
   328 			r = prop.Get(obuf);
       
   329 			BASIC_ERROR(r, r == KErrNone);
       
   330 			r = obuf.Compare(ibuf);
       
   331 			BASIC_ERROR(r, r == 0);
       
   332 			}
       
   333 
       
   334 		// If the supplied buffer is too small Get() fails with KErrOverflow and the truncated value is reported.
       
   335 		if (type == RProperty::EByteArray)
       
   336 			{
       
   337 			TBuf8<16> ibuf((TUint8*) "0123456789012345");
       
   338 			TBuf8<16> obuf((TUint8*) "abcdefghigklmnop");
       
   339 			TPtr8 optr((TUint8*) obuf.Ptr(), 0, 15);
       
   340 			r = prop.Set(ibuf);
       
   341 			BASIC_ERROR(r, r == KErrNone);
       
   342 			r = prop.Get(optr);
       
   343 			BASIC_ERROR(r, r == KErrOverflow);
       
   344 			BASIC_ERROR(optr.Length(), optr.Length() == 15); 
       
   345 			BASIC_ERROR(obuf[14], obuf[14] == '4'); 
       
   346 			BASIC_ERROR(obuf[15], obuf[15] == 'p');
       
   347 			}
       
   348 
       
   349 		// The calling thread will have the specified request status signalled when the property is next updated.
       
   350 		iReason = KRequestPending;
       
   351 		r = prop.Subscribe(subs);
       
   352 		BASIC_ERROR(r, r == KErrNone);
       
   353 		BASIC_ERROR(iReason, iReason == KRequestPending);
       
   354 		if (type == RProperty::EInt)
       
   355 			{
       
   356 			r = prop.Set(1);
       
   357 			BASIC_ERROR(r, r == KErrNone);
       
   358 			}
       
   359 		else
       
   360 			{
       
   361 			TBuf8<16> buf((TUint8*) "Foo");
       
   362 			r = prop.Set(buf);
       
   363 			BASIC_ERROR(r, r == KErrNone);
       
   364 			}
       
   365 		NKern::FSWait(&iSem);
       
   366 		BASIC_ERROR(iReason, iReason == KErrNone);
       
   367 
       
   368 		r = prop.Delete();
       
   369 		BASIC_ERROR(r, r == KErrNone);
       
   370 
       
   371 		// Cancel an outstanding subscription request.
       
   372 		// If it has not already completed, the request is completed with KErrCancelled.
       
   373 		iReason = KRequestPending;
       
   374 		r = prop.Subscribe(subs);
       
   375 		BASIC_ERROR(r, r == KErrNone);
       
   376 		BASIC_ERROR(iReason, iReason == KRequestPending);
       
   377 		prop.Cancel(subs);		
       
   378 		NKern::FSWait(&iSem);
       
   379 		BASIC_ERROR(iReason, iReason == KErrCancel);
       
   380 
       
   381 		r = prop.Define(type, KPassPolicy, KPassPolicy);
       
   382 		BASIC_ERROR(r, r == KErrNone);
       
   383 
       
   384 		iReason = KRequestPending;
       
   385 		r = prop.Subscribe(subs);
       
   386 		BASIC_ERROR(r, r == KErrNone);
       
   387 		BASIC_ERROR(iReason, iReason == KRequestPending);
       
   388 		if (type == RProperty::EInt)
       
   389 			{
       
   390 			r = prop.Set(1);
       
   391 			BASIC_ERROR(r, r == KErrNone);
       
   392 			}
       
   393 		else
       
   394 			{
       
   395 			TBuf8<16> buf((TUint8*) "Foo");
       
   396 			r = prop.Set(buf);
       
   397 			BASIC_ERROR(r, r == KErrNone);
       
   398 			}
       
   399 		NKern::FSWait(&iSem);
       
   400 		BASIC_ERROR(iReason, iReason == KErrNone);
       
   401 		prop.Cancel(subs);		
       
   402 		BASIC_ERROR(iReason, iReason == KErrNone);
       
   403 
       
   404 		iReason = KRequestPending;
       
   405 		r = prop.Subscribe(subs);
       
   406 		BASIC_ERROR(r, r == KErrNone);
       
   407 		BASIC_ERROR(iReason, iReason == KRequestPending);
       
   408 		prop.Cancel(subs);		
       
   409 		NKern::FSWait(&iSem);
       
   410 		BASIC_ERROR(iReason, iReason == KErrCancel);
       
   411 
       
   412 		r = prop.Delete();
       
   413 		BASIC_ERROR(r, r == KErrNone);
       
   414 
       
   415 		prop.Close();
       
   416 		}
       
   417 	return ETrue;
       
   418 	}
       
   419 
       
   420 //
       
   421 // Client requests.
       
   422 //
       
   423 TBool DPropLChannel::Request(TInt aFunction, TAny* a1, TAny*)
       
   424 	{
       
   425 	TBool r;
       
   426 	switch (aFunction)
       
   427 		{
       
   428 		case RPropChannel::EBasicTests:
       
   429 			RPropChannel::TBasicInfo info;
       
   430 			kumemget32(&info, a1, sizeof(info));
       
   431 			NKern::ThreadEnterCS();
       
   432 			r = Basic(&info);
       
   433 			NKern::ThreadLeaveCS();
       
   434 			break;	
       
   435 		default:
       
   436 			r = EFalse;
       
   437 			break;
       
   438 		}
       
   439 	return r;
       
   440 	}