javamanager/javainstaller/installer/src.s60/applicationregistrator/applicationregistrator.cpp
changeset 21 2a9601315dfc
child 23 98ccebc37403
child 24 0fd27995241b
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*
       
     2 * Copyright (c) 2008-2010 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:  The JNI code for Java Installer component
       
    15 *                ApplicationRegistrator.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include <apaid.h>
       
    21 #include <f32file.h>
       
    22 #include <apgcli.h>
       
    23 #include <utf.h>
       
    24 #include <s32mem.h>
       
    25 #include <bautils.h>
       
    26 #include <w32std.h>
       
    27 #include <apgtask.h>
       
    28 #include <apacmdln.h>
       
    29 #include <centralrepository.h>
       
    30 #include <AknUtils.h>
       
    31 #include <hal.h>
       
    32 
       
    33 #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    34 #include <apgicnfl.h>
       
    35 #else
       
    36 #include <apgicnflpartner.h>
       
    37 #endif
       
    38 
       
    39 
       
    40 
       
    41 // JNI header must be included before iconconverter.h. Latter includes some
       
    42 // other header file which defines WIN32 macro, causing incorrect definitions
       
    43 // to be taken from jniport.h when WINSCW compilation is made.
       
    44 // This error situation can be seen from linker warnings which complain
       
    45 // about not frozen exports for JNI methods.
       
    46 #include "com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator.h"
       
    47 #include "iconconverter.h"
       
    48 #include "javacommonutils.h"
       
    49 #include "logger.h"
       
    50 
       
    51 // NAMESPACE DECLARATION
       
    52 using namespace java;
       
    53 
       
    54 /**
       
    55  * MIDP Stub SIS file UID. The application type Uid for MIDlets in S60
       
    56  */
       
    57 const TUid KMidletApplicationTypeUid = { 0x10210E26 };
       
    58 
       
    59 /**
       
    60  * Symbian file path separator
       
    61  */
       
    62 _LIT(KPathSeperator, "\\");
       
    63 
       
    64 /**
       
    65  * Postfix for the fake application name generated only to make AppArc happy
       
    66  */
       
    67 _LIT(KAppPostfix, ".fakeapp");
       
    68 
       
    69 // ------------------------
       
    70 
       
    71 /**
       
    72  * Internal wrapper method that is used to make TRAPping the leaves in the
       
    73  * native Symbian code easier.
       
    74  * Used from JNI method ...1registerApplication()
       
    75  * @see Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1registerApplication
       
    76  */
       
    77 jint registerApplicationL(JNIEnv *aEnv, jclass aClass, jint aSessionHandle,
       
    78                           jint aUid, HBufC16 *aGroupName, HBufC16 *aMIDletName, HBufC16 *aTargetDrive,
       
    79                           HBufC16 *aIconFileName, HBufC16 *aJarFileName, jboolean aHidden,
       
    80                           jboolean aBackground);
       
    81 
       
    82 /**
       
    83  * Internal helper method for checking whether Application Shell is already running
       
    84  * Used JNI method ...1startAppShellUi
       
    85  *
       
    86  * @return ETrue if AppShell is running
       
    87  */
       
    88 TBool isAppShellUiRunning();
       
    89 
       
    90 /**
       
    91  * Internal helper method for checking whether this code is executing in
       
    92  * a device that has correctly working version of
       
    93  * RApaLsSession::ForceCommitNonNativeApplicationsUpdatesL()
       
    94  *
       
    95  * @return ETrue if force commit works well
       
    96  */
       
    97 TBool isForceCommitSupported();
       
    98 
       
    99 /**
       
   100  * Internal helper method for starting menu application
       
   101  *
       
   102  * @return KErrNone or Symbian error code
       
   103  */
       
   104 TInt startAppShellApplicationL();
       
   105 
       
   106 // --------------------------
       
   107 
       
   108 /**
       
   109  * Starts native application registration session.
       
   110  *
       
   111  * @return native session handle or Symbian error code (negative number)
       
   112  */
       
   113 JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1startSession
       
   114 (JNIEnv *, jclass)
       
   115 {
       
   116     TInt err;
       
   117     RApaLsSession *pApaSession = new RApaLsSession;
       
   118 
       
   119     if (NULL == pApaSession)
       
   120     {
       
   121         // Could not create session
       
   122         return KErrGeneral;
       
   123     }
       
   124 
       
   125     err = pApaSession->Connect();
       
   126     if (KErrNone != err)
       
   127     {
       
   128         // Cannot connect to AppArc server
       
   129         return err;
       
   130     }
       
   131 
       
   132 #if 1
       
   133 //#ifndef RD_JAVA_USIF_APP_REG
       
   134     // Delete any pending (un)registrations (possible if
       
   135     // e.g. device rebooted before commit).
       
   136     // This call does nothing if there is no pending registrations.
       
   137     // Ignore errors.
       
   138     (void)pApaSession->RollbackNonNativeApplicationsUpdates();
       
   139 
       
   140     // Prepare for Java application registrations / unregistrations
       
   141     TRAP(err, pApaSession->PrepareNonNativeApplicationsUpdatesL());
       
   142     if (KErrNone != err)
       
   143     {
       
   144         // Close session and return error
       
   145         pApaSession->Close();
       
   146         return err;
       
   147     }
       
   148 #endif // RD_JAVA_USIF_APP_REG
       
   149 
       
   150     // Return handle to session. Utilize the fact that in Symbian
       
   151     // all pointer addresses are MOD 4 so the last 2 bits are 0
       
   152     // and can be shifted out. This way the returned handle is
       
   153     // always positive whereas Symbian error codes are always negative.
       
   154     return reinterpret_cast<TUint>(pApaSession)>>2;
       
   155 }
       
   156 
       
   157 
       
   158 /**
       
   159  * Registers Java Application to S60 AppArc
       
   160  *
       
   161  * @param[in] aSessionHandle
       
   162  * @param[in] aUid The Uid of the application.
       
   163  * @param[in] aGroupName  Max group name len is 16 in AppArc
       
   164  * @param[in] aMIDletName
       
   165  * @param[in] aTargetDrive Must be "C:", "E:", ..., "J:"
       
   166  * @param[in] aIconFileName The name of the icon
       
   167  * @param[in] aJarFileName The full path name of the jar file
       
   168  * @param[in] aHidden
       
   169  * @param[in] aBackground
       
   170  * @return 0 if registration succeeded or Symbian error code
       
   171  */
       
   172 #if 0
       
   173 //#ifdef RD_JAVA_USIF_APP_REG
       
   174 JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1registerApplication
       
   175 (JNIEnv */*aEnv*/, jclass /*aClass*/, jint /*aSessionHandle*/, jint /*aUid*/, jstring /*aGroupName*/,
       
   176  jstring /*aMIDletName*/, jstring /*aTargetDrive*/, jstring /*aIconFileName*/,
       
   177  jstring /*aJarFileName*/, jboolean /*aHidden*/, jboolean /*aBackground*/)
       
   178 {
       
   179     return KErrNone;
       
   180 }
       
   181 #else
       
   182 JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1registerApplication
       
   183 (JNIEnv *aEnv, jclass aClass, jint aSessionHandle, jint aUid, jstring aGroupName,
       
   184  jstring aMIDletName, jstring aTargetDrive, jstring aIconFileName,
       
   185  jstring aJarFileName, jboolean aHidden, jboolean aBackground)
       
   186 {
       
   187     TInt err(KErrNone);
       
   188     TBool fStayInLoop(EFalse);
       
   189 
       
   190     HBufC16 *unicodeIconFileName(NULL);
       
   191     HBufC16 *unicodeGroupName(NULL);
       
   192     HBufC16 *unicodeMIDletName(NULL);
       
   193     HBufC16 *unicodeTargetDrive(NULL);
       
   194     HBufC16 *unicodeJarFileName(NULL);
       
   195 
       
   196     // create loop that is executed only once to make error handling easier
       
   197     do
       
   198     {
       
   199         // Copy the unicode characters in jstrings to Symbian buffers so that
       
   200         // they can be used in S60 code
       
   201         const jchar *iconFileName = aEnv->GetStringChars(aIconFileName, 0);
       
   202         if (NULL == iconFileName)
       
   203         {
       
   204             ELOG(
       
   205                 EJavaInstaller,
       
   206                 "Cannot register application, getting icon file name as unicode failed in JNI");
       
   207             err = KErrArgument;
       
   208             break;
       
   209         }
       
   210         unicodeIconFileName = HBufC16::New(aEnv->GetStringLength(aIconFileName) + 1);
       
   211         if (NULL == unicodeIconFileName)
       
   212         {
       
   213             err = KErrNoMemory;
       
   214             break;
       
   215         }
       
   216         *unicodeIconFileName = iconFileName;
       
   217         aEnv->ReleaseStringChars(aIconFileName, iconFileName);
       
   218 
       
   219         const jchar *groupName = aEnv->GetStringChars(aGroupName, 0);
       
   220         if (NULL == groupName)
       
   221         {
       
   222             ELOG(
       
   223                 EJavaInstaller,
       
   224                 "Cannot register application, getting group name as unicode failed in JNI");
       
   225             err = KErrArgument;
       
   226             break;
       
   227         }
       
   228         unicodeGroupName = HBufC16::New(aEnv->GetStringLength(aGroupName) + 1);
       
   229         if (NULL == unicodeGroupName)
       
   230         {
       
   231             err = KErrNoMemory;
       
   232             break;
       
   233         }
       
   234         *unicodeGroupName = groupName;
       
   235         aEnv->ReleaseStringChars(aGroupName, groupName);
       
   236 
       
   237         const jchar *midletName = aEnv->GetStringChars(aMIDletName, 0);
       
   238         if (NULL == midletName)
       
   239         {
       
   240             ELOG(
       
   241                 EJavaInstaller,
       
   242                 "Cannot register application, getting midlet name as unicode failed in JNI");
       
   243             err = KErrArgument;
       
   244             break;
       
   245         }
       
   246         unicodeMIDletName = HBufC16::New(aEnv->GetStringLength(aMIDletName) + 1);
       
   247         if (NULL == unicodeMIDletName)
       
   248         {
       
   249             err = KErrNoMemory;
       
   250             break;
       
   251         }
       
   252         *unicodeMIDletName = midletName;
       
   253         aEnv->ReleaseStringChars(aMIDletName, midletName);
       
   254 
       
   255         const jchar *targetDrive = aEnv->GetStringChars(aTargetDrive, 0);
       
   256         if (NULL == targetDrive)
       
   257         {
       
   258             ELOG(
       
   259                 EJavaInstaller,
       
   260                 "Cannot register application, getting target drive as unicode failed in JNI");
       
   261             err = KErrArgument;
       
   262             break;
       
   263         }
       
   264         unicodeTargetDrive = HBufC16::New(aEnv->GetStringLength(aTargetDrive) + 1);
       
   265         if (NULL == unicodeTargetDrive)
       
   266         {
       
   267             err = KErrNoMemory;
       
   268             break;
       
   269         }
       
   270         *unicodeTargetDrive = targetDrive;
       
   271         aEnv->ReleaseStringChars(aTargetDrive, targetDrive);
       
   272 
       
   273         const jchar *jarFileName = aEnv->GetStringChars(aJarFileName, 0);
       
   274         if (NULL == jarFileName)
       
   275         {
       
   276             ELOG(
       
   277                 EJavaInstaller,
       
   278                 "Cannot register application, getting jar file name as unicode failed in JNI");
       
   279             err = KErrArgument;
       
   280             break;
       
   281         }
       
   282         unicodeJarFileName = HBufC16::New(aEnv->GetStringLength(aJarFileName) + 1);
       
   283         if (NULL == unicodeTargetDrive)
       
   284         {
       
   285             err = KErrNoMemory;
       
   286             break;
       
   287         }
       
   288         *unicodeJarFileName = jarFileName;
       
   289         aEnv->ReleaseStringChars(aJarFileName, jarFileName);
       
   290     }
       
   291     while (fStayInLoop);
       
   292 
       
   293     if (KErrNone != err)
       
   294     {
       
   295         delete unicodeIconFileName;
       
   296         delete unicodeGroupName;
       
   297         delete unicodeMIDletName;
       
   298         delete unicodeTargetDrive;
       
   299         delete unicodeJarFileName;
       
   300 
       
   301         return err;
       
   302     }
       
   303 
       
   304     // Call the actual register method inside TRAP harness
       
   305     TInt ret = KErrNone;
       
   306     TRAP(err,
       
   307          ret = registerApplicationL(
       
   308                    aEnv, aClass, aSessionHandle, aUid, unicodeGroupName,
       
   309                    unicodeMIDletName, unicodeTargetDrive, unicodeIconFileName,
       
   310                    unicodeJarFileName, aHidden, aBackground));
       
   311 
       
   312     LOG1WSTR(
       
   313         EJavaInstaller,
       
   314         EInfo,
       
   315         "Registering application, midlet name (%s)",
       
   316         (wchar_t *)(unicodeMIDletName->Des().PtrZ()));
       
   317     LOG1WSTR(
       
   318         EJavaInstaller,
       
   319         EInfo,
       
   320         "Registering application, icon file name (%s)",
       
   321         (wchar_t *)(unicodeIconFileName->Des().PtrZ()));
       
   322 
       
   323     if (KErrNone != err)
       
   324     {
       
   325         ELOG1(EJavaInstaller,
       
   326               "Cannot register application, err code is %d ",
       
   327               err);
       
   328     }
       
   329     if (KErrNone != ret)
       
   330     {
       
   331         // error even though the code did not leave
       
   332         err = ret;
       
   333 
       
   334         ELOG1(EJavaInstaller,
       
   335               "Cannot register application, non-leaving error %d",
       
   336               ret);
       
   337     }
       
   338 
       
   339     // Free all Symbian buffers containing copies of jstring data
       
   340     delete unicodeIconFileName;
       
   341     delete unicodeGroupName;
       
   342     delete unicodeMIDletName;
       
   343     delete unicodeTargetDrive;
       
   344     delete unicodeJarFileName;
       
   345 
       
   346     return err;
       
   347 }
       
   348 #endif // RD_JAVA_USIF_APP_REG
       
   349 
       
   350 
       
   351 /**
       
   352  * See JNI method __1registerApplication.
       
   353  * This method makes all calls that may leave (the actual registering)
       
   354  */
       
   355 jint registerApplicationL(
       
   356     JNIEnv *, jclass, jint aSessionHandle, jint aUid, HBufC16 *aGroupName,
       
   357     HBufC16 *aMIDletName, HBufC16 *aTargetDrive, HBufC16 *aIconFileName,
       
   358     HBufC16 * /*aJarFileName*/, jboolean aHidden, jboolean aBackground)
       
   359 {
       
   360     RFs         fileServ;
       
   361     RFile       appArcIcon;
       
   362     TUid        midletUid;
       
   363     TInt        err;
       
   364     TInt        numberOfIcons = 1; // Conversion results always one icon in mbm.
       
   365     // Also default mbm has one icon.
       
   366 
       
   367     midletUid.iUid = aUid;
       
   368 
       
   369     // AppArc requires open RFile handle
       
   370     err = fileServ.Connect();
       
   371     if (KErrNone != err)
       
   372     {
       
   373         // Will not register application without icon
       
   374         ELOG1(EJavaInstaller,
       
   375               "Cannot open RFs connection, err code is %d ", err);
       
   376         return err;
       
   377     }
       
   378     CleanupClosePushL(fileServ);
       
   379 
       
   380     // The session must be shared so that AppArc can
       
   381     // use the same icon file handle
       
   382     err = fileServ.ShareProtected();
       
   383     if (KErrNone != err)
       
   384     {
       
   385         ELOG1(EJavaInstaller,
       
   386               "Cannot share file server session, err code is %d ", err);
       
   387         User::Leave(err);
       
   388     }
       
   389 
       
   390     // Default icon has been copied from ROM, so the icon may have ReadOnly
       
   391     // flag on. Must remove that flag.
       
   392     fileServ.SetAtt(*aIconFileName, 0, KEntryAttReadOnly);
       
   393 
       
   394     // open the icon
       
   395     err = appArcIcon.Open(
       
   396               fileServ,
       
   397               *aIconFileName,
       
   398               (EFileShareReadersOrWriters | EFileWrite));
       
   399     if (KErrNone != err)
       
   400     {
       
   401         ELOG1(EJavaInstaller,
       
   402               "registerApplicationL: Cannot open icon, err code is %d ", err);
       
   403         User::Leave(err);
       
   404     }
       
   405 
       
   406     // Now icon is open
       
   407     CleanupClosePushL(appArcIcon);
       
   408 
       
   409     // Generate the executable name name using the same
       
   410     // algorithm as used earlier in S60 platform
       
   411     // in case some external S60 application
       
   412     // needs to parse the Uid from the executable name.
       
   413     TFileName appName;
       
   414     appName.Copy(KPathSeperator);
       
   415     appName.AppendNum(midletUid.iUid);
       
   416     appName.Append(KAppPostfix);
       
   417 
       
   418     // Create writer needed for actual registration
       
   419     CApaRegistrationResourceFileWriter *writer = NULL;
       
   420     writer = CApaRegistrationResourceFileWriter::NewL(
       
   421                  midletUid,
       
   422                  appName,
       
   423                  TApaAppCapability::ENonNative);
       
   424     CleanupStack::PushL(writer);
       
   425 
       
   426     writer->SetGroupNameL(*aGroupName);
       
   427     if (aBackground)
       
   428     {
       
   429         // By default this is false, so the value needs to be set
       
   430         // only if it is true
       
   431         writer->SetLaunchInBackgroundL(ETrue);
       
   432     }
       
   433     if (aHidden)
       
   434     {
       
   435         // By default this is false, so the value needs to be set
       
   436         // only if it is true
       
   437         writer->SetAppIsHiddenL(ETrue);
       
   438     }
       
   439 
       
   440     // write application Uid to opaque data   (needed by MIDlet launcher)
       
   441     TBuf8<4>         opaqueData;     // opaque data will contain one signed 32-bit int
       
   442     RDesWriteStream  writeStream(opaqueData);
       
   443     writeStream.WriteInt32L(midletUid.iUid);
       
   444     writeStream.CommitL();
       
   445     writer->SetOpaqueDataL(opaqueData);
       
   446 
       
   447     CApaLocalisableResourceFileWriter*  lWriter = NULL;
       
   448     lWriter =
       
   449         CApaLocalisableResourceFileWriter::NewL(
       
   450             KNullDesC,  // short caption
       
   451             *aMIDletName,  // caption
       
   452             numberOfIcons,
       
   453             KNullDesC);
       
   454     CleanupStack::PushL(lWriter);
       
   455 
       
   456     TDriveUnit targetDrive(*aTargetDrive);
       
   457 
       
   458     // Convert session handle to pointer.
       
   459     RApaLsSession *pApaSession =
       
   460         reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
       
   461 
       
   462     // Register application to AppArc
       
   463     pApaSession->RegisterNonNativeApplicationL(
       
   464         KMidletApplicationTypeUid,
       
   465         targetDrive,
       
   466         *writer,
       
   467         lWriter,
       
   468         &appArcIcon);
       
   469 
       
   470     CleanupStack::PopAndDestroy(lWriter);
       
   471     CleanupStack::PopAndDestroy(writer);
       
   472     // close icon file handle
       
   473     CleanupStack::PopAndDestroy(&appArcIcon);
       
   474 
       
   475     // close file server connection
       
   476     CleanupStack::PopAndDestroy(&fileServ);
       
   477 
       
   478     return err;
       
   479 }
       
   480 
       
   481 
       
   482 /**
       
   483  * Unregisters Java Application from S60 AppArc
       
   484  *
       
   485  * @param[in] aSessionHandle
       
   486  * @param[in] aUid The Uid of the application to be unregistered..
       
   487  * @return 0 if unregistration succeeded or Symbian error code
       
   488  */
       
   489 #if 0
       
   490 //#ifdef RD_JAVA_USIF_APP_REG
       
   491 JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1unregisterApplication
       
   492 (JNIEnv *, jclass, jint /*aSessionHandle*/, jint /*aUid*/)
       
   493 {
       
   494     return KErrNone;
       
   495 }
       
   496 #else
       
   497 JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1unregisterApplication
       
   498 (JNIEnv *, jclass, jint aSessionHandle, jint aUid)
       
   499 {
       
   500     // Convert session handle to pointer.
       
   501     RApaLsSession *pApaSession =
       
   502         reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
       
   503 
       
   504     TUid appUid;
       
   505     appUid.iUid = aUid;
       
   506     TRAPD(err, pApaSession->DeregisterNonNativeApplicationL(appUid));
       
   507     return err;
       
   508 }
       
   509 #endif // RD_JAVA_USIF_APP_REG
       
   510 
       
   511 
       
   512 /**
       
   513  * Commits native application registration session.
       
   514  * If commit succeeds the native session is closed.
       
   515  *
       
   516  * @param[in] aSessionHandle
       
   517  * @param[in] aSynchronous if true, makes synchronous commit
       
   518  * @return 0 or Symbian error code (negative number)
       
   519  */
       
   520 JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1commitSession
       
   521 (JNIEnv *, jclass, jint aSessionHandle, jboolean aSynchronous)
       
   522 {
       
   523     // Convert session handle to pointer.
       
   524     RApaLsSession *pApaSession =
       
   525         reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
       
   526 
       
   527     TInt err = KErrNone;
       
   528 
       
   529 #if 1
       
   530 //#ifndef RD_JAVA_USIF_APP_REG
       
   531     if (aSynchronous)
       
   532     {
       
   533         // Make synchronous commit
       
   534         TRAP(err, pApaSession->CommitNonNativeApplicationsUpdatesL());
       
   535         if (KErrNone == err)
       
   536         {
       
   537             pApaSession->Close();
       
   538             delete pApaSession;
       
   539         }
       
   540         return err;
       
   541     }
       
   542 
       
   543     // Otherwise check whether the device supports asynchronous commit
       
   544     // (has a working version of new AppArc method ForceCommitNonNativeApplicationsUpdatesL)
       
   545     // Latest S60 5.0 builds contain fix for Symbian
       
   546     // defect PDEF129466 (PDEF129467 for Symbian OS 9.5).
       
   547     if (!isForceCommitSupported())
       
   548     {
       
   549         // Use old API
       
   550         TRAP(err, pApaSession->CommitNonNativeApplicationsUpdatesL());
       
   551     }
       
   552     else
       
   553     {
       
   554 #ifdef __WINS__
       
   555         // Use always this synchronous commit when running in emulator
       
   556         // to make writing autotest cases easier.
       
   557         TRAP(err, pApaSession->CommitNonNativeApplicationsUpdatesL());
       
   558 #else
       
   559         // asynchronous commit
       
   560         TRAP(err, pApaSession->ForceCommitNonNativeApplicationsUpdatesL());
       
   561 #endif // __WINS__
       
   562     }
       
   563 #endif // RD_JAVA_USIF_APP_REG
       
   564 
       
   565     if (KErrNone == err)
       
   566     {
       
   567         pApaSession->Close();
       
   568         delete pApaSession;
       
   569     }
       
   570     return err;
       
   571 }
       
   572 
       
   573 
       
   574 /**
       
   575  * Rolls back and closes native application registration session.
       
   576  *
       
   577  * @param[in] aSessionHandle
       
   578  * @return 0 or Symbian error code (negative number)
       
   579  */
       
   580 JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1rollbackSession
       
   581 (JNIEnv *, jclass, jint aSessionHandle)
       
   582 {
       
   583     // Convert session handle to pointer.
       
   584     RApaLsSession *pApaSession =
       
   585         reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
       
   586 
       
   587     TInt err = KErrNone;
       
   588 #if 1
       
   589 //#ifndef RD_JAVA_USIF_APP_REG
       
   590     err = pApaSession->RollbackNonNativeApplicationsUpdates();
       
   591 #endif // RD_JAVA_USIF_APP_REG
       
   592     pApaSession->Close();
       
   593     delete pApaSession;
       
   594 
       
   595     return err;
       
   596 }
       
   597 
       
   598 
       
   599 /**
       
   600  * Tells whether the uid is in use in AppArc.
       
   601  * Calls AppArc RApaLsSession::GetAppType
       
   602  *
       
   603  * @param[in] aSessionHandle
       
   604  * @param[in] aUid
       
   605  * @return 0 if the uid is not in use,
       
   606  *  1 if the uid is in use
       
   607  */
       
   608 JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1uidInUse
       
   609 (JNIEnv *, jclass, jint aSessionHandle, jint aUid)
       
   610 {
       
   611     // Convert session handle to pointer.
       
   612     RApaLsSession *pApaSession =
       
   613         reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
       
   614 
       
   615     TUid typeUid;
       
   616     TUid appUid;
       
   617     appUid.iUid = aUid;
       
   618     TInt err = pApaSession->GetAppType(typeUid, appUid);
       
   619     if (KErrNone == err)
       
   620     {
       
   621         // AppArc knows the app type -> the uid is in use
       
   622         return 1;
       
   623     }
       
   624     else
       
   625     {
       
   626         return 0;
       
   627     }
       
   628 }
       
   629 
       
   630 
       
   631 /**
       
   632  * Returns the logical group name of the application.
       
   633  * Calls AppArc RApaLsSession::GetAppCapability
       
   634  *
       
   635  * @param[in] aSessionHandle
       
   636  * @param[in] aUid
       
   637  * @param[out] aGroupName should be "" when called, will contain group name
       
   638  *  when function returns if call was successfull.
       
   639  *  Note that max group name len is 16.
       
   640  * @return Symbian error code (negative number) if fails, otherwise 0
       
   641  */
       
   642 JNIEXPORT jint JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1getGroupName
       
   643 (JNIEnv *aEnv, jclass aClass, jint aSessionHandle, jint aUid, jobject aGroupName)
       
   644 {
       
   645     if (0 == aGroupName)
       
   646     {
       
   647         // Cannot return logical group name because StringBuffer param is null
       
   648         return KErrArgument;
       
   649     }
       
   650 
       
   651     // Convert session handle to pointer.
       
   652     RApaLsSession *pApaSession =
       
   653         reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
       
   654 
       
   655     TInt    err;
       
   656     TUid    midletUid;
       
   657     TApaAppCapabilityBuf cap;
       
   658 
       
   659     midletUid.iUid = aUid;
       
   660 
       
   661     err = pApaSession->GetAppCapability(cap, midletUid);
       
   662     if (KErrNone != err)
       
   663     {
       
   664         return err;
       
   665     }
       
   666 
       
   667     // The name is available in Unicode format from cap, convert it to UTF8
       
   668     // Then lenght of the buffer has '+1' to reserve space for zero terminator
       
   669     // needed to convert string to Java string
       
   670     TBuf8<KApaMaxAppGroupName+1> nameBuf;   // max group name len is 16
       
   671     err = CnvUtfConverter::ConvertFromUnicodeToUtf8(nameBuf, cap().iGroupName);
       
   672     if (KErrNone != err)
       
   673     {
       
   674         return err;
       
   675     }
       
   676 
       
   677     // Get class handle to StringBuffer
       
   678     aClass = aEnv->GetObjectClass(aGroupName);
       
   679 
       
   680     // Get method ID to StringBuffer StringBuffer.append(String)
       
   681     jmethodID methodID = aEnv->GetMethodID(
       
   682                              aClass,
       
   683                              "append",
       
   684                              "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
       
   685     if (0 == methodID)
       
   686     {
       
   687         return KErrGeneral;
       
   688     }
       
   689 
       
   690     // Create new Java String
       
   691     jstring logicalName = aEnv->NewStringUTF((const char*)(nameBuf.PtrZ()));
       
   692 
       
   693     // Append it to aGroupName parameter
       
   694     aEnv->CallObjectMethod(aGroupName, methodID, logicalName);
       
   695 
       
   696     return 0;
       
   697 }
       
   698 
       
   699 
       
   700 /**
       
   701  * Closes native application registration session.
       
   702  *
       
   703  * @param[in] aSessionHandle the session to be closed
       
   704  */
       
   705 JNIEXPORT void JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1closeSession
       
   706 (JNIEnv *, jclass, jint aSessionHandle)
       
   707 {
       
   708     // Convert session handle to pointer.
       
   709     RApaLsSession *pApaSession =
       
   710         reinterpret_cast<RApaLsSession*>(aSessionHandle<<2);
       
   711 
       
   712     pApaSession->Close();
       
   713     delete pApaSession;
       
   714 }
       
   715 
       
   716 
       
   717 /**
       
   718  * Converts icon to S60 specific format. SVG icons are converted to MIF,
       
   719  * other icons to MBM.
       
   720  *
       
   721  * @param[in] aInputIconFilename file name of the original icon inside .jar
       
   722  * @param[in] aOutputIconFilename file name for converted (output) icon
       
   723  * @param[in] aJarFilename jar file name. In S60 the icon is always
       
   724  *   inside the .jar file
       
   725  * @param[out] aIconSuffix the correct suffix of the icon is returned through
       
   726  *    this parameter, will contain '.mbm' or '.mif' when function returns
       
   727  * @return true if the conversion succeeds
       
   728  */
       
   729 JNIEXPORT jboolean JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1convertIcon
       
   730 (JNIEnv *aEnv, jclass aClass, jstring aInputIconFilename,
       
   731  jstring aOutputIconFilename, jstring aJarFilename, jobject aIconSuffix)
       
   732 {
       
   733     jboolean conversionSucceeded = JNI_TRUE;
       
   734     RFs      fileServ;
       
   735 
       
   736     // IconConverter requires open RFile handle
       
   737     TInt err = fileServ.Connect();
       
   738     if (KErrNone != err)
       
   739     {
       
   740         // Cannot convert icons without file server connection
       
   741         ELOG1(EJavaInstaller,
       
   742               "_1convertIcon: Cannot open RFs connection, err code is %d ", err);
       
   743         return err;
       
   744     }
       
   745 
       
   746     // Copy the unicode characters in jstrings to Symbian buffers so that
       
   747     // they can be used in S60 code
       
   748     const jchar *iconFileName = aEnv->GetStringChars(aInputIconFilename, 0);
       
   749     if (NULL == iconFileName)
       
   750     {
       
   751         ELOG(
       
   752             EJavaInstaller,
       
   753             "Cannot convert icon, getting icon file name as unicode failed in JNI");
       
   754         fileServ.Close();
       
   755         return JNI_FALSE;
       
   756     }
       
   757     HBufC16 *unicodeIconFileName = HBufC16::New(aEnv->GetStringLength(aInputIconFilename) + 1);
       
   758     if (NULL == unicodeIconFileName)
       
   759     {
       
   760         fileServ.Close();
       
   761         return JNI_FALSE;
       
   762     }
       
   763     *unicodeIconFileName = iconFileName;
       
   764     aEnv->ReleaseStringChars(aInputIconFilename, iconFileName);
       
   765 
       
   766     const jchar *jarFileName = aEnv->GetStringChars(aJarFilename, 0);
       
   767     if (NULL == jarFileName)
       
   768     {
       
   769         ELOG(
       
   770             EJavaInstaller,
       
   771             "Cannot convert icon, getting jar file name as unicode failed in JNI");
       
   772         delete unicodeIconFileName;
       
   773         fileServ.Close();
       
   774         return JNI_FALSE;
       
   775     }
       
   776     HBufC16 *unicodeJarFileName = HBufC16::New(aEnv->GetStringLength(aJarFilename) + 1);
       
   777     if (NULL == unicodeJarFileName)
       
   778     {
       
   779         delete unicodeIconFileName;
       
   780         fileServ.Close();
       
   781         return JNI_FALSE;
       
   782     }
       
   783     *unicodeJarFileName = jarFileName;
       
   784     aEnv->ReleaseStringChars(aJarFilename, jarFileName);
       
   785 
       
   786     const jchar *outputFileName = aEnv->GetStringChars(aOutputIconFilename, 0);
       
   787     if (NULL == outputFileName)
       
   788     {
       
   789         ELOG(
       
   790             EJavaInstaller,
       
   791             "Cannot convert icon, getting output file name as unicode failed in JNI");
       
   792         delete unicodeIconFileName;
       
   793         delete unicodeJarFileName;
       
   794         fileServ.Close();
       
   795         return JNI_FALSE;
       
   796     }
       
   797     HBufC16 *unicodeOutputFileName = HBufC16::New(aEnv->GetStringLength(aOutputIconFilename) + 1);
       
   798     if (NULL == unicodeOutputFileName)
       
   799     {
       
   800         delete unicodeIconFileName;
       
   801         delete unicodeJarFileName;
       
   802         fileServ.Close();
       
   803         return JNI_FALSE;
       
   804     }
       
   805     *unicodeOutputFileName = outputFileName;
       
   806     aEnv->ReleaseStringChars(aOutputIconFilename, outputFileName);
       
   807 
       
   808     CIconConverter *pConv = NULL;
       
   809     TRAP(err, pConv= CIconConverter::NewL(fileServ));
       
   810     if (KErrNone != err)
       
   811     {
       
   812         ELOG1(EJavaInstaller, "Cannot create icon converter, error %d ", err);
       
   813         delete unicodeIconFileName;
       
   814         delete unicodeJarFileName;
       
   815         delete unicodeOutputFileName;
       
   816         fileServ.Close();
       
   817         return JNI_FALSE;
       
   818     }
       
   819 
       
   820     // read icon from .jar file, convert it to MIF/MBM and store to file
       
   821     TBool isMbmIcon = EFalse;
       
   822     err = pConv->Convert(*unicodeJarFileName, *unicodeIconFileName,
       
   823                          *unicodeOutputFileName, &isMbmIcon);
       
   824     delete pConv;
       
   825     if (KErrNone != err)
       
   826     {
       
   827         WLOG1(EJavaInstaller,
       
   828               "Cannot convert icon, err code is %d.",
       
   829               err);
       
   830         conversionSucceeded = JNI_FALSE;
       
   831     }
       
   832 
       
   833     // Free all Symbian buffers containing copies of jstring data
       
   834     delete unicodeIconFileName;
       
   835     delete unicodeJarFileName;
       
   836     delete unicodeOutputFileName;
       
   837     fileServ.Close();
       
   838 
       
   839     // set the value of aIconSuffix to '.mbm' or '.mif'
       
   840     if (0 == aIconSuffix)
       
   841     {
       
   842         // Cannot return icon suffix name because StringBuffer param is null
       
   843         WLOG(EJavaInstaller,
       
   844              "_1convertIcon cannot return the correct icon suffix because param is null");
       
   845         return JNI_FALSE;
       
   846     }
       
   847 
       
   848     // Get class handle to StringBuffer
       
   849     aClass = aEnv->GetObjectClass(aIconSuffix);
       
   850 
       
   851     // Get method ID to StringBuffer StringBuffer.append(String)
       
   852     jmethodID methodID = aEnv->GetMethodID(
       
   853                              aClass,
       
   854                              "append",
       
   855                              "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
       
   856     if (0 == methodID)
       
   857     {
       
   858         WLOG(EJavaInstaller, "_1convertIcon: JNI: getting append method failed.");
       
   859         return JNI_FALSE;
       
   860     }
       
   861 
       
   862     // Create new Java String, Multibitmap file name suffix is '.mbm',
       
   863     // suffix for mif wrapped svg is '.mif'
       
   864     jstring suffix;
       
   865     if (isMbmIcon)
       
   866     {
       
   867         suffix = aEnv->NewStringUTF(".mbm");
       
   868     }
       
   869     else
       
   870     {
       
   871         suffix = aEnv->NewStringUTF(".mif");
       
   872     }
       
   873 
       
   874     // Append it to aIconSuffix parameter
       
   875     aEnv->CallObjectMethod(aIconSuffix, methodID, suffix);
       
   876 
       
   877     return conversionSucceeded;
       
   878 }
       
   879 
       
   880 
       
   881 /**
       
   882  * Returns true if the current device is touch screen
       
   883  * device without physical LSK and RSK
       
   884  *
       
   885  * @return true if virtual on screen keypad is needed
       
   886  */
       
   887 JNIEXPORT jboolean JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1isOnDeviceKeypadNeeded
       
   888 (JNIEnv *, jclass)
       
   889 {
       
   890     // Return TRUE -> OnScreenKeypad attribute will be given
       
   891     // default value if the attribute has not been defined in
       
   892     // .jad file or manifest.
       
   893     // The runtime code will check whether the device has touch
       
   894     // screen using AknLayoutUtils::PenEnabled() and show the
       
   895     // keypad only if needed.
       
   896     return JNI_TRUE;
       
   897 }
       
   898 
       
   899 
       
   900 /**
       
   901  * Sends a process to process notification to the parent process
       
   902  * of Java Installer telling that Installer is about to start
       
   903  * displaying UI dialogs.
       
   904  */
       
   905 JNIEXPORT void JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1notifyLauncherThatUiIsReady
       
   906 (JNIEnv *, jclass)
       
   907 {
       
   908     RProcess currentProcess;
       
   909     currentProcess.Rendezvous(EJavaInstaller);
       
   910 
       
   911     return;
       
   912 }
       
   913 
       
   914 
       
   915 /**
       
   916  * Returns true if the code is executed in Symbian 9.2
       
   917  * emulator environment.
       
   918  *
       
   919  * @return if Symbian 9.2 emulator environment
       
   920  */
       
   921 JNIEXPORT jboolean JNICALL Java_com_nokia_mj_impl_installer_applicationregistrator_ApplicationRegistrator__1runningIn92Emulator
       
   922 (JNIEnv *, jclass)
       
   923 {
       
   924 #if !defined(RD_JAVA_S60_RELEASE_5_0_IAD) && defined(__WINS__)
       
   925     return JNI_TRUE;
       
   926 #else
       
   927     return JNI_FALSE;
       
   928 #endif
       
   929 }
       
   930 
       
   931 
       
   932 /**
       
   933  * Internal helper method for checking whether this code is executing in
       
   934  * a device that has correctly working version of
       
   935  * RApaLsSession::ForceCommitNonNativeApplicationsUpdatesL()
       
   936  *
       
   937  * The device family based on Nokia XpressMusic5800 did not have
       
   938  * working version of force commit
       
   939  *
       
   940  * @return ETrue if current device does not belong to Nokia XpressMusic5800
       
   941  *  device family
       
   942  */
       
   943 TBool isForceCommitSupported()
       
   944 {
       
   945     TInt err;
       
   946     TInt value;
       
   947 
       
   948     err = HAL::Get(HAL::EModel, value);
       
   949     if (KErrNone == err)
       
   950     {
       
   951         LOG1(EJavaInstaller, EInfo, "Device model is %d", value);
       
   952     }
       
   953     else
       
   954     {
       
   955         WLOG1(EJavaInstaller, "Cannot get device model id, error %d", err);
       
   956         // It is safest to assume that force commit is not supported
       
   957         return EFalse;
       
   958     }
       
   959 
       
   960     // Check against all current (28. Aug 2009) members of the device family.
       
   961     // Note that several closely related devices share the same model id.
       
   962     if ((0x2000DA56 != value) &&
       
   963             (0x2001DE9D != value) &&
       
   964             (0x2000DA60 != value) &&
       
   965             (0x20023765 != value))
       
   966     {
       
   967         // The device does not belong to Nokia 5800 XpressMusic device family,
       
   968         // so it supports foce commit
       
   969         return ETrue;
       
   970     }
       
   971     else
       
   972     {
       
   973         return EFalse;
       
   974     }
       
   975 }