diff -r e8e63152f320 -r 2a9601315dfc javacommons/utils/src.s60/javaoslayer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javacommons/utils/src.s60/javaoslayer.cpp Mon May 03 12:27:20 2010 +0300 @@ -0,0 +1,686 @@ +/* +* 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 +#include +#include // Needed for strcmp +#include +#include +#include +#include +#include +#include +#include +#include +#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 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<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(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(handle); + libAccess->Close(); + delete libAccess; + } + else + { + ELOG(EUtils, "dlclose failed, null handle"); + } + return 0; +} +OS_EXPORT void JavaOsLayer::bootClassPath(std::list& odcFiles, + std::list& 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_ptrpathDes(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 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 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 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& aEntries) +{ + DIR *pDIR = opendir(aDirPath.c_str()); // open directory + + if (pDIR == NULL) + { + std::string errorMsg("Cannot read ROM ODC files: "); + errorMsg.append(strerror(errno)); + ELOG(EUtils, errorMsg.c_str()); + throw ExceptionBase(errorMsg, __FILE__, __FUNCTION__, __LINE__); + } + + 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& 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& entries, + std::list& odcFiles, + std::list& bcpEntites) +{ + std::vector::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& romEntries, + const std::vector& iadEntries, + std::vector& deltaEntries) +{ + std::vector::const_iterator iter; // ROM CP iter + std::vector::const_iterator matchIter; // IAD CP iter + std::vector 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; +} +