#include "EngineCommon.h" #include "OpenCVEngine.h" #include "HardwareDetector.h" #include "StringUtils.h" #include #include #include #include #include #include #include using namespace android; const int OpenCVEngine::Platform = DetectKnownPlatforms(); const int OpenCVEngine::CpuID = GetCpuID(); const int OpenCVEngine::KnownVersions[] = {2040000, 2040100, 2040200, 2040300, 2040301, 2040302, 2040400, 2040500}; bool OpenCVEngine::ValidateVersion(int version) { for (size_t i = 0; i < sizeof(KnownVersions)/sizeof(int); i++) if (KnownVersions[i] == version) return true; return false; } int OpenCVEngine::NormalizeVersionString(std::string version) { int result = 0; if (version.empty()) { return result; } std::vector parts = SplitStringVector(version, '.'); // Use only 4 digits of the version, i.e. 1.2.3.4. // Other digits will be ignored. if (parts.size() > 4) parts.erase(parts.begin()+4, parts.end()); int multiplyer = 1000000; for (std::vector::const_iterator it = parts.begin(); it != parts.end(); ++it) { int digit = atoi(it->c_str()); result += multiplyer*digit; multiplyer /= 100; } if (!ValidateVersion(result)) result = 0; return result; } OpenCVEngine::OpenCVEngine(IPackageManager* PkgManager): PackageManager(PkgManager) { assert(PkgManager); } int32_t OpenCVEngine::GetVersion() { return OPEN_CV_ENGINE_VERSION; } String16 OpenCVEngine::GetLibPathByVersion(android::String16 version) { std::string std_version(String8(version).string()); int norm_version; std::string path; LOGD("OpenCVEngine::GetLibPathByVersion(%s) impl", String8(version).string()); norm_version = NormalizeVersionString(std_version); if (0 != norm_version) { path = PackageManager->GetPackagePathByVersion(norm_version, Platform, CpuID); if (path.empty()) { LOGI("Package OpenCV of version \"%s\" (%d) is not installed. Try to install it :)", String8(version).string(), norm_version); } else { FixPermissions(path); } } else { LOGE("OpenCV version \"%s\" (%d) is not supported", String8(version).string(), norm_version); } return String16(path.c_str()); } android::String16 OpenCVEngine::GetLibraryList(android::String16 version) { std::string std_version = String8(version).string(); int norm_version; String16 result; norm_version = NormalizeVersionString(std_version); if (0 != norm_version) { std::string tmp = PackageManager->GetPackagePathByVersion(norm_version, Platform, CpuID); if (!tmp.empty()) { tmp += (std::string("/") + LIB_OPENCV_INFO_NAME); LOGD("Trying to load info library \"%s\"", tmp.c_str()); void* handle; InfoFunctionType info_func; handle = dlopen(tmp.c_str(), RTLD_LAZY); if (handle) { const char* error; dlerror(); info_func = (InfoFunctionType)dlsym(handle, "GetLibraryList"); if ((error = dlerror()) == NULL) { result = String16((*info_func)()); dlclose(handle); } else { LOGE("Library loading error: \"%s\"", error); } } else { LOGI("Info library not found in package"); } } else { LOGI("Package OpenCV of version \"%s\" (%d) is not installed. Try to install it :)", std_version.c_str(), norm_version); } } else { LOGE("OpenCV version \"%s\" is not supported", std_version.c_str()); } return result; } bool OpenCVEngine::InstallVersion(android::String16 version) { std::string std_version = String8(version).string(); int norm_version; bool result = false; LOGD("OpenCVEngine::InstallVersion() begin"); norm_version = NormalizeVersionString(std_version); if (0 != norm_version) { LOGD("PackageManager->InstallVersion call"); result = PackageManager->InstallVersion(norm_version, Platform, CpuID); } else { LOGE("OpenCV version \"%s\" (%d) is not supported", std_version.c_str(), norm_version); } LOGD("OpenCVEngine::InstallVersion() end"); return result; } bool OpenCVEngine::FixPermissions(const std::string& path) { LOGD("Fixing permissions for folder: \"%s\"", path.c_str()); chmod(path.c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); DIR* dir = opendir(path.c_str()); if (!dir) { LOGD("Fixing permissions error"); return false; } dirent* files = readdir(dir); while (files) { LOGD("Fix permissions for \"%s\"", files->d_name); chmod((path + std::string("/") + std::string(files->d_name)).c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); files = readdir(dir); } closedir(dir); return true; }