--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commands/swi/swi.cpp Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,1250 @@
+// swi.cpp
+//
+// Copyright (c) 2008 - 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "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:
+// Accenture - Initial contribution
+//
+
+#include "swi.h"
+#include <fshell/common.mmh>
+#include <fshell/ltkutils.h>
+
+typedef TBuf<1> TUserInput;
+_LIT(KSwiYes, "y");
+_LIT(KSwiNo, "n");
+_LIT(KSwiJarExtension, "*.jar");
+_LIT(KSwiJadExtension, "*.jad");
+#ifndef SYMBIAN_JAVA_NOT_INCLUDED
+_LIT8(KDefaultJadMimeType, "text/vnd.sun.j2me.app-descriptor");
+_LIT8(KDefaultJarMimeType, "application/java-archive");
+#endif
+_LIT(KDefaultMatch, "*");
+
+//
+// CCmdSwi
+// class to handle the fshell console user interaction
+//
+CCommandBase* CCmdSwi::NewLC()
+ {
+ CCmdSwi* self = new(ELeave) CCmdSwi();
+ CleanupStack::PushL(self);
+ self->BaseConstructL();
+ return self;
+ }
+
+CCmdSwi::~CCmdSwi()
+ {
+#ifndef SYMBIAN_JAVA_NOT_INCLUDED
+ delete iMidletHandler;
+#endif
+ delete iSisHandler;
+ delete iMatch;
+ }
+
+CCmdSwi::CCmdSwi():
+CCommandBase(CCommandBase::EManualComplete)
+ {
+ }
+
+const TDesC& CCmdSwi::Name() const
+ {
+ _LIT(KName, "swi");
+ return KName;
+ }
+
+void CCmdSwi::ArgumentsL(RCommandArgumentList& aArguments)
+ {
+ aArguments.AppendEnumL((TInt&)iCommand, _L("operation"));
+
+ _LIT(KArgFilename, "sis-file");
+ aArguments.AppendFileNameL(iSisFile, KArgFilename);
+ }
+
+void CCmdSwi::OptionsL(RCommandOptionList& aOptions)
+ {
+ _LIT(KOptUid, "uid");
+ aOptions.AppendUintL((TUint&)iUid.iUid, KOptUid);
+
+ _LIT(KOptVerbose, "verbose");
+ aOptions.AppendBoolL(iVerbose, KOptVerbose);
+
+ _LIT(KOptQuiet, "quiet");
+ aOptions.AppendBoolL(iQuiet, KOptQuiet);
+
+ _LIT(KOptMatch, "match");
+ aOptions.AppendStringL(iMatch, KOptMatch);
+ }
+
+void CCmdSwi::DoRunL()
+ {
+ if (iMatch == NULL)
+ {
+ iMatch = KDefaultMatch().AllocL();
+ }
+
+ iSisHandler = CSwiSisInstallerAO::NewL(*this, FsL(), iVerbose, iQuiet);
+#ifndef SYMBIAN_JAVA_NOT_INCLUDED
+ iMidletHandler = CSwiMidletInstallerAO::NewL(*this, FsL(), iVerbose, iQuiet);
+#endif
+
+ switch (iCommand)
+ {
+ case EList:
+ //TODO matching
+ TRAPL(iSisHandler->ListInstalledAppsL(iUid, *iMatch), _L("Couldn't list installed SIS files"));
+#ifndef SYMBIAN_JAVA_NOT_INCLUDED
+ TRAPL(iMidletHandler->ListInstalledAppsL(iUid, *iMatch), _L("Couldn't list installed midlets"));
+#endif
+ Complete(KErrNone);
+ break;
+
+ case EUninstall:
+ if (!iOptions.IsPresent(&iUid))
+ {
+ LeaveIfErr(KErrArgument, _L("UID must be specified for \"uninstall\""));
+ }
+ TRAPD(error, iSisHandler->UninstallL(iUid));
+ if (error != KErrNone)
+ {
+#ifndef SYMBIAN_JAVA_NOT_INCLUDED
+ // possibly a midlet
+ TRAP(error, iMidletHandler->UninstallL(iUid));
+#endif
+ }
+ LeaveIfErr(error, _L("Failed to uninstall package 0x%08x"), iUid.iUid);
+ break;
+
+ case EInstall:
+ if (!iArguments.IsPresent(1))
+ {
+ LeaveIfErr(KErrArgument, _L("SIS file must be specified for \"install\""));
+ }
+ User::LeaveIfError(Stdin().SetReadMode(RIoReadHandle::ELine));
+#ifndef SYMBIAN_JAVA_NOT_INCLUDED
+ if (IsMidlet())
+ {
+ TRAPL(iMidletHandler->InstallL(iSisFile), _L("Failed to install midlet '%S'"), &iSisFile);
+ }
+ else
+#endif
+ {
+ TRAPL(iSisHandler->InstallL(iSisFile), _L("Failed to install sis '%S'"), &iSisFile);
+ }
+ break;
+ }
+
+ }
+
+TBool CCmdSwi::IsMidlet()
+ {
+ if ((iSisFile.MatchF(KSwiJarExtension) != KErrNotFound) || (iSisFile.MatchF(KSwiJadExtension) != KErrNotFound))
+ return ETrue;
+ return EFalse;
+ }
+
+//
+// CCmdSwi::GetAnswer
+// only for use when not in quiet mode
+// Reads input from stdin, determines whether it's a 'yes' or 'no', returning ETrue, EFalse respectively
+//
+TBool CCmdSwi::GetAnswer()
+ {
+ ASSERT(!iQuiet);
+ TUserInput in;
+ for (;;)
+ {
+ if (Stdin().Read(in) != KErrNone)
+ {
+ return EFalse;
+ }
+ Stdout().Write(in);
+ if (in.MatchF(KSwiYes) == 0)
+ {
+ return ETrue;
+ }
+ if (in.MatchF(KSwiNo) == 0)
+ {
+ return EFalse;
+ }
+ // else it's an unrecognised response
+ }
+ }
+
+//
+// MCmdSwiParent hooks
+//
+RIoConsoleReadHandle& CCmdSwi::Input()
+ {
+ return Stdin();
+ }
+
+RIoConsoleWriteHandle& CCmdSwi::Output(TInt aError)
+ {
+ if (aError == KErrNone)
+ {
+ return Stdout();
+ }
+ return Stderr();
+ }
+
+//
+// CCmdSwi::Finished
+// callback from the underlying AO's RunL
+//
+void CCmdSwi::Finished(const TInt aError)
+ {
+ Complete(aError);
+ }
+
+//
+// Sis installer AO
+//
+CSwiSisInstallerAO* CSwiSisInstallerAO::NewL(MCmdSwiParent& aParent, RFs& aFs, TBool aVerbose, TBool aQuiet)
+ {
+ CSwiSisInstallerAO* self = new (ELeave) CSwiSisInstallerAO(aParent, aFs, aVerbose, aQuiet);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CSwiSisInstallerAO::CSwiSisInstallerAO(MCmdSwiParent& aParent, RFs& aFs, TBool aVerbose, TBool aQuiet)
+ : CActive(CActive::EPriorityStandard), iParent(aParent), iVerbose(aVerbose), iQuiet(aQuiet), iCurrentDrive('c')
+ {
+ TFileName sessionPath;
+ TInt err = aFs.SessionPath(sessionPath);
+ if (err == KErrNone)
+ {
+ iCurrentDrive = sessionPath[0];
+ iCurrentDrive.LowerCase();
+ }
+ CActiveScheduler::Add(this);
+ }
+
+CSwiSisInstallerAO::~CSwiSisInstallerAO()
+ {
+ Cancel();
+ delete iLauncher;
+ delete iRegPackage;
+ iRegistrySession.Close();
+ delete iPrefs;
+ }
+
+void CSwiSisInstallerAO::ConstructL()
+ {
+ iLauncher = CAsyncLauncher::NewL();
+ User::LeaveIfError(iRegistrySession.Connect());
+ iPrefs = Swi::CInstallPrefs::NewL();
+ iPrefs->SetPerformRevocationCheck(EFalse); // TODO - not currently supported in CCmdSwi
+ }
+
+void CSwiSisInstallerAO::RunL()
+ {
+ iParent.Finished(iStatus.Int());
+ }
+
+void CSwiSisInstallerAO::DoCancel()
+ {
+ iLauncher->CancelOperation();
+ iParent.Finished(KErrCancel);
+ }
+
+void CSwiSisInstallerAO::PrintDetails(Swi::CSisRegistryPackage& aPackage)
+ {
+ if (iVerbose)
+ {
+ TName myBuf;
+ myBuf.Format(_L("\r\nName:\t%S\r\n"), &aPackage.Name());
+ Stdout().Write(myBuf);
+ myBuf.Format(_L("Vendor:\t%S\r\n"), &aPackage.Vendor());
+ Stdout().Write(myBuf);
+ myBuf.Format(_L("Uid:\t0x%x\r\n"), aPackage.Uid());
+ Stdout().Write(myBuf);
+ }
+ else
+ {
+ TBuf<256> buf; buf.Format(_L("0x%08x: "), aPackage.Uid());
+ Stdout().Write(buf);
+ Stdout().Write(aPackage.Name());
+ Stdout().Write(_L("\r\n"));
+ }
+ }
+
+void CSwiSisInstallerAO::InstallL(TFileName& aInstallFile)
+ {
+ // install regular sis file
+ ASSERT(iPrefs);
+ ASSERT(iLauncher);
+ iLauncher->InstallL(*this, aInstallFile, *iPrefs, iStatus);
+ SetActive();
+ }
+
+void CSwiSisInstallerAO::UninstallL(const TUid& aPackageUid)
+ {
+ // remove regular sis file
+ ASSERT(iLauncher);
+ ASSERT(!iRegPackage);
+ Swi::CSisRegistryPackage* iRegPackage = GetSisRegistryPackageL(aPackageUid);
+ iLauncher->UninstallL(*this, *iRegPackage, iStatus);
+ SetActive();
+ }
+
+//
+// CSwiSisInstallerAO::ListInstalledAppsL
+// lists apps currently installed on the device
+//
+void CSwiSisInstallerAO::ListInstalledAppsL(const TUid& aAppUid, const TDesC& aMatchString)
+ {
+ if (aAppUid.iUid != 0)
+ {
+ DisplayPackageL(aAppUid);
+ }
+ else
+ {
+ ASSERT(iRegistrySession.Handle() > 0);
+ RPointerArray<CSisRegistryPackage> packages;
+ LtkUtils::CleanupResetAndDestroyPushL(packages);
+ iRegistrySession.InstalledPackagesL(packages);
+ if (packages.Count() <= 0)
+ {
+ User::Leave(KErrNotFound);
+ }
+ TInt count = 0;
+ const TInt endCount = packages.Count();
+ do
+ {
+ CSisRegistryPackage* current = packages[count++];
+ if ((current->Name().MatchF(aMatchString) >= 0) || (current->Vendor().MatchF(aMatchString) >= 0))
+ {
+ PrintDetails(*current);
+ }
+ } while (count < endCount);
+ CleanupStack::PopAndDestroy(&packages);
+ }
+ }
+
+//
+// CSwiSisInstallerAO::DisplayPackageL
+// find information on the specified package uid and display it on the console
+//
+void CSwiSisInstallerAO::DisplayPackageL(const TUid& aPackageUid)
+ {
+ ASSERT(iRegistrySession.Handle() > 0);
+ Swi::RSisRegistryEntry entry;
+ User::LeaveIfError(entry.Open(iRegistrySession, aPackageUid));
+ CleanupClosePushL(entry);
+ Swi::CSisRegistryPackage* registryPackage = entry.PackageL();
+ CleanupStack::PushL(registryPackage);
+ PrintDetails(*registryPackage);
+ CleanupStack::PopAndDestroy(2, &entry);
+ }
+
+//
+// CSwiSisInstallerAO::GetSisRegistryPackageL
+// locate the sis registry package corresponding to the specified package ui
+//
+Swi::CSisRegistryPackage* CSwiSisInstallerAO::GetSisRegistryPackageL(const TUid& aPackageUid)
+ {
+ ASSERT(iRegistrySession.Handle() > 0);
+ if (!iRegistrySession.IsInstalledL(aPackageUid))
+ {
+ User::Leave(KErrNotFound); // invalid uid
+ }
+ // else iterate through the installed packages to find ours
+ RPointerArray<Swi::CSisRegistryPackage> packages;
+ iRegistrySession.InstalledPackagesL(packages);
+ if (packages.Count() <= 0)
+ {
+ User::Leave(KErrNotFound);
+ }
+ TInt count = 0;
+ const TInt endCount = packages.Count();
+ Swi::CSisRegistryPackage* found = NULL;
+ do
+ {
+ Swi::CSisRegistryPackage* current = packages[count];
+ if (current->Uid() == aPackageUid)
+ {
+ found = current;
+ break;
+ }
+ count++;
+ } while (count < endCount);
+ ASSERT(found); // IsInstalledL stated it's in there
+ return found;
+ }
+
+//
+// SWI UI Hooks
+//
+TBool CSwiSisInstallerAO::DisplayTextL(const Swi::CAppInfo& /*aAppInfo*/, Swi::TFileTextOption /*aOption*/, const TDesC& aText)
+ {
+ TBool response = ETrue; // default, the user will continue with the installation/uninstallation
+ if (!iQuiet)
+ {
+ Stdout().Write(aText);
+ Stdout().Write(_L("Continue [y/n]?\r\n"));
+ response = iParent.GetAnswer();
+ }
+ return response;
+ }
+
+void CSwiSisInstallerAO::DisplayErrorL(const Swi::CAppInfo& /*aAppInfo*/, Swi::TErrorDialog aType, const TDesC& /*aParam*/)
+ {
+ if (iVerbose)
+ {
+ switch (aType)
+ {
+ case Swi::EUiAlreadyInRom:
+ Stderr().Write(_L("\r\nCannot overwrite a ROM component.\r\n"));
+ break;
+
+ case Swi::EUiMissingDependency:
+ Stderr().Write(_L("\r\nMissing a dependency.\r\n"));
+ break;
+
+ case Swi::EUiRequireVer:
+ Stderr().Write(_L("\r\nA dependency exists on a specific version of an application which is different from the one installed.\r\n"));
+ break;
+
+ case Swi::EUiFileCorrupt:
+ Stderr().Write(_L("\r\nSISX file corrupt. Checksums stored in file do not match actual.\r\n"));
+ break;
+
+ case Swi::EUiDiskNotPresent:
+ Stderr().Write(_L("\r\nAll your bases are belong to us. <disk not present>\r\n"));
+ break;
+
+ case Swi::EUiCannotRead:
+ Stderr().Write(_L("\r\nCannot read a file which is needed in order to proceed.\r\n"));
+ break;
+
+ case Swi::EUiCannotDelete:
+ Stderr().Write(_L("\r\nCannot delete a file.\r\n"));
+ break;
+
+ case Swi::EUiInvalidFileName:
+ Stderr().Write(_L("\r\nA filename specified in the SISX package is not valid.\r\n"));
+ break;
+
+ case Swi::EUiInsufficientSpaceOnDrive:
+ Stderr().Write(_L("\r\nInsufficient space on the drive.\r\n"));
+ break;
+
+ case Swi::EUiCapabilitiesCannotBeGranted:
+ Stderr().Write(_L("\r\nApplication requires system capability it is not signed for.\r\n"));
+ break;
+
+ case Swi::EUiUnknownFile:
+ Stderr().Write(_L("\r\nNot a recognised SISX file.\r\n"));
+ break;
+
+ case Swi::EUiMissingBasePackage:
+ Stderr().Write(_L("\r\nA base package required for installation is not present.\r\n"));
+ break;
+
+ case Swi::EUiConstraintsExceeded:
+ Stderr().Write(_L("\r\nConstraints imposed by a developer mode certificate have been exceeded.\r\n"));
+ break;
+
+ case Swi::EUiSIDViolation:
+ Stderr().Write(_L("\r\nThe package contains a file with a protected SID which is not signed for.\r\n"));
+ break;
+
+ case Swi::EUiVIDViolation:
+ Stderr().Write(_L("\r\nThe package contains a file with a protected VID which is not signed for.\r\n"));
+ break;
+
+ case Swi::EUiSIDMismatch:
+ Stderr().Write(_L("\r\nMismatched SID.\r\n"));
+ break;
+
+ case Swi::EUiBlockingEclipsingFile:
+ Stderr().Write(_L("\r\nThe package contains an invalid eclipsing file which is already in the device other than ROM.\r\n"));
+ break;
+
+ default:
+ {
+ TBuf<64> buf;
+ buf.Format(_L("\r\nAn error %d has occured. Aborting.\r\n"), aType);
+ Stderr().Write(buf);
+ }
+ break;
+ };
+ }
+ }
+
+TBool CSwiSisInstallerAO::DisplayDependencyBreakL(const Swi::CAppInfo& /*aAppInfo*/, const RPointerArray<TDesC>& /*aComponents*/)
+ {
+ TBool response = ETrue; // default response is to continue with uninstallation
+ if (iVerbose)
+ {
+ Stdout().Write(_L("\r\nComponent being uninstalled has dependencies which may no longer work. Continue uninstalling [y/n]?\r\n"));
+ response = iParent.GetAnswer();
+ }
+ return response;
+ }
+
+TBool CSwiSisInstallerAO::DisplayApplicationsInUseL(const Swi::CAppInfo& /*aAppInfo*/, const RPointerArray<TDesC>& /*aAppNames*/)
+ {
+ TBool response = EFalse; // EFalse indicates we don't continue with uninstallation
+ if (!iQuiet)
+ {
+ Stdout().Write(_L("\r\nApplication is currently open. Continue uninstalling? [y/n]\r\n"));
+ response = iParent.GetAnswer();
+ }
+ if (!response)
+ {
+ Stderr().Write(_L("Uninstall aborted. Application will not be closed.\r\n"));
+ }
+ return response;
+ }
+
+TBool CSwiSisInstallerAO::DisplayQuestionL(const Swi::CAppInfo& /* aAppInfo */, Swi::TQuestionDialog aQuestion, const TDesC& aDes)
+ {
+ TBool response = ETrue; // default behaviour assumes the user presses 'Yes' to any question
+ if (!iQuiet)
+ {
+ if (aQuestion == Swi::EQuestionIncompatible)
+ {
+ Stdout().Write(_L("\r\nApplication is not compatible with this device. Install anyway [y/n]?"));
+ }
+ else if (aQuestion == Swi::EQuestionOverwriteFile)
+ {
+ Stdout().Write(_L("\r\nSome system files will be overwritten by this installation. Install anyway [y/n]?"));
+ }
+ else
+ {
+ TBuf<128> buf; buf.Format(_L("Unrecognised question from engine %d\r\n"), aQuestion);
+ Stderr().Write(buf);
+ User::Leave(KErrNotSupported);
+ }
+
+ if (aDes.Length() > 0)
+ {
+ Stdout().Write(aDes);
+ }
+ Stdout().Write(_L("\r\n"));
+ response = iParent.GetAnswer();
+ }
+ return response;
+ }
+
+TBool CSwiSisInstallerAO::DisplayInstallL(const Swi::CAppInfo& aAppInfo, const CApaMaskedBitmap* /*aLogo*/, const RPointerArray<Swi::CCertificateInfo>& /*aCertificates*/)
+ {
+ if (iVerbose)
+ {
+ TBuf<256> myBuf;
+ myBuf.Format(_L("NAME:\t\t%S\r\n"), &aAppInfo.AppName());
+ Stdout().Write(myBuf);
+ myBuf.Format(_L("VENDOR:\t\t%S\r\n"), &aAppInfo.AppVendor());
+ Stdout().Write(myBuf);
+ myBuf.Format(_L("VERSION:\t%d.%d.%d\r\n"), aAppInfo.AppVersion().iMajor, aAppInfo.AppVersion().iMinor, aAppInfo.AppVersion().iBuild);
+ Stdout().Write(myBuf);
+ }
+ TBool response = ETrue; // default behaviour is to continue the install
+ return response;
+ }
+
+TBool CSwiSisInstallerAO::DisplayGrantCapabilitiesL(const Swi::CAppInfo& /*aAppInfo*/, const TCapabilitySet& /*aCapabilitySet*/)
+ {
+ TBool response = ETrue; // default behaviour is to continue the install
+ if (iVerbose)
+ {
+ // todo verbose mode
+ Stdout().Write(_L("\r\nTODO - CCmdSwi::DisplayGrantCapabilitiesL\r\n"));
+ }
+ return response;
+ }
+
+TInt CSwiSisInstallerAO::DisplayLanguageL(const Swi::CAppInfo& /*aAppInfo*/, const RArray<TLanguage>& /*aLanguages*/)
+ {
+ if (iVerbose)
+ {
+ // todo verbose mode
+ Stdout().Write(_L("\r\nTODO - CCmdSwi::DisplayLanguageL\r\n"));
+ }
+ return 0; // the first language
+ }
+
+TInt CSwiSisInstallerAO::DisplayDriveL(const Swi::CAppInfo& /*aAppInfo*/, TInt64 aSize, const RArray<TChar>& aDriveLetters, const RArray<TInt64>& aDriveSpaces)
+ {
+ TInt response = 0; // default to the first known drive
+ for (TInt i = 0; i < aDriveLetters.Count(); i++)
+ {
+ TChar letter = aDriveLetters[i];
+ letter.LowerCase();
+ if (letter == iCurrentDrive)
+ {
+ response = i; // Default to using the CWD drive, if it is in the list of available drives
+ break;
+ }
+ }
+
+ if (!iQuiet)
+ {
+ TBuf<128> info;
+ info.Format(_L("Application requires %d bytes free space. Please select installation drive:\r\n"), aSize);
+ Stdout().Write(info);
+ for (TInt ii = 0 ; ii < aDriveLetters.Count() ; ii++)
+ {
+ info.Format(_L("%d. \'"), ii); // pseudo-drive number
+ info.Append(aDriveLetters[ii]); // drive letter
+ info.Append(_L("\' "));
+ info.AppendNum(aDriveSpaces[ii]); // free space
+ info.Append(_L(" bytes free\r\n"));
+ Stdout().Write(info);
+ }
+ TUserInput in;
+ User::LeaveIfError(Stdin().Read(in));
+ TLex lex(in);
+ User::LeaveIfError(lex.Val(response));
+ }
+ return response;
+ }
+
+TBool CSwiSisInstallerAO::DisplayUpgradeL(const Swi::CAppInfo& /*aAppInfo*/, const Swi::CAppInfo& /*aExistingAppInfo*/)
+ {
+ TBool response = ETrue; // default behaviour is to continue the install
+ if (!iQuiet)
+ {
+ Stdout().Write(_L("Do you wish to replace the existing installed application [y/n]?\r\n"));
+ response = iParent.GetAnswer();
+ }
+ return response;
+ }
+
+TBool CSwiSisInstallerAO::DisplayOptionsL(const Swi::CAppInfo& /*aAppInfo*/, const RPointerArray<TDesC>& /*aOptions*/, RArray<TBool>& /*aSelections*/)
+ {
+ TBool response = ETrue; // default behaviour is to continue the install
+ if (iVerbose)
+ {
+ // todo verbose mode
+ Stdout().Write(_L("TODO - CCmdSwi::DisplayOptionsL\r\n"));
+ }
+ return response;
+ }
+
+TBool CSwiSisInstallerAO::HandleInstallEventL(const Swi::CAppInfo& /*aAppInfo*/, Swi::TInstallEvent aEvent, TInt /*aValue*/, const TDesC& /*aDes*/)
+ {
+ TBool response = ETrue; // default behaviour is to continue the install
+ if (iVerbose)
+ {
+ switch (aEvent)
+ {
+ case Swi::EEventUpdateProgressBar:
+ Stdout().Write(_L("."));
+ break;
+
+ case Swi::EEventCompletedInstall:
+ case Swi::EEventCompletedUnInstall:
+ {
+ Stdout().Write(_L("\r\nComplete\r\n"));
+ }
+ break;
+
+ default:
+ // do nothing to inform the user of other cases
+ break;
+ };
+ }
+ return response;
+ }
+
+void CSwiSisInstallerAO::HandleCancellableInstallEventL(const Swi::CAppInfo& /*aAppInfo*/, Swi::TInstallCancellableEvent aEvent, Swi::MCancelHandler& /*aCancelHandler*/, TInt /*aValue*/, const TDesC& /*aDes*/)
+ {
+ if (iVerbose)
+ {
+ switch (aEvent)
+ {
+ case Swi::EEventRemovingFiles:
+ {
+ Stdout().Write(_L("\r\nRemoving files\r\n"));
+ }
+ break;
+
+ case Swi::EEventShuttingDownApps:
+ {
+ Stdout().Write(_L("Closing App\r\n"));
+ }
+ break;
+
+ case Swi::EEventCopyingFiles:
+ {
+ Stdout().Write(_L("Copying files\r\n"));
+ }
+ break;
+
+ default:
+ break;
+ };
+ }
+ }
+
+TBool CSwiSisInstallerAO::DisplaySecurityWarningL(const Swi::CAppInfo& /*aAppInfo*/, Swi::TSignatureValidationResult /*aSigValidationResult*/, RPointerArray<CPKIXValidationResultBase>& /*aPkixResults*/, RPointerArray<Swi::CCertificateInfo>& /*aCertificates*/, TBool /*aInstallAnyway*/)
+ {
+ TBool response = ETrue; // default behaviour is to continue the install
+ if (!iQuiet)
+ {
+ Stdout().Write(_L("\r\nApplication signature cannot be validated. Continue installing [y/n]?\r\n"));
+ response = iParent.GetAnswer();
+ }
+ return response;
+ }
+
+TBool CSwiSisInstallerAO::DisplayOcspResultL(const Swi::CAppInfo& /*aAppInfo*/, Swi::TRevocationDialogMessage /*aMessage*/, RPointerArray<TOCSPOutcome>& /*aOutcomes*/, RPointerArray<Swi::CCertificateInfo>& /*aCertificates*/, TBool /*aWarningOnly*/)
+ {
+ TBool response = ETrue; // default behaviour is to continue the install
+ if (iVerbose)
+ {
+ // todo verbose mode
+ Stdout().Write(_L("TODO - CCmdSwi::DisplayOcspResultL\r\n"));
+ }
+ return response;
+ }
+
+void CSwiSisInstallerAO::DisplayCannotOverwriteFileL(const Swi::CAppInfo& /*aAppInfo*/, const Swi::CAppInfo& /*aInstalledAppInfo*/, const TDesC& aFileName)
+ {
+ if (iVerbose)
+ {
+ Stdout().Write(_L("\r\nCannot overwrite a file required for installation. Aborting -"));
+ Stdout().Write(aFileName);
+ Stdout().Write(_L(" - \r\n"));
+ }
+ }
+
+TBool CSwiSisInstallerAO::DisplayMissingDependencyL(const Swi::CAppInfo& /*aAppInfo*/, const TDesC& aDependencyName, TVersion /*aWantedVersionFrom*/, TVersion /*aWantedVersionTo*/, TVersion /*aInstalledVersion*/)
+ {
+ TBool response = ETrue; // default behaviour is to continue the install
+ if (!iQuiet)
+ {
+ Stdout().Write(_L("Warning: Depedency is missing or has incorrect version - "));
+ Stdout().Write(aDependencyName);
+ Stdout().Write(_L(" - \r\n"));
+ }
+ return response;
+ }
+
+TBool CSwiSisInstallerAO::DisplayUninstallL(const Swi::CAppInfo& aAppInfo)
+ {
+ if (iVerbose)
+ {
+ TName myBuf;
+ myBuf.Format(_L("NAME:\t\t%S\r\n"), &aAppInfo.AppName());
+ Stdout().Write(myBuf);
+ myBuf.Format(_L("VENDOR:\t\t%S\r\n"), &aAppInfo.AppVendor());
+ Stdout().Write(myBuf);
+ myBuf.Format(_L("VERSION:\t%d.%d.%d\r\n"), aAppInfo.AppVersion().iMajor, aAppInfo.AppVersion().iMinor, aAppInfo.AppVersion().iBuild);
+ Stdout().Write(myBuf);
+ }
+ TBool response = ETrue; // default behaviour is to continue the uninstall
+ return response;
+ }
+
+#ifndef SYMBIAN_JAVA_NOT_INCLUDED
+//
+// java ui installer
+//
+CSwiMidletInstallerAO* CSwiMidletInstallerAO::NewL(MCmdSwiParent& aParent, RFs& aFs, TBool aVerbose, TBool aQuiet)
+ {
+ CSwiMidletInstallerAO* self = new (ELeave) CSwiMidletInstallerAO(aParent, aFs, aVerbose, aQuiet);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CSwiMidletInstallerAO::CSwiMidletInstallerAO(MCmdSwiParent& aParent, RFs& aFs, TBool aVerbose, TBool aQuiet)
+ : CActive(CActive::EPriorityStandard), iParent(aParent), iFs(aFs), iVerbose(aVerbose), iQuiet(aQuiet)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CSwiMidletInstallerAO::~CSwiMidletInstallerAO()
+ {
+ Cancel();
+ if (iInstaller)
+ delete iInstaller;
+ if (iJadHandle)
+ iJadHandle->CloseFileHandle();
+ if (iJarHandle)
+ iJarHandle->CloseFileHandle();
+ if (iInfo)
+ delete iInfo;
+ if (iRemover)
+ delete iRemover;
+ }
+
+void CSwiMidletInstallerAO::ConstructL()
+ {
+ iInstaller = CJavaInstaller::NewL(*this, *this, KNullDesC8, EFalse, 0);
+ }
+
+TBool CSwiMidletInstallerAO::IsJad(TDes& aMidlet)
+ {
+ if (aMidlet.MatchF(KSwiJadExtension) > 0)
+ return ETrue;
+ return EFalse;
+ }
+
+TBool CSwiMidletInstallerAO::IsJar(TDes& aMidlet)
+ {
+ if (aMidlet.MatchF(KSwiJarExtension) > 0)
+ return ETrue;
+ return EFalse;
+ }
+
+void CSwiMidletInstallerAO::ListInstalledAppsL(TUid aAppUid, const TDesC& aMatchString)
+ {
+ MJavaRegistry* reg = MJavaRegistry::CreateL();
+ RArray<TUid> list;
+ TInt count = 0;
+ CleanupStack::PushL(reg);
+ if ((aAppUid.iUid != 0) && (reg->SuiteEntryExistsL(aAppUid)))
+ {
+ MJavaRegistrySuiteEntry* suite = reg->SuiteEntryL(aAppUid);
+ CleanupStack::PushL(suite);
+ suite->MIDletUidsL(list);
+ while (count < list.Count())
+ {
+ MJavaRegistryMIDletEntry* entry = reg->MIDletEntryL(list[count++]);
+ CleanupStack::PushL(entry);
+ DisplayPackageL(*entry);
+ CleanupStack::Pop(entry);
+ entry->Release();
+ }
+ CleanupStack::Pop(suite);
+ suite->Release();
+ }
+ else
+ {
+ reg->InstalledMIDletUidsL(list);
+ while (count < list.Count())
+ {
+ MJavaRegistryMIDletEntry* entry = reg->MIDletEntryL(list[count++]);
+ CleanupStack::PushL(entry);
+ if ((entry->MIDletNameL().MatchF(aMatchString)>=0) || (entry->SuiteEntryL().VendorL().MatchF(aMatchString)>=0))
+ {
+ DisplayPackageL(*entry);
+ }
+ CleanupStack::Pop(entry);
+ entry->Release();
+ }
+ }
+ CleanupStack::Pop(reg);
+ }
+
+//
+// CSwiMidleInstallerAO::DisplayPackageL
+// find information on the specified package uid and display it on the console
+//
+void CSwiMidletInstallerAO::DisplayPackageL(MJavaRegistryMIDletEntry& aPackage)
+ {
+ TName myBuf;
+ myBuf.Format(_L("\r\nNAME:\t%S\r\n"), &aPackage.MIDletNameL());
+ Stdout().Write(myBuf);
+ myBuf.Format(_L("VENDOR:\t%S\r\n"), &aPackage.SuiteEntryL().VendorL());
+ Stdout().Write(myBuf);
+ myBuf.Format(_L("UID:\t0x%x\r\n"), aPackage.SuiteEntryL().UidL());
+ Stdout().Write(myBuf);
+ }
+
+//
+// CSwiMidletInstallerAO::InstallL
+// installs a jar/jad midp 1.0/2.0-compatible midlet
+//
+void CSwiMidletInstallerAO::InstallL(TFileName& aInstallFile)
+ {
+ ASSERT(iInstaller);
+ ASSERT(!iInfo);
+ ASSERT(!iJarHandle);
+ ASSERT(!iJadHandle);
+ if (aInstallFile.Length() <= 0)
+ {
+ User::Leave(KErrNotFound);
+ }
+ if (iVerbose)
+ {
+ Stdout().Write(_L("Installing Midlet...\r\n"));
+ }
+ const TInt length = aInstallFile.Length() - 3; // the java midlet filename minus the jad/jar extension name
+ TFileName sisterFile(aInstallFile.Left(length));
+ if (IsJad(aInstallFile))
+ {
+ iJadHandle = CJavaFileHandle::NewL(iFs, aInstallFile, KNullDesC, KDefaultJadMimeType());
+ // name the associated jar file
+ sisterFile.Append(_L("jar"));
+ iJarHandle = CJavaFileHandle::NewL(iFs, sisterFile, KNullDesC, KDefaultJarMimeType());
+ }
+ else
+ {
+ ASSERT(IsJar(aInstallFile));
+ iJarHandle = CJavaFileHandle::NewL(iFs, aInstallFile, KNullDesC, KDefaultJarMimeType());
+ // name the associated jad file
+ sisterFile.Append(_L("jad"));
+ iJadHandle = CJavaFileHandle::NewL(iFs, sisterFile, KNullDesC, KDefaultJadMimeType());
+ }
+ iInfo = CMIDPInstallationLaunchInfo::NewL(iFs, *iJadHandle, *iJarHandle);
+ iInstaller->Install(*iInfo, iStatus);
+ SetActive();
+ }
+
+//
+// CSwiMidletInstallerAO::Uninstall
+// uninstalls a jar/jad midp 1.0/2.0-compatible midlet
+//
+void CSwiMidletInstallerAO::UninstallL(const TUid& aPackageUid)
+ {
+ ASSERT(!iRemover);
+ if (iVerbose)
+ {
+ Stdout().Write(_L("Removing Midlet...\r\n"));
+ }
+ iRemover = CJavaRemover::NewL(aPackageUid, *this);
+ iRemover->Remove(iStatus);
+ SetActive();
+ }
+
+void CSwiMidletInstallerAO::RunL()
+ {
+ iParent.Finished(iStatus.Int());
+ }
+
+void CSwiMidletInstallerAO::DoCancel()
+ {
+ ASSERT(iInstaller);
+ ASSERT(iRemover);
+ iInstaller->Cancel();
+ iRemover->Cancel();
+ iParent.Finished(KErrCancel);
+ }
+
+//
+// java installer UI hooks
+//
+TBool CSwiMidletInstallerAO::StartInstallL(const CMIDletSuiteAttributes& aMIDlet)
+ {
+ if (iVerbose)
+ {
+ TName myBuf;
+ myBuf.Format(_L("\r\nNAME:\t\t%S\r\n"), &aMIDlet.MIDletName());
+ Stdout().Write(myBuf);
+ myBuf.Format(_L("VENDOR:\t\t%S\r\n"), &aMIDlet.MIDletVendor());
+ Stdout().Write(myBuf);
+ myBuf.Format(_L("VERSION:\t%d.%d.%d\r\n"), aMIDlet.MIDletVersion().iMajor, aMIDlet.MIDletVersion().iMinor, aMIDlet.MIDletVersion().iBuild);
+ Stdout().Write(myBuf);
+ }
+ TBool response = ETrue; // default behaviour is to continue the install
+ return response;
+ }
+
+TBool CSwiMidletInstallerAO::SelectDriveL(const CMIDletSuiteAttributes& /*aMIDlet*/, TInt aSpaceRequired, TChar& aDrive, TBool& aSufficientSpace)
+ {
+ aSufficientSpace = ETrue;
+ aDrive = 'c';
+ if (iQuiet)
+ {
+ // Default to CWD drive if writeable
+ TFileName sessionPath;
+ TInt err = iFs.SessionPath(sessionPath);
+ if (err == KErrNone)
+ {
+ TChar drive = sessionPath[0];
+ drive.LowerCase();
+ TVolumeInfo volInfo;
+ if (iFs.Volume(volInfo, ((TUint)drive)-'a') == KErrNone && volInfo.iFree >= aSpaceRequired && !(volInfo.iDrive.iDriveAtt & KDriveAttRom) && !(volInfo.iDrive.iMediaAtt & KMediaAttWriteProtected))
+ {
+ aDrive = drive;
+ }
+ }
+ }
+ else
+ {
+ // ask the question
+ TBuf<128> info;
+ info.Format(_L("Midlet requires %d bytes free space. Please select installation drive:\r\n"), aSpaceRequired);
+ Stdout().Write(info);
+
+ // cycle through drive list checking for existing drive
+ TDriveList drives;
+ TVolumeInfo volume;
+ TChar driveChar;
+ TBool displayed = EFalse;
+ User::LeaveIfError(iFs.DriveList(drives));
+ for (TInt ii = 0 ; ii < KMaxDrives ; ii++)
+ {
+ if (drives[ii])
+ {
+ // drive exists
+ if (KErrNone == iFs.Volume(volume, ii))
+ {
+ // drive is present
+ if (volume.iFree >= aSpaceRequired)
+ {
+ // drive has sufficient space
+ aSufficientSpace = ETrue;
+ if (!(volume.iDrive.iDriveAtt & KDriveAttRom) &&
+ !(volume.iDrive.iMediaAtt & KMediaAttWriteProtected))
+ {
+ // drive is not a rom drive and is not write protected
+ User::LeaveIfError(iFs.DriveToChar(ii, driveChar));
+ info.Format(_L("%d. \'"), ii); // drive number
+ info.Append(driveChar); // drive letter
+ info.Append(_L("\' "));
+ info.AppendNum(volume.iFree); // free space
+ info.Append(_L(" bytes free\r\n"));
+ Stdout().Write(info);
+ displayed = ETrue;
+ }
+ }
+ }
+ }
+ }
+ // get the answer
+ if (displayed)
+ {
+ TUserInput in;
+ User::LeaveIfError(Stdin().Read(in));
+ TLex lex(in);
+ TInt response;
+ User::LeaveIfError(lex.Val(response));
+ User::LeaveIfError(iFs.DriveToChar(response, aDrive));
+ }
+ else
+ {
+ Stdout().Write(_L("Error. No drives capable of supporting midlet install. Aborting\r\n"));
+ return EFalse;
+ }
+ }
+ return ETrue;
+ }
+
+TBool CSwiMidletInstallerAO::ReplaceExistingMIDletL(const CMIDletSuiteAttributes& /*aMIDlet*/, const TAppVersion& /*aOldVersion*/)
+ {
+ TBool response = ETrue; // default behaviour is to continue the install
+ if (!iQuiet)
+ {
+ Stdout().Write(_L("Do you wish to replace the existing midlet [y/n]?\r\n"));
+ response = iParent.GetAnswer();
+ }
+ return response;
+ }
+
+TBool CSwiMidletInstallerAO::UpgradeRMSL(const CMIDletSuiteAttributes& /*aMIDlet*/, const TAppVersion& /*aOldVersion*/)
+ {
+ TBool response = ETrue; // default behaviour is to continue the install
+ if (!iQuiet)
+ {
+ Stdout().Write(_L("Do you wish to upgrade the existing midlet [y/n]?\r\n"));
+ response = iParent.GetAnswer();
+ }
+ return response;
+ }
+
+TBool CSwiMidletInstallerAO::MIDletUntrustedL(const CMIDletSuiteAttributes& /*aMIDlet*/)
+ {
+ TBool response = ETrue; // default behaviour is to continue the install
+ if (!iQuiet)
+ {
+ Stdout().Write(_L("\r\nMidlet is untrusted. Continue installing [y/n]?\r\n"));
+ response = iParent.GetAnswer();
+ }
+ return response;
+ }
+
+void CSwiMidletInstallerAO::CertificateHasNoRootL(const CMIDletSuiteAttributes& /*aMIDlet*/, const CPKIXCertChain& /*aCertChain*/, const CPKIXValidationResult& /*aValidationResult*/)
+ {
+ Stderr().Write(_L("\r\nCertificate attached to midlet has no identifiable root. Aborting installation.\r\n"));
+ }
+
+void CSwiMidletInstallerAO::BadSignatureL(const CMIDletSuiteAttributes& /*aMIDlet*/, const CPKIXCertChain& /*aCertChain*/, const CPKIXValidationResult& /*aValidationResult*/)
+ {
+ if (iVerbose)
+ {
+ Stdout().Write(_L("\r\nWarning: Midlet certificate chain is incomplete. Continuing installation\r\n"));
+ }
+ }
+
+TBool CSwiMidletInstallerAO::PerformRevocationCheckL(TBool& aDoCheck)
+ {
+ aDoCheck = EFalse;
+ return ETrue;
+ }
+
+void CSwiMidletInstallerAO::StartRevocationCheckL()
+ {
+ if (iVerbose)
+ {
+ Stdout().Write(_L("\r\nStarted: Revocation check\r\n"));
+ }
+ }
+
+void CSwiMidletInstallerAO::FinishedRevocationCheckL()
+ {
+ if (iVerbose)
+ {
+ Stdout().Write(_L("\r\nFinished: Revocation check\r\n"));
+ }
+ }
+
+void CSwiMidletInstallerAO::StartIconConversionL()
+ {
+ }
+
+void CSwiMidletInstallerAO::FinishedIconConversionL()
+ {
+ }
+
+TBool CSwiMidletInstallerAO::OCSPWarningL(const CMIDletSuiteAttributes& /*aMIDlet*/, TRevocationMsg /*aRevocationMsg*/, const TOCSPOutcome* /*aOCSPOutcome*/)
+ {
+ if (iVerbose)
+ {
+ Stdout().Write(_L("\r\nWarning: OCSP failure. Continuing installation.\r\n"));
+ }
+ return ETrue;
+ }
+
+void CSwiMidletInstallerAO::OCSPErrorL(const CMIDletSuiteAttributes& /*aMIDlet*/, TRevocationMsg /*aRevocationMsg*/, const TOCSPOutcome* /*aOCSPOutcome*/)
+ {
+ Stderr().Write(_L("\r\nOCSP Error. Aborting installation.\r\n"));
+ }
+
+TBool CSwiMidletInstallerAO::MIDletInUseL(const CMIDletSuiteAttributes& /*aMIDlet*/)
+ {
+ TBool response = EFalse; // EFalse indicates we don't continue with uninstallation
+ if (!iQuiet)
+ {
+ // print the question
+ Stdout().Write(_L("\r\nMidlet is currently open. Continue installing? [y/n]\r\n"));
+
+ // get the answer
+ TUserInput in;
+ const TInt error = Stdin().Read(in);
+ if ((error == KErrNone) && (in.MatchF(KSwiYes) == 0))
+ {
+ response = ETrue;
+ }
+ }
+ if (!response)
+ {
+ Stderr().Write(_L("Uninstall aborted. Midlet has not been closed.\r\n"));
+ }
+ return response;
+ }
+
+void CSwiMidletInstallerAO::OTAReportResponseL(TInt aOTAResponseCode, const TDesC& /*aReportBody*/)
+ {
+ if (iVerbose)
+ {
+ switch (aOTAResponseCode)
+ {
+ case CJavaMIDletInstallationResult::EOkay:
+ Stdout().Write(_L("\r\nComplete\r\n"));
+ break;
+
+ default:
+ Stdout().Write(_L("Abort\r\n"));
+ break;
+ };
+ }
+ }
+
+TInt CSwiMidletInstallerAO::CopyStarted(TInt /*aSize*/)
+ {
+ return KErrNone;
+ }
+
+TInt CSwiMidletInstallerAO::DownloadStarted(TInt /*aSize*/)
+ {
+ if (iVerbose)
+ {
+ Stdout().Write(_L("Downloading midlet\r\n"));
+ }
+ return KErrNone;
+ }
+
+TInt CSwiMidletInstallerAO::UpdateProgress(TInt /*aSize*/)
+ {
+ if (iVerbose)
+ {
+ Stdout().Write(_L("."));
+ }
+ return KErrNone;
+ }
+
+TBool CSwiMidletInstallerAO::GetUsernamePasswordL(HBufC8*& /*aUsername*/, HBufC8*& /*aPassword*/)
+ {
+ if (iVerbose)
+ {
+ Stdout().Write(_L("\r\nTODO: CCmdSwi::GetUsernamePasswordL\r\n"));
+ }
+ return EFalse;
+ }
+
+TBool CSwiMidletInstallerAO::ConfirmRemovalL(const TDesC& /*aRemovalMessage*/)
+ {
+ TBool response = ETrue; // default behaviour is to continue the uninstall
+ return response;
+ }
+
+void CSwiMidletInstallerAO::InitialiseProgressBarL(TInt /*aMaximumLength*/)
+ {
+ }
+
+void CSwiMidletInstallerAO::UpdateProgressBarL(TInt /*aUnits*/)
+ {
+ if (iVerbose)
+ {
+ Stdout().Write(_L("."));
+ }
+ }
+
+TBool CSwiMidletInstallerAO::MIDletInUseL()
+ {
+ TBool response = EFalse; // EFalse indicates we don't continue with uninstallation
+ if (!iQuiet)
+ {
+ // print the question
+ Stdout().Write(_L("\r\nApplication is currently open. Continue uninstalling? [y/n]\r\n"));
+
+ // get the answer
+ TUserInput in;
+ const TInt error = Stdin().Read(in);
+ if ((error == KErrNone) && (in.MatchF(KSwiYes) == 0))
+ {
+ response = ETrue;
+ }
+ }
+ return response;
+ }
+
+TBool CSwiMidletInstallerAO::FileInUseL(const TDesC& /*aFileName*/)
+ {
+ TBool response = EFalse; // EFalse indicates we don't continue with uninstallation
+ if (!iQuiet)
+ {
+ // print the question
+ Stdout().Write(_L("\r\nApplication has a file handle open. Continue uninstalling? [y/n]\r\n"));
+
+ // get the answer
+ TUserInput in;
+ const TInt error = Stdin().Read(in);
+ if ((error == KErrNone) && (in.MatchF(KSwiYes) == 0))
+ {
+ response = ETrue;
+ }
+ }
+ return response;
+ }
+
+#endif // SYMBIAN_JAVA_NOT_INCLUDED
+
+#ifdef EXE_BUILD
+EXE_BOILER_PLATE(CCmdSwi)
+#endif
+