|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930" xml:lang="en"><title>Factory |
|
13 Implementation</title><shortdesc>Media driver must implement a PDD factory class derived from <codeph>DPhysicalDevice</codeph>. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <p>The PDD factory creates the main media driver objects. </p> |
|
15 <p>The <xref href="GUID-0437DB4C-FC4E-51DC-BB4C-95C0B26834F5.dita">Device Driver |
|
16 Guide</xref> describes the general theory for implementing a derived class, |
|
17 while this section gives the specifics for the media driver. </p> |
|
18 <p>In implementing your <xref href="GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930.dita"><apiname>DPhysicalDevice</apiname></xref> derived class, |
|
19 you must, as a minimum, provide an implementation for the following four functions, |
|
20 defined as pure virtual in <codeph>DPhysicalDevice</codeph>: </p> |
|
21 <ul> |
|
22 <li id="GUID-7D2FC41B-4294-5082-92D7-07DA9A991CF4"><p> <xref href="GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930.dita#GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930/GUID-CBAFA0EC-B111-57B9-8E4F-EE8ADDB56252">Install() - complete the initialisation of the PDD factory object</xref> </p> </li> |
|
23 <li id="GUID-BDCE51AB-897F-5609-971F-1F3E36AC34D0"><p> <xref href="GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930.dita#GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930/GUID-32B157E9-0F71-5C1B-A0FA-08D5B1ACA700">Create() - create the media driver object</xref> </p> </li> |
|
24 <li id="GUID-B3F2FE95-F58A-5C48-99F1-39C2521153C5"><p> <xref href="GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930.dita#GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930/GUID-9EAFB357-5770-529A-BED5-0721C38C7BD1">Validate() - check that the PDD is suitable for use</xref> </p> </li> |
|
25 <li id="GUID-6D959402-0B3F-547D-B1E7-500C96768649"><p> <xref href="GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930.dita#GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930/GUID-2F29C284-DE66-5A92-9D9A-0348E01D1139">GetCaps() - return the capabilities of the Media Driver</xref> </p> </li> |
|
26 </ul> |
|
27 <p>The following function is virtual in <xref href="GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930.dita"><apiname>DPhysicalDevice</apiname></xref> but |
|
28 has a default implementation that must be changed: </p> |
|
29 <ul> |
|
30 <li id="GUID-53148446-2A45-5E6B-A9F8-B653383F2256"><p> <xref href="GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930.dita#GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930/GUID-E3E875BD-F89D-5728-AF4B-658A595E9298">Info() - set the priority of the media driver</xref> </p> </li> |
|
31 </ul> |
|
32 <section id="GUID-CBAFA0EC-B111-57B9-8E4F-EE8ADDB56252"><title>Install() - |
|
33 complete the initialisation of the PDD factory object</title> <p>See also <xref href="GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930.dita#GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930/GUID-0065FAAF-D734-3ED2-816A-CCE9BF607BAB"><apiname>DPhysicalDevice::Install()</apiname></xref>. </p> <p>This |
|
34 PDD factory function is called after the PDD DLL has been successfully loaded, |
|
35 as a result of a call to <xref href="GUID-C197C9A7-EA05-3F24-9854-542E984C612D.dita#GUID-C197C9A7-EA05-3F24-9854-542E984C612D/GUID-A0F4BF4A-9C58-3E5E-88E1-6D98597DDA18"><apiname>User::LoadPhysicalDevice()</apiname></xref>, and |
|
36 the factory object has been successfully created on the kernel heap. </p> <p>The |
|
37 function is a second stage constructor for the factory object, and allows |
|
38 any further initialisation of the factory object to be done. As a minimum, |
|
39 the function must set a name for the media driver's factory object. The name |
|
40 is important as it is the way in which the object will subsequently be found. |
|
41 The name should be of the form: </p> <codeblock id="GUID-DE6A4AD9-EE64-536D-8532-6624EDAB69AB" xml:space="preserve">Media.<MDExt></codeblock> <p>where <codeph><MDExt></codeph> is descriptive of the specific media. For example, <codeph>Media.Ata</codeph>, |
|
42 and <codeph>Media.Iram</codeph>. </p> <p>When a <xref href="GUID-918D17D8-B751-35EE-A592-4F0EAB005EC7.dita"><apiname>DMedia</apiname></xref> object, |
|
43 created by the internal Symbian platform <filepath>ELOCD.LDD</filepath> logical |
|
44 device driver, attempts to mount a media device, i.e. to open a media driver, |
|
45 it does a search by name. This is a search through all loaded PDDs whose names |
|
46 match <codeph>Media.*</codeph>. </p> <p>The following simple function is typical: </p> <codeblock id="GUID-8FA1A096-470B-55EC-A0CE-282AD6ABC9CA" xml:space="preserve">TInt DMyPhysicalDeviceMedia::Install() |
|
47 { |
|
48 _LIT(KDrvNm, "Media.MyName"); |
|
49 return SetName(&KDrvNm); |
|
50 } |
|
51 </codeblock> </section> |
|
52 <section id="GUID-32B157E9-0F71-5C1B-A0FA-08D5B1ACA700"><title>Create() - |
|
53 create the media driver object</title> <p>See also <xref href="GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930.dita#GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930/GUID-B88265CA-0881-3666-BF76-C32E47F9A3A1"><apiname>DPhysicalDevice::Create()</apiname></xref>. </p> <p>This |
|
54 PDD factory function is called by the device driver framework to create, and |
|
55 return, the media driver object. This is an instance of a class derived from <xref href="GUID-A0D4EB25-0BA4-39EE-874B-465EB9628DCC.dita"><apiname>DMediaDriver</apiname></xref>. |
|
56 Note that, occasionally, you may find this object referred to as the physical |
|
57 channel. </p> <p> <codeph>Create()</codeph> is called when initially mounting |
|
58 a media device, or accessing a removable media after an insertion event. Contrast |
|
59 this with <xref href="GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930.dita#GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930/GUID-CBAFA0EC-B111-57B9-8E4F-EE8ADDB56252">Install()</xref>, |
|
60 which is only called once, when the PDD factory object is loaded. </p> <p>Typically, <codeph>Create()</codeph> does |
|
61 the following: </p> <ul> |
|
62 <li id="GUID-C5FF60E4-9512-597F-9F89-7C0E6BB75ED8"><p>Compares the build version |
|
63 of the media driver with the version requested, and returns <xref href="GUID-F89DA3F0-2A48-3F9B-8F08-29350E92D0E4.dita"><apiname>KErrNotSupported</apiname></xref> if |
|
64 the versions are incompatible. </p> </li> |
|
65 <li id="GUID-B3F68A1C-320D-5CA5-BAE4-59A716C937B0"><p>Creates an instance |
|
66 of the <xref href="GUID-A0D4EB25-0BA4-39EE-874B-465EB9628DCC.dita"><apiname>DMediaDriver</apiname></xref> derived class, the media driver object. </p> </li> |
|
67 <li id="GUID-13D14DBA-8629-54A8-9CFD-E50E7AF32CD7"><p>Initiates second-phase |
|
68 construction of the media driver object. Typically, this involves initialisation |
|
69 that is capable of failing. This may be done synchronously or asynchronously. |
|
70 You would probably do this asynchronously for removable media that is slow |
|
71 to power up, or for slow internal media, in which case, you would need to |
|
72 make sure that you attached a DFC queue during <xref href="GUID-A70A01D2-467E-5BA8-A01D-6182558F3F52.dita">media |
|
73 driver initialisation</xref>. Although the device driver framework does not |
|
74 mandate any specific function name in which to implement this, the example |
|
75 code fragment suggests a function name of <codeph>DoCreate()</codeph>. </p> </li> |
|
76 <li id="GUID-CB1D26B5-A868-5993-9ABF-BD101A94443F"><p>Acknowledges creation |
|
77 of the media driver object. The way you do this depends on whether creation |
|
78 is done synchronously or asynchronously: </p> <ul> |
|
79 <li id="GUID-0C8288F4-874D-5C34-8D38-FCF1665903BD"><p>Synchronous creation |
|
80 - call <xref href="GUID-A0D4EB25-0BA4-39EE-874B-465EB9628DCC.dita#GUID-A0D4EB25-0BA4-39EE-874B-465EB9628DCC/GUID-DF0539A1-FDB2-3A31-A57B-863F9033B67A"><apiname>DMediaDriver::OpenMediaDriverComplete()</apiname></xref> passing <xref href="GUID-6CA4F1ED-7947-3087-B618-D35858FAA3BC.dita"><apiname>KErrNone</apiname></xref>, |
|
81 or an error code if appropriate, and then return <codeph>KErrNone</codeph> from <codeph>Create()</codeph>. |
|
82 Do not return any value other than <xref href="GUID-6CA4F1ED-7947-3087-B618-D35858FAA3BC.dita"><apiname>KErrNone</apiname></xref> from Create(), |
|
83 otherwise the framework may call it again. </p> <p>Note that <xref href="GUID-A0D4EB25-0BA4-39EE-874B-465EB9628DCC.dita#GUID-A0D4EB25-0BA4-39EE-874B-465EB9628DCC/GUID-DF0539A1-FDB2-3A31-A57B-863F9033B67A"><apiname>DMediaDriver::OpenMediaDriverComplete()</apiname></xref> can |
|
84 be called from within the media driver class, if that is the way the driver |
|
85 is designed, but <codeph>Create()</codeph> must still return <codeph>KErrNone</codeph>. </p> </li> |
|
86 <li id="GUID-AF5F1A17-990F-5475-8B0D-25DA45E74B72"><p>Asynchronous creation |
|
87 - return either <xref href="GUID-6CA4F1ED-7947-3087-B618-D35858FAA3BC.dita"><apiname>KErrNone</apiname></xref>, if initiation of the operation |
|
88 was successful, or an error code, if the operation failed immediately. However, |
|
89 it is the responsibility of the media driver object to signal completion. </p> </li> |
|
90 </ul> </li> |
|
91 </ul> <p>The following is a typical example: </p> <codeblock id="GUID-69BF7285-1086-5BD9-9624-61DAF0A22DE9" xml:space="preserve">TInt DMyPhysicalDeviceMedia::Create(DBase*& aChannel, TInt aMediaId, const TDesC8* aInfo ,const TVersion &aVer) |
|
92 { |
|
93 // Check the build version of the media driver |
|
94 if (!Kern::QueryVersionSupported(iVersion,aVer)) |
|
95 { |
|
96 return KErrNotSupported; |
|
97 } |
|
98 |
|
99 //Create my DMediaDriver derived object |
|
100 DMyMediaDriver* pD=new DMyMediaDriver (aMediaId); |
|
101 aChannel=pD; |
|
102 |
|
103 // Call my media driver’s second-stage constructor |
|
104 Tint r = KErrNoMemory; |
|
105 if(pD) |
|
106 { |
|
107 r = pD->DoCreate(aMediaId); |
|
108 } |
|
109 |
|
110 // Synchronous Creation (don’t do this if Asynchronous)… |
|
111 if(r == KErrNone) |
|
112 { |
|
113 pD->OpenMediaDriverComplete(KErrNone); |
|
114 } |
|
115 |
|
116 return r; |
|
117 } |
|
118 </codeblock> </section> |
|
119 <section id="GUID-9EAFB357-5770-529A-BED5-0721C38C7BD1"><title>Validate() |
|
120 - check that the PDD is suitable for use</title> <p>See also <xref href="GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930.dita#GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930/GUID-70B6293C-9000-31D9-AE9E-441C9760B92E"><apiname>DPhysicalDevice::Validate()</apiname></xref>. </p> <p>This |
|
121 PDD factory function is called by the kernel's device driver framework to |
|
122 check whether this PDD is suitable for use with the media type specified in |
|
123 the function. </p> <p>A typical implementation of this function would perform |
|
124 the following steps: </p> <ul> |
|
125 <li id="GUID-A4708377-3D61-5115-92CA-BB0660D9B3F1"><p>Compare the build version |
|
126 of the media driver with the version requested </p> </li> |
|
127 <li id="GUID-47FECD2E-FF54-56F2-93A6-5CC08CB24DB7"><p>Confirm that this driver |
|
128 is responsible for the media type </p> </li> |
|
129 </ul> <p>The following is a very typical implementation: </p> <codeblock id="GUID-E08EC5CD-BCC7-517F-86A9-0B04E62D6E9E" xml:space="preserve">TInt DMyPhysicalDeviceMedia::Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) |
|
130 { |
|
131 // Check the build version of the media driver |
|
132 if (!Kern::QueryVersionSupported(iVersion,aVer)) |
|
133 { |
|
134 return KErrNotSupported; |
|
135 } |
|
136 |
|
137 // Check that the given type of media is supported by this driver |
|
138 if (aUnit!=MEDIA_DEVICE_MYMEDIA) |
|
139 { |
|
140 return KErrNotSupported; |
|
141 } |
|
142 |
|
143 return KErrNone; |
|
144 } |
|
145 |
|
146 </codeblock> <p>Note that the value passed in via the <codeph>aUnit</codeph> argument |
|
147 is the unique media ID used when the media driver was registered. In other |
|
148 contexts, the argument may be denoted by the symobol <codeph>aMediaId</codeph>. </p> </section> |
|
149 <section id="GUID-2F29C284-DE66-5A92-9D9A-0348E01D1139"><title>GetCaps() - |
|
150 return the capabilities of the Media Driver</title> <p>See also <xref href="GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930.dita#GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930/GUID-CA336905-B068-3CFB-80D7-4DF29B92BF4F"><apiname>DPhysicalDevice::GetCaps()</apiname></xref>. </p> <p>For |
|
151 media drivers, this PDD factory function is not used. However, an implementation |
|
152 is required because the function is defined as pure virtual in the <codeph>DPhysicalDevice</codeph> base |
|
153 class. Simply implement an empty function, for example: </p> <codeblock id="GUID-D1DF97CF-7719-5414-9CFB-237E3079B280" xml:space="preserve">void DMyPhysicalDeviceMedia::GetCaps(TDes8& /*aDes*/) const |
|
154 // |
|
155 // Return the media drivers capabilities. |
|
156 // |
|
157 { |
|
158 } |
|
159 </codeblock> </section> |
|
160 <section id="GUID-E3E875BD-F89D-5728-AF4B-658A595E9298"><title>Info() - set |
|
161 the priority of the media driver</title> <p>See also <xref href="GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930.dita#GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930/GUID-440B4A06-BA90-385B-A06D-B8553F0EE63F"><apiname>DPhysicalDevice::Info()</apiname></xref>. </p> <p>This |
|
162 PDD factory function is intended to return information relating to the media |
|
163 driver. The function can, potentially, return many different types of information, |
|
164 depending on the value passed as the first parameter. However, the only type |
|
165 of information that Symbian platform currently requires is the priority of |
|
166 the media driver. The returned priority value is used by Symbian platform |
|
167 to decide the order in which media drivers are to be opened. </p> <p>The default |
|
168 implementation just returns 0, and therefore needs to be overridden. </p> <p>Under |
|
169 most circumstances, you can return the value <xref href="GUID-CE45BE16-7122-3250-B9B5-8CD0F7F7FAEB.dita"><apiname>KMediaDriverPriorityNormal</apiname></xref>. |
|
170 You can, however, return <xref href="GUID-52FB0DED-240A-342A-8922-9450BE2F9E02.dita"><apiname>KMediaDriverPriorityHigh</apiname></xref> in circumstances |
|
171 where it is important that the driver is initialised before a lower priority |
|
172 driver. </p> <p>The following code fragment is a typical implementation: </p> <codeblock id="GUID-7A065EF3-FE4B-541D-B9E4-0F112A9B741B" xml:space="preserve">TInt DMyPhysicalDeviceMedia::Info(TInt aFunction, TAny* /*a1*/) |
|
173 { |
|
174 if (aFunction==EPriority) |
|
175 { |
|
176 return KMediaDriverPriorityNormal; |
|
177 } |
|
178 return KErrNotSupported; |
|
179 } |
|
180 </codeblock> <p>where <codeph>EPriority</codeph> indicates that priority |
|
181 information is required (this is an enum value of enum <codeph>TInfoFunction</codeph>, |
|
182 defined in <xref href="GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930.dita"><apiname>DPhysicalDevice</apiname></xref>. </p> </section> |
|
183 </conbody></concept> |