javatools/javaappconverter/src.s60/silentmidletconvert.cpp
branchRCL_3
changeset 14 04becd199f91
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     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 "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: Java platform 2.0 javaappconverter process
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32base.h>
       
    20 #include <apgcli.h>
       
    21 #include <pathinfo.h>
       
    22 #include <driveinfo.h>
       
    23 
       
    24 #include "silentmidletconvert.h"
       
    25 #include "javauids.h"
       
    26 #include "javacommonutils.h"
       
    27 #include "logger.h"
       
    28 #include "javaprocessconstants.h"
       
    29 #include "javasymbianoslayer.h"
       
    30 
       
    31 
       
    32 using namespace java::util;
       
    33 
       
    34 _LIT(KJarFileNameSuffix, ".jar");
       
    35 _LIT(KJadFileNameSuffix, ".jad");
       
    36 _LIT(KFLJarFileNameSuffix, ".dm");
       
    37 _LIT(KSDJarFileNameSuffix, ".dcf");
       
    38 _LIT(KSMCBackSplash, "\\");
       
    39 
       
    40 // The directory where the java applications to be converted are searched from
       
    41 _LIT(KMidletSuiteInstallBasePath, ":\\Private\\102033E6\\MIDlets\\");
       
    42 
       
    43 
       
    44 /**
       
    45  * To create new instance of this class.
       
    46  *
       
    47  * @param aFs - A reference to the file server.
       
    48  * @return Reference to the object of this class.
       
    49  * @exception If construction fails.
       
    50  *
       
    51  */
       
    52 CSilentMIDletConvert* CSilentMIDletConvert::NewLC(RFs& aFs)
       
    53 {
       
    54     CSilentMIDletConvert* self = new(ELeave) CSilentMIDletConvert(aFs);
       
    55     CleanupStack::PushL(self);
       
    56     self->ConstructL();
       
    57     return self;
       
    58 }
       
    59 
       
    60 /**
       
    61  * To do 1st phase construction for this object.
       
    62  *
       
    63  * Adds this active object to the scheduler.
       
    64  *
       
    65  * @param aFs - A reference to the file server.
       
    66  */
       
    67 CSilentMIDletConvert::CSilentMIDletConvert(RFs& aFs) :
       
    68         CActive(EPriorityStandard), iFs(aFs), iNumberOfAppsToInstall(0),
       
    69         iDefaultTargetInstallationDrive(-1)
       
    70 {
       
    71     CActiveScheduler::Add(this);
       
    72 }
       
    73 
       
    74 /**
       
    75  * To do 2nd phase construction for this object.
       
    76  *
       
    77  * @exception If the method is not able to allocate necessary buffers.
       
    78  */
       
    79 void CSilentMIDletConvert::ConstructL()
       
    80 {
       
    81     JELOG2(EJavaConverters);
       
    82 
       
    83     iConvertServer = new(ELeave) ConvertServer();
       
    84 }
       
    85 
       
    86 /**
       
    87  * Deletes this object.
       
    88  * All allocated resources are released.
       
    89  */
       
    90 CSilentMIDletConvert::~CSilentMIDletConvert()
       
    91 {
       
    92     JELOG2(EJavaConverters);
       
    93     Cancel();
       
    94     iInstallFiles.ResetAndDestroy();
       
    95     iInstallFiles.Close();
       
    96 
       
    97     iDirs.ResetAndDestroy();
       
    98     iDirs.Close();
       
    99 
       
   100     delete iConvertServer;
       
   101     iConvertServer = NULL;
       
   102 }
       
   103 
       
   104 /**
       
   105  * To start silent installation.
       
   106  */
       
   107 void CSilentMIDletConvert::Start()
       
   108 {
       
   109     JELOG2(EJavaConverters);
       
   110     iState = EFindOutDeviceDrives;
       
   111     CompleteRequest();
       
   112 }
       
   113 
       
   114 /**
       
   115  * To stop whole preinstaller.
       
   116  * Stops the active scheduler.
       
   117  */
       
   118 void CSilentMIDletConvert::Exit()
       
   119 {
       
   120     Deque();
       
   121     CActiveScheduler::Stop();
       
   122 }
       
   123 
       
   124 /**
       
   125  * To complete the request for this object.
       
   126  *
       
   127  * @Postconditions The following conditions are true immediately after
       
   128  * returning from this method.
       
   129  * - iStatus == KErrNone
       
   130  * - IsActive() == ETrue
       
   131  */
       
   132 void CSilentMIDletConvert::CompleteRequest()
       
   133 {
       
   134     JELOG2(EJavaConverters);
       
   135 
       
   136     TRequestStatus *status = &iStatus;
       
   137     User::RequestComplete(status, KErrNone);
       
   138     if (!IsActive())
       
   139     {
       
   140         SetActive();
       
   141     }
       
   142 }
       
   143 
       
   144 /**
       
   145  * To run this active object.
       
   146  *
       
   147  * The state logic is:
       
   148  *
       
   149  * EFindOutDeviceDrives: find out all non-remote drives in the device
       
   150  *    - mark externally mountable drives (removable drives)
       
   151  *    - mark read only drives (ROM)
       
   152  *
       
   153  * EFindOutDrivesToBeScannedNow: make list of drives to be scanned
       
   154  *    - start with all mounted drives
       
   155  *
       
   156  * EAppsInInstalledDirectories: go through all directories in iDirs one by one
       
   157  *  and find all java applications in the subdirectories of the directory
       
   158  *    - if only .jar/.dcf/.dm file is found it is added to iInstallFiles
       
   159  *    - if .jad file is found, it is added to iInstallFiles
       
   160  *
       
   161  * ECheckWhichAppsShouldBeConverted: for each java application check from
       
   162  *  AppArc whether it should be converted
       
   163  *    - if the application has been installed, convert it
       
   164  *
       
   165  * EExecuteConvertServer: give list of install files to preinstall server,
       
   166  *  start Java Installer in poll mode, start convert server in another thread,
       
   167  *  convert server will give the names of the .jad or .jar/.dcf/.dm files to Java Installer
       
   168  *  when it polls them,  convert server will log whether each installation
       
   169  *  succeeded. After all install files have been polled, convert server will ask
       
   170  *  Java Installer to exit. After that this active object moves to next state.
       
   171  *
       
   172  * EMarkConversionDone: remove 'uids' data file created by javaapppreconverter
       
   173  *
       
   174  * EExit: free resources and exit
       
   175  *
       
   176  */
       
   177 void CSilentMIDletConvert::RunL()
       
   178 {
       
   179     JELOG2(EJavaConverters);
       
   180 
       
   181     switch (iState)
       
   182     {
       
   183     case EFindOutDeviceDrives:
       
   184     {
       
   185         LOG(EJavaConverters, EInfo,
       
   186             "CSilentMIDletConvert::RunL EFindOutDeviceDrives");
       
   187         GetAllDeviceDrivesL();
       
   188         iState = EFindOutDrivesToBeScannedNow;
       
   189         CompleteRequest();
       
   190     }
       
   191     break;
       
   192 
       
   193     case EFindOutDrivesToBeScannedNow:
       
   194     {
       
   195         LOG(EJavaConverters, EInfo,
       
   196             "CSilentMIDletConvert::RunL EFindOutDrivesToBeScannedNow");
       
   197 
       
   198         TChar driveChar = 'C';
       
   199 
       
   200         // forget old search directories
       
   201         iDirs.ResetAndDestroy();
       
   202 
       
   203         for (TInt drive = 0; drive < KMaxDrives; drive++)
       
   204         {
       
   205             // All present drives will be scanned for
       
   206             // java applications to be converted
       
   207             if (iDriveStatuses[drive] & DriveInfo::EDrivePresent)
       
   208             {
       
   209                 (void)iFs.DriveToChar(drive, driveChar);
       
   210 
       
   211                 // The base Java application install directory in this
       
   212                 // drive must be scanned.
       
   213                 // Reserve memory also for drive letter and terminating zero
       
   214                 // for logging.
       
   215                 HBufC *baseInstallDir = HBufC::NewLC(KMidletSuiteInstallBasePath().Length() + 2);
       
   216 
       
   217                 TPtr dirPtr(baseInstallDir->Des());
       
   218                 dirPtr.Append(driveChar);
       
   219                 dirPtr.Append(KMidletSuiteInstallBasePath());
       
   220 
       
   221                 // Add new search directory
       
   222                 iDirs.AppendL(baseInstallDir);
       
   223                 CleanupStack::Pop(baseInstallDir);
       
   224             }
       
   225         }
       
   226 
       
   227         iState = EAppsInInstalledDirectories;
       
   228         CompleteRequest();
       
   229     }
       
   230     break;
       
   231 
       
   232     case EAppsInInstalledDirectories:
       
   233     {
       
   234         LOG(EJavaConverters, EInfo,
       
   235             "CSilentMIDletConvert::RunL EAppsInInstalledDirectories");
       
   236 
       
   237         GetInstallFilesL(iDirs);
       
   238 
       
   239         iState = ECheckWhichAppsShouldBeConverted;
       
   240         CompleteRequest();
       
   241     }
       
   242     break;
       
   243 
       
   244     case ECheckWhichAppsShouldBeConverted:
       
   245     {
       
   246         LOG(EJavaConverters, EInfo,
       
   247             "CSilentMIDletConvert::RunL ECheckWhichAppsShouldBeConverted");
       
   248 
       
   249         // Check all Jad / Jar files in iInstallFiles and remove those
       
   250         // that need not be converted (those that cannot be found from
       
   251         // AppArc). Updates also iNumberOfAppsToInstall
       
   252         CheckNeedToInstall();
       
   253 
       
   254         iState = EExecuteConvertServer;
       
   255         CompleteRequest();
       
   256     }
       
   257     break;
       
   258 
       
   259     case EExecuteConvertServer:
       
   260     {
       
   261         LOG(EJavaConverters, EInfo,
       
   262             "CSilentMIDletConvert::RunL EExecuteConvertServer");
       
   263 
       
   264         if (iNumberOfAppsToInstall > 0)
       
   265         {
       
   266             // Install all MIDlet Suites still in iInstallFiles.
       
   267 
       
   268             // Pass iInstallFiles to ConvertServer
       
   269             iConvertServer->setInstallFiles(iInstallFiles);
       
   270 
       
   271             // Start the server
       
   272             int err = iConvertServer->start();
       
   273             if (0 != err)
       
   274             {
       
   275                 // server cannot be started
       
   276                 ELOG1(EJavaConverters,
       
   277                       "Cannot start convert server, err %d", err);
       
   278             }
       
   279 
       
   280             // Starts Java Installer, waits until Java Installer exits
       
   281             RunJavaInstallerL();
       
   282 
       
   283             iState = EMarkConversionDone;
       
   284         }
       
   285         else
       
   286         {
       
   287             iState = EMarkConversionDone;
       
   288             CompleteRequest();
       
   289         }
       
   290     }
       
   291     break;
       
   292 
       
   293     case EMarkConversionDone:
       
   294     {
       
   295         // If this line is executed, converting old midlets succeeded.
       
   296         // Remove the 'uids' data file so that conversion will not be
       
   297         // done again if OMJ sis package is installed again to the same device.
       
   298         RemoveDataFile();
       
   299 
       
   300         iState = EExit;
       
   301         CompleteRequest();
       
   302     }
       
   303     break;
       
   304 
       
   305     case EExit:
       
   306     {
       
   307         LOG(EJavaConverters, EInfo, "CSilentMIDletConvert::RunL EExit");
       
   308 
       
   309         // Stops the server if it is running
       
   310         iConvertServer->stop();
       
   311 
       
   312         FullCleanup();
       
   313 
       
   314         // The whole javaappconverter process is stopped.
       
   315         Exit();
       
   316     }
       
   317     break;
       
   318 
       
   319     }
       
   320 }
       
   321 
       
   322 /**
       
   323  * To handle leave from RunL.
       
   324  * This method exits this active object using normal state machine
       
   325  * After calling this method this active object will exit.
       
   326  *
       
   327  * @param aError - A reason of error.
       
   328  * @return KErrNone.
       
   329  */
       
   330 TInt CSilentMIDletConvert::RunError(TInt aError)
       
   331 {
       
   332     ELOG2(EJavaConverters,
       
   333           "CSilentMIDletConvert::RunError(%d) from state %d", aError, iState);
       
   334 
       
   335     Cancel();
       
   336 
       
   337     iState = EExit;
       
   338     CompleteRequest();
       
   339 
       
   340     return KErrNone;
       
   341 }
       
   342 
       
   343 /**
       
   344  * To do cancelling for this object.
       
   345  *
       
   346  */
       
   347 void CSilentMIDletConvert::DoCancel()
       
   348 {
       
   349     ELOG1(EJavaConverters,
       
   350           "CSilentMIDletConvert::DoCancel from state %d", iState);
       
   351 
       
   352     // Check whether convert server must be stopped
       
   353     if (iState == EExecuteConvertServer)
       
   354     {
       
   355         // Stops the server if it is running
       
   356         iConvertServer->stop();
       
   357     }
       
   358 }
       
   359 
       
   360 /**
       
   361  * Add .jad files in the directories specified in aDirs to iInstallFiles.
       
   362  * If a directory does not contain a .jad file but it contains a .jar/.dcf/.dm file,
       
   363  * add that file to iInstallFiles
       
   364  *
       
   365  * @param aDirs - An array of directories to be scanned.
       
   366  * @exception Unable to alloc memory for the internal buffers.
       
   367  * @exception Unable to get directory's contents.
       
   368  */
       
   369 void CSilentMIDletConvert::GetInstallFilesL(RPointerArray<HBufC>& aDirs)
       
   370 {
       
   371     JELOG2(EJavaConverters);
       
   372 
       
   373     // Number of MIDlet installation base directories to scan,
       
   374     // one directory per local drive
       
   375     const TInt nBaseDirs = aDirs.Count();
       
   376 
       
   377     for (TInt i = 0; i < nBaseDirs; i++)
       
   378     {
       
   379         TFileName suitePath;
       
   380 
       
   381         // Form base directory path, MIDlets have been installed
       
   382         // to subdirectories of this directory
       
   383         const TPtrC& dir = ((HBufC *)(aDirs[i]))->Des();
       
   384         TFileName baseSuitePath = dir;
       
   385 
       
   386         CDir *entryList;
       
   387         CDir *dirList;
       
   388         TInt err = iFs.GetDir(baseSuitePath, KEntryAttMatchMask, ESortNone, entryList, dirList);
       
   389         if (KErrNone != err)
       
   390         {
       
   391             WLOG1WSTR(EJavaConverters,
       
   392                       "CSilentMIDletConvert::GetInstallFilesL Cannot list directory %s",
       
   393                       (wchar_t *)(baseSuitePath.PtrZ()));
       
   394 
       
   395             // If no S60 Java application has been installed to the drive,
       
   396             // the directory does not exist but it is OK
       
   397             if (KErrPathNotFound != err)
       
   398             {
       
   399                 User::Leave(err);
       
   400             }
       
   401             continue;
       
   402         }
       
   403 
       
   404         // Only midlet installation directory entries are meaningfull,
       
   405         // discard other possible entries
       
   406         delete entryList;
       
   407 
       
   408         TInt   nCount = dirList->Count();
       
   409         TEntry dirEntry;
       
   410 
       
   411         for (TInt nInd = 0; nInd < nCount; nInd++)
       
   412         {
       
   413             dirEntry = (*dirList)[nInd];
       
   414             // Just to make sure this really is subdirectory
       
   415             if (dirEntry.IsDir())
       
   416             {
       
   417                 // Is this midlet suite subdir?
       
   418                 // Midlet suite subdirs look like this "[102b567B]"
       
   419                 // Must parse the value of the Uid as unsigned int to avoid
       
   420                 // overflow
       
   421                 TUint32 nUid;
       
   422                 TLex   lexer(dirEntry.iName);
       
   423                 lexer.Inc();
       
   424                 err = lexer.Val(nUid, EHex);
       
   425                 if (KErrNone != err)
       
   426                 {
       
   427                     // Not midlet suite subdir, skip it
       
   428                     continue;
       
   429                 }
       
   430 
       
   431                 // Does the subdirectory contain any Jar files?
       
   432                 suitePath = baseSuitePath;
       
   433                 suitePath.Append(dirEntry.iName);
       
   434                 suitePath.Append(KSMCBackSplash);
       
   435 
       
   436                 CDir *suiteDirEntryList;
       
   437                 err = iFs.GetDir(suitePath, KEntryAttMatchMask, ESortNone, suiteDirEntryList);
       
   438                 if (KErrNone != err)
       
   439                 {
       
   440                     ELOG1WSTR(EJavaConverters,
       
   441                               "CSilentMIDletConvert::GetInstallFilesL Cannot list content of suite dir %s",
       
   442                               (wchar_t *)(suitePath.PtrZ()));
       
   443                     User::Leave(err);
       
   444                     return;
       
   445                 }
       
   446                 // If there is .jad or Jar file in suiteDirEntryList, adds
       
   447                 // it to iInstallFiles.
       
   448                 // Recognizes also DRM protected Jar files (.dm, .dcf)
       
   449                 AddJadJarToInstallFilesL(suitePath, suiteDirEntryList);
       
   450                 delete suiteDirEntryList;
       
   451             }
       
   452         } // for - loop all directory entries in a base installation directories
       
   453         delete dirList;
       
   454 
       
   455     } // for - loop all base installation directories
       
   456 
       
   457     if (iInstallFiles.Count() == 0)
       
   458     {
       
   459         WLOG(EJavaConverters,
       
   460              "CSilentMIDletConvert::GetInstallFilesL No MIDlets to convert");
       
   461     }
       
   462 }
       
   463 
       
   464 /**
       
   465  * Check all Jad / Jar files in iInstallFiles and remove those
       
   466  * that need not be converted. Updates also iNumberOfAppsToInstall.
       
   467  */
       
   468 void CSilentMIDletConvert::CheckNeedToInstall()
       
   469 {
       
   470     // It is too late to check from AppArc whether the application is a
       
   471     // valid java application or no. The Java registry dll:s have been eclipsed and
       
   472     // old apps are now invalid.
       
   473     // javaapppreconverter has stored the Uids of the valid midlets to 'uids' file
       
   474     // in to the data subdirectory of this process.
       
   475     // ReadMidletUids() can be used to read the uids of the valid midlets to array.
       
   476     // If uid is in the array, it is valid.
       
   477     TFileName uidsDataFilePathName(KUidsImportDataFilePathName);
       
   478     RArray<TUid> validUids = ReadMidletUids(uidsDataFilePathName);
       
   479 
       
   480     // loop through iInstallFiles one be one
       
   481     TInt   nNumberOfAppsToInstall = 0;
       
   482     TInt   err;
       
   483     TInt   nFiles = iInstallFiles.Count();
       
   484     TParse fp;
       
   485     for (TInt nInd = 0; nInd < nFiles; nInd++)
       
   486     {
       
   487         // get the directory path of the current iInstallFiles[nInd]
       
   488         err = fp.Set(*(iInstallFiles[nInd]), NULL, NULL);
       
   489         if (KErrNone != err)
       
   490         {
       
   491             WLOG1(EJavaConverters,
       
   492                   "CSilentMIDletConvert::CheckNeedToInstall Cannot parse install file name %s",
       
   493                   iInstallFiles[nInd]);
       
   494             continue;
       
   495         }
       
   496 
       
   497         TPtrC installDir = fp.DriveAndPath();
       
   498 
       
   499         // read Java applications uid(s) from 'uids' file in the directory
       
   500         RArray<TUid> appUids = ReadMidletUids(installDir);
       
   501 
       
   502         // For each app uid, check whether it is uid of an valid java  application.
       
   503         // If yes, make conversion installation for the .jad/Jar file
       
   504         // in this directory.
       
   505         TInt nIndUids;
       
   506         TInt nCountUids = appUids.Count();
       
   507         for (nIndUids = 0; nIndUids < nCountUids; nIndUids++)
       
   508         {
       
   509             err = validUids.Find(appUids[nIndUids]);
       
   510             if (KErrNotFound == err)
       
   511             {
       
   512                 LOG1(EJavaConverters, EInfo,
       
   513                      "CSilentMIDletConvert::CheckNeedToInstall Midlet with Uid %x "
       
   514                      "was not registered to AppArc",
       
   515                      appUids[nIndUids].iUid);
       
   516 
       
   517                 // Do not convert any app in this Midlet suite
       
   518                 delete iInstallFiles[nInd];
       
   519                 iInstallFiles[nInd] = NULL;
       
   520                 break;
       
   521             }
       
   522             else
       
   523             {
       
   524                 // The application is valid, so it should be converted
       
   525                 nNumberOfAppsToInstall++;
       
   526             }
       
   527         }
       
   528         appUids.Close();
       
   529     }
       
   530     validUids.Close();
       
   531 
       
   532     // how many applications to convert
       
   533     iNumberOfAppsToInstall = nNumberOfAppsToInstall;
       
   534 }
       
   535 
       
   536 /**
       
   537  * Read the midlet uids from file 'uids' in the directory
       
   538  * given in parameter aDir and return them in RArray
       
   539  *
       
   540  * @param aDir -  directory that contains 'uids' file
       
   541  * @return the midlet uids in RArray. Caller must destroy the RArray
       
   542  */
       
   543 RArray<TUid> CSilentMIDletConvert::ReadMidletUids(const TPtrC& aDir)
       
   544 {
       
   545     RArray<TUid> midletUids;
       
   546     RFile fileUids;
       
   547     TFileName nameUids = aDir;
       
   548     nameUids.Append(_L("uids"));
       
   549 
       
   550     TInt err = fileUids.Open(iFs, nameUids, EFileRead);
       
   551     if (KErrNone != err)
       
   552     {
       
   553         // cannot open "uids" file
       
   554         nameUids.Append(0);
       
   555         WLOG1WSTR(EJavaConverters,
       
   556                   "CSilentMIDletConvert::ReadMidletUids cannot open uids file in dir %s",
       
   557                   (wchar_t *)(&(nameUids[0])));
       
   558         WLOG1(EJavaConverters, "Error is %d", err);
       
   559         return midletUids;
       
   560     }
       
   561 
       
   562     TInt fileSize(0);
       
   563     err = fileUids.Size(fileSize);
       
   564     if (fileSize < 8)
       
   565     {
       
   566         // valid "uids" file contains at least the uid of the suite and
       
   567         // uid of at least one midlet
       
   568         fileUids.Close();
       
   569         // invalid "uids" file
       
   570         nameUids.Append(0);
       
   571         WLOG1WSTR(EJavaConverters,
       
   572                   "CSilentMIDletConvert::ReadMidletUids invalid uids file in dir %s",
       
   573                   (wchar_t *)(&(nameUids[0])));
       
   574         return midletUids;
       
   575     }
       
   576 
       
   577     // reserve buffer for one uid
       
   578     TBuf8<4> readBuf;
       
   579     TDes8 readBufDes(readBuf);
       
   580 
       
   581     // The first uid is suite uid but we are not interested in it. Skip it.
       
   582     err = fileUids.Read(readBufDes);
       
   583     if (KErrNone != err)
       
   584     {
       
   585         fileUids.Close();
       
   586         // cannot read "uids" file
       
   587         nameUids.Append(0);
       
   588         WLOG1WSTR(EJavaConverters,
       
   589                   "CSilentMIDletConvert::ReadMidletUids cannot read uids file in dir %s",
       
   590                   (wchar_t *)(&(nameUids[0])));
       
   591         WLOG1(EJavaConverters, "Error is %d", err);
       
   592         return midletUids;
       
   593     }
       
   594 
       
   595     // Now read rest of the file one uid at a time
       
   596     TInt  nReadBytes = readBufDes.Length();
       
   597     TUint midletUidValue;
       
   598     TUint temp;
       
   599 
       
   600     while (nReadBytes == 4)
       
   601     {
       
   602         err = fileUids.Read(readBufDes);
       
   603         if (KErrNone != err)
       
   604         {
       
   605             fileUids.Close();
       
   606             // cannot read "uids" file
       
   607             nameUids.Append(0);
       
   608             WLOG1WSTR(EJavaConverters,
       
   609                       "CSilentMIDletConvert::ReadMidletUids(2) cannot from uids file in dir %s",
       
   610                       (wchar_t *)(&(nameUids[0])));
       
   611             WLOG1(EJavaConverters, "Error is %d", err);
       
   612             return midletUids;
       
   613         }
       
   614 
       
   615         nReadBytes = readBufDes.Length();
       
   616         if (nReadBytes == 4)
       
   617         {
       
   618             // One whole midlet id was read to buffer.
       
   619             // 4 bytes per midlet, least significant byte first
       
   620             TUid  midletUid;
       
   621 
       
   622             midletUidValue = readBufDes[0];
       
   623             temp = readBufDes[1];
       
   624             midletUidValue += temp<<8;
       
   625             temp = readBufDes[2];
       
   626             midletUidValue += temp<<16;
       
   627             temp = readBufDes[3];
       
   628             midletUidValue += temp<<24;
       
   629 
       
   630             midletUid.iUid = midletUidValue;
       
   631             midletUids.Append(midletUid);
       
   632         }
       
   633     }
       
   634 
       
   635     fileUids.Close();
       
   636 
       
   637     return midletUids;
       
   638 }
       
   639 
       
   640 /**
       
   641  * Scan the content of one directory entry and add the name of
       
   642  * .jad / .jar /.dcf/.dm file to iInstallFiles if
       
   643  * the directory contains a valid, installed Java application.
       
   644  * Recognizes also DRM protected jar files (.dm, .dcf)
       
   645  *
       
   646  * @param aSuitePathName -  directory to be scanned.
       
   647  * @param aSuiteDirEntryList - contents of the directory
       
   648  * @exception Unable to alloc memory for the internal buffers.
       
   649  */
       
   650 void CSilentMIDletConvert::AddJadJarToInstallFilesL(
       
   651     const TFileName &aSuitePathName,
       
   652     const CDir *aSuiteDirEntryList)
       
   653 {
       
   654     JELOG2(EJavaConverters);
       
   655 
       
   656     if (NULL == aSuiteDirEntryList)
       
   657     {
       
   658         return;
       
   659     }
       
   660 
       
   661     TInt nCount = aSuiteDirEntryList->Count();
       
   662     if (0 == nCount)
       
   663     {
       
   664         return;
       
   665     }
       
   666 
       
   667     TInt        suffixPos;
       
   668     TEntry      dirEntry;
       
   669     TBool       jarFileInSuiteDir = EFalse;
       
   670     TBool       jadFileInSuiteDir = EFalse;
       
   671     TFileName   jadFullPathName;
       
   672     TFileName   jarFullPathName;
       
   673 
       
   674     for (TInt nInd = 0; nInd < nCount; nInd++)
       
   675     {
       
   676         dirEntry = (*aSuiteDirEntryList)[nInd];
       
   677         // Directory cannot be Jar file.
       
   678         // Empty file cannot valid Jar file
       
   679         if (dirEntry.IsDir() || (dirEntry.iSize == 0))
       
   680         {
       
   681             continue;
       
   682         }
       
   683         // get the suffix of the name
       
   684         suffixPos = dirEntry.iName.LocateReverse('.');
       
   685         if (suffixPos == KErrNotFound)
       
   686         {
       
   687             // File name does not contain '.' char
       
   688             continue;
       
   689         }
       
   690         TPtrC suffix(dirEntry.iName.Mid(suffixPos));
       
   691 
       
   692         // if the name ends with ".jar" the name is current candidate
       
   693         // for the name to be added to iInstallFiles list
       
   694         if (suffix.CompareF(KJarFileNameSuffix) == 0)
       
   695         {
       
   696             jarFullPathName = aSuitePathName;
       
   697             jarFullPathName.Append(dirEntry.iName);
       
   698             jarFileInSuiteDir = ETrue;
       
   699         }
       
   700         else if (suffix.CompareF(KJadFileNameSuffix) == 0)
       
   701         {
       
   702             // If .jad file is found, then it will be added
       
   703             // to iInstallFiles list
       
   704             jadFullPathName = aSuitePathName;
       
   705             jadFullPathName.Append(dirEntry.iName);
       
   706             jadFileInSuiteDir = ETrue;
       
   707         }
       
   708         else if (suffix.CompareF(KFLJarFileNameSuffix) == 0)
       
   709         {
       
   710             // forward locked and combined delivery DRM protected
       
   711             // .jar files have suffix ".dm"
       
   712             jarFullPathName = aSuitePathName;
       
   713             jarFullPathName.Append(dirEntry.iName);
       
   714             jarFileInSuiteDir = ETrue;
       
   715         }
       
   716         else if (suffix.CompareF(KSDJarFileNameSuffix) == 0)
       
   717         {
       
   718             // separate delivery DRM protected .jar files have suffix ".dcf"
       
   719             jarFullPathName = aSuitePathName;
       
   720             jarFullPathName.Append(dirEntry.iName);
       
   721             jarFileInSuiteDir = ETrue;
       
   722         }
       
   723     }
       
   724 
       
   725     // If directory contains a Jar file, then add something to iInstallFiles
       
   726     if (jarFileInSuiteDir)
       
   727     {
       
   728         // If directory contains also .jad file, add .jad file name to iInstallFiles
       
   729         if (jadFileInSuiteDir)
       
   730         {
       
   731             // Reserve one char for null terminator
       
   732             HBufC* path = HBufC::NewLC(jadFullPathName.Length() + 1);
       
   733             TPtr pathPtr(path->Des());
       
   734             pathPtr.Append(jadFullPathName);
       
   735 
       
   736             LOG1WSTR(EJavaConverters, EInfo,
       
   737                      "CSilentMIDletConvert::AddJadJarToInstallFilesL Adding jad file %s",
       
   738                      (wchar_t *)(pathPtr.PtrZ()));
       
   739             iInstallFiles.Append(path);
       
   740             CleanupStack::Pop(path);
       
   741         }
       
   742         else
       
   743         {
       
   744             // Reserve one char for null terminator
       
   745             HBufC* path = HBufC::NewLC(jarFullPathName.Length() + 1);
       
   746             TPtr pathPtr(path->Des());
       
   747             pathPtr.Append(jarFullPathName);
       
   748 
       
   749             LOG1WSTR(EJavaConverters, EInfo,
       
   750                      "CSilentMIDletConvert::AddJadJarToInstallFilesL Adding jar file %s",
       
   751                      (wchar_t *)(pathPtr.PtrZ()));
       
   752             iInstallFiles.Append(path);
       
   753             CleanupStack::Pop(path);
       
   754         }
       
   755     }
       
   756 }
       
   757 
       
   758 /**
       
   759  * Start Java Installer in poll mode and then wait until it exits.
       
   760  */
       
   761 void CSilentMIDletConvert::RunJavaInstallerL()
       
   762 {
       
   763     LOG(EJavaConverters, EInfo, "CSilentMIDletConvert::RunJavaInstaller");
       
   764 
       
   765     RProcess rJavaInstaller;
       
   766     TFileName fileName;
       
   767     TInt err;
       
   768     // Max one path name, user name and password and some options ->
       
   769     // 1536 is enough
       
   770     TBuf<1536> commandLine;
       
   771 
       
   772     // Build command line used to pass all necessary info to Java Installer
       
   773     std::auto_ptr<HBufC> installerStarterDll(
       
   774         stringToDes(java::runtime::JAVA_INSTALLER_STARTER_DLL));
       
   775     commandLine = installerStarterDll->Des();
       
   776     commandLine.Append(_L(" poll -address=convert"));
       
   777 
       
   778     // Run installer silently
       
   779     commandLine.Append(_L(" -silent"));
       
   780 
       
   781     // Convert old S60 applications so that applications uids,
       
   782     // private data and RMS data are all preserved
       
   783     commandLine.Append(_L(" -convert=yes"));
       
   784 
       
   785     // Upgrading MIDlets is allowed
       
   786     commandLine.Append(_L(" -upgrade=yes"));
       
   787 
       
   788     // No OCSP checks for converted MIDlets
       
   789     commandLine.Append(_L(" -ocsp=no"));
       
   790 
       
   791     // Allow upgrade even if version number has not increased
       
   792     commandLine.Append(_L(" -overwrite=yes"));
       
   793 
       
   794     // Downloading .jar is not allowed.
       
   795     commandLine.Append(_L(" -download=no"));
       
   796 
       
   797     // If upgrade install, automatically upgrade also the data
       
   798     commandLine.Append(_L(" -upgrade_data=yes"));
       
   799 
       
   800     // If the device has an internal drive with much free disk space,
       
   801     // install all converted applications to that drive
       
   802     if (iDefaultTargetInstallationDrive > -1)
       
   803     {
       
   804         TChar targetDrive;
       
   805         err = RFs::DriveToChar(iDefaultTargetInstallationDrive, targetDrive);
       
   806         if (KErrNone == err)
       
   807         {
       
   808             commandLine.Append(_L(" -drive="));
       
   809             commandLine.Append(targetDrive);
       
   810         }
       
   811     }
       
   812 
       
   813     // start JavaInstaller
       
   814     std::auto_ptr<HBufC> installerProcess(
       
   815         stringToDes(java::runtime::JAVA_PROCESS));
       
   816     err = rJavaInstaller.Create(installerProcess->Des(), commandLine);
       
   817     if (KErrNone == err)
       
   818     {
       
   819         LOG(EJavaConverters, EInfo, "CSilentMIDletConvert::RunJavaInstaller calling Rendezvous");
       
   820         // This call will wait until Java Installer exits (or panics)
       
   821         rJavaInstaller.Logon(iStatus);
       
   822 
       
   823         LOG(EJavaConverters, EInfo, "CSilentMIDletConvert::RunJavaInstaller calling Resume");
       
   824         rJavaInstaller.Resume();
       
   825     }
       
   826     else
       
   827     {
       
   828         ELOG1(EJavaConverters,
       
   829               "CSilentMIDletConvert::RunJavaInstaller Cannot start Installer, error %d", err);
       
   830         // CActive will trap the following leave, execution will go to RunError
       
   831         User::Leave(err);
       
   832     }
       
   833 
       
   834     LOG(EJavaConverters, EInfo, "CSilentMIDletConvert::RunJavaInstaller calling RProcess::Close");
       
   835     // free resources before returning
       
   836     rJavaInstaller.Close();
       
   837 
       
   838     // now wait until Java Installer exits
       
   839     SetActive();
       
   840 }
       
   841 
       
   842 /**
       
   843  * To cleanup member variables.
       
   844  */
       
   845 void CSilentMIDletConvert::FullCleanup()
       
   846 {
       
   847     JELOG2(EJavaConverters);
       
   848 
       
   849     iDirs.ResetAndDestroy();
       
   850     iInstallFiles.ResetAndDestroy();
       
   851 }
       
   852 
       
   853 
       
   854 /**
       
   855  * Checks all local drives in the device and stores the DriveInfo API drive
       
   856  * status information for each drive to iDriveStatuses
       
   857  * @exception Cannot get drive list.
       
   858  */
       
   859 void CSilentMIDletConvert::GetAllDeviceDrivesL()
       
   860 {
       
   861     JELOG2(EJavaConverters);
       
   862 
       
   863     TDriveList driveList;
       
   864     // get all drives
       
   865     TInt err = iFs.DriveList(driveList);
       
   866     if (KErrNone != err)
       
   867     {
       
   868         ELOG1(EJavaConverters,
       
   869               "CSilentMIDletConvert::GetAllDeviceDrives cannot get drive list, err %d", err);
       
   870         User::Leave(err);
       
   871     }
       
   872 
       
   873     // store status of the non-remote, non-substed drives
       
   874     TInt64 requiredFreeDiskSpace = KMinimumFreeDiskSpace;
       
   875     TUint  status = 0;
       
   876     for (TInt drive = 0; drive < KMaxDrives; drive++)
       
   877     {
       
   878         iDriveStatuses[drive] = 0;
       
   879 
       
   880         if (driveList[drive] == 0)
       
   881         {
       
   882             // no such drive in this device
       
   883             continue;
       
   884         }
       
   885 
       
   886         err = DriveInfo::GetDriveStatus(iFs, drive, status);
       
   887         if (KErrNone != err)
       
   888         {
       
   889             ELOG2(EJavaConverters,
       
   890                   "CSilentMIDletConvert::GetAllDeviceDrivesL cannot get drive %d status, err %d",
       
   891                   drive, err);
       
   892             User::Leave(err);
       
   893         }
       
   894         // D drive is temporary RAM drive, skip it
       
   895         // Drives J to Y are substed or remote drives, skip them
       
   896         if ((drive == EDriveD) || ((drive >= EDriveJ) && (drive <= EDriveY)))
       
   897         {
       
   898             continue;
       
   899         }
       
   900 
       
   901         iDriveStatuses[drive] = status;
       
   902 
       
   903         // If the device has an internal (non-removable) drive with much
       
   904         // free disk space, use that drive as the target installation drive
       
   905         // when making the conversion installations.
       
   906         // Skip drives A: to D:, C: drive is not valid target drive because
       
   907         // we do not want to fill C: drive unnecessarily
       
   908         if (drive < EDriveE)
       
   909         {
       
   910             continue;
       
   911         }
       
   912         // drive must be internal and visible to the user but
       
   913         // it must NOT be corrupted or in exclusive use or read only
       
   914         if ((status & DriveInfo::EDriveInternal) &&
       
   915                 (!(status & DriveInfo::EDriveCorrupt)) &&
       
   916                 (!(status & DriveInfo::EDriveInUse)) &&
       
   917                 (!(status & DriveInfo::EDriveReadOnly)) &&
       
   918                 (status & DriveInfo::EDriveUserVisible))
       
   919         {
       
   920             // Is there 'enough' free disk space for conversion
       
   921             TVolumeInfo volumeInfo;
       
   922             err = iFs.Volume(volumeInfo, drive);
       
   923             if (KErrNone == err)
       
   924             {
       
   925                 if (volumeInfo.iFree > requiredFreeDiskSpace)
       
   926                 {
       
   927                     iDefaultTargetInstallationDrive = drive;
       
   928 
       
   929                     // If some other internal drive has even more free
       
   930                     // disk space, it will be used as the target drive
       
   931                     requiredFreeDiskSpace = volumeInfo.iFree;
       
   932                 }
       
   933             }
       
   934         }
       
   935     }
       
   936 }
       
   937 
       
   938 /**
       
   939  * Remove the data file that contain information about the midlets to be converted.
       
   940  */
       
   941 void CSilentMIDletConvert::RemoveDataFile()
       
   942 {
       
   943     TFileName dataFile(KUidsImportDataFilePathName);
       
   944     dataFile.Append(KUidsImportDataFileName);
       
   945 
       
   946     TInt err = iFs.Delete(dataFile);
       
   947     if (KErrNone != err)
       
   948     {
       
   949         ELOG1(EJavaConverters,
       
   950               "CSilentMIDletConvert::RemoveDataFile: Cannot delete data file, err %d ",
       
   951               err);
       
   952     }
       
   953 }