|
1 /* |
|
2 * Copyright (c) 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 "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 * |
|
16 */ |
|
17 #include <apgcli.h> |
|
18 #include <swi/sisregistrysession.h> |
|
19 #include <swi/sisregistryentry.h> |
|
20 #include <javaregistry.h> |
|
21 #include <javaregistrypackageentry.h> |
|
22 #include <javaregistryapplicationentry.h> |
|
23 #include <mcsmenuutils.h> |
|
24 #include <utf.h> |
|
25 #include "mcsdef.h" |
|
26 #include "mcsmenu.h" |
|
27 #include "mcsmenuitem.h" |
|
28 #include "menuuninstalloperation.h" |
|
29 |
|
30 _LIT8( KAppMimeType, "x-epoc/x-sisx-app" ); |
|
31 _LIT8( KMidletMimeType, "application/java-archive" ); |
|
32 _LIT8( KWidgetMimeType, "application/x-nokia-widget"); |
|
33 |
|
34 const TUid KMidletType = { 0x10210E26 }; |
|
35 |
|
36 |
|
37 // ========================= LOCAL FUNCTIONS =============== |
|
38 |
|
39 // --------------------------------------------------------- |
|
40 // CleanupResetAndDestroy() |
|
41 // --------------------------------------------------------- |
|
42 // |
|
43 template<class T> |
|
44 static void CleanupResetAndDestroy( TAny* aObj ) |
|
45 { |
|
46 if( aObj ) |
|
47 { |
|
48 static_cast<T*>( aObj )->ResetAndDestroy(); |
|
49 } |
|
50 } |
|
51 |
|
52 // --------------------------------------------------------- |
|
53 // CleanupResetAndDestroyPushL |
|
54 // --------------------------------------------------------- |
|
55 // |
|
56 template<class T> |
|
57 static void CleanupResetAndDestroyPushL(T& aArray) |
|
58 { |
|
59 CleanupStack::PushL( TCleanupItem( &CleanupResetAndDestroy<T>, &aArray ) ); |
|
60 } |
|
61 |
|
62 // ========================= MEMBER FUNCTIONS ============== |
|
63 |
|
64 // --------------------------------------------------------- |
|
65 // CMenuUninstallOperation::~CMenuUninstallOperation |
|
66 // --------------------------------------------------------- |
|
67 // |
|
68 CMenuUninstallOperation::~CMenuUninstallOperation() |
|
69 { |
|
70 Cancel(); |
|
71 iUninstaller.Close(); |
|
72 delete iRemoveOperation; |
|
73 iWidgetRegistry.Close(); |
|
74 } |
|
75 |
|
76 // --------------------------------------------------------- |
|
77 // CMenuUninstallOperation::NewL |
|
78 // --------------------------------------------------------- |
|
79 // |
|
80 CMenuUninstallOperation* CMenuUninstallOperation::NewL( |
|
81 RMenu &aMenu, |
|
82 TInt aPriority, |
|
83 TRequestStatus &aObserverStatus, |
|
84 CMenuItem& aItem ) |
|
85 { |
|
86 CMenuUninstallOperation* self; |
|
87 |
|
88 self = new ( ELeave ) CMenuUninstallOperation( aMenu, aPriority, aObserverStatus ); |
|
89 CleanupStack::PushL( self ); |
|
90 self->ConstructL( aItem ); |
|
91 CleanupStack::Pop( self ); |
|
92 return self; |
|
93 } |
|
94 |
|
95 // --------------------------------------------------------- |
|
96 // CMenuUninstallOperation::CMenuUninstallOperation |
|
97 // --------------------------------------------------------- |
|
98 // |
|
99 CMenuUninstallOperation::CMenuUninstallOperation |
|
100 ( RMenu &aMenu, TInt aPriority, TRequestStatus &aObserverStatus ) |
|
101 : CMenuOperation( aMenu, aPriority, aObserverStatus ), |
|
102 iState( EIdle ), |
|
103 iRemoveOperation( NULL ) |
|
104 { |
|
105 CActiveScheduler::Add( this ); |
|
106 } |
|
107 |
|
108 // --------------------------------------------------------- |
|
109 // CMenuUninstallOperation::ConstructL |
|
110 // --------------------------------------------------------- |
|
111 // |
|
112 void CMenuUninstallOperation::ConstructL( CMenuItem& aItem ) |
|
113 { |
|
114 User::LeaveIfError( iWidgetRegistry.Connect() ); |
|
115 TBool exists; |
|
116 TPtrC uidAttr( aItem.GetAttributeL( KMenuAttrUid, exists ) ); |
|
117 TUint uid; |
|
118 TUid packageUid = KNullUid; |
|
119 |
|
120 |
|
121 if( !exists ) |
|
122 { |
|
123 User::Leave( KErrCorrupt ); |
|
124 } |
|
125 |
|
126 if( aItem.Flags() & TMenuItem::ELockDelete ) |
|
127 { |
|
128 iObserverStatus = KRequestPending; |
|
129 SetActive(); |
|
130 TRequestStatus* status = &iStatus; |
|
131 User::RequestComplete( status, KErrAccessDenied ); |
|
132 return; |
|
133 } |
|
134 |
|
135 User::LeaveIfError( iUninstaller.Connect() ); |
|
136 |
|
137 iId = aItem.Id(); |
|
138 |
|
139 // Prepare parameters |
|
140 MenuUtils::GetTUint( uidAttr, uid ); |
|
141 |
|
142 |
|
143 RBuf8 mimeType; |
|
144 mimeType.CleanupClosePushL(); |
|
145 AppInfoL( TUid::Uid( uid ), mimeType, packageUid ); |
|
146 |
|
147 // Commence the uninstallations |
|
148 iUninstaller.Uninstall( iStatus, packageUid, mimeType ); |
|
149 iObserverStatus = KRequestPending; |
|
150 if( mimeType == KMidletMimeType() |
|
151 && IsWidget( TUid::Uid( uid ) ) ) |
|
152 { |
|
153 //we remove java type app(it will gain different uid |
|
154 //during next install) and widget type app(it MIGHT get |
|
155 //different uid during next install) from xml |
|
156 iState = EUninstalling; |
|
157 } |
|
158 else |
|
159 { |
|
160 //if its not java or widget app we leave it in xml, |
|
161 //appscanner will hide it for later passible reinstallation |
|
162 iState = ERemoving; |
|
163 } |
|
164 CleanupStack::PopAndDestroy( &mimeType ); |
|
165 SetActive(); |
|
166 } |
|
167 |
|
168 // --------------------------------------------------------- |
|
169 // CMenuUninstallOperation::AppInfo |
|
170 // --------------------------------------------------------- |
|
171 // |
|
172 void CMenuUninstallOperation::AppInfoL( const TUid& aAppUid, |
|
173 RBuf8& aMimeType, TUid& aPackageUid ) |
|
174 { |
|
175 TUid typeUid; |
|
176 RApaLsSession apaLsSession; |
|
177 |
|
178 User::LeaveIfError( apaLsSession.Connect() ); |
|
179 CleanupClosePushL( apaLsSession ); |
|
180 User::LeaveIfError( apaLsSession.GetAllApps() ); |
|
181 |
|
182 if( KErrNone == apaLsSession.GetAppType( typeUid, aAppUid ) && |
|
183 typeUid == KMidletType ) |
|
184 { |
|
185 GetJavaSuitUidL( aAppUid, aPackageUid ); |
|
186 User::LeaveIfError( aMimeType.Create( KMidletMimeType() ) ); |
|
187 } |
|
188 else if( IsWidget( aAppUid ) ) |
|
189 { |
|
190 aPackageUid = aAppUid; |
|
191 CWidgetPropertyValue* widgetProperty( iWidgetRegistry. |
|
192 GetWidgetPropertyValueL( aAppUid, EMimeType ) ); |
|
193 CleanupStack::PushL( widgetProperty ); |
|
194 TPtrC mimeType( *widgetProperty ); |
|
195 if (mimeType.Length() == 0) |
|
196 { |
|
197 User::LeaveIfError( aMimeType.Create( KWidgetMimeType() ) ); |
|
198 } |
|
199 else |
|
200 { |
|
201 HBufC8* mimeType8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L( mimeType ); |
|
202 CleanupStack::PushL( mimeType8 ); |
|
203 User::LeaveIfError( aMimeType.Create( *mimeType8 ) ); |
|
204 CleanupStack::PopAndDestroy( mimeType8 ); |
|
205 } |
|
206 CleanupStack::PopAndDestroy( widgetProperty ); |
|
207 } |
|
208 else |
|
209 { |
|
210 TApaAppInfo appInfo; |
|
211 User::LeaveIfError( apaLsSession.GetAppInfo( appInfo, aAppUid ) ); |
|
212 if( !GetInstallPkgUidL( appInfo.iFullName, aPackageUid ) ) |
|
213 { |
|
214 aPackageUid = aAppUid; |
|
215 } |
|
216 User::LeaveIfError( aMimeType.Create( KAppMimeType() ) ); |
|
217 } |
|
218 |
|
219 CleanupStack::PopAndDestroy( &apaLsSession ); |
|
220 } |
|
221 |
|
222 // --------------------------------------------------------- |
|
223 // CMenuUninstallOperation::GetInstallPkgUidL |
|
224 // --------------------------------------------------------- |
|
225 // |
|
226 TBool CMenuUninstallOperation::GetInstallPkgUidL( const TDesC& aAppFullName, TUid& aPackageUid ) |
|
227 { |
|
228 // Search for the full name of the application amongst every file name in |
|
229 // every installed packages. |
|
230 TBool found = EFalse; |
|
231 Swi::RSisRegistrySession iSisRegSession; |
|
232 |
|
233 // Get the array of ids of every installed packages |
|
234 if( KErrNone != iSisRegSession.Connect() ) |
|
235 { |
|
236 return found; |
|
237 } |
|
238 CleanupClosePushL( iSisRegSession ); |
|
239 |
|
240 RArray<TUid> packageIds; |
|
241 CleanupClosePushL( packageIds ); |
|
242 |
|
243 iSisRegSession.InstalledUidsL( packageIds ); |
|
244 |
|
245 RPointerArray< HBufC > packageFiles; |
|
246 CleanupResetAndDestroyPushL( packageFiles ); |
|
247 |
|
248 for( TInt i = 0; i < packageIds.Count() && !found; ++i ) |
|
249 { |
|
250 const TUid packageId = packageIds[i]; |
|
251 Swi::RSisRegistryEntry packageEntry; |
|
252 |
|
253 // Get the array of file names in the current install package and look |
|
254 // if there is one suggesting that the application was installed from |
|
255 // the package. |
|
256 if( KErrNone == packageEntry.Open( iSisRegSession, packageId ) ) |
|
257 { |
|
258 CleanupClosePushL( packageEntry ); |
|
259 packageEntry.FilesL( packageFiles ); |
|
260 for( TInt pf = 0; pf < packageFiles.Count() && !found; ++pf ) |
|
261 { |
|
262 if( packageFiles[pf]->FindC( aAppFullName ) == 0 ) |
|
263 { |
|
264 aPackageUid = packageId; |
|
265 found = ETrue; |
|
266 } |
|
267 } |
|
268 packageFiles.ResetAndDestroy(); |
|
269 CleanupStack::PopAndDestroy( &packageEntry ); |
|
270 } |
|
271 } |
|
272 |
|
273 CleanupStack::PopAndDestroy( &packageFiles ); |
|
274 CleanupStack::PopAndDestroy( &packageIds ); |
|
275 CleanupStack::PopAndDestroy( &iSisRegSession ); |
|
276 |
|
277 return found; |
|
278 } |
|
279 |
|
280 // --------------------------------------------------------- |
|
281 // CMenuUninstallOperation::GetJavaSuitUidL |
|
282 // --------------------------------------------------------- |
|
283 // |
|
284 void CMenuUninstallOperation::GetJavaSuitUidL( const TUid& aAppUid, TUid& aPackageUid ) |
|
285 { |
|
286 Java::CJavaRegistry* javaRegistry; |
|
287 javaRegistry = Java::CJavaRegistry::NewLC(); |
|
288 |
|
289 Java::CJavaRegistryEntry* regEntry = |
|
290 javaRegistry->RegistryEntryL( aAppUid ); |
|
291 if( regEntry ) |
|
292 { |
|
293 CleanupStack::PushL( regEntry ); |
|
294 |
|
295 Java::TJavaRegistryEntryType entryType = regEntry->Type(); |
|
296 |
|
297 if ( ( entryType >= Java::EGeneralPackage ) && |
|
298 (entryType < Java::EGeneralApplication) ) |
|
299 { |
|
300 //package entry |
|
301 aPackageUid = regEntry->Uid(); |
|
302 } |
|
303 else |
|
304 { |
|
305 //application entry |
|
306 Java::CJavaRegistryApplicationEntry* regApplicationEntry = |
|
307 static_cast<Java::CJavaRegistryApplicationEntry*>( regEntry ); |
|
308 Java::CJavaRegistryPackageEntry* regPackageEntry = |
|
309 regApplicationEntry->PackageEntryL(); |
|
310 aPackageUid = regPackageEntry->Uid(); |
|
311 delete regPackageEntry; |
|
312 } |
|
313 CleanupStack::PopAndDestroy( regEntry ); |
|
314 } |
|
315 else |
|
316 { |
|
317 aPackageUid = aAppUid; |
|
318 } |
|
319 CleanupStack::PopAndDestroy( javaRegistry ); |
|
320 } |
|
321 |
|
322 // --------------------------------------------------------- |
|
323 // CMenuUninstallOperation::IsWidget |
|
324 // --------------------------------------------------------- |
|
325 // |
|
326 |
|
327 TBool CMenuUninstallOperation::IsWidget( const TUid& aAppUid ) |
|
328 { |
|
329 return iWidgetRegistry.IsWidget( aAppUid ); |
|
330 } |
|
331 |
|
332 // --------------------------------------------------------- |
|
333 // CMenuUninstallOperation::RunL |
|
334 // --------------------------------------------------------- |
|
335 // |
|
336 void CMenuUninstallOperation::RunL() |
|
337 { |
|
338 if( KErrNone == iStatus.Int() ) |
|
339 { |
|
340 switch( iState ) |
|
341 { |
|
342 case EUninstalling: |
|
343 { |
|
344 __ASSERT_DEBUG( NULL == iRemoveOperation, User::Invariant() ); |
|
345 iState = ERemoving; |
|
346 iRemoveOperation = iMenu.RemoveL( iId, iStatus ); |
|
347 SetActive(); |
|
348 } |
|
349 break; |
|
350 |
|
351 case ERemoving: |
|
352 { |
|
353 delete iRemoveOperation; |
|
354 iRemoveOperation = NULL; |
|
355 iState = EIdle; |
|
356 TRequestStatus* status = &iObserverStatus; |
|
357 User::RequestComplete( status, iStatus.Int() ); |
|
358 } |
|
359 break; |
|
360 |
|
361 default: |
|
362 // Object is in an unexpected state |
|
363 __ASSERT_DEBUG( 0, User::Invariant() ); |
|
364 } |
|
365 } |
|
366 else if ( KErrNotFound == iStatus.Int() && iState == ERemoving ) |
|
367 { |
|
368 // Most probably: After uninstalling the application the application |
|
369 // scanner removed the corresponding item from the xml so not finding |
|
370 // the menuitem is not an error here. |
|
371 delete iRemoveOperation; |
|
372 iRemoveOperation = NULL; |
|
373 iState = EIdle; |
|
374 TRequestStatus* status = &iObserverStatus; |
|
375 User::RequestComplete( status, KErrNone ); |
|
376 } |
|
377 else |
|
378 { |
|
379 // Report error |
|
380 delete iRemoveOperation; |
|
381 iRemoveOperation = NULL; |
|
382 iState = EIdle; |
|
383 TRequestStatus* status = &iObserverStatus; |
|
384 User::RequestComplete( status, iStatus.Int() ); |
|
385 } |
|
386 } |
|
387 |
|
388 // --------------------------------------------------------- |
|
389 // CMenuUninstallOperation::DoCancel |
|
390 // --------------------------------------------------------- |
|
391 // |
|
392 void CMenuUninstallOperation::DoCancel() |
|
393 { |
|
394 switch( iState ) |
|
395 { |
|
396 case EUninstalling: |
|
397 { |
|
398 iState = EIdle; |
|
399 } |
|
400 break; |
|
401 |
|
402 case ERemoving: |
|
403 { |
|
404 delete iRemoveOperation; |
|
405 iRemoveOperation = NULL; |
|
406 iState = EIdle; |
|
407 } |
|
408 break; |
|
409 |
|
410 default: |
|
411 // Object is in an unexpected state |
|
412 __ASSERT_DEBUG( 0, User::Invariant() ); |
|
413 } |
|
414 iUninstaller.CancelAsyncRequest( SwiUI::ERequestUninstall ); |
|
415 // Complete the caller: |
|
416 TRequestStatus* status = &iObserverStatus; |
|
417 User::RequestComplete( status, KErrCancel ); |
|
418 } |
|
419 |
|
420 // --------------------------------------------------------- |
|
421 // CMenuUninstallOperation::RunError |
|
422 // --------------------------------------------------------- |
|
423 // |
|
424 TInt CMenuUninstallOperation::RunError( TInt aError ) |
|
425 { |
|
426 TRequestStatus* status = &iObserverStatus; |
|
427 User::RequestComplete( status, aError ); |
|
428 |
|
429 return KErrNone; |
|
430 } |