|
1 // Copyright (c) 2005-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 "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 // Implementation of the Configurator server for on demand loading of CPMs. |
|
15 // |
|
16 // |
|
17 |
|
18 #include <cfextras.h> |
|
19 #include <e32svr.h> |
|
20 #include <e32uid.h> |
|
21 #include <e32base.h> |
|
22 #include "c32startshared.h" |
|
23 #include "c32startserv.h" |
|
24 #include "c32startPolicy.h" |
|
25 |
|
26 /** |
|
27 @file |
|
28 Implements the Configurator Server side. |
|
29 |
|
30 @internalTechnology |
|
31 */ |
|
32 |
|
33 CRsConfiguratorServer::CRsConfiguratorServer(CCommsProcessStarter& aCommsProcess) |
|
34 : CPolicyServer(CActive::EPriorityStandard,iPolicy,ESharableSessions), |
|
35 iCommsProcess(aCommsProcess) |
|
36 /** C'tor |
|
37 @param aCommsProcess base class for managing CPMs |
|
38 */ |
|
39 { |
|
40 } |
|
41 |
|
42 CRsConfiguratorServer::~CRsConfiguratorServer() |
|
43 /** D'tor |
|
44 */ |
|
45 { |
|
46 } |
|
47 CSession2* CRsConfiguratorServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const |
|
48 /** Create new session object.Connect API is policed for its capability. |
|
49 @internalComponent |
|
50 */ |
|
51 { |
|
52 return new(ELeave) CRsConfiguratorServerSession(this); |
|
53 } |
|
54 |
|
55 |
|
56 CRsConfiguratorServer* CRsConfiguratorServer::NewL(CCommsProcessStarter& aCommsProcess) |
|
57 /** Create new Configurator Server instance. |
|
58 This is the only way of instantiation |
|
59 @internalComponent |
|
60 @param aCommsProcess base class for CPM management |
|
61 */ |
|
62 { |
|
63 CRsConfiguratorServer* self = new(ELeave) CRsConfiguratorServer(aCommsProcess); |
|
64 CleanupStack::PushL(self); |
|
65 self->ConstructL(); |
|
66 CleanupStack::Pop(self); |
|
67 return self; |
|
68 } |
|
69 |
|
70 CRsConfiguratorServer* CRsConfiguratorServer::NewLC(CCommsProcessStarter& aCommsProcess) |
|
71 /** Create new Configurator Server instance. |
|
72 This is the only way of instantiation |
|
73 @internalComponent |
|
74 @param aCommsProcess base class for CPM management |
|
75 */ |
|
76 { |
|
77 CRsConfiguratorServer* self=new(ELeave) CRsConfiguratorServer(aCommsProcess); |
|
78 CleanupStack::PushL(self); |
|
79 self->ConstructL(); |
|
80 return self; |
|
81 } |
|
82 |
|
83 void CRsConfiguratorServer::ConstructL() |
|
84 /** Second level construction of ConfiguratorServer. |
|
85 Configurator Server is started |
|
86 @internalComponent |
|
87 */ |
|
88 { |
|
89 StartL(KRsConfiguratorServerName); |
|
90 } |
|
91 |
|
92 |
|
93 TInt CRsConfiguratorServer::EnumerateModules(const TCFGroupNameF& aGroupName, TInt& aStartAt, TCFModuleNameF& aName) |
|
94 /** Returns a module name from list of modules which matches the group name |
|
95 @param aGroupName name of a group to which module belongs. |
|
96 @param aStartAt search for aName starting at this position. |
|
97 @param aName returns the name for matching group. |
|
98 */ |
|
99 { |
|
100 RPointerArray<CModuleRef>& modules=GetModulesList(); |
|
101 TInt count = modules.Count(); |
|
102 if(aStartAt >= count) |
|
103 { |
|
104 return KErrEof; |
|
105 } |
|
106 |
|
107 for(TInt i=aStartAt;i<count;i++) |
|
108 { |
|
109 CModuleRef* pModule = modules[i]; |
|
110 if(aGroupName == pModule->GroupName()) |
|
111 { |
|
112 aName = pModule->Name(); |
|
113 aStartAt = i; // to retain the last found position |
|
114 __FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::EnumerateModules Module Found (%S)"),&aName); |
|
115 return KErrNone; |
|
116 } |
|
117 } |
|
118 __FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::EnumerateModules RSModuleUnknown For Group (%S)"),&aGroupName); |
|
119 return KErrRSModuleUnknown; |
|
120 } |
|
121 |
|
122 TInt CRsConfiguratorServer::LoadCpm(const TCFModuleNameF& aName,const RMessage2& aMessage) |
|
123 /** Loads the CPM module. |
|
124 retunrs KErrNone on succesfull load request. |
|
125 KErrRSModuleAlreadyExist if module is already loaded. |
|
126 KErrRSModuleUnknown if Module is not listed. |
|
127 KErrRSModuleNotLoaded if load is fails. |
|
128 @param aName name of the module to be loaded. |
|
129 */ |
|
130 { |
|
131 __FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::LoadCpm (%S)"),&aName); |
|
132 CModuleRef* pModule; |
|
133 if((pModule = FindCpm(aName)) != NULL) |
|
134 { |
|
135 if(pModule->State()==ENotLoaded) |
|
136 { |
|
137 // RMessage set here, determines if a module's message can be completed or not. |
|
138 // message completion is not on "OnDemand" property, as a boot time module can also be On-Demand loaded. |
|
139 pModule->SetRMessage(aMessage); |
|
140 // check if any of the bindings has this OnDemand module, if yes, set iHasBinding = ETrue |
|
141 RPointerArray<CBindingRef>& bindings = iCommsProcess.GetBindingList(); |
|
142 for(TInt i=0; i<bindings.Count(); i++) |
|
143 { |
|
144 const CBindingRef& bind(*bindings[i]); |
|
145 if(pModule->Name() == bind.FromModule().Module() || pModule->Name() == bind.ToModule().Module()) |
|
146 { |
|
147 pModule->SetHasBindings(); |
|
148 break; |
|
149 } |
|
150 } |
|
151 iCommsProcess.LoadOnDemandModule(*pModule); |
|
152 return KErrNone; |
|
153 } |
|
154 else if ((pModule->State()==ELoaded) || (pModule->State()==ELoading)) |
|
155 { |
|
156 __FLOG_1(_L8("CRsConfiguratorServer::LoadCpm - %S ModuleAlreadyExist"),&aName); |
|
157 return KErrRSModuleAlreadyExist; |
|
158 } |
|
159 } |
|
160 __FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::LoadCpm (%S) ModuleUnknown"),&aName); |
|
161 return KErrRSModuleUnknown; |
|
162 } |
|
163 |
|
164 TInt CRsConfiguratorServer::GetModuleIniData(const TCFModuleNameF& aName,const RMessage2& aMessage) |
|
165 /** Get the data from [inidata] section for a given module name. |
|
166 @param aName name of the module for which inidata section has to be retrieved. |
|
167 @param aInidata contains inidata for given module name. |
|
168 @param aActualSize on return contains actual size of [inidata] |
|
169 @return an error code. |
|
170 */ |
|
171 { |
|
172 __FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::GetModuleIniData (%S) "),&aName); |
|
173 CModuleRef* pModule; |
|
174 TPckgBuf<TInt> actualLength; |
|
175 if((pModule = FindCpm(aName)) != NULL) |
|
176 { |
|
177 TInt deslength = aMessage.GetDesMaxLength(1); // Buffer length to get the contents |
|
178 if(deslength <0) |
|
179 { |
|
180 return deslength; |
|
181 } |
|
182 HBufC8* inidata = pModule->GetIniData(); |
|
183 if(inidata != NULL) |
|
184 { |
|
185 actualLength = inidata->Length(); // Actual length of the inidata |
|
186 TInt err = aMessage.Write(2, actualLength); |
|
187 if (err == KErrNone ) |
|
188 { |
|
189 if(inidata->Length() <= deslength) |
|
190 { |
|
191 err = aMessage.Write(1, *inidata); |
|
192 } |
|
193 else |
|
194 { |
|
195 return KErrOverflow; |
|
196 } |
|
197 } |
|
198 return err; |
|
199 } |
|
200 else // No inidata Section return actual size as 0"Zero". |
|
201 { |
|
202 actualLength = 0; |
|
203 TInt err = aMessage.Write(2, actualLength); |
|
204 return KErrNone; |
|
205 } |
|
206 } |
|
207 |
|
208 __FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::GetModuleIniData (%S) ModuleUnknown "),&aName); |
|
209 return KErrRSModuleUnknown; |
|
210 |
|
211 } |
|
212 |
|
213 TInt CRsConfiguratorServer::UnLoadCpm(const TCFModuleNameF& aName, const RMessage2& aMessage) |
|
214 /** Unloads module loaded by configurator itself. This calls root server UnloadCpm() internally. |
|
215 @param aName name of the module to be unloaded. |
|
216 @param aMessage which is to be completed once the root server unloads the module. |
|
217 Else message would be completed by the Configurator server session ServiceL with error returned from here. |
|
218 @return an error code. |
|
219 */ |
|
220 { |
|
221 __FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::UnLoadCpm (%S)"),&aName); |
|
222 |
|
223 CModuleRef* pModule; |
|
224 TRSUnLoadType unloadType = (TRSUnLoadType) aMessage.Int1(); |
|
225 if((pModule = FindCpm(aName)) != NULL) |
|
226 { |
|
227 if(pModule->State()==ELoaded) |
|
228 { |
|
229 // RMessage set here, determines if a module's message can be completed or not. |
|
230 // message completion is not on "OnDemand" property, as a boot time module can also be On-Demand unloaded. |
|
231 pModule->SetRMessage(aMessage); |
|
232 pModule->UnLoadCpm(aName,unloadType); |
|
233 return KErrNone; |
|
234 } |
|
235 else |
|
236 { |
|
237 return KErrRSModuleNotLoaded; |
|
238 } |
|
239 } |
|
240 |
|
241 __FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::UnLoadCpm (%S) ModuleUnknown "),&aName); |
|
242 return KErrRSModuleUnknown; |
|
243 } |
|
244 |
|
245 TInt CRsConfiguratorServer::CancelUnLoadCpm(const TCFModuleNameF& aName) |
|
246 /** Cancel asynchronous unloading of a comms Provider Module. |
|
247 There is no guarantee the module unloading is canceled. |
|
248 A best effort is made and the asynchronous request waiting for the module |
|
249 to load returns KErrCanceled on success. |
|
250 |
|
251 @param aName name of the unloading module. |
|
252 @return an error code. |
|
253 */ |
|
254 { |
|
255 __FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::CancelUnLoadCpm (%S)"),&aName); |
|
256 |
|
257 CModuleRef* pModule; |
|
258 if((pModule = FindCpm(aName)) != NULL) |
|
259 { |
|
260 pModule->CancelUnLoadCpm(aName); |
|
261 return KErrNone; |
|
262 } |
|
263 |
|
264 __FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::CancelUnLoadCpm (%S) ModuleUnknown "),&aName); |
|
265 return KErrRSModuleUnknown; |
|
266 } |
|
267 |
|
268 TInt CRsConfiguratorServer::CancelLoadCpm(const TCFModuleNameF& aName) |
|
269 /**Cancels asynchronous loading of a comms Provider Module. |
|
270 There is no guarantee the module loading is canceled. |
|
271 A best effort is made and the asynchronous request waiting for the module |
|
272 to load returns with KErrCanceled on success. |
|
273 |
|
274 @param aName name of the unloading module. |
|
275 @return an error code. |
|
276 */ |
|
277 { |
|
278 __FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::CancelLoadCpm (%S)"),&aName); |
|
279 |
|
280 CModuleRef* pModule; |
|
281 if((pModule = FindCpm(aName)) != NULL) |
|
282 { |
|
283 pModule->CancelLoadCpm(aName); |
|
284 return KErrNone; |
|
285 } |
|
286 |
|
287 __FLOG_STATIC1(KSubsys,KComponent,_L8("CRsConfiguratorServer::CancelLoadCpm (%S) ModuleUnknown "),&aName); |
|
288 return KErrRSModuleUnknown; |
|
289 } |
|
290 |
|
291 CModuleRef* CRsConfiguratorServer::FindCpm(const TCFModuleNameF& aName) |
|
292 /**Find a comms provider module by name. |
|
293 Search the modules array for a cpm with the matching name |
|
294 if found return a pointer, otherwise return NULL. |
|
295 @param aName The name of the cpm to be found. |
|
296 @return The cpm found or NULL |
|
297 @internalComponent |
|
298 */ |
|
299 { |
|
300 RPointerArray<CModuleRef>& modules = GetModulesList(); |
|
301 TInt count = modules.Count(); |
|
302 for(TInt i=0;i<count;i++) |
|
303 { |
|
304 CModuleRef* pModule = modules[i]; |
|
305 if(aName == pModule->Name()) |
|
306 { |
|
307 return pModule; |
|
308 } |
|
309 } |
|
310 return NULL; |
|
311 } |
|
312 |
|
313 |
|
314 |
|
315 |