--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javacommons/utils/src.s60/javaoslayer.cpp Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,688 @@
+/*
+* Copyright (c) 2007-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <dirent.h>
+#include <memory>
+#include <string.h> // Needed for strcmp
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <sstream>
+#include <e32err.h>
+#include <f32file.h>
+#include <hal.h>
+#include <flogger.h>
+#include "logger.h"
+#include "javaoslayer.h"
+#include "javasymbianoslayer.h"
+#include "libraryloaderexception.h"
+#include "dynamiclibloader.h"
+#include "javacommonutils.h"
+#include "s60commonutils.h"
+
+using namespace java::util;
+
+const char * const BOOT_CLASSPATH_MIDP_FILE = "midpodclist";
+const char * const BOOT_CLASSPATH_INSTALLER_FILE = "installerodclist";
+const char * const BOOT_CLASSPATH_TCKRUNNER_FILE = "tckrunnerodclist";
+
+_LIT(KStartUpTraceDir, "java\\full");
+_LIT(KStartUpTraceFile, "startup.txt");
+_LIT(KTraceSpaceExtra, " ");
+
+OS_EXPORT void JavaOsLayer::startUpTrace(const std::string& header,
+ int freeMem, int totalMem)
+{
+ if (header.length() == 0)
+ {
+ _LIT(KDash, "-");
+ RFileLogger::Write(KStartUpTraceDir, KStartUpTraceFile,
+ EFileLoggingModeAppend, KDash);
+ }
+ else
+ {
+ TTime time;
+ time.HomeTime();
+ const int maxStrLen = 41;
+ TBuf<maxStrLen> str;
+ _LIT(KFormatStr, "%-B%:0%J%:1%T%:2%S%.%*C2%:3%+B");
+ TRAP_IGNORE(time.FormatL(str, KFormatStr));
+ int mem = 0;
+ int err = HAL::Get(HALData::EMemoryRAMFree, mem);
+ if (err != KErrNone)
+ {
+ mem = err;
+ }
+ HBufC* buf = stringToDes(header.c_str());
+ const int maxLen = 41;
+ int headerLen = Min(buf->Length(), maxLen);
+ TPtrC headerPtr = buf->Left(headerLen);
+ TPtrC spacePtr = KTraceSpaceExtra().Right(maxLen - headerLen);
+
+ int heapUsageTotal;
+ User::AllocSize(heapUsageTotal);
+
+ _LIT(KOutStr, "%S%S Time(%S), SysMem(%d), pUsedHeap(%d), free(%d), total(%d)");
+ RFileLogger::WriteFormat(KStartUpTraceDir, KStartUpTraceFile,
+ EFileLoggingModeAppend,
+ KOutStr,
+ &headerPtr, &spacePtr, &str, mem, heapUsageTotal, freeMem, totalMem);
+ delete buf;
+ }
+}
+
+
+OS_EXPORT void JavaOsLayer::getOsSpecificLibName(std::string& result,
+ const char* libName)
+{
+// JELOG2(EUtils);
+ if (libName)
+ {
+ result = libName;
+ }
+ else
+ {
+ ELOG(EUtils, "JavaOsLayer::getOsSpecificLibName() libname was null");
+ }
+}
+
+OS_EXPORT void JavaOsLayer::getOsSpecificJavaRootPath(std::string& path)
+{
+// JELOG2(EUtils);
+ path = "c:\\java";
+}
+
+OS_EXPORT std::string& JavaOsLayer::getBinRoot(std::string& path, bool append)
+{
+// JELOG2(EUtils);
+ const char* start = ":\\sys\\bin\\";
+ if (append)
+ {
+ path += start;
+ }
+ else
+ {
+ path = start+1;
+ }
+ return path;
+}
+
+OS_EXPORT std::string& JavaOsLayer::getResRoot(std::string& path, bool append)
+{
+// JELOG2(EUtils);
+ const char* start = ":\\resource\\java\\";
+ if (append)
+ {
+ path += start;
+ }
+ else
+ {
+ path = start+1;
+ }
+ return path;
+}
+
+OS_EXPORT std::string& JavaOsLayer::getMidpRoot(std::string& path, bool append)
+{
+// JELOG2(EUtils);
+ const char* start = ":\\private\\102033E6\\";
+// const char* start = ":\\private\\200211D9\\";
+ if (append)
+ {
+ path += start;
+ }
+ else
+ {
+ path = start+1;
+ }
+ /*
+ TUint32 uid = RProcess().SecureId().iId;
+ std::ostringstream oss;
+ oss<<std::hex<<uid;
+ path += oss.str();
+ path += "]\\";
+ */
+ return path;
+}
+
+OS_EXPORT std::string& JavaOsLayer::getJavaCaptainRoot(std::string& path, bool append)
+{
+// JELOG2(EUtils);
+ const char* start = ":\\private\\200211DC\\";
+ if (append)
+ {
+ path += start;
+ }
+ else
+ {
+ path = start+1;
+ }
+ return path;
+}
+
+OS_EXPORT DriveId JavaOsLayer::getMidpDrive()
+{
+// JELOG2(EUtils);
+ int driveNum = 1;
+ TUint16 driveLetter = RProcess().FileName()[0];
+ RFs::CharToDrive(driveLetter, driveNum);
+ char* drive = new char[2];
+ drive[0] = *((char*)&driveLetter);
+ drive[1] = 0;
+ return DriveId(drive, driveNum);
+}
+
+
+OS_EXPORT void* JavaOsLayer::dlopen(const char* libName)
+{
+ JELOG2(EUtils);
+ RLibrary* libAccess = 0;
+ if (libName)
+ {
+ libAccess = new RLibrary();
+ if (libAccess)
+ {
+ HBufC* buf = stringToDes(libName);
+ if (buf)
+ {
+ int status = libAccess->Load(*buf);
+ LOG2(EUtils, EInfo, "JavaOsLayer::dlopen(%s), Handle: %X",
+ libName, libAccess);
+ delete buf;
+ if (status != KErrNone)
+ {
+ delete libAccess;
+ libAccess = 0;
+ throw LibraryLoaderException(OPENING_LIBRARY_FAILED, status,
+ "Error opening Symbian lib.",
+ __FILE__, __FUNCTION__, __LINE__);
+
+ }
+ else
+ {
+ //The code below makes RLibrary accessible from any thread.
+ // copies the handle without doing Open()
+ RLibrary duplicate=*libAccess;
+ // overwrite the original
+ status = libAccess->Duplicate(RThread());
+ duplicate.Close(); // close the original
+ }
+ }
+ }
+ }
+ else
+ {
+ ELOG(EUtils, "JavaOsLayer::dlopen() libname was null");
+ }
+ return libAccess;
+}
+
+OS_EXPORT void* JavaOsLayer::dlsym(void* handle, const char* name,
+ bool containsByteCode)
+{
+ JELOG2(EUtils);
+ void* func = 0;
+ if (handle && name)
+ {
+ RLibrary* libAccess = reinterpret_cast<RLibrary*>(handle);
+ LookupFunc lookup = (LookupFunc)libAccess->Lookup(containsByteCode?2:1);
+ if (lookup)
+ {
+ func = (void*) lookup(name);
+ LOG2(EUtils, EInfo, "JavaOsLayer::dlsym() fuction name: %s, "
+ "fPtr: %X", name, func);
+ if (func == 0)
+ {
+ ELOG1(EUtils, "dlsym failed for %s.", name);
+ }
+ }
+ else
+ {
+ ELOG1(EUtils,
+ "No lookup method in ordinal 1 when looking for %s.", name);
+ }
+ }
+ else
+ {
+ ELOG2(EUtils, "JavaOsLayer::dlsym() null argument handle: %X, name %X",
+ handle, name);
+ }
+ return func;
+}
+
+OS_EXPORT int JavaOsLayer::dlclose(void* handle)
+{
+ JELOG2(EUtils);
+ if (handle)
+ {
+ RLibrary* libAccess = reinterpret_cast<RLibrary*>(handle);
+ libAccess->Close();
+ delete libAccess;
+ }
+ else
+ {
+ ELOG(EUtils, "dlclose failed, null handle");
+ }
+ return 0;
+}
+OS_EXPORT void JavaOsLayer::bootClassPath(std::list<std::wstring>& odcFiles,
+ std::list<std::wstring>& bcpEntites,
+ const int pathType)
+{
+ /*
+ * getResRoot requires drive letter but VerifiedFileNameL adds correct one.
+ * C drive used that it is checked first and if file is found that is used
+ * after that z is checked.
+ */
+ std::string path = "c";
+ JavaOsLayer::getResRoot(path, true);
+
+ if (BOOT_CLASSPATH_MIDP == pathType)
+ {
+ path.append(BOOT_CLASSPATH_MIDP_FILE);
+ }
+ else if (BOOT_CLASSPATH_INSTALLER == pathType)
+ {
+ path.append(BOOT_CLASSPATH_INSTALLER_FILE);
+ }
+ else if (BOOT_CLASSPATH_TCKRUNNER == pathType)
+ {
+ path.append(BOOT_CLASSPATH_TCKRUNNER_FILE);
+ }
+ else
+ {
+ path.append(BOOT_CLASSPATH_MIDP_FILE);
+ }
+
+ std::auto_ptr<HBufC>pathDes(stringToDes(path.c_str()));
+ TFileName realPathName;
+ TRAPD(err, realPathName = S60CommonUtils::VerifiedFileNameL(*pathDes));
+
+ if (KErrNone == err)
+ {
+ std::wstring temp((wchar_t*)realPathName.PtrZ());
+ std::string odcFileName(temp.begin(), temp.end());
+
+ std::vector<std::string> romClasspathEntries;
+ std::string dir_path("Z:\\resource\\java\\jvm\\lib\\jrt");
+
+ listDirectory(dir_path, romClasspathEntries); // This is always needed.
+
+ if (odcFileName[0] == 'c' || odcFileName[0] == 'C') // IAD deployed
+ {
+ std::vector<std::string> updatedClasspathEntries;
+ listOdcFile(path, updatedClasspathEntries); // Read all ODC files from odc file
+
+ std::string::size_type const delimiter = path.rfind("\\");
+ path = path.substr(0, delimiter); // IAD ODC file directory
+
+ populateCPEntries((path + "\\jvm\\lib\\jrt\\"), updatedClasspathEntries, odcFiles, bcpEntites);
+
+ std::vector<std::string> romDeltaEntries;
+
+ // Add all ROM entries that are not deployed using IAD.
+ deltaCPEntries(romClasspathEntries, updatedClasspathEntries, romDeltaEntries);
+
+ // Add ROM only entries
+ populateCPEntries((dir_path + "\\"), romDeltaEntries, odcFiles, bcpEntites);
+ }
+ else // Classpath only at ROM so using dir listing.
+ {
+ populateCPEntries((dir_path + "\\"), romClasspathEntries, odcFiles, bcpEntites);
+ }
+ }
+ else
+ {
+ ELOG1(EUtils, "Cannot get real path name for: '%s'", path.c_str());
+ }
+}
+
+void JavaOsLayer::listDirectory(std::string& aDirPath, std::vector<std::string>& aEntries)
+{
+ DIR *pDIR = opendir(aDirPath.c_str()); // open directory
+
+ if (pDIR == NULL)
+ {
+ std::string errorMsg("Cannot read ROM ODC files: ");
+ errorMsg.append(strerror(errno));
+ errorMsg.append(" : dir: ");
+ errorMsg.append(aDirPath.c_str());
+ ELOG(EUtils, errorMsg.c_str());
+ // Suppres error if no Java at all on device ROM.
+ }
+
+ struct dirent* pDirEnt = readdir(pDIR);
+ while (pDirEnt != NULL)
+ {
+ aEntries.push_back(std::string(pDirEnt->d_name));
+ pDirEnt = readdir(pDIR);
+ }
+
+ closedir(pDIR); // Release the open directory
+}
+
+void JavaOsLayer::listOdcFile(std::string& filePath, std::vector<std::string>& entries)
+{
+ std::ifstream odcFile;
+ odcFile.open(filePath.c_str(), std::ifstream::in);
+
+ if (odcFile)
+ {
+ std::string line;
+ while (std::getline(odcFile, line))
+ {
+ // Trim enter if exists.
+ std::string::size_type const enter = line.find_last_not_of("\n");
+ entries.push_back(line.substr(0, enter));
+ }
+ odcFile.close();
+ }
+ else
+ {
+ ELOG1(EUtils, "Cannot read file: '%s'", filePath.c_str());
+ }
+}
+
+void JavaOsLayer::populateCPEntries(const std::string& pathPrefix,
+ const std::vector<std::string>& entries,
+ std::list<std::wstring>& odcFiles,
+ std::list<std::wstring>& bcpEntites)
+{
+ std::vector<std::string>::const_iterator iter;
+
+ for (iter = entries.begin(); iter != entries.end(); ++iter)
+ {
+ std::string entryName((*iter));
+ entryName.insert(0, pathPrefix); // Full path needed.
+
+ std::wstring wideEntryName = L"";
+
+ try
+ {
+ wideEntryName = JavaCommonUtils::utf8ToWstring(entryName.c_str());
+ }
+ catch (ExceptionBase& eb)
+ {
+ // Suppress error to skip invalid ones.
+ ELOG2(EUtils, "utf8->wstring failed on cp entry: '%s' exp: %s ",
+ entryName.c_str(), eb.toString().c_str());
+ }
+ size_t pos = wideEntryName.rfind(L".odc");
+ bool isOdcFile = (pos != std::string::npos) &&
+ (pos == (wideEntryName.length() - 4));
+ if (isOdcFile)
+ {
+ odcFiles.push_back(wideEntryName);
+ }
+ else
+ {
+ bcpEntites.push_back(wideEntryName);
+ }
+ }
+}
+
+void JavaOsLayer::deltaCPEntries(const std::vector<std::string>& romEntries,
+ const std::vector<std::string>& iadEntries,
+ std::vector<std::string>& deltaEntries)
+{
+ std::vector<std::string>::const_iterator iter; // ROM CP iter
+ std::vector<std::string>::const_iterator matchIter; // IAD CP iter
+ std::vector<std::string> romDeltaEntries;
+
+ // Iterate through all rom entries
+ for (iter = romEntries.begin(); iter != romEntries.end(); ++iter)
+ {
+ bool match = false;
+ // and check if they do not match to IAD ones add to romDeltaEntries.
+ for (matchIter = iadEntries.begin(); matchIter != iadEntries.end(); ++matchIter)
+ {
+ if ((*matchIter) == (*iter))
+ {
+ match = true;
+ break;
+ }
+ }
+
+ if (!match)
+ {
+ deltaEntries.push_back((*iter));
+ }
+ }
+}
+
+OS_EXPORT FuncPtr findMethod(const char* funcName,
+ const FuncTable funcTable[],
+ int tableSize)
+{
+// JELOG2(EUtils);
+ int res = 0;
+ int mid = 0;
+ int top = 0;
+ int bottom = tableSize-1;
+
+ if (funcName == 0)
+ {
+ ELOG(EUtils, "findMethod failed, null funcName");
+ return 0;
+ }
+ if (funcTable == 0)
+ {
+ ELOG(EUtils, "findMethod failed, null funcTable");
+ return 0;
+ }
+
+ // Loop while the number of the items left in the list is greater
+ // than 2. Each iteration will split the number of items left to search
+ // in half
+ while ((bottom - top) > 1)
+ {
+ // This case handles the normal serach case where the number of
+ // items left to search is greater than 2
+ mid = (top + bottom) / 2;
+ res = strcmp(funcName, funcTable[mid].mFuncName);
+ if (res == 0)
+ {
+ return((FuncPtr) funcTable[mid].mFuncAddr);
+ }
+ if (res > 0)
+ {
+ top = mid;
+ }
+ else
+ {
+ bottom = mid;
+ }
+ }
+
+ // If there are two items left in the list then the bottom item should be
+ // checked for a match
+ if (bottom != top)
+ {
+ // Check the bottom item to see if it is a match
+ res=strcmp(funcName, funcTable[bottom].mFuncName);
+ if (res == 0)
+ {
+ return ((FuncPtr) funcTable[bottom].mFuncAddr);
+ }
+ }
+
+ // Check the top item to see if it is a match
+ res=strcmp(funcName, funcTable[top].mFuncName);
+
+ if (res == 0)
+ {
+ return ((FuncPtr) funcTable[top].mFuncAddr);
+ }
+
+ // Neither the top or bottom items were a match so the
+ // method must not exist in the file
+ return 0;
+}
+
+OS_EXPORT HBufC* stringToDes(const char* str)
+{
+// JELOG2(EUtils);
+ HBufC* resultBuf = 0;
+ try
+ {
+ if (str)
+ {
+ int len = strlen(str);
+ resultBuf = HBufC::New(len + 1);
+ TPtr ptr = resultBuf->Des();
+ TPtr8 ptr8((TUint8 *)str, len);
+ ptr8.SetLength(len);
+ ptr.Copy(ptr8);
+ ptr.ZeroTerminate();
+ }
+ }
+ catch (...)
+ {
+ ELOG(EUtils, "stringToDes, exception");
+ }
+ return resultBuf;
+}
+
+OS_EXPORT wchar_t* desToWstring(TPtr16& aDes)
+{
+ return (wchar_t*) aDes.PtrZ();
+}
+
+OS_EXPORT TAppVersion wstringToAppVersion(const std::wstring& aVersionString)
+{
+ TAppVersion appVersion;
+ char* temp = JavaCommonUtils::wstringToUtf8(aVersionString);
+ std::string versionStr = temp;
+
+ std::string::size_type idx = 0;
+ idx = versionStr.find(".", idx);
+
+ // 00.00.00 --> 00 00.00
+ if (idx != std::string::npos)
+ {
+ versionStr.replace(idx, 1, " ");
+ }
+
+ idx = versionStr.find(".", idx + 1);
+
+ // 00 00.00 --> 00 00 00
+ if (idx != std::string::npos)
+ {
+ versionStr.replace(idx, 1, " ");
+ }
+
+ int major = 0;
+ int minor = 0;
+ int build = 0;
+ int result = sscanf(
+ versionStr.c_str(), "%d %d %d", &major, &minor, &build);
+
+ if (major > 0)
+ {
+ appVersion.iMajor = major;
+ }
+
+ if (minor > 0)
+ {
+ appVersion.iMinor = minor;
+ }
+
+ if (build > 0)
+ {
+ appVersion.iBuild = build;
+ }
+ delete[] temp;
+
+ return appVersion;
+}
+
+OS_EXPORT HBufC* wstringToBuf(const std::wstring& aString)
+{
+ HBufC* stringBuf = HBufC::New(aString.size());
+ if (stringBuf != 0)
+ {
+ TPtr16 namePtr(stringBuf->Des());
+ namePtr.Append((const TUint16*)aString.c_str(), aString.size());
+ }
+ return stringBuf;
+}
+
+/**
+ *
+ */
+OS_EXPORT java::util::Uid& TUidToUid(const TUid& aId,java::util::Uid& aOutUid)
+{
+// JELOG2(EUtils);
+ if (0 == aId.iUid)
+ return aOutUid;
+
+ std::wstringstream stream;
+ stream.fill('0');
+ stream << std::setw(8) << std::hex << (int)aId.iUid; // codescanner::leave
+
+ std::wstring idAsStr;
+ idAsStr.reserve(11);
+ idAsStr.append(L"[");
+ idAsStr.append(stream.str());
+ idAsStr.append(L"]");
+ Uid tmpUid(idAsStr);
+ aOutUid = tmpUid;
+ return aOutUid;
+}
+
+/**
+ *
+ */
+OS_EXPORT TInt uidToTUid(const java::util::Uid& aUid,TUid& aOutId)
+{
+// JELOG2(EUtils);
+ long long tmpInt = 0;
+ std::wstring uidAsStr = aUid.toString();
+ if (0 == uidAsStr.size())
+ return KErrArgument;
+
+ JavaCommonUtils::trimWstring(uidAsStr,L'\n');
+ JavaCommonUtils::trimWstring(uidAsStr,L'\t');
+ JavaCommonUtils::trimWstring(uidAsStr,L' ');
+
+ if ((10 != uidAsStr.size()) && (8 != uidAsStr.size()))
+ return KErrArgument;
+
+ if (('[' == uidAsStr.at(0)) && (']' == uidAsStr.at(uidAsStr.size()-1)))
+ {
+ if (10 != uidAsStr.size())
+ return KErrArgument;
+ std::wstring plainNumStr = uidAsStr.substr(1,uidAsStr.size()-2);
+ std::wstringstream stream(plainNumStr);
+ stream >> std::hex >> tmpInt; // codescanner::leave
+ if ((false == stream.eof()) || (stream.fail()))
+ return KErrArgument;
+ }
+ else
+ {
+ std::wstringstream stream(uidAsStr);
+ stream >> std::hex >> tmpInt; // codescanner::leave
+ if ((false == stream.eof()) || (stream.fail()))
+ return KErrArgument;
+ }
+
+ if ((tmpInt > 0xEFFFFFFF) || (tmpInt < 0))
+ return KErrArgument;
+ aOutId.iUid = tmpInt;
+ return KErrNone;
+}
+