diff -r 0fd27995241b -r 9ac0a0a7da70 javatools/javaappbackconverter/src.s60/backconverter.cpp --- a/javatools/javaappbackconverter/src.s60/backconverter.cpp Tue May 11 16:07:20 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,570 +0,0 @@ -/* -* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: Java platform 2.0 javaappbackconverter process. -* Reregisters the old S60 MIDlets back to AppArc -* -*/ - - -#include -#include -#include -#include - -#include "javacommonutils.h" -#include "javauids.h" -#include "backconverter.h" -#include "noarmlogs.h" - - -const TInt KDelayWhenWaitingAppArc = 500000; - -// This is in the private data cage of javaappbackconverter -_LIT(KMidletImportDirectory, "C:\\private\\20022D90\\data\\"); - -// Symbian file path separator -_LIT(KPathSeperator, "\\"); - -// Postfix for the fake application name generated only to make AppArc happy -_LIT(KAppPostfix, ".fakeapp"); - -// The application type Uid for MIDlets in S60 -const TUid KUidMidletApplicationType = { 0x10210E26 }; - -/** - * To create new instance of this class. - * - * @param aFs - A reference to the file server. - * @return Reference to the object of this class. - * @exception If construction fails. - * - */ -CBackConverter* CBackConverter::NewLC(RFs& aFs) -{ - CBackConverter* self = new(ELeave) CBackConverter(aFs); - CleanupStack::PushL(self); - self->ConstructL(); - return self; -} - -/** - * To do 1st phase construction for this object. - * - * Adds this active object to the scheduler. - * - * @param param aFs - A reference to the file server. - * @return Reference to the object of this class. - */ -CBackConverter::CBackConverter(RFs& aFs) : - CActive(EPriorityStandard), iFs(aFs) -{ - CActiveScheduler::Add(this); -} - -/** - * To do 2nd phase construction for this object. - * - * @exception If the method is not able to allocate necessary buffers. - */ -void CBackConverter::ConstructL() -{ - JELOG2(EJavaConverters); - - iMidlets = new(ELeave) CMidletList(); - iState = EInitialize; -} - -/** - * Deletes this object. - * All allocated resources are released. - */ -CBackConverter::~CBackConverter() -{ - JELOG2(EJavaConverters); - Cancel(); - if (iMidlets) - { - iMidlets->ResetAndDestroy(); - delete iMidlets; - iMidlets = NULL; - } -} - -/** - * To start back conversion - */ -void CBackConverter::Start() -{ - JELOG2(EJavaConverters); - iState = EInitialize; - CompleteRequest(); -} - -/** - * To stop whole back conversion. - * Stops the active scheduler. - */ -void CBackConverter::Exit() -{ - Deque(); - CActiveScheduler::Stop(); -} - -/** - * To complete the request for this object. - * - * @Postconditions The following conditions are true immediately after - * returning from this method. - * - iStatus == KErrNone - * - IsActive() == ETrue - */ -void CBackConverter::CompleteRequest() -{ - JELOG2(EJavaConverters); - - TRequestStatus *status = &iStatus; - User::RequestComplete(status, KErrNone); - if (!IsActive()) - { - SetActive(); - } -} - -/** - * To run this active object. - * - * The state logic is: - * - * EInitialize: - * - if midlet export data file does not exist, exit - * - * EReadConversionData: - * - read data from data file to iMidlets - * - * EReregisterMidlets: - * - register each midlet in iMidlets to AppArc - * - * EExit: - * - free resources and exit - * - */ -void CBackConverter::RunL() -{ - JELOG2(EJavaConverters); - - switch (iState) - { - - case EInitialize: - { - LOG(EJavaConverters, EInfo, - "CBackConverter::RunL EInitialize"); - - TFileName dataFile(KMidletImportDirectory); - dataFile.Append(KMidletExportDataFileName); - TUint attributes; - TInt err = iFs.Att(dataFile, attributes); - if (KErrNone != err) - { - WLOG1(EJavaConverters, - "CBackConverter::RunL EInitialize " - "Data file does not exist (%d). Cannot do back conversion.", err); - LOG1WSTR(EJavaConverters, EInfo, - "Data file name is %s", (wchar_t *)(dataFile.PtrZ())); - iState = EExit; - } - else - { - iState = EReadConversionData; - } - CompleteRequest(); - } - break; - - case EReadConversionData: - { - LOG(EJavaConverters, EInfo, - "CBackConverter::RunL EReadConversionData"); - - // Read all midlet info from data file to iMidlets - TFileName importDirectory(KMidletImportDirectory); - iMidlets->ImportListL(iFs, importDirectory); - - iState = EUnregisterOldMidletData; - CompleteRequest(); - } - break; - - case EUnregisterOldMidletData: - { - LOG(EJavaConverters, EInfo, - "CBackConverter::RunL EUnregisterOldMidletData"); - - // If executing backconverter after user cancel, - // AppArc may contain Java 2.0 specific data - // for converted midlets. Remove it or reregistration - // will not update the data. - UnregisterOldMidletData(); - - iState = EReregisterMidlets; - CompleteRequest(); - } - break; - - case EReregisterMidlets: - { - LOG(EJavaConverters, EInfo, - "CBackConverter::RunL EReregisterMidlets"); - - // Reregister old midlet info back to AppArc - RegisterMidletsL(); - - // If this line is executed, registering old midlets - // back to AppArc succeeded. So the data file can be - // removed. - RemoveDataFile(); - - iState = EExit; - CompleteRequest(); - } - break; - - case EExit: - { - LOG(EJavaConverters, EInfo, "CBackConverter::RunL EExit"); - - FullCleanup(); - - // The whole javaappbackconverter process is stopped. - Exit(); - } - break; - - } -} - -/** - * To handle leave from RunL. - * This method exits this active object using normal state machine - * After calling this method this active object will exit. - * - * @param aError - A reason of error. - * @return KErrNone. - */ -TInt CBackConverter::RunError(TInt aError) -{ - ELOG2(EJavaConverters, - "CBackConverter::RunError(%d) from state %d", aError, iState); - - Cancel(); - - iState = EExit; - CompleteRequest(); - - return KErrNone; -} - -/** - * To do cancelling for this object. - * - */ -void CBackConverter::DoCancel() -{ - ELOG1(EJavaConverters, - "CBackConverter::DoCancel from state %d", iState); - -} - -/** - * To cleanup member variables. - */ -void CBackConverter::FullCleanup() -{ - JELOG2(EJavaPreinstaller); - - if (iMidlets) - { - iMidlets->ResetAndDestroy(); - delete iMidlets; - iMidlets = NULL; - } -} - -/** - * Register all midlets in iMidlets to AppArc. - */ -void CBackConverter::RegisterMidletsL() -{ - RApaLsSession apaSession; - - // open AppArc session - TInt err = apaSession.Connect(); - if (KErrNone != err) - { - // Cannot connect to AppArc server - ELOG(EJavaConverters, - "CBackConverter::RegisterMidletsL: Cannot connect to AppArc server"); - User::Leave(err); - } - CleanupClosePushL(apaSession); - - // Delete any pending (un)registrations (possible if - // e.g. device rebooted before commit). - // This call does nothing if there is no pending registrations. - // Ignore errors. - (void)apaSession.RollbackNonNativeApplicationsUpdates(); - - // Prepare for Java application registrations / unregistrations - TRAP(err, apaSession.PrepareNonNativeApplicationsUpdatesL()); - if (KErrNone != err) - { - ELOG1(EJavaConverters, - "CBackConverter::RegisterMidletsL: " - "PrepareNonNativeApplicationsUpdatesL leaved with err %d", - err); - User::Leave(err); - } - - // register midlets one by one - CMidletInfo *midlet = iMidlets->GetFirst(); - TBuf8<512> midletDesc; - - while (NULL != midlet) - { - midlet->ToString8(midletDesc); - WLOG(EJavaConverters, - "CBackConverter::RegisterMidletsL Going to reregister this midlet:"); - midletDesc.ZeroTerminate(); - WLOG(EJavaPreinstaller, (const char *)(midletDesc.Ptr())); - midletDesc.Zero(); - - RegisterOneMidletL(&apaSession, midlet); - midlet = iMidlets->GetNext(); - } - - // commit registrations - TRAP(err, apaSession.CommitNonNativeApplicationsUpdatesL()); - if (KErrNone != err) - { - ELOG1(EJavaConverters, - "CBackConverter::RegisterMidletsL: " - "CommitNonNativeApplicationsUpdatesL leaved with err %d", - err); - User::Leave(err); - } - - CleanupStack::PopAndDestroy(); // apaSession -} - -/** - * Register one midlet to AppArc - * - * @param aSession AppArc session - * @param aMidlet the midlet to be registered - * @exception If registering application fails - */ -void CBackConverter::RegisterOneMidletL(RApaLsSession *aSession, CMidletInfo *aMidlet) -{ - JELOG2(EJavaPreinstaller); - - RFile appArcIcon; - TInt numberOfIcons = 1; - - // open the icon in the shared mode required by AppArc - TInt err = appArcIcon.Open( - iFs, - aMidlet->GetIconFileName(), - (EFileShareReadersOrWriters | EFileWrite)); - if (KErrNone != err) - { - ELOG1(EJavaConverters, - "CBackConverter::RegisterOneMidletL: Cannot open icon, err code is %d ", - err); - User::Leave(err); - } - - // Now icon is open - CleanupClosePushL(appArcIcon); - - // Generate the executable name name using the same - // algorithm as used earlier in S60 platform - // in case some external S60 application - // needs to parse the Uid from the executable name. - TFileName appName; - appName.Copy(KPathSeperator); - appName.AppendNum(aMidlet->GetMidletUid().iUid); - appName.Append(KAppPostfix); - - // Create writer needed for actual registration - CApaRegistrationResourceFileWriter *writer = NULL; - writer = - CApaRegistrationResourceFileWriter::NewL( - aMidlet->GetMidletUid(), - appName, - TApaAppCapability::ENonNative); - CleanupStack::PushL(writer); - - writer->SetGroupNameL(aMidlet->GetGroupName()); - - // Write MIDlet suite id and MIDlet id to opaque data (needed by S60 MIDlet launcher) - TBuf8<8> opaqueData; // opaque data will contain two signed 32-bit int - RDesWriteStream writeStream(opaqueData); - writeStream.WriteInt32L(aMidlet->GetSuiteId()); - writeStream.WriteInt32L(aMidlet->GetMidletId()); - writeStream.CommitL(); - writer->SetOpaqueDataL(opaqueData); - - CApaLocalisableResourceFileWriter* lWriter = NULL; - lWriter = - CApaLocalisableResourceFileWriter::NewL( - KNullDesC, // short caption - aMidlet->GetMidletName(), // caption - numberOfIcons, - KNullDesC); - CleanupStack::PushL(lWriter); - - TDriveUnit targetDrive(aMidlet->GetDrive()); - - // Register application to AppArc - aSession->RegisterNonNativeApplicationL( - KUidMidletApplicationType, - targetDrive, - *writer, - lWriter, - &appArcIcon); - - CleanupStack::PopAndDestroy(lWriter); - CleanupStack::PopAndDestroy(writer); - // close icon file handle - CleanupStack::PopAndDestroy(); // appArcIcon -} - -/** - * Unregisters the applications to be back converted from AppArc - * so that they can be registered again with the same Uid but with - * new opaque data (needed for old S60 Java). - * This function needs to called only if making back conversion after - * the user has canceled the installation of Java 2.0. - * If back conversion is done while uninstalling Java 2.0, all Java applications - * have been uninstalled and there are no Uids to be unregistered. - * - * Leaves with error code if AppArc cannot be connected or if - * unregistrations cannot be committed. - */ -void CBackConverter::UnregisterOldMidletData() -{ - // connect to AppArc - RApaLsSession apaSession; - - TInt err = apaSession.Connect(); - if (KErrNone != err) - { - // Fatal error, try to connect again. The midlets cannot be back converted - // using the same uids as earlier if the unregistration cannot be done. - TInt retryCount = 0; - do - { - ELOG1(EJavaConverters, - "CBackConverter::UnregisterCurrentJavaAppsL Cannot connect to " - "AppArc server, err %d", err); - - // wait - User::After(KDelayWhenWaitingAppArc); - - err = apaSession.Connect(); - if (KErrNone == err) - { - break; - } - - retryCount++; - } - while (retryCount < 10); - - if (KErrNone != err) - { - return; - } - } - - // Delete any pending (un)registrations (possible if - // e.g. device rebooted before commit). - // This call does nothing if there is no pending registrations. - // Ignore errors. - (void)apaSession.RollbackNonNativeApplicationsUpdates(); - - // Prepare for Java application unregistrations - TRAP(err, apaSession.PrepareNonNativeApplicationsUpdatesL()); - if (KErrNone != err) - { - ELOG1(EJavaConverters, - "CBackConverter::UnregisterCurrentJavaAppsL: " - "PrepareNonNativeApplicationsUpdatesL leaved with err %d", - err); - apaSession.Close(); - return; - } - - // Unregister all apps - CMidletInfo *midlet = iMidlets->GetFirst(); - - while (NULL != midlet) - { - TRAP(err, apaSession.DeregisterNonNativeApplicationL(midlet->GetMidletUid())); - if (KErrNone != err) - { - WLOG2(EJavaConverters, - "CBackConverter::UnregisterCurrentJavaAppsL: " - "DeregisterNonNativeApplicationL leaved with err %d for uid %d", - err, midlet->GetMidletUid().iUid); - // Ignore error, this particular application cannot be back converted. - } - - midlet = iMidlets->GetNext(); - } - - // Commit unregistrations - TRAP(err, apaSession.CommitNonNativeApplicationsUpdatesL()) - { - if (KErrNone != err) - { - ELOG1(EJavaConverters, - "CBackConverter::UnregisterCurrentJavaAppsL: " - "CommitNonNativeApplicationsUpdatesL leaved with err %d", - err); - apaSession.Close(); - return; - } - } - - apaSession.Close(); - return; -} - -/** - * Remove data file that contains info about midlets to be back converted. - */ -void CBackConverter::RemoveDataFile() -{ - TFileName dataFile(KMidletImportDirectory); - dataFile.Append(KMidletExportDataFileName); - - TInt err = iFs.Delete(dataFile); - if (KErrNone != err) - { - ELOG1(EJavaConverters, - "CBackConverter::RemoveDataFile: Cannot delete data file, err %d ", - err); - } -}