|
1 /* |
|
2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * Implements an AsyncRequest object for the SIF Transport library |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include <e32base.h> |
|
21 #include <e32std.h> |
|
22 #include <apgcli.h> |
|
23 #include <scs/ipcstream.h> |
|
24 #include <scs/nullstream.h> |
|
25 #include <scs/cleanuputils.h> |
|
26 #include <usif/usiferror.h> |
|
27 #include "usiflog.h" |
|
28 #include "siftransportserver.h" |
|
29 #include "siftransportcommon.h" |
|
30 |
|
31 using namespace Usif; |
|
32 |
|
33 void CSifTransportRequest::CreateAndExecuteL(TInt aFunction, CSifTransportSession* aSession, TransportTaskFactory::GenerateTask aTaskFactory, const RMessage2& aMessage) |
|
34 { |
|
35 DEBUG_PRINTF2(_L8("CSifTransportRequest::CreateAndExecuteL for aFunction = %d\n"),aFunction); |
|
36 |
|
37 CSifTransportRequest* self = new (ELeave) CSifTransportRequest(aFunction, aSession, aMessage); |
|
38 CleanupStack::PushL(self); |
|
39 |
|
40 // Validate the file handle adoption. |
|
41 TInt err = self->AdoptFileHandle(aFunction, aMessage); |
|
42 if (err != KErrNone) |
|
43 { |
|
44 DEBUG_PRINTF2(_L8("Failed to adopt a file handle from RMessage2, error = %d\n"),err); |
|
45 aMessage.Panic(KSifTransportServerRequestError, err); |
|
46 User::Leave(err); |
|
47 } |
|
48 |
|
49 self->PrepareParamsL(); |
|
50 self->SetupRequestL(aTaskFactory); |
|
51 self->TransferToScsFrameworkL(); |
|
52 CleanupStack::Pop(self); |
|
53 self->SetActive(); |
|
54 self->LaunchTask(); |
|
55 } |
|
56 |
|
57 // Read file handle from aMessage for all request by file handle. |
|
58 TInt CSifTransportRequest::AdoptFileHandle(TInt aFunction, const RMessage2& aMessage) |
|
59 { |
|
60 if (aFunction & EFileHandleInIpc) |
|
61 { |
|
62 return (iFile.AdoptFromClient(aMessage, 0, 1)); |
|
63 } |
|
64 return KErrNone; |
|
65 } |
|
66 |
|
67 CSifTransportRequest::CSifTransportRequest(TInt aFunction, CSifTransportSession* aSession, const RMessage2& aMessage) |
|
68 : CAsyncRequest(aSession, 0, aMessage), iFunction(aFunction), iSecurityContext(aMessage) |
|
69 // iFile and iSecurityContext above cannot be a local variable because we pass it to SIF plug-ins during asynchronous calls. |
|
70 // Hence, their lifetime must be guaranteed. |
|
71 { |
|
72 if (iFunction & EInstall) |
|
73 { |
|
74 iComponentId = EInvalidComponentId; |
|
75 } |
|
76 |
|
77 // Read component id from aMessage. |
|
78 if (aFunction & EComponentIdInIpc) |
|
79 { |
|
80 iComponentId = aMessage.Int0(); |
|
81 } |
|
82 } |
|
83 |
|
84 CSifTransportRequest::~CSifTransportRequest() |
|
85 { |
|
86 DEBUG_PRINTF2(_L8("CSifRequest::~CSifRequest() for aFunction = %d\n"),iFunction); |
|
87 |
|
88 Cancel(); |
|
89 |
|
90 if (iParams.iFileHandle != NULL) |
|
91 { |
|
92 iParams.iFileHandle->Close(); |
|
93 } |
|
94 |
|
95 delete iParams.iFileName; |
|
96 delete iParams.iComponentInfo; |
|
97 delete iParams.iCustomArguments; |
|
98 delete iParams.iCustomResults; |
|
99 delete iTask; |
|
100 } |
|
101 |
|
102 void CSifTransportRequest::PrepareParamsL() |
|
103 { |
|
104 DEBUG_PRINTF2(_L8("CSifRequest::PrepareParamsL() for aFunction = %d\n"),iFunction); |
|
105 |
|
106 // Make sure that the buffers for opaque containers are not allocated |
|
107 ASSERT(iParams.iComponentInfo == NULL); |
|
108 ASSERT(iParams.iCustomArguments == NULL); |
|
109 ASSERT(iParams.iCustomResults == NULL); |
|
110 |
|
111 // Read file name from iMessagePtr2 |
|
112 if (iFunction & EFileNameInIpc) |
|
113 { |
|
114 // iFileName below cannot be a local variable because we pass it to installation |
|
115 // requests during asynchronous calls. Hence, the lifetime of it must be guaranteed. |
|
116 HBufC* fileName = HBufC::NewL(KMaxFileName); |
|
117 iParams.iFileName = fileName; |
|
118 TPtr bufFileName(fileName->Des()); |
|
119 iMessagePtr2.ReadL(0, bufFileName); |
|
120 } |
|
121 |
|
122 // Create component info |
|
123 if (iFunction & EComponentInfoInIpc) |
|
124 { |
|
125 iParams.iComponentInfo = CComponentInfo::NewL(); |
|
126 } |
|
127 |
|
128 // Create containers for custom params |
|
129 if (iFunction & EOpaqueDataToPlugin) |
|
130 { |
|
131 // We have to also create these containers for asynchronous requests |
|
132 // without opaque params. This is because a request API may not |
|
133 // provide methods without opaque params in order to keep it small. |
|
134 iParams.iCustomArguments = COpaqueNamedParams::NewL(); |
|
135 iParams.iCustomResults = COpaqueNamedParams::NewL(); |
|
136 } |
|
137 |
|
138 // Read custom arguments from iMessagePtr2 |
|
139 if ((iFunction & EOpaqueDataInIpc) && (iFunction & EOpaqueDataToPlugin)) |
|
140 { |
|
141 RIpcReadStream ipcrstream; |
|
142 ipcrstream.Open(iMessagePtr2, 2); |
|
143 CleanupClosePushL(ipcrstream); |
|
144 ipcrstream >> const_cast<COpaqueNamedParams&>(*iParams.iCustomArguments); |
|
145 CleanupStack::PopAndDestroy(&ipcrstream); |
|
146 } |
|
147 } |
|
148 |
|
149 void CSifTransportRequest::SetupRequestL(TransportTaskFactory::GenerateTask aTaskFactory) |
|
150 { |
|
151 DEBUG_PRINTF2(_L8("CSifTransportRequest::SetupInstallerRequestL() for aFunction = %d\n"),iFunction); |
|
152 |
|
153 iParams.iSecurityContext = &iSecurityContext; |
|
154 iParams.iRequestStatus = &iStatus; |
|
155 |
|
156 // Instantiate an appropriate SIF Transport Task using aTaskFactory |
|
157 switch (iFunction) |
|
158 { |
|
159 case EGetComponentInfoByFileName: |
|
160 case EGetComponentInfoByFileHandle: |
|
161 { |
|
162 if (iParams.iFileName == NULL) |
|
163 { |
|
164 iParams.iFileHandle = &iFile; |
|
165 } |
|
166 |
|
167 iTask = aTaskFactory(TransportTaskFactory::EGetComponentInfo, iParams); |
|
168 break; |
|
169 } |
|
170 |
|
171 case EInstallByFileName: |
|
172 case EInstallByFileHandle: |
|
173 case EInstallByFileNameWithOpaqueData: |
|
174 case EInstallByFileHandleWithOpaqueData: |
|
175 { |
|
176 if (iParams.iFileName == NULL) |
|
177 { |
|
178 iParams.iFileHandle = &iFile; |
|
179 } |
|
180 |
|
181 iTask = aTaskFactory(TransportTaskFactory::EInstall, iParams); |
|
182 break; |
|
183 } |
|
184 |
|
185 case EUninstall: |
|
186 case EUninstallWithOpaqueData: |
|
187 { |
|
188 iParams.iComponentId = iComponentId; |
|
189 iTask = aTaskFactory(TransportTaskFactory::EUninstall, iParams); |
|
190 break; |
|
191 } |
|
192 |
|
193 case EActivate: |
|
194 { |
|
195 iParams.iComponentId = iComponentId; |
|
196 |
|
197 iTask = aTaskFactory(TransportTaskFactory::EActivate, iParams); |
|
198 break; |
|
199 } |
|
200 |
|
201 case EDeactivate: |
|
202 { |
|
203 iParams.iComponentId = iComponentId; |
|
204 iTask = aTaskFactory(TransportTaskFactory::EDeactivate, iParams); |
|
205 break; |
|
206 } |
|
207 |
|
208 default: |
|
209 ASSERT(0); |
|
210 } |
|
211 } |
|
212 |
|
213 void CSifTransportRequest::DoCancel() |
|
214 { |
|
215 DEBUG_PRINTF2(_L8("CSifTransportRequest::DoCancel() for aFunction = %d\n"),iFunction); |
|
216 |
|
217 ASSERT(iTask != NULL); |
|
218 |
|
219 iTask->Cancel(); |
|
220 } |
|
221 |
|
222 void CSifTransportRequest::DoCleanup() |
|
223 { |
|
224 DEBUG_PRINTF2(_L8("CSifTransportRequest::DoCleanup() for aFunction = %d\n"),iFunction); |
|
225 Cancel(); |
|
226 } |
|
227 |
|
228 void CSifTransportRequest::ProcessOpaqueResultsL() |
|
229 { |
|
230 // Write custom results to iMessagePtr2 |
|
231 RIpcWriteStream ipcwstream; |
|
232 ipcwstream.Open(iMessagePtr2, 3); |
|
233 CleanupClosePushL(ipcwstream); |
|
234 ipcwstream << *iParams.iCustomResults; |
|
235 CleanupStack::PopAndDestroy(&ipcwstream); |
|
236 } |
|
237 |
|
238 void CSifTransportRequest::ProcessTaskResultsL() |
|
239 { |
|
240 if (iFunction & EComponentInfoInIpc) |
|
241 { |
|
242 // Write component info to iMessagePtr2 |
|
243 RIpcWriteStream ipcwstream; |
|
244 ipcwstream.Open(iMessagePtr2, 2); |
|
245 CleanupClosePushL(ipcwstream); |
|
246 ipcwstream << *iParams.iComponentInfo; |
|
247 CleanupStack::PopAndDestroy(&ipcwstream); |
|
248 } |
|
249 |
|
250 if (iFunction & EOpaqueDataInIpc) |
|
251 { |
|
252 TRAPD(err, ProcessOpaqueResultsL()); |
|
253 if (err != KErrNone) |
|
254 { |
|
255 DEBUG_PRINTF3(_L8("CSifRequest::RunL() for aFunction = %d - received error %d while processing opaque results. The error is ignored, since the install operation has already completed"),iFunction, err); |
|
256 } |
|
257 } |
|
258 } |
|
259 |
|
260 void CSifTransportRequest::RunL() |
|
261 { |
|
262 DEBUG_PRINTF2(_L8("CSifTransportRequest::RunL() for aFunction = %d\n"),iFunction); |
|
263 |
|
264 if (iTaskComplete) |
|
265 { |
|
266 ProcessTaskResultsL(); |
|
267 CAsyncRequest::RunL(); |
|
268 } |
|
269 else |
|
270 { |
|
271 SetActive(); |
|
272 iTaskComplete = iTask->Execute(); |
|
273 } |
|
274 } |
|
275 |
|
276 void CSifTransportRequest::LaunchTask() |
|
277 { |
|
278 iTaskComplete = iTask->Execute(); |
|
279 } |