Update contrib.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "t_prop_ldd.h"
17 #include <kernel/kernel.h>
20 class DPropLDevice : public DLogicalDevice
24 virtual TInt Install();
25 virtual void GetCaps(TDes8& aDes) const;
26 virtual TInt Create(DLogicalChannelBase*& aChannel);
29 class DPropLChannel : public DLogicalChannelBase
35 virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
36 virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
39 TInt Basic(RPropChannel::TBasicInfo* aInfo);
41 static void CompleteFn(TAny* aPtr, TInt aReason);
47 DECLARE_STANDARD_LDD()
49 // Create a new device
52 return new DPropLDevice;
55 DPropLDevice::DPropLDevice()
61 iVersion = TVersion(1,0,1);
65 TInt DPropLDevice::Install()
67 // Install the device driver.
70 TInt r = SetName(&KPropLdName);
74 void DPropLDevice::GetCaps(TDes8&) const
76 // Return the Comm capabilities.
81 TInt DPropLDevice::Create(DLogicalChannelBase*& aChannel)
83 // Create a channel on the device.
86 aChannel = new DPropLChannel;
87 return aChannel ? KErrNone : KErrNoMemory;
90 DPropLChannel::DPropLChannel()
92 NKern::FSSetOwner(&iSem, NKern::CurrentThread());
95 TInt DPropLChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /* aInfo*/ , const TVersion& aVer)
97 // Create the channel from the passed info.
100 if (!Kern::QueryVersionSupported(TVersion(1,0,1),aVer))
101 return KErrNotSupported;
105 DPropLChannel::~DPropLChannel()
110 #define BASIC_ERROR(aRes, aCond) \
114 Kern::Printf("Test '" #aCond "' fails; r = %d;\n\tfile '" __FILE__ "'; line %d;\n", aRes, __LINE__); \
120 void DPropLChannel::CompleteFn(TAny* aPtr, TInt aReason)
122 DPropLChannel* self = (DPropLChannel*) aPtr;
123 self->iReason = aReason;
124 NKern::FSSignal(&self->iSem);
127 TBool DPropLChannel::Basic(RPropChannel::TBasicInfo* aInfo)
130 TUid category = aInfo->iCategory;
131 TUint key = aInfo->iKey;
132 TUint count = aInfo->iCount;
133 RProperty::TType type = aInfo->iType;
135 for (TUint i = 0; i < count; ++i)
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);
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.
147 TSecurityPolicy policy;
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);
154 BASIC_ERROR(r, r == KErrNone);
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);
160 static _LIT_SECURITY_POLICY_PASS(KPassPolicy);
161 TSecurityPolicy badPolicy;
162 *(TInt*)&badPolicy = -1;
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);
169 if (type == RProperty::EInt)
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);
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);
180 BASIC_ERROR(r, r == KErrNone);
181 BASIC_ERROR(value, value == 0);
183 BASIC_ERROR(r, r == KErrNone);
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);
191 BASIC_ERROR(r, r == KErrNone);
192 r = prop.Define(RProperty::EByteArray, KPassPolicy, KPassPolicy, RProperty::KMaxPropertySize+1);
193 BASIC_ERROR(r, r == KErrTooBig);
195 // Following defintion the property has a default value, zero-length data for byte-array and text
197 r = prop.Define(RProperty::EByteArray, KPassPolicy, KPassPolicy);
198 BASIC_ERROR(r, r == KErrNone);
201 BASIC_ERROR(r, r == KErrNone);
202 BASIC_ERROR(buf.Size(), buf.Size() == 0);
204 BASIC_ERROR(r, r == KErrNone);
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);
215 BASIC_ERROR(r, r == KErrNone);
216 NKern::FSWait(&iSem);
217 BASIC_ERROR(iReason, iReason == KErrNotFound);
219 // If the property has not been defined Delete() fails with KErrNotFound.
221 BASIC_ERROR(r, r == KErrNotFound);
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);
231 BASIC_ERROR(r, r == KErrNone);
232 NKern::FSWait(&iSem);
233 BASIC_ERROR(iReason, iReason == KErrNotFound);
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)
246 BASIC_ERROR(r, r == KErrNone);
250 TBuf8<16> buf((TUint8*) "Foo");
252 BASIC_ERROR(r, r == KErrNone);
254 NKern::FSWait(&iSem);
255 BASIC_ERROR(iReason, iReason == KErrNone);
257 BASIC_ERROR(r, r == KErrNone);
259 // If the property has not been defined Set()/Get() fail with KErrNotFound.
263 if (type == RProperty::EInt)
266 BASIC_ERROR(r, r == KErrNotFound);
268 BASIC_ERROR(r, r == KErrNotFound);
273 BASIC_ERROR(r, r == KErrNotFound);
275 BASIC_ERROR(r, r == KErrNotFound);
279 r = prop.Define(type, KPassPolicy, KPassPolicy);
280 BASIC_ERROR(r, r == KErrNone);
282 // If the property is larger than KMaxPropertySize Set() fails with KErrTooBig
284 if (type == RProperty::EByteArray)
286 TBuf8<RProperty::KMaxPropertySize + 1> buf(RProperty::KMaxPropertySize + 1);
288 BASIC_ERROR(r, r == KErrTooBig);
292 // When type of operation mismatch with the property type Set()/Get() fails with KErrArgument.
294 if (type != RProperty::EInt)
298 BASIC_ERROR(r, r == KErrArgument);
300 BASIC_ERROR(r, r == KErrArgument);
306 BASIC_ERROR(r, r == KErrArgument);
308 BASIC_ERROR(r, r == KErrArgument);
313 if (type == RProperty::EInt)
316 BASIC_ERROR(r, r == KErrNone);
319 BASIC_ERROR(r, r == KErrNone);
320 BASIC_ERROR(value, value == 1);
324 TBuf8<16> ibuf((TUint8*)"Foo");
327 BASIC_ERROR(r, r == KErrNone);
329 BASIC_ERROR(r, r == KErrNone);
330 r = obuf.Compare(ibuf);
331 BASIC_ERROR(r, r == 0);
334 // If the supplied buffer is too small Get() fails with KErrOverflow and the truncated value is reported.
335 if (type == RProperty::EByteArray)
337 TBuf8<16> ibuf((TUint8*) "0123456789012345");
338 TBuf8<16> obuf((TUint8*) "abcdefghigklmnop");
339 TPtr8 optr((TUint8*) obuf.Ptr(), 0, 15);
341 BASIC_ERROR(r, r == KErrNone);
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');
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)
357 BASIC_ERROR(r, r == KErrNone);
361 TBuf8<16> buf((TUint8*) "Foo");
363 BASIC_ERROR(r, r == KErrNone);
365 NKern::FSWait(&iSem);
366 BASIC_ERROR(iReason, iReason == KErrNone);
369 BASIC_ERROR(r, r == KErrNone);
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);
378 NKern::FSWait(&iSem);
379 BASIC_ERROR(iReason, iReason == KErrCancel);
381 r = prop.Define(type, KPassPolicy, KPassPolicy);
382 BASIC_ERROR(r, r == KErrNone);
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)
391 BASIC_ERROR(r, r == KErrNone);
395 TBuf8<16> buf((TUint8*) "Foo");
397 BASIC_ERROR(r, r == KErrNone);
399 NKern::FSWait(&iSem);
400 BASIC_ERROR(iReason, iReason == KErrNone);
402 BASIC_ERROR(iReason, iReason == KErrNone);
404 iReason = KRequestPending;
405 r = prop.Subscribe(subs);
406 BASIC_ERROR(r, r == KErrNone);
407 BASIC_ERROR(iReason, iReason == KRequestPending);
409 NKern::FSWait(&iSem);
410 BASIC_ERROR(iReason, iReason == KErrCancel);
413 BASIC_ERROR(r, r == KErrNone);
423 TBool DPropLChannel::Request(TInt aFunction, TAny* a1, TAny*)
428 case RPropChannel::EBasicTests:
429 RPropChannel::TBasicInfo info;
430 kumemget32(&info, a1, sizeof(info));
431 NKern::ThreadEnterCS();
433 NKern::ThreadLeaveCS();